Changed equipment behaviour, now equipped items stay in the inventory
This commit is contained in:
		@@ -12,16 +12,19 @@ class Item(Entity):
 | 
			
		||||
    """
 | 
			
		||||
    A class for items.
 | 
			
		||||
    """
 | 
			
		||||
    held: bool
 | 
			
		||||
    held_by: Optional[InventoryHolder]
 | 
			
		||||
    price: int
 | 
			
		||||
 | 
			
		||||
    def __init__(self, held: bool = False,
 | 
			
		||||
    def __init__(self, equipped: bool = False,
 | 
			
		||||
                 held_by: Optional[InventoryHolder] = None,
 | 
			
		||||
                 hold_slot: str = "equipped_secondary",
 | 
			
		||||
                 price: int = 2, *args, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.held = held
 | 
			
		||||
        self.held_by = held_by
 | 
			
		||||
        self.equipped = equipped
 | 
			
		||||
        self.hold_slot = hold_slot
 | 
			
		||||
        if equipped:
 | 
			
		||||
            self.equip()
 | 
			
		||||
        self.price = price
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
@@ -35,11 +38,11 @@ class Item(Entity):
 | 
			
		||||
        """
 | 
			
		||||
        The item is dropped from the inventory onto the floor.
 | 
			
		||||
        """
 | 
			
		||||
        if self.held:
 | 
			
		||||
        if self.held_by is not None:
 | 
			
		||||
            self.unequip()
 | 
			
		||||
            self.held_by.remove_from_inventory(self)
 | 
			
		||||
            self.held_by.map.add_entity(self)
 | 
			
		||||
            self.move(self.held_by.y, self.held_by.x)
 | 
			
		||||
            self.held = False
 | 
			
		||||
            self.held_by = None
 | 
			
		||||
 | 
			
		||||
    def use(self) -> None:
 | 
			
		||||
@@ -52,28 +55,41 @@ class Item(Entity):
 | 
			
		||||
        Indicates what should be done when the item is thrown.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
    def on_equip(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Indicates a special behaviour when equipping
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
    def on_unequip(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Indicates a special behaviour when unequipping
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
    def equip(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Indicates what should be done when the item is equipped.
 | 
			
		||||
        """
 | 
			
		||||
        # Other objects are only equipped as secondary.
 | 
			
		||||
        if self.held_by.equipped_secondary:
 | 
			
		||||
            self.held_by.equipped_secondary.unequip()
 | 
			
		||||
        self.held_by.remove_from_inventory(self)
 | 
			
		||||
        self.held_by.equipped_secondary = self
 | 
			
		||||
        if not self.equipped:
 | 
			
		||||
            if getattr(self.held_by, self.hold_slot):
 | 
			
		||||
                getattr(self.held_by, self.hold_slot).unequip()
 | 
			
		||||
            self.equipped = True
 | 
			
		||||
            setattr(self.held_by, self.hold_slot, self)
 | 
			
		||||
            self.on_equip()
 | 
			
		||||
 | 
			
		||||
    def unequip(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Indicates what should be done when the item is unequipped.
 | 
			
		||||
        """
 | 
			
		||||
        self.held_by.remove_from_inventory(self)
 | 
			
		||||
        self.held_by.add_to_inventory(self)
 | 
			
		||||
        if self.equipped:
 | 
			
		||||
            setattr(self.held_by, self.hold_slot, None)
 | 
			
		||||
            self.equipped = False
 | 
			
		||||
            self.on_unequip()
 | 
			
		||||
 | 
			
		||||
    def hold(self, holder: InventoryHolder) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        The item is taken from the floor and put into the inventory.
 | 
			
		||||
        """
 | 
			
		||||
        self.held = True
 | 
			
		||||
        self.held_by = holder
 | 
			
		||||
        self.held_by.map.remove_entity(self)
 | 
			
		||||
        holder.add_to_inventory(self)
 | 
			
		||||
@@ -83,7 +99,7 @@ class Item(Entity):
 | 
			
		||||
        Saves the state of the item into a dictionary.
 | 
			
		||||
        """
 | 
			
		||||
        d = super().save_state()
 | 
			
		||||
        d["held"] = self.held
 | 
			
		||||
        d["equipped"] = self.equipped
 | 
			
		||||
        return d
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
@@ -103,10 +119,12 @@ class Item(Entity):
 | 
			
		||||
        inventory.
 | 
			
		||||
        """
 | 
			
		||||
        if for_free:
 | 
			
		||||
            self.unequip() if self.equipped else None
 | 
			
		||||
            self.hold(buyer)
 | 
			
		||||
            seller.remove_from_inventory(self)
 | 
			
		||||
            return True
 | 
			
		||||
        elif buyer.hazel >= self.price:
 | 
			
		||||
            self.unequip() if self.equipped else None
 | 
			
		||||
            self.hold(buyer)
 | 
			
		||||
            seller.remove_from_inventory(self)
 | 
			
		||||
            buyer.change_hazel_balance(-self.price)
 | 
			
		||||
@@ -169,7 +187,7 @@ class Bomb(Item):
 | 
			
		||||
        """
 | 
			
		||||
        When the bomb is used, it is thrown and then it explodes.
 | 
			
		||||
        """
 | 
			
		||||
        if self.held:
 | 
			
		||||
        if self.held_by is not None:
 | 
			
		||||
            self.owner = self.held_by
 | 
			
		||||
            super().drop()
 | 
			
		||||
            self.exploding = True
 | 
			
		||||
@@ -236,7 +254,7 @@ class Weapon(Item):
 | 
			
		||||
    damage: int
 | 
			
		||||
 | 
			
		||||
    def __init__(self, damage: int = 3, *args, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        super().__init__(hold_slot="equipped_main", *args, **kwargs)
 | 
			
		||||
        self.damage = damage
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
@@ -251,20 +269,17 @@ class Weapon(Item):
 | 
			
		||||
        d["damage"] = self.damage
 | 
			
		||||
        return d
 | 
			
		||||
 | 
			
		||||
    def equip(self) -> None:
 | 
			
		||||
    def on_equip(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        When a weapon is equipped, the player gains strength.
 | 
			
		||||
        """
 | 
			
		||||
        self.held_by.remove_from_inventory(self)
 | 
			
		||||
        self.held_by.equipped_main = self
 | 
			
		||||
        self.held_by.strength += self.damage
 | 
			
		||||
 | 
			
		||||
    def unequip(self) -> None:
 | 
			
		||||
    def on_unequip(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Remove the strength earned by the weapon.
 | 
			
		||||
        :return:
 | 
			
		||||
        """
 | 
			
		||||
        super().unequip()
 | 
			
		||||
        self.held_by.strength -= self.damage
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -301,12 +316,10 @@ class Armor(Item):
 | 
			
		||||
        return f"CON+{self.constitution}" if self.constitution \
 | 
			
		||||
            else super().description
 | 
			
		||||
 | 
			
		||||
    def equip(self) -> None:
 | 
			
		||||
        super().equip()
 | 
			
		||||
    def on_equip(self) -> None:
 | 
			
		||||
        self.held_by.constitution += self.constitution
 | 
			
		||||
 | 
			
		||||
    def unequip(self) -> None:
 | 
			
		||||
        super().unequip()
 | 
			
		||||
    def on_unequip(self) -> None:
 | 
			
		||||
        self.held_by.constitution -= self.constitution
 | 
			
		||||
 | 
			
		||||
    def save_state(self) -> dict:
 | 
			
		||||
@@ -332,13 +345,7 @@ class Helmet(Armor):
 | 
			
		||||
    def __init__(self, name: str = "helmet", constitution: int = 2,
 | 
			
		||||
                 price: int = 18, *args, **kwargs):
 | 
			
		||||
        super().__init__(name=name, constitution=constitution, price=price,
 | 
			
		||||
                         *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def equip(self) -> None:
 | 
			
		||||
        if self.held_by.equipped_helmet:
 | 
			
		||||
            self.held_by.equipped_helmet.unequip()
 | 
			
		||||
        self.held_by.remove_from_inventory(self)
 | 
			
		||||
        self.held_by.equipped_helmet = self
 | 
			
		||||
                         hold_slot="equipped_helmet", *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Chestplate(Armor):
 | 
			
		||||
@@ -348,13 +355,7 @@ class Chestplate(Armor):
 | 
			
		||||
    def __init__(self, name: str = "chestplate", constitution: int = 4,
 | 
			
		||||
                 price: int = 30, *args, **kwargs):
 | 
			
		||||
        super().__init__(name=name, constitution=constitution, price=price,
 | 
			
		||||
                         *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def equip(self) -> None:
 | 
			
		||||
        if self.held_by.equipped_armor:
 | 
			
		||||
            self.held_by.equipped_armor.unequip()
 | 
			
		||||
        self.held_by.remove_from_inventory(self)
 | 
			
		||||
        self.held_by.equipped_armor = self
 | 
			
		||||
                         hold_slot="equipped_armor", *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BodySnatchPotion(Item):
 | 
			
		||||
@@ -426,8 +427,7 @@ class Ring(Item):
 | 
			
		||||
                  ("CRI", self.critical), ("XP", self.experience)]
 | 
			
		||||
        return ", ".join(f"{key}+{value}" for key, value in fields if value)
 | 
			
		||||
 | 
			
		||||
    def equip(self) -> None:
 | 
			
		||||
        super().equip()
 | 
			
		||||
    def on_equip(self) -> None:
 | 
			
		||||
        self.held_by.maxhealth += self.maxhealth
 | 
			
		||||
        self.held_by.strength += self.strength
 | 
			
		||||
        self.held_by.intelligence += self.intelligence
 | 
			
		||||
@@ -437,8 +437,7 @@ class Ring(Item):
 | 
			
		||||
        self.held_by.critical += self.critical
 | 
			
		||||
        self.held_by.xp_buff += self.experience
 | 
			
		||||
 | 
			
		||||
    def unequip(self) -> None:
 | 
			
		||||
        super().unequip()
 | 
			
		||||
    def on_unequip(self) -> None:
 | 
			
		||||
        self.held_by.maxhealth -= self.maxhealth
 | 
			
		||||
        self.held_by.strength -= self.strength
 | 
			
		||||
        self.held_by.intelligence -= self.intelligence
 | 
			
		||||
@@ -557,13 +556,6 @@ class LongRangeWeapon(Weapon):
 | 
			
		||||
            self.held_by.map.logs.add_message(line)
 | 
			
		||||
        return (to_kill.y, to_kill.x) if to_kill else None
 | 
			
		||||
 | 
			
		||||
    def equip(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Equip the weapon.
 | 
			
		||||
        """
 | 
			
		||||
        self.held_by.remove_from_inventory(self)
 | 
			
		||||
        self.held_by.equipped_main = self
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def stat(self) -> str:
 | 
			
		||||
        """
 | 
			
		||||
 
 | 
			
		||||
@@ -837,6 +837,7 @@ class InventoryHolder(Entity):
 | 
			
		||||
        for i in range(len(inventory)):
 | 
			
		||||
            if isinstance(inventory[i], dict):
 | 
			
		||||
                inventory[i] = self.dict_to_item(inventory[i])
 | 
			
		||||
                inventory[i].held_by = self
 | 
			
		||||
        return inventory
 | 
			
		||||
 | 
			
		||||
    def dict_to_item(self, item_dict: dict) -> Entity:
 | 
			
		||||
 
 | 
			
		||||
@@ -155,9 +155,9 @@ class TestEntities(unittest.TestCase):
 | 
			
		||||
        """
 | 
			
		||||
        item = Item()
 | 
			
		||||
        self.map.add_entity(item)
 | 
			
		||||
        self.assertFalse(item.held)
 | 
			
		||||
        self.assertIsNone(item.held_by)
 | 
			
		||||
        item.hold(self.player)
 | 
			
		||||
        self.assertTrue(item.held)
 | 
			
		||||
        self.assertEqual(item.held_by, self.player)
 | 
			
		||||
        item.drop()
 | 
			
		||||
        self.assertEqual(item.y, 1)
 | 
			
		||||
        self.assertEqual(item.x, 6)
 | 
			
		||||
@@ -165,7 +165,6 @@ class TestEntities(unittest.TestCase):
 | 
			
		||||
        # Pick up item
 | 
			
		||||
        self.player.move_left()
 | 
			
		||||
        self.player.move_right()
 | 
			
		||||
        self.assertTrue(item.held)
 | 
			
		||||
        self.assertEqual(item.held_by, self.player)
 | 
			
		||||
        self.assertIn(item, self.player.inventory)
 | 
			
		||||
        self.assertNotIn(item, self.map.entities)
 | 
			
		||||
@@ -208,7 +207,7 @@ class TestEntities(unittest.TestCase):
 | 
			
		||||
        # The player can't hold the explosion
 | 
			
		||||
        explosion.hold(self.player)
 | 
			
		||||
        self.assertNotIn(explosion, self.player.inventory)
 | 
			
		||||
        self.assertFalse(explosion.held)
 | 
			
		||||
        self.assertIsNone(explosion.held_by)
 | 
			
		||||
 | 
			
		||||
        # The explosion disappears after one tick
 | 
			
		||||
        explosion.act(self.map)
 | 
			
		||||
 
 | 
			
		||||
@@ -491,10 +491,8 @@ class TestGame(unittest.TestCase):
 | 
			
		||||
        # Drop an item
 | 
			
		||||
        bomb = self.game.player.inventory[-1]
 | 
			
		||||
        self.assertEqual(self.game.inventory_menu.validate(), bomb)
 | 
			
		||||
        self.assertTrue(bomb.held)
 | 
			
		||||
        self.assertEqual(bomb.held_by, self.game.player)
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.DROP)
 | 
			
		||||
        self.assertFalse(bomb.held)
 | 
			
		||||
        self.assertIsNone(bomb.held_by)
 | 
			
		||||
        self.assertIsNone(bomb.owner)
 | 
			
		||||
        self.assertFalse(bomb.exploding)
 | 
			
		||||
@@ -504,10 +502,8 @@ class TestGame(unittest.TestCase):
 | 
			
		||||
        # Use the bomb
 | 
			
		||||
        bomb = self.game.player.inventory[-1]
 | 
			
		||||
        self.assertEqual(self.game.inventory_menu.validate(), bomb)
 | 
			
		||||
        self.assertTrue(bomb.held)
 | 
			
		||||
        self.assertEqual(bomb.held_by, self.game.player)
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.USE)
 | 
			
		||||
        self.assertFalse(bomb.held)
 | 
			
		||||
        self.assertIsNone(bomb.held_by)
 | 
			
		||||
        self.assertEqual(bomb.owner, self.game.player)
 | 
			
		||||
        self.assertTrue(bomb.exploding)
 | 
			
		||||
@@ -660,42 +656,37 @@ class TestGame(unittest.TestCase):
 | 
			
		||||
        sword.hold(self.game.player)
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.EQUIP)
 | 
			
		||||
        self.assertEqual(self.game.player.equipped_main, sword)
 | 
			
		||||
        self.assertFalse(self.game.player.inventory)
 | 
			
		||||
 | 
			
		||||
        # shield goes into the secondary equipment slot
 | 
			
		||||
        shield = Shield()
 | 
			
		||||
        shield.hold(self.game.player)
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.EQUIP)
 | 
			
		||||
        shield.equip()
 | 
			
		||||
        self.assertEqual(self.game.player.equipped_secondary, shield)
 | 
			
		||||
        self.assertFalse(self.game.player.inventory)
 | 
			
		||||
 | 
			
		||||
        # helmet goes into the helmet slot
 | 
			
		||||
        helmet = Helmet()
 | 
			
		||||
        helmet.hold(self.game.player)
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.EQUIP)
 | 
			
		||||
        helmet.equip()
 | 
			
		||||
        self.assertEqual(self.game.player.equipped_helmet, helmet)
 | 
			
		||||
        self.assertFalse(self.game.player.inventory)
 | 
			
		||||
 | 
			
		||||
        # helmet goes into the armor slot
 | 
			
		||||
        chestplate = Chestplate()
 | 
			
		||||
        chestplate.hold(self.game.player)
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.EQUIP)
 | 
			
		||||
        chestplate.equip()
 | 
			
		||||
        self.assertEqual(self.game.player.equipped_armor, chestplate)
 | 
			
		||||
        self.assertFalse(self.game.player.inventory)
 | 
			
		||||
 | 
			
		||||
        # Use bomb
 | 
			
		||||
        bomb = Bomb()
 | 
			
		||||
        bomb.hold(self.game.player)
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.EQUIP)
 | 
			
		||||
        bomb.equip()
 | 
			
		||||
        self.assertEqual(self.game.player.equipped_secondary, bomb)
 | 
			
		||||
        self.assertIn(shield, self.game.player.inventory)
 | 
			
		||||
        self.assertFalse(shield.equipped)
 | 
			
		||||
        self.game.state = GameMode.PLAY
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.USE)
 | 
			
		||||
        self.assertIsNone(self.game.player.equipped_secondary)
 | 
			
		||||
        self.game.state = GameMode.INVENTORY
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.EQUIP)
 | 
			
		||||
        shield.equip()
 | 
			
		||||
        self.assertEqual(self.game.player.equipped_secondary, shield)
 | 
			
		||||
        self.assertFalse(self.game.player.inventory)
 | 
			
		||||
 | 
			
		||||
        # Reequip, which is useless but covers code
 | 
			
		||||
        sword.equip()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user