From ac8c7a0a4c040d6ce2e774df49f921fa12a9e000 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 8 Jan 2021 11:07:38 +0100 Subject: [PATCH 01/13] Only read required keys in settings file --- squirrelbattle/settings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/squirrelbattle/settings.py b/squirrelbattle/settings.py index b5e2c14..549fc5f 100644 --- a/squirrelbattle/settings.py +++ b/squirrelbattle/settings.py @@ -73,7 +73,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: """ From b42f1277b171f31f159d7bda196350c97571c299 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 8 Jan 2021 11:10:10 +0100 Subject: [PATCH 02/13] Exit the game on KeyboardInterrupt (don't log this error) --- squirrelbattle/game.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index ecdfccb..f39cda5 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -94,7 +94,11 @@ 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) From 75e93611c3da02002f52af6c7a1aab9fb730dc85 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 8 Jan 2021 11:21:40 +0100 Subject: [PATCH 03/13] Capture all mouse events and take into account mouse attributes, fixes #58 --- squirrelbattle/display/creditsdisplay.py | 2 +- squirrelbattle/display/display.py | 3 +-- squirrelbattle/display/display_manager.py | 4 ++-- squirrelbattle/display/menudisplay.py | 10 +++++----- squirrelbattle/game.py | 4 ++-- squirrelbattle/term_manager.py | 2 +- squirrelbattle/tests/game_test.py | 23 +++++++++++++++-------- 7 files changed, 27 insertions(+), 21 deletions(-) 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 884c997..94b9ca6 100644 --- a/squirrelbattle/display/display.py +++ b/squirrelbattle/display/display.py @@ -187,12 +187,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 0042615..a1d2ed9 100644 --- a/squirrelbattle/display/display_manager.py +++ b/squirrelbattle/display/display_manager.py @@ -63,7 +63,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. """ @@ -76,7 +76,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 cc73010..6c4d991 100644 --- a/squirrelbattle/display/menudisplay.py +++ b/squirrelbattle/display/menudisplay.py @@ -50,7 +50,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. """ @@ -134,13 +134,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) @@ -189,7 +189,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. """ @@ -232,7 +232,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/game.py b/squirrelbattle/game.py index f39cda5..ba8493f 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -100,8 +100,8 @@ class Game: 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) 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/game_test.py b/squirrelbattle/tests/game_test.py index 0843ae8..dab0e7e 100644 --- a/squirrelbattle/tests/game_test.py +++ b/squirrelbattle/tests/game_test.py @@ -1,6 +1,6 @@ # 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 @@ -257,10 +257,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) @@ -272,11 +274,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) @@ -572,7 +576,8 @@ 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) @@ -747,9 +752,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 From e56bdc16c2a50ba2da266ec7bf1605d1e93b744e Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 8 Jan 2021 11:55:25 +0100 Subject: [PATCH 04/13] Add item description, closes #59 --- squirrelbattle/display/menudisplay.py | 2 ++ squirrelbattle/entities/items.py | 28 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/squirrelbattle/display/menudisplay.py b/squirrelbattle/display/menudisplay.py index 6c4d991..4e08436 100644 --- a/squirrelbattle/display/menudisplay.py +++ b/squirrelbattle/display/menudisplay.py @@ -172,6 +172,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 "")) @@ -217,6 +218,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" diff --git a/squirrelbattle/entities/items.py b/squirrelbattle/entities/items.py index 0436e37..9828fb6 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. @@ -109,6 +116,10 @@ class Heart(Item): super().__init__(name=name, price=price, *args, **kwargs) self.healing = healing + @property + def description(self) -> str: + return "HP+5" + def hold(self, entity: InventoryHolder) -> None: """ When holding a heart, the player is healed and @@ -217,6 +228,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 @@ -261,6 +276,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 @@ -375,6 +395,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 From 571e9db3e8728695b290e8d1f94e1f142459ef9f Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 8 Jan 2021 12:06:28 +0100 Subject: [PATCH 05/13] Fix french translations --- squirrelbattle/entities/items.py | 7 +- squirrelbattle/interfaces.py | 2 +- .../locale/de/LC_MESSAGES/squirrelbattle.po | 95 +++++++++++++------ .../locale/es/LC_MESSAGES/squirrelbattle.po | 95 +++++++++++++------ .../locale/fr/LC_MESSAGES/squirrelbattle.po | 95 +++++++++++++------ squirrelbattle/tests/translations_test.py | 7 ++ 6 files changed, 205 insertions(+), 96 deletions(-) diff --git a/squirrelbattle/entities/items.py b/squirrelbattle/entities/items.py index 9828fb6..dab346c 100644 --- a/squirrelbattle/entities/items.py +++ b/squirrelbattle/entities/items.py @@ -86,7 +86,7 @@ class Item(Entity): """ Returns the list of all item classes. """ - return [BodySnatchPotion, Bomb, Heart, Shield, Sword,\ + return [BodySnatchPotion, Bomb, Heart, Shield, Sword, Chestplate, Helmet, RingCritical, RingXP] def be_sold(self, buyer: InventoryHolder, seller: InventoryHolder) -> bool: @@ -118,7 +118,7 @@ class Heart(Item): @property def description(self) -> str: - return "HP+5" + return f"HP+{self.healing}" def hold(self, entity: InventoryHolder) -> None: """ @@ -304,6 +304,7 @@ class Shield(Armor): super().__init__(name=name, constitution=constitution, price=price, *args, **kwargs) + class Helmet(Armor): """ Class of helmet items, they can be equipped on the head. @@ -319,6 +320,7 @@ class Helmet(Armor): self.held_by.remove_from_inventory(self) self.held_by.equipped_helmet = self + class Chestplate(Armor): """ Class of chestplate items, they can be equipped on the body. @@ -334,6 +336,7 @@ class Chestplate(Armor): self.held_by.remove_from_inventory(self) self.held_by.equipped_armor = self + class BodySnatchPotion(Item): """ The body-snatch potion allows to exchange all characteristics with a random diff --git a/squirrelbattle/interfaces.py b/squirrelbattle/interfaces.py index f1f740b..fa43c73 100644 --- a/squirrelbattle/interfaces.py +++ b/squirrelbattle/interfaces.py @@ -605,7 +605,7 @@ class Entity: from squirrelbattle.entities.monsters import Tiger, Hedgehog, \ Rabbit, TeddyBear, GiantSeaEagle from squirrelbattle.entities.friendly import Merchant, Sunflower, \ - Trumpet + Trumpet return [BodySnatchPotion, Bomb, Heart, Hedgehog, Rabbit, TeddyBear, Sunflower, Tiger, Merchant, GiantSeaEagle, Trumpet] diff --git a/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po index 20aa2a7..1d6d8df 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 12:03+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -21,40 +21,49 @@ msgstr "" 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:40 msgid "Inventory:" msgstr "Bestand:" -#: squirrelbattle/display/statsdisplay.py:52 +#: squirrelbattle/display/statsdisplay.py:57 msgid "Equipped main:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:56 +#: squirrelbattle/display/statsdisplay.py:61 msgid "Equipped secondary:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:61 +#: squirrelbattle/display/statsdisplay.py:66 msgid "Equipped chestplate:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:65 +#: squirrelbattle/display/statsdisplay.py:70 msgid "Equipped helmet:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:72 +#: squirrelbattle/display/statsdisplay.py:77 msgid "YOU ARE DEAD" msgstr "SIE WURDEN GESTORBEN" @@ -63,41 +72,41 @@ msgstr "SIE WURDEN GESTORBEN" 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:347 msgid "" "Some keys are missing in your save file.\n" "Your save seems to be corrupt. It got deleted." @@ -105,7 +114,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:355 msgid "" "No player was found on this map!\n" "Maybe you died?" @@ -113,7 +122,7 @@ msgstr "" "Auf dieser Karte wurde kein Spieler gefunden!\n" "Vielleicht sind Sie gestorben?" -#: squirrelbattle/game.py:356 +#: squirrelbattle/game.py:375 msgid "" "The JSON file is not correct.\n" "Your save seems corrupted. It got deleted." @@ -121,26 +130,26 @@ msgstr "" "Die JSON-Datei ist nicht korrekt.\n" "Ihre Speicherung scheint korrumpiert. Sie wurde gelöscht." -#: squirrelbattle/interfaces.py:452 +#: squirrelbattle/interfaces.py:712 msgid "It's a critical hit!" msgstr "" -#: squirrelbattle/interfaces.py:453 +#: squirrelbattle/interfaces.py:713 #, python-brace-format msgid "{name} hits {opponent}." msgstr "{name} schlägt {opponent}." -#: squirrelbattle/interfaces.py:465 +#: squirrelbattle/interfaces.py:727 #, python-brace-format msgid "{name} takes {damage} damage." msgstr "" -#: squirrelbattle/interfaces.py:467 +#: squirrelbattle/interfaces.py:729 #, python-brace-format msgid "{name} dies." msgstr "{name} stirbt." -#: squirrelbattle/interfaces.py:501 +#: squirrelbattle/interfaces.py:763 #, python-brace-format msgid "{entity} said: {message}" msgstr "{entity} hat gesagt: {message}" @@ -149,8 +158,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 +256,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" @@ -290,3 +303,23 @@ msgstr "Herz" #: squirrelbattle/tests/translations_test.py:75 msgid "sword" msgstr "schwert" + +#: squirrelbattle/tests/translations_test.py:76 +msgid "helmet" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:77 +msgid "chestplate" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:78 +msgid "shield" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:79 +msgid "ring_of_critical_damage" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:81 +msgid "ring_of_more_experience" +msgstr "" diff --git a/squirrelbattle/locale/es/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/es/LC_MESSAGES/squirrelbattle.po index 0bfdac6..9c15730 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 12:03+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -21,40 +21,49 @@ msgstr "" 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:40 msgid "Inventory:" msgstr "Inventorio :" -#: squirrelbattle/display/statsdisplay.py:52 +#: squirrelbattle/display/statsdisplay.py:57 msgid "Equipped main:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:56 +#: squirrelbattle/display/statsdisplay.py:61 msgid "Equipped secondary:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:61 +#: squirrelbattle/display/statsdisplay.py:66 msgid "Equipped chestplate:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:65 +#: squirrelbattle/display/statsdisplay.py:70 msgid "Equipped helmet:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:72 +#: squirrelbattle/display/statsdisplay.py:77 msgid "YOU ARE DEAD" msgstr "ERES MUERTO" @@ -62,41 +71,41 @@ msgstr "ERES MUERTO" 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:347 msgid "" "Some keys are missing in your save file.\n" "Your save seems to be corrupt. It got deleted." @@ -104,7 +113,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:355 msgid "" "No player was found on this map!\n" "Maybe you died?" @@ -112,7 +121,7 @@ msgstr "" "No jugador encontrado sobre la carta !\n" "¿ Quizas murió ?" -#: squirrelbattle/game.py:356 +#: squirrelbattle/game.py:375 msgid "" "The JSON file is not correct.\n" "Your save seems corrupted. It got deleted." @@ -120,26 +129,26 @@ msgstr "" "El JSON archivo no es correcto.\n" "Su guarda parece corrupta. Fue eliminada." -#: squirrelbattle/interfaces.py:452 +#: squirrelbattle/interfaces.py:712 msgid "It's a critical hit!" msgstr "" -#: squirrelbattle/interfaces.py:453 +#: squirrelbattle/interfaces.py:713 #, python-brace-format msgid "{name} hits {opponent}." msgstr "{name} golpea a {opponent}." -#: squirrelbattle/interfaces.py:465 +#: squirrelbattle/interfaces.py:727 #, python-brace-format msgid "{name} takes {damage} damage." msgstr "" -#: squirrelbattle/interfaces.py:467 +#: squirrelbattle/interfaces.py:729 #, python-brace-format msgid "{name} dies." msgstr "{name} se muere." -#: squirrelbattle/interfaces.py:501 +#: squirrelbattle/interfaces.py:763 #, python-brace-format msgid "{entity} said: {message}" msgstr "{entity} dijo : {message}" @@ -148,8 +157,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 +255,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" @@ -289,3 +302,23 @@ msgstr "corazón" #: squirrelbattle/tests/translations_test.py:75 msgid "sword" msgstr "espada" + +#: squirrelbattle/tests/translations_test.py:76 +msgid "helmet" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:77 +msgid "chestplate" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:78 +msgid "shield" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:79 +msgid "ring_of_critical_damage" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:81 +msgid "ring_of_more_experience" +msgstr "" diff --git a/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po index 42172c3..18baf0b 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 12:03+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -21,40 +21,49 @@ 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:40 msgid "Inventory:" msgstr "Inventaire :" -#: squirrelbattle/display/statsdisplay.py:52 +#: squirrelbattle/display/statsdisplay.py:57 msgid "Equipped main:" msgstr "Équipement principal :" -#: squirrelbattle/display/statsdisplay.py:56 +#: squirrelbattle/display/statsdisplay.py:61 msgid "Equipped secondary:" msgstr "Équipement secondaire :" -#: squirrelbattle/display/statsdisplay.py:61 +#: squirrelbattle/display/statsdisplay.py:66 msgid "Equipped chestplate:" msgstr "Plastron équipé :" -#: squirrelbattle/display/statsdisplay.py:65 +#: squirrelbattle/display/statsdisplay.py:70 msgid "Equipped helmet:" msgstr "Casque équipé :" -#: squirrelbattle/display/statsdisplay.py:72 +#: squirrelbattle/display/statsdisplay.py:77 msgid "YOU ARE DEAD" msgstr "VOUS ÊTES MORT" @@ -63,41 +72,41 @@ msgstr "VOUS ÊTES MORT" 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:347 msgid "" "Some keys are missing in your save file.\n" "Your save seems to be corrupt. It got deleted." @@ -105,7 +114,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:355 msgid "" "No player was found on this map!\n" "Maybe you died?" @@ -113,7 +122,7 @@ msgstr "" "Aucun joueur n'a été trouvé sur la carte !\n" "Peut-être êtes-vous mort ?" -#: squirrelbattle/game.py:356 +#: squirrelbattle/game.py:375 msgid "" "The JSON file is not correct.\n" "Your save seems corrupted. It got deleted." @@ -121,26 +130,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:712 msgid "It's a critical hit!" msgstr "C'est un coup critique !" -#: squirrelbattle/interfaces.py:453 +#: squirrelbattle/interfaces.py:713 #, python-brace-format msgid "{name} hits {opponent}." msgstr "{name} frappe {opponent}." -#: squirrelbattle/interfaces.py:465 +#: squirrelbattle/interfaces.py:727 #, python-brace-format msgid "{name} takes {damage} damage." msgstr "{name} prend {damage} dégâts." -#: squirrelbattle/interfaces.py:467 +#: squirrelbattle/interfaces.py:729 #, python-brace-format msgid "{name} dies." msgstr "{name} meurt." -#: squirrelbattle/interfaces.py:501 +#: squirrelbattle/interfaces.py:763 #, python-brace-format msgid "{entity} said: {message}" msgstr "{entity} a dit : {message}" @@ -149,8 +158,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 +256,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" @@ -290,3 +303,23 @@ msgstr "cœur" #: squirrelbattle/tests/translations_test.py:75 msgid "sword" msgstr "épée" + +#: squirrelbattle/tests/translations_test.py:76 +msgid "helmet" +msgstr "casque" + +#: squirrelbattle/tests/translations_test.py:77 +msgid "chestplate" +msgstr "plastron" + +#: squirrelbattle/tests/translations_test.py:78 +msgid "shield" +msgstr "bouclier" + +#: squirrelbattle/tests/translations_test.py:79 +msgid "ring of critical damage" +msgstr "anneau de coup critique" + +#: squirrelbattle/tests/translations_test.py:81 +msgid "ring of more experience" +msgstr "anneau de plus d'expérience" diff --git a/squirrelbattle/tests/translations_test.py b/squirrelbattle/tests/translations_test.py index 4a99e73..1ffa7d3 100644 --- a/squirrelbattle/tests/translations_test.py +++ b/squirrelbattle/tests/translations_test.py @@ -73,3 +73,10 @@ class TestTranslations(unittest.TestCase): 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") From 120ec82d096e33574a4e72082683c5ec7200fe67 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 8 Jan 2021 12:07:13 +0100 Subject: [PATCH 06/13] Helmet needs only one character in squirrel mode, add a trailing space --- squirrelbattle/display/texturepack.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/squirrelbattle/display/texturepack.py b/squirrelbattle/display/texturepack.py index 81302b3..1fa0584 100644 --- a/squirrelbattle/display/texturepack.py +++ b/squirrelbattle/display/texturepack.py @@ -118,7 +118,7 @@ TexturePack.SQUIRREL_PACK = TexturePack( HAZELNUT='🌰', HEART='💜', HEDGEHOG='🦔', - HELMET='⛑️', + HELMET='⛑️ ', PLAYER='🐿️ ️', MERCHANT='🦜', RABBIT='🐇', From f48377e055b10c1573b0c0e5285e5974efa901ef Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 8 Jan 2021 14:23:57 +0100 Subject: [PATCH 07/13] Save floors and visibility, fixes #61 --- squirrelbattle/game.py | 8 ++++++-- squirrelbattle/interfaces.py | 20 +++++++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index ba8493f..837e753 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -335,14 +335,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.") @@ -359,6 +361,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 fa43c73..19ee25c 100644 --- a/squirrelbattle/interfaces.py +++ b/squirrelbattle/interfaces.py @@ -80,18 +80,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() @@ -338,9 +338,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 +352,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): """ From 156e4a7e3aaca95cafc2fe52508193e5991086fb Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 8 Jan 2021 14:51:56 +0100 Subject: [PATCH 08/13] Add a hint to tell the user how to use ladders --- docs/entities/monsters.rst | 2 +- docs/texture-pack.rst | 6 +- squirrelbattle/display/statsdisplay.py | 9 +++ .../locale/de/LC_MESSAGES/squirrelbattle.po | 69 +++++++++++-------- .../locale/es/LC_MESSAGES/squirrelbattle.po | 69 +++++++++++-------- .../locale/fr/LC_MESSAGES/squirrelbattle.po | 59 +++++++++------- squirrelbattle/tests/translations_test.py | 1 + 7 files changed, 132 insertions(+), 83 deletions(-) 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/statsdisplay.py b/squirrelbattle/display/statsdisplay.py index 35ff92c..d148c55 100644 --- a/squirrelbattle/display/statsdisplay.py +++ b/squirrelbattle/display/statsdisplay.py @@ -5,6 +5,7 @@ import curses from ..entities.player import Player from ..game import Game +from ..settings import Settings from ..translations import gettext as _ from .display import Display @@ -14,6 +15,7 @@ class StatsDisplay(Display): A class to handle the display of the stats of the player. """ player: Player + settings: Settings def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -21,6 +23,7 @@ class StatsDisplay(Display): def update(self, game: Game) -> None: self.player = game.player + self.settings = game.settings def update_pad(self) -> None: string2 = f"{_(self.player.name).capitalize()} " \ @@ -77,6 +80,12 @@ 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.settings.KEY_LADDER) + self.addstr(self.pad, self.height - 2, 0, msg, + italic=True, reverse=True) + def display(self) -> None: self.pad.erase() self.update_pad() diff --git a/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po index 1d6d8df..4130e13 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 12:03+0100\n" +"POT-Creation-Date: 2021-01-08 14:47+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,6 +17,12 @@ 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." @@ -43,30 +49,35 @@ msgstr "BESTAND" msgid "STALL" msgstr "STAND" -#: squirrelbattle/display/statsdisplay.py:40 +#: squirrelbattle/display/statsdisplay.py:43 msgid "Inventory:" msgstr "Bestand:" -#: squirrelbattle/display/statsdisplay.py:57 +#: squirrelbattle/display/statsdisplay.py:60 msgid "Equipped main:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:61 +#: squirrelbattle/display/statsdisplay.py:64 msgid "Equipped secondary:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:66 +#: squirrelbattle/display/statsdisplay.py:69 msgid "Equipped chestplate:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:70 +#: squirrelbattle/display/statsdisplay.py:73 msgid "Equipped helmet:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:77 +#: squirrelbattle/display/statsdisplay.py:80 msgid "YOU ARE DEAD" msgstr "SIE WURDEN GESTORBEN" +#: squirrelbattle/display/statsdisplay.py:84 +#, python-brace-format +msgid "Use {key} to use the ladder" +msgstr "" + #. TODO #: squirrelbattle/entities/friendly.py:33 msgid "I don't sell any squirrel" @@ -106,7 +117,7 @@ msgstr "Der Spieler klettert auf dem Stock {floor} hinoben." msgid "The buyer does not have enough money" msgstr "Der Kaufer hat nicht genug Geld" -#: squirrelbattle/game.py:347 +#: squirrelbattle/game.py:349 msgid "" "Some keys are missing in your save file.\n" "Your save seems to be corrupt. It got deleted." @@ -114,7 +125,7 @@ msgstr "" "In Ihrer Speicherdatei fehlen einige Schlüssel.\n" "Ihre Speicherung scheint korrupt zu sein. Es wird gelöscht." -#: squirrelbattle/game.py:355 +#: squirrelbattle/game.py:357 msgid "" "No player was found on this map!\n" "Maybe you died?" @@ -122,7 +133,7 @@ msgstr "" "Auf dieser Karte wurde kein Spieler gefunden!\n" "Vielleicht sind Sie gestorben?" -#: squirrelbattle/game.py:375 +#: squirrelbattle/game.py:379 msgid "" "The JSON file is not correct.\n" "Your save seems corrupted. It got deleted." @@ -130,26 +141,26 @@ msgstr "" "Die JSON-Datei ist nicht korrekt.\n" "Ihre Speicherung scheint korrumpiert. Sie wurde gelöscht." -#: squirrelbattle/interfaces.py:712 +#: squirrelbattle/interfaces.py:718 msgid "It's a critical hit!" msgstr "" -#: squirrelbattle/interfaces.py:713 +#: squirrelbattle/interfaces.py:719 #, python-brace-format msgid "{name} hits {opponent}." msgstr "{name} schlägt {opponent}." -#: squirrelbattle/interfaces.py:727 +#: squirrelbattle/interfaces.py:733 #, python-brace-format msgid "{name} takes {damage} damage." msgstr "" -#: squirrelbattle/interfaces.py:729 +#: squirrelbattle/interfaces.py:735 #, python-brace-format msgid "{name} dies." msgstr "{name} stirbt." -#: squirrelbattle/interfaces.py:763 +#: squirrelbattle/interfaces.py:769 #, python-brace-format msgid "{entity} said: {message}" msgstr "{entity} hat gesagt: {message}" @@ -284,42 +295,46 @@ 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:76 +#: squirrelbattle/tests/translations_test.py:77 msgid "helmet" msgstr "" -#: squirrelbattle/tests/translations_test.py:77 +#: squirrelbattle/tests/translations_test.py:78 msgid "chestplate" msgstr "" -#: squirrelbattle/tests/translations_test.py:78 +#: squirrelbattle/tests/translations_test.py:79 msgid "shield" msgstr "" -#: squirrelbattle/tests/translations_test.py:79 -msgid "ring_of_critical_damage" +#: squirrelbattle/tests/translations_test.py:80 +msgid "ring of critical damage" msgstr "" -#: squirrelbattle/tests/translations_test.py:81 -msgid "ring_of_more_experience" +#: squirrelbattle/tests/translations_test.py:82 +msgid "ring of more experience" msgstr "" diff --git a/squirrelbattle/locale/es/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/es/LC_MESSAGES/squirrelbattle.po index 9c15730..c6e4484 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-08 12:03+0100\n" +"POT-Creation-Date: 2021-01-08 14:47+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,6 +17,12 @@ 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." @@ -43,30 +49,35 @@ msgstr "INVENTORIO" msgid "STALL" msgstr "PUESTO" -#: squirrelbattle/display/statsdisplay.py:40 +#: squirrelbattle/display/statsdisplay.py:43 msgid "Inventory:" msgstr "Inventorio :" -#: squirrelbattle/display/statsdisplay.py:57 +#: squirrelbattle/display/statsdisplay.py:60 msgid "Equipped main:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:61 +#: squirrelbattle/display/statsdisplay.py:64 msgid "Equipped secondary:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:66 +#: squirrelbattle/display/statsdisplay.py:69 msgid "Equipped chestplate:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:70 +#: squirrelbattle/display/statsdisplay.py:73 msgid "Equipped helmet:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:77 +#: squirrelbattle/display/statsdisplay.py:80 msgid "YOU ARE DEAD" msgstr "ERES MUERTO" +#: squirrelbattle/display/statsdisplay.py:84 +#, python-brace-format +msgid "Use {key} to use the ladder" +msgstr "" + #: squirrelbattle/entities/friendly.py:33 msgid "I don't sell any squirrel" msgstr "No vendo ninguna ardilla" @@ -105,7 +116,7 @@ msgstr "" msgid "The buyer does not have enough money" msgstr "El comprador no tiene suficiente dinero" -#: squirrelbattle/game.py:347 +#: squirrelbattle/game.py:349 msgid "" "Some keys are missing in your save file.\n" "Your save seems to be corrupt. It got deleted." @@ -113,7 +124,7 @@ msgstr "" "Algunas claves faltan en su archivo de guarda.\n" "Su guarda parece a ser corruptido. Fue eliminado." -#: squirrelbattle/game.py:355 +#: squirrelbattle/game.py:357 msgid "" "No player was found on this map!\n" "Maybe you died?" @@ -121,7 +132,7 @@ msgstr "" "No jugador encontrado sobre la carta !\n" "¿ Quizas murió ?" -#: squirrelbattle/game.py:375 +#: squirrelbattle/game.py:379 msgid "" "The JSON file is not correct.\n" "Your save seems corrupted. It got deleted." @@ -129,26 +140,26 @@ msgstr "" "El JSON archivo no es correcto.\n" "Su guarda parece corrupta. Fue eliminada." -#: squirrelbattle/interfaces.py:712 +#: squirrelbattle/interfaces.py:718 msgid "It's a critical hit!" msgstr "" -#: squirrelbattle/interfaces.py:713 +#: squirrelbattle/interfaces.py:719 #, python-brace-format msgid "{name} hits {opponent}." msgstr "{name} golpea a {opponent}." -#: squirrelbattle/interfaces.py:727 +#: squirrelbattle/interfaces.py:733 #, python-brace-format msgid "{name} takes {damage} damage." msgstr "" -#: squirrelbattle/interfaces.py:729 +#: squirrelbattle/interfaces.py:735 #, python-brace-format msgid "{name} dies." msgstr "{name} se muere." -#: squirrelbattle/interfaces.py:763 +#: squirrelbattle/interfaces.py:769 #, python-brace-format msgid "{entity} said: {message}" msgstr "{entity} dijo : {message}" @@ -283,42 +294,46 @@ 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:76 +#: squirrelbattle/tests/translations_test.py:77 msgid "helmet" msgstr "" -#: squirrelbattle/tests/translations_test.py:77 +#: squirrelbattle/tests/translations_test.py:78 msgid "chestplate" msgstr "" -#: squirrelbattle/tests/translations_test.py:78 +#: squirrelbattle/tests/translations_test.py:79 msgid "shield" msgstr "" -#: squirrelbattle/tests/translations_test.py:79 -msgid "ring_of_critical_damage" +#: squirrelbattle/tests/translations_test.py:80 +msgid "ring of critical damage" msgstr "" -#: squirrelbattle/tests/translations_test.py:81 -msgid "ring_of_more_experience" +#: squirrelbattle/tests/translations_test.py:82 +msgid "ring of more experience" msgstr "" diff --git a/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po index 18baf0b..fe3f613 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-08 12:03+0100\n" +"POT-Creation-Date: 2021-01-08 14:47+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -43,30 +43,35 @@ msgstr "INVENTAIRE" msgid "STALL" msgstr "STAND" -#: squirrelbattle/display/statsdisplay.py:40 +#: squirrelbattle/display/statsdisplay.py:43 msgid "Inventory:" msgstr "Inventaire :" -#: squirrelbattle/display/statsdisplay.py:57 +#: squirrelbattle/display/statsdisplay.py:60 msgid "Equipped main:" msgstr "Équipement principal :" -#: squirrelbattle/display/statsdisplay.py:61 +#: squirrelbattle/display/statsdisplay.py:64 msgid "Equipped secondary:" msgstr "Équipement secondaire :" -#: squirrelbattle/display/statsdisplay.py:66 +#: squirrelbattle/display/statsdisplay.py:69 msgid "Equipped chestplate:" msgstr "Plastron équipé :" -#: squirrelbattle/display/statsdisplay.py:70 +#: squirrelbattle/display/statsdisplay.py:73 msgid "Equipped helmet:" msgstr "Casque équipé :" -#: squirrelbattle/display/statsdisplay.py:77 +#: squirrelbattle/display/statsdisplay.py:80 msgid "YOU ARE DEAD" msgstr "VOUS ÊTES MORT" +#: squirrelbattle/display/statsdisplay.py:84 +#, python-brace-format +msgid "Use {key} to use the ladder" +msgstr "Appuyez sur {key} pour utiliser l'échelle" + #. TODO #: squirrelbattle/entities/friendly.py:33 msgid "I don't sell any squirrel" @@ -106,7 +111,7 @@ msgstr "Le joueur monte à l'étage {floor}." msgid "The buyer does not have enough money" msgstr "L'acheteur n'a pas assez d'argent" -#: squirrelbattle/game.py:347 +#: squirrelbattle/game.py:349 msgid "" "Some keys are missing in your save file.\n" "Your save seems to be corrupt. It got deleted." @@ -114,7 +119,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:355 +#: squirrelbattle/game.py:357 msgid "" "No player was found on this map!\n" "Maybe you died?" @@ -122,7 +127,7 @@ msgstr "" "Aucun joueur n'a été trouvé sur la carte !\n" "Peut-être êtes-vous mort ?" -#: squirrelbattle/game.py:375 +#: squirrelbattle/game.py:379 msgid "" "The JSON file is not correct.\n" "Your save seems corrupted. It got deleted." @@ -130,26 +135,26 @@ msgstr "" "Le fichier JSON de sauvegarde est incorrect.\n" "Votre sauvegarde semble corrompue. Elle a été supprimée." -#: squirrelbattle/interfaces.py:712 +#: squirrelbattle/interfaces.py:718 msgid "It's a critical hit!" msgstr "C'est un coup critique !" -#: squirrelbattle/interfaces.py:713 +#: squirrelbattle/interfaces.py:719 #, python-brace-format msgid "{name} hits {opponent}." msgstr "{name} frappe {opponent}." -#: squirrelbattle/interfaces.py:727 +#: squirrelbattle/interfaces.py:733 #, python-brace-format msgid "{name} takes {damage} damage." msgstr "{name} prend {damage} dégâts." -#: squirrelbattle/interfaces.py:729 +#: squirrelbattle/interfaces.py:735 #, python-brace-format msgid "{name} dies." msgstr "{name} meurt." -#: squirrelbattle/interfaces.py:763 +#: squirrelbattle/interfaces.py:769 #, python-brace-format msgid "{entity} said: {message}" msgstr "{entity} a dit : {message}" @@ -284,42 +289,46 @@ 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:76 +#: squirrelbattle/tests/translations_test.py:77 msgid "helmet" msgstr "casque" -#: squirrelbattle/tests/translations_test.py:77 +#: squirrelbattle/tests/translations_test.py:78 msgid "chestplate" msgstr "plastron" -#: squirrelbattle/tests/translations_test.py:78 +#: squirrelbattle/tests/translations_test.py:79 msgid "shield" msgstr "bouclier" -#: squirrelbattle/tests/translations_test.py:79 +#: squirrelbattle/tests/translations_test.py:80 msgid "ring of critical damage" msgstr "anneau de coup critique" -#: squirrelbattle/tests/translations_test.py:81 +#: squirrelbattle/tests/translations_test.py:82 msgid "ring of more experience" msgstr "anneau de plus d'expérience" diff --git a/squirrelbattle/tests/translations_test.py b/squirrelbattle/tests/translations_test.py index 1ffa7d3..54581f3 100644 --- a/squirrelbattle/tests/translations_test.py +++ b/squirrelbattle/tests/translations_test.py @@ -67,6 +67,7 @@ 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") From 28a6532a2101ca6fb68a155c675f6f34e2e2f83a Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 8 Jan 2021 14:59:44 +0100 Subject: [PATCH 09/13] Add a hint to tell the user how to talk to friendly entities --- squirrelbattle/display/statsdisplay.py | 12 ++++++++++- .../locale/de/LC_MESSAGES/squirrelbattle.po | 21 ++++++++++++------- .../locale/es/LC_MESSAGES/squirrelbattle.po | 21 ++++++++++++------- .../locale/fr/LC_MESSAGES/squirrelbattle.po | 21 ++++++++++++------- 4 files changed, 50 insertions(+), 25 deletions(-) diff --git a/squirrelbattle/display/statsdisplay.py b/squirrelbattle/display/statsdisplay.py index d148c55..cba8c06 100644 --- a/squirrelbattle/display/statsdisplay.py +++ b/squirrelbattle/display/statsdisplay.py @@ -5,6 +5,7 @@ import curses from ..entities.player import Player from ..game import Game +from ..interfaces import FriendlyEntity from ..settings import Settings from ..translations import gettext as _ from .display import Display @@ -82,10 +83,19 @@ class StatsDisplay(Display): if self.player.map.tiles[self.player.y][self.player.x].is_ladder(): msg = _("Use {key} to use the ladder") \ - .format(key=self.settings.KEY_LADDER) + .format(key=self.settings.KEY_LADDER.upper()) self.addstr(self.pad, self.height - 2, 0, msg, italic=True, reverse=True) + for dy, dx in [(-1, 0), (0, -1), (0, 1), (1, 0)]: + for entity in self.player.map.find_entities(FriendlyEntity): + if entity.y == self.player.y + dy \ + and entity.x == self.player.x + dx: + msg = _("Use {key} then move to talk to the entity") \ + .format(key=self.settings.KEY_CHAT.upper()) + self.addstr(self.pad, self.height - 1, 0, msg, + italic=True, reverse=True) + def display(self) -> None: self.pad.erase() self.update_pad() diff --git a/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po index 4130e13..7bf5e67 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 14:47+0100\n" +"POT-Creation-Date: 2021-01-08 14:59+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -49,35 +49,40 @@ msgstr "BESTAND" msgid "STALL" msgstr "STAND" -#: squirrelbattle/display/statsdisplay.py:43 +#: squirrelbattle/display/statsdisplay.py:44 msgid "Inventory:" msgstr "Bestand:" -#: squirrelbattle/display/statsdisplay.py:60 +#: squirrelbattle/display/statsdisplay.py:61 msgid "Equipped main:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:64 +#: squirrelbattle/display/statsdisplay.py:65 msgid "Equipped secondary:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:69 +#: squirrelbattle/display/statsdisplay.py:70 msgid "Equipped chestplate:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:73 +#: squirrelbattle/display/statsdisplay.py:74 msgid "Equipped helmet:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:80 +#: squirrelbattle/display/statsdisplay.py:81 msgid "YOU ARE DEAD" msgstr "SIE WURDEN GESTORBEN" -#: squirrelbattle/display/statsdisplay.py:84 +#: squirrelbattle/display/statsdisplay.py:85 #, python-brace-format msgid "Use {key} to use the ladder" msgstr "" +#: squirrelbattle/display/statsdisplay.py:94 +#, 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" diff --git a/squirrelbattle/locale/es/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/es/LC_MESSAGES/squirrelbattle.po index c6e4484..9ac1e4e 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-08 14:47+0100\n" +"POT-Creation-Date: 2021-01-08 14:59+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -49,35 +49,40 @@ msgstr "INVENTORIO" msgid "STALL" msgstr "PUESTO" -#: squirrelbattle/display/statsdisplay.py:43 +#: squirrelbattle/display/statsdisplay.py:44 msgid "Inventory:" msgstr "Inventorio :" -#: squirrelbattle/display/statsdisplay.py:60 +#: squirrelbattle/display/statsdisplay.py:61 msgid "Equipped main:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:64 +#: squirrelbattle/display/statsdisplay.py:65 msgid "Equipped secondary:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:69 +#: squirrelbattle/display/statsdisplay.py:70 msgid "Equipped chestplate:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:73 +#: squirrelbattle/display/statsdisplay.py:74 msgid "Equipped helmet:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:80 +#: squirrelbattle/display/statsdisplay.py:81 msgid "YOU ARE DEAD" msgstr "ERES MUERTO" -#: squirrelbattle/display/statsdisplay.py:84 +#: squirrelbattle/display/statsdisplay.py:85 #, python-brace-format msgid "Use {key} to use the ladder" msgstr "" +#: squirrelbattle/display/statsdisplay.py:94 +#, 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" diff --git a/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po index fe3f613..c3c4864 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-08 14:47+0100\n" +"POT-Creation-Date: 2021-01-08 14:59+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -43,35 +43,40 @@ msgstr "INVENTAIRE" msgid "STALL" msgstr "STAND" -#: squirrelbattle/display/statsdisplay.py:43 +#: squirrelbattle/display/statsdisplay.py:44 msgid "Inventory:" msgstr "Inventaire :" -#: squirrelbattle/display/statsdisplay.py:60 +#: squirrelbattle/display/statsdisplay.py:61 msgid "Equipped main:" msgstr "Équipement principal :" -#: squirrelbattle/display/statsdisplay.py:64 +#: squirrelbattle/display/statsdisplay.py:65 msgid "Equipped secondary:" msgstr "Équipement secondaire :" -#: squirrelbattle/display/statsdisplay.py:69 +#: squirrelbattle/display/statsdisplay.py:70 msgid "Equipped chestplate:" msgstr "Plastron équipé :" -#: squirrelbattle/display/statsdisplay.py:73 +#: squirrelbattle/display/statsdisplay.py:74 msgid "Equipped helmet:" msgstr "Casque équipé :" -#: squirrelbattle/display/statsdisplay.py:80 +#: squirrelbattle/display/statsdisplay.py:81 msgid "YOU ARE DEAD" msgstr "VOUS ÊTES MORT" -#: squirrelbattle/display/statsdisplay.py:84 +#: 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 +#, python-brace-format +msgid "Use {key} then move to talk to the entity" +msgstr "Appuyez sur {key} puis déplacez-vous pour parler à l'entité" + #. TODO #: squirrelbattle/entities/friendly.py:33 msgid "I don't sell any squirrel" From 1270640619065dc738812936a045bab5c3a2c69c Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 8 Jan 2021 15:07:35 +0100 Subject: [PATCH 10/13] Change hint whenever the T key is pressed or not --- squirrelbattle/display/statsdisplay.py | 12 ++++++---- .../locale/de/LC_MESSAGES/squirrelbattle.po | 22 ++++++++++------- .../locale/es/LC_MESSAGES/squirrelbattle.po | 22 ++++++++++------- .../locale/fr/LC_MESSAGES/squirrelbattle.po | 24 +++++++++++-------- 4 files changed, 47 insertions(+), 33 deletions(-) diff --git a/squirrelbattle/display/statsdisplay.py b/squirrelbattle/display/statsdisplay.py index cba8c06..91b85b9 100644 --- a/squirrelbattle/display/statsdisplay.py +++ b/squirrelbattle/display/statsdisplay.py @@ -15,16 +15,16 @@ class StatsDisplay(Display): """ A class to handle the display of the stats of the player. """ + game: Game player: Player - settings: Settings def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.pad = self.newpad(self.rows, self.cols) def update(self, game: Game) -> None: + self.game = game self.player = game.player - self.settings = game.settings def update_pad(self) -> None: string2 = f"{_(self.player.name).capitalize()} " \ @@ -83,7 +83,7 @@ class StatsDisplay(Display): if self.player.map.tiles[self.player.y][self.player.x].is_ladder(): msg = _("Use {key} to use the ladder") \ - .format(key=self.settings.KEY_LADDER.upper()) + .format(key=self.game.settings.KEY_LADDER.upper()) self.addstr(self.pad, self.height - 2, 0, msg, italic=True, reverse=True) @@ -91,8 +91,10 @@ class StatsDisplay(Display): for entity in self.player.map.find_entities(FriendlyEntity): if entity.y == self.player.y + dy \ and entity.x == self.player.x + dx: - msg = _("Use {key} then move to talk to the entity") \ - .format(key=self.settings.KEY_CHAT.upper()) + 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) diff --git a/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po index 7bf5e67..e55e2a1 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 14:59+0100\n" +"POT-Creation-Date: 2021-01-08 15:04+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -49,36 +49,40 @@ msgstr "BESTAND" msgid "STALL" msgstr "STAND" -#: squirrelbattle/display/statsdisplay.py:44 +#: squirrelbattle/display/statsdisplay.py:46 msgid "Inventory:" msgstr "Bestand:" -#: squirrelbattle/display/statsdisplay.py:61 +#: squirrelbattle/display/statsdisplay.py:63 msgid "Equipped main:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:65 +#: squirrelbattle/display/statsdisplay.py:67 msgid "Equipped secondary:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:70 +#: squirrelbattle/display/statsdisplay.py:72 msgid "Equipped chestplate:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:74 +#: squirrelbattle/display/statsdisplay.py:76 msgid "Equipped helmet:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:81 +#: squirrelbattle/display/statsdisplay.py:83 msgid "YOU ARE DEAD" msgstr "SIE WURDEN GESTORBEN" -#: squirrelbattle/display/statsdisplay.py:85 +#: squirrelbattle/display/statsdisplay.py:87 #, python-brace-format msgid "Use {key} to use the ladder" msgstr "" -#: squirrelbattle/display/statsdisplay.py:94 +#: squirrelbattle/display/statsdisplay.py:96 +msgid "Move to the friendly entity to talk to it" +msgstr "" + +#: squirrelbattle/display/statsdisplay.py:98 #, python-brace-format msgid "Use {key} then move to talk to the entity" msgstr "" diff --git a/squirrelbattle/locale/es/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/es/LC_MESSAGES/squirrelbattle.po index 9ac1e4e..aaa59cc 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-08 14:59+0100\n" +"POT-Creation-Date: 2021-01-08 15:04+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -49,36 +49,40 @@ msgstr "INVENTORIO" msgid "STALL" msgstr "PUESTO" -#: squirrelbattle/display/statsdisplay.py:44 +#: squirrelbattle/display/statsdisplay.py:46 msgid "Inventory:" msgstr "Inventorio :" -#: squirrelbattle/display/statsdisplay.py:61 +#: squirrelbattle/display/statsdisplay.py:63 msgid "Equipped main:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:65 +#: squirrelbattle/display/statsdisplay.py:67 msgid "Equipped secondary:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:70 +#: squirrelbattle/display/statsdisplay.py:72 msgid "Equipped chestplate:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:74 +#: squirrelbattle/display/statsdisplay.py:76 msgid "Equipped helmet:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:81 +#: squirrelbattle/display/statsdisplay.py:83 msgid "YOU ARE DEAD" msgstr "ERES MUERTO" -#: squirrelbattle/display/statsdisplay.py:85 +#: squirrelbattle/display/statsdisplay.py:87 #, python-brace-format msgid "Use {key} to use the ladder" msgstr "" -#: squirrelbattle/display/statsdisplay.py:94 +#: squirrelbattle/display/statsdisplay.py:96 +msgid "Move to the friendly entity to talk to it" +msgstr "" + +#: squirrelbattle/display/statsdisplay.py:98 #, python-brace-format msgid "Use {key} then move to talk to the entity" msgstr "" diff --git a/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po index c3c4864..f55fa7e 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-08 14:59+0100\n" +"POT-Creation-Date: 2021-01-08 15:04+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -43,39 +43,43 @@ msgstr "INVENTAIRE" msgid "STALL" msgstr "STAND" -#: squirrelbattle/display/statsdisplay.py:44 +#: squirrelbattle/display/statsdisplay.py:46 msgid "Inventory:" msgstr "Inventaire :" -#: squirrelbattle/display/statsdisplay.py:61 +#: squirrelbattle/display/statsdisplay.py:63 msgid "Equipped main:" msgstr "Équipement principal :" -#: squirrelbattle/display/statsdisplay.py:65 +#: squirrelbattle/display/statsdisplay.py:67 msgid "Equipped secondary:" msgstr "Équipement secondaire :" -#: squirrelbattle/display/statsdisplay.py:70 +#: squirrelbattle/display/statsdisplay.py:72 msgid "Equipped chestplate:" msgstr "Plastron équipé :" -#: squirrelbattle/display/statsdisplay.py:74 +#: squirrelbattle/display/statsdisplay.py:76 msgid "Equipped helmet:" msgstr "Casque équipé :" -#: squirrelbattle/display/statsdisplay.py:81 +#: squirrelbattle/display/statsdisplay.py:83 msgid "YOU ARE DEAD" msgstr "VOUS ÊTES MORT" -#: squirrelbattle/display/statsdisplay.py:85 +#: squirrelbattle/display/statsdisplay.py:87 #, python-brace-format msgid "Use {key} to use the ladder" msgstr "Appuyez sur {key} pour utiliser l'échelle" -#: squirrelbattle/display/statsdisplay.py:94 +#: squirrelbattle/display/statsdisplay.py:96 +msgid "Move to the friendly entity to talk to it" +msgstr "Avancez vers l'entité pour lui parler" + +#: squirrelbattle/display/statsdisplay.py:98 #, python-brace-format msgid "Use {key} then move to talk to the entity" -msgstr "Appuyez sur {key} puis déplacez-vous pour parler à l'entité" +msgstr "Appuyez sur {key} puis déplacez-vous pour parler" #. TODO #: squirrelbattle/entities/friendly.py:33 From a497d08f316a5f2d80758fc0c017599eccc397ec Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 8 Jan 2021 15:48:12 +0100 Subject: [PATCH 11/13] Implement the monocle of truth, closes #62 --- squirrelbattle/display/statsdisplay.py | 42 +++++++++++++++---- squirrelbattle/display/texturepack.py | 2 + squirrelbattle/entities/items.py | 10 ++++- squirrelbattle/game.py | 2 +- squirrelbattle/interfaces.py | 16 +++---- .../locale/de/LC_MESSAGES/squirrelbattle.po | 24 ++++++----- .../locale/es/LC_MESSAGES/squirrelbattle.po | 24 ++++++----- .../locale/fr/LC_MESSAGES/squirrelbattle.po | 24 ++++++----- squirrelbattle/tests/game_test.py | 1 + squirrelbattle/tests/translations_test.py | 1 + 10 files changed, 97 insertions(+), 49 deletions(-) diff --git a/squirrelbattle/display/statsdisplay.py b/squirrelbattle/display/statsdisplay.py index 91b85b9..a60f6a2 100644 --- a/squirrelbattle/display/statsdisplay.py +++ b/squirrelbattle/display/statsdisplay.py @@ -3,10 +3,10 @@ import curses +from ..entities.items import Monocle from ..entities.player import Player from ..game import Game -from ..interfaces import FriendlyEntity -from ..settings import Settings +from ..interfaces import FightingEntity from ..translations import gettext as _ from .display import Display @@ -87,16 +87,40 @@ class StatsDisplay(Display): 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(FriendlyEntity): + 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: - 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 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() diff --git a/squirrelbattle/display/texturepack.py b/squirrelbattle/display/texturepack.py index 1fa0584..34c76ee 100644 --- a/squirrelbattle/display/texturepack.py +++ b/squirrelbattle/display/texturepack.py @@ -84,6 +84,7 @@ TexturePack.ASCII_PACK = TexturePack( HEDGEHOG='*', HELMET='0', MERCHANT='M', + MONOCLE='ô', PLAYER='@', RABBIT='Y', RING_OF_CRITICAL_DAMAGE='o', @@ -121,6 +122,7 @@ TexturePack.SQUIRREL_PACK = TexturePack( 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 dab346c..25244cd 100644 --- a/squirrelbattle/entities/items.py +++ b/squirrelbattle/entities/items.py @@ -86,8 +86,8 @@ class Item(Entity): """ Returns the list of all item classes. """ - return [BodySnatchPotion, Bomb, Heart, Shield, Sword, - Chestplate, Helmet, RingCritical, RingXP] + return [BodySnatchPotion, Chestplate, Bomb, Heart, Helmet, Monocle, + Shield, Sword, RingCritical, RingXP] def be_sold(self, buyer: InventoryHolder, seller: InventoryHolder) -> bool: """ @@ -453,3 +453,9 @@ class RingXP(Ring): experience: float = 2, *args, **kwargs): super().__init__(name=name, price=price, experience=experience, *args, **kwargs) + + +class Monocle(Item): + def __init__(self, name: str = "monocle", price: int = 10, + *args, **kwargs): + super().__init__(name=name, price=price, *args, **kwargs) diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index 837e753..5cb3762 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -345,7 +345,7 @@ class Game: try: self.map_index = d["map_index"] self.maps = [Map().load_state(map_dict) for map_dict in d["maps"]] - except KeyError: + except KeyError as e: self.message = _("Some keys are missing in your save file.\n" "Your save seems to be corrupt. It got deleted.") os.unlink(ResourceManager.get_config_path("save.json")) diff --git a/squirrelbattle/interfaces.py b/squirrelbattle/interfaces.py index 19ee25c..900067c 100644 --- a/squirrelbattle/interfaces.py +++ b/squirrelbattle/interfaces.py @@ -635,24 +635,26 @@ class Entity: from squirrelbattle.entities.friendly import Merchant, Sunflower, \ Trumpet from squirrelbattle.entities.items import BodySnatchPotion, Bomb, \ - Heart, Sword, Shield, Chestplate, Helmet, RingCritical, RingXP + Heart, Monocle, Sword, Shield, Chestplate, Helmet, \ + RingCritical, RingXP return { - "Tiger": Tiger, "Bomb": Bomb, + "Chestplate": Chestplate, "Heart": Heart, "BodySnatchPotion": BodySnatchPotion, + "Eagle": GiantSeaEagle, "Hedgehog": Hedgehog, - "Rabbit": Rabbit, - "TeddyBear": TeddyBear, + "Helmet": Helmet, "Player": Player, "Merchant": Merchant, + "Monocle": Monocle, "Sunflower": Sunflower, "Sword": Sword, "Trumpet": Trumpet, - "Eagle": GiantSeaEagle, "Shield": Shield, - "Chestplate": Chestplate, - "Helmet": Helmet, + "TeddyBear": TeddyBear, + "Tiger": Tiger, + "Rabbit": Rabbit, "RingCritical": RingCritical, "RingXP": RingXP, } diff --git a/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po index e55e2a1..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 15:04+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" @@ -49,40 +49,40 @@ msgstr "BESTAND" msgid "STALL" msgstr "STAND" -#: squirrelbattle/display/statsdisplay.py:46 +#: squirrelbattle/display/statsdisplay.py:44 msgid "Inventory:" msgstr "Bestand:" -#: squirrelbattle/display/statsdisplay.py:63 +#: squirrelbattle/display/statsdisplay.py:61 msgid "Equipped main:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:67 +#: squirrelbattle/display/statsdisplay.py:65 msgid "Equipped secondary:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:72 +#: squirrelbattle/display/statsdisplay.py:70 msgid "Equipped chestplate:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:76 +#: squirrelbattle/display/statsdisplay.py:74 msgid "Equipped helmet:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:83 +#: squirrelbattle/display/statsdisplay.py:81 msgid "YOU ARE DEAD" msgstr "SIE WURDEN GESTORBEN" -#: squirrelbattle/display/statsdisplay.py:87 +#: squirrelbattle/display/statsdisplay.py:85 #, python-brace-format msgid "Use {key} to use the ladder" msgstr "" -#: squirrelbattle/display/statsdisplay.py:96 +#: squirrelbattle/display/statsdisplay.py:94 msgid "Move to the friendly entity to talk to it" msgstr "" -#: squirrelbattle/display/statsdisplay.py:98 +#: squirrelbattle/display/statsdisplay.py:96 #, python-brace-format msgid "Use {key} then move to talk to the entity" msgstr "" @@ -347,3 +347,7 @@ 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 aaa59cc..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-08 15:04+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" @@ -49,40 +49,40 @@ msgstr "INVENTORIO" msgid "STALL" msgstr "PUESTO" -#: squirrelbattle/display/statsdisplay.py:46 +#: squirrelbattle/display/statsdisplay.py:44 msgid "Inventory:" msgstr "Inventorio :" -#: squirrelbattle/display/statsdisplay.py:63 +#: squirrelbattle/display/statsdisplay.py:61 msgid "Equipped main:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:67 +#: squirrelbattle/display/statsdisplay.py:65 msgid "Equipped secondary:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:72 +#: squirrelbattle/display/statsdisplay.py:70 msgid "Equipped chestplate:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:76 +#: squirrelbattle/display/statsdisplay.py:74 msgid "Equipped helmet:" msgstr "" -#: squirrelbattle/display/statsdisplay.py:83 +#: squirrelbattle/display/statsdisplay.py:81 msgid "YOU ARE DEAD" msgstr "ERES MUERTO" -#: squirrelbattle/display/statsdisplay.py:87 +#: squirrelbattle/display/statsdisplay.py:85 #, python-brace-format msgid "Use {key} to use the ladder" msgstr "" -#: squirrelbattle/display/statsdisplay.py:96 +#: squirrelbattle/display/statsdisplay.py:94 msgid "Move to the friendly entity to talk to it" msgstr "" -#: squirrelbattle/display/statsdisplay.py:98 +#: squirrelbattle/display/statsdisplay.py:96 #, python-brace-format msgid "Use {key} then move to talk to the entity" msgstr "" @@ -346,3 +346,7 @@ 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 f55fa7e..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-08 15:04+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" @@ -43,40 +43,40 @@ msgstr "INVENTAIRE" msgid "STALL" msgstr "STAND" -#: squirrelbattle/display/statsdisplay.py:46 +#: squirrelbattle/display/statsdisplay.py:44 msgid "Inventory:" msgstr "Inventaire :" -#: squirrelbattle/display/statsdisplay.py:63 +#: squirrelbattle/display/statsdisplay.py:61 msgid "Equipped main:" msgstr "Équipement principal :" -#: squirrelbattle/display/statsdisplay.py:67 +#: squirrelbattle/display/statsdisplay.py:65 msgid "Equipped secondary:" msgstr "Équipement secondaire :" -#: squirrelbattle/display/statsdisplay.py:72 +#: squirrelbattle/display/statsdisplay.py:70 msgid "Equipped chestplate:" msgstr "Plastron équipé :" -#: squirrelbattle/display/statsdisplay.py:76 +#: squirrelbattle/display/statsdisplay.py:74 msgid "Equipped helmet:" msgstr "Casque équipé :" -#: squirrelbattle/display/statsdisplay.py:83 +#: squirrelbattle/display/statsdisplay.py:81 msgid "YOU ARE DEAD" msgstr "VOUS ÊTES MORT" -#: squirrelbattle/display/statsdisplay.py:87 +#: 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:96 +#: 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:98 +#: 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" @@ -341,3 +341,7 @@ 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/tests/game_test.py b/squirrelbattle/tests/game_test.py index dab0e7e..785cd6a 100644 --- a/squirrelbattle/tests/game_test.py +++ b/squirrelbattle/tests/game_test.py @@ -66,6 +66,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) diff --git a/squirrelbattle/tests/translations_test.py b/squirrelbattle/tests/translations_test.py index 54581f3..bdf0238 100644 --- a/squirrelbattle/tests/translations_test.py +++ b/squirrelbattle/tests/translations_test.py @@ -81,3 +81,4 @@ class TestTranslations(unittest.TestCase): "anneau de coup critique") self.assertEqual(_("ring of more experience"), "anneau de plus d'expérience") + self.assertEqual(_("monocle"), "monocle") From 7a4936e6a5443d9408e7e62b97f8c3e7cb8b5a37 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 8 Jan 2021 15:58:54 +0100 Subject: [PATCH 12/13] Test monocles --- squirrelbattle/game.py | 2 +- squirrelbattle/tests/entities_test.py | 19 +++++++++++++++++-- squirrelbattle/tests/game_test.py | 23 +++++++++++++---------- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index 5cb3762..837e753 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -345,7 +345,7 @@ class Game: try: self.map_index = d["map_index"] self.maps = [Map().load_state(map_dict) for map_dict in d["maps"]] - except KeyError as e: + except KeyError: self.message = _("Some keys are missing in your save file.\n" "Your save seems to be corrupt. It got deleted.") os.unlink(ResourceManager.get_config_path("save.json")) 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 785cd6a..a5cb8ae 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 @@ -10,7 +10,7 @@ from ..display.display import Display from ..display.display_manager import DisplayManager from ..entities.friendly import Merchant, Sunflower from ..entities.items import Bomb, Heart, Sword, Explosion, Shield, Helmet, \ - Chestplate, RingCritical + Chestplate, RingCritical, Monocle from ..entities.monsters import GiantSeaEagle from ..entities.player import Player from ..enums import DisplayActions @@ -584,6 +584,7 @@ class TestGame(unittest.TestCase): # 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]) @@ -702,19 +703,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: """ From 46a5dc6931d51d2ba15472541294f999c0debeb4 Mon Sep 17 00:00:00 2001 From: Nicolas Margulies Date: Fri, 8 Jan 2021 17:26:56 +0100 Subject: [PATCH 13/13] Made mobs check if they can see the player --- squirrelbattle/entities/monsters.py | 4 +++- squirrelbattle/interfaces.py | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/squirrelbattle/entities/monsters.py b/squirrelbattle/entities/monsters.py index e22aa51..374b1d6 100644 --- a/squirrelbattle/entities/monsters.py +++ b/squirrelbattle/entities/monsters.py @@ -42,7 +42,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/interfaces.py b/squirrelbattle/interfaces.py index 900067c..17e5cee 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 _ @@ -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)))