Merge branch 'save_floors' into 'master'

Save floors

Closes #62 et #61

See merge request ynerant/squirrel-battle!58
This commit is contained in:
ynerant 2021-01-08 16:05:10 +01:00
commit 4a80dc36ad
13 changed files with 277 additions and 113 deletions

View File

@ -57,7 +57,7 @@ Dans le `pack de textures`_ ASCII, il est représenté par le caractère ``8``.
Dans le `pack de textures`_ écureuil, il est représenté par l'émoji ``🧸``.
Pyguargue
Pygargue
---------
Son nom est fixé à `eagle`. Il a par défaut une force à **1000** et **5000** points de vie.

View File

@ -22,7 +22,7 @@ Pack de textures
.. _Bouclier: entities/items.html#bouclier
.. _Hazel: ../index.html
.. _Plastron: ../entities/items.html#plastron
.. _Pyguargue: ../entities/monsters.html#Pyguargue
.. _Pygargue: ../entities/monsters.html#Pygargue
.. _Casque: ../entities/items.html#Casque
.. _Anneau: ../entities/items.html#Anneau
.. _Trompette: ../entities/items.html#Trompette
@ -64,7 +64,7 @@ Chaque tuile fait un caractère de large.
* Bouclier_ : ``D``
* Hazel_ : ``¤``
* Plastron_ : ``(``
* Pyguargue_ : ``µ``
* Pygargue_ : ``µ``
* Casque_ : ``0``
* Anneau_ : ``o``
* Trompette_ : ``/``
@ -95,7 +95,7 @@ Chaque tuile fait 2 caractères de large pour afficher les émojis proprement.
* Bouclier_ : ``🛡️``
* Hazel_ : ``🌰``
* Plastron_ : ``🦺``
* Pyguargue_ : ``🦅``
* Pygargue_ : ``🦅``
* Casque_ : ``⛑️``
* Anneau_ : ``💍``
* Trompette_ : ``🎺``

View File

@ -3,8 +3,10 @@
import curses
from ..entities.items import Monocle
from ..entities.player import Player
from ..game import Game
from ..interfaces import FightingEntity
from ..translations import gettext as _
from .display import Display
@ -13,6 +15,7 @@ class StatsDisplay(Display):
"""
A class to handle the display of the stats of the player.
"""
game: Game
player: Player
def __init__(self, *args, **kwargs):
@ -20,6 +23,7 @@ class StatsDisplay(Display):
self.pad = self.newpad(self.rows, self.cols)
def update(self, game: Game) -> None:
self.game = game
self.player = game.player
def update_pad(self) -> None:
@ -77,6 +81,47 @@ class StatsDisplay(Display):
self.addstr(self.pad, 15, 0, _("YOU ARE DEAD"), curses.COLOR_RED,
bold=True, blink=True, standout=True)
if self.player.map.tiles[self.player.y][self.player.x].is_ladder():
msg = _("Use {key} to use the ladder") \
.format(key=self.game.settings.KEY_LADDER.upper())
self.addstr(self.pad, self.height - 2, 0, msg,
italic=True, reverse=True)
self.update_entities_stats()
def update_entities_stats(self) -> None:
"""
Display information about a near entity if we have a monocle.
"""
for dy, dx in [(-1, 0), (0, -1), (0, 1), (1, 0)]:
for entity in self.player.map.find_entities(FightingEntity):
if entity == self.player:
continue
if entity.y == self.player.y + dy \
and entity.x == self.player.x + dx:
if entity.is_friendly():
msg = _("Move to the friendly entity to talk to it") \
if self.game.waiting_for_friendly_key else \
_("Use {key} then move to talk to the entity") \
.format(key=self.game.settings.KEY_CHAT.upper())
self.addstr(self.pad, self.height - 1, 0, msg,
italic=True, reverse=True)
if isinstance(self.player.equipped_secondary, Monocle):
# Truth monocle
message = f"{entity.translated_name.capitalize()} " \
f"{self.pack[entity.name.upper()]}\n" \
f"STR {entity.strength}\n" \
f"INT {entity.intelligence}\n" \
f"CHR {entity.charisma}\n" \
f"DEX {entity.dexterity}\n" \
f"CON {entity.constitution}\n" \
f"CRI {entity.critical}%"
self.addstr(self.pad, 17, 0, message)
# Only display one entity
break
def display(self) -> None:
self.pad.erase()
self.update_pad()

View File

@ -84,6 +84,7 @@ TexturePack.ASCII_PACK = TexturePack(
HEDGEHOG='*',
HELMET='0',
MERCHANT='M',
MONOCLE='ô',
PLAYER='@',
RABBIT='Y',
RING_OF_CRITICAL_DAMAGE='o',
@ -121,6 +122,7 @@ TexturePack.SQUIRREL_PACK = TexturePack(
HELMET='⛑️ ',
PLAYER='🐿️ ',
MERCHANT='🦜',
MONOCLE='🧐',
RABBIT='🐇',
RING_OF_CRITICAL_DAMAGE='💍',
RING_OF_MORE_EXPERIENCE='💍',

View File

@ -86,8 +86,8 @@ class Item(Entity):
"""
Returns the list of all item classes.
"""
return [BodySnatchPotion, Bomb, Heart, Shield, Sword,
Chestplate, Helmet, RingCritical, RingXP]
return [BodySnatchPotion, Chestplate, Bomb, Heart, Helmet, Monocle,
Shield, Sword, RingCritical, RingXP]
def be_sold(self, buyer: InventoryHolder, seller: InventoryHolder) -> bool:
"""
@ -453,3 +453,9 @@ class RingXP(Ring):
experience: float = 2, *args, **kwargs):
super().__init__(name=name, price=price, experience=experience,
*args, **kwargs)
class Monocle(Item):
def __init__(self, name: str = "monocle", price: int = 10,
*args, **kwargs):
super().__init__(name=name, price=price, *args, **kwargs)

View File

@ -335,14 +335,16 @@ class Game:
"""
Saves the game to a dictionary.
"""
return self.map.save_state()
return dict(map_index=self.map_index,
maps=[m.save_state() for m in self.maps])
def load_state(self, d: dict) -> None:
"""
Loads the game from a dictionary.
"""
try:
self.map.load_state(d)
self.map_index = d["map_index"]
self.maps = [Map().load_state(map_dict) for map_dict in d["maps"]]
except KeyError:
self.message = _("Some keys are missing in your save file.\n"
"Your save seems to be corrupt. It got deleted.")
@ -359,6 +361,8 @@ class Game:
return
self.player = players[0]
self.map.compute_visibility(self.player.y, self.player.x,
self.player.vision)
self.display_actions(DisplayActions.UPDATE)
def load_game(self) -> None:

View File

@ -80,18 +80,18 @@ class Map:
currentx: int
currenty: int
def __init__(self, width: int, height: int, tiles: list,
start_y: int, start_x: int):
def __init__(self, width: int = 0, height: int = 0, tiles: list = None,
start_y: int = 0, start_x: int = 0):
self.floor = 0
self.width = width
self.height = height
self.start_y = start_y
self.start_x = start_x
self.tiles = tiles
self.visibility = [[False for _ in range(len(tiles[0]))]
for _ in range(len(tiles))]
self.tiles = tiles or []
self.visibility = [[False for _ in range(len(self.tiles[0]))]
for _ in range(len(self.tiles))]
self.seen_tiles = [[False for _ in range(len(tiles[0]))]
for _ in range(len(tiles))]
for _ in range(len(self.tiles))]
self.entities = []
self.logs = Logs()
@ -338,9 +338,10 @@ class Map:
for enti in self.entities:
d["entities"].append(enti.save_state())
d["map"] = self.draw_string(TexturePack.ASCII_PACK)
d["seen_tiles"] = self.seen_tiles
return d
def load_state(self, d: dict) -> None:
def load_state(self, d: dict) -> "Map":
"""
Loads the map's attributes from a dictionary.
"""
@ -351,11 +352,16 @@ class Map:
self.currentx = d["currentx"]
self.currenty = d["currenty"]
self.tiles = self.load_dungeon_from_string(d["map"])
self.seen_tiles = d["seen_tiles"]
self.visibility = [[False for _ in range(len(self.tiles[0]))]
for _ in range(len(self.tiles))]
self.entities = []
dictclasses = Entity.get_all_entity_classes_in_a_dict()
for entisave in d["entities"]:
self.add_entity(dictclasses[entisave["type"]](**entisave))
return self
class Tile(Enum):
"""
@ -629,24 +635,26 @@ class Entity:
from squirrelbattle.entities.friendly import Merchant, Sunflower, \
Trumpet
from squirrelbattle.entities.items import BodySnatchPotion, Bomb, \
Heart, Sword, Shield, Chestplate, Helmet, RingCritical, RingXP
Heart, Monocle, Sword, Shield, Chestplate, Helmet, \
RingCritical, RingXP
return {
"Tiger": Tiger,
"Bomb": Bomb,
"Chestplate": Chestplate,
"Heart": Heart,
"BodySnatchPotion": BodySnatchPotion,
"Eagle": GiantSeaEagle,
"Hedgehog": Hedgehog,
"Rabbit": Rabbit,
"TeddyBear": TeddyBear,
"Helmet": Helmet,
"Player": Player,
"Merchant": Merchant,
"Monocle": Monocle,
"Sunflower": Sunflower,
"Sword": Sword,
"Trumpet": Trumpet,
"Eagle": GiantSeaEagle,
"Shield": Shield,
"Chestplate": Chestplate,
"Helmet": Helmet,
"TeddyBear": TeddyBear,
"Tiger": Tiger,
"Rabbit": Rabbit,
"RingCritical": RingCritical,
"RingXP": RingXP,
}

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: 2021-01-08 12:03+0100\n"
"POT-Creation-Date: 2021-01-08 15:15+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,6 +17,12 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ring_of_critical_damage"
msgstr ""
msgid "ring_of_more_experience"
msgstr ""
#, python-brace-format
msgid "{name} takes {amount} damage."
msgstr "{name} nimmt {amount} Schadenspunkte."
@ -43,30 +49,44 @@ msgstr "BESTAND"
msgid "STALL"
msgstr "STAND"
#: squirrelbattle/display/statsdisplay.py:40
#: squirrelbattle/display/statsdisplay.py:44
msgid "Inventory:"
msgstr "Bestand:"
#: squirrelbattle/display/statsdisplay.py:57
#: squirrelbattle/display/statsdisplay.py:61
msgid "Equipped main:"
msgstr ""
#: squirrelbattle/display/statsdisplay.py:61
#: squirrelbattle/display/statsdisplay.py:65
msgid "Equipped secondary:"
msgstr ""
#: squirrelbattle/display/statsdisplay.py:66
#: squirrelbattle/display/statsdisplay.py:70
msgid "Equipped chestplate:"
msgstr ""
#: squirrelbattle/display/statsdisplay.py:70
#: squirrelbattle/display/statsdisplay.py:74
msgid "Equipped helmet:"
msgstr ""
#: squirrelbattle/display/statsdisplay.py:77
#: squirrelbattle/display/statsdisplay.py:81
msgid "YOU ARE DEAD"
msgstr "SIE WURDEN GESTORBEN"
#: squirrelbattle/display/statsdisplay.py:85
#, python-brace-format
msgid "Use {key} to use the ladder"
msgstr ""
#: squirrelbattle/display/statsdisplay.py:94
msgid "Move to the friendly entity to talk to it"
msgstr ""
#: squirrelbattle/display/statsdisplay.py:96
#, python-brace-format
msgid "Use {key} then move to talk to the entity"
msgstr ""
#. TODO
#: squirrelbattle/entities/friendly.py:33
msgid "I don't sell any squirrel"
@ -106,7 +126,7 @@ msgstr "Der Spieler klettert auf dem Stock {floor} hinoben."
msgid "The buyer does not have enough money"
msgstr "Der Kaufer hat nicht genug Geld"
#: squirrelbattle/game.py:347
#: squirrelbattle/game.py:349
msgid ""
"Some keys are missing in your save file.\n"
"Your save seems to be corrupt. It got deleted."
@ -114,7 +134,7 @@ msgstr ""
"In Ihrer Speicherdatei fehlen einige Schlüssel.\n"
"Ihre Speicherung scheint korrupt zu sein. Es wird gelöscht."
#: squirrelbattle/game.py:355
#: squirrelbattle/game.py:357
msgid ""
"No player was found on this map!\n"
"Maybe you died?"
@ -122,7 +142,7 @@ msgstr ""
"Auf dieser Karte wurde kein Spieler gefunden!\n"
"Vielleicht sind Sie gestorben?"
#: squirrelbattle/game.py:375
#: squirrelbattle/game.py:379
msgid ""
"The JSON file is not correct.\n"
"Your save seems corrupted. It got deleted."
@ -130,26 +150,26 @@ msgstr ""
"Die JSON-Datei ist nicht korrekt.\n"
"Ihre Speicherung scheint korrumpiert. Sie wurde gelöscht."
#: squirrelbattle/interfaces.py:712
#: squirrelbattle/interfaces.py:718
msgid "It's a critical hit!"
msgstr ""
#: squirrelbattle/interfaces.py:713
#: squirrelbattle/interfaces.py:719
#, python-brace-format
msgid "{name} hits {opponent}."
msgstr "{name} schlägt {opponent}."
#: squirrelbattle/interfaces.py:727
#: squirrelbattle/interfaces.py:733
#, python-brace-format
msgid "{name} takes {damage} damage."
msgstr ""
#: squirrelbattle/interfaces.py:729
#: squirrelbattle/interfaces.py:735
#, python-brace-format
msgid "{name} dies."
msgstr "{name} stirbt."
#: squirrelbattle/interfaces.py:763
#: squirrelbattle/interfaces.py:769
#, python-brace-format
msgid "{entity} said: {message}"
msgstr "{entity} hat gesagt: {message}"
@ -284,42 +304,50 @@ msgstr "Teddybär"
msgid "tiger"
msgstr "Tiger"
#: squirrelbattle/tests/translations_test.py:71
#: squirrelbattle/tests/translations_test.py:70
msgid "eagle"
msgstr ""
#: squirrelbattle/tests/translations_test.py:72
msgid "body snatch potion"
msgstr "Leichenfleddererzaubertrank"
#: squirrelbattle/tests/translations_test.py:72
#: squirrelbattle/tests/translations_test.py:73
msgid "bomb"
msgstr "Bombe"
#: squirrelbattle/tests/translations_test.py:73
#: squirrelbattle/tests/translations_test.py:74
msgid "explosion"
msgstr "Explosion"
#: squirrelbattle/tests/translations_test.py:74
#: squirrelbattle/tests/translations_test.py:75
msgid "heart"
msgstr "Herz"
#: squirrelbattle/tests/translations_test.py:75
#: squirrelbattle/tests/translations_test.py:76
msgid "sword"
msgstr "schwert"
#: squirrelbattle/tests/translations_test.py:76
#: squirrelbattle/tests/translations_test.py:77
msgid "helmet"
msgstr ""
#: squirrelbattle/tests/translations_test.py:77
#: squirrelbattle/tests/translations_test.py:78
msgid "chestplate"
msgstr ""
#: squirrelbattle/tests/translations_test.py:78
#: squirrelbattle/tests/translations_test.py:79
msgid "shield"
msgstr ""
#: squirrelbattle/tests/translations_test.py:79
msgid "ring_of_critical_damage"
#: squirrelbattle/tests/translations_test.py:80
msgid "ring of critical damage"
msgstr ""
#: squirrelbattle/tests/translations_test.py:81
msgid "ring_of_more_experience"
#: squirrelbattle/tests/translations_test.py:82
msgid "ring of more experience"
msgstr ""
#: squirrelbattle/tests/translations_test.py:84
msgid "monocle"
msgstr ""

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: 2021-01-08 12:03+0100\n"
"POT-Creation-Date: 2021-01-08 15:15+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,6 +17,12 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ring_of_critical_damage"
msgstr ""
msgid "ring_of_more_experience"
msgstr ""
#, python-brace-format
msgid "{name} takes {amount} damage."
msgstr "{name} recibe {amount} daño."
@ -43,30 +49,44 @@ msgstr "INVENTORIO"
msgid "STALL"
msgstr "PUESTO"
#: squirrelbattle/display/statsdisplay.py:40
#: squirrelbattle/display/statsdisplay.py:44
msgid "Inventory:"
msgstr "Inventorio :"
#: squirrelbattle/display/statsdisplay.py:57
#: squirrelbattle/display/statsdisplay.py:61
msgid "Equipped main:"
msgstr ""
#: squirrelbattle/display/statsdisplay.py:61
#: squirrelbattle/display/statsdisplay.py:65
msgid "Equipped secondary:"
msgstr ""
#: squirrelbattle/display/statsdisplay.py:66
#: squirrelbattle/display/statsdisplay.py:70
msgid "Equipped chestplate:"
msgstr ""
#: squirrelbattle/display/statsdisplay.py:70
#: squirrelbattle/display/statsdisplay.py:74
msgid "Equipped helmet:"
msgstr ""
#: squirrelbattle/display/statsdisplay.py:77
#: squirrelbattle/display/statsdisplay.py:81
msgid "YOU ARE DEAD"
msgstr "ERES MUERTO"
#: squirrelbattle/display/statsdisplay.py:85
#, python-brace-format
msgid "Use {key} to use the ladder"
msgstr ""
#: squirrelbattle/display/statsdisplay.py:94
msgid "Move to the friendly entity to talk to it"
msgstr ""
#: squirrelbattle/display/statsdisplay.py:96
#, python-brace-format
msgid "Use {key} then move to talk to the entity"
msgstr ""
#: squirrelbattle/entities/friendly.py:33
msgid "I don't sell any squirrel"
msgstr "No vendo ninguna ardilla"
@ -105,7 +125,7 @@ msgstr ""
msgid "The buyer does not have enough money"
msgstr "El comprador no tiene suficiente dinero"
#: squirrelbattle/game.py:347
#: squirrelbattle/game.py:349
msgid ""
"Some keys are missing in your save file.\n"
"Your save seems to be corrupt. It got deleted."
@ -113,7 +133,7 @@ msgstr ""
"Algunas claves faltan en su archivo de guarda.\n"
"Su guarda parece a ser corruptido. Fue eliminado."
#: squirrelbattle/game.py:355
#: squirrelbattle/game.py:357
msgid ""
"No player was found on this map!\n"
"Maybe you died?"
@ -121,7 +141,7 @@ msgstr ""
"No jugador encontrado sobre la carta !\n"
"¿ Quizas murió ?"
#: squirrelbattle/game.py:375
#: squirrelbattle/game.py:379
msgid ""
"The JSON file is not correct.\n"
"Your save seems corrupted. It got deleted."
@ -129,26 +149,26 @@ msgstr ""
"El JSON archivo no es correcto.\n"
"Su guarda parece corrupta. Fue eliminada."
#: squirrelbattle/interfaces.py:712
#: squirrelbattle/interfaces.py:718
msgid "It's a critical hit!"
msgstr ""
#: squirrelbattle/interfaces.py:713
#: squirrelbattle/interfaces.py:719
#, python-brace-format
msgid "{name} hits {opponent}."
msgstr "{name} golpea a {opponent}."
#: squirrelbattle/interfaces.py:727
#: squirrelbattle/interfaces.py:733
#, python-brace-format
msgid "{name} takes {damage} damage."
msgstr ""
#: squirrelbattle/interfaces.py:729
#: squirrelbattle/interfaces.py:735
#, python-brace-format
msgid "{name} dies."
msgstr "{name} se muere."
#: squirrelbattle/interfaces.py:763
#: squirrelbattle/interfaces.py:769
#, python-brace-format
msgid "{entity} said: {message}"
msgstr "{entity} dijo : {message}"
@ -283,42 +303,50 @@ msgstr "osito de peluche"
msgid "tiger"
msgstr "tigre"
#: squirrelbattle/tests/translations_test.py:71
#: squirrelbattle/tests/translations_test.py:70
msgid "eagle"
msgstr ""
#: squirrelbattle/tests/translations_test.py:72
msgid "body snatch potion"
msgstr "poción de intercambio"
#: squirrelbattle/tests/translations_test.py:72
#: squirrelbattle/tests/translations_test.py:73
msgid "bomb"
msgstr "bomba"
#: squirrelbattle/tests/translations_test.py:73
#: squirrelbattle/tests/translations_test.py:74
msgid "explosion"
msgstr "explosión"
#: squirrelbattle/tests/translations_test.py:74
#: squirrelbattle/tests/translations_test.py:75
msgid "heart"
msgstr "corazón"
#: squirrelbattle/tests/translations_test.py:75
#: squirrelbattle/tests/translations_test.py:76
msgid "sword"
msgstr "espada"
#: squirrelbattle/tests/translations_test.py:76
#: squirrelbattle/tests/translations_test.py:77
msgid "helmet"
msgstr ""
#: squirrelbattle/tests/translations_test.py:77
#: squirrelbattle/tests/translations_test.py:78
msgid "chestplate"
msgstr ""
#: squirrelbattle/tests/translations_test.py:78
#: squirrelbattle/tests/translations_test.py:79
msgid "shield"
msgstr ""
#: squirrelbattle/tests/translations_test.py:79
msgid "ring_of_critical_damage"
#: squirrelbattle/tests/translations_test.py:80
msgid "ring of critical damage"
msgstr ""
#: squirrelbattle/tests/translations_test.py:81
msgid "ring_of_more_experience"
#: squirrelbattle/tests/translations_test.py:82
msgid "ring of more experience"
msgstr ""
#: squirrelbattle/tests/translations_test.py:84
msgid "monocle"
msgstr ""

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: 2021-01-08 12:03+0100\n"
"POT-Creation-Date: 2021-01-08 15:15+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -43,30 +43,44 @@ msgstr "INVENTAIRE"
msgid "STALL"
msgstr "STAND"
#: squirrelbattle/display/statsdisplay.py:40
#: squirrelbattle/display/statsdisplay.py:44
msgid "Inventory:"
msgstr "Inventaire :"
#: squirrelbattle/display/statsdisplay.py:57
#: squirrelbattle/display/statsdisplay.py:61
msgid "Equipped main:"
msgstr "Équipement principal :"
#: squirrelbattle/display/statsdisplay.py:61
#: squirrelbattle/display/statsdisplay.py:65
msgid "Equipped secondary:"
msgstr "Équipement secondaire :"
#: squirrelbattle/display/statsdisplay.py:66
#: squirrelbattle/display/statsdisplay.py:70
msgid "Equipped chestplate:"
msgstr "Plastron équipé :"
#: squirrelbattle/display/statsdisplay.py:70
#: squirrelbattle/display/statsdisplay.py:74
msgid "Equipped helmet:"
msgstr "Casque équipé :"
#: squirrelbattle/display/statsdisplay.py:77
#: squirrelbattle/display/statsdisplay.py:81
msgid "YOU ARE DEAD"
msgstr "VOUS ÊTES MORT"
#: squirrelbattle/display/statsdisplay.py:85
#, python-brace-format
msgid "Use {key} to use the ladder"
msgstr "Appuyez sur {key} pour utiliser l'échelle"
#: squirrelbattle/display/statsdisplay.py:94
msgid "Move to the friendly entity to talk to it"
msgstr "Avancez vers l'entité pour lui parler"
#: squirrelbattle/display/statsdisplay.py:96
#, python-brace-format
msgid "Use {key} then move to talk to the entity"
msgstr "Appuyez sur {key} puis déplacez-vous pour parler"
#. TODO
#: squirrelbattle/entities/friendly.py:33
msgid "I don't sell any squirrel"
@ -106,7 +120,7 @@ msgstr "Le joueur monte à l'étage {floor}."
msgid "The buyer does not have enough money"
msgstr "L'acheteur n'a pas assez d'argent"
#: squirrelbattle/game.py:347
#: squirrelbattle/game.py:349
msgid ""
"Some keys are missing in your save file.\n"
"Your save seems to be corrupt. It got deleted."
@ -114,7 +128,7 @@ msgstr ""
"Certaines clés de votre ficher de sauvegarde sont manquantes.\n"
"Votre sauvegarde semble corrompue. Elle a été supprimée."
#: squirrelbattle/game.py:355
#: squirrelbattle/game.py:357
msgid ""
"No player was found on this map!\n"
"Maybe you died?"
@ -122,7 +136,7 @@ msgstr ""
"Aucun joueur n'a été trouvé sur la carte !\n"
"Peut-être êtes-vous mort ?"
#: squirrelbattle/game.py:375
#: squirrelbattle/game.py:379
msgid ""
"The JSON file is not correct.\n"
"Your save seems corrupted. It got deleted."
@ -130,26 +144,26 @@ msgstr ""
"Le fichier JSON de sauvegarde est incorrect.\n"
"Votre sauvegarde semble corrompue. Elle a été supprimée."
#: squirrelbattle/interfaces.py:712
#: squirrelbattle/interfaces.py:718
msgid "It's a critical hit!"
msgstr "C'est un coup critique !"
#: squirrelbattle/interfaces.py:713
#: squirrelbattle/interfaces.py:719
#, python-brace-format
msgid "{name} hits {opponent}."
msgstr "{name} frappe {opponent}."
#: squirrelbattle/interfaces.py:727
#: squirrelbattle/interfaces.py:733
#, python-brace-format
msgid "{name} takes {damage} damage."
msgstr "{name} prend {damage} dégâts."
#: squirrelbattle/interfaces.py:729
#: squirrelbattle/interfaces.py:735
#, python-brace-format
msgid "{name} dies."
msgstr "{name} meurt."
#: squirrelbattle/interfaces.py:763
#: squirrelbattle/interfaces.py:769
#, python-brace-format
msgid "{entity} said: {message}"
msgstr "{entity} a dit : {message}"
@ -284,42 +298,50 @@ msgstr "nounours"
msgid "tiger"
msgstr "tigre"
#: squirrelbattle/tests/translations_test.py:71
#: squirrelbattle/tests/translations_test.py:70
msgid "eagle"
msgstr "pygargue"
#: squirrelbattle/tests/translations_test.py:72
msgid "body snatch potion"
msgstr "potion d'arrachage de corps"
#: squirrelbattle/tests/translations_test.py:72
#: squirrelbattle/tests/translations_test.py:73
msgid "bomb"
msgstr "bombe"
#: squirrelbattle/tests/translations_test.py:73
#: squirrelbattle/tests/translations_test.py:74
msgid "explosion"
msgstr "explosion"
#: squirrelbattle/tests/translations_test.py:74
#: squirrelbattle/tests/translations_test.py:75
msgid "heart"
msgstr "cœur"
#: squirrelbattle/tests/translations_test.py:75
#: squirrelbattle/tests/translations_test.py:76
msgid "sword"
msgstr "épée"
#: squirrelbattle/tests/translations_test.py:76
#: squirrelbattle/tests/translations_test.py:77
msgid "helmet"
msgstr "casque"
#: squirrelbattle/tests/translations_test.py:77
#: squirrelbattle/tests/translations_test.py:78
msgid "chestplate"
msgstr "plastron"
#: squirrelbattle/tests/translations_test.py:78
#: squirrelbattle/tests/translations_test.py:79
msgid "shield"
msgstr "bouclier"
#: squirrelbattle/tests/translations_test.py:79
#: squirrelbattle/tests/translations_test.py:80
msgid "ring of critical damage"
msgstr "anneau de coup critique"
#: squirrelbattle/tests/translations_test.py:81
#: squirrelbattle/tests/translations_test.py:82
msgid "ring of more experience"
msgstr "anneau de plus d'expérience"
#: squirrelbattle/tests/translations_test.py:84
msgid "monocle"
msgstr "monocle"

View File

@ -1,11 +1,12 @@
# Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse
# SPDX-License-Identifier: GPL-3.0-or-later
import random
import unittest
from squirrelbattle.entities.items import BodySnatchPotion, Bomb, Heart, Item, \
Explosion
from squirrelbattle.entities.monsters import Tiger, Hedgehog, Rabbit, TeddyBear
from squirrelbattle.entities.monsters import Tiger, Hedgehog, Rabbit,\
TeddyBear, GiantSeaEagle
from squirrelbattle.entities.friendly import Trumpet
from squirrelbattle.entities.player import Player
from squirrelbattle.interfaces import Entity, Map
@ -264,3 +265,17 @@ class TestEntities(unittest.TestCase):
player_state = player.save_state()
self.assertEqual(player_state["current_xp"], 10)
def test_critical_hit(self) -> None:
"""
Ensure that critical hits are working.
"""
random.seed(2) # Next random.randint(1, 100) will output 8
self.player.critical = 10
sea_eagle = GiantSeaEagle()
self.map.add_entity(sea_eagle)
sea_eagle.move(2, 6)
old_health = sea_eagle.health
self.player.hit(sea_eagle)
self.assertEqual(sea_eagle.health,
old_health - self.player.strength * 4)

View File

@ -1,8 +1,8 @@
# Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse
# SPDX-License-Identifier: GPL-3.0-or-later
import curses
import os
import random
import unittest
from ..bootstrap import Bootstrap
@ -10,7 +10,7 @@ from ..display.display import Display
from ..display.display_manager import DisplayManager
from ..entities.friendly import Merchant, Sunflower
from ..entities.items import Bomb, Heart, Sword, Explosion, Shield, Helmet, \
Chestplate, RingCritical
Chestplate, RingCritical, Monocle
from ..entities.monsters import GiantSeaEagle
from ..entities.player import Player
from ..enums import DisplayActions
@ -66,6 +66,7 @@ class TestGame(unittest.TestCase):
new_state = self.game.save_state()
self.assertEqual(old_state, new_state)
self.assertIsNone(self.game.message)
# Ensure that the bomb is loaded
self.assertTrue(self.game.player.inventory)
@ -583,6 +584,7 @@ class TestGame(unittest.TestCase):
# Buy a heart
merchant.inventory[1] = Heart()
self.game.display_actions(DisplayActions.REFRESH)
item = self.game.store_menu.validate()
self.assertIn(item, merchant.inventory)
self.assertEqual(item, merchant.inventory[1])
@ -701,19 +703,21 @@ class TestGame(unittest.TestCase):
self.game.save_state()
ring.unequip()
def test_critical_hit(self) -> None:
def test_monocle(self) -> None:
"""
Ensure that critical hits are working.
The player is wearing a monocle, then the stats are displayed.
"""
random.seed(2) # Next random.randint(1, 100) will output 8
self.game.player.critical = 10
self.game.state = GameMode.PLAY
monocle = Monocle()
monocle.hold(self.game.player)
monocle.equip()
sea_eagle = GiantSeaEagle()
self.game.map.add_entity(sea_eagle)
sea_eagle.move(2, 6)
old_health = sea_eagle.health
self.game.player.hit(sea_eagle)
self.assertEqual(sea_eagle.health,
old_health - self.game.player.strength * 4)
self.game.display_actions(DisplayActions.REFRESH)
def test_ladders(self) -> None:
"""

View File

@ -67,6 +67,7 @@ class TestTranslations(unittest.TestCase):
self.assertEqual(_("sunflower"), "tournesol")
self.assertEqual(_("teddy bear"), "nounours")
self.assertEqual(_("tiger"), "tigre")
self.assertEqual(_("eagle"), "pygargue")
self.assertEqual(_("body snatch potion"), "potion d'arrachage de corps")
self.assertEqual(_("bomb"), "bombe")
@ -80,3 +81,4 @@ class TestTranslations(unittest.TestCase):
"anneau de coup critique")
self.assertEqual(_("ring of more experience"),
"anneau de plus d'expérience")
self.assertEqual(_("monocle"), "monocle")