Merge branch 'ladders' into 'master'

Ladders

See merge request ynerant/squirrel-battle!53
This commit is contained in:
ynerant 2021-01-06 18:01:36 +01:00
commit 00a4dec6a4
14 changed files with 279 additions and 109 deletions

View File

@ -1,8 +1,8 @@
1 6
####### #############
#.....# #...........#
#.H...# #...........#
#.....# #####...........#
#.....# #...............#
#.....# #............H..#
#.##### #.###...........#
#.# #.# #...........#
#.# #.# #############

View File

@ -1,6 +1,6 @@
1 17
########### #########
#.........# #.......#
#....H....# #.......#
#.........# ############.......#
#.........###############..........#.......##############
#.........#........................#....................#
@ -13,7 +13,7 @@
########.##########......# #.........# #.........#
#...........##......# #.........# #.........#
#...........##......# #.........# #.........#
#...........##......# #.........# ################.######
#...........##..H...# #.........# ################.######
#...........##......# #.........# #.................############
#...........##......# ########.########.......#.........#..........#
#...........##......# #...............#.......#.........#..........#

View File

@ -23,8 +23,11 @@ class MapDisplay(Display):
def update_pad(self) -> None:
self.pad.resize(500, 500)
self.addstr(self.pad, 0, 0, self.map.draw_string(self.pack),
self.pack.tile_fg_color, self.pack.tile_bg_color)
for i in range(self.map.height):
for j in range(self.map.width):
self.addstr(self.pad, i, j * self.pack.tile_width,
self.map.tiles[i][j].char(self.pack),
*self.map.tiles[i][j].color(self.pack))
for e in self.map.entities:
self.addstr(self.pad, e.y, self.pack.tile_width * e.x,
self.pack[e.name.upper()],

View File

@ -23,15 +23,17 @@ class StatsDisplay(Display):
self.player = game.player
def update_pad(self) -> None:
string2 = "Player -- LVL {}\nEXP {}/{}\nHP {}/{}"\
.format(self.player.level, self.player.current_xp,
self.player.max_xp, self.player.health,
self.player.maxhealth)
string2 = f"{_(self.player.name).capitalize()} " \
f"-- LVL {self.player.level} -- " \
f"FLOOR {-self.player.map.floor}\n" \
f"EXP {self.player.current_xp}/{self.player.max_xp}\n" \
f"HP {self.player.health}/{self.player.maxhealth}"
self.addstr(self.pad, 0, 0, string2)
string3 = "STR {}\nINT {}\nCHR {}\nDEX {}\nCON {}"\
.format(self.player.strength,
self.player.intelligence, self.player.charisma,
self.player.dexterity, self.player.constitution)
string3 = f"STR {self.player.strength}\n" \
f"INT {self.player.intelligence}\n" \
f"CHR {self.player.charisma}\n" \
f"DEX {self.player.dexterity}\n" \
f"CON {self.player.constitution}"
self.addstr(self.pad, 3, 0, string3)
inventory_str = _("Inventory:") + " "

View File

@ -68,6 +68,7 @@ TexturePack.ASCII_PACK = TexturePack(
EMPTY=' ',
EXPLOSION='%',
FLOOR='.',
LADDER='H',
HAZELNUT='¤',
HEART='',
HEDGEHOG='*',
@ -95,6 +96,7 @@ TexturePack.SQUIRREL_PACK = TexturePack(
EMPTY=' ',
EXPLOSION='💥',
FLOOR='██',
LADDER=('🪜', curses.COLOR_WHITE, curses.COLOR_WHITE),
HAZELNUT='🌰',
HEART='💜',
HEDGEHOG='🦔',

View File

@ -47,6 +47,7 @@ class KeyValues(Enum):
SPACE = auto()
CHAT = auto()
WAIT = auto()
LADDER = auto()
@staticmethod
def translate_key(key: str, settings: Settings) -> Optional["KeyValues"]:
@ -81,4 +82,6 @@ class KeyValues(Enum):
return KeyValues.CHAT
elif key == settings.KEY_WAIT:
return KeyValues.WAIT
elif key == settings.KEY_LADDER:
return KeyValues.LADDER
return None

View File

@ -3,7 +3,7 @@
from json import JSONDecodeError
from random import randint
from typing import Any, Optional
from typing import Any, Optional, List
import curses
import json
import os
@ -22,7 +22,8 @@ class Game:
"""
The game object controls all actions in the game.
"""
map: Map
maps: List[Map]
map_index: int
player: Player
screen: Any
# display_actions is a display interface set by the bootstrapper
@ -52,7 +53,9 @@ class Game:
Creates a new game on the screen.
"""
# TODO generate a new map procedurally
self.map = Map.load(ResourceManager.get_asset_path("example_map_2.txt"))
self.maps = []
self.map_index = 0
self.map = Map.load(ResourceManager.get_asset_path("example_map.txt"))
self.map.logs = self.logs
self.logs.clear()
self.player = Player()
@ -61,6 +64,24 @@ class Game:
self.map.spawn_random_entities(randint(3, 10))
self.inventory_menu.update_player(self.player)
@property
def map(self) -> Map:
"""
Return the current map where the user is.
"""
return self.maps[self.map_index]
@map.setter
def map(self, m: Map) -> None:
"""
Redefine the current map.
"""
if len(self.maps) == self.map_index:
# Insert new map
self.maps.append(m)
# Redefine the current map
self.maps[self.map_index] = m
def run(self, screen: Any) -> None: # pragma no cover
"""
Main infinite loop.
@ -135,6 +156,54 @@ class Game:
self.waiting_for_friendly_key = True
elif key == KeyValues.WAIT:
self.map.tick(self.player)
elif key == KeyValues.LADDER:
self.handle_ladder()
def handle_ladder(self) -> None:
"""
The player pressed the ladder key to switch map
"""
# On a ladder, we switch level
y, x = self.player.y, self.player.x
if not self.map.tiles[y][x].is_ladder():
return
# We move up on the ladder of the beginning,
# down at the end of the stage
move_down = y != self.map.start_y and x != self.map.start_x
old_map = self.map
self.map_index += 1 if move_down else -1
if self.map_index == -1:
self.map_index = 0
return
while self.map_index >= len(self.maps):
# TODO: generate a new map
self.maps.append(Map.load(ResourceManager.get_asset_path(
"example_map_2.txt")))
new_map = self.map
new_map.floor = self.map_index
old_map.remove_entity(self.player)
new_map.add_entity(self.player)
if move_down:
self.player.move(self.map.start_y, self.map.start_x)
self.logs.add_message(
_("The player climbs down to the floor {floor}.")
.format(floor=-self.map_index))
else:
# Find the ladder of the end of the game
ladder_y, ladder_x = -1, -1
for y in range(self.map.height):
for x in range(self.map.width):
if (y, x) != (self.map.start_y, self.map.start_x) \
and self.map.tiles[y][x].is_ladder():
ladder_y, ladder_x = y, x
break
self.player.move(ladder_y, ladder_x)
self.logs.add_message(
_("The player climbs up the floor {floor}.")
.format(floor=-self.map_index))
self.display_actions(DisplayActions.UPDATE)
def handle_friendly_entity_chat(self, key: KeyValues) -> None:
"""

View File

@ -37,6 +37,7 @@ class Map:
The Map object represents a with its width, height
and tiles, that have their custom properties.
"""
floor: int
width: int
height: int
start_y: int
@ -51,6 +52,7 @@ class Map:
def __init__(self, width: int, height: int, tiles: list,
start_y: int, start_x: int):
self.floor = 0
self.width = width
self.height = height
self.start_y = start_y
@ -146,7 +148,6 @@ class Map:
Puts randomly {count} entities on the map, only on empty ground tiles.
"""
for ignored in range(count):
y, x = 0, 0
while True:
y, x = randint(0, self.height - 1), randint(0, self.width - 1)
tile = self.tiles[y][x]
@ -207,6 +208,7 @@ class Tile(Enum):
EMPTY = auto()
WALL = auto()
FLOOR = auto()
LADDER = auto()
@staticmethod
def from_ascii_char(ch: str) -> "Tile":
@ -223,7 +225,16 @@ class Tile(Enum):
Translates a Tile to the corresponding character according
to the texture pack.
"""
return getattr(pack, self.name)
val = getattr(pack, self.name)
return val[0] if isinstance(val, tuple) else val
def color(self, pack: TexturePack) -> Tuple[int, int]:
"""
Retrieve the tuple (fg_color, bg_color) of the current Tile.
"""
val = getattr(pack, self.name)
return (val[1], val[2]) if isinstance(val, tuple) else \
(pack.tile_fg_color, pack.tile_bg_color)
def is_wall(self) -> bool:
"""
@ -231,6 +242,12 @@ class Tile(Enum):
"""
return self == Tile.WALL
def is_ladder(self) -> bool:
"""
Is this Tile a ladder?
"""
return self == Tile.LADDER
def can_walk(self) -> bool:
"""
Checks if an entity (player or not) can move in this tile.

View File

@ -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: 2020-12-12 18:02+0100\n"
"POT-Creation-Date: 2021-01-06 15:19+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"
@ -17,19 +17,19 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: squirrelbattle/display/menudisplay.py:139
#: squirrelbattle/display/menudisplay.py:160
msgid "INVENTORY"
msgstr "BESTAND"
#: squirrelbattle/display/menudisplay.py:164
#: squirrelbattle/display/menudisplay.py:202
msgid "STALL"
msgstr "STAND"
#: squirrelbattle/display/statsdisplay.py:33
#: squirrelbattle/display/statsdisplay.py:36
msgid "Inventory:"
msgstr "Bestand:"
#: squirrelbattle/display/statsdisplay.py:52
#: squirrelbattle/display/statsdisplay.py:55
msgid "YOU ARE DEAD"
msgstr "SIE WURDEN GESTORBEN"
@ -58,11 +58,21 @@ msgstr "Die Bombe explodiert."
msgid "{player} exchanged its body with {entity}."
msgstr "{player} täuscht seinem Körper mit {entity} aus."
#: squirrelbattle/game.py:205 squirrelbattle/tests/game_test.py:573
#: squirrelbattle/game.py:182
#, 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
#, 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
msgid "The buyer does not have enough money"
msgstr "Der Kaufer hat nicht genug Geld"
#: squirrelbattle/game.py:249
#: squirrelbattle/game.py:328
msgid ""
"Some keys are missing in your save file.\n"
"Your save seems to be corrupt. It got deleted."
@ -70,7 +80,7 @@ msgstr ""
"In Ihrer Speicherdatei fehlen einige Schlüssel.\n"
"Ihre Speicherung scheint korrupt zu sein. Es wird gelöscht."
#: squirrelbattle/game.py:257
#: squirrelbattle/game.py:336
msgid ""
"No player was found on this map!\n"
"Maybe you died?"
@ -78,7 +88,7 @@ msgstr ""
"Auf dieser Karte wurde kein Spieler gefunden!\n"
"Vielleicht sind Sie gestorben?"
#: squirrelbattle/game.py:277
#: squirrelbattle/game.py:356
msgid ""
"The JSON file is not correct.\n"
"Your save seems corrupted. It got deleted."
@ -86,22 +96,22 @@ msgstr ""
"Die JSON-Datei ist nicht korrekt.\n"
"Ihre Speicherung scheint korrumpiert. Sie wurde gelöscht."
#: squirrelbattle/interfaces.py:429
#: squirrelbattle/interfaces.py:453
#, python-brace-format
msgid "{name} hits {opponent}."
msgstr "{name} schlägt {opponent}."
#: squirrelbattle/interfaces.py:441
#: squirrelbattle/interfaces.py:465
#, python-brace-format
msgid "{name} takes {amount} damage."
msgstr "{name} nimmt {amount} Schadenspunkte."
#: squirrelbattle/interfaces.py:443
#: squirrelbattle/interfaces.py:467
#, python-brace-format
msgid "{name} dies."
msgstr "{name} stirbt."
#: squirrelbattle/interfaces.py:477
#: squirrelbattle/interfaces.py:501
#, python-brace-format
msgid "{entity} said: {message}"
msgstr "{entity} hat gesagt: {message}"
@ -110,8 +120,8 @@ msgstr "{entity} hat gesagt: {message}"
msgid "Back"
msgstr "Zurück"
#: squirrelbattle/tests/game_test.py:344 squirrelbattle/tests/game_test.py:347
#: squirrelbattle/tests/game_test.py:350 squirrelbattle/tests/game_test.py:353
#: 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/translations_test.py:16
msgid "New game"
msgstr "Neu Spiel"
@ -197,57 +207,61 @@ msgid "Key used to wait"
msgstr "Wartentaste"
#: squirrelbattle/tests/translations_test.py:56
msgid "Key used to use ladders"
msgstr "Leitertaste"
#: squirrelbattle/tests/translations_test.py:58
msgid "Texture pack"
msgstr "Textur-Packung"
#: squirrelbattle/tests/translations_test.py:57
#: squirrelbattle/tests/translations_test.py:59
msgid "Language"
msgstr "Sprache"
#: squirrelbattle/tests/translations_test.py:60
#: squirrelbattle/tests/translations_test.py:62
msgid "player"
msgstr "Spieler"
#: squirrelbattle/tests/translations_test.py:62
#: squirrelbattle/tests/translations_test.py:64
msgid "hedgehog"
msgstr "Igel"
#: squirrelbattle/tests/translations_test.py:63
#: squirrelbattle/tests/translations_test.py:65
msgid "merchant"
msgstr "Kaufmann"
#: squirrelbattle/tests/translations_test.py:64
#: squirrelbattle/tests/translations_test.py:66
msgid "rabbit"
msgstr "Kanninchen"
#: squirrelbattle/tests/translations_test.py:65
#: squirrelbattle/tests/translations_test.py:67
msgid "sunflower"
msgstr "Sonnenblume"
#: squirrelbattle/tests/translations_test.py:66
#: squirrelbattle/tests/translations_test.py:68
msgid "teddy bear"
msgstr "Teddybär"
#: squirrelbattle/tests/translations_test.py:67
#: squirrelbattle/tests/translations_test.py:69
msgid "tiger"
msgstr "Tiger"
#: squirrelbattle/tests/translations_test.py:69
#: squirrelbattle/tests/translations_test.py:71
msgid "body snatch potion"
msgstr "Leichenfleddererzaubertrank"
#: squirrelbattle/tests/translations_test.py:70
#: squirrelbattle/tests/translations_test.py:72
msgid "bomb"
msgstr "Bombe"
#: squirrelbattle/tests/translations_test.py:71
#: squirrelbattle/tests/translations_test.py:73
msgid "explosion"
msgstr "Explosion"
#: squirrelbattle/tests/translations_test.py:72
#: squirrelbattle/tests/translations_test.py:74
msgid "heart"
msgstr "Herz"
#: squirrelbattle/tests/translations_test.py:73
#: squirrelbattle/tests/translations_test.py:75
msgid "sword"
msgstr "schwert"

View File

@ -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: 2020-12-12 18:02+0100\n"
"POT-Creation-Date: 2021-01-06 15:19+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"
@ -17,19 +17,19 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: squirrelbattle/display/menudisplay.py:139
#: squirrelbattle/display/menudisplay.py:160
msgid "INVENTORY"
msgstr "INVENTORIO"
#: squirrelbattle/display/menudisplay.py:164
#: squirrelbattle/display/menudisplay.py:202
msgid "STALL"
msgstr "PUESTO"
#: squirrelbattle/display/statsdisplay.py:33
#: squirrelbattle/display/statsdisplay.py:36
msgid "Inventory:"
msgstr "Inventorio :"
#: squirrelbattle/display/statsdisplay.py:52
#: squirrelbattle/display/statsdisplay.py:55
msgid "YOU ARE DEAD"
msgstr "ERES MUERTO"
@ -57,11 +57,21 @@ msgstr "La bomba está explotando."
msgid "{player} exchanged its body with {entity}."
msgstr "{player} intercambió su cuerpo con {entity}."
#: squirrelbattle/game.py:205 squirrelbattle/tests/game_test.py:573
#: squirrelbattle/game.py:182
#, python-brace-format
msgid "The player climbs down to the floor {floor}."
msgstr ""
#: squirrelbattle/game.py:195
#, python-brace-format
msgid "The player climbs up the floor {floor}."
msgstr ""
#: squirrelbattle/game.py:285 squirrelbattle/tests/game_test.py:592
msgid "The buyer does not have enough money"
msgstr "El comprador no tiene suficiente dinero"
#: squirrelbattle/game.py:249
#: squirrelbattle/game.py:328
msgid ""
"Some keys are missing in your save file.\n"
"Your save seems to be corrupt. It got deleted."
@ -69,7 +79,7 @@ msgstr ""
"Algunas claves faltan en su archivo de guarda.\n"
"Su guarda parece a ser corruptido. Fue eliminado."
#: squirrelbattle/game.py:257
#: squirrelbattle/game.py:336
msgid ""
"No player was found on this map!\n"
"Maybe you died?"
@ -77,7 +87,7 @@ msgstr ""
"No jugador encontrado sobre la carta !\n"
"¿ Quizas murió ?"
#: squirrelbattle/game.py:277
#: squirrelbattle/game.py:356
msgid ""
"The JSON file is not correct.\n"
"Your save seems corrupted. It got deleted."
@ -85,22 +95,22 @@ msgstr ""
"El JSON archivo no es correcto.\n"
"Su guarda parece corrupta. Fue eliminada."
#: squirrelbattle/interfaces.py:429
#: squirrelbattle/interfaces.py:453
#, python-brace-format
msgid "{name} hits {opponent}."
msgstr "{name} golpea a {opponent}."
#: squirrelbattle/interfaces.py:441
#: squirrelbattle/interfaces.py:465
#, python-brace-format
msgid "{name} takes {amount} damage."
msgstr "{name} recibe {amount} daño."
#: squirrelbattle/interfaces.py:443
#: squirrelbattle/interfaces.py:467
#, python-brace-format
msgid "{name} dies."
msgstr "{name} se muere."
#: squirrelbattle/interfaces.py:477
#: squirrelbattle/interfaces.py:501
#, python-brace-format
msgid "{entity} said: {message}"
msgstr "{entity} dijo : {message}"
@ -109,8 +119,8 @@ msgstr "{entity} dijo : {message}"
msgid "Back"
msgstr "Volver"
#: squirrelbattle/tests/game_test.py:344 squirrelbattle/tests/game_test.py:347
#: squirrelbattle/tests/game_test.py:350 squirrelbattle/tests/game_test.py:353
#: 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/translations_test.py:16
msgid "New game"
msgstr "Nuevo partido"
@ -196,57 +206,61 @@ msgid "Key used to wait"
msgstr "Tecla para espera"
#: squirrelbattle/tests/translations_test.py:56
msgid "Key used to use ladders"
msgstr "Tecla para el uso de las escaleras"
#: squirrelbattle/tests/translations_test.py:58
msgid "Texture pack"
msgstr "Paquete de texturas"
#: squirrelbattle/tests/translations_test.py:57
#: squirrelbattle/tests/translations_test.py:59
msgid "Language"
msgstr "Languaje"
#: squirrelbattle/tests/translations_test.py:60
#: squirrelbattle/tests/translations_test.py:62
msgid "player"
msgstr "jugador"
#: squirrelbattle/tests/translations_test.py:62
#: squirrelbattle/tests/translations_test.py:64
msgid "hedgehog"
msgstr "erizo"
#: squirrelbattle/tests/translations_test.py:63
#: squirrelbattle/tests/translations_test.py:65
msgid "merchant"
msgstr "comerciante"
#: squirrelbattle/tests/translations_test.py:64
#: squirrelbattle/tests/translations_test.py:66
msgid "rabbit"
msgstr "conejo"
#: squirrelbattle/tests/translations_test.py:65
#: squirrelbattle/tests/translations_test.py:67
msgid "sunflower"
msgstr "girasol"
#: squirrelbattle/tests/translations_test.py:66
#: squirrelbattle/tests/translations_test.py:68
msgid "teddy bear"
msgstr "osito de peluche"
#: squirrelbattle/tests/translations_test.py:67
#: squirrelbattle/tests/translations_test.py:69
msgid "tiger"
msgstr "tigre"
#: squirrelbattle/tests/translations_test.py:69
#: squirrelbattle/tests/translations_test.py:71
msgid "body snatch potion"
msgstr "poción de intercambio"
#: squirrelbattle/tests/translations_test.py:70
#: squirrelbattle/tests/translations_test.py:72
msgid "bomb"
msgstr "bomba"
#: squirrelbattle/tests/translations_test.py:71
#: squirrelbattle/tests/translations_test.py:73
msgid "explosion"
msgstr "explosión"
#: squirrelbattle/tests/translations_test.py:72
#: squirrelbattle/tests/translations_test.py:74
msgid "heart"
msgstr "corazón"
#: squirrelbattle/tests/translations_test.py:73
#: squirrelbattle/tests/translations_test.py:75
msgid "sword"
msgstr "espada"

View File

@ -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: 2020-12-12 18:02+0100\n"
"POT-Creation-Date: 2021-01-06 15:19+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"
@ -17,19 +17,19 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: squirrelbattle/display/menudisplay.py:139
#: squirrelbattle/display/menudisplay.py:160
msgid "INVENTORY"
msgstr "INVENTAIRE"
#: squirrelbattle/display/menudisplay.py:164
#: squirrelbattle/display/menudisplay.py:202
msgid "STALL"
msgstr "STAND"
#: squirrelbattle/display/statsdisplay.py:33
#: squirrelbattle/display/statsdisplay.py:36
msgid "Inventory:"
msgstr "Inventaire :"
#: squirrelbattle/display/statsdisplay.py:52
#: squirrelbattle/display/statsdisplay.py:55
msgid "YOU ARE DEAD"
msgstr "VOUS ÊTES MORT"
@ -58,11 +58,21 @@ msgstr "La bombe explose."
msgid "{player} exchanged its body with {entity}."
msgstr "{player} a échangé son corps avec {entity}."
#: squirrelbattle/game.py:205 squirrelbattle/tests/game_test.py:573
#: squirrelbattle/game.py:182
#, python-brace-format
msgid "The player climbs down to the floor {floor}."
msgstr "Le joueur descend à l'étage {floor}."
#: squirrelbattle/game.py:195
#, 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
msgid "The buyer does not have enough money"
msgstr "L'acheteur n'a pas assez d'argent"
#: squirrelbattle/game.py:249
#: squirrelbattle/game.py:328
msgid ""
"Some keys are missing in your save file.\n"
"Your save seems to be corrupt. It got deleted."
@ -70,7 +80,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:257
#: squirrelbattle/game.py:336
msgid ""
"No player was found on this map!\n"
"Maybe you died?"
@ -78,7 +88,7 @@ msgstr ""
"Aucun joueur n'a été trouvé sur la carte !\n"
"Peut-être êtes-vous mort ?"
#: squirrelbattle/game.py:277
#: squirrelbattle/game.py:356
msgid ""
"The JSON file is not correct.\n"
"Your save seems corrupted. It got deleted."
@ -86,22 +96,22 @@ msgstr ""
"Le fichier JSON de sauvegarde est incorrect.\n"
"Votre sauvegarde semble corrompue. Elle a été supprimée."
#: squirrelbattle/interfaces.py:429
#: squirrelbattle/interfaces.py:453
#, python-brace-format
msgid "{name} hits {opponent}."
msgstr "{name} frappe {opponent}."
#: squirrelbattle/interfaces.py:441
#: squirrelbattle/interfaces.py:465
#, python-brace-format
msgid "{name} takes {amount} damage."
msgstr "{name} prend {amount} points de dégât."
#: squirrelbattle/interfaces.py:443
#: squirrelbattle/interfaces.py:467
#, python-brace-format
msgid "{name} dies."
msgstr "{name} meurt."
#: squirrelbattle/interfaces.py:477
#: squirrelbattle/interfaces.py:501
#, python-brace-format
msgid "{entity} said: {message}"
msgstr "{entity} a dit : {message}"
@ -110,8 +120,8 @@ msgstr "{entity} a dit : {message}"
msgid "Back"
msgstr "Retour"
#: squirrelbattle/tests/game_test.py:344 squirrelbattle/tests/game_test.py:347
#: squirrelbattle/tests/game_test.py:350 squirrelbattle/tests/game_test.py:353
#: 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/translations_test.py:16
msgid "New game"
msgstr "Nouvelle partie"
@ -197,57 +207,61 @@ msgid "Key used to wait"
msgstr "Touche pour attendre"
#: squirrelbattle/tests/translations_test.py:56
msgid "Key used to use ladders"
msgstr "Touche pour utiliser les échelles"
#: squirrelbattle/tests/translations_test.py:58
msgid "Texture pack"
msgstr "Pack de textures"
#: squirrelbattle/tests/translations_test.py:57
#: squirrelbattle/tests/translations_test.py:59
msgid "Language"
msgstr "Langue"
#: squirrelbattle/tests/translations_test.py:60
#: squirrelbattle/tests/translations_test.py:62
msgid "player"
msgstr "joueur"
#: squirrelbattle/tests/translations_test.py:62
#: squirrelbattle/tests/translations_test.py:64
msgid "hedgehog"
msgstr "hérisson"
#: squirrelbattle/tests/translations_test.py:63
#: squirrelbattle/tests/translations_test.py:65
msgid "merchant"
msgstr "marchand"
#: squirrelbattle/tests/translations_test.py:64
#: squirrelbattle/tests/translations_test.py:66
msgid "rabbit"
msgstr "lapin"
#: squirrelbattle/tests/translations_test.py:65
#: squirrelbattle/tests/translations_test.py:67
msgid "sunflower"
msgstr "tournesol"
#: squirrelbattle/tests/translations_test.py:66
#: squirrelbattle/tests/translations_test.py:68
msgid "teddy bear"
msgstr "nounours"
#: squirrelbattle/tests/translations_test.py:67
#: squirrelbattle/tests/translations_test.py:69
msgid "tiger"
msgstr "tigre"
#: squirrelbattle/tests/translations_test.py:69
#: squirrelbattle/tests/translations_test.py:71
msgid "body snatch potion"
msgstr "potion d'arrachage de corps"
#: squirrelbattle/tests/translations_test.py:70
#: squirrelbattle/tests/translations_test.py:72
msgid "bomb"
msgstr "bombe"
#: squirrelbattle/tests/translations_test.py:71
#: squirrelbattle/tests/translations_test.py:73
msgid "explosion"
msgstr ""
#: squirrelbattle/tests/translations_test.py:72
#: squirrelbattle/tests/translations_test.py:74
msgid "heart"
msgstr "cœur"
#: squirrelbattle/tests/translations_test.py:73
#: squirrelbattle/tests/translations_test.py:75
msgid "sword"
msgstr "épée"

View File

@ -34,6 +34,7 @@ class Settings:
self.KEY_DROP = ['r', 'Key used to drop an item in the inventory']
self.KEY_CHAT = ['t', 'Key used to talk to a friendly entity']
self.KEY_WAIT = ['w', 'Key used to wait']
self.KEY_LADDER = ['<', 'Key used to use ladders']
self.TEXTURE_PACK = ['ascii', 'Texture pack']
self.LOCALE = [locale.getlocale()[0][:2], 'Language']

View File

@ -46,11 +46,6 @@ class TestGame(unittest.TestCase):
bomb.hold(self.game.player)
sword.hold(self.game.player)
for entity in self.game.map.entities:
# trumpets change order when they are loaded, this breaks the test.
if entity.name == 'trumpet':
self.game.map.remove_entity(entity)
# Ensure that merchants can be saved
merchant = Merchant()
merchant.move(3, 6)
@ -153,6 +148,9 @@ class TestGame(unittest.TestCase):
self.assertEqual(KeyValues.translate_key(
self.game.settings.KEY_WAIT, self.game.settings),
KeyValues.WAIT)
self.assertEqual(KeyValues.translate_key(
self.game.settings.KEY_LADDER, self.game.settings),
KeyValues.LADDER)
self.assertEqual(KeyValues.translate_key(' ', self.game.settings),
KeyValues.SPACE)
self.assertEqual(KeyValues.translate_key('plop', self.game.settings),
@ -343,7 +341,7 @@ class TestGame(unittest.TestCase):
self.assertEqual(self.game.settings.KEY_LEFT_PRIMARY, 'a')
# Navigate to "texture pack"
for ignored in range(11):
for ignored in range(12):
self.game.handle_key_pressed(KeyValues.DOWN)
# Change texture pack
@ -615,6 +613,37 @@ class TestGame(unittest.TestCase):
self.game.handle_key_pressed(KeyValues.SPACE)
self.assertEqual(self.game.state, GameMode.PLAY)
def test_ladders(self) -> None:
"""
Ensure that the player can climb on ladders.
"""
self.game.state = GameMode.PLAY
self.assertEqual(self.game.player.map.floor, 0)
self.game.handle_key_pressed(KeyValues.LADDER)
self.assertEqual(self.game.player.map.floor, 0)
# Move nowhere
self.game.player.move(10, 10)
self.game.handle_key_pressed(KeyValues.LADDER)
self.assertEqual(self.game.player.map.floor, 0)
# Move down
self.game.player.move(3, 40) # Move on a ladder
self.game.handle_key_pressed(KeyValues.LADDER)
self.assertEqual(self.game.map_index, 1)
self.assertEqual(self.game.player.map.floor, 1)
self.assertEqual(self.game.player.y, 1)
self.assertEqual(self.game.player.x, 17)
self.game.display_actions(DisplayActions.UPDATE)
# Move up
self.game.handle_key_pressed(KeyValues.LADDER)
self.assertEqual(self.game.player.map.floor, 0)
self.assertEqual(self.game.player.y, 3)
self.assertEqual(self.game.player.x, 40)
self.game.display_actions(DisplayActions.UPDATE)
def test_credits(self) -> None:
"""
Load credits menu.

View File

@ -53,6 +53,8 @@ class TestTranslations(unittest.TestCase):
self.assertEqual(_("Key used to talk to a friendly entity"),
"Touche pour parler à une entité pacifique")
self.assertEqual(_("Key used to wait"), "Touche pour attendre")
self.assertEqual(_("Key used to use ladders"),
"Touche pour utiliser les échelles")
self.assertEqual(_("Texture pack"), "Pack de textures")
self.assertEqual(_("Language"), "Langue")