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 1 6
####### ############# ####### #############
#.....# #...........# #.H...# #...........#
#.....# #####...........# #.....# #####...........#
#.....# #...............# #.....# #............H..#
#.##### #.###...........# #.##### #.###...........#
#.# #.# #...........# #.# #.# #...........#
#.# #.# ############# #.# #.# #############

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@
from json import JSONDecodeError from json import JSONDecodeError
from random import randint from random import randint
from typing import Any, Optional from typing import Any, Optional, List
import curses import curses
import json import json
import os import os
@ -22,7 +22,8 @@ class Game:
""" """
The game object controls all actions in the game. The game object controls all actions in the game.
""" """
map: Map maps: List[Map]
map_index: int
player: Player player: Player
screen: Any screen: Any
# display_actions is a display interface set by the bootstrapper # display_actions is a display interface set by the bootstrapper
@ -52,7 +53,9 @@ class Game:
Creates a new game on the screen. Creates a new game on the screen.
""" """
# TODO generate a new map procedurally # 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.map.logs = self.logs
self.logs.clear() self.logs.clear()
self.player = Player() self.player = Player()
@ -61,6 +64,24 @@ class Game:
self.map.spawn_random_entities(randint(3, 10)) self.map.spawn_random_entities(randint(3, 10))
self.inventory_menu.update_player(self.player) 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 def run(self, screen: Any) -> None: # pragma no cover
""" """
Main infinite loop. Main infinite loop.
@ -135,6 +156,54 @@ class Game:
self.waiting_for_friendly_key = True self.waiting_for_friendly_key = True
elif key == KeyValues.WAIT: elif key == KeyValues.WAIT:
self.map.tick(self.player) 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: 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 The Map object represents a with its width, height
and tiles, that have their custom properties. and tiles, that have their custom properties.
""" """
floor: int
width: int width: int
height: int height: int
start_y: int start_y: int
@ -51,6 +52,7 @@ class Map:
def __init__(self, width: int, height: int, tiles: list, def __init__(self, width: int, height: int, tiles: list,
start_y: int, start_x: int): start_y: int, start_x: int):
self.floor = 0
self.width = width self.width = width
self.height = height self.height = height
self.start_y = start_y self.start_y = start_y
@ -146,7 +148,6 @@ class Map:
Puts randomly {count} entities on the map, only on empty ground tiles. Puts randomly {count} entities on the map, only on empty ground tiles.
""" """
for ignored in range(count): for ignored in range(count):
y, x = 0, 0
while True: while True:
y, x = randint(0, self.height - 1), randint(0, self.width - 1) y, x = randint(0, self.height - 1), randint(0, self.width - 1)
tile = self.tiles[y][x] tile = self.tiles[y][x]
@ -207,6 +208,7 @@ class Tile(Enum):
EMPTY = auto() EMPTY = auto()
WALL = auto() WALL = auto()
FLOOR = auto() FLOOR = auto()
LADDER = auto()
@staticmethod @staticmethod
def from_ascii_char(ch: str) -> "Tile": def from_ascii_char(ch: str) -> "Tile":
@ -223,7 +225,16 @@ class Tile(Enum):
Translates a Tile to the corresponding character according Translates a Tile to the corresponding character according
to the texture pack. 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: def is_wall(self) -> bool:
""" """
@ -231,6 +242,12 @@ class Tile(Enum):
""" """
return self == Tile.WALL return self == Tile.WALL
def is_ladder(self) -> bool:
"""
Is this Tile a ladder?
"""
return self == Tile.LADDER
def can_walk(self) -> bool: def can_walk(self) -> bool:
""" """
Checks if an entity (player or not) can move in this tile. Checks if an entity (player or not) can move in this tile.

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

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-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" "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,19 +17,19 @@ 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:139 #: squirrelbattle/display/menudisplay.py:160
msgid "INVENTORY" msgid "INVENTORY"
msgstr "INVENTORIO" msgstr "INVENTORIO"
#: squirrelbattle/display/menudisplay.py:164 #: squirrelbattle/display/menudisplay.py:202
msgid "STALL" msgid "STALL"
msgstr "PUESTO" msgstr "PUESTO"
#: squirrelbattle/display/statsdisplay.py:33 #: squirrelbattle/display/statsdisplay.py:36
msgid "Inventory:" msgid "Inventory:"
msgstr "Inventorio :" msgstr "Inventorio :"
#: squirrelbattle/display/statsdisplay.py:52 #: squirrelbattle/display/statsdisplay.py:55
msgid "YOU ARE DEAD" msgid "YOU ARE DEAD"
msgstr "ERES MUERTO" msgstr "ERES MUERTO"
@ -57,11 +57,21 @@ msgstr "La bomba está explotando."
msgid "{player} exchanged its body with {entity}." msgid "{player} exchanged its body with {entity}."
msgstr "{player} intercambió su cuerpo con {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" msgid "The buyer does not have enough money"
msgstr "El comprador no tiene suficiente dinero" msgstr "El comprador no tiene suficiente dinero"
#: squirrelbattle/game.py:249 #: squirrelbattle/game.py:328
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."
@ -69,7 +79,7 @@ msgstr ""
"Algunas claves faltan en su archivo de guarda.\n" "Algunas claves faltan en su archivo de guarda.\n"
"Su guarda parece a ser corruptido. Fue eliminado." "Su guarda parece a ser corruptido. Fue eliminado."
#: squirrelbattle/game.py:257 #: squirrelbattle/game.py:336
msgid "" msgid ""
"No player was found on this map!\n" "No player was found on this map!\n"
"Maybe you died?" "Maybe you died?"
@ -77,7 +87,7 @@ msgstr ""
"No jugador encontrado sobre la carta !\n" "No jugador encontrado sobre la carta !\n"
"¿ Quizas murió ?" "¿ Quizas murió ?"
#: squirrelbattle/game.py:277 #: squirrelbattle/game.py:356
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."
@ -85,22 +95,22 @@ msgstr ""
"El JSON archivo no es correcto.\n" "El JSON archivo no es correcto.\n"
"Su guarda parece corrupta. Fue eliminada." "Su guarda parece corrupta. Fue eliminada."
#: squirrelbattle/interfaces.py:429 #: squirrelbattle/interfaces.py:453
#, python-brace-format #, python-brace-format
msgid "{name} hits {opponent}." msgid "{name} hits {opponent}."
msgstr "{name} golpea a {opponent}." msgstr "{name} golpea a {opponent}."
#: squirrelbattle/interfaces.py:441 #: squirrelbattle/interfaces.py:465
#, python-brace-format #, python-brace-format
msgid "{name} takes {amount} damage." msgid "{name} takes {amount} damage."
msgstr "{name} recibe {amount} daño." msgstr "{name} recibe {amount} daño."
#: squirrelbattle/interfaces.py:443 #: squirrelbattle/interfaces.py:467
#, python-brace-format #, python-brace-format
msgid "{name} dies." msgid "{name} dies."
msgstr "{name} se muere." msgstr "{name} se muere."
#: squirrelbattle/interfaces.py:477 #: squirrelbattle/interfaces.py:501
#, python-brace-format #, python-brace-format
msgid "{entity} said: {message}" msgid "{entity} said: {message}"
msgstr "{entity} dijo : {message}" msgstr "{entity} dijo : {message}"
@ -109,8 +119,8 @@ msgstr "{entity} dijo : {message}"
msgid "Back" msgid "Back"
msgstr "Volver" msgstr "Volver"
#: squirrelbattle/tests/game_test.py:344 squirrelbattle/tests/game_test.py:347 #: squirrelbattle/tests/game_test.py:358 squirrelbattle/tests/game_test.py:361
#: squirrelbattle/tests/game_test.py:350 squirrelbattle/tests/game_test.py:353 #: squirrelbattle/tests/game_test.py:364 squirrelbattle/tests/game_test.py:367
#: squirrelbattle/tests/translations_test.py:16 #: squirrelbattle/tests/translations_test.py:16
msgid "New game" msgid "New game"
msgstr "Nuevo partido" msgstr "Nuevo partido"
@ -196,57 +206,61 @@ msgid "Key used to wait"
msgstr "Tecla para espera" msgstr "Tecla para espera"
#: squirrelbattle/tests/translations_test.py:56 #: 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" msgid "Texture pack"
msgstr "Paquete de texturas" msgstr "Paquete de texturas"
#: squirrelbattle/tests/translations_test.py:57 #: squirrelbattle/tests/translations_test.py:59
msgid "Language" msgid "Language"
msgstr "Languaje" msgstr "Languaje"
#: squirrelbattle/tests/translations_test.py:60 #: squirrelbattle/tests/translations_test.py:62
msgid "player" msgid "player"
msgstr "jugador" msgstr "jugador"
#: squirrelbattle/tests/translations_test.py:62 #: squirrelbattle/tests/translations_test.py:64
msgid "hedgehog" msgid "hedgehog"
msgstr "erizo" msgstr "erizo"
#: squirrelbattle/tests/translations_test.py:63 #: squirrelbattle/tests/translations_test.py:65
msgid "merchant" msgid "merchant"
msgstr "comerciante" msgstr "comerciante"
#: squirrelbattle/tests/translations_test.py:64 #: squirrelbattle/tests/translations_test.py:66
msgid "rabbit" msgid "rabbit"
msgstr "conejo" msgstr "conejo"
#: squirrelbattle/tests/translations_test.py:65 #: squirrelbattle/tests/translations_test.py:67
msgid "sunflower" msgid "sunflower"
msgstr "girasol" msgstr "girasol"
#: squirrelbattle/tests/translations_test.py:66 #: squirrelbattle/tests/translations_test.py:68
msgid "teddy bear" msgid "teddy bear"
msgstr "osito de peluche" msgstr "osito de peluche"
#: squirrelbattle/tests/translations_test.py:67 #: squirrelbattle/tests/translations_test.py:69
msgid "tiger" msgid "tiger"
msgstr "tigre" msgstr "tigre"
#: squirrelbattle/tests/translations_test.py:69 #: squirrelbattle/tests/translations_test.py:71
msgid "body snatch potion" msgid "body snatch potion"
msgstr "poción de intercambio" msgstr "poción de intercambio"
#: squirrelbattle/tests/translations_test.py:70 #: squirrelbattle/tests/translations_test.py:72
msgid "bomb" msgid "bomb"
msgstr "bomba" msgstr "bomba"
#: squirrelbattle/tests/translations_test.py:71 #: squirrelbattle/tests/translations_test.py:73
msgid "explosion" msgid "explosion"
msgstr "explosión" msgstr "explosión"
#: squirrelbattle/tests/translations_test.py:72 #: squirrelbattle/tests/translations_test.py:74
msgid "heart" msgid "heart"
msgstr "corazón" msgstr "corazón"
#: squirrelbattle/tests/translations_test.py:73 #: squirrelbattle/tests/translations_test.py:75
msgid "sword" msgid "sword"
msgstr "espada" msgstr "espada"

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-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" "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,19 +17,19 @@ 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:139 #: squirrelbattle/display/menudisplay.py:160
msgid "INVENTORY" msgid "INVENTORY"
msgstr "INVENTAIRE" msgstr "INVENTAIRE"
#: squirrelbattle/display/menudisplay.py:164 #: squirrelbattle/display/menudisplay.py:202
msgid "STALL" msgid "STALL"
msgstr "STAND" msgstr "STAND"
#: squirrelbattle/display/statsdisplay.py:33 #: squirrelbattle/display/statsdisplay.py:36
msgid "Inventory:" msgid "Inventory:"
msgstr "Inventaire :" msgstr "Inventaire :"
#: squirrelbattle/display/statsdisplay.py:52 #: squirrelbattle/display/statsdisplay.py:55
msgid "YOU ARE DEAD" msgid "YOU ARE DEAD"
msgstr "VOUS ÊTES MORT" msgstr "VOUS ÊTES MORT"
@ -58,11 +58,21 @@ msgstr "La bombe explose."
msgid "{player} exchanged its body with {entity}." msgid "{player} exchanged its body with {entity}."
msgstr "{player} a échangé son corps avec {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" msgid "The buyer does not have enough money"
msgstr "L'acheteur n'a pas assez d'argent" msgstr "L'acheteur n'a pas assez d'argent"
#: squirrelbattle/game.py:249 #: squirrelbattle/game.py:328
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."
@ -70,7 +80,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:257 #: squirrelbattle/game.py:336
msgid "" msgid ""
"No player was found on this map!\n" "No player was found on this map!\n"
"Maybe you died?" "Maybe you died?"
@ -78,7 +88,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:277 #: squirrelbattle/game.py:356
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."
@ -86,22 +96,22 @@ 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/interfaces.py:429 #: squirrelbattle/interfaces.py:453
#, python-brace-format #, python-brace-format
msgid "{name} hits {opponent}." msgid "{name} hits {opponent}."
msgstr "{name} frappe {opponent}." msgstr "{name} frappe {opponent}."
#: squirrelbattle/interfaces.py:441 #: squirrelbattle/interfaces.py:465
#, python-brace-format #, python-brace-format
msgid "{name} takes {amount} damage." msgid "{name} takes {amount} damage."
msgstr "{name} prend {amount} points de dégât." msgstr "{name} prend {amount} points de dégât."
#: squirrelbattle/interfaces.py:443 #: squirrelbattle/interfaces.py:467
#, python-brace-format #, python-brace-format
msgid "{name} dies." msgid "{name} dies."
msgstr "{name} meurt." msgstr "{name} meurt."
#: squirrelbattle/interfaces.py:477 #: squirrelbattle/interfaces.py:501
#, python-brace-format #, python-brace-format
msgid "{entity} said: {message}" msgid "{entity} said: {message}"
msgstr "{entity} a dit : {message}" msgstr "{entity} a dit : {message}"
@ -110,8 +120,8 @@ msgstr "{entity} a dit : {message}"
msgid "Back" msgid "Back"
msgstr "Retour" msgstr "Retour"
#: squirrelbattle/tests/game_test.py:344 squirrelbattle/tests/game_test.py:347 #: squirrelbattle/tests/game_test.py:358 squirrelbattle/tests/game_test.py:361
#: squirrelbattle/tests/game_test.py:350 squirrelbattle/tests/game_test.py:353 #: squirrelbattle/tests/game_test.py:364 squirrelbattle/tests/game_test.py:367
#: squirrelbattle/tests/translations_test.py:16 #: squirrelbattle/tests/translations_test.py:16
msgid "New game" msgid "New game"
msgstr "Nouvelle partie" msgstr "Nouvelle partie"
@ -197,57 +207,61 @@ msgid "Key used to wait"
msgstr "Touche pour attendre" msgstr "Touche pour attendre"
#: squirrelbattle/tests/translations_test.py:56 #: 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" msgid "Texture pack"
msgstr "Pack de textures" msgstr "Pack de textures"
#: squirrelbattle/tests/translations_test.py:57 #: squirrelbattle/tests/translations_test.py:59
msgid "Language" msgid "Language"
msgstr "Langue" msgstr "Langue"
#: squirrelbattle/tests/translations_test.py:60 #: squirrelbattle/tests/translations_test.py:62
msgid "player" msgid "player"
msgstr "joueur" msgstr "joueur"
#: squirrelbattle/tests/translations_test.py:62 #: squirrelbattle/tests/translations_test.py:64
msgid "hedgehog" msgid "hedgehog"
msgstr "hérisson" msgstr "hérisson"
#: squirrelbattle/tests/translations_test.py:63 #: squirrelbattle/tests/translations_test.py:65
msgid "merchant" msgid "merchant"
msgstr "marchand" msgstr "marchand"
#: squirrelbattle/tests/translations_test.py:64 #: squirrelbattle/tests/translations_test.py:66
msgid "rabbit" msgid "rabbit"
msgstr "lapin" msgstr "lapin"
#: squirrelbattle/tests/translations_test.py:65 #: squirrelbattle/tests/translations_test.py:67
msgid "sunflower" msgid "sunflower"
msgstr "tournesol" msgstr "tournesol"
#: squirrelbattle/tests/translations_test.py:66 #: squirrelbattle/tests/translations_test.py:68
msgid "teddy bear" msgid "teddy bear"
msgstr "nounours" msgstr "nounours"
#: squirrelbattle/tests/translations_test.py:67 #: squirrelbattle/tests/translations_test.py:69
msgid "tiger" msgid "tiger"
msgstr "tigre" msgstr "tigre"
#: squirrelbattle/tests/translations_test.py:69 #: squirrelbattle/tests/translations_test.py:71
msgid "body snatch potion" msgid "body snatch potion"
msgstr "potion d'arrachage de corps" msgstr "potion d'arrachage de corps"
#: squirrelbattle/tests/translations_test.py:70 #: squirrelbattle/tests/translations_test.py:72
msgid "bomb" msgid "bomb"
msgstr "bombe" msgstr "bombe"
#: squirrelbattle/tests/translations_test.py:71 #: squirrelbattle/tests/translations_test.py:73
msgid "explosion" msgid "explosion"
msgstr "" msgstr ""
#: squirrelbattle/tests/translations_test.py:72 #: squirrelbattle/tests/translations_test.py:74
msgid "heart" msgid "heart"
msgstr "cœur" msgstr "cœur"
#: squirrelbattle/tests/translations_test.py:73 #: squirrelbattle/tests/translations_test.py:75
msgid "sword" msgid "sword"
msgstr "épée" 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_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_CHAT = ['t', 'Key used to talk to a friendly entity']
self.KEY_WAIT = ['w', 'Key used to wait'] self.KEY_WAIT = ['w', 'Key used to wait']
self.KEY_LADDER = ['<', 'Key used to use ladders']
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

