diff --git a/components/equipment.py b/components/equipment.py new file mode 100644 index 0000000..5095d94 --- /dev/null +++ b/components/equipment.py @@ -0,0 +1,87 @@ +from __future__ import annotations + +from typing import Optional, TYPE_CHECKING + +from components.base_component import BaseComponent +from equipment_types import EquipmentType + +if TYPE_CHECKING: + from entity import Actor, Item + + +class Equipment(BaseComponent): + parent: Actor + + def __init__(self, weapon: Optional[Item] = None, armor: Optional[Item] = None): + self.weapon = weapon + self.armor = armor + + @property + def defense_bonuse(self) -> int: + bonus = 0 + + if self.weapon is not None and self.weapon.equippable is not None: + bonus += self.weapon.equippable.defense_bonus + + if self.armor is not None and self.armor.equippable is not None: + bonus += self.armor.equippable.defense_bonus + + return bonus + + @property + def power_bonus(self) -> int: + bonus = 0 + + if self.weapon is not None and self.weapon.equippable is not None: + bonus += self.weapon.equippable.power_bonus + + if self.armor is not None and self.armor.equippable is not None: + bonus += self.armor.equippable.power_bonus + + return bonus + + def item_is_equipped(self, item: Item) -> bool: + return self.weapon == item or self.armor == item + + def unequip_message(self, item_name: str) -> None: + self.parent.gamemap.engine.message_log.add_message( + f"You remove the {item_name}." + ) + + def equip_message(self, item_name: str) -> None: + self.parent.gamemap.engine.message_log.add_message( + f"You equip the {item_name}." + ) + + def equip_to_slot(self, slot: str, item: Item, add_message: bool) -> None: + current_item = getattr(self, slot) + + if current_item is not None: + self.unequip_from_slot(slot, add_message) + + setattr(self, slot, item) + + if add_message: + self.equip_message(item.name) + + def unequip_from_slot(self, slot: str, add_message: bool) -> None: + current_item = getattr(self, slot) + + if add_message: + self.unequip_message(current_item.name) + + setattr(self, slot, None) + + def toggle_equip(self, equippable_item: Item, add_message: bool = True) -> None: + if ( + equippable_item.equippable + and equippable_item.equippable.equipment_type == EquipmentType.WEAPON + ): + slot = "weapon" + else: + slot = "armor" + + if getattr(self, slot) == equippable_item: + self.unequip_from_slot(slot, add_message) + else: + self.equip_to_slot(slot, equippable_item, add_message) diff --git a/entity.py b/entity.py index d040010..b9c933c 100644 --- a/entity.py +++ b/entity.py @@ -9,6 +9,7 @@ from render_order import RenderOrder if TYPE_CHECKING: from components.ai import BaseAI from components.consumable import Consumable + from components.equipment import Equipment from components.equippable import Equippable from components.fighter import Fighter from components.inventory import Inventory @@ -95,6 +96,7 @@ class Actor(Entity): color: Tuple[int, int, int] = (255, 255, 255), name: str = "", ai_cls: Type[BaseAI], + equipment: Equipment, fighter: Fighter, inventory: Inventory, level: Level, @@ -111,6 +113,9 @@ class Actor(Entity): self.ai: Optional[BaseAI] = ai_cls(self) + self.equipment: Equipment = equipment + self.equipment.parent = self + self.fighter = fighter self.fighter.parent = self diff --git a/entity_factories.py b/entity_factories.py index 219b4f1..6ec3aba 100644 --- a/entity_factories.py +++ b/entity_factories.py @@ -1,5 +1,6 @@ -from components.ai import HostileEnemy from components import consumable, equippable +from components.ai import HostileEnemy +from components.equipment import Equipment from components.fighter import Fighter from components.inventory import Inventory from components.level import Level @@ -10,6 +11,7 @@ player = Actor( color=(255, 255, 255), name="Player", ai_cls=HostileEnemy, + equipment=Equipment(), fighter=Fighter(hp=30, defense=2, power=5), inventory=Inventory(capacity=26), level=Level(level_up_base=200), @@ -20,6 +22,7 @@ orc = Actor( color=(63, 127, 63), name="Orc", ai_cls=HostileEnemy, + equipment=Equipment(), fighter=Fighter(hp=10, defense=0, power=3), inventory=Inventory(capacity=0), level=Level(xp_given=35), @@ -29,6 +32,7 @@ troll = Actor( color=(0, 127, 0), name="Troll", ai_cls=HostileEnemy, + equipment=Equipment(), fighter=Fighter(hp=16, defense=1, power=4), inventory=Inventory(capacity=0), level=Level(xp_given=100),