Fixed grammar, unified the docstring's format and added documentation to some classes that did not have any. Closes #32.
This commit is contained in:
		@@ -24,9 +24,16 @@ class Display:
 | 
			
		||||
        self.pack = pack or TexturePack.get_pack("ascii")
 | 
			
		||||
 | 
			
		||||
    def newpad(self, height: int, width: int) -> Union[FakePad, Any]:
 | 
			
		||||
        """
 | 
			
		||||
        Overwrites the native curses function of the same name.
 | 
			
		||||
        """
 | 
			
		||||
        return curses.newpad(height, width) if self.screen else FakePad()
 | 
			
		||||
 | 
			
		||||
    def truncate(self, msg: str, height: int, width: int) -> str:
 | 
			
		||||
        """
 | 
			
		||||
        Truncates a string into a string adapted to the width and height of
 | 
			
		||||
        the screen.
 | 
			
		||||
        """
 | 
			
		||||
        height = max(0, height)
 | 
			
		||||
        width = max(0, width)
 | 
			
		||||
        lines = msg.split("\n")
 | 
			
		||||
@@ -36,8 +43,8 @@ class Display:
 | 
			
		||||
 | 
			
		||||
    def translate_color(self, color: Union[int, Tuple[int, int, int]]) -> int:
 | 
			
		||||
        """
 | 
			
		||||
        Translate a tuple (R, G, B) into a curses color index.
 | 
			
		||||
        If we have already a color index, then nothing is processed.
 | 
			
		||||
        Translates a tuple (R, G, B) into a curses color index.
 | 
			
		||||
        If we already have a color index, then nothing is processed.
 | 
			
		||||
        If this is a tuple, we construct a new color index if non-existing
 | 
			
		||||
        and we return this index.
 | 
			
		||||
        The values of R, G and B must be between 0 and 1000, and not
 | 
			
		||||
@@ -66,9 +73,9 @@ class Display:
 | 
			
		||||
               low: bool = False, right: bool = False, top: bool = False,
 | 
			
		||||
               vertical: bool = False, chartext: bool = False) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Display a message onto the pad.
 | 
			
		||||
        Displays a message onto the pad.
 | 
			
		||||
        If the message is too large, it is truncated vertically and horizontally
 | 
			
		||||
        The text can be bold, italic, blinking, ... if the good parameters are
 | 
			
		||||
        The text can be bold, italic, blinking, ... if the right parameters are
 | 
			
		||||
        given. These parameters are translated into curses attributes.
 | 
			
		||||
        The foreground and background colors can be given as curses constants
 | 
			
		||||
        (curses.COLOR_*), or by giving a tuple (R, G, B) that corresponds to
 | 
			
		||||
@@ -126,6 +133,9 @@ class Display:
 | 
			
		||||
 | 
			
		||||
    def resize(self, y: int, x: int, height: int, width: int,
 | 
			
		||||
               resize_pad: bool = True) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Resizes a pad.
 | 
			
		||||
        """
 | 
			
		||||
        self.x = x
 | 
			
		||||
        self.y = y
 | 
			
		||||
        self.width = width
 | 
			
		||||
@@ -136,6 +146,9 @@ class Display:
 | 
			
		||||
            self.pad.resize(self.height + 1, self.width + 1)
 | 
			
		||||
 | 
			
		||||
    def refresh(self, *args, resize_pad: bool = True) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Refreshes a pad
 | 
			
		||||
        """
 | 
			
		||||
        if len(args) == 4:
 | 
			
		||||
            self.resize(*args, resize_pad)
 | 
			
		||||
        self.display()
 | 
			
		||||
@@ -144,10 +157,10 @@ class Display:
 | 
			
		||||
                    window_y: int, window_x: int,
 | 
			
		||||
                    last_y: int, last_x: int) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Refresh a pad on a part of the window.
 | 
			
		||||
        Refreshes a pad on a part of the window.
 | 
			
		||||
        The refresh starts at coordinates (top_y, top_x) from the pad,
 | 
			
		||||
        and is drawn from (window_y, window_x) to (last_y, last_x).
 | 
			
		||||
        If coordinates are invalid (negative indexes/length..., then nothing
 | 
			
		||||
        If coordinates are invalid (negative indexes/length...), then nothing
 | 
			
		||||
        is drawn and no error is raised.
 | 
			
		||||
        """
 | 
			
		||||
        top_y, top_x = max(0, top_y), max(0, top_x)
 | 
			
		||||
@@ -167,7 +180,7 @@ class Display:
 | 
			
		||||
    def handle_click(self, y: int, x: int, game: Game) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        A mouse click was performed on the coordinates (y, x) of the pad.
 | 
			
		||||
        Maybe it can do something.
 | 
			
		||||
        Maybe it should do something.
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
@@ -181,7 +194,9 @@ class Display:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VerticalSplit(Display):
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    A class to split the screen in two vertically with a pretty line.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.pad = self.newpad(self.rows, 1)
 | 
			
		||||
@@ -202,7 +217,9 @@ class VerticalSplit(Display):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HorizontalSplit(Display):
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    A class to split the screen in two horizontally with a pretty line.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.pad = self.newpad(1, self.cols)
 | 
			
		||||
@@ -223,6 +240,9 @@ class HorizontalSplit(Display):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Box(Display):
 | 
			
		||||
    """
 | 
			
		||||
    A class for pretty boxes to print menus and other content.
 | 
			
		||||
    """
 | 
			
		||||
    title: str = ""
 | 
			
		||||
 | 
			
		||||
    def update_title(self, title: str) -> None:
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,9 @@ class DisplayManager:
 | 
			
		||||
        self.update_game_components()
 | 
			
		||||
 | 
			
		||||
    def handle_display_action(self, action: DisplayActions, *params) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Handles the differents values of display action.
 | 
			
		||||
        """
 | 
			
		||||
        if action == DisplayActions.REFRESH:
 | 
			
		||||
            self.refresh()
 | 
			
		||||
        elif action == DisplayActions.UPDATE:
 | 
			
		||||
@@ -49,6 +52,9 @@ class DisplayManager:
 | 
			
		||||
            self.handle_mouse_click(*params)
 | 
			
		||||
 | 
			
		||||
    def update_game_components(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Updates the game components, for example when loading a game.
 | 
			
		||||
        """
 | 
			
		||||
        for d in self.displays:
 | 
			
		||||
            d.pack = TexturePack.get_pack(self.game.settings.TEXTURE_PACK)
 | 
			
		||||
        self.mapdisplay.update_map(self.game.map)
 | 
			
		||||
@@ -62,6 +68,9 @@ class DisplayManager:
 | 
			
		||||
        self.messagedisplay.update_message(self.game.message)
 | 
			
		||||
 | 
			
		||||
    def handle_mouse_click(self, y: int, x: int) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Handles the mouse clicks.
 | 
			
		||||
        """
 | 
			
		||||
        displays = self.refresh()
 | 
			
		||||
        display = None
 | 
			
		||||
        for d in displays:
 | 
			
		||||
@@ -74,6 +83,9 @@ class DisplayManager:
 | 
			
		||||
            display.handle_click(y - display.y, x - display.x, self.game)
 | 
			
		||||
 | 
			
		||||
    def refresh(self) -> List[Display]:
 | 
			
		||||
        """
 | 
			
		||||
        Refreshes all components on the screen.
 | 
			
		||||
        """
 | 
			
		||||
        displays = []
 | 
			
		||||
 | 
			
		||||
        if self.game.state == GameMode.PLAY \
 | 
			
		||||
@@ -127,7 +139,7 @@ class DisplayManager:
 | 
			
		||||
 | 
			
		||||
    def resize_window(self) -> bool:
 | 
			
		||||
        """
 | 
			
		||||
        If the window got resized, ensure that the screen size got updated.
 | 
			
		||||
        When the window is resized, ensures that the screen size is updated.
 | 
			
		||||
        """
 | 
			
		||||
        y, x = self.screen.getmaxyx() if self.screen else (0, 0)
 | 
			
		||||
        if self.screen and curses.is_term_resized(self.rows,
 | 
			
		||||
@@ -138,8 +150,16 @@ class DisplayManager:
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def rows(self) -> int:
 | 
			
		||||
        """
 | 
			
		||||
        Overwrites the native curses attribute of the same name,
 | 
			
		||||
        for testing purposes.
 | 
			
		||||
        """
 | 
			
		||||
        return curses.LINES if self.screen else 42
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def cols(self) -> int:
 | 
			
		||||
        """
 | 
			
		||||
        Overwrites the native curses attribute of the same name,
 | 
			
		||||
        for testing purposes.
 | 
			
		||||
        """
 | 
			
		||||
        return curses.COLS if self.screen else 42
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,9 @@ from squirrelbattle.interfaces import Logs
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LogsDisplay(Display):
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    A class to handle the display of the logs.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, *args) -> None:
 | 
			
		||||
        super().__init__(*args)
 | 
			
		||||
        self.pad = self.newpad(self.rows, self.cols)
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,9 @@ from .display import Display
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MapDisplay(Display):
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    A class to handle the display of the map.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, *args):
 | 
			
		||||
        super().__init__(*args)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ from ..translations import gettext as _
 | 
			
		||||
 | 
			
		||||
class MenuDisplay(Display):
 | 
			
		||||
    """
 | 
			
		||||
    A class to display the menu objects
 | 
			
		||||
    A class to display the menu objects.
 | 
			
		||||
    """
 | 
			
		||||
    position: int
 | 
			
		||||
 | 
			
		||||
@@ -78,7 +78,7 @@ class MenuDisplay(Display):
 | 
			
		||||
 | 
			
		||||
class SettingsMenuDisplay(MenuDisplay):
 | 
			
		||||
    """
 | 
			
		||||
    A class to display specifically a settingsmenu object
 | 
			
		||||
    A class to display specifically a settingsmenu object.
 | 
			
		||||
    """
 | 
			
		||||
    @property
 | 
			
		||||
    def values(self) -> List[str]:
 | 
			
		||||
@@ -91,7 +91,7 @@ class SettingsMenuDisplay(MenuDisplay):
 | 
			
		||||
 | 
			
		||||
class MainMenuDisplay(Display):
 | 
			
		||||
    """
 | 
			
		||||
    A class to display specifically a mainmenu object
 | 
			
		||||
    A class to display specifically a mainmenu object.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, menu: MainMenu, *args):
 | 
			
		||||
        super().__init__(*args)
 | 
			
		||||
