First pass on the logs
The newly-added logs manage a list of messages. Entities do register a message to it when hitting each other. Display is created, but not yet added to the layout actually displayed.
This commit is contained in:
		@@ -3,6 +3,7 @@ from squirrelbattle.display.mapdisplay import MapDisplay
 | 
			
		||||
from squirrelbattle.display.statsdisplay import StatsDisplay
 | 
			
		||||
from squirrelbattle.display.menudisplay import SettingsMenuDisplay, \
 | 
			
		||||
    MainMenuDisplay
 | 
			
		||||
from squirrelbattle.display.logsdisplay import LogsDisplay
 | 
			
		||||
from squirrelbattle.display.texturepack import TexturePack
 | 
			
		||||
from typing import Any
 | 
			
		||||
from squirrelbattle.game import Game, GameMode
 | 
			
		||||
@@ -20,8 +21,10 @@ class DisplayManager:
 | 
			
		||||
        self.mainmenudisplay = MainMenuDisplay(self.game.main_menu,
 | 
			
		||||
                                               screen, pack)
 | 
			
		||||
        self.settingsmenudisplay = SettingsMenuDisplay(screen, pack)
 | 
			
		||||
        self.logsdisplay = LogsDisplay(screen, pack)
 | 
			
		||||
        self.displays = [self.statsdisplay, self.mapdisplay,
 | 
			
		||||
                         self.mainmenudisplay, self.settingsmenudisplay]
 | 
			
		||||
                         self.mainmenudisplay, self.settingsmenudisplay,
 | 
			
		||||
                         self.logsdisplay]
 | 
			
		||||
        self.update_game_components()
 | 
			
		||||
 | 
			
		||||
    def handle_display_action(self, action: DisplayActions) -> None:
 | 
			
		||||
@@ -36,6 +39,7 @@ class DisplayManager:
 | 
			
		||||
        self.mapdisplay.update_map(self.game.map)
 | 
			
		||||
        self.statsdisplay.update_player(self.game.player)
 | 
			
		||||
        self.settingsmenudisplay.update_menu(self.game.settings_menu)
 | 
			
		||||
        self.logsdisplay.update_logs(self.game.logs)
 | 
			
		||||
 | 
			
		||||
    def refresh(self) -> None:
 | 
			
		||||
        if self.game.state == GameMode.PLAY:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								squirrelbattle/display/logsdisplay.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								squirrelbattle/display/logsdisplay.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
from squirrelbattle.display.display import Display
 | 
			
		||||
from squirrelbattle.interfaces import Logs
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LogsDisplay(Display):
 | 
			
		||||
 | 
			
		||||
    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 display(self) -> None:
 | 
			
		||||
        messages = self.logs.messages[-self.height:].reverse()
 | 
			
		||||
        for i, y in enumerate(range(self.y + self.height - 1, self.y - 1, - 1)):
 | 
			
		||||
            self.pad.addstr(y, self.x, messages[i][:self.width])
 | 
			
		||||
