diff --git a/docs/entities/monsters.rst b/docs/entities/monsters.rst index 31735bd..d648069 100644 --- a/docs/entities/monsters.rst +++ b/docs/entities/monsters.rst @@ -57,7 +57,7 @@ Dans le `pack de textures`_ ASCII, il est représenté par le caractère ``8``. Dans le `pack de textures`_ écureuil, il est représenté par l'émoji ``🧸``. -Pyguargue +Pygargue --------- Son nom est fixé à `eagle`. Il a par défaut une force à **1000** et **5000** points de vie. diff --git a/docs/texture-pack.rst b/docs/texture-pack.rst index 072b6ff..6dc3b60 100644 --- a/docs/texture-pack.rst +++ b/docs/texture-pack.rst @@ -22,7 +22,7 @@ Pack de textures .. _Bouclier: entities/items.html#bouclier .. _Hazel: ../index.html .. _Plastron: ../entities/items.html#plastron -.. _Pyguargue: ../entities/monsters.html#Pyguargue +.. _Pygargue: ../entities/monsters.html#Pygargue .. _Casque: ../entities/items.html#Casque .. _Anneau: ../entities/items.html#Anneau .. _Trompette: ../entities/items.html#Trompette @@ -64,7 +64,7 @@ Chaque tuile fait un caractère de large. * Bouclier_ : ``D`` * Hazel_ : ``¤`` * Plastron_ : ``(`` - * Pyguargue_ : ``µ`` + * Pygargue_ : ``µ`` * Casque_ : ``0`` * Anneau_ : ``o`` * Trompette_ : ``/`` @@ -95,7 +95,7 @@ Chaque tuile fait 2 caractères de large pour afficher les émojis proprement. * Bouclier_ : ``🛡️`` * Hazel_ : ``🌰`` * Plastron_ : ``🦺`` - * Pyguargue_ : ``🦅`` + * Pygargue_ : ``🦅`` * Casque_ : ``⛑️`` * Anneau_ : ``💍`` * Trompette_ : ``🎺`` diff --git a/squirrelbattle/display/creditsdisplay.py b/squirrelbattle/display/creditsdisplay.py index a97c10e..93f2f72 100644 --- a/squirrelbattle/display/creditsdisplay.py +++ b/squirrelbattle/display/creditsdisplay.py @@ -92,6 +92,6 @@ class CreditsDisplay(Display): self.addstr(self.pad, y_offset + i, x_offset + j, c, fg_color, bg_color, bold=bold) - def handle_click(self, y: int, x: int, game: Game) -> None: + def handle_click(self, y: int, x: int, attr: int, game: Game) -> None: if self.pad.inch(y - 1, x - 1) != ord(" "): self.ascii_art_displayed = True diff --git a/squirrelbattle/display/display.py b/squirrelbattle/display/display.py index 3f9e08f..17d8c29 100644 --- a/squirrelbattle/display/display.py +++ b/squirrelbattle/display/display.py @@ -190,12 +190,11 @@ class Display: """ raise NotImplementedError - def handle_click(self, y: int, x: int, game: Game) -> None: + def handle_click(self, y: int, x: int, attr: int, game: Game) -> None: """ A mouse click was performed on the coordinates (y, x) of the pad. Maybe it should do something. """ - pass @property def rows(self) -> int: diff --git a/squirrelbattle/display/display_manager.py b/squirrelbattle/display/display_manager.py index 0eceb62..b4153c9 100644 --- a/squirrelbattle/display/display_manager.py +++ b/squirrelbattle/display/display_manager.py @@ -66,7 +66,7 @@ class DisplayManager: d.pack = TexturePack.get_pack(self.game.settings.TEXTURE_PACK) d.update(self.game) - def handle_mouse_click(self, y: int, x: int) -> None: + def handle_mouse_click(self, y: int, x: int, attr: int) -> None: """ Handles the mouse clicks. """ @@ -79,7 +79,7 @@ class DisplayManager: # of that display display = d if display: - display.handle_click(y - display.y, x - display.x, self.game) + display.handle_click(y - display.y, x - display.x, attr, self.game) def refresh(self) -> List[Display]: """ diff --git a/squirrelbattle/display/menudisplay.py b/squirrelbattle/display/menudisplay.py index b3001ab..1099f5b 100644 --- a/squirrelbattle/display/menudisplay.py +++ b/squirrelbattle/display/menudisplay.py @@ -51,7 +51,7 @@ class MenuDisplay(Display): self.height - 2 + self.y, self.width - 2 + self.x) - def handle_click(self, y: int, x: int, game: Game) -> None: + def handle_click(self, y: int, x: int, attr: int, game: Game) -> None: """ We can select a menu item with the mouse. """ @@ -135,13 +135,13 @@ class MainMenuDisplay(Display): def update(self, game: Game) -> None: self.menudisplay.update_menu(game.main_menu) - def handle_click(self, y: int, x: int, game: Game) -> None: + def handle_click(self, y: int, x: int, attr: int, game: Game) -> None: menuwidth = min(self.menudisplay.preferred_width, self.width) menuy, menux = len(self.title) + 8, self.width // 2 - menuwidth // 2 - 1 menuheight = min(self.menudisplay.preferred_height, self.height - menuy) if menuy <= y < menuy + menuheight and menux <= x < menux + menuwidth: - self.menudisplay.handle_click(y - menuy, x - menux, game) + self.menudisplay.handle_click(y - menuy, x - menux, attr, game) if y <= len(self.title): self.fg_color = randint(0, 1000), randint(0, 1000), randint(0, 1000) @@ -176,6 +176,7 @@ class PlayerInventoryDisplay(MenuDisplay): and self.selected else f" {rep} " self.addstr(self.pad, i + 1, 0, selection + " " + item.translated_name.capitalize() + + (f" ({item.description})" if item.description else "") + (": " + str(item.price) + " Hazels" if self.store_mode else "")) @@ -193,7 +194,7 @@ class PlayerInventoryDisplay(MenuDisplay): def trueheight(self) -> int: return 2 + super().trueheight - def handle_click(self, y: int, x: int, game: Game) -> None: + def handle_click(self, y: int, x: int, attr: int, game: Game) -> None: """ We can select a menu item with the mouse. """ @@ -221,6 +222,7 @@ class StoreInventoryDisplay(MenuDisplay): and self.selected else f" {rep} " self.addstr(self.pad, i + 1, 0, selection + " " + item.translated_name.capitalize() + + (f" ({item.description})" if item.description else "") + ": " + str(item.price) + " Hazels") price = f"{self.pack.HAZELNUT} {self.menu.merchant.hazel} Hazels" @@ -236,7 +238,7 @@ class StoreInventoryDisplay(MenuDisplay): def trueheight(self) -> int: return 2 + super().trueheight - def handle_click(self, y: int, x: int, game: Game) -> None: + def handle_click(self, y: int, x: int, attr: int, game: Game) -> None: """ We can select a menu item with the mouse. """ diff --git a/squirrelbattle/display/statsdisplay.py b/squirrelbattle/display/statsdisplay.py index 35ff92c..a60f6a2 100644 --- a/squirrelbattle/display/statsdisplay.py +++ b/squirrelbattle/display/statsdisplay.py @@ -3,8 +3,10 @@ import curses +from ..entities.items import Monocle from ..entities.player import Player from ..game import Game +from ..interfaces import FightingEntity from ..translations import gettext as _ from .display import Display @@ -13,6 +15,7 @@ class StatsDisplay(Display): """ A class to handle the display of the stats of the player. """ + game: Game player: Player def __init__(self, *args, **kwargs): @@ -20,6 +23,7 @@ class StatsDisplay(Display): self.pad = self.newpad(self.rows, self.cols) def update(self, game: Game) -> None: + self.game = game self.player = game.player def update_pad(self) -> None: @@ -77,6 +81,47 @@ class StatsDisplay(Display): self.addstr(self.pad, 15, 0, _("YOU ARE DEAD"), curses.COLOR_RED, bold=True, blink=True, standout=True) + if self.player.map.tiles[self.player.y][self.player.x].is_ladder(): + msg = _("Use {key} to use the ladder") \ + .format(key=self.game.settings.KEY_LADDER.upper()) + self.addstr(self.pad, self.height - 2, 0, msg, + italic=True, reverse=True) + + self.update_entities_stats() + + def update_entities_stats(self) -> None: + """ + Display information about a near entity if we have a monocle. + """ + for dy, dx in [(-1, 0), (0, -1), (0, 1), (1, 0)]: + for entity in self.player.map.find_entities(FightingEntity): + if entity == self.player: + continue + + if entity.y == self.player.y + dy \ + and entity.x == self.player.x + dx: + if entity.is_friendly(): + msg = _("Move to the friendly entity to talk to it") \ + if self.game.waiting_for_friendly_key else \ + _("Use {key} then move to talk to the entity") \ + .format(key=self.game.settings.KEY_CHAT.upper()) + self.addstr(self.pad, self.height - 1, 0, msg, + italic=True, reverse=True) + + if isinstance(self.player.equipped_secondary, Monocle): + # Truth monocle + message = f"{entity.translated_name.capitalize()} " \ + f"{self.pack[entity.name.upper()]}\n" \ + f"STR {entity.strength}\n" \ + f"INT {entity.intelligence}\n" \ + f"CHR {entity.charisma}\n" \ + f"DEX {entity.dexterity}\n" \ + f"CON {entity.constitution}\n" \ + f"CRI {entity.critical}%" + self.addstr(self.pad, 17, 0, message) + # Only display one entity + break + def display(self) -> None: self.pad.erase() self.update_pad() diff --git a/squirrelbattle/display/texturepack.py b/squirrelbattle/display/texturepack.py index 328f05e..d5c6da1 100644 --- a/squirrelbattle/display/texturepack.py +++ b/squirrelbattle/display/texturepack.py @@ -93,6 +93,7 @@ TexturePack.ASCII_PACK = TexturePack( HEDGEHOG='*', HELMET='0', MERCHANT='M', + MONOCLE='ô', PLAYER='@', RABBIT='Y', RING_OF_CRITICAL_DAMAGE='o', @@ -133,9 +134,10 @@ TexturePack.SQUIRREL_PACK = TexturePack( HAZELNUT='🌰', HEART='💜', HEDGEHOG='🦔', - HELMET='⛑️', + HELMET='⛑️ ', PLAYER='🐿️ ️', MERCHANT='🦜', + MONOCLE='🧐', RABBIT='🐇', RING_OF_CRITICAL_DAMAGE='💍', RING_OF_MORE_EXPERIENCE='💍', diff --git a/squirrelbattle/entities/items.py b/squirrelbattle/entities/items.py index c4594df..2560c21 100644 --- a/squirrelbattle/entities/items.py +++ b/squirrelbattle/entities/items.py @@ -24,6 +24,13 @@ class Item(Entity): self.held_by = held_by self.price = price + @property + def description(self) -> str: + """ + In the inventory, indicate the usefulness of the item. + """ + return "" + def drop(self) -> None: """ The item is dropped from the inventory onto the floor. @@ -84,9 +91,9 @@ class Item(Entity): """ Returns the list of all item classes. """ - return [BodySnatchPotion, Bomb, Heart, Shield, Sword, - Chestplate, Helmet, RingCritical, RingXP, - ScrollofDamage, ScrollofWeakening, Ruler, Bow, FireBallStaff] + return [BodySnatchPotion, Bomb, Bow, Chestplate, FireBallStaff, + Heart, Helmet, Monocle, ScrollofDamage, ScrollofWeakening, + Shield, Sword, RingCritical, RingXP, Ruler] def be_sold(self, buyer: InventoryHolder, seller: InventoryHolder, for_free: bool = False) -> bool: @@ -120,6 +127,10 @@ class Heart(Item): super().__init__(name=name, price=price, *args, **kwargs) self.healing = healing + @property + def description(self) -> str: + return f"HP+{self.healing}" + def hold(self, entity: InventoryHolder) -> None: """ When holding a heart, the player is healed and @@ -228,6 +239,10 @@ class Weapon(Item): super().__init__(*args, **kwargs) self.damage = damage + @property + def description(self) -> str: + return f"STR+{self.damage}" if self.damage else super().description + def save_state(self) -> dict: """ Saves the state of the weapon into a dictionary @@ -281,6 +296,11 @@ class Armor(Item): super().__init__(*args, **kwargs) self.constitution = constitution + @property + def description(self) -> str: + return f"CON+{self.constitution}" if self.constitution \ + else super().description + def equip(self) -> None: super().equip() self.held_by.constitution += self.constitution @@ -398,6 +418,14 @@ class Ring(Item): self.critical = critical self.experience = experience + @property + def description(self) -> str: + fields = [("MAX HP", self.maxhealth), ("STR", self.strength), + ("INT", self.intelligence), ("CHR", self.charisma), + ("DEX", self.dexterity), ("CON", self.constitution), + ("CRI", self.critical), ("XP", self.experience)] + return ", ".join(f"{key}+{value}" for key, value in fields if value) + def equip(self) -> None: super().equip() self.held_by.maxhealth += self.maxhealth @@ -446,7 +474,6 @@ class RingXP(Ring): super().__init__(name=name, price=price, experience=experience, *args, **kwargs) - class ScrollofDamage(Item): """ A scroll that, when used, deals damage to all entities in a certain radius. @@ -604,3 +631,9 @@ class FireBallStaff(LongRangeWeapon): explosion = Explosion(y=y, x=x) self.held_by.map.add_entity(explosion) + + +class Monocle(Item): + def __init__(self, name: str = "monocle", price: int = 10, + *args, **kwargs): + super().__init__(name=name, price=price, *args, **kwargs) \ No newline at end of file diff --git a/squirrelbattle/entities/monsters.py b/squirrelbattle/entities/monsters.py index cae12f2..b62421a 100644 --- a/squirrelbattle/entities/monsters.py +++ b/squirrelbattle/entities/monsters.py @@ -43,7 +43,9 @@ class Monster(FightingEntity): # that targets the player. # If they can not move and are already close to the player, # they hit. - if target and (self.y, self.x) in target.paths: + if target and (self.y, self.x) in target.paths and \ + self.map.is_visible_from(self.y, self.x, + target.y, target.x, 5): # Moves to target player by choosing the best available path for next_y, next_x in target.paths[(self.y, self.x)]: moved = self.check_move(next_y, next_x, True) diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index b576c68..9734144 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -97,10 +97,14 @@ class Game: screen.noutrefresh() self.display_actions(DisplayActions.REFRESH) curses.doupdate() - key = screen.getkey() + try: + key = screen.getkey() + except KeyboardInterrupt: + exit(0) + return if key == "KEY_MOUSE": - _ignored1, x, y, _ignored2, _ignored3 = curses.getmouse() - self.display_actions(DisplayActions.MOUSE, y, x) + _ignored1, x, y, _ignored2, attr = curses.getmouse() + self.display_actions(DisplayActions.MOUSE, y, x, attr) else: self.handle_key_pressed( KeyValues.translate_key(key, self.settings), key) @@ -401,14 +405,16 @@ class Game: """ Saves the game to a dictionary. """ - return self.map.save_state() + return dict(map_index=self.map_index, + maps=[m.save_state() for m in self.maps]) def load_state(self, d: dict) -> None: """ Loads the game from a dictionary. """ try: - self.map.load_state(d) + self.map_index = d["map_index"] + self.maps = [Map().load_state(map_dict) for map_dict in d["maps"]] except KeyError: self.message = _("Some keys are missing in your save file.\n" "Your save seems to be corrupt. It got deleted.") @@ -425,6 +431,8 @@ class Game: return self.player = players[0] + self.map.compute_visibility(self.player.y, self.player.x, + self.player.vision) self.display_actions(DisplayActions.UPDATE) def load_game(self) -> None: diff --git a/squirrelbattle/interfaces.py b/squirrelbattle/interfaces.py index 0a43b9a..828fe59 100644 --- a/squirrelbattle/interfaces.py +++ b/squirrelbattle/interfaces.py @@ -7,6 +7,7 @@ from random import choice, choices, randint from typing import List, Optional, Any, Dict, Tuple from queue import PriorityQueue from functools import reduce +from copy import deepcopy from .display.texturepack import TexturePack from .translations import gettext as _ @@ -80,18 +81,18 @@ class Map: currentx: int currenty: int - def __init__(self, width: int, height: int, tiles: list, - start_y: int, start_x: int): + def __init__(self, width: int = 0, height: int = 0, tiles: list = None, + start_y: int = 0, start_x: int = 0): self.floor = 0 self.width = width self.height = height self.start_y = start_y self.start_x = start_x - self.tiles = tiles - self.visibility = [[False for _ in range(len(tiles[0]))] - for _ in range(len(tiles))] + self.tiles = tiles or [] + self.visibility = [[False for _ in range(len(self.tiles[0]))] + for _ in range(len(self.tiles))] self.seen_tiles = [[False for _ in range(len(tiles[0]))] - for _ in range(len(tiles))] + for _ in range(len(self.tiles))] self.entities = [] self.logs = Logs() @@ -193,6 +194,14 @@ class Map: entity.move(y, x) self.add_entity(entity) + def is_visible_from(self, starty: int, startx: int, desty: int, destx: int, + max_range: int) -> bool: + oldvisibility = deepcopy(self.visibility) + self.compute_visibility(starty, startx, max_range) + result = self.visibility[desty][destx] + self.visibility = oldvisibility + return result + def compute_visibility(self, y: int, x: int, max_range: int) -> None: """ Sets the visible tiles to be the ones visible by an entity at point @@ -245,10 +254,12 @@ class Map: if x + y > max_range: continue is_opaque = self.is_wall(y, x, octant, origin) + if y == top_y and octant == 7 and x == 4: + self.logs.add_message(f"{x}, {y}, {top.X}, {top.Y}") is_visible = is_opaque\ - or ((y != top_y or top > Slope(y * 4 - 1, x * 4 + 1)) + or ((y != top_y or top >= Slope(y, x)) and (y != bottom_y - or bottom < Slope(y * 4 + 1, x * 4 - 1))) + or bottom <= Slope(y, x))) # is_visible = is_opaque\ # or ((y != top_y or top >= Slope(y, x)) # and (y != bottom_y or bottom <= Slope(y, x))) @@ -338,9 +349,10 @@ class Map: for enti in self.entities: d["entities"].append(enti.save_state()) d["map"] = self.draw_string(TexturePack.ASCII_PACK) + d["seen_tiles"] = self.seen_tiles return d - def load_state(self, d: dict) -> None: + def load_state(self, d: dict) -> "Map": """ Loads the map's attributes from a dictionary. """ @@ -351,11 +363,16 @@ class Map: self.currentx = d["currentx"] self.currenty = d["currenty"] self.tiles = self.load_dungeon_from_string(d["map"]) + self.seen_tiles = d["seen_tiles"] + self.visibility = [[False for _ in range(len(self.tiles[0]))] + for _ in range(len(self.tiles))] self.entities = [] dictclasses = Entity.get_all_entity_classes_in_a_dict() for entisave in d["entities"]: self.add_entity(dictclasses[entisave["type"]](**entisave)) + return self + class Tile(Enum): """ @@ -636,32 +653,34 @@ class Entity: Trumpet, Chest from squirrelbattle.entities.items import BodySnatchPotion, Bomb, \ Heart, Sword, Shield, Chestplate, Helmet, RingCritical, RingXP, \ - ScrollofDamage, ScrollofWeakening, Ruler, Bow, FireBallStaff + ScrollofDamage, ScrollofWeakening, Ruler, Bow, FireBallStaff, \ + Monocle return { - "Tiger": Tiger, - "Bomb": Bomb, - "Heart": Heart, "BodySnatchPotion": BodySnatchPotion, - "Hedgehog": Hedgehog, - "Rabbit": Rabbit, - "TeddyBear": TeddyBear, - "Player": Player, - "Merchant": Merchant, - "Sunflower": Sunflower, - "Sword": Sword, - "Trumpet": Trumpet, - "Eagle": GiantSeaEagle, - "Shield": Shield, + "Bomb": Bomb, + "Bow": Bow, + "Chest": Chest, "Chestplate": Chestplate, + "Eagle": GiantSeaEagle, + "FireBallStaff": FireBallStaff, + "Heart": Heart, + "Hedgehog": Hedgehog, "Helmet": Helmet, + "Merchant": Merchant, + "Monocle": Monocle, + "Player": Player, + "Rabbit": Rabbit, "RingCritical": RingCritical, "RingXP": RingXP, "Ruler": Ruler, "ScrollofDamage": ScrollofDamage, "ScrollofWeakening": ScrollofWeakening, - "Bow": Bow, - "FireBallStaff": FireBallStaff, - "Chest": Chest, + "Shield": Shield, + "Sunflower": Sunflower, + "Sword": Sword, + "Trumpet": Trumpet, + "TeddyBear": TeddyBear, + "Tiger": Tiger, } def save_state(self) -> dict: diff --git a/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po index 20aa2a7..2cea0a3 100644 --- a/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po +++ b/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: squirrelbattle 3.14.1\n" "Report-Msgid-Bugs-To: squirrel-battle@crans.org\n" -"POT-Creation-Date: 2021-01-08 01:57+0100\n" +"POT-Creation-Date: 2021-01-08 15:15+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,87 +17,116 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +msgid "ring_of_critical_damage" +msgstr "" + +msgid "ring_of_more_experience" +msgstr "" + #, python-brace-format msgid "{name} takes {amount} damage." msgstr "{name} nimmt {amount} Schadenspunkte." -#: squirrelbattle/display/menudisplay.py:160 +#: squirrelbattle/display/creditsdisplay.py:28 +#: squirrelbattle/display/menudisplay.py:123 +#: squirrelbattle/display/menudisplay.py:148 +msgid "Credits" +msgstr "" + +#: squirrelbattle/display/creditsdisplay.py:32 +msgid "Developers:" +msgstr "" + +#: squirrelbattle/display/creditsdisplay.py:38 +msgid "Translators:" +msgstr "" + +#: squirrelbattle/display/menudisplay.py:168 msgid "INVENTORY" msgstr "BESTAND" -#: squirrelbattle/display/menudisplay.py:202 +#: squirrelbattle/display/menudisplay.py:214 msgid "STALL" msgstr "STAND" -#: squirrelbattle/display/statsdisplay.py:23 -#: squirrelbattle/tests/translations_test.py:60 -msgid "player" -msgstr "Spieler" - -#: squirrelbattle/display/statsdisplay.py:35 +#: squirrelbattle/display/statsdisplay.py:44 msgid "Inventory:" msgstr "Bestand:" -#: squirrelbattle/display/statsdisplay.py:52 +#: squirrelbattle/display/statsdisplay.py:61 msgid "Equipped main:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:56 +#: squirrelbattle/display/statsdisplay.py:65 msgid "Equipped secondary:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:61 +#: squirrelbattle/display/statsdisplay.py:70 msgid "Equipped chestplate:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:65 +#: squirrelbattle/display/statsdisplay.py:74 msgid "Equipped helmet:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:72 +#: squirrelbattle/display/statsdisplay.py:81 msgid "YOU ARE DEAD" msgstr "SIE WURDEN GESTORBEN" +#: squirrelbattle/display/statsdisplay.py:85 +#, python-brace-format +msgid "Use {key} to use the ladder" +msgstr "" + +#: squirrelbattle/display/statsdisplay.py:94 +msgid "Move to the friendly entity to talk to it" +msgstr "" + +#: squirrelbattle/display/statsdisplay.py:96 +#, python-brace-format +msgid "Use {key} then move to talk to the entity" +msgstr "" + #. TODO #: squirrelbattle/entities/friendly.py:33 msgid "I don't sell any squirrel" msgstr "Ich verkaufe keinen Eichhörnchen." -#: squirrelbattle/entities/friendly.py:52 +#: squirrelbattle/entities/friendly.py:55 msgid "Flower power!!" msgstr "Blumenmacht!!" -#: squirrelbattle/entities/friendly.py:52 +#: squirrelbattle/entities/friendly.py:55 msgid "The sun is warm today" msgstr "Die Sonne ist warm heute" #. The bomb is exploding. #. Each entity that is close to the bomb takes damages. #. The player earn XP if the entity was killed. -#: squirrelbattle/entities/items.py:163 +#: squirrelbattle/entities/items.py:178 msgid "Bomb is exploding." msgstr "Die Bombe explodiert." -#: squirrelbattle/entities/items.py:344 +#: squirrelbattle/entities/items.py:365 #, python-brace-format msgid "{player} exchanged its body with {entity}." msgstr "{player} täuscht seinem Körper mit {entity} aus." -#: squirrelbattle/game.py:182 +#: squirrelbattle/game.py:200 #, python-brace-format msgid "The player climbs down to the floor {floor}." msgstr "Der Spieler klettert auf dem Stock {floor} hinunter." -#: squirrelbattle/game.py:195 +#: squirrelbattle/game.py:213 #, python-brace-format msgid "The player climbs up the floor {floor}." msgstr "Der Spieler klettert auf dem Stock {floor} hinoben." -#: squirrelbattle/game.py:285 squirrelbattle/tests/game_test.py:592 +#: squirrelbattle/game.py:304 squirrelbattle/tests/game_test.py:603 msgid "The buyer does not have enough money" msgstr "Der Kaufer hat nicht genug Geld" -#: squirrelbattle/game.py:328 +#: squirrelbattle/game.py:349 msgid "" "Some keys are missing in your save file.\n" "Your save seems to be corrupt. It got deleted." @@ -105,7 +134,7 @@ msgstr "" "In Ihrer Speicherdatei fehlen einige Schlüssel.\n" "Ihre Speicherung scheint korrupt zu sein. Es wird gelöscht." -#: squirrelbattle/game.py:336 +#: squirrelbattle/game.py:357 msgid "" "No player was found on this map!\n" "Maybe you died?" @@ -113,7 +142,7 @@ msgstr "" "Auf dieser Karte wurde kein Spieler gefunden!\n" "Vielleicht sind Sie gestorben?" -#: squirrelbattle/game.py:356 +#: squirrelbattle/game.py:379 msgid "" "The JSON file is not correct.\n" "Your save seems corrupted. It got deleted." @@ -121,26 +150,26 @@ msgstr "" "Die JSON-Datei ist nicht korrekt.\n" "Ihre Speicherung scheint korrumpiert. Sie wurde gelöscht." -#: squirrelbattle/interfaces.py:452 +#: squirrelbattle/interfaces.py:718 msgid "It's a critical hit!" msgstr "" -#: squirrelbattle/interfaces.py:453 +#: squirrelbattle/interfaces.py:719 #, python-brace-format msgid "{name} hits {opponent}." msgstr "{name} schlägt {opponent}." -#: squirrelbattle/interfaces.py:465 +#: squirrelbattle/interfaces.py:733 #, python-brace-format msgid "{name} takes {damage} damage." msgstr "" -#: squirrelbattle/interfaces.py:467 +#: squirrelbattle/interfaces.py:735 #, python-brace-format msgid "{name} dies." msgstr "{name} stirbt." -#: squirrelbattle/interfaces.py:501 +#: squirrelbattle/interfaces.py:769 #, python-brace-format msgid "{entity} said: {message}" msgstr "{entity} hat gesagt: {message}" @@ -149,8 +178,8 @@ msgstr "{entity} hat gesagt: {message}" msgid "Back" msgstr "Zurück" -#: squirrelbattle/tests/game_test.py:358 squirrelbattle/tests/game_test.py:361 -#: squirrelbattle/tests/game_test.py:364 squirrelbattle/tests/game_test.py:367 +#: squirrelbattle/tests/game_test.py:368 squirrelbattle/tests/game_test.py:371 +#: squirrelbattle/tests/game_test.py:374 squirrelbattle/tests/game_test.py:377 #: squirrelbattle/tests/translations_test.py:16 msgid "New game" msgstr "Neu Spiel" @@ -247,6 +276,10 @@ msgstr "Textur-Packung" msgid "Language" msgstr "Sprache" +#: squirrelbattle/tests/translations_test.py:62 +msgid "player" +msgstr "Spieler" + #: squirrelbattle/tests/translations_test.py:64 msgid "hedgehog" msgstr "Igel" @@ -271,22 +304,50 @@ msgstr "Teddybär" msgid "tiger" msgstr "Tiger" -#: squirrelbattle/tests/translations_test.py:71 +#: squirrelbattle/tests/translations_test.py:70 +msgid "eagle" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:72 msgid "body snatch potion" msgstr "Leichenfleddererzaubertrank" -#: squirrelbattle/tests/translations_test.py:72 +#: squirrelbattle/tests/translations_test.py:73 msgid "bomb" msgstr "Bombe" -#: squirrelbattle/tests/translations_test.py:73 +#: squirrelbattle/tests/translations_test.py:74 msgid "explosion" msgstr "Explosion" -#: squirrelbattle/tests/translations_test.py:74 +#: squirrelbattle/tests/translations_test.py:75 msgid "heart" msgstr "Herz" -#: squirrelbattle/tests/translations_test.py:75 +#: squirrelbattle/tests/translations_test.py:76 msgid "sword" msgstr "schwert" + +#: squirrelbattle/tests/translations_test.py:77 +msgid "helmet" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:78 +msgid "chestplate" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:79 +msgid "shield" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:80 +msgid "ring of critical damage" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:82 +msgid "ring of more experience" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:84 +msgid "monocle" +msgstr "" diff --git a/squirrelbattle/locale/es/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/es/LC_MESSAGES/squirrelbattle.po index 0bfdac6..18868c3 100644 --- a/squirrelbattle/locale/es/LC_MESSAGES/squirrelbattle.po +++ b/squirrelbattle/locale/es/LC_MESSAGES/squirrelbattle.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: squirrelbattle 3.14.1\n" "Report-Msgid-Bugs-To: squirrel-battle@crans.org\n" -"POT-Creation-Date: 2021-01-06 15:19+0100\n" +"POT-Creation-Date: 2021-01-08 15:15+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,86 +17,115 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +msgid "ring_of_critical_damage" +msgstr "" + +msgid "ring_of_more_experience" +msgstr "" + #, python-brace-format msgid "{name} takes {amount} damage." msgstr "{name} recibe {amount} daño." -#: squirrelbattle/display/menudisplay.py:160 +#: squirrelbattle/display/creditsdisplay.py:28 +#: squirrelbattle/display/menudisplay.py:123 +#: squirrelbattle/display/menudisplay.py:148 +msgid "Credits" +msgstr "" + +#: squirrelbattle/display/creditsdisplay.py:32 +msgid "Developers:" +msgstr "" + +#: squirrelbattle/display/creditsdisplay.py:38 +msgid "Translators:" +msgstr "" + +#: squirrelbattle/display/menudisplay.py:168 msgid "INVENTORY" msgstr "INVENTORIO" -#: squirrelbattle/display/menudisplay.py:202 +#: squirrelbattle/display/menudisplay.py:214 msgid "STALL" msgstr "PUESTO" -#: squirrelbattle/display/statsdisplay.py:23 -#: squirrelbattle/tests/translations_test.py:60 -msgid "player" -msgstr "jugador" - -#: squirrelbattle/display/statsdisplay.py:35 +#: squirrelbattle/display/statsdisplay.py:44 msgid "Inventory:" msgstr "Inventorio :" -#: squirrelbattle/display/statsdisplay.py:52 +#: squirrelbattle/display/statsdisplay.py:61 msgid "Equipped main:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:56 +#: squirrelbattle/display/statsdisplay.py:65 msgid "Equipped secondary:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:61 +#: squirrelbattle/display/statsdisplay.py:70 msgid "Equipped chestplate:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:65 +#: squirrelbattle/display/statsdisplay.py:74 msgid "Equipped helmet:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:72 +#: squirrelbattle/display/statsdisplay.py:81 msgid "YOU ARE DEAD" msgstr "ERES MUERTO" +#: squirrelbattle/display/statsdisplay.py:85 +#, python-brace-format +msgid "Use {key} to use the ladder" +msgstr "" + +#: squirrelbattle/display/statsdisplay.py:94 +msgid "Move to the friendly entity to talk to it" +msgstr "" + +#: squirrelbattle/display/statsdisplay.py:96 +#, python-brace-format +msgid "Use {key} then move to talk to the entity" +msgstr "" + #: squirrelbattle/entities/friendly.py:33 msgid "I don't sell any squirrel" msgstr "No vendo ninguna ardilla" -#: squirrelbattle/entities/friendly.py:52 +#: squirrelbattle/entities/friendly.py:55 msgid "Flower power!!" msgstr "Poder de las flores!!" -#: squirrelbattle/entities/friendly.py:52 +#: squirrelbattle/entities/friendly.py:55 msgid "The sun is warm today" msgstr "El sol está caliente hoy" #. The bomb is exploding. #. Each entity that is close to the bomb takes damages. #. The player earn XP if the entity was killed. -#: squirrelbattle/entities/items.py:163 +#: squirrelbattle/entities/items.py:178 msgid "Bomb is exploding." msgstr "La bomba está explotando." -#: squirrelbattle/entities/items.py:344 +#: squirrelbattle/entities/items.py:365 #, python-brace-format msgid "{player} exchanged its body with {entity}." msgstr "{player} intercambió su cuerpo con {entity}." -#: squirrelbattle/game.py:182 +#: squirrelbattle/game.py:200 #, python-brace-format msgid "The player climbs down to the floor {floor}." msgstr "" -#: squirrelbattle/game.py:195 +#: squirrelbattle/game.py:213 #, python-brace-format msgid "The player climbs up the floor {floor}." msgstr "" -#: squirrelbattle/game.py:285 squirrelbattle/tests/game_test.py:592 +#: squirrelbattle/game.py:304 squirrelbattle/tests/game_test.py:603 msgid "The buyer does not have enough money" msgstr "El comprador no tiene suficiente dinero" -#: squirrelbattle/game.py:328 +#: squirrelbattle/game.py:349 msgid "" "Some keys are missing in your save file.\n" "Your save seems to be corrupt. It got deleted." @@ -104,7 +133,7 @@ msgstr "" "Algunas claves faltan en su archivo de guarda.\n" "Su guarda parece a ser corruptido. Fue eliminado." -#: squirrelbattle/game.py:336 +#: squirrelbattle/game.py:357 msgid "" "No player was found on this map!\n" "Maybe you died?" @@ -112,7 +141,7 @@ msgstr "" "No jugador encontrado sobre la carta !\n" "¿ Quizas murió ?" -#: squirrelbattle/game.py:356 +#: squirrelbattle/game.py:379 msgid "" "The JSON file is not correct.\n" "Your save seems corrupted. It got deleted." @@ -120,26 +149,26 @@ msgstr "" "El JSON archivo no es correcto.\n" "Su guarda parece corrupta. Fue eliminada." -#: squirrelbattle/interfaces.py:452 +#: squirrelbattle/interfaces.py:718 msgid "It's a critical hit!" msgstr "" -#: squirrelbattle/interfaces.py:453 +#: squirrelbattle/interfaces.py:719 #, python-brace-format msgid "{name} hits {opponent}." msgstr "{name} golpea a {opponent}." -#: squirrelbattle/interfaces.py:465 +#: squirrelbattle/interfaces.py:733 #, python-brace-format msgid "{name} takes {damage} damage." msgstr "" -#: squirrelbattle/interfaces.py:467 +#: squirrelbattle/interfaces.py:735 #, python-brace-format msgid "{name} dies." msgstr "{name} se muere." -#: squirrelbattle/interfaces.py:501 +#: squirrelbattle/interfaces.py:769 #, python-brace-format msgid "{entity} said: {message}" msgstr "{entity} dijo : {message}" @@ -148,8 +177,8 @@ msgstr "{entity} dijo : {message}" msgid "Back" msgstr "Volver" -#: squirrelbattle/tests/game_test.py:358 squirrelbattle/tests/game_test.py:361 -#: squirrelbattle/tests/game_test.py:364 squirrelbattle/tests/game_test.py:367 +#: squirrelbattle/tests/game_test.py:368 squirrelbattle/tests/game_test.py:371 +#: squirrelbattle/tests/game_test.py:374 squirrelbattle/tests/game_test.py:377 #: squirrelbattle/tests/translations_test.py:16 msgid "New game" msgstr "Nuevo partido" @@ -246,6 +275,10 @@ msgstr "Paquete de texturas" msgid "Language" msgstr "Languaje" +#: squirrelbattle/tests/translations_test.py:62 +msgid "player" +msgstr "jugador" + #: squirrelbattle/tests/translations_test.py:64 msgid "hedgehog" msgstr "erizo" @@ -270,22 +303,50 @@ msgstr "osito de peluche" msgid "tiger" msgstr "tigre" -#: squirrelbattle/tests/translations_test.py:71 +#: squirrelbattle/tests/translations_test.py:70 +msgid "eagle" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:72 msgid "body snatch potion" msgstr "poción de intercambio" -#: squirrelbattle/tests/translations_test.py:72 +#: squirrelbattle/tests/translations_test.py:73 msgid "bomb" msgstr "bomba" -#: squirrelbattle/tests/translations_test.py:73 +#: squirrelbattle/tests/translations_test.py:74 msgid "explosion" msgstr "explosión" -#: squirrelbattle/tests/translations_test.py:74 +#: squirrelbattle/tests/translations_test.py:75 msgid "heart" msgstr "corazón" -#: squirrelbattle/tests/translations_test.py:75 +#: squirrelbattle/tests/translations_test.py:76 msgid "sword" msgstr "espada" + +#: squirrelbattle/tests/translations_test.py:77 +msgid "helmet" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:78 +msgid "chestplate" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:79 +msgid "shield" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:80 +msgid "ring of critical damage" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:82 +msgid "ring of more experience" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:84 +msgid "monocle" +msgstr "" diff --git a/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po index 42172c3..4657fe8 100644 --- a/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po +++ b/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: squirrelbattle 3.14.1\n" "Report-Msgid-Bugs-To: squirrel-battle@crans.org\n" -"POT-Creation-Date: 2021-01-06 15:19+0100\n" +"POT-Creation-Date: 2021-01-08 15:15+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -21,83 +21,106 @@ msgstr "" msgid "{name} takes {amount} damage." msgstr "{name} prend {amount} points de dégât." -#: squirrelbattle/display/menudisplay.py:160 +#: squirrelbattle/display/creditsdisplay.py:28 +#: squirrelbattle/display/menudisplay.py:123 +#: squirrelbattle/display/menudisplay.py:148 +msgid "Credits" +msgstr "" + +#: squirrelbattle/display/creditsdisplay.py:32 +msgid "Developers:" +msgstr "" + +#: squirrelbattle/display/creditsdisplay.py:38 +msgid "Translators:" +msgstr "" + +#: squirrelbattle/display/menudisplay.py:168 msgid "INVENTORY" msgstr "INVENTAIRE" -#: squirrelbattle/display/menudisplay.py:202 +#: squirrelbattle/display/menudisplay.py:214 msgid "STALL" msgstr "STAND" -#: squirrelbattle/display/statsdisplay.py:23 -#: squirrelbattle/tests/translations_test.py:60 -msgid "player" -msgstr "joueur" - -#: squirrelbattle/display/statsdisplay.py:35 +#: squirrelbattle/display/statsdisplay.py:44 msgid "Inventory:" msgstr "Inventaire :" -#: squirrelbattle/display/statsdisplay.py:52 +#: squirrelbattle/display/statsdisplay.py:61 msgid "Equipped main:" msgstr "Équipement principal :" -#: squirrelbattle/display/statsdisplay.py:56 +#: squirrelbattle/display/statsdisplay.py:65 msgid "Equipped secondary:" msgstr "Équipement secondaire :" -#: squirrelbattle/display/statsdisplay.py:61 +#: squirrelbattle/display/statsdisplay.py:70 msgid "Equipped chestplate:" msgstr "Plastron équipé :" -#: squirrelbattle/display/statsdisplay.py:65 +#: squirrelbattle/display/statsdisplay.py:74 msgid "Equipped helmet:" msgstr "Casque équipé :" -#: squirrelbattle/display/statsdisplay.py:72 +#: squirrelbattle/display/statsdisplay.py:81 msgid "YOU ARE DEAD" msgstr "VOUS ÊTES MORT" +#: squirrelbattle/display/statsdisplay.py:85 +#, python-brace-format +msgid "Use {key} to use the ladder" +msgstr "Appuyez sur {key} pour utiliser l'échelle" + +#: squirrelbattle/display/statsdisplay.py:94 +msgid "Move to the friendly entity to talk to it" +msgstr "Avancez vers l'entité pour lui parler" + +#: squirrelbattle/display/statsdisplay.py:96 +#, python-brace-format +msgid "Use {key} then move to talk to the entity" +msgstr "Appuyez sur {key} puis déplacez-vous pour parler" + #. TODO #: squirrelbattle/entities/friendly.py:33 msgid "I don't sell any squirrel" msgstr "Je ne vends pas d'écureuil" -#: squirrelbattle/entities/friendly.py:52 +#: squirrelbattle/entities/friendly.py:55 msgid "Flower power!!" msgstr "Pouvoir des fleurs !!" -#: squirrelbattle/entities/friendly.py:52 +#: squirrelbattle/entities/friendly.py:55 msgid "The sun is warm today" msgstr "Le soleil est chaud aujourd'hui" #. The bomb is exploding. #. Each entity that is close to the bomb takes damages. #. The player earn XP if the entity was killed. -#: squirrelbattle/entities/items.py:163 +#: squirrelbattle/entities/items.py:178 msgid "Bomb is exploding." msgstr "La bombe explose." -#: squirrelbattle/entities/items.py:344 +#: squirrelbattle/entities/items.py:365 #, python-brace-format msgid "{player} exchanged its body with {entity}." msgstr "{player} a échangé son corps avec {entity}." -#: squirrelbattle/game.py:182 +#: squirrelbattle/game.py:200 #, python-brace-format msgid "The player climbs down to the floor {floor}." msgstr "Le joueur descend à l'étage {floor}." -#: squirrelbattle/game.py:195 +#: squirrelbattle/game.py:213 #, python-brace-format msgid "The player climbs up the floor {floor}." msgstr "Le joueur monte à l'étage {floor}." -#: squirrelbattle/game.py:285 squirrelbattle/tests/game_test.py:592 +#: squirrelbattle/game.py:304 squirrelbattle/tests/game_test.py:603 msgid "The buyer does not have enough money" msgstr "L'acheteur n'a pas assez d'argent" -#: squirrelbattle/game.py:328 +#: squirrelbattle/game.py:349 msgid "" "Some keys are missing in your save file.\n" "Your save seems to be corrupt. It got deleted." @@ -105,7 +128,7 @@ msgstr "" "Certaines clés de votre ficher de sauvegarde sont manquantes.\n" "Votre sauvegarde semble corrompue. Elle a été supprimée." -#: squirrelbattle/game.py:336 +#: squirrelbattle/game.py:357 msgid "" "No player was found on this map!\n" "Maybe you died?" @@ -113,7 +136,7 @@ msgstr "" "Aucun joueur n'a été trouvé sur la carte !\n" "Peut-être êtes-vous mort ?" -#: squirrelbattle/game.py:356 +#: squirrelbattle/game.py:379 msgid "" "The JSON file is not correct.\n" "Your save seems corrupted. It got deleted." @@ -121,26 +144,26 @@ msgstr "" "Le fichier JSON de sauvegarde est incorrect.\n" "Votre sauvegarde semble corrompue. Elle a été supprimée." -#: squirrelbattle/interfaces.py:452 +#: squirrelbattle/interfaces.py:718 msgid "It's a critical hit!" msgstr "C'est un coup critique !" -#: squirrelbattle/interfaces.py:453 +#: squirrelbattle/interfaces.py:719 #, python-brace-format msgid "{name} hits {opponent}." msgstr "{name} frappe {opponent}." -#: squirrelbattle/interfaces.py:465 +#: squirrelbattle/interfaces.py:733 #, python-brace-format msgid "{name} takes {damage} damage." msgstr "{name} prend {damage} dégâts." -#: squirrelbattle/interfaces.py:467 +#: squirrelbattle/interfaces.py:735 #, python-brace-format msgid "{name} dies." msgstr "{name} meurt." -#: squirrelbattle/interfaces.py:501 +#: squirrelbattle/interfaces.py:769 #, python-brace-format msgid "{entity} said: {message}" msgstr "{entity} a dit : {message}" @@ -149,8 +172,8 @@ msgstr "{entity} a dit : {message}" msgid "Back" msgstr "Retour" -#: squirrelbattle/tests/game_test.py:358 squirrelbattle/tests/game_test.py:361 -#: squirrelbattle/tests/game_test.py:364 squirrelbattle/tests/game_test.py:367 +#: squirrelbattle/tests/game_test.py:368 squirrelbattle/tests/game_test.py:371 +#: squirrelbattle/tests/game_test.py:374 squirrelbattle/tests/game_test.py:377 #: squirrelbattle/tests/translations_test.py:16 msgid "New game" msgstr "Nouvelle partie" @@ -247,6 +270,10 @@ msgstr "Pack de textures" msgid "Language" msgstr "Langue" +#: squirrelbattle/tests/translations_test.py:62 +msgid "player" +msgstr "joueur" + #: squirrelbattle/tests/translations_test.py:64 msgid "hedgehog" msgstr "hérisson" @@ -271,22 +298,50 @@ msgstr "nounours" msgid "tiger" msgstr "tigre" -#: squirrelbattle/tests/translations_test.py:71 +#: squirrelbattle/tests/translations_test.py:70 +msgid "eagle" +msgstr "pygargue" + +#: squirrelbattle/tests/translations_test.py:72 msgid "body snatch potion" msgstr "potion d'arrachage de corps" -#: squirrelbattle/tests/translations_test.py:72 +#: squirrelbattle/tests/translations_test.py:73 msgid "bomb" msgstr "bombe" -#: squirrelbattle/tests/translations_test.py:73 +#: squirrelbattle/tests/translations_test.py:74 msgid "explosion" msgstr "explosion" -#: squirrelbattle/tests/translations_test.py:74 +#: squirrelbattle/tests/translations_test.py:75 msgid "heart" msgstr "cœur" -#: squirrelbattle/tests/translations_test.py:75 +#: squirrelbattle/tests/translations_test.py:76 msgid "sword" msgstr "épée" + +#: squirrelbattle/tests/translations_test.py:77 +msgid "helmet" +msgstr "casque" + +#: squirrelbattle/tests/translations_test.py:78 +msgid "chestplate" +msgstr "plastron" + +#: squirrelbattle/tests/translations_test.py:79 +msgid "shield" +msgstr "bouclier" + +#: squirrelbattle/tests/translations_test.py:80 +msgid "ring of critical damage" +msgstr "anneau de coup critique" + +#: squirrelbattle/tests/translations_test.py:82 +msgid "ring of more experience" +msgstr "anneau de plus d'expérience" + +#: squirrelbattle/tests/translations_test.py:84 +msgid "monocle" +msgstr "monocle" diff --git a/squirrelbattle/settings.py b/squirrelbattle/settings.py index 284b41f..6f7cf57 100644 --- a/squirrelbattle/settings.py +++ b/squirrelbattle/settings.py @@ -74,7 +74,8 @@ class Settings: """ d = json.loads(json_str) for key in d: - setattr(self, key, d[key]) + if hasattr(self, key): + setattr(self, key, d[key]) def dumps_to_string(self) -> str: """ diff --git a/squirrelbattle/term_manager.py b/squirrelbattle/term_manager.py index 6484289..2e74fff 100644 --- a/squirrelbattle/term_manager.py +++ b/squirrelbattle/term_manager.py @@ -21,7 +21,7 @@ class TermManager: # pragma: no cover # make cursor invisible curses.curs_set(False) # Catch mouse events - curses.mousemask(True) + curses.mousemask(curses.ALL_MOUSE_EVENTS | curses.REPORT_MOUSE_POSITION) # Enable colors curses.start_color() diff --git a/squirrelbattle/tests/entities_test.py b/squirrelbattle/tests/entities_test.py index af6f7dd..5729032 100644 --- a/squirrelbattle/tests/entities_test.py +++ b/squirrelbattle/tests/entities_test.py @@ -1,11 +1,12 @@ # Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse # SPDX-License-Identifier: GPL-3.0-or-later - +import random import unittest from squirrelbattle.entities.items import BodySnatchPotion, Bomb, Heart, Item, \ Explosion -from squirrelbattle.entities.monsters import Tiger, Hedgehog, Rabbit, TeddyBear +from squirrelbattle.entities.monsters import Tiger, Hedgehog, Rabbit,\ + TeddyBear, GiantSeaEagle from squirrelbattle.entities.friendly import Trumpet from squirrelbattle.entities.player import Player from squirrelbattle.interfaces import Entity, Map @@ -264,3 +265,17 @@ class TestEntities(unittest.TestCase): player_state = player.save_state() self.assertEqual(player_state["current_xp"], 10) + + def test_critical_hit(self) -> None: + """ + Ensure that critical hits are working. + """ + random.seed(2) # Next random.randint(1, 100) will output 8 + self.player.critical = 10 + sea_eagle = GiantSeaEagle() + self.map.add_entity(sea_eagle) + sea_eagle.move(2, 6) + old_health = sea_eagle.health + self.player.hit(sea_eagle) + self.assertEqual(sea_eagle.health, + old_health - self.player.strength * 4) diff --git a/squirrelbattle/tests/game_test.py b/squirrelbattle/tests/game_test.py index a8e9c59..0901067 100644 --- a/squirrelbattle/tests/game_test.py +++ b/squirrelbattle/tests/game_test.py @@ -1,8 +1,8 @@ # Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse # SPDX-License-Identifier: GPL-3.0-or-later +import curses import os -import random import unittest from ..bootstrap import Bootstrap @@ -11,7 +11,7 @@ from ..display.display_manager import DisplayManager from ..entities.friendly import Merchant, Sunflower, Chest from ..entities.items import Bomb, Heart, Sword, Explosion, Shield, Helmet, \ Chestplate, RingCritical, Bow, FireBallStaff, ScrollofDamage,\ - ScrollofWeakening + ScrollofWeakening, Monocle from ..entities.monsters import Rabbit, GiantSeaEagle from ..entities.player import Player from ..enums import DisplayActions, KeyValues, GameMode @@ -67,6 +67,7 @@ class TestGame(unittest.TestCase): new_state = self.game.save_state() self.assertEqual(old_state, new_state) + self.assertIsNone(self.game.message) # Ensure that the bomb is loaded self.assertTrue(self.game.player.inventory) @@ -258,10 +259,12 @@ class TestGame(unittest.TestCase): self.game.state = GameMode.MAINMENU # Change the color of the artwork - self.game.display_actions(DisplayActions.MOUSE, 0, 10) + self.game.display_actions(DisplayActions.MOUSE, 0, 10, + curses.BUTTON1_CLICKED) # Settings menu - self.game.display_actions(DisplayActions.MOUSE, 25, 21) + self.game.display_actions(DisplayActions.MOUSE, 25, 21, + curses.BUTTON1_CLICKED) self.assertEqual(self.game.main_menu.position, 4) self.assertEqual(self.game.state, GameMode.SETTINGS) @@ -273,11 +276,13 @@ class TestGame(unittest.TestCase): self.game.state = GameMode.INVENTORY # Click nowhere - self.game.display_actions(DisplayActions.MOUSE, 0, 0) + self.game.display_actions(DisplayActions.MOUSE, 0, 0, + curses.BUTTON1_CLICKED) self.assertEqual(self.game.state, GameMode.INVENTORY) # Click on the second item - self.game.display_actions(DisplayActions.MOUSE, 8, 25) + self.game.display_actions(DisplayActions.MOUSE, 8, 25, + curses.BUTTON1_CLICKED) self.assertEqual(self.game.state, GameMode.INVENTORY) self.assertEqual(self.game.inventory_menu.position, 1) @@ -573,12 +578,14 @@ class TestGame(unittest.TestCase): # Buy the second item by clicking on it item = self.game.store_menu.validate() self.assertIn(item, merchant.inventory) - self.game.display_actions(DisplayActions.MOUSE, 7, 25) + self.game.display_actions(DisplayActions.MOUSE, 7, 25, + curses.BUTTON1_CLICKED) self.assertIn(item, self.game.player.inventory) self.assertNotIn(item, merchant.inventory) # Buy a heart merchant.inventory[1] = Heart() + self.game.display_actions(DisplayActions.REFRESH) item = self.game.store_menu.validate() self.assertIn(item, merchant.inventory) self.assertEqual(item, merchant.inventory[1]) @@ -697,19 +704,21 @@ class TestGame(unittest.TestCase): self.game.save_state() ring.unequip() - def test_critical_hit(self) -> None: + def test_monocle(self) -> None: """ - Ensure that critical hits are working. + The player is wearing a monocle, then the stats are displayed. """ - random.seed(2) # Next random.randint(1, 100) will output 8 - self.game.player.critical = 10 + self.game.state = GameMode.PLAY + + monocle = Monocle() + monocle.hold(self.game.player) + monocle.equip() + sea_eagle = GiantSeaEagle() self.game.map.add_entity(sea_eagle) sea_eagle.move(2, 6) - old_health = sea_eagle.health - self.game.player.hit(sea_eagle) - self.assertEqual(sea_eagle.health, - old_health - self.game.player.strength * 4) + + self.game.display_actions(DisplayActions.REFRESH) def test_ladders(self) -> None: """ @@ -748,9 +757,11 @@ class TestGame(unittest.TestCase): """ self.game.state = GameMode.MAINMENU - self.game.display_actions(DisplayActions.MOUSE, 41, 41) + self.game.display_actions(DisplayActions.MOUSE, 41, 41, + curses.BUTTON1_CLICKED) self.assertEqual(self.game.state, GameMode.CREDITS) - self.game.display_actions(DisplayActions.MOUSE, 21, 21) + self.game.display_actions(DisplayActions.MOUSE, 21, 21, + curses.BUTTON1_CLICKED) self.game.display_actions(DisplayActions.REFRESH) self.game.state = GameMode.CREDITS diff --git a/squirrelbattle/tests/translations_test.py b/squirrelbattle/tests/translations_test.py index 4a99e73..bdf0238 100644 --- a/squirrelbattle/tests/translations_test.py +++ b/squirrelbattle/tests/translations_test.py @@ -67,9 +67,18 @@ class TestTranslations(unittest.TestCase): self.assertEqual(_("sunflower"), "tournesol") self.assertEqual(_("teddy bear"), "nounours") self.assertEqual(_("tiger"), "tigre") + self.assertEqual(_("eagle"), "pygargue") self.assertEqual(_("body snatch potion"), "potion d'arrachage de corps") self.assertEqual(_("bomb"), "bombe") self.assertEqual(_("explosion"), "explosion") self.assertEqual(_("heart"), "cœur") self.assertEqual(_("sword"), "épée") + self.assertEqual(_("helmet"), "casque") + self.assertEqual(_("chestplate"), "plastron") + self.assertEqual(_("shield"), "bouclier") + self.assertEqual(_("ring of critical damage"), + "anneau de coup critique") + self.assertEqual(_("ring of more experience"), + "anneau de plus d'expérience") + self.assertEqual(_("monocle"), "monocle")