Merge branch 'inventory' into 'master'

Inventory

Closes #10

See merge request ynerant/squirrel-battle!36
This commit is contained in:
ynerant 2020-12-05 13:28:05 +01:00
commit 4d60e95165
16 changed files with 453 additions and 412 deletions

View File

@ -11,7 +11,7 @@ with open("README.md", "r") as f:
long_description = f.read() long_description = f.read()
# Compile messages # Compile messages
for language in ["de", "en", "fr"]: for language in ["de", "fr"]:
args = ["msgfmt", "--check-format", args = ["msgfmt", "--check-format",
"-o", f"squirrelbattle/locale/{language}/LC_MESSAGES" "-o", f"squirrelbattle/locale/{language}/LC_MESSAGES"
"/squirrelbattle.mo", "/squirrelbattle.mo",

View File

@ -6,8 +6,8 @@ from squirrelbattle.display.display import VerticalSplit, HorizontalSplit
from squirrelbattle.display.mapdisplay import MapDisplay from squirrelbattle.display.mapdisplay import MapDisplay
from squirrelbattle.display.messagedisplay import MessageDisplay from squirrelbattle.display.messagedisplay import MessageDisplay
from squirrelbattle.display.statsdisplay import StatsDisplay from squirrelbattle.display.statsdisplay import StatsDisplay
from squirrelbattle.display.menudisplay import SettingsMenuDisplay, \ from squirrelbattle.display.menudisplay import MainMenuDisplay, \
MainMenuDisplay InventoryDisplay, SettingsMenuDisplay
from squirrelbattle.display.logsdisplay import LogsDisplay from squirrelbattle.display.logsdisplay import LogsDisplay
from squirrelbattle.display.texturepack import TexturePack from squirrelbattle.display.texturepack import TexturePack
from typing import Any from typing import Any
@ -23,10 +23,11 @@ class DisplayManager:
pack = TexturePack.get_pack(self.game.settings.TEXTURE_PACK) pack = TexturePack.get_pack(self.game.settings.TEXTURE_PACK)
self.mapdisplay = MapDisplay(screen, pack) self.mapdisplay = MapDisplay(screen, pack)
self.statsdisplay = StatsDisplay(screen, pack) self.statsdisplay = StatsDisplay(screen, pack)
self.logsdisplay = LogsDisplay(screen, pack)
self.inventorydisplay = InventoryDisplay(screen, pack)
self.mainmenudisplay = MainMenuDisplay(self.game.main_menu, self.mainmenudisplay = MainMenuDisplay(self.game.main_menu,
screen, pack) screen, pack)
self.settingsmenudisplay = SettingsMenuDisplay(screen, pack) self.settingsmenudisplay = SettingsMenuDisplay(screen, pack)
self.logsdisplay = LogsDisplay(screen, pack)
self.messagedisplay = MessageDisplay(screen=screen, pack=None) self.messagedisplay = MessageDisplay(screen=screen, pack=None)
self.hbar = HorizontalSplit(screen, pack) self.hbar = HorizontalSplit(screen, pack)
self.vbar = VerticalSplit(screen, pack) self.vbar = VerticalSplit(screen, pack)
@ -46,12 +47,14 @@ class DisplayManager:
d.pack = TexturePack.get_pack(self.game.settings.TEXTURE_PACK) d.pack = TexturePack.get_pack(self.game.settings.TEXTURE_PACK)
self.mapdisplay.update_map(self.game.map) self.mapdisplay.update_map(self.game.map)
self.statsdisplay.update_player(self.game.player) self.statsdisplay.update_player(self.game.player)
self.inventorydisplay.update_menu(self.game.inventory_menu)
self.settingsmenudisplay.update_menu(self.game.settings_menu) self.settingsmenudisplay.update_menu(self.game.settings_menu)
self.logsdisplay.update_logs(self.game.logs) self.logsdisplay.update_logs(self.game.logs)
self.messagedisplay.update_message(self.game.message) self.messagedisplay.update_message(self.game.message)
def refresh(self) -> None: def refresh(self) -> None:
if self.game.state == GameMode.PLAY: if self.game.state == GameMode.PLAY \
or self.game.state == GameMode.INVENTORY:
# The map pad has already the good size # The map pad has already the good size
self.mapdisplay.refresh(0, 0, self.rows * 4 // 5, self.mapdisplay.refresh(0, 0, self.rows * 4 // 5,
self.mapdisplay.pack.tile_width self.mapdisplay.pack.tile_width
@ -64,10 +67,15 @@ class DisplayManager:
self.rows // 5 - 1, self.cols * 4 // 5) self.rows // 5 - 1, self.cols * 4 // 5)
self.hbar.refresh(self.rows * 4 // 5, 0, 1, self.cols * 4 // 5) self.hbar.refresh(self.rows * 4 // 5, 0, 1, self.cols * 4 // 5)
self.vbar.refresh(0, self.cols * 4 // 5, self.rows, 1) self.vbar.refresh(0, self.cols * 4 // 5, self.rows, 1)
if self.game.state == GameMode.MAINMENU: if self.game.state == GameMode.INVENTORY:
self.inventorydisplay.refresh(self.rows // 10,
self.cols // 2,
8 * self.rows // 10,
2 * self.cols // 5)
elif self.game.state == GameMode.MAINMENU:
self.mainmenudisplay.refresh(0, 0, self.rows, self.cols) self.mainmenudisplay.refresh(0, 0, self.rows, self.cols)
if self.game.state == GameMode.SETTINGS: elif self.game.state == GameMode.SETTINGS:
self.settingsmenudisplay.refresh(0, 0, self.rows, self.cols - 1) self.settingsmenudisplay.refresh(0, 0, self.rows, self.cols)
if self.game.message: if self.game.message:
height, width = 0, 0 height, width = 0, 0

View File

@ -1,6 +1,6 @@
# Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse # Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import curses
from typing import List from typing import List
from squirrelbattle.menus import Menu, MainMenu from squirrelbattle.menus import Menu, MainMenu
@ -21,8 +21,6 @@ class MenuDisplay(Display):
# Menu values are printed in pad # Menu values are printed in pad
self.pad = self.newpad(self.trueheight, self.truewidth + 2) self.pad = self.newpad(self.trueheight, self.truewidth + 2)
for i in range(self.trueheight):
self.addstr(self.pad, i, 0, " " + self.values[i])
def update_pad(self) -> None: def update_pad(self) -> None:
for i in range(self.trueheight): for i in range(self.trueheight):
@ -100,3 +98,23 @@ class MainMenuDisplay(Display):
self.menudisplay.refresh( self.menudisplay.refresh(
menuy, menux, min(self.menudisplay.preferred_height, menuy, menux, min(self.menudisplay.preferred_height,
self.height - menuy), menuwidth) self.height - menuy), menuwidth)
class InventoryDisplay(MenuDisplay):
def update_pad(self) -> None:
message = _("== INVENTORY ==")
self.addstr(self.pad, 0, (self.width - len(message)) // 2, message,
curses.A_BOLD | curses.A_ITALIC)
for i, item in enumerate(self.menu.values):
rep = self.pack[item.name.upper()]
selection = f"[{rep}]" if i == self.menu.position else f" {rep} "
self.addstr(self.pad, 2 + i, 0, selection
+ " " + _(item.name).capitalize())
@property
def truewidth(self) -> int:
return max(1, self.height if hasattr(self, "height") else 10)
@property
def trueheight(self) -> int:
return 2 + super().trueheight

View File

@ -1,10 +1,12 @@
# Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse # Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from random import randint
from typing import Optional from typing import Optional
from .player import Player from .player import Player
from ..interfaces import Entity, FightingEntity, Map from ..interfaces import Entity, FightingEntity, Map
from ..translations import gettext as _
class Item(Entity): class Item(Entity):
@ -20,16 +22,26 @@ class Item(Entity):
self.held = held self.held = held
self.held_by = held_by self.held_by = held_by
def drop(self, y: int, x: int) -> None: def drop(self) -> None:
""" """
The item is dropped from the inventory onto the floor The item is dropped from the inventory onto the floor
""" """
if self.held: if self.held:
self.held_by.inventory.remove(self) self.held_by.inventory.remove(self)
self.map.add_entity(self)
self.move(self.held_by.y, self.held_by.x)
self.held = False self.held = False
self.held_by = None self.held_by = None
self.map.add_entity(self)
self.move(y, x) def use(self) -> None:
"""
Indicates what should be done when the item is used.
"""
def equip(self) -> None:
"""
Indicates what should be done when the item is equipped.
"""
def hold(self, player: "Player") -> None: def hold(self, player: "Player") -> None:
""" """
@ -81,26 +93,47 @@ class Bomb(Item):
""" """
damage: int = 5 damage: int = 5
exploding: bool exploding: bool
owner: Optional["Player"]
tick: int
def __init__(self, damage: int = 5, exploding: bool = False, def __init__(self, damage: int = 5, exploding: bool = False,
*args, **kwargs): *args, **kwargs):
super().__init__(name="bomb", *args, **kwargs) super().__init__(name="bomb", *args, **kwargs)
self.damage = damage self.damage = damage
self.exploding = exploding self.exploding = exploding
self.tick = 4
self.owner = None
def drop(self, x: int, y: int) -> None: def use(self) -> None:
super().drop(x, y) """
self.exploding = True When the bomb is used, throw it and explodes it.
"""
if self.held:
self.owner = self.held_by
super().drop()
self.exploding = True
def act(self, m: Map) -> None: def act(self, m: Map) -> None:
""" """
Special exploding action of the bomb Special exploding action of the bomb
""" """
if self.exploding: if self.exploding:
for e in m.entities.copy(): if self.tick > 0:
if abs(e.x - self.x) + abs(e.y - self.y) <= 1 and \ # The bomb will explode in <tick> moves
isinstance(e, FightingEntity): self.tick -= 1
e.take_damage(self, self.damage) else:
# The bomb is exploding.
# Each entity that is close to the bomb takes damages.
# The player earn XP if the entity was killed.
log_message = _("Bomb is exploding.")
for e in m.entities.copy():
if abs(e.x - self.x) + abs(e.y - self.y) <= 3 and \
isinstance(e, FightingEntity):
log_message += " " + e.take_damage(self, self.damage)
if e.dead:
self.owner.add_xp(randint(3, 7))
m.logs.add_message(log_message)
m.entities.remove(self)
def save_state(self) -> dict: def save_state(self) -> dict:
""" """

View File

@ -37,6 +37,10 @@ class KeyValues(Enum):
LEFT = auto() LEFT = auto()
RIGHT = auto() RIGHT = auto()
ENTER = auto() ENTER = auto()
INVENTORY = auto()
USE = auto()
EQUIP = auto()
DROP = auto()
SPACE = auto() SPACE = auto()
@staticmethod @staticmethod
@ -58,6 +62,14 @@ class KeyValues(Enum):
return KeyValues.UP return KeyValues.UP
elif key == settings.KEY_ENTER: elif key == settings.KEY_ENTER:
return KeyValues.ENTER return KeyValues.ENTER
elif key == settings.KEY_INVENTORY:
return KeyValues.INVENTORY
elif key == settings.KEY_USE:
return KeyValues.USE
elif key == settings.KEY_EQUIP:
return KeyValues.EQUIP
elif key == settings.KEY_DROP:
return KeyValues.DROP
elif key == ' ': elif key == ' ':
return KeyValues.SPACE return KeyValues.SPACE
return None return None

View File

@ -39,6 +39,7 @@ class Game:
self.main_menu = menus.MainMenu() self.main_menu = menus.MainMenu()
self.settings_menu = menus.SettingsMenu() self.settings_menu = menus.SettingsMenu()
self.settings_menu.update_values(self.settings) self.settings_menu.update_values(self.settings)
self.inventory_menu = menus.InventoryMenu()
self.logs = Logs() self.logs = Logs()
self.message = None self.message = None
@ -54,6 +55,7 @@ class Game:
self.map.add_entity(self.player) self.map.add_entity(self.player)
self.player.move(self.map.start_y, self.map.start_x) self.player.move(self.map.start_y, self.map.start_x)
self.map.spawn_random_entities(randint(3, 10)) self.map.spawn_random_entities(randint(3, 10))
self.inventory_menu.update_player(self.player)
def run(self, screen: Any) -> None: def run(self, screen: Any) -> None:
""" """
@ -82,6 +84,8 @@ class Game:
if self.state == GameMode.PLAY: if self.state == GameMode.PLAY:
self.handle_key_pressed_play(key) self.handle_key_pressed_play(key)
elif self.state == GameMode.INVENTORY:
self.handle_key_pressed_inventory(key)
elif self.state == GameMode.MAINMENU: elif self.state == GameMode.MAINMENU:
self.handle_key_pressed_main_menu(key) self.handle_key_pressed_main_menu(key)
elif self.state == GameMode.SETTINGS: elif self.state == GameMode.SETTINGS:
@ -104,9 +108,34 @@ class Game:
elif key == KeyValues.RIGHT: elif key == KeyValues.RIGHT:
if self.player.move_right(): if self.player.move_right():
self.map.tick() self.map.tick()
elif key == KeyValues.INVENTORY:
self.state = GameMode.INVENTORY
elif key == KeyValues.SPACE: elif key == KeyValues.SPACE:
self.state = GameMode.MAINMENU self.state = GameMode.MAINMENU
def handle_key_pressed_inventory(self, key: KeyValues) -> None:
"""
In the inventory menu, we can interact with items or close the menu.
"""
if key == KeyValues.SPACE or key == KeyValues.INVENTORY:
self.state = GameMode.PLAY
elif key == KeyValues.UP:
self.inventory_menu.go_up()
elif key == KeyValues.DOWN:
self.inventory_menu.go_down()
if self.inventory_menu.values and not self.player.dead:
if key == KeyValues.USE:
self.inventory_menu.validate().use()
elif key == KeyValues.EQUIP:
self.inventory_menu.validate().equip()
elif key == KeyValues.DROP:
self.inventory_menu.validate().drop()
# Ensure that the cursor has a good position
self.inventory_menu.position = min(self.inventory_menu.position,
len(self.inventory_menu.values)
- 1)
def handle_key_pressed_main_menu(self, key: KeyValues) -> None: def handle_key_pressed_main_menu(self, key: KeyValues) -> None:
""" """
In the main menu, we can navigate through options. In the main menu, we can navigate through options.

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: squirrelbattle 3.14.1\n" "Project-Id-Version: squirrelbattle 3.14.1\n"
"Report-Msgid-Bugs-To: squirrel-battle@crans.org\n" "Report-Msgid-Bugs-To: squirrel-battle@crans.org\n"
"POT-Creation-Date: 2020-11-28 16:03+0100\n" "POT-Creation-Date: 2020-12-05 13:11+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,7 +17,70 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: squirrelbattle/tests/game_test.py:284 squirrelbattle/tests/game_test.py:287 #: squirrelbattle/display/menudisplay.py:105
msgid "== INVENTORY =="
msgstr "== BESTAND =="
#: squirrelbattle/display/statsdisplay.py:34
msgid "Inventory:"
msgstr "Bestand:"
#: squirrelbattle/display/statsdisplay.py:39
msgid "YOU ARE DEAD"
msgstr "SIE WURDEN GESTORBEN"
#. 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:129
msgid "Bomb is exploding."
msgstr ""
#: squirrelbattle/game.py:177
msgid ""
"Some keys are missing in your save file.\n"
"Your save seems to be corrupt. It got deleted."
msgstr ""
"In Ihrer Speicherdatei fehlen einige Schlüssel.\n"
"Ihre Speicherung scheint korrupt zu sein. Es wird gelöscht."
#: squirrelbattle/game.py:185
msgid ""
"No player was found on this map!\n"
"Maybe you died?"
msgstr ""
"Auf dieser Karte wurde kein Spieler gefunden!\n"
"Vielleicht sind Sie gestorben?"
#: squirrelbattle/game.py:205
msgid ""
"The JSON file is not correct.\n"
"Your save seems corrupted. It got deleted."
msgstr ""
"Die JSON-Datei ist nicht korrekt.\n"
"Ihre Speicherung scheint korrumpiert. Sie wurde gelöscht."
#: squirrelbattle/interfaces.py:398
#, python-brace-format
msgid "{name} hits {opponent}."
msgstr "{name} schlägt {opponent}."
#: squirrelbattle/interfaces.py:410
#, python-brace-format
msgid "{name} takes {amount} damage."
msgstr "{name} nimmt {amount} Schadenspunkte."
#: squirrelbattle/interfaces.py:412
#, python-brace-format
msgid "{name} dies."
msgstr "{name} stirbt."
#: squirrelbattle/menus.py:72
msgid "Back"
msgstr "Zurück"
#: squirrelbattle/tests/game_test.py:294 squirrelbattle/tests/game_test.py:297
#: squirrelbattle/tests/game_test.py:300
#: squirrelbattle/tests/translations_test.py:16 #: squirrelbattle/tests/translations_test.py:16
msgid "New game" msgid "New game"
msgstr "Neu Spiel" msgstr "Neu Spiel"
@ -79,88 +142,53 @@ msgid "Key to validate a menu"
msgstr "Menütaste" msgstr "Menütaste"
#: squirrelbattle/tests/translations_test.py:45 #: squirrelbattle/tests/translations_test.py:45
msgid "Key used to open the inventory"
msgstr "Bestandtaste"
#: squirrelbattle/tests/translations_test.py:47
msgid "Key used to use an item in the inventory"
msgstr "Taste um eines Objekts im Bestand zu verwenden"
#: squirrelbattle/tests/translations_test.py:49
msgid "Key used to equip an item in the inventory"
msgstr "Taste um eines Objekts im Bestand auszurüsten"
#: squirrelbattle/tests/translations_test.py:51
msgid "Key used to drop an item in the inventory"
msgstr "Taste um eines Objekts im Bestand zu werfen"
#: squirrelbattle/tests/translations_test.py:53
msgid "Texture pack" msgid "Texture pack"
msgstr "Textur-Packung" msgstr "Textur-Packung"
#: squirrelbattle/tests/translations_test.py:46 #: squirrelbattle/tests/translations_test.py:54
msgid "Language" msgid "Language"
msgstr "Sprache" msgstr "Sprache"
#: squirrelbattle/tests/translations_test.py:49 #: squirrelbattle/tests/translations_test.py:57
msgid "player" msgid "player"
msgstr "Spieler" msgstr "Spieler"
#: squirrelbattle/tests/translations_test.py:51 #: squirrelbattle/tests/translations_test.py:59
msgid "tiger" msgid "tiger"
msgstr "Tiger" msgstr "Tiger"
#: squirrelbattle/tests/translations_test.py:52 #: squirrelbattle/tests/translations_test.py:60
msgid "hedgehog" msgid "hedgehog"
msgstr "Igel" msgstr "Igel"
#: squirrelbattle/tests/translations_test.py:53 #: squirrelbattle/tests/translations_test.py:61
msgid "rabbit" msgid "rabbit"
msgstr "Kanninchen" msgstr "Kanninchen"
#: squirrelbattle/tests/translations_test.py:54 #: squirrelbattle/tests/translations_test.py:62
msgid "teddy bear" msgid "teddy bear"
msgstr "Teddybär" msgstr "Teddybär"
#: squirrelbattle/tests/translations_test.py:56 #: squirrelbattle/tests/translations_test.py:64
msgid "bomb" msgid "bomb"
msgstr "Bombe" msgstr "Bombe"
#: squirrelbattle/tests/translations_test.py:57 #: squirrelbattle/tests/translations_test.py:65
msgid "heart" msgid "heart"
msgstr "Herz" msgstr "Herz"
#: squirrelbattle/display/statsdisplay.py:34
msgid "Inventory:"
msgstr "Bestand:"
#: squirrelbattle/display/statsdisplay.py:39
msgid "YOU ARE DEAD"
msgstr "SIE WURDEN GESTORBEN"
#: squirrelbattle/interfaces.py:398
#, python-brace-format
msgid "{name} hits {opponent}."
msgstr "{name} schlägt {opponent}."
#: squirrelbattle/interfaces.py:410
#, python-brace-format
msgid "{name} takes {amount} damage."
msgstr "{name} nimmt {amount} Schadenspunkte."
#: squirrelbattle/interfaces.py:412
#, python-brace-format
msgid "{name} dies."
msgstr "{name} stirbt."
#: squirrelbattle/menus.py:71
msgid "Back"
msgstr "Zurück"
#: squirrelbattle/game.py:148
msgid ""
"Some keys are missing in your save file.\n"
"Your save seems to be corrupt. It got deleted."
msgstr ""
"In Ihrer Speicherdatei fehlen einige Schlüssel.\n"
"Ihre Speicherung scheint korrupt zu sein. Es wird gelöscht."
#: squirrelbattle/game.py:156
msgid ""
"No player was found on this map!\n"
"Maybe you died?"
msgstr ""
"Auf dieser Karte wurde kein Spieler gefunden!\n"
"Vielleicht sind Sie gestorben?"
#: squirrelbattle/game.py:176
msgid ""
"The JSON file is not correct.\n"
"Your save seems corrupted. It got deleted."
msgstr ""
"Die JSON-Datei ist nicht korrekt.\n"
"Ihre Speicherung scheint korrumpiert. Sie wurde gelöscht."

View File

@ -1,195 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ÿnérant, eichhornchen, nicomarg, charlse
# This file is distributed under the same license as the squirrelbattle package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: squirrelbattle 3.14.1\n"
"Report-Msgid-Bugs-To: squirrel-battle@crans.org\n"
"POT-Creation-Date: 2020-11-28 16:03+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: squirrelbattle/display/statsdisplay.py:34
msgid "Inventory:"
msgstr ""
#: squirrelbattle/display/statsdisplay.py:39
msgid "YOU ARE DEAD"
msgstr ""
#: squirrelbattle/interfaces.py:394 squirrelbattle/interfaces.py:398
#, python-brace-format
msgid "{name} hits {opponent}."
msgstr ""
#: squirrelbattle/interfaces.py:405 squirrelbattle/interfaces.py:410
#, python-brace-format
msgid "{name} takes {amount} damage."
msgstr ""
#: squirrelbattle/menus.py:45 squirrelbattle/tests/translations_test.py:14
#: squirrelbattle/tests/game_test.py:284 squirrelbattle/tests/game_test.py:287
#: squirrelbattle/tests/translations_test.py:16
msgid "New game"
msgstr ""
#: squirrelbattle/menus.py:46 squirrelbattle/tests/translations_test.py:15
#: squirrelbattle/tests/translations_test.py:17
msgid "Resume"
msgstr ""
#: squirrelbattle/menus.py:47 squirrelbattle/tests/translations_test.py:17
#: squirrelbattle/tests/translations_test.py:19
msgid "Save"
msgstr ""
#: squirrelbattle/menus.py:48 squirrelbattle/tests/translations_test.py:16
#: squirrelbattle/tests/translations_test.py:18
msgid "Load"
msgstr ""
#: squirrelbattle/menus.py:49 squirrelbattle/tests/translations_test.py:18
#: squirrelbattle/tests/translations_test.py:20
msgid "Settings"
msgstr ""
#: squirrelbattle/menus.py:50 squirrelbattle/tests/translations_test.py:19
#: squirrelbattle/tests/translations_test.py:21
msgid "Exit"
msgstr ""
#: squirrelbattle/menus.py:71
msgid "Back"
msgstr ""
#: squirrelbattle/game.py:147 squirrelbattle/game.py:148
msgid ""
"Some keys are missing in your save file.\n"
"Your save seems to be corrupt. It got deleted."
msgstr ""
#: squirrelbattle/game.py:155 squirrelbattle/game.py:156
msgid ""
"No player was found on this map!\n"
"Maybe you died?"
msgstr ""
#: squirrelbattle/game.py:175 squirrelbattle/game.py:176
msgid ""
"The JSON file is not correct.\n"
"Your save seems corrupted. It got deleted."
msgstr ""
#: squirrelbattle/settings.py:21 squirrelbattle/tests/translations_test.py:21
#: squirrelbattle/tests/translations_test.py:25
#: squirrelbattle/tests/translations_test.py:27
msgid "Main key to move up"
msgstr ""
#: squirrelbattle/settings.py:22 squirrelbattle/tests/translations_test.py:23
#: squirrelbattle/tests/translations_test.py:27
#: squirrelbattle/tests/translations_test.py:29
msgid "Secondary key to move up"
msgstr ""
#: squirrelbattle/settings.py:23 squirrelbattle/tests/translations_test.py:25
#: squirrelbattle/tests/translations_test.py:29
#: squirrelbattle/tests/translations_test.py:31
msgid "Main key to move down"
msgstr ""
#: squirrelbattle/settings.py:24 squirrelbattle/tests/translations_test.py:27
#: squirrelbattle/tests/translations_test.py:31
#: squirrelbattle/tests/translations_test.py:33
msgid "Secondary key to move down"
msgstr ""
#: squirrelbattle/settings.py:25 squirrelbattle/tests/translations_test.py:29
#: squirrelbattle/tests/translations_test.py:33
#: squirrelbattle/tests/translations_test.py:35
msgid "Main key to move left"
msgstr ""
#: squirrelbattle/settings.py:26 squirrelbattle/tests/translations_test.py:31
#: squirrelbattle/tests/translations_test.py:35
#: squirrelbattle/tests/translations_test.py:37
msgid "Secondary key to move left"
msgstr ""
#: squirrelbattle/settings.py:27 squirrelbattle/tests/translations_test.py:33
#: squirrelbattle/tests/translations_test.py:37
#: squirrelbattle/tests/translations_test.py:39
msgid "Main key to move right"
msgstr ""
#: squirrelbattle/settings.py:29 squirrelbattle/tests/translations_test.py:35
#: squirrelbattle/tests/translations_test.py:39
#: squirrelbattle/tests/translations_test.py:41
msgid "Secondary key to move right"
msgstr ""
#: squirrelbattle/settings.py:30 squirrelbattle/tests/translations_test.py:37
#: squirrelbattle/tests/translations_test.py:41
#: squirrelbattle/tests/translations_test.py:43
msgid "Key to validate a menu"
msgstr ""
#: squirrelbattle/settings.py:31 squirrelbattle/tests/translations_test.py:39
#: squirrelbattle/tests/translations_test.py:43
#: squirrelbattle/tests/translations_test.py:45
msgid "Texture pack"
msgstr ""
#: squirrelbattle/settings.py:32 squirrelbattle/tests/translations_test.py:40
#: squirrelbattle/tests/translations_test.py:44
#: squirrelbattle/tests/translations_test.py:46
msgid "Language"
msgstr ""
#: squirrelbattle/interfaces.py:407 squirrelbattle/interfaces.py:412
#, python-brace-format
msgid "{name} dies."
msgstr ""
#: squirrelbattle/tests/translations_test.py:47
#: squirrelbattle/tests/translations_test.py:49
msgid "player"
msgstr ""
#: squirrelbattle/tests/translations_test.py:49
#: squirrelbattle/tests/translations_test.py:51
msgid "tiger"
msgstr ""
#: squirrelbattle/tests/translations_test.py:50
#: squirrelbattle/tests/translations_test.py:52
msgid "hedgehog"
msgstr ""
#: squirrelbattle/tests/translations_test.py:51
#: squirrelbattle/tests/translations_test.py:53
msgid "rabbit"
msgstr ""
#: squirrelbattle/tests/translations_test.py:52
#: squirrelbattle/tests/translations_test.py:54
msgid "teddy bear"
msgstr ""
#: squirrelbattle/tests/translations_test.py:54
#: squirrelbattle/tests/translations_test.py:56
msgid "bomb"
msgstr ""
#: squirrelbattle/tests/translations_test.py:55
#: squirrelbattle/tests/translations_test.py:57
msgid "heart"
msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: squirrelbattle 3.14.1\n" "Project-Id-Version: squirrelbattle 3.14.1\n"
"Report-Msgid-Bugs-To: squirrel-battle@crans.org\n" "Report-Msgid-Bugs-To: squirrel-battle@crans.org\n"
"POT-Creation-Date: 2020-11-28 16:03+0100\n" "POT-Creation-Date: 2020-12-05 13:11+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,6 +17,10 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: squirrelbattle/display/menudisplay.py:105
msgid "== INVENTORY =="
msgstr "== INVENTAIRE =="
#: squirrelbattle/display/statsdisplay.py:34 #: squirrelbattle/display/statsdisplay.py:34
msgid "Inventory:" msgid "Inventory:"
msgstr "Inventaire :" msgstr "Inventaire :"
@ -25,52 +29,14 @@ msgstr "Inventaire :"
msgid "YOU ARE DEAD" msgid "YOU ARE DEAD"
msgstr "VOUS ÊTES MORT" msgstr "VOUS ÊTES MORT"
#: squirrelbattle/interfaces.py:394 squirrelbattle/interfaces.py:398 #. The bomb is exploding.
#, python-brace-format #. Each entity that is close to the bomb takes damages.
msgid "{name} hits {opponent}." #. The player earn XP if the entity was killed.
msgstr "{name} frappe {opponent}." #: squirrelbattle/entities/items.py:129
msgid "Bomb is exploding."
msgstr "La bombe explose."
#: squirrelbattle/interfaces.py:405 squirrelbattle/interfaces.py:410 #: squirrelbattle/game.py:177
#, python-brace-format
msgid "{name} takes {amount} damage."
msgstr "{name} prend {amount} points de dégât."
#: squirrelbattle/menus.py:45 squirrelbattle/tests/translations_test.py:14
#: squirrelbattle/tests/game_test.py:284 squirrelbattle/tests/game_test.py:287
#: squirrelbattle/tests/translations_test.py:16
msgid "New game"
msgstr "Nouvelle partie"
#: squirrelbattle/menus.py:46 squirrelbattle/tests/translations_test.py:15
#: squirrelbattle/tests/translations_test.py:17
msgid "Resume"
msgstr "Continuer"
#: squirrelbattle/menus.py:47 squirrelbattle/tests/translations_test.py:17
#: squirrelbattle/tests/translations_test.py:19
msgid "Save"
msgstr "Sauvegarder"
#: squirrelbattle/menus.py:48 squirrelbattle/tests/translations_test.py:16
#: squirrelbattle/tests/translations_test.py:18
msgid "Load"
msgstr "Charger"
#: squirrelbattle/menus.py:49 squirrelbattle/tests/translations_test.py:18
#: squirrelbattle/tests/translations_test.py:20
msgid "Settings"
msgstr "Paramètres"
#: squirrelbattle/menus.py:50 squirrelbattle/tests/translations_test.py:19
#: squirrelbattle/tests/translations_test.py:21
msgid "Exit"
msgstr "Quitter"
#: squirrelbattle/menus.py:71
msgid "Back"
msgstr "Retour"
#: squirrelbattle/game.py:147 squirrelbattle/game.py:148
msgid "" msgid ""
"Some keys are missing in your save file.\n" "Some keys are missing in your save file.\n"
"Your save seems to be corrupt. It got deleted." "Your save seems to be corrupt. It got deleted."
@ -78,7 +44,7 @@ msgstr ""
"Certaines clés de votre ficher de sauvegarde sont manquantes.\n" "Certaines clés de votre ficher de sauvegarde sont manquantes.\n"
"Votre sauvegarde semble corrompue. Elle a été supprimée." "Votre sauvegarde semble corrompue. Elle a été supprimée."
#: squirrelbattle/game.py:155 squirrelbattle/game.py:156 #: squirrelbattle/game.py:185
msgid "" msgid ""
"No player was found on this map!\n" "No player was found on this map!\n"
"Maybe you died?" "Maybe you died?"
@ -86,7 +52,7 @@ msgstr ""
"Aucun joueur n'a été trouvé sur la carte !\n" "Aucun joueur n'a été trouvé sur la carte !\n"
"Peut-être êtes-vous mort ?" "Peut-être êtes-vous mort ?"
#: squirrelbattle/game.py:175 squirrelbattle/game.py:176 #: squirrelbattle/game.py:205
msgid "" msgid ""
"The JSON file is not correct.\n" "The JSON file is not correct.\n"
"Your save seems corrupted. It got deleted." "Your save seems corrupted. It got deleted."
@ -94,108 +60,135 @@ msgstr ""
"Le fichier JSON de sauvegarde est incorrect.\n" "Le fichier JSON de sauvegarde est incorrect.\n"
"Votre sauvegarde semble corrompue. Elle a été supprimée." "Votre sauvegarde semble corrompue. Elle a été supprimée."
#: squirrelbattle/settings.py:21 squirrelbattle/tests/translations_test.py:21 #: squirrelbattle/interfaces.py:398
#: squirrelbattle/tests/translations_test.py:25 #, python-brace-format
#: squirrelbattle/tests/translations_test.py:27 msgid "{name} hits {opponent}."
msgid "Main key to move up" msgstr "{name} frappe {opponent}."
msgstr "Touche principale pour aller vers le haut"
#: squirrelbattle/settings.py:22 squirrelbattle/tests/translations_test.py:23 #: squirrelbattle/interfaces.py:410
#: squirrelbattle/tests/translations_test.py:27 #, python-brace-format
#: squirrelbattle/tests/translations_test.py:29 msgid "{name} takes {amount} damage."
msgid "Secondary key to move up" msgstr "{name} prend {amount} points de dégât."
msgstr "Touche secondaire pour aller vers le haut"
#: squirrelbattle/settings.py:23 squirrelbattle/tests/translations_test.py:25 #: squirrelbattle/interfaces.py:412
#: squirrelbattle/tests/translations_test.py:29
#: squirrelbattle/tests/translations_test.py:31
msgid "Main key to move down"
msgstr "Touche principale pour aller vers le bas"
#: squirrelbattle/settings.py:24 squirrelbattle/tests/translations_test.py:27
#: squirrelbattle/tests/translations_test.py:31
#: squirrelbattle/tests/translations_test.py:33
msgid "Secondary key to move down"
msgstr "Touche secondaire pour aller vers le bas"
#: squirrelbattle/settings.py:25 squirrelbattle/tests/translations_test.py:29
#: squirrelbattle/tests/translations_test.py:33
#: squirrelbattle/tests/translations_test.py:35
msgid "Main key to move left"
msgstr "Touche principale pour aller vers la gauche"
#: squirrelbattle/settings.py:26 squirrelbattle/tests/translations_test.py:31
#: squirrelbattle/tests/translations_test.py:35
#: squirrelbattle/tests/translations_test.py:37
msgid "Secondary key to move left"
msgstr "Touche secondaire pour aller vers la gauche"
#: squirrelbattle/settings.py:27 squirrelbattle/tests/translations_test.py:33
#: squirrelbattle/tests/translations_test.py:37
#: squirrelbattle/tests/translations_test.py:39
msgid "Main key to move right"
msgstr "Touche principale pour aller vers la droite"
#: squirrelbattle/settings.py:29 squirrelbattle/tests/translations_test.py:35
#: squirrelbattle/tests/translations_test.py:39
#: squirrelbattle/tests/translations_test.py:41
msgid "Secondary key to move right"
msgstr "Touche secondaire pour aller vers la droite"
#: squirrelbattle/settings.py:30 squirrelbattle/tests/translations_test.py:37
#: squirrelbattle/tests/translations_test.py:41
#: squirrelbattle/tests/translations_test.py:43
msgid "Key to validate a menu"
msgstr "Touche pour valider un menu"
#: squirrelbattle/settings.py:31 squirrelbattle/tests/translations_test.py:39
#: squirrelbattle/tests/translations_test.py:43
#: squirrelbattle/tests/translations_test.py:45
msgid "Texture pack"
msgstr "Pack de textures"
#: squirrelbattle/settings.py:32 squirrelbattle/tests/translations_test.py:40
#: squirrelbattle/tests/translations_test.py:44
#: squirrelbattle/tests/translations_test.py:46
msgid "Language"
msgstr "Langue"
#: squirrelbattle/interfaces.py:407 squirrelbattle/interfaces.py:412
#, python-brace-format #, python-brace-format
msgid "{name} dies." msgid "{name} dies."
msgstr "{name} meurt." msgstr "{name} meurt."
#: squirrelbattle/menus.py:72
msgid "Back"
msgstr "Retour"
#: squirrelbattle/tests/game_test.py:294 squirrelbattle/tests/game_test.py:297
#: squirrelbattle/tests/game_test.py:300
#: squirrelbattle/tests/translations_test.py:16
msgid "New game"
msgstr "Nouvelle partie"
#: squirrelbattle/tests/translations_test.py:17
msgid "Resume"
msgstr "Continuer"
#: squirrelbattle/tests/translations_test.py:18
msgid "Load"
msgstr "Charger"
#: squirrelbattle/tests/translations_test.py:19
msgid "Save"
msgstr "Sauvegarder"
#: squirrelbattle/tests/translations_test.py:20
msgid "Settings"
msgstr "Paramètres"
#: squirrelbattle/tests/translations_test.py:21
msgid "Exit"
msgstr "Quitter"
#: squirrelbattle/tests/translations_test.py:27
msgid "Main key to move up"
msgstr "Touche principale pour aller vers le haut"
#: squirrelbattle/tests/translations_test.py:29
msgid "Secondary key to move up"
msgstr "Touche secondaire pour aller vers le haut"
#: squirrelbattle/tests/translations_test.py:31
msgid "Main key to move down"
msgstr "Touche principale pour aller vers le bas"
#: squirrelbattle/tests/translations_test.py:33
msgid "Secondary key to move down"
msgstr "Touche secondaire pour aller vers le bas"
#: squirrelbattle/tests/translations_test.py:35
msgid "Main key to move left"
msgstr "Touche principale pour aller vers la gauche"
#: squirrelbattle/tests/translations_test.py:37
msgid "Secondary key to move left"
msgstr "Touche secondaire pour aller vers la gauche"
#: squirrelbattle/tests/translations_test.py:39
msgid "Main key to move right"
msgstr "Touche principale pour aller vers la droite"
#: squirrelbattle/tests/translations_test.py:41
msgid "Secondary key to move right"
msgstr "Touche secondaire pour aller vers la droite"
#: squirrelbattle/tests/translations_test.py:43
msgid "Key to validate a menu"
msgstr "Touche pour valider un menu"
#: squirrelbattle/tests/translations_test.py:45
msgid "Key used to open the inventory"
msgstr "Touche utilisée pour ouvrir l'inventaire"
#: squirrelbattle/tests/translations_test.py:47 #: squirrelbattle/tests/translations_test.py:47
msgid "Key used to use an item in the inventory"
msgstr "Touche pour utiliser un objet de l'inventaire"
#: squirrelbattle/tests/translations_test.py:49 #: squirrelbattle/tests/translations_test.py:49
msgid "Key used to equip an item in the inventory"
msgstr "Touche pour équiper un objet de l'inventaire"
#: squirrelbattle/tests/translations_test.py:51
msgid "Key used to drop an item in the inventory"
msgstr "Touche pour jeter un objet de l'inventaire"
#: squirrelbattle/tests/translations_test.py:53
msgid "Texture pack"
msgstr "Pack de textures"
#: squirrelbattle/tests/translations_test.py:54
msgid "Language"
msgstr "Langue"
#: squirrelbattle/tests/translations_test.py:57
msgid "player" msgid "player"
msgstr "joueur" msgstr "joueur"
#: squirrelbattle/tests/translations_test.py:49 #: squirrelbattle/tests/translations_test.py:59
#: squirrelbattle/tests/translations_test.py:51
msgid "tiger" msgid "tiger"
msgstr "tigre" msgstr "tigre"
#: squirrelbattle/tests/translations_test.py:50 #: squirrelbattle/tests/translations_test.py:60
#: squirrelbattle/tests/translations_test.py:52
msgid "hedgehog" msgid "hedgehog"
msgstr "hérisson" msgstr "hérisson"
#: squirrelbattle/tests/translations_test.py:51 #: squirrelbattle/tests/translations_test.py:61
#: squirrelbattle/tests/translations_test.py:53
msgid "rabbit" msgid "rabbit"
msgstr "lapin" msgstr "lapin"
#: squirrelbattle/tests/translations_test.py:52 #: squirrelbattle/tests/translations_test.py:62
#: squirrelbattle/tests/translations_test.py:54
msgid "teddy bear" msgid "teddy bear"
msgstr "nounours" msgstr "nounours"
#: squirrelbattle/tests/translations_test.py:54 #: squirrelbattle/tests/translations_test.py:64
#: squirrelbattle/tests/translations_test.py:56
msgid "bomb" msgid "bomb"
msgstr "bombe" msgstr "bombe"
#: squirrelbattle/tests/translations_test.py:55 #: squirrelbattle/tests/translations_test.py:65
#: squirrelbattle/tests/translations_test.py:57
msgid "heart" msgid "heart"
msgstr "cœur" msgstr "cœur"

View File

@ -5,6 +5,7 @@ from enum import Enum
from typing import Any, Optional from typing import Any, Optional
from .display.texturepack import TexturePack from .display.texturepack import TexturePack
from .entities.player import Player
from .enums import GameMode, KeyValues, DisplayActions from .enums import GameMode, KeyValues, DisplayActions
from .settings import Settings from .settings import Settings
from .translations import gettext as _, Translator from .translations import gettext as _, Translator
@ -115,3 +116,14 @@ class SettingsMenu(Menu):
game.settings.write_settings() game.settings.write_settings()
self.waiting_for_key = False self.waiting_for_key = False
self.update_values(game.settings) self.update_values(game.settings)
class InventoryMenu(Menu):
player: Player
def update_player(self, player: Player) -> None:
self.player = player
@property
def values(self) -> list:
return self.player.inventory

View File

@ -27,6 +27,10 @@ class Settings:
self.KEY_RIGHT_PRIMARY = ['d', 'Main key to move right'] self.KEY_RIGHT_PRIMARY = ['d', 'Main key to move right']
self.KEY_RIGHT_SECONDARY = ['KEY_RIGHT', 'Secondary key to move right'] self.KEY_RIGHT_SECONDARY = ['KEY_RIGHT', 'Secondary key to move right']
self.KEY_ENTER = ['\n', 'Key to validate a menu'] self.KEY_ENTER = ['\n', 'Key to validate a menu']
self.KEY_INVENTORY = ['i', 'Key used to open the inventory']
self.KEY_USE = ['u', 'Key used to use an item in the inventory']
self.KEY_EQUIP = ['e', 'Key used to equip an item in the inventory']
self.KEY_DROP = ['r', 'Key used to drop an item in the inventory']
self.TEXTURE_PACK = ['ascii', 'Texture pack'] self.TEXTURE_PACK = ['ascii', 'Texture pack']
self.LOCALE = [locale.getlocale()[0][:2], 'Language'] self.LOCALE = [locale.getlocale()[0][:2], 'Language']

View File

@ -97,12 +97,13 @@ class TestEntities(unittest.TestCase):
self.assertFalse(item.held) self.assertFalse(item.held)
item.hold(self.player) item.hold(self.player)
self.assertTrue(item.held) self.assertTrue(item.held)
item.drop(2, 6) item.drop()
self.assertEqual(item.y, 2) self.assertEqual(item.y, 1)
self.assertEqual(item.x, 6) self.assertEqual(item.x, 6)
# Pick up item # Pick up item
self.player.move_down() self.player.move_left()
self.player.move_right()
self.assertTrue(item.held) self.assertTrue(item.held)
self.assertEqual(item.held_by, self.player) self.assertEqual(item.held_by, self.player)
self.assertIn(item, self.player.inventory) self.assertIn(item, self.player.inventory)
@ -125,10 +126,14 @@ class TestEntities(unittest.TestCase):
item.act(self.map) item.act(self.map)
self.assertFalse(hedgehog.dead) self.assertFalse(hedgehog.dead)
self.assertFalse(teddy_bear.dead) self.assertFalse(teddy_bear.dead)
item.drop(42, 42) self.player.move(42, 42)
item.hold(self.player)
item.use()
self.assertEqual(item.y, 42) self.assertEqual(item.y, 42)
self.assertEqual(item.x, 42) self.assertEqual(item.x, 42)
item.act(self.map) # Wait for the explosion
for ignored in range(5):
item.act(self.map)
self.assertTrue(hedgehog.dead) self.assertTrue(hedgehog.dead)
self.assertTrue(teddy_bear.dead) self.assertTrue(teddy_bear.dead)
bomb_state = item.save_state() bomb_state = item.save_state()

View File

@ -7,6 +7,7 @@ import unittest
from ..bootstrap import Bootstrap from ..bootstrap import Bootstrap
from ..display.display import Display from ..display.display import Display
from ..display.display_manager import DisplayManager from ..display.display_manager import DisplayManager
from ..entities.items import Bomb
from ..entities.player import Player from ..entities.player import Player
from ..enums import DisplayActions from ..enums import DisplayActions
from ..game import Game, KeyValues, GameMode from ..game import Game, KeyValues, GameMode
@ -107,6 +108,18 @@ class TestGame(unittest.TestCase):
self.assertEqual(KeyValues.translate_key( self.assertEqual(KeyValues.translate_key(
self.game.settings.KEY_ENTER, self.game.settings), self.game.settings.KEY_ENTER, self.game.settings),
KeyValues.ENTER) KeyValues.ENTER)
self.assertEqual(KeyValues.translate_key(
self.game.settings.KEY_INVENTORY, self.game.settings),
KeyValues.INVENTORY)
self.assertEqual(KeyValues.translate_key(
self.game.settings.KEY_USE, self.game.settings),
KeyValues.USE)
self.assertEqual(KeyValues.translate_key(
self.game.settings.KEY_EQUIP, self.game.settings),
KeyValues.EQUIP)
self.assertEqual(KeyValues.translate_key(
self.game.settings.KEY_DROP, self.game.settings),
KeyValues.DROP)
self.assertEqual(KeyValues.translate_key(' ', self.game.settings), self.assertEqual(KeyValues.translate_key(' ', self.game.settings),
KeyValues.SPACE) KeyValues.SPACE)
self.assertEqual(KeyValues.translate_key('plop', self.game.settings), self.assertEqual(KeyValues.translate_key('plop', self.game.settings),
@ -261,11 +274,8 @@ class TestGame(unittest.TestCase):
self.assertEqual(self.game.settings.KEY_LEFT_PRIMARY, 'a') self.assertEqual(self.game.settings.KEY_LEFT_PRIMARY, 'a')
# Navigate to "texture pack" # Navigate to "texture pack"
self.game.handle_key_pressed(KeyValues.DOWN) for ignored in range(9):
self.game.handle_key_pressed(KeyValues.DOWN) self.game.handle_key_pressed(KeyValues.DOWN)
self.game.handle_key_pressed(KeyValues.DOWN)
self.game.handle_key_pressed(KeyValues.DOWN)
self.game.handle_key_pressed(KeyValues.DOWN)
# Change texture pack # Change texture pack
self.assertEqual(self.game.settings.TEXTURE_PACK, "ascii") self.assertEqual(self.game.settings.TEXTURE_PACK, "ascii")
@ -337,3 +347,64 @@ class TestGame(unittest.TestCase):
self.game.display_actions(DisplayActions.REFRESH) self.game.display_actions(DisplayActions.REFRESH)
self.game.handle_key_pressed(None, "random key") self.game.handle_key_pressed(None, "random key")
self.assertIsNone(self.game.message) self.assertIsNone(self.game.message)
def test_inventory_menu(self) -> None:
"""
Open the inventory menu and interact with items.
"""
self.game.state = GameMode.PLAY
# Open and close the inventory
self.game.handle_key_pressed(KeyValues.INVENTORY)
self.assertEqual(self.game.state, GameMode.INVENTORY)
self.game.handle_key_pressed(KeyValues.SPACE)
self.assertEqual(self.game.state, GameMode.PLAY)
# Add five bombs in the inventory
for ignored in range(5):
bomb = Bomb()
bomb.map = self.game.map
bomb.map.add_entity(bomb)
bomb.hold(self.game.player)
self.game.handle_key_pressed(KeyValues.INVENTORY)
self.assertEqual(self.game.state, GameMode.INVENTORY)
# Navigate in the menu
self.game.handle_key_pressed(KeyValues.DOWN)
self.game.handle_key_pressed(KeyValues.DOWN)
self.game.handle_key_pressed(KeyValues.DOWN)
self.assertEqual(self.game.inventory_menu.position, 3)
self.game.handle_key_pressed(KeyValues.DOWN)
self.game.handle_key_pressed(KeyValues.DOWN)
self.game.handle_key_pressed(KeyValues.UP)
self.game.handle_key_pressed(KeyValues.DOWN)
self.assertEqual(self.game.inventory_menu.position, 4)
# Equip key does nothing
self.game.handle_key_pressed(KeyValues.EQUIP)
# Drop an item
bomb = self.game.player.inventory[-1]
self.assertEqual(self.game.inventory_menu.validate(), bomb)
self.assertTrue(bomb.held)
self.assertEqual(bomb.held_by, self.game.player)
self.game.handle_key_pressed(KeyValues.DROP)
self.assertFalse(bomb.held)
self.assertIsNone(bomb.held_by)
self.assertIsNone(bomb.owner)
self.assertFalse(bomb.exploding)
self.assertEqual(bomb.y, self.game.player.y)
self.assertEqual(bomb.x, self.game.player.x)
# Use the bomb
bomb = self.game.player.inventory[-1]
self.assertEqual(self.game.inventory_menu.validate(), bomb)
self.assertTrue(bomb.held)
self.assertEqual(bomb.held_by, self.game.player)
self.game.handle_key_pressed(KeyValues.USE)
self.assertFalse(bomb.held)
self.assertIsNone(bomb.held_by)
self.assertEqual(bomb.owner, self.game.player)
self.assertTrue(bomb.exploding)
self.assertEqual(bomb.y, self.game.player.y)
self.assertEqual(bomb.x, self.game.player.x)

View File

@ -4,9 +4,13 @@
import unittest import unittest
from squirrelbattle.settings import Settings from squirrelbattle.settings import Settings
from squirrelbattle.translations import Translator
class TestSettings(unittest.TestCase): class TestSettings(unittest.TestCase):
def setUp(self) -> None:
Translator.setlocale("en")
def test_settings(self) -> None: def test_settings(self) -> None:
""" """
Ensure that settings are well loaded. Ensure that settings are well loaded.

View File

@ -42,6 +42,14 @@ class TestTranslations(unittest.TestCase):
"Touche secondaire pour aller vers la droite") "Touche secondaire pour aller vers la droite")
self.assertEqual(_("Key to validate a menu"), self.assertEqual(_("Key to validate a menu"),
"Touche pour valider un menu") "Touche pour valider un menu")
self.assertEqual(_("Key used to open the inventory"),
"Touche utilisée pour ouvrir l'inventaire")
self.assertEqual(_("Key used to use an item in the inventory"),
"Touche pour utiliser un objet de l'inventaire")
self.assertEqual(_("Key used to equip an item in the inventory"),
"Touche pour équiper un objet de l'inventaire")
self.assertEqual(_("Key used to drop an item in the inventory"),
"Touche pour jeter un objet de l'inventaire")
self.assertEqual(_("Texture pack"), "Pack de textures") self.assertEqual(_("Texture pack"), "Pack de textures")
self.assertEqual(_("Language"), "Langue") self.assertEqual(_("Language"), "Langue")

View File

@ -3,6 +3,7 @@
import gettext as gt import gettext as gt
import os import os
import re
import subprocess import subprocess
from pathlib import Path from pathlib import Path
from typing import Any, List from typing import Any, List
@ -53,6 +54,9 @@ class Translator:
Analyse all strings in the project and extract them. Analyse all strings in the project and extract them.
""" """
for language in cls.SUPPORTED_LOCALES: for language in cls.SUPPORTED_LOCALES:
if language == "en":
# Don't translate the main language
continue
file_name = Path(__file__).parent / "locale" / language \ file_name = Path(__file__).parent / "locale" / language \
/ "LC_MESSAGES" / "squirrelbattle.po" / "LC_MESSAGES" / "squirrelbattle.po"
args = ["find", "squirrelbattle", "-iname", "*.py"] args = ["find", "squirrelbattle", "-iname", "*.py"]
@ -65,9 +69,14 @@ class Translator:
"--copyright-holder=ÿnérant, eichhornchen, " "--copyright-holder=ÿnérant, eichhornchen, "
"nicomarg, charlse", "nicomarg, charlse",
"--msgid-bugs-address=squirrel-battle@crans.org", "--msgid-bugs-address=squirrel-battle@crans.org",
"--sort-by-file",
"-o", file_name] "-o", file_name]
if file_name.is_file(): if file_name.is_file():
args.append("--join-existing") args.append("--join-existing")
with open(file_name, "r") as f:
content = f.read()
with open(file_name, "w") as f:
f.write(re.sub("#:.*\n", "", content))
print(f"Make {language} messages...") print(f"Make {language} messages...")
subprocess.Popen(args, stdin=find.stdout).wait() subprocess.Popen(args, stdin=find.stdout).wait()
@ -77,6 +86,8 @@ class Translator:
Compile translation messages from source files. Compile translation messages from source files.
""" """
for language in cls.SUPPORTED_LOCALES: for language in cls.SUPPORTED_LOCALES:
if language == "en":
continue
args = ["msgfmt", "--check-format", args = ["msgfmt", "--check-format",
"-o", Path(__file__).parent / "locale" / language "-o", Path(__file__).parent / "locale" / language
/ "LC_MESSAGES" / "squirrelbattle.mo", / "LC_MESSAGES" / "squirrelbattle.mo",