Merge branch 'master' into 'familiars'
# Conflicts: # squirrelbattle/display/display_manager.py # squirrelbattle/display/logsdisplay.py # squirrelbattle/display/mapdisplay.py # squirrelbattle/display/menudisplay.py # squirrelbattle/menus.py
This commit is contained in:
		@@ -172,9 +172,19 @@ class Display:
 | 
			
		||||
 | 
			
		||||
        if last_y >= window_y and last_x >= window_x:
 | 
			
		||||
            # Refresh the pad only if coordinates are valid
 | 
			
		||||
            pad.refresh(top_y, top_x, window_y, window_x, last_y, last_x)
 | 
			
		||||
            pad.noutrefresh(top_y, top_x, window_y, window_x, last_y, last_x)
 | 
			
		||||
 | 
			
		||||
    def display(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Draw the content of the display and refresh pads.
 | 
			
		||||
        """
 | 
			
		||||
        raise NotImplementedError
 | 
			
		||||
 | 
			
		||||
    def update(self, game: Game) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        The game state was updated.
 | 
			
		||||
        Indicate what to do with the new state.
 | 
			
		||||
        """
 | 
			
		||||
        raise NotImplementedError
 | 
			
		||||
 | 
			
		||||
    def handle_click(self, y: int, x: int, game: Game) -> None:
 | 
			
		||||
 
 | 
			
		||||
@@ -56,19 +56,12 @@ class DisplayManager:
 | 
			
		||||
 | 
			
		||||
    def update_game_components(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Updates the game components, for example when loading a game.
 | 
			
		||||
        The game state was updated.
 | 
			
		||||
        Trigger all displays of these modifications.
 | 
			
		||||
        """
 | 
			
		||||
        for d in self.displays:
 | 
			
		||||
            d.pack = TexturePack.get_pack(self.game.settings.TEXTURE_PACK)
 | 
			
		||||
        self.mapdisplay.update_map(self.game.map)
 | 
			
		||||
        self.statsdisplay.update_player(self.game.player)
 | 
			
		||||
        self.game.inventory_menu.update_player(self.game.player)
 | 
			
		||||
        self.game.store_menu.update_merchant(self.game.player)
 | 
			
		||||
        self.playerinventorydisplay.update_menu(self.game.inventory_menu)
 | 
			
		||||
        self.storeinventorydisplay.update_menu(self.game.store_menu)
 | 
			
		||||
        self.settingsmenudisplay.update_menu(self.game.settings_menu)
 | 
			
		||||
        self.logsdisplay.update_logs(self.game.logs)
 | 
			
		||||
        self.messagedisplay.update_message(self.game.message)
 | 
			
		||||
            d.update(self.game)
 | 
			
		||||
 | 
			
		||||
    def handle_mouse_click(self, y: int, x: int) -> None:
 | 
			
		||||
        """
 | 
			
		||||
@@ -90,6 +83,7 @@ class DisplayManager:
 | 
			
		||||
        Refreshes all components on the screen.
 | 
			
		||||
        """
 | 
			
		||||
        displays = []
 | 
			
		||||
        pack = TexturePack.get_pack(self.game.settings.TEXTURE_PACK)
 | 
			
		||||
 | 
			
		||||
        if self.game.state == GameMode.PLAY \
 | 
			
		||||
                or self.game.state == GameMode.INVENTORY \
 | 
			
		||||
@@ -112,14 +106,24 @@ class DisplayManager:
 | 
			
		||||
 | 
			
		||||
            if self.game.state == GameMode.INVENTORY:
 | 
			
		||||
                self.playerinventorydisplay.refresh(
 | 
			
		||||
                    self.rows // 10, self.cols // 2,
 | 
			
		||||
                    8 * self.rows // 10, 2 * self.cols // 5)
 | 
			
		||||
                    self.rows // 10,
 | 
			
		||||
                    pack.tile_width * (self.cols // (2 * pack.tile_width)),
 | 
			
		||||
                    8 * self.rows // 10,
 | 
			
		||||
                    pack.tile_width * (2 * self.cols // (5 * pack.tile_width)))
 | 
			
		||||
                displays.append(self.playerinventorydisplay)
 | 
			
		||||
            elif self.game.state == GameMode.STORE:
 | 
			
		||||
                self.storeinventorydisplay.refresh(
 | 
			
		||||
                    self.rows // 10, self.cols // 2,
 | 
			
		||||
                    8 * self.rows // 10, 2 * self.cols // 5)
 | 
			
		||||
                    self.rows // 10,
 | 
			
		||||
                    pack.tile_width * (self.cols // (2 * pack.tile_width)),
 | 
			
		||||
                    8 * self.rows // 10,
 | 
			
		||||
                    pack.tile_width * (2 * self.cols // (5 * pack.tile_width)))
 | 
			
		||||
                self.playerinventorydisplay.refresh(
 | 
			
		||||
                    self.rows // 10,
 | 
			
		||||
                    pack.tile_width * (self.cols // (10 * pack.tile_width)),
 | 
			
		||||
                    8 * self.rows // 10,
 | 
			
		||||
                    pack.tile_width * (2 * self.cols // (5 * pack.tile_width)))
 | 
			
		||||
                displays.append(self.storeinventorydisplay)
 | 
			
		||||
                displays.append(self.playerinventorydisplay)
 | 
			
		||||
        elif self.game.state == GameMode.MAINMENU:
 | 
			
		||||
            self.mainmenudisplay.refresh(0, 0, self.rows, self.cols)
 | 
			
		||||
            displays.append(self.mainmenudisplay)
 | 
			
		||||
@@ -135,7 +139,8 @@ class DisplayManager:
 | 
			
		||||
            for line in self.game.message.split("\n"):
 | 
			
		||||
                height += 1
 | 
			
		||||
                width = max(width, len(line))
 | 
			
		||||
            y, x = (self.rows - height) // 2, (self.cols - width) // 2
 | 
			
		||||
            y = pack.tile_width * (self.rows - height) // (2 * pack.tile_width)
 | 
			
		||||
            x = pack.tile_width * ((self.cols - width) // (2 * pack.tile_width))
 | 
			
		||||
            self.messagedisplay.refresh(y, x, height, width)
 | 
			
		||||
            displays.append(self.messagedisplay)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
from squirrelbattle.display.display import Display
 | 
			
		||||
from squirrelbattle.game import Game
 | 
			
		||||
from squirrelbattle.interfaces import Logs
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -9,12 +10,14 @@ class LogsDisplay(Display):
 | 
			
		||||
    """
 | 
			
		||||
    A class to handle the display of the logs.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    logs: Logs
 | 
			
		||||
    def __init__(self, *args) -> None:
 | 
			
		||||
        super().__init__(*args)
 | 
			
		||||
        self.pad = self.newpad(self.rows, self.cols)
 | 
			
		||||
 | 
			
		||||
    def update_logs(self, logs: Logs) -> None:
 | 
			
		||||
        self.logs = logs
 | 
			
		||||
    def update(self, game: Game) -> None:
 | 
			
		||||
        self.logs = game.logs
 | 
			
		||||
 | 
			
		||||
    def display(self) -> None:
 | 
			
		||||
        messages = self.logs.messages[-self.height:]
 | 
			
		||||
 
 | 
			
		||||
@@ -3,20 +3,25 @@
 | 
			
		||||
 | 
			
		||||
from squirrelbattle.interfaces import Map
 | 
			
		||||
from .display import Display
 | 
			
		||||
from ..game import Game
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MapDisplay(Display):
 | 
			
		||||
    """
 | 
			
		||||
    A class to handle the display of the map.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    map: Map
 | 
			
		||||
    def __init__(self, *args):
 | 
			
		||||
        super().__init__(*args)
 | 
			
		||||
 | 
			
		||||
    def update_map(self, m: Map) -> None:
 | 
			
		||||
        self.map = m
 | 
			
		||||
        self.pad = self.newpad(m.height, self.pack.tile_width * m.width + 1)
 | 
			
		||||
    def update(self, game: Game) -> None:
 | 
			
		||||
        self.map = game.map
 | 
			
		||||
        self.pad = self.newpad(self.map.height,
 | 
			
		||||
                               self.pack.tile_width * self.map.width + 1)
 | 
			
		||||
 | 
			
		||||
    def update_pad(self) -> None:
 | 
			
		||||
        self.pad.resize(500, 500)
 | 
			
		||||
        self.addstr(self.pad, 0, 0, self.map.draw_string(self.pack),
 | 
			
		||||
                    self.pack.tile_fg_color, self.pack.tile_bg_color)
 | 
			
		||||
        for e in self.map.entities:
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,9 @@ import curses
 | 
			
		||||
from random import randint
 | 
			
		||||
from typing import List
 | 
			
		||||
 | 
			
		||||
from squirrelbattle.menus import Menu, MainMenu
 | 
			
		||||
from squirrelbattle.menus import Menu, MainMenu, SettingsMenu, StoreMenu
 | 
			
		||||
from .display import Box, Display
 | 
			
		||||
from ..entities.player import Player
 | 
			
		||||
from ..enums import KeyValues, GameMode
 | 
			
		||||
from ..game import Game
 | 
			
		||||
from ..resources import ResourceManager
 | 
			
		||||
@@ -17,6 +18,7 @@ class MenuDisplay(Display):
 | 
			
		||||
    """
 | 
			
		||||
    A class to display the menu objects.
 | 
			
		||||
    """
 | 
			
		||||
    menu: Menu
 | 
			
		||||
    position: int
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
@@ -80,6 +82,11 @@ class SettingsMenuDisplay(MenuDisplay):
 | 
			
		||||
    """
 | 
			
		||||
    A class to display specifically a settingsmenu object.
 | 
			
		||||
    """
 | 
			
		||||
    menu: SettingsMenu
 | 
			
		||||
 | 
			
		||||
    def update(self, game: Game) -> None:
 | 
			
		||||
        self.update_menu(game.settings_menu)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def values(self) -> List[str]:
 | 
			
		||||
        return [_(a[1][1]) + (" : "
 | 
			
		||||
@@ -124,6 +131,9 @@ class MainMenuDisplay(Display):
 | 
			
		||||
            menuy, menux, min(self.menudisplay.preferred_height,
 | 
			
		||||
                              self.height - menuy), menuwidth)
 | 
			
		||||
 | 
			
		||||
    def update(self, game: Game) -> None:
 | 
			
		||||
        self.menudisplay.update_menu(game.main_menu)
 | 
			
		||||
 | 
			
		||||
    def handle_click(self, y: int, x: int, game: Game) -> None:
 | 
			
		||||
        menuwidth = min(self.menudisplay.preferred_width, self.width)
 | 
			
		||||
        menuy, menux = len(self.title) + 8, self.width // 2 - menuwidth // 2 - 1
 | 
			
		||||
@@ -143,13 +153,33 @@ class PlayerInventoryDisplay(MenuDisplay):
 | 
			
		||||
    """
 | 
			
		||||
    A class to handle the display of the player's inventory.
 | 
			
		||||
    """
 | 
			
		||||
    player: Player = None
 | 
			
		||||
    selected: bool = True
 | 
			
		||||
    store_mode: bool = False
 | 
			
		||||
 | 
			
		||||
    def update(self, game: Game) -> None:
 | 
			
		||||
        self.player = game.player
 | 
			
		||||
        self.update_menu(game.inventory_menu)
 | 
			
		||||
        self.store_mode = game.state == GameMode.STORE
 | 
			
		||||
        self.selected = game.state == GameMode.INVENTORY \
 | 
			
		||||
            or (self.store_mode and not game.is_in_store_menu)
 | 
			
		||||
 | 
			
		||||
    def update_pad(self) -> None:
 | 
			
		||||
        self.menubox.update_title(_("INVENTORY"))
 | 
			
		||||
        for i, item in enumerate(self.menu.values):
 | 
			
		||||
            rep = self.pack[item.name.upper()]
 | 
			
		||||
            selection = f"[{rep}]" if i == self.menu.position else f" {rep} "
 | 
			
		||||
            selection = f"[{rep}]" if i == self.menu.position \
 | 
			
		||||
                and self.selected else f" {rep} "
 | 
			
		||||
            self.addstr(self.pad, i + 1, 0, selection
 | 
			
		||||
                        + " " + item.translated_name.capitalize())
 | 
			
		||||
                        + " " + item.translated_name.capitalize()
 | 
			
		||||
                        + (": " + str(item.price) + " Hazels"
 | 
			
		||||
                           if self.store_mode else ""))
 | 
			
		||||
 | 
			
		||||
        if self.store_mode:
 | 
			
		||||
            price = f"{self.pack.HAZELNUT} {self.player.hazel} Hazels"
 | 
			
		||||
            width = len(price) + (self.pack.tile_width - 1)
 | 
			
		||||
            self.addstr(self.pad, self.height - 3, self.width - width - 2,
 | 
			
		||||
                        price, italic=True)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def truewidth(self) -> int:
 | 
			
		||||
@@ -164,6 +194,7 @@ class PlayerInventoryDisplay(MenuDisplay):
 | 
			
		||||
        We can select a menu item with the mouse.
 | 
			
		||||
        """
 | 
			
		||||
        self.menu.position = max(0, min(len(self.menu.values) - 1, y - 2))
 | 
			
		||||
        game.is_in_store_menu = False
 | 
			
		||||
        game.handle_key_pressed(KeyValues.ENTER)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -171,15 +202,28 @@ class StoreInventoryDisplay(MenuDisplay):
 | 
			
		||||
    """
 | 
			
		||||
    A class to handle the display of a merchant's inventory.
 | 
			
		||||
    """
 | 
			
		||||
    menu: StoreMenu
 | 
			
		||||
    selected: bool = False
 | 
			
		||||
 | 
			
		||||
    def update(self, game: Game) -> None:
 | 
			
		||||
        self.update_menu(game.store_menu)
 | 
			
		||||
        self.selected = game.is_in_store_menu
 | 
			
		||||
 | 
			
		||||
    def update_pad(self) -> None:
 | 
			
		||||
        self.menubox.update_title(_("STALL"))
 | 
			
		||||
        for i, item in enumerate(self.menu.values):
 | 
			
		||||
            rep = self.pack[item.name.upper()]
 | 
			
		||||
            selection = f"[{rep}]" if i == self.menu.position else f" {rep} "
 | 
			
		||||
            selection = f"[{rep}]" if i == self.menu.position \
 | 
			
		||||
                and self.selected else f" {rep} "
 | 
			
		||||
            self.addstr(self.pad, i + 1, 0, selection
 | 
			
		||||
                        + " " + item.translated_name.capitalize()
 | 
			
		||||
                        + ": " + str(item.price) + " Hazels")
 | 
			
		||||
 | 
			
		||||
        price = f"{self.pack.HAZELNUT} {self.menu.merchant.hazel} Hazels"
 | 
			
		||||
        width = len(price) + (self.pack.tile_width - 1)
 | 
			
		||||
        self.addstr(self.pad, self.height - 3, self.width - width - 2, price,
 | 
			
		||||
                    italic=True)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def truewidth(self) -> int:
 | 
			
		||||
        return max(1, self.height if hasattr(self, "height") else 10)
 | 
			
		||||
@@ -193,4 +237,5 @@ class StoreInventoryDisplay(MenuDisplay):
 | 
			
		||||
        We can select a menu item with the mouse.
 | 
			
		||||
        """
 | 
			
		||||
        self.menu.position = max(0, min(len(self.menu.values) - 1, y - 2))
 | 
			
		||||
        game.is_in_store_menu = True
 | 
			
		||||
        game.handle_key_pressed(KeyValues.ENTER)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
import curses
 | 
			
		||||
 | 
			
		||||
from squirrelbattle.display.display import Box, Display
 | 
			
		||||
from squirrelbattle.game import Game
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MessageDisplay(Display):
 | 
			
		||||
@@ -17,8 +18,8 @@ class MessageDisplay(Display):
 | 
			
		||||
        self.message = ""
 | 
			
		||||
        self.pad = self.newpad(1, 1)
 | 
			
		||||
 | 
			
		||||
    def update_message(self, msg: str) -> None:
 | 
			
		||||
        self.message = msg
 | 
			
		||||
    def update(self, game: Game) -> None:
 | 
			
		||||
        self.message = game.message
 | 
			
		||||
 | 
			
		||||
    def display(self) -> None:
 | 
			
		||||
        self.box.refresh(self.y - 1, self.x - 2,
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@
 | 
			
		||||
import curses
 | 
			
		||||
 | 
			
		||||
from ..entities.player import Player
 | 
			
		||||
from ..game import Game
 | 
			
		||||
from ..translations import gettext as _
 | 
			
		||||
from .display import Display
 | 
			
		||||
 | 
			
		||||
@@ -18,8 +19,8 @@ class StatsDisplay(Display):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.pad = self.newpad(self.rows, self.cols)
 | 
			
		||||
 | 
			
		||||
    def update_player(self, p: Player) -> None:
 | 
			
		||||
        self.player = p
 | 
			
		||||
    def update(self, game: Game) -> None:
 | 
			
		||||
        self.player = game.player
 | 
			
		||||
 | 
			
		||||
    def update_pad(self) -> None:
 | 
			
		||||
        string2 = "Player -- LVL {}\nEXP {}/{}\nHP {}/{}"\
 | 
			
		||||
 
 | 
			
		||||
@@ -102,7 +102,7 @@ TexturePack.SQUIRREL_PACK = TexturePack(
 | 
			
		||||
    MERCHANT='🦜',
 | 
			
		||||
    RABBIT='🐇',
 | 
			
		||||
    SUNFLOWER='🌻',
 | 
			
		||||
    SWORD='🗡️',
 | 
			
		||||
    SWORD='🗡️ ',
 | 
			
		||||
    TEDDY_BEAR='🧸',
 | 
			
		||||
    TIGER='🐅',
 | 
			
		||||
    TRUMPET='🎺',
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user