diff --git a/squirrelbattle/entities/friendly.py b/squirrelbattle/entities/friendly.py index 0e7ac1c..3e965d5 100644 --- a/squirrelbattle/entities/friendly.py +++ b/squirrelbattle/entities/friendly.py @@ -1,18 +1,14 @@ -from ..interfaces import FriendlyEntity +from ..interfaces import FriendlyEntity, InventoryHolder from ..translations import gettext as _ from .player import Player from .items import Item from random import choice -from typing import Any -class Merchant(FriendlyEntity): +class Merchant(InventoryHolder, FriendlyEntity): """ The class for merchants in the dungeon """ - inventory = list - hazel = int - def keys(self) -> list: """ Returns a friendly entitie's specific attributes @@ -22,16 +18,9 @@ class Merchant(FriendlyEntity): def __init__(self, name: str = "merchant", inventory: list = None, hazel: int = 75, *args, **kwargs): super().__init__(name=name, *args, **kwargs) - self.inventory = inventory or [] + self.inventory = self.translate_inventory(inventory or []) self.hazel = hazel - entity_classes = self.get_all_entity_classes_in_a_dict() - - for i in range(len(self.inventory)): - if isinstance(self.inventory[i], dict): - item_class = entity_classes[self.inventory[i]["type"]] - self.inventory[i] = item_class(**self.inventory[i]) - if not self.inventory: for i in range(5): self.inventory.append(choice(Item.get_all_items())()) @@ -41,29 +30,8 @@ class Merchant(FriendlyEntity): This function is used to open the merchant's inventory in a menu, and allow the player to buy/sell objects """ - # TODO return _("I don't sell any squirrel") - def save_state(self) -> dict: - """ - We save the inventory of the merchant formatted as JSON - """ - d = super().save_state() - d["inventory"] = [item.save_state() for item in self.inventory] - return d - - def add_to_inventory(self, obj: Any) -> None: - """ - Adds an object to inventory - """ - self.inventory.append(obj) - - def remove_from_inventory(self, obj: Any) -> None: - """ - Removes an object from the inventory - """ - self.inventory.remove(obj) - def change_hazel_balance(self, hz: int) -> None: """ Change the number of hazel the merchant has by hz. diff --git a/squirrelbattle/entities/items.py b/squirrelbattle/entities/items.py index 87c9ba1..76f8a37 100644 --- a/squirrelbattle/entities/items.py +++ b/squirrelbattle/entities/items.py @@ -5,7 +5,7 @@ from random import choice, randint from typing import Optional, Any from .player import Player -from ..interfaces import Entity, FightingEntity, Map +from ..interfaces import Entity, FightingEntity, Map, InventoryHolder from ..translations import gettext as _ @@ -66,7 +66,8 @@ class Item(Entity): def get_all_items() -> list: return [BodySnatchPotion, Bomb, Heart, Sword] - def be_sold(self, buyer: Entity, seller: Entity, game: Any) -> bool: + def be_sold(self, buyer: InventoryHolder, seller: InventoryHolder, + game: Any) -> bool: """ Does all necessary actions when an object is to be sold. Is overwritten by some classes that cannot exist in the player's @@ -93,12 +94,12 @@ class Heart(Item): super().__init__(name=name, price=price, *args, **kwargs) self.healing = healing - def hold(self, player: "Player") -> None: + def hold(self, entity: InventoryHolder) -> None: """ When holding a heart, heal the player and don't put item in inventory. """ - player.health = min(player.maxhealth, player.health + self.healing) - player.map.remove_entity(self) + entity.health = min(entity.maxhealth, entity.health + self.healing) + entity.map.remove_entity(self) def save_state(self) -> dict: """ @@ -108,7 +109,8 @@ class Heart(Item): d["healing"] = self.healing return d - def be_sold(self, buyer: Entity, seller: Entity, game: Any) -> bool: + def be_sold(self, buyer: InventoryHolder, seller: InventoryHolder, + game: Any) -> bool: """ Does all necessary actions when an object is to be sold. Is overwritten by some classes that cannot exist in the player's diff --git a/squirrelbattle/entities/player.py b/squirrelbattle/entities/player.py index b14f9da..d8bf31a 100644 --- a/squirrelbattle/entities/player.py +++ b/squirrelbattle/entities/player.py @@ -2,20 +2,18 @@ # SPDX-License-Identifier: GPL-3.0-or-later from random import randint -from typing import Dict, Tuple, Any +from typing import Dict, Tuple -from ..interfaces import FightingEntity +from ..interfaces import FightingEntity, InventoryHolder -class Player(FightingEntity): +class Player(InventoryHolder, FightingEntity): """ The class of the player """ current_xp: int = 0 max_xp: int = 10 - inventory: list paths: Dict[Tuple[int, int], Tuple[int, int]] - hazel: int # It is the currency of this game def __init__(self, name: str = "player", maxhealth: int = 20, strength: int = 5, intelligence: int = 1, charisma: int = 1, @@ -29,12 +27,7 @@ class Player(FightingEntity): level=level, *args, **kwargs) self.current_xp = current_xp self.max_xp = max_xp - self.inventory = inventory if inventory else list() - entity_classes = self.get_all_entity_classes_in_a_dict() - for i in range(len(self.inventory)): - if isinstance(self.inventory[i], dict): - item_class = entity_classes[self.inventory[i]["type"]] - self.inventory[i] = item_class(**self.inventory[i]) + self.inventory = self.translate_inventory(inventory or []) self.paths = dict() self.hazel = hazel @@ -70,13 +63,6 @@ class Player(FightingEntity): self.current_xp += xp self.level_up() - def change_hazel_balance(self, hz: int) -> None: - """ - Change the number of hazel the player has by hz. hz is negative - when the player loses money and positive when he gains money - """ - self.hazel += hz - # noinspection PyTypeChecker,PyUnresolvedReferences def check_move(self, y: int, x: int, move_if_possible: bool = False) \ -> bool: @@ -126,18 +112,6 @@ class Player(FightingEntity): queue.append((new_y, new_x)) self.paths = predecessors - def add_to_inventory(self, obj: Any) -> None: - """ - Adds an object to inventory - """ - self.inventory.append(obj) - - def remove_from_inventory(self, obj: Any) -> None: - """ - Removes an object from the inventory - """ - self.inventory.remove(obj) - def save_state(self) -> dict: """ Saves the state of the entity into a dictionary @@ -145,6 +119,4 @@ class Player(FightingEntity): d = super().save_state() d["current_xp"] = self.current_xp d["max_xp"] = self.max_xp - d["inventory"] = [item.save_state() for item in self.inventory] - d["hazel"] = self.hazel return d diff --git a/squirrelbattle/interfaces.py b/squirrelbattle/interfaces.py index e3e29da..c035a38 100644 --- a/squirrelbattle/interfaces.py +++ b/squirrelbattle/interfaces.py @@ -483,3 +483,56 @@ class FriendlyEntity(FightingEntity): Returns a friendly entity's specific attributes """ return ["maxhealth", "health"] + + +class InventoryHolder(Entity): + hazel: int # Currency of the game + inventory: list + + def translate_inventory(self, inventory: list) -> list: + """ + Translate the JSON-state of the inventory into a list of the items in + the inventory. + """ + for i in range(len(inventory)): + if isinstance(inventory[i], dict): + inventory[i] = self.dict_to_inventory(inventory[i]) + return inventory + + def dict_to_inventory(self, item_dict: dict) -> Entity: + """ + Translate a dict object that contains the state of an item + into an item object. + """ + entity_classes = self.get_all_entity_classes_in_a_dict() + + item_class = entity_classes[item_dict["type"]] + return item_class(**item_dict) + + def save_state(self) -> dict: + """ + We save the inventory of the merchant formatted as JSON + """ + d = super().save_state() + d["hazel"] = self.hazel + d["inventory"] = [item.save_state() for item in self.inventory] + return d + + def add_to_inventory(self, obj: Any) -> None: + """ + Adds an object to inventory + """ + self.inventory.append(obj) + + def remove_from_inventory(self, obj: Any) -> None: + """ + 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 + """ + self.hazel += hz