@@ -135,6 +135,9 @@ class MainMenuDisplay(Display):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PlayerInventoryDisplay(MenuDisplay):
 | 
			
		||||
    """
 | 
			
		||||
    A class to handle the display of the player's inventory.
 | 
			
		||||
    """
 | 
			
		||||
    def update_pad(self) -> None:
 | 
			
		||||
        self.menubox.update_title(_("INVENTORY"))
 | 
			
		||||
        for i, item in enumerate(self.menu.values):
 | 
			
		||||
@@ -160,6 +163,9 @@ class PlayerInventoryDisplay(MenuDisplay):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class StoreInventoryDisplay(MenuDisplay):
 | 
			
		||||
    """
 | 
			
		||||
    A class to handle the display of a merchant's inventory.
 | 
			
		||||
    """
 | 
			
		||||
    def update_pad(self) -> None:
 | 
			
		||||
        self.menubox.update_title(_("STALL"))
 | 
			
		||||
        for i, item in enumerate(self.menu.values):
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ from squirrelbattle.display.display import Box, Display
 | 
			
		||||
 | 
			
		||||
class MessageDisplay(Display):
 | 
			
		||||
    """
 | 
			
		||||
    Display a message in a popup.
 | 
			
		||||
    A class to handle the display of popup messages.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,9 @@ from .display import Display
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class StatsDisplay(Display):
 | 
			
		||||
    """
 | 
			
		||||
    A class to handle the display of the stats of the player.
 | 
			
		||||
    """
 | 
			
		||||
    player: Player
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,9 @@ from typing import Any
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TexturePack:
 | 
			
		||||
    """
 | 
			
		||||
    A class to handle displaying several textures.
 | 
			
		||||
    """
 | 
			
		||||
    _packs = dict()
 | 
			
		||||
 | 
			
		||||
    name: str
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ from random import choice
 | 
			
		||||
 | 
			
		||||
class Merchant(InventoryHolder, FriendlyEntity):
 | 
			
		||||
    """
 | 
			
		||||
    The class for merchants in the dungeon
 | 
			
		||||
    The class of merchants in the dungeon.
 | 
			
		||||
    """
 | 
			
		||||
    def keys(self) -> list:
 | 
			
		||||
        """
 | 
			
		||||
@@ -28,13 +28,13 @@ class Merchant(InventoryHolder, FriendlyEntity):
 | 
			
		||||
    def talk_to(self, player: Player) -> str:
 | 
			
		||||
        """
 | 
			
		||||
        This function is used to open the merchant's inventory in a menu,
 | 
			
		||||
        and allow the player to buy/sell objects
 | 
			
		||||
        and allows the player to buy/sell objects.
 | 
			
		||||
        """
 | 
			
		||||
        return _("I don't sell any squirrel")
 | 
			
		||||
 | 
			
		||||
    def change_hazel_balance(self, hz: int) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Change the number of hazel the merchant has by hz.
 | 
			
		||||
        Changes the number of hazel the merchant has by hz.
 | 
			
		||||
        """
 | 
			
		||||
        self.hazel += hz
 | 
			
		||||
 | 
			
		||||
@@ -49,4 +49,7 @@ class Sunflower(FriendlyEntity):
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def dialogue_option(self) -> list:
 | 
			
		||||
        """
 | 
			
		||||
        Lists all that a sunflower can say to the player.
 | 
			
		||||
        """
 | 
			
		||||
        return [_("Flower power!!"), _("The sun is warm today")]
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ from ..translations import gettext as _
 | 
			
		||||
 | 
			
		||||
class Item(Entity):
 | 
			
		||||
    """
 | 
			
		||||
    A class for items
 | 
			
		||||
    A class for items.
 | 
			
		||||
    """
 | 
			
		||||
    held: bool
 | 
			
		||||
    held_by: Optional[InventoryHolder]
 | 
			
		||||
@@ -27,7 +27,7 @@ class Item(Entity):
 | 
			
		||||
 | 
			
		||||
    def drop(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        The item is dropped from the inventory onto the floor
 | 
			
		||||
        The item is dropped from the inventory onto the floor.
 | 
			
		||||
        """
 | 
			
		||||
        if self.held:
 | 
			
		||||
            self.held_by.inventory.remove(self)
 | 
			
		||||
@@ -48,7 +48,7 @@ class Item(Entity):
 | 
			
		||||
 | 
			
		||||
    def hold(self, player: InventoryHolder) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        The item is taken from the floor and put into the inventory
 | 
			
		||||
        The item is taken from the floor and put into the inventory.
 | 
			
		||||
        """
 | 
			
		||||
        self.held = True
 | 
			
		||||
        self.held_by = player
 | 
			
		||||
@@ -57,7 +57,7 @@ class Item(Entity):
 | 
			
		||||
 | 
			
		||||
    def save_state(self) -> dict:
 | 
			
		||||
        """
 | 
			
		||||
        Saves the state of the entity into a dictionary
 | 
			
		||||
        Saves the state of the item into a dictionary.
 | 
			
		||||
        """
 | 
			
		||||
        d = super().save_state()
 | 
			
		||||
        d["held"] = self.held
 | 
			
		||||
@@ -65,13 +65,16 @@ class Item(Entity):
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def get_all_items() -> list:
 | 
			
		||||
        """
 | 
			
		||||
        Returns the list of all item classes.
 | 
			
		||||
        """
 | 
			
		||||
        return [BodySnatchPotion, Bomb, Heart, Sword]
 | 
			
		||||
 | 
			
		||||
    def be_sold(self, buyer: InventoryHolder, seller: InventoryHolder) -> bool:
 | 
			
		||||
        """
 | 
			
		||||
        Does all necessary actions when an object is to be sold.
 | 
			
		||||
        Is overwritten by some classes that cannot exist in the player's
 | 
			
		||||
        inventory
 | 
			
		||||
        inventory.
 | 
			
		||||
        """
 | 
			
		||||
        if buyer.hazel >= self.price:
 | 
			
		||||
            self.hold(buyer)
 | 
			
		||||
@@ -85,7 +88,7 @@ class Item(Entity):
 | 
			
		||||
 | 
			
		||||
class Heart(Item):
 | 
			
		||||
    """
 | 
			
		||||
    A heart item to return health to the player
 | 
			
		||||
    A heart item to return health to the player.
 | 
			
		||||
    """
 | 
			
		||||
    healing: int
 | 
			
		||||
 | 
			
		||||
@@ -96,14 +99,15 @@ class Heart(Item):
 | 
			
		||||
 | 
			
		||||
    def hold(self, entity: InventoryHolder) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        When holding a heart, heal the player and don't put item in inventory.
 | 
			
		||||
        When holding a heart, the player is healed and
 | 
			
		||||
        the item is not put in the inventory.
 | 
			
		||||
        """
 | 
			
		||||
        entity.health = min(entity.maxhealth, entity.health + self.healing)
 | 
			
		||||
        entity.map.remove_entity(self)
 | 
			
		||||
 | 
			
		||||
    def save_state(self) -> dict:
 | 
			
		||||
        """
 | 
			
		||||
        Saves the state of the header into a dictionary
 | 
			
		||||
        Saves the state of the heart into a dictionary.
 | 
			
		||||
        """
 | 
			
		||||
        d = super().save_state()
 | 
			
		||||
        d["healing"] = self.healing
 | 
			
		||||
@@ -129,7 +133,7 @@ class Bomb(Item):
 | 
			
		||||
 | 
			
		||||
    def use(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        When the bomb is used, throw it and explodes it.
 | 
			
		||||
        When the bomb is used, it is thrown and then it explodes.
 | 
			
		||||
        """
 | 
			
		||||
        if self.held:
 | 
			
		||||
            self.owner = self.held_by
 | 
			
		||||
@@ -138,7 +142,7 @@ class Bomb(Item):
 | 
			
		||||
 | 
			
		||||
    def act(self, m: Map) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Special exploding action of the bomb
 | 
			
		||||
        Special exploding action of the bomb.
 | 
			
		||||
        """
 | 
			
		||||
        if self.exploding:
 | 
			
		||||
            if self.tick > 0:
 | 
			
		||||
@@ -164,7 +168,7 @@ class Bomb(Item):
 | 
			
		||||
 | 
			
		||||
    def save_state(self) -> dict:
 | 
			
		||||
        """
 | 
			
		||||
        Saves the state of the bomb into a dictionary
 | 
			
		||||
        Saves the state of the bomb into a dictionary.
 | 
			
		||||
        """
 | 
			
		||||
        d = super().save_state()
 | 
			
		||||
        d["exploding"] = self.exploding
 | 
			
		||||
@@ -181,13 +185,13 @@ class Explosion(Item):
 | 
			
		||||
 | 
			
		||||
    def act(self, m: Map) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        The explosion instant dies.
 | 
			
		||||
        The bomb disappears after exploding.
 | 
			
		||||
        """
 | 
			
		||||
        m.remove_entity(self)
 | 
			
		||||
 | 
			
		||||
    def hold(self, player: InventoryHolder) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        The player can't hold any explosion.
 | 
			
		||||
        The player can't hold an explosion.
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,8 +10,8 @@ from ..interfaces import FightingEntity, Map
 | 
			
		||||
class Monster(FightingEntity):
 | 
			
		||||
    """
 | 
			
		||||
    The class for all monsters in the dungeon.
 | 
			
		||||
    A monster must override this class, and the parameters are given
 | 
			
		||||
    in the __init__ function.
 | 
			
		||||
    All specific monster classes overwrite this class,
 | 
			
		||||
    and the parameters are given in the __init__ function.
 | 
			
		||||
    An example of the specification of a monster that has a strength of 4
 | 
			
		||||
    and 20 max HP:
 | 
			
		||||
 | 
			
		||||
@@ -21,7 +21,7 @@ class Monster(FightingEntity):
 | 
			
		||||
            super().__init__(name="my_monster", strength=strength,
 | 
			
		||||
                             maxhealth=maxhealth, *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    With that way, attributes can be overwritten when the entity got created.
 | 
			
		||||
    With that way, attributes can be overwritten when the entity is created.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
@@ -29,7 +29,7 @@ class Monster(FightingEntity):
 | 
			
		||||
    def act(self, m: Map) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        By default, a monster will move randomly where it is possible
 | 
			
		||||
        And if a player is close to the monster, the monster run on the player.
 | 
			
		||||
        If the player is closeby, the monster runs to the player.
 | 
			
		||||
        """
 | 
			
		||||
        target = None
 | 
			
		||||
        for entity in m.entities:
 | 
			
		||||
@@ -38,12 +38,12 @@ class Monster(FightingEntity):
 | 
			
		||||
                target = entity
 | 
			
		||||
                break
 | 
			
		||||
 | 
			
		||||
        # A Dijkstra algorithm has ran that targets the player.
 | 
			
		||||
        # With that way, monsters can simply follow the path.
 | 
			
		||||
        # If they can't move and they are already close to the player,
 | 
			
		||||
        # They hit.
 | 
			
		||||
        # Monsters move according to a Dijkstra algorithm
 | 
			
		||||
        # that targets the player.
 | 
			
		||||
        # If they can not move and are already close to the player,
 | 
			
		||||
        # they hit.
 | 
			
		||||
        if target and (self.y, self.x) in target.paths:
 | 
			
		||||
            # Move to target player by choosing the best avaliable path
 | 
			
		||||
            # Moves to target player by choosing the best available path
 | 
			
		||||
            for next_y, next_x in target.paths[(self.y, self.x)]:
 | 
			
		||||
                moved = self.check_move(next_y, next_x, True)
 | 
			
		||||
                if moved:
 | 
			
		||||
@@ -52,8 +52,8 @@ class Monster(FightingEntity):
 | 
			
		||||
                    self.map.logs.add_message(self.hit(target))
 | 
			
		||||
                    break
 | 
			
		||||
        else:
 | 
			
		||||
            # Move in a random direction
 | 
			
		||||
            # If the direction is not available, try another one
 | 
			
		||||
            # Moves in a random direction
 | 
			
		||||
            # If the direction is not available, tries another one
 | 
			
		||||
            moves = [self.move_up, self.move_down,
 | 
			
		||||
                     self.move_left, self.move_right]
 | 
			
		||||
            shuffle(moves)
 | 
			
		||||
@@ -64,7 +64,7 @@ class Monster(FightingEntity):
 | 
			
		||||
 | 
			
		||||
class Tiger(Monster):
 | 
			
		||||
    """
 | 
			
		||||
    A tiger monster
 | 
			
		||||
    A tiger monster.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, name: str = "tiger", strength: int = 2,
 | 
			
		||||
                 maxhealth: int = 20, *args, **kwargs) -> None:
 | 
			
		||||
@@ -74,7 +74,7 @@ class Tiger(Monster):
 | 
			
		||||
 | 
			
		||||
class Hedgehog(Monster):
 | 
			
		||||
    """
 | 
			
		||||
    A really mean hedgehog monster
 | 
			
		||||
    A really mean hedgehog monster.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, name: str = "hedgehog", strength: int = 3,
 | 
			
		||||
                 maxhealth: int = 10, *args, **kwargs) -> None:
 | 
			
		||||
@@ -84,7 +84,7 @@ class Hedgehog(Monster):
 | 
			
		||||
 | 
			
		||||
class Rabbit(Monster):
 | 
			
		||||
    """
 | 
			
		||||
    A rabbit monster
 | 
			
		||||
    A rabbit monster.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, name: str = "rabbit", strength: int = 1,
 | 
			
		||||
                 maxhealth: int = 15, *args, **kwargs) -> None:
 | 
			
		||||
@@ -94,7 +94,7 @@ class Rabbit(Monster):
 | 
			
		||||
 | 
			
		||||
class TeddyBear(Monster):
 | 
			
		||||
    """
 | 
			
		||||
    A cute teddybear monster
 | 
			
		||||
    A cute teddybear monster.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, name: str = "teddy_bear", strength: int = 0,
 | 
			
		||||
                 maxhealth: int = 50, *args, **kwargs) -> None:
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ from ..interfaces import FightingEntity, InventoryHolder
 | 
			
		||||
 | 
			
		||||
class Player(InventoryHolder, FightingEntity):
 | 
			
		||||
    """
 | 
			
		||||
    The class of the player
 | 
			
		||||
    The class of the player.
 | 
			
		||||
    """
 | 
			
		||||
    current_xp: int = 0
 | 
			
		||||
    max_xp: int = 10
 | 
			
		||||
@@ -45,7 +45,7 @@ class Player(InventoryHolder, FightingEntity):
 | 
			
		||||
 | 
			
		||||
    def level_up(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Add levels to the player as much as it is possible.
 | 
			
		||||
        Add as many levels as possible to the player.
 | 
			
		||||
        """
 | 
			
		||||
        while self.current_xp > self.max_xp:
 | 
			
		||||
            self.level += 1
 | 
			
		||||
@@ -59,8 +59,8 @@ class Player(InventoryHolder, FightingEntity):
 | 
			
		||||
 | 
			
		||||
    def add_xp(self, xp: int) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Add some experience to the player.
 | 
			
		||||
        If the required amount is reached, level up.
 | 
			
		||||
        Adds some experience to the player.
 | 
			
		||||
        If the required amount is reached, the player levels up.
 | 
			
		||||
        """
 | 
			
		||||
        self.current_xp += xp
 | 
			
		||||
        self.level_up()
 | 
			
		||||
@@ -89,9 +89,8 @@ class Player(InventoryHolder, FightingEntity):
 | 
			
		||||
 | 
			
		||||
    def recalculate_paths(self, max_distance: int = 8) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Use Dijkstra algorithm to calculate best paths for monsters to go to
 | 
			
		||||
        the player. Actually, the paths are computed for each tile adjacent to
 | 
			
		||||
        the player then for each step the monsters use the best path avaliable.
 | 
			
		||||
        Uses Dijkstra algorithm to calculate best paths for monsters to go to
 | 
			
		||||
        the player.
 | 
			
		||||
        """
 | 
			
		||||
        distances = []
 | 
			
		||||
        predecessors = []
 | 
			
		||||
 
 | 
			
		||||
@@ -16,12 +16,11 @@ class DisplayActions(Enum):
 | 
			
		||||
    """
 | 
			
		||||
    REFRESH = auto()
 | 
			
		||||
    UPDATE = auto()
 | 
			
		||||
    MOUSE = auto()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GameMode(Enum):
 | 
			
		||||
    """
 | 
			
		||||
    Game mode options
 | 
			
		||||
    Game mode options.
 | 
			
		||||
    """
 | 
			
		||||
    MAINMENU = auto()
 | 
			
		||||
    PLAY = auto()
 | 
			
		||||
@@ -32,9 +31,8 @@ class GameMode(Enum):
 | 
			
		||||
 | 
			
		||||
class KeyValues(Enum):
 | 
			
		||||
    """
 | 
			
		||||
    Key values options used in the game
 | 
			
		||||
    Key values options used in the game.
 | 
			
		||||
    """
 | 
			
		||||
    MOUSE = auto()
 | 
			
		||||
    UP = auto()
 | 
			
		||||
    DOWN = auto()
 | 
			
		||||
    LEFT = auto()
 | 
			
		||||
@@ -46,12 +44,11 @@ class KeyValues(Enum):
 | 
			
		||||
    DROP = auto()
 | 
			
		||||
    SPACE = auto()
 | 
			
		||||
    CHAT = auto()
 | 
			
		||||
    WAIT = auto()
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def translate_key(key: str, settings: Settings) -> Optional["KeyValues"]:
 | 
			
		||||
        """
 | 
			
		||||
        Translate the raw string key into an enum value that we can use.
 | 
			
		||||
        Translates the raw string key into an enum value that we can use.
 | 
			
		||||
        """
 | 
			
		||||
        if key in (settings.KEY_DOWN_SECONDARY,
 | 
			
		||||
                   settings.KEY_DOWN_PRIMARY):
 | 
			
		||||
@@ -79,6 +76,4 @@ class KeyValues(Enum):
 | 
			
		||||
            return KeyValues.SPACE
 | 
			
		||||
        elif key == settings.KEY_CHAT:
 | 
			
		||||
            return KeyValues.CHAT
 | 
			
		||||
        elif key == settings.KEY_WAIT:
 | 
			
		||||
            return KeyValues.WAIT
 | 
			
		||||
        return None
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ class Game:
 | 
			
		||||
 | 
			
		||||
    def __init__(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Init the game.
 | 
			
		||||
        Initiates the game.
 | 
			
		||||
        """
 | 
			
		||||
        self.state = GameMode.MAINMENU
 | 
			
		||||
        self.waiting_for_friendly_key = False
 | 
			
		||||
@@ -48,7 +48,7 @@ class Game:
 | 
			
		||||
 | 
			
		||||
    def new_game(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Create a new game on the screen.
 | 
			
		||||
        Creates a new game on the screen.
 | 
			
		||||
        """
 | 
			
		||||
        # TODO generate a new map procedurally
 | 
			
		||||
        self.map = Map.load(ResourceManager.get_asset_path("example_map.txt"))
 | 
			
		||||
@@ -63,8 +63,8 @@ class Game:
 | 
			
		||||
    def run(self, screen: Any) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Main infinite loop.
 | 
			
		||||
        We wait for the player's action, then we do what that should be done
 | 
			
		||||
        when the given key gets pressed.
 | 
			
		||||
        We wait for the player's action, then we do what should be done
 | 
			
		||||
        when a key gets pressed.
 | 
			
		||||
        """
 | 
			
		||||
        while True:  # pragma no cover
 | 
			
		||||
            screen.erase()
 | 
			
		||||
@@ -81,7 +81,7 @@ class Game:
 | 
			
		||||
    def handle_key_pressed(self, key: Optional[KeyValues], raw_key: str = '')\
 | 
			
		||||
            -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Indicates what should be done when the given key is pressed,
 | 
			
		||||
        Indicates what should be done when a given key is pressed,
 | 
			
		||||
        according to the current game state.
 | 
			
		||||
        """
 | 
			
		||||
        if self.message:
 | 
			
		||||
@@ -133,8 +133,9 @@ class Game:
 | 
			
		||||
 | 
			
		||||
    def handle_friendly_entity_chat(self, key: KeyValues) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        If the player is talking to a friendly entity, we get the direction
 | 
			
		||||
        where the entity is, then we interact with it.
 | 
			
		||||
        If the player tries to talk to a friendly entity, the game waits for
 | 
			
		||||
        a directional key to be pressed, verifies there is a friendly entity
 | 
			
		||||
        in that direction and then lets the player interact with it.
 | 
			
		||||
        """
 | 
			
		||||
        if not self.waiting_for_friendly_key:
 | 
			
		||||
            return
 | 
			
		||||
@@ -210,7 +211,7 @@ class Game:
 | 
			
		||||
 | 
			
		||||
    def handle_key_pressed_main_menu(self, key: KeyValues) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        In the main menu, we can navigate through options.
 | 
			
		||||
        In the main menu, we can navigate through different options.
 | 
			
		||||
        """
 | 
			
		||||
        if key == KeyValues.DOWN:
 | 
			
		||||
            self.main_menu.go_down()
 | 
			
		||||
@@ -235,13 +236,13 @@ class Game:
 | 
			
		||||
 | 
			
		||||
    def save_state(self) -> dict:
 | 
			
		||||
        """
 | 
			
		||||
        Saves the game to a dictionary
 | 
			
		||||
        Saves the game to a dictionary.
 | 
			
		||||
        """
 | 
			
		||||
        return self.map.save_state()
 | 
			
		||||
 | 
			
		||||
    def load_state(self, d: dict) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Loads the game from a dictionary
 | 
			
		||||
        Loads the game from a dictionary.
 | 
			
		||||
        """
 | 
			
		||||
        try:
 | 
			
		||||
            self.map.load_state(d)
 | 
			
		||||
@@ -265,7 +266,7 @@ class Game:
 | 
			
		||||
 | 
			
		||||
    def load_game(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Loads the game from a file
 | 
			
		||||
        Loads the game from a file.
 | 
			
		||||
        """
 | 
			
		||||
        file_path = ResourceManager.get_config_path("save.json")
 | 
			
		||||
        if os.path.isfile(file_path):
 | 
			
		||||
@@ -282,7 +283,7 @@ class Game:
 | 
			
		||||
 | 
			
		||||
    def save_game(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Saves the game to a file
 | 
			
		||||
        Saves the game to a file.
 | 
			
		||||
        """
 | 
			
		||||
        with open(ResourceManager.get_config_path("save.json"), "w") as f:
 | 
			
		||||
            f.write(json.dumps(self.save_state()))
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ from .translations import gettext as _
 | 
			
		||||
 | 
			
		||||
class Logs:
 | 
			
		||||
    """
 | 
			
		||||
    The logs object stores the messages to display. It is encapsulating a list
 | 
			
		||||
    The logs object stores the messages to display. It encapsulates a list
 | 
			
		||||
    of such messages, to allow multiple pointers to keep track of it even if
 | 
			
		||||
    the list was to be reassigned.
 | 
			
		||||
    """
 | 
			
		||||
@@ -32,7 +32,7 @@ class Logs:
 | 
			
		||||
 | 
			
		||||
class Map:
 | 
			
		||||
    """
 | 
			
		||||
    Object that represents a Map with its width, height
 | 
			
		||||
    The Map object represents a with its width, height
 | 
			
		||||
    and tiles, that have their custom properties.
 | 
			
		||||
    """
 | 
			
		||||
    width: int
 | 
			
		||||
@@ -59,14 +59,14 @@ class Map:
 | 
			
		||||
 | 
			
		||||
    def add_entity(self, entity: "Entity") -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Register a new entity in the map.
 | 
			
		||||
        Registers a new entity in the map.
 | 
			
		||||
        """
 | 
			
		||||
        self.entities.append(entity)
 | 
			
		||||
        entity.map = self
 | 
			
		||||
 | 
			
		||||
    def remove_entity(self, entity: "Entity") -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Unregister an entity from the map.
 | 
			
		||||
        Unregisters an entity from the map.
 | 
			
		||||
        """
 | 
			
		||||
        if entity in self.entities:
 | 
			
		||||
            self.entities.remove(entity)
 | 
			
		||||
@@ -86,7 +86,7 @@ class Map:
 | 
			
		||||
    def entity_is_present(self, y: int, x: int) -> bool:
 | 
			
		||||
        """
 | 
			
		||||
        Indicates that the tile at the coordinates (y, x) contains a killable
 | 
			
		||||
        entity
 | 
			
		||||
        entity.
 | 
			
		||||
        """
 | 
			
		||||
        return 0 <= y < self.height and 0 <= x < self.width and \
 | 
			
		||||
            any(entity.x == x and entity.y == y and entity.is_friendly()
 | 
			
		||||
@@ -95,7 +95,7 @@ class Map:
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def load(filename: str) -> "Map":
 | 
			
		||||
        """
 | 
			
		||||
        Read a file that contains the content of a map, and build a Map object.
 | 
			
		||||
        Reads a file that contains the content of a map, and builds a Map object.
 | 
			
		||||
        """
 | 
			
		||||
        with open(filename, "r") as f:
 | 
			
		||||
            file = f.read()
 | 
			
		||||
@@ -104,7 +104,7 @@ class Map:
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def load_from_string(content: str) -> "Map":
 | 
			
		||||
        """
 | 
			
		||||
        Load a map represented by its characters and build a Map object.
 | 
			
		||||
        Loads a map represented by its characters and builds a Map object.
 | 
			
		||||
        """
 | 
			
		||||
        lines = content.split("\n")
 | 
			
		||||
        first_line = lines[0]
 | 
			
		||||
@@ -120,7 +120,7 @@ class Map:
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def load_dungeon_from_string(content: str) -> List[List["Tile"]]:
 | 
			
		||||
        """
 | 
			
		||||
        Transforms a string into the list of corresponding tiles
 | 
			
		||||
        Transforms a string into the list of corresponding tiles.
 | 
			
		||||
        """
 | 
			
		||||
        lines = content.split("\n")
 | 
			
		||||
        tiles = [[Tile.from_ascii_char(c)
 | 
			
		||||
@@ -129,7 +129,7 @@ class Map:
 | 
			
		||||
 | 
			
		||||
    def draw_string(self, pack: TexturePack) -> str:
 | 
			
		||||
        """
 | 
			
		||||
        Draw the current map as a string object that can be rendered
 | 
			
		||||
        Draws the current map as a string object that can be rendered
 | 
			
		||||
        in the window.
 | 
			
		||||
        """
 | 
			
		||||
        return "\n".join("".join(tile.char(pack) for tile in line)
 | 
			
		||||
@@ -137,7 +137,7 @@ class Map:
 | 
			
		||||
 | 
			
		||||
    def spawn_random_entities(self, count: int) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Put randomly {count} entities on the map, where it is available.
 | 
			
		||||
        Puts randomly {count} entities on the map, only on empty ground tiles.
 | 
			
		||||
        """
 | 
			
		||||
        for ignored in range(count):
 | 
			
		||||
            y, x = 0, 0
 | 
			
		||||
@@ -152,14 +152,14 @@ class Map:
 | 
			
		||||
 | 
			
		||||
    def tick(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Trigger all entity events.
 | 
			
		||||
        Triggers all entity events.
 | 
			
		||||
        """
 | 
			
		||||
        for entity in self.entities:
 | 
			
		||||
            entity.act(self)
 | 
			
		||||
 | 
			
		||||
    def save_state(self) -> dict:
 | 
			
		||||
        """
 | 
			
		||||
        Saves the map's attributes to a dictionary
 | 
			
		||||
        Saves the map's attributes to a dictionary.
 | 
			
		||||
        """
 | 
			
		||||
        d = dict()
 | 
			
		||||
        d["width"] = self.width
 | 
			
		||||
@@ -176,7 +176,7 @@ class Map:
 | 
			
		||||
 | 
			
		||||
    def load_state(self, d: dict) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Loads the map's attributes from a dictionary
 | 
			
		||||
        Loads the map's attributes from a dictionary.
 | 
			
		||||
        """
 | 
			
		||||
        self.width = d["width"]
 | 
			
		||||
        self.height = d["height"]
 | 
			
		||||
@@ -193,7 +193,7 @@ class Map:
 | 
			
		||||
 | 
			
		||||
class Tile(Enum):
 | 
			
		||||
    """
 | 
			
		||||
    The internal representation of the tiles of the map
 | 
			
		||||
    The internal representation of the tiles of the map.
 | 
			
		||||
    """
 | 
			
		||||
    EMPTY = auto()
 | 
			
		||||
    WALL = auto()
 | 
			
		||||
@@ -202,7 +202,7 @@ class Tile(Enum):
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def from_ascii_char(ch: str) -> "Tile":
 | 
			
		||||
        """
 | 
			
		||||
        Maps an ascii character to its equivalent in the texture pack
 | 
			
		||||
        Maps an ascii character to its equivalent in the texture pack.
 | 
			
		||||
        """
 | 
			
		||||
        for tile in Tile:
 | 
			
		||||
            if tile.char(TexturePack.ASCII_PACK) == ch:
 | 
			
		||||
@@ -212,7 +212,7 @@ class Tile(Enum):
 | 
			
		||||
    def char(self, pack: TexturePack) -> str:
 | 
			
		||||
        """
 | 
			
		||||
        Translates a Tile to the corresponding character according
 | 
			
		||||
        to the texture pack
 | 
			
		||||
        to the texture pack.
 | 
			
		||||
        """
 | 
			
		||||
        return getattr(pack, self.name)
 | 
			
		||||
 | 
			
		||||
@@ -224,14 +224,14 @@ class Tile(Enum):
 | 
			
		||||
 | 
			
		||||
    def can_walk(self) -> bool:
 | 
			
		||||
        """
 | 
			
		||||
        Check if an entity (player or not) can move in this tile.
 | 
			
		||||
        Checks if an entity (player or not) can move in this tile.
 | 
			
		||||
        """
 | 
			
		||||
        return not self.is_wall() and self != Tile.EMPTY
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Entity:
 | 
			
		||||
    """
 | 
			
		||||
    An Entity object represents any entity present on the map
 | 
			
		||||
    An Entity object represents any entity present on the map.
 | 
			
		||||
    """
 | 
			
		||||
    y: int
 | 
			
		||||
    x: int
 | 
			
		||||
@@ -249,7 +249,7 @@ class Entity:
 | 
			
		||||
    def check_move(self, y: int, x: int, move_if_possible: bool = False)\
 | 
			
		||||
            -> bool:
 | 
			
		||||
        """
 | 
			
		||||
        Checks if moving to (y,x) is authorized
 | 
			
		||||
        Checks if moving to (y,x) is authorized.
 | 
			
		||||
        """
 | 
			
		||||
        free = self.map.is_free(y, x)
 | 
			
		||||
        if free and move_if_possible:
 | 
			
		||||
@@ -258,7 +258,7 @@ class Entity:
 | 
			
		||||
 | 
			
		||||
    def move(self, y: int, x: int) -> bool:
 | 
			
		||||
        """
 | 
			
		||||
        Moves an entity to (y,x) coordinates
 | 
			
		||||
        Moves an entity to (y,x) coordinates.
 | 
			
		||||
        """
 | 
			
		||||
        self.y = y
 | 
			
		||||
        self.x = x
 | 
			
		||||
@@ -266,49 +266,49 @@ class Entity:
 | 
			
		||||
 | 
			
		||||
    def move_up(self, force: bool = False) -> bool:
 | 
			
		||||
        """
 | 
			
		||||
        Moves the entity up one tile, if possible
 | 
			
		||||
        Moves the entity up one tile, if possible.
 | 
			
		||||
        """
 | 
			
		||||
        return self.move(self.y - 1, self.x) if force else \
 | 
			
		||||
            self.check_move(self.y - 1, self.x, True)
 | 
			
		||||
 | 
			
		||||
    def move_down(self, force: bool = False) -> bool:
 | 
			
		||||
        """
 | 
			
		||||
        Moves the entity down one tile, if possible
 | 
			
		||||
        Moves the entity down one tile, if possible.
 | 
			
		||||
        """
 | 
			
		||||
        return self.move(self.y + 1, self.x) if force else \
 | 
			
		||||
            self.check_move(self.y + 1, self.x, True)
 | 
			
		||||
 | 
			
		||||
    def move_left(self, force: bool = False) -> bool:
 | 
			
		||||
        """
 | 
			
		||||
        Moves the entity left one tile, if possible
 | 
			
		||||
        Moves the entity left one tile, if possible.
 | 
			
		||||
        """
 | 
			
		||||
        return self.move(self.y, self.x - 1) if force else \
 | 
			
		||||
            self.check_move(self.y, self.x - 1, True)
 | 
			
		||||
 | 
			
		||||
    def move_right(self, force: bool = False) -> bool:
 | 
			
		||||
        """
 | 
			
		||||
        Moves the entity right one tile, if possible
 | 
			
		||||
        Moves the entity right one tile, if possible.
 | 
			
		||||
        """
 | 
			
		||||
        return self.move(self.y, self.x + 1) if force else \
 | 
			
		||||
            self.check_move(self.y, self.x + 1, True)
 | 
			
		||||
 | 
			
		||||
    def act(self, m: Map) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Define the action of the entity that is ran each tick.
 | 
			
		||||
        Defines the action the entity will do at each tick.
 | 
			
		||||
        By default, does nothing.
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def distance_squared(self, other: "Entity") -> int:
 | 
			
		||||
        """
 | 
			
		||||
        Get the square of the distance to another entity.
 | 
			
		||||
        Useful to check distances since square root takes time.
 | 
			
		||||
        Gives the square of the distance to another entity.
 | 
			
		||||
        Useful to check distances since taking the square root takes time.
 | 
			
		||||
        """
 | 
			
		||||
        return (self.y - other.y) ** 2 + (self.x - other.x) ** 2
 | 
			
		||||
 | 
			
		||||
    def distance(self, other: "Entity") -> float:
 | 
			
		||||
        """
 | 
			
		||||
        Get the cartesian distance to another entity.
 | 
			
		||||
        Gives the cartesian distance to another entity.
 | 
			
		||||
        """
 | 
			
		||||
        return sqrt(self.distance_squared(other))
 | 
			
		||||
 | 
			
		||||
@@ -340,12 +340,15 @@ class Entity:
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def translated_name(self) -> str:
 | 
			
		||||
        """
 | 
			
		||||
        Translates the name of entities.
 | 
			
		||||
        """
 | 
			
		||||
        return _(self.name.replace("_", " "))
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def get_all_entity_classes() -> list:
 | 
			
		||||
        """
 | 
			
		||||
        Returns all entities subclasses
 | 
			
		||||
        Returns all entities subclasses.
 | 
			
		||||
        """
 | 
			
		||||
        from squirrelbattle.entities.items import BodySnatchPotion, Bomb, Heart
 | 
			
		||||
        from squirrelbattle.entities.monsters import Tiger, Hedgehog, \
 | 
			
		||||
@@ -357,7 +360,7 @@ class Entity:
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def get_all_entity_classes_in_a_dict() -> dict:
 | 
			
		||||
        """
 | 
			
		||||
        Returns all entities subclasses in a dictionary
 | 
			
		||||
        Returns all entities subclasses in a dictionary.
 | 
			
		||||
        """
 | 
			
		||||
        from squirrelbattle.entities.player import Player
 | 
			
		||||
        from squirrelbattle.entities.monsters import Tiger, Hedgehog, Rabbit, \
 | 
			
		||||
@@ -381,7 +384,7 @@ class Entity:
 | 
			
		||||
 | 
			
		||||
    def save_state(self) -> dict:
 | 
			
		||||
        """
 | 
			
		||||
        Saves the coordinates of the entity
 | 
			
		||||
        Saves the coordinates of the entity.
 | 
			
		||||
        """
 | 
			
		||||
        d = dict()
 | 
			
		||||
        d["x"] = self.x
 | 
			
		||||
@@ -393,7 +396,7 @@ class Entity:
 | 
			
		||||
class FightingEntity(Entity):
 | 
			
		||||
    """
 | 
			
		||||
    A FightingEntity is an entity that can fight, and thus has a health,
 | 
			
		||||
    level and stats
 | 
			
		||||
    level and stats.
 | 
			
		||||
    """
 | 
			
		||||
    maxhealth: int
 | 
			
		||||
    health: int
 | 
			
		||||
@@ -420,11 +423,15 @@ class FightingEntity(Entity):
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def dead(self) -> bool:
 | 
			
		||||
        """
 | 
			
		||||
        Is this entity dead ?
 | 
			
		||||
        """
 | 
			
		||||
        return self.health <= 0
 | 
			
		||||
 | 
			
		||||
    def hit(self, opponent: "FightingEntity") -> str:
 | 
			
		||||
        """
 | 
			
		||||
        Deals damage to the opponent, based on the stats
 | 
			
		||||
        The entity deals damage to the opponent
 | 
			
		||||
        based on their respective stats.
 | 
			
		||||
        """
 | 
			
		||||
        return _("{name} hits {opponent}.")\
 | 
			
		||||
            .format(name=_(self.translated_name.capitalize()),
 | 
			
		||||
@@ -433,7 +440,8 @@ class FightingEntity(Entity):
 | 
			
		||||
 | 
			
		||||
    def take_damage(self, attacker: "Entity", amount: int) -> str:
 | 
			
		||||
        """
 | 
			
		||||
        Take damage from the attacker, based on the stats
 | 
			
		||||
        The entity takes damage from the attacker
 | 
			
		||||
        based on their respective stats.
 | 
			
		||||
        """
 | 
			
		||||
        self.health -= amount
 | 
			
		||||
        if self.health <= 0:
 | 
			
		||||
@@ -446,20 +454,20 @@ class FightingEntity(Entity):
 | 
			
		||||
 | 
			
		||||
    def die(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        If a fighting entity has no more health, it dies and is removed
 | 
			
		||||
        If a fighting entity has no more health, it dies and is removed.
 | 
			
		||||
        """
 | 
			
		||||
        self.map.remove_entity(self)
 | 
			
		||||
 | 
			
		||||
    def keys(self) -> list:
 | 
			
		||||
        """
 | 
			
		||||
        Returns a fighting entity's specific attributes
 | 
			
		||||
        Returns a fighting entity's specific attributes.
 | 
			
		||||
        """
 | 
			
		||||
        return ["name", "maxhealth", "health", "level", "strength",
 | 
			
		||||
                "intelligence", "charisma", "dexterity", "constitution"]
 | 
			
		||||
 | 
			
		||||
    def save_state(self) -> dict:
 | 
			
		||||
        """
 | 
			
		||||
        Saves the state of the entity into a dictionary
 | 
			
		||||
        Saves the state of the entity into a dictionary.
 | 
			
		||||
        """
 | 
			
		||||
        d = super().save_state()
 | 
			
		||||
        for name in self.keys():
 | 
			
		||||
@@ -469,7 +477,7 @@ class FightingEntity(Entity):
 | 
			
		||||
 | 
			
		||||
class FriendlyEntity(FightingEntity):
 | 
			
		||||
    """
 | 
			
		||||
    Friendly entities are living entities which do not attack the player
 | 
			
		||||
    Friendly entities are living entities which do not attack the player.
 | 
			
		||||
    """
 | 
			
		||||
    dialogue_option: list
 | 
			
		||||
 | 
			
		||||
@@ -480,7 +488,7 @@ class FriendlyEntity(FightingEntity):
 | 
			
		||||
 | 
			
		||||
    def keys(self) -> list:
 | 
			
		||||
        """
 | 
			
		||||
        Returns a friendly entity's specific attributes
 | 
			
		||||
        Returns a friendly entity's specific attributes.
 | 
			
		||||
        """
 | 
			
		||||
        return ["maxhealth", "health"]
 | 
			
		||||
 | 
			
		||||
@@ -491,7 +499,7 @@ class InventoryHolder(Entity):
 | 
			
		||||
 | 
			
		||||
    def translate_inventory(self, inventory: list) -> list:
 | 
			
		||||
        """
 | 
			
		||||
        Translate the JSON-state of the inventory into a list of the items in
 | 
			
		||||
        Translates the JSON save of the inventory into a list of the items in
 | 
			
		||||
        the inventory.
 | 
			
		||||
        """
 | 
			
		||||
        for i in range(len(inventory)):
 | 
			
		||||
@@ -501,7 +509,7 @@ class InventoryHolder(Entity):
 | 
			
		||||
 | 
			
		||||
    def dict_to_inventory(self, item_dict: dict) -> Entity:
 | 
			
		||||
        """
 | 
			
		||||
        Translate a dict object that contains the state of an item
 | 
			
		||||
        Translates a dictionnary that contains the state of an item
 | 
			
		||||
        into an item object.
 | 
			
		||||
        """
 | 
			
		||||
        entity_classes = self.get_all_entity_classes_in_a_dict()
 | 
			
		||||
@@ -511,7 +519,7 @@ class InventoryHolder(Entity):
 | 
			
		||||
 | 
			
		||||
    def save_state(self) -> dict:
 | 
			
		||||
        """
 | 
			
		||||
        We save the inventory of the merchant formatted as JSON
 | 
			
		||||
        The inventory of the merchant is saved in a JSON format.
 | 
			
		||||
        """
 | 
			
		||||
        d = super().save_state()
 | 
			
		||||
        d["hazel"] = self.hazel
 | 
			
		||||
@@ -520,19 +528,19 @@ class InventoryHolder(Entity):
 | 
			
		||||
 | 
			
		||||
    def add_to_inventory(self, obj: Any) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Adds an object to inventory
 | 
			
		||||
        Adds an object to the inventory.
 | 
			
		||||
        """
 | 
			
		||||
        self.inventory.append(obj)
 | 
			
		||||
 | 
			
		||||
    def remove_from_inventory(self, obj: Any) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Removes an object from the inventory
 | 
			
		||||
        Removes an object from the inventory.
 | 
			
		||||
        """
 | 
			
		||||
        self.inventory.remove(obj)
 | 
			
		||||
 | 
			
		||||
    def change_hazel_balance(self, hz: int) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Change the number of hazel the entity has by hz. hz is negative
 | 
			
		||||
        when the player loses money and positive when he gains money
 | 
			
		||||
        Changes the number of hazel the entity has by hz. hz is negative
 | 
			
		||||
        when the entity loses money and positive when it gains money.
 | 
			
		||||
        """
 | 
			
		||||
        self.hazel += hz
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ from .translations import gettext as _, Translator
 | 
			
		||||
 | 
			
		||||
class Menu:
 | 
			
		||||
    """
 | 
			
		||||
    A Menu object is the logical representation of a menu in the game
 | 
			
		||||
    A Menu object is the logical representation of a menu in the game.
 | 
			
		||||
    """
 | 
			
		||||
    values: list
 | 
			
		||||
 | 
			
		||||
@@ -23,26 +23,26 @@ class Menu:
 | 
			
		||||
 | 
			
		||||
    def go_up(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Moves the pointer of the menu on the previous value
 | 
			
		||||
        Moves the pointer of the menu on the previous value.
 | 
			
		||||
        """
 | 
			
		||||
        self.position = max(0, self.position - 1)
 | 
			
		||||
 | 
			
		||||
    def go_down(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Moves the pointer of the menu on the next value
 | 
			
		||||
        Moves the pointer of the menu on the next value.
 | 
			
		||||
        """
 | 
			
		||||
        self.position = min(len(self.values) - 1, self.position + 1)
 | 
			
		||||
 | 
			
		||||
    def validate(self) -> Any:
 | 
			
		||||
        """
 | 
			
		||||
        Selects the value that is pointed by the menu pointer
 | 
			
		||||
        Selects the value that is pointed by the menu pointer.
 | 
			
		||||
        """
 | 
			
		||||
        return self.values[self.position]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MainMenuValues(Enum):
 | 
			
		||||
    """
 | 
			
		||||
    Values of the main menu
 | 
			
		||||
    Values of the main menu.
 | 
			
		||||
    """
 | 
			
		||||
    START = "New game"
 | 
			
		||||
    RESUME = "Resume"
 | 
			
		||||
@@ -57,14 +57,14 @@ class MainMenuValues(Enum):
 | 
			
		||||
 | 
			
		||||
class MainMenu(Menu):
 | 
			
		||||
    """
 | 
			
		||||
    A special instance of a menu : the main menu
 | 
			
		||||
    A special instance of a menu : the main menu.
 | 
			
		||||
    """
 | 
			
		||||
    values = [e for e in MainMenuValues]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SettingsMenu(Menu):
 | 
			
		||||
    """
 | 
			
		||||
    A special instance of a menu : the settings menu
 | 
			
		||||
    A special instance of a menu : the settings menu.
 | 
			
		||||
    """
 | 
			
		||||
    waiting_for_key: bool = False
 | 
			
		||||
 | 
			
		||||
@@ -75,7 +75,7 @@ class SettingsMenu(Menu):
 | 
			
		||||
    def handle_key_pressed(self, key: Optional[KeyValues], raw_key: str,
 | 
			
		||||
                           game: Any) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        In the setting menu, we van select a setting and change it
 | 
			
		||||
        In the setting menu, we can select a setting and change it.
 | 
			
		||||
        """
 | 
			
		||||
        if not self.waiting_for_key:
 | 
			
		||||
            # Navigate normally through the menu.
 | 
			
		||||
@@ -121,22 +121,40 @@ class SettingsMenu(Menu):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class InventoryMenu(Menu):
 | 
			
		||||
    """
 | 
			
		||||
    A special instance of a menu : the menu for the inventory of the player.
 | 
			
		||||
    """
 | 
			
		||||
    player: Player
 | 
			
		||||
 | 
			
		||||
    def update_player(self, player: Player) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Updates the player.
 | 
			
		||||
        """
 | 
			
		||||
        self.player = player
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def values(self) -> list:
 | 
			
		||||
        """
 | 
			
		||||
        Returns the values of the menu.
 | 
			
		||||
        """
 | 
			
		||||
        return self.player.inventory
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class StoreMenu(Menu):
 | 
			
		||||
    """
 | 
			
		||||
    A special instance of a menu : the menu for the inventory of a merchant.
 | 
			
		||||
    """
 | 
			
		||||
    merchant: Merchant
 | 
			
		||||
 | 
			
		||||
    def update_merchant(self, merchant: Merchant) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Updates the merchant.
 | 
			
		||||
        """
 | 
			
		||||
        self.merchant = merchant
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def values(self) -> list:
 | 
			
		||||
        """
 | 
			
		||||
        Returns the values of the menu.
 | 
			
		||||
        """
 | 
			
		||||
        return self.merchant.inventory
 | 
			
		||||
 
 | 
			
		||||
@@ -13,9 +13,9 @@ from .translations import gettext as _
 | 
			
		||||
class Settings:
 | 
			
		||||
    """
 | 
			
		||||
    This class stores the settings of the game.
 | 
			
		||||
    Settings can be get by using for example settings.TEXTURE_PACK directly.
 | 
			
		||||
    The comment can be get by using settings.get_comment('TEXTURE_PACK').
 | 
			
		||||
    We can define the setting by simply use settings.TEXTURE_PACK = 'new_key'
 | 
			
		||||
    Settings can be obtained by using for example settings.TEXTURE_PACK directly.
 | 
			
		||||
    The comment can be obtained by using settings.get_comment('TEXTURE_PACK').
 | 
			
		||||
    We can set the setting by simply using settings.TEXTURE_PACK = 'new_key'
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.KEY_UP_PRIMARY = ['z', 'Main key to move up']
 | 
			
		||||
@@ -50,7 +50,7 @@ class Settings:
 | 
			
		||||
 | 
			
		||||
    def get_comment(self, item: str) -> str:
 | 
			
		||||
        """
 | 
			
		||||
        Retrieve the comment of a setting.
 | 
			
		||||
        Retrieves the comment relative to a setting.
 | 
			
		||||
        """
 | 
			
		||||
        if item in self.settings_keys:
 | 
			
		||||
            return _(object.__getattribute__(self, item)[1])
 | 
			
		||||
@@ -61,13 +61,13 @@ class Settings:
 | 
			
		||||
    @property
 | 
			
		||||
    def settings_keys(self) -> Generator[str, Any, None]:
 | 
			
		||||
        """
 | 
			
		||||
        Get the list of all parameters.
 | 
			
		||||
        Gets the list of all parameters.
 | 
			
		||||
        """
 | 
			
		||||
        return (key for key in self.__dict__)
 | 
			
		||||
 | 
			
		||||
    def loads_from_string(self, json_str: str) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Dump settings
 | 
			
		||||
        Loads settings.
 | 
			
		||||
        """
 | 
			
		||||
        d = json.loads(json_str)
 | 
			
		||||
        for key in d:
 | 
			
		||||
@@ -75,7 +75,7 @@ class Settings:
 | 
			
		||||
 | 
			
		||||
    def dumps_to_string(self) -> str:
 | 
			
		||||
        """
 | 
			
		||||
        Dump settings
 | 
			
		||||
        Dumps settings.
 | 
			
		||||
        """
 | 
			
		||||
        d = dict()
 | 
			
		||||
        for key in self.settings_keys:
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ from types import TracebackType
 | 
			
		||||
class TermManager:  # pragma: no cover
 | 
			
		||||
    """
 | 
			
		||||
    The TermManager object initializes the terminal, returns a screen object and
 | 
			
		||||
    de-initializes the terminal after use
 | 
			
		||||
    de-initializes the terminal after use.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.screen = curses.initscr()
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ from squirrelbattle.resources import ResourceManager
 | 
			
		||||
class TestEntities(unittest.TestCase):
 | 
			
		||||
    def setUp(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Load example map that can be used in tests.
 | 
			
		||||
        Loads example map that can be used in tests.
 | 
			
		||||
        """
 | 
			
		||||
        self.map = Map.load(ResourceManager.get_asset_path("example_map.txt"))
 | 
			
		||||
        self.player = Player()
 | 
			
		||||
@@ -23,7 +23,7 @@ class TestEntities(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_basic_entities(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test some random stuff with basic entities.
 | 
			
		||||
        Tests some random stuff with basic entities.
 | 
			
		||||
        """
 | 
			
		||||
        entity = Entity()
 | 
			
		||||
        entity.move(42, 64)
 | 
			
		||||
@@ -38,7 +38,7 @@ class TestEntities(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_fighting_entities(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test some random stuff with fighting entities.
 | 
			
		||||
        Tests some random stuff with fighting entities.
 | 
			
		||||
        """
 | 
			
		||||
        entity = Tiger()
 | 
			
		||||
        self.map.add_entity(entity)
 | 
			
		||||
@@ -91,7 +91,7 @@ class TestEntities(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_items(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test some random stuff with items.
 | 
			
		||||
        Tests some random stuff with items.
 | 
			
		||||
        """
 | 
			
		||||
        item = Item()
 | 
			
		||||
        self.map.add_entity(item)
 | 
			
		||||
@@ -112,7 +112,7 @@ class TestEntities(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_bombs(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test some random stuff with bombs.
 | 
			
		||||
        Tests some random stuff with bombs.
 | 
			
		||||
        """
 | 
			
		||||
        item = Bomb()
 | 
			
		||||
        hedgehog = Hedgehog()
 | 
			
		||||
@@ -156,7 +156,7 @@ class TestEntities(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_hearts(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test some random stuff with hearts.
 | 
			
		||||
        Tests some random stuff with hearts.
 | 
			
		||||
        """
 | 
			
		||||
        item = Heart()
 | 
			
		||||
        self.map.add_entity(item)
 | 
			
		||||
@@ -171,7 +171,7 @@ class TestEntities(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_body_snatch_potion(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test some random stuff with body snatch potions.
 | 
			
		||||
        Tests some random stuff with body snatch potions.
 | 
			
		||||
        """
 | 
			
		||||
        item = BodySnatchPotion()
 | 
			
		||||
        self.map.add_entity(item)
 | 
			
		||||
@@ -189,7 +189,7 @@ class TestEntities(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_players(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test some random stuff with players.
 | 
			
		||||
        Tests some random stuff with players.
 | 
			
		||||
        """
 | 
			
		||||
        player = Player()
 | 
			
		||||
        self.map.add_entity(player)
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ from ..translations import gettext as _, Translator
 | 
			
		||||
class TestGame(unittest.TestCase):
 | 
			
		||||
    def setUp(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Setup game.
 | 
			
		||||
        Sets the game up.
 | 
			
		||||
        """
 | 
			
		||||
        self.game = Game()
 | 
			
		||||
        self.game.new_game()
 | 
			
		||||
@@ -31,7 +31,7 @@ class TestGame(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_load_game(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Save a game and reload it.
 | 
			
		||||
        Saves a game and reloads it.
 | 
			
		||||
        """
 | 
			
		||||
        bomb = Bomb()
 | 
			
		||||
        self.game.map.add_entity(bomb)
 | 
			
		||||
@@ -85,7 +85,7 @@ class TestGame(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_bootstrap_fail(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Ensure that the test can't play the game,
 | 
			
		||||
        Ensures that the test can't play the game,
 | 
			
		||||
        because there is no associated shell.
 | 
			
		||||
        Yeah, that's only for coverage.
 | 
			
		||||
        """
 | 
			
		||||
@@ -94,7 +94,7 @@ class TestGame(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_key_translation(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test key bindings.
 | 
			
		||||
        Tests key bindings.
 | 
			
		||||
        """
 | 
			
		||||
        self.game.settings = Settings()
 | 
			
		||||
 | 
			
		||||
@@ -150,7 +150,7 @@ class TestGame(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_key_press(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Press a key and see what is done.
 | 
			
		||||
        Presses a key and asserts what is done is correct.
 | 
			
		||||
        """
 | 
			
		||||
        self.assertEqual(self.game.state, GameMode.MAINMENU)
 | 
			
		||||
        self.assertEqual(self.game.main_menu.validate(),
 | 
			
		||||
@@ -241,7 +241,7 @@ class TestGame(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_mouse_click(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Simulate mouse clicks.
 | 
			
		||||
        Simulates mouse clicks.
 | 
			
		||||
        """
 | 
			
		||||
        self.game.state = GameMode.MAINMENU
 | 
			
		||||
 | 
			
		||||
@@ -271,7 +271,7 @@ class TestGame(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_new_game(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Ensure that the start button starts a new game.
 | 
			
		||||
        Ensures that the start button starts a new game.
 | 
			
		||||
        """
 | 
			
		||||
        old_map = self.game.map
 | 
			
		||||
        old_player = self.game.player
 | 
			
		||||
@@ -294,7 +294,7 @@ class TestGame(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_settings_menu(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Ensure that the settings menu is working properly.
 | 
			
		||||
        Ensures that the settings menu is working properly.
 | 
			
		||||
        """
 | 
			
		||||
        self.game.settings = Settings()
 | 
			
		||||
 | 
			
		||||
@@ -380,7 +380,7 @@ class TestGame(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_dead_screen(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Kill player and render dead screen.
 | 
			
		||||
        Kills the player and renders the dead message on the fake screen.
 | 
			
		||||
        """
 | 
			
		||||
        self.game.state = GameMode.PLAY
 | 
			
		||||
        # Kill player
 | 
			
		||||
@@ -396,13 +396,13 @@ class TestGame(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_not_implemented(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Check that some functions are not implemented, only for coverage.
 | 
			
		||||
        Checks that some functions are not implemented, only for coverage.
 | 
			
		||||
        """
 | 
			
		||||
        self.assertRaises(NotImplementedError, Display.display, None)
 | 
			
		||||
 | 
			
		||||
    def test_messages(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Display error messages.
 | 
			
		||||
        Displays error messages.
 | 
			
		||||
        """
 | 
			
		||||
        self.game.message = "I am an error"
 | 
			
		||||
        self.game.display_actions(DisplayActions.UPDATE)
 | 
			
		||||
@@ -412,7 +412,7 @@ class TestGame(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_inventory_menu(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Open the inventory menu and interact with items.
 | 
			
		||||
        Opens the inventory menu and interacts with items.
 | 
			
		||||
        """
 | 
			
		||||
        self.game.state = GameMode.PLAY
 | 
			
		||||
        # Open and close the inventory
 | 
			
		||||
@@ -473,7 +473,7 @@ class TestGame(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_talk_to_sunflowers(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Interact with sunflowers
 | 
			
		||||
        Interacts with sunflowers.
 | 
			
		||||
        """
 | 
			
		||||
        self.game.state = GameMode.PLAY
 | 
			
		||||
 | 
			
		||||
@@ -524,7 +524,7 @@ class TestGame(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_talk_to_merchant(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Interact with merchants
 | 
			
		||||
        Interacts with merchants.
 | 
			
		||||
        """
 | 
			
		||||
        self.game.state = GameMode.PLAY
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ from squirrelbattle.resources import ResourceManager
 | 
			
		||||
class TestInterfaces(unittest.TestCase):
 | 
			
		||||
    def test_map(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Create a map and check that it is well parsed.
 | 
			
		||||
        Creates a map and checks that it is well parsed.
 | 
			
		||||
        """
 | 
			
		||||
        m = Map.load_from_string("0 0\n.#\n#.\n")
 | 
			
		||||
        self.assertEqual(m.width, 2)
 | 
			
		||||
@@ -20,7 +20,7 @@ class TestInterfaces(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_load_map(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Try to load a map from a file.
 | 
			
		||||
        Tries to load a map from a file.
 | 
			
		||||
        """
 | 
			
		||||
        m = Map.load(ResourceManager.get_asset_path("example_map.txt"))
 | 
			
		||||
        self.assertEqual(m.width, 52)
 | 
			
		||||
@@ -28,7 +28,7 @@ class TestInterfaces(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_tiles(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test some things about tiles.
 | 
			
		||||
        Tests some things about tiles.
 | 
			
		||||
        """
 | 
			
		||||
        self.assertFalse(Tile.FLOOR.is_wall())
 | 
			
		||||
        self.assertTrue(Tile.WALL.is_wall())
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ class TestSettings(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_settings(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Ensure that settings are well loaded.
 | 
			
		||||
        Ensures that settings are well loaded.
 | 
			
		||||
        """
 | 
			
		||||
        settings = Settings()
 | 
			
		||||
        self.assertEqual(settings.KEY_UP_PRIMARY, 'z')
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ class TestTranslations(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_main_menu_translation(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Ensure that the main menu is translated.
 | 
			
		||||
        Ensures that the main menu is translated.
 | 
			
		||||
        """
 | 
			
		||||
        self.assertEqual(_("New game"), "Nouvelle partie")
 | 
			
		||||
        self.assertEqual(_("Resume"), "Continuer")
 | 
			
		||||
@@ -22,7 +22,7 @@ class TestTranslations(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_settings_menu_translation(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Ensure that the settings menu is translated.
 | 
			
		||||
        Ensures that the settings menu is translated.
 | 
			
		||||
        """
 | 
			
		||||
        self.assertEqual(_("Main key to move up"),
 | 
			
		||||
                         "Touche principale pour aller vers le haut")
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ class Translator:
 | 
			
		||||
    """
 | 
			
		||||
    This module uses gettext to translate strings.
 | 
			
		||||
    Translator.setlocale defines the language of the strings,
 | 
			
		||||
    then gettext() translates the message.
 | 
			
		||||
    then gettext() translates the messages.
 | 
			
		||||
    """
 | 
			
		||||
    SUPPORTED_LOCALES: List[str] = ["de", "en", "es", "fr"]
 | 
			
		||||
    locale: str = "en"
 | 
			
		||||
@@ -22,7 +22,7 @@ class Translator:
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def refresh_translations(cls) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Load compiled translations.
 | 
			
		||||
        Loads compiled translations.
 | 
			
		||||
        """
 | 
			
		||||
        for language in cls.SUPPORTED_LOCALES:
 | 
			
		||||
            rep = Path(__file__).parent / "locale" / language / "LC_MESSAGES"
 | 
			
		||||
@@ -37,7 +37,7 @@ class Translator:
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def setlocale(cls, lang: str) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Define the language used to translate the game.
 | 
			
		||||
        Defines the language used to translate the game.
 | 
			
		||||
        The language must be supported, otherwise nothing is done.
 | 
			
		||||
        """
 | 
			
		||||
        lang = lang[:2]
 | 
			
		||||
@@ -51,7 +51,7 @@ class Translator:
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def makemessages(cls) -> None:  # pragma: no cover
 | 
			
		||||
        """
 | 
			
		||||
        Analyse all strings in the project and extract them.
 | 
			
		||||
        Analyses all strings in the project and extracts them.
 | 
			
		||||
        """
 | 
			
		||||
        for language in cls.SUPPORTED_LOCALES:
 | 
			
		||||
            if language == "en":
 | 
			
		||||
@@ -83,7 +83,7 @@ class Translator:
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def compilemessages(cls) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Compile translation messages from source files.
 | 
			
		||||
        Compiles translation messages from source files.
 | 
			
		||||
        """
 | 
			
		||||
        for language in cls.SUPPORTED_LOCALES:
 | 
			
		||||
            if language == "en":
 | 
			
		||||
@@ -99,7 +99,7 @@ class Translator:
 | 
			
		||||
 | 
			
		||||
def gettext(message: str) -> str:
 | 
			
		||||
    """
 | 
			
		||||
    Translate a message.
 | 
			
		||||
    Translates a message.
 | 
			
		||||
    """
 | 
			
		||||
    return Translator.get_translator().gettext(message)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user