@@ -44,7 +44,7 @@ class Monster(FightingEntity):
 | 
			
		||||
            next_y, next_x = target.paths[(self.y, self.x)]
 | 
			
		||||
            moved = self.check_move(next_y, next_x, True)
 | 
			
		||||
            if not moved and self.distance_squared(target) <= 1:
 | 
			
		||||
                self.hit(target)
 | 
			
		||||
                self.map.logs.add_message(self.hit(target))
 | 
			
		||||
        else:
 | 
			
		||||
            for _ in range(100):
 | 
			
		||||
                if choice([self.move_up, self.move_down,
 | 
			
		||||
 
 | 
			
		||||
@@ -70,7 +70,7 @@ class Player(FightingEntity):
 | 
			
		||||
        for entity in self.map.entities:
 | 
			
		||||
            if entity.y == y and entity.x == x:
 | 
			
		||||
                if entity.is_fighting_entity():
 | 
			
		||||
                    self.hit(entity)
 | 
			
		||||
                    self.map.logs.add_message(self.hit(entity))
 | 
			
		||||
                    if entity.dead:
 | 
			
		||||
                        self.add_xp(randint(3, 7))
 | 
			
		||||
                    return True
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ import sys
 | 
			
		||||
 | 
			
		||||
from .entities.player import Player
 | 
			
		||||
from .enums import GameMode, KeyValues, DisplayActions
 | 
			
		||||
from .interfaces import Map
 | 
			
		||||
from .interfaces import Map, Logs
 | 
			
		||||
from .resources import ResourceManager
 | 
			
		||||
from .settings import Settings
 | 
			
		||||
from . import menus
 | 
			
		||||
@@ -33,6 +33,7 @@ class Game:
 | 
			
		||||
        self.settings.load_settings()
 | 
			
		||||
        self.settings.write_settings()
 | 
			
		||||
        self.settings_menu.update_values(self.settings)
 | 
			
		||||
        self.logs = Logs()
 | 
			
		||||
 | 
			
		||||
    def new_game(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
@@ -40,6 +41,7 @@ class Game:
 | 
			
		||||
        """
 | 
			
		||||
        # TODO generate a new map procedurally
 | 
			
		||||
        self.map = Map.load(ResourceManager.get_asset_path("example_map_2.txt"))
 | 
			
		||||
        self.map.logs = self.logs
 | 
			
		||||
        self.player = Player()
 | 
			
		||||
        self.map.add_entity(self.player)
 | 
			
		||||
        self.player.move(self.map.start_y, self.map.start_x)
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,26 @@ from typing import List, Optional
 | 
			
		||||
from squirrelbattle.display.texturepack import TexturePack
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Logs:
 | 
			
		||||
    """
 | 
			
		||||
    The logs object stores the messages to display. It is encapsulating a list
 | 
			
		||||
    of such messages, to allow multiple pointers to keep track of it even if
 | 
			
		||||
    the list was to be reassigned.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self) -> None:
 | 
			
		||||
        self.messages = []
 | 
			
		||||
 | 
			
		||||
    def add_message(self, msg: str) -> None:
 | 
			
		||||
        self.messages.append(msg)
 | 
			
		||||
 | 
			
		||||
    def add_messages(self, msg: List[str]) -> None:
 | 
			
		||||
        self.messages += msg
 | 
			
		||||
 | 
			
		||||
    def clear(self) -> None:
 | 
			
		||||
        self.messages = []
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Map:
 | 
			
		||||
    """
 | 
			
		||||
    Object that represents a Map with its width, height
 | 
			
		||||
@@ -18,6 +38,7 @@ class Map:
 | 
			
		||||
    start_x: int
 | 
			
		||||
    tiles: List[List["Tile"]]
 | 
			
		||||
    entities: List["Entity"]
 | 
			
		||||
    logs: Logs
 | 
			
		||||
    # coordinates of the point that should be
 | 
			
		||||
    # on the topleft corner of the screen
 | 
			
		||||
    currentx: int
 | 
			
		||||
@@ -362,19 +383,22 @@ class FightingEntity(Entity):
 | 
			
		||||
    def dead(self) -> bool:
 | 
			
		||||
        return self.health <= 0
 | 
			
		||||
 | 
			
		||||
    def hit(self, opponent: "FightingEntity") -> None:
 | 
			
		||||
    def hit(self, opponent: "FightingEntity") -> str:
 | 
			
		||||
        """
 | 
			
		||||
        Deals damage to the opponent, based on the stats
 | 
			
		||||
        """
 | 
			
		||||
        opponent.take_damage(self, self.strength)
 | 
			
		||||
        return f"{self.name} hits {opponent.name}. "\
 | 
			
		||||
            + opponent.take_damage(self, self.strength)
 | 
			
		||||
 | 
			
		||||
    def take_damage(self, attacker: "Entity", amount: int) -> None:
 | 
			
		||||
    def take_damage(self, attacker: "Entity", amount: int) -> str:
 | 
			
		||||
        """
 | 
			
		||||
        Take damage from the attacker, based on the stats
 | 
			
		||||
        """
 | 
			
		||||
        self.health -= amount
 | 
			
		||||
        if self.health <= 0:
 | 
			
		||||
            self.die()
 | 
			
		||||
        return f"{self.name} takes {amount} damage."\
 | 
			
		||||
            + (f" {self.name} dies." if self.health <= 0 else "")
 | 
			
		||||
 | 
			
		||||
    def die(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user