@ -46,11 +46,6 @@ class TestGame(unittest.TestCase):
bomb.hold(self.game.player) bomb.hold(self.game.player)
sword.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 # Ensure that merchants can be saved
merchant = Merchant() merchant = Merchant()
merchant.move(3, 6) merchant.move(3, 6)
@ -153,6 +148,9 @@ class TestGame(unittest.TestCase):
self.assertEqual(KeyValues.translate_key( self.assertEqual(KeyValues.translate_key(
self.game.settings.KEY_WAIT, self.game.settings), self.game.settings.KEY_WAIT, self.game.settings),
KeyValues.WAIT) 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), 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),
@ -343,7 +341,7 @@ 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"
for ignored in range(11): for ignored in range(12):
self.game.handle_key_pressed(KeyValues.DOWN) self.game.handle_key_pressed(KeyValues.DOWN)
# Change texture pack # Change texture pack
@ -615,6 +613,37 @@ class TestGame(unittest.TestCase):
self.game.handle_key_pressed(KeyValues.SPACE) self.game.handle_key_pressed(KeyValues.SPACE)
self.assertEqual(self.game.state, GameMode.PLAY) 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: def test_credits(self) -> None:
""" """
Load credits menu. Load credits menu.

View File

@ -53,6 +53,8 @@ class TestTranslations(unittest.TestCase):
self.assertEqual(_("Key used to talk to a friendly entity"), self.assertEqual(_("Key used to talk to a friendly entity"),
"Touche pour parler à une entité pacifique") "Touche pour parler à une entité pacifique")
self.assertEqual(_("Key used to wait"), "Touche pour attendre") 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(_("Texture pack"), "Pack de textures")
self.assertEqual(_("Language"), "Langue") self.assertEqual(_("Language"), "Langue")