From fe769c4488a360d6562ec3bcdf9399fc99aac723 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 18 Dec 2020 17:30:03 +0100 Subject: [PATCH 01/13] We can equip items --- squirrelbattle/display/statsdisplay.py | 17 +++++++++++++---- squirrelbattle/entities/items.py | 20 +++++++++++++++----- squirrelbattle/entities/player.py | 14 ++++++++++++-- squirrelbattle/game.py | 1 + squirrelbattle/interfaces.py | 10 ++++++---- 5 files changed, 47 insertions(+), 15 deletions(-) diff --git a/squirrelbattle/display/statsdisplay.py b/squirrelbattle/display/statsdisplay.py index ef358bb..00f6675 100644 --- a/squirrelbattle/display/statsdisplay.py +++ b/squirrelbattle/display/statsdisplay.py @@ -20,7 +20,7 @@ class StatsDisplay(Display): self.player = game.player def update_pad(self) -> None: - string2 = "Player -- LVL {}\nEXP {}/{}\nHP {}/{}"\ + string2 = _("player").capitalize() + " -- LVL {}\nEXP {}/{}\nHP {}/{}"\ .format(self.player.level, self.player.current_xp, self.player.max_xp, self.player.health, self.player.maxhealth) @@ -46,11 +46,20 @@ class StatsDisplay(Display): printed_items.append(item) self.addstr(self.pad, 8, 0, inventory_str) - self.addstr(self.pad, 9, 0, f"{self.pack.HAZELNUT} " - f"x{self.player.hazel}") + if self.player.equipped_item: + self.addstr(self.pad, 9, 0, + _("Equipped item:") + " " + f"{self.pack[self.player.equipped_item.name.upper()]}") + if self.player.equipped_armor: + self.addstr(self.pad, 10, 0, + _("Equipped armor:") + " " + f"{self.pack[self.player.equipped_armor.name.upper()]}") + + self.addstr(self.pad, 11, 0, f"{self.pack.HAZELNUT} " + f"x{self.player.hazel}") if self.player.dead: - self.addstr(self.pad, 11, 0, _("YOU ARE DEAD"), curses.COLOR_RED, + self.addstr(self.pad, 13, 0, _("YOU ARE DEAD"), curses.COLOR_RED, bold=True, blink=True, standout=True) def display(self) -> None: diff --git a/squirrelbattle/entities/items.py b/squirrelbattle/entities/items.py index 865a703..9719e3a 100644 --- a/squirrelbattle/entities/items.py +++ b/squirrelbattle/entities/items.py @@ -4,7 +4,6 @@ from random import choice, randint from typing import Optional -from .player import Player from ..interfaces import Entity, FightingEntity, Map, InventoryHolder from ..translations import gettext as _ @@ -45,15 +44,26 @@ class Item(Entity): """ Indicates what should be done when the item is equipped. """ + if self.held_by.equipped_item: + self.held_by.equipped_item.unequip() + self.held_by.equipped_item = self + self.held_by.remove_from_inventory(self) - def hold(self, player: InventoryHolder) -> None: + def unequip(self) -> None: + """ + Indicates what should be done when the item is unequipped. + """ + self.held_by.add_to_inventory(self) + self.held_by.equipped_item = None + + def hold(self, holder: InventoryHolder) -> None: """ The item is taken from the floor and put into the inventory """ self.held = True - self.held_by = player + self.held_by = holder self.held_by.map.remove_entity(self) - player.add_to_inventory(self) + holder.add_to_inventory(self) def save_state(self) -> dict: """ @@ -116,7 +126,7 @@ class Bomb(Item): """ damage: int = 5 exploding: bool - owner: Optional["Player"] + owner: Optional["InventoryHolder"] tick: int def __init__(self, name: str = "bomb", damage: int = 5, diff --git a/squirrelbattle/entities/player.py b/squirrelbattle/entities/player.py index 19c8348..d7c9e28 100644 --- a/squirrelbattle/entities/player.py +++ b/squirrelbattle/entities/player.py @@ -4,8 +4,9 @@ from functools import reduce from queue import PriorityQueue from random import randint -from typing import Dict, Tuple +from typing import Dict, Optional, Tuple +from .items import Item from ..interfaces import FightingEntity, InventoryHolder @@ -16,12 +17,15 @@ class Player(InventoryHolder, FightingEntity): current_xp: int = 0 max_xp: int = 10 paths: Dict[Tuple[int, int], Tuple[int, int]] + equipped_item: Optional[Item] + equipped_armor: Optional[Item] def __init__(self, name: str = "player", maxhealth: int = 20, strength: int = 5, intelligence: int = 1, charisma: int = 1, dexterity: int = 1, constitution: int = 1, level: int = 1, current_xp: int = 0, max_xp: int = 10, inventory: list = None, - hazel: int = 42, *args, **kwargs) \ + hazel: int = 42, equipped_item: Optional[Item] = None, + equipped_armor: Optional[Item] = None, *args, **kwargs) \ -> None: super().__init__(name=name, maxhealth=maxhealth, strength=strength, intelligence=intelligence, charisma=charisma, @@ -32,6 +36,12 @@ class Player(InventoryHolder, FightingEntity): self.inventory = self.translate_inventory(inventory or []) self.paths = dict() self.hazel = hazel + if isinstance(equipped_item, dict): + equipped_item = self.dict_to_item(equipped_item) + if isinstance(equipped_armor, dict): + equipped_armor = self.dict_to_item(equipped_armor) + self.equipped_item = equipped_item + self.equipped_armor = equipped_armor def move(self, y: int, x: int) -> None: """ diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index 0553d2e..e0f3df9 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -126,6 +126,7 @@ class Game: self.map.tick() elif key == KeyValues.INVENTORY: self.state = GameMode.INVENTORY + self.display_actions(DisplayActions.UPDATE) elif key == KeyValues.SPACE: self.state = GameMode.MAINMENU elif key == KeyValues.CHAT: diff --git a/squirrelbattle/interfaces.py b/squirrelbattle/interfaces.py index 94025bd..c5d9e0e 100644 --- a/squirrelbattle/interfaces.py +++ b/squirrelbattle/interfaces.py @@ -496,10 +496,10 @@ class InventoryHolder(Entity): """ for i in range(len(inventory)): if isinstance(inventory[i], dict): - inventory[i] = self.dict_to_inventory(inventory[i]) + inventory[i] = self.dict_to_item(inventory[i]) return inventory - def dict_to_inventory(self, item_dict: dict) -> Entity: + def dict_to_item(self, item_dict: dict) -> Entity: """ Translate a dict object that contains the state of an item into an item object. @@ -522,13 +522,15 @@ class InventoryHolder(Entity): """ Adds an object to inventory """ - self.inventory.append(obj) + if obj not in self.inventory: + self.inventory.append(obj) def remove_from_inventory(self, obj: Any) -> None: """ Removes an object from the inventory """ - self.inventory.remove(obj) + if obj in self.inventory: + self.inventory.remove(obj) def change_hazel_balance(self, hz: int) -> None: """ From 1b4612afd05991a62f0ea75308e986f500ae996e Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 18 Dec 2020 17:39:11 +0100 Subject: [PATCH 02/13] Swords add strength --- squirrelbattle/entities/items.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/squirrelbattle/entities/items.py b/squirrelbattle/entities/items.py index 9719e3a..5564cb0 100644 --- a/squirrelbattle/entities/items.py +++ b/squirrelbattle/entities/items.py @@ -225,9 +225,28 @@ class Sword(Weapon): """ A basic weapon """ - def __init__(self, name: str = "sword", price: int = 20, *args, **kwargs): + strength: int + + def __init__(self, name: str = "sword", price: int = 20, strength: int = 3, + *args, **kwargs): super().__init__(name=name, price=price, *args, **kwargs) self.name = name + self.strength = strength + + def equip(self) -> None: + """ + When a sword is equipped, the player gains strength. + """ + super().equip() + self.held_by.strength += self.strength + + def unequip(self) -> None: + """ + Remove the strength earned by the sword. + :return: + """ + super().unequip() + self.held_by.strength -= self.strength class BodySnatchPotion(Item): From 947572522842624d9ad3882d5c8d115a1037f7a3 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 18 Dec 2020 17:50:26 +0100 Subject: [PATCH 03/13] Save equipped item and armor --- squirrelbattle/entities/player.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/squirrelbattle/entities/player.py b/squirrelbattle/entities/player.py index d7c9e28..a370264 100644 --- a/squirrelbattle/entities/player.py +++ b/squirrelbattle/entities/player.py @@ -154,4 +154,8 @@ class Player(InventoryHolder, FightingEntity): d = super().save_state() d["current_xp"] = self.current_xp d["max_xp"] = self.max_xp + d["equipped_item"] = self.equipped_item.save_state()\ + if self.equipped_item else None + d["equipped_armor"] = self.equipped_armor.save_state()\ + if self.equipped_armor else None return d From 9aa684fb7741e3fc3c188d9ff42bb4db853e07c8 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 18 Dec 2020 17:57:42 +0100 Subject: [PATCH 04/13] Use directly equipped items outside the inventory --- squirrelbattle/entities/items.py | 4 ++-- squirrelbattle/entities/player.py | 11 +++++++++++ squirrelbattle/game.py | 2 ++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/squirrelbattle/entities/items.py b/squirrelbattle/entities/items.py index 5564cb0..4da4a8c 100644 --- a/squirrelbattle/entities/items.py +++ b/squirrelbattle/entities/items.py @@ -29,7 +29,7 @@ class Item(Entity): The item is dropped from the inventory onto the floor """ if self.held: - self.held_by.inventory.remove(self) + 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 @@ -46,8 +46,8 @@ class Item(Entity): """ if self.held_by.equipped_item: self.held_by.equipped_item.unequip() - self.held_by.equipped_item = self self.held_by.remove_from_inventory(self) + self.held_by.equipped_item = self def unequip(self) -> None: """ diff --git a/squirrelbattle/entities/player.py b/squirrelbattle/entities/player.py index a370264..89f16c7 100644 --- a/squirrelbattle/entities/player.py +++ b/squirrelbattle/entities/player.py @@ -75,6 +75,17 @@ class Player(InventoryHolder, FightingEntity): self.current_xp += xp self.level_up() + def remove_from_inventory(self, obj: Item) -> None: + """ + Remove the given item from the inventory, even if the item is equipped. + """ + if obj == self.equipped_item: + self.equipped_item = None + elif obj == self.equipped_armor: + self.equipped_armor = None + else: + return super().remove_from_inventory(obj) + # noinspection PyTypeChecker,PyUnresolvedReferences def check_move(self, y: int, x: int, move_if_possible: bool = False) \ -> bool: diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index e0f3df9..d0aaf84 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -127,6 +127,8 @@ class Game: elif key == KeyValues.INVENTORY: self.state = GameMode.INVENTORY self.display_actions(DisplayActions.UPDATE) + elif key == KeyValues.USE and self.player.equipped_item: + self.player.equipped_item.use() elif key == KeyValues.SPACE: self.state = GameMode.MAINMENU elif key == KeyValues.CHAT: From c01307202a8125a222b2600b4cbcaa746591164d Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 18 Dec 2020 20:01:52 +0100 Subject: [PATCH 05/13] Add shields to be more protected, see #48 --- squirrelbattle/display/texturepack.py | 2 ++ squirrelbattle/entities/items.py | 50 ++++++++++++++++++++------- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/squirrelbattle/display/texturepack.py b/squirrelbattle/display/texturepack.py index 1f6dc76..2295667 100644 --- a/squirrelbattle/display/texturepack.py +++ b/squirrelbattle/display/texturepack.py @@ -70,6 +70,7 @@ TexturePack.ASCII_PACK = TexturePack( MERCHANT='M', PLAYER='@', RABBIT='Y', + SHIELD='D', SUNFLOWER='I', SWORD='\u2020', TEDDY_BEAR='8', @@ -96,6 +97,7 @@ TexturePack.SQUIRREL_PACK = TexturePack( PLAYER='๐Ÿฟ๏ธ ๏ธ', MERCHANT='๐Ÿฆœ', RABBIT='๐Ÿ‡', + SHIELD='๐Ÿ›ก๏ธ ', SUNFLOWER='๐ŸŒป', SWORD='๐Ÿ—ก๏ธ ', TEDDY_BEAR='๐Ÿงธ', diff --git a/squirrelbattle/entities/items.py b/squirrelbattle/entities/items.py index 4da4a8c..b3f8a84 100644 --- a/squirrelbattle/entities/items.py +++ b/squirrelbattle/entities/items.py @@ -40,14 +40,20 @@ class Item(Entity): Indicates what should be done when the item is used. """ - def equip(self) -> None: + def equip(self, armor: bool = False) -> None: """ Indicates what should be done when the item is equipped. """ - if self.held_by.equipped_item: - self.held_by.equipped_item.unequip() - self.held_by.remove_from_inventory(self) - self.held_by.equipped_item = self + if armor: + 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 + else: + if self.held_by.equipped_item: + self.held_by.equipped_item.unequip() + self.held_by.remove_from_inventory(self) + self.held_by.equipped_item = self def unequip(self) -> None: """ @@ -75,7 +81,7 @@ class Item(Entity): @staticmethod def get_all_items() -> list: - return [BodySnatchPotion, Bomb, Heart, Sword] + return [BodySnatchPotion, Bomb, Heart, Shield, Sword] def be_sold(self, buyer: InventoryHolder, seller: InventoryHolder) -> bool: """ @@ -225,20 +231,17 @@ class Sword(Weapon): """ A basic weapon """ - strength: int - - def __init__(self, name: str = "sword", price: int = 20, strength: int = 3, + def __init__(self, name: str = "sword", price: int = 20, *args, **kwargs): super().__init__(name=name, price=price, *args, **kwargs) self.name = name - self.strength = strength - def equip(self) -> None: + def equip(self, armor: bool = False) -> None: """ When a sword is equipped, the player gains strength. """ super().equip() - self.held_by.strength += self.strength + self.held_by.strength += self.damage def unequip(self) -> None: """ @@ -246,7 +249,28 @@ class Sword(Weapon): :return: """ super().unequip() - self.held_by.strength -= self.strength + self.held_by.strength -= self.damage + + +class Shield(Item): + constitution: int + + def __init__(self, constitution: int = 2, *args, **kwargs): + super().__init__(name="shield", *args, **kwargs) + self.constitution = constitution + + def equip(self, armor: bool = True) -> None: + super().equip(armor) + self.held_by.constitution += self.constitution + + def unequip(self) -> None: + super().unequip() + self.held_by.constitution -= self.constitution + + def save_state(self) -> dict: + d = super().save_state() + d["constitution"] = self.constitution + return d class BodySnatchPotion(Item): From 9b8dfb00da8cfa38f9ad5abca3a95defa4ebc7e2 Mon Sep 17 00:00:00 2001 From: eichhornchen Date: Tue, 5 Jan 2021 19:07:15 +0100 Subject: [PATCH 06/13] Added critical hit system: the player and rabbit entities have a chance of making x4 damage! Closes #52 --- squirrelbattle/entities/monsters.py | 4 ++-- squirrelbattle/entities/player.py | 6 +++--- squirrelbattle/interfaces.py | 14 +++++++++++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/squirrelbattle/entities/monsters.py b/squirrelbattle/entities/monsters.py index 34cd4bf..e50fad0 100644 --- a/squirrelbattle/entities/monsters.py +++ b/squirrelbattle/entities/monsters.py @@ -87,9 +87,9 @@ class Rabbit(Monster): A rabbit monster """ def __init__(self, name: str = "rabbit", strength: int = 1, - maxhealth: int = 15, *args, **kwargs) -> None: + maxhealth: int = 15, critical: int = 30, *args, **kwargs) -> None: super().__init__(name=name, strength=strength, - maxhealth=maxhealth, *args, **kwargs) + maxhealth=maxhealth, critical=critical, *args, **kwargs) class TeddyBear(Monster): diff --git a/squirrelbattle/entities/player.py b/squirrelbattle/entities/player.py index 89f16c7..2a023d8 100644 --- a/squirrelbattle/entities/player.py +++ b/squirrelbattle/entities/player.py @@ -25,12 +25,12 @@ class Player(InventoryHolder, FightingEntity): dexterity: int = 1, constitution: int = 1, level: int = 1, current_xp: int = 0, max_xp: int = 10, inventory: list = None, hazel: int = 42, equipped_item: Optional[Item] = None, - equipped_armor: Optional[Item] = None, *args, **kwargs) \ - -> None: + equipped_armor: Optional[Item] = None, critical: int = 5,\ + *args, **kwargs) -> None: super().__init__(name=name, maxhealth=maxhealth, strength=strength, intelligence=intelligence, charisma=charisma, dexterity=dexterity, constitution=constitution, - level=level, *args, **kwargs) + level=level, critical=critical, *args, **kwargs) self.current_xp = current_xp self.max_xp = max_xp self.inventory = self.translate_inventory(inventory or []) diff --git a/squirrelbattle/interfaces.py b/squirrelbattle/interfaces.py index c5d9e0e..599f546 100644 --- a/squirrelbattle/interfaces.py +++ b/squirrelbattle/interfaces.py @@ -403,11 +403,12 @@ class FightingEntity(Entity): dexterity: int constitution: int level: int + critical: int def __init__(self, maxhealth: int = 0, health: Optional[int] = None, strength: int = 0, intelligence: int = 0, charisma: int = 0, dexterity: int = 0, constitution: int = 0, level: int = 0, - *args, **kwargs) -> None: + critical: int = 0, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.maxhealth = maxhealth self.health = maxhealth if health is None else health @@ -417,6 +418,7 @@ class FightingEntity(Entity): self.dexterity = dexterity self.constitution = constitution self.level = level + self.critical = critical @property def dead(self) -> bool: @@ -426,10 +428,16 @@ class FightingEntity(Entity): """ Deals damage to the opponent, based on the stats """ + diceroll = randint(0, 100) + damage = self.strength + string = " " + if diceroll <= self.critical: # It is a critical hit + damage *= 4 + string = _(" It's a critical hit! ") return _("{name} hits {opponent}.")\ .format(name=_(self.translated_name.capitalize()), - opponent=_(opponent.translated_name)) + " " + \ - opponent.take_damage(self, self.strength) + opponent=_(opponent.translated_name)) + string + \ + opponent.take_damage(self, damage) def take_damage(self, attacker: "Entity", amount: int) -> str: """ From 4bddf076ea5de4efdd80cf26184cd444059a1be0 Mon Sep 17 00:00:00 2001 From: eichhornchen Date: Tue, 5 Jan 2021 19:18:25 +0100 Subject: [PATCH 07/13] Fighting now takes into account the constitution. Closes #51 --- squirrelbattle/entities/items.py | 30 +++++++++++++++--------------- squirrelbattle/interfaces.py | 7 ++++--- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/squirrelbattle/entities/items.py b/squirrelbattle/entities/items.py index b3f8a84..6c54fef 100644 --- a/squirrelbattle/entities/items.py +++ b/squirrelbattle/entities/items.py @@ -226,6 +226,21 @@ class Weapon(Item): d["damage"] = self.damage return d + def equip(self, armor: bool = False) -> None: + """ + When a weapon is equipped, the player gains strength. + """ + super().equip() + self.held_by.strength += self.damage + + def unequip(self) -> None: + """ + Remove the strength earned by the weapon. + :return: + """ + super().unequip() + self.held_by.strength -= self.damage + class Sword(Weapon): """ @@ -236,21 +251,6 @@ class Sword(Weapon): super().__init__(name=name, price=price, *args, **kwargs) self.name = name - def equip(self, armor: bool = False) -> None: - """ - When a sword is equipped, the player gains strength. - """ - super().equip() - self.held_by.strength += self.damage - - def unequip(self) -> None: - """ - Remove the strength earned by the sword. - :return: - """ - super().unequip() - self.held_by.strength -= self.damage - class Shield(Item): constitution: int diff --git a/squirrelbattle/interfaces.py b/squirrelbattle/interfaces.py index 599f546..dceea6a 100644 --- a/squirrelbattle/interfaces.py +++ b/squirrelbattle/interfaces.py @@ -443,11 +443,12 @@ class FightingEntity(Entity): """ Take damage from the attacker, based on the stats """ - self.health -= amount + damage = max(0, amount - self.constitution) + self.health -= damage if self.health <= 0: self.die() - return _("{name} takes {amount} damage.")\ - .format(name=self.translated_name.capitalize(), amount=str(amount))\ + return _("{name} takes {damage} damage.")\ + .format(name=self.translated_name.capitalize(), damage=str(damage))\ + (" " + _("{name} dies.") .format(name=self.translated_name.capitalize()) if self.health <= 0 else "") From 3ace133037f62e511d7cd021e530fc5259aaf751 Mon Sep 17 00:00:00 2001 From: eichhornchen Date: Tue, 5 Jan 2021 19:23:25 +0100 Subject: [PATCH 08/13] Critical hit chance is now displayed along with the other stats. --- squirrelbattle/display/statsdisplay.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/squirrelbattle/display/statsdisplay.py b/squirrelbattle/display/statsdisplay.py index 00f6675..b3ae831 100644 --- a/squirrelbattle/display/statsdisplay.py +++ b/squirrelbattle/display/statsdisplay.py @@ -25,10 +25,11 @@ class StatsDisplay(Display): self.player.max_xp, self.player.health, self.player.maxhealth) self.addstr(self.pad, 0, 0, string2) - string3 = "STR {}\nINT {}\nCHR {}\nDEX {}\nCON {}"\ + string3 = "STR {}\nINT {}\nCHR {}\nDEX {}\nCON {}\nCRI {}%"\ .format(self.player.strength, self.player.intelligence, self.player.charisma, - self.player.dexterity, self.player.constitution) + self.player.dexterity, self.player.constitution,\ + self.player.critical) self.addstr(self.pad, 3, 0, string3) inventory_str = _("Inventory:") + " " @@ -44,22 +45,22 @@ class StatsDisplay(Display): if count > 1: inventory_str += f"x{count} " printed_items.append(item) - self.addstr(self.pad, 8, 0, inventory_str) + self.addstr(self.pad, 9, 0, inventory_str) if self.player.equipped_item: - self.addstr(self.pad, 9, 0, + self.addstr(self.pad, 10, 0, _("Equipped item:") + " " f"{self.pack[self.player.equipped_item.name.upper()]}") if self.player.equipped_armor: - self.addstr(self.pad, 10, 0, + self.addstr(self.pad, 11, 0, _("Equipped armor:") + " " f"{self.pack[self.player.equipped_armor.name.upper()]}") - self.addstr(self.pad, 11, 0, f"{self.pack.HAZELNUT} " + self.addstr(self.pad, 12, 0, f"{self.pack.HAZELNUT} " f"x{self.player.hazel}") if self.player.dead: - self.addstr(self.pad, 13, 0, _("YOU ARE DEAD"), curses.COLOR_RED, + self.addstr(self.pad, 14, 0, _("YOU ARE DEAD"), curses.COLOR_RED, bold=True, blink=True, standout=True) def display(self) -> None: From 424044a5e4f1998d2c2949f895bf631d8a370d67 Mon Sep 17 00:00:00 2001 From: eichhornchen Date: Tue, 5 Jan 2021 19:40:11 +0100 Subject: [PATCH 09/13] Added an overpowered eagle boss. To avoid seing it too often, entities now have a certain chance of being spawned. Closes #19. --- squirrelbattle/display/texturepack.py | 3 +++ squirrelbattle/entities/monsters.py | 9 +++++++++ squirrelbattle/interfaces.py | 21 ++++++++++++++++----- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/squirrelbattle/display/texturepack.py b/squirrelbattle/display/texturepack.py index 2295667..ed89be6 100644 --- a/squirrelbattle/display/texturepack.py +++ b/squirrelbattle/display/texturepack.py @@ -30,6 +30,7 @@ class TexturePack: TEDDY_BEAR: str TIGER: str WALL: str + EAGLE: str ASCII_PACK: "TexturePack" SQUIRREL_PACK: "TexturePack" @@ -76,6 +77,7 @@ TexturePack.ASCII_PACK = TexturePack( TEDDY_BEAR='8', TIGER='n', WALL='#', + EAGLE='ยต', ) TexturePack.SQUIRREL_PACK = TexturePack( @@ -103,4 +105,5 @@ TexturePack.SQUIRREL_PACK = TexturePack( TEDDY_BEAR='๐Ÿงธ', TIGER='๐Ÿ…', WALL='๐Ÿงฑ', + EAGLE='๐Ÿฆ…', ) diff --git a/squirrelbattle/entities/monsters.py b/squirrelbattle/entities/monsters.py index e50fad0..bcdff11 100644 --- a/squirrelbattle/entities/monsters.py +++ b/squirrelbattle/entities/monsters.py @@ -100,3 +100,12 @@ class TeddyBear(Monster): maxhealth: int = 50, *args, **kwargs) -> None: super().__init__(name=name, strength=strength, maxhealth=maxhealth, *args, **kwargs) + +class GiantSeaEagle(Monster): + """ + An eagle boss + """ + def __init__(self, name: str = "eagle", strength: int = 1000, + maxhealth: int = 5000, *args, **kwargs) -> None: + super().__init__(name=name, strength=strength, + maxhealth=maxhealth, *args, **kwargs) diff --git a/squirrelbattle/interfaces.py b/squirrelbattle/interfaces.py index dceea6a..25a8baa 100644 --- a/squirrelbattle/interfaces.py +++ b/squirrelbattle/interfaces.py @@ -3,7 +3,7 @@ from enum import Enum, auto from math import sqrt -from random import choice, randint +from random import choice, randint, choices from typing import List, Optional, Any from .display.texturepack import TexturePack @@ -146,7 +146,8 @@ class Map: tile = self.tiles[y][x] if tile.can_walk(): break - entity = choice(Entity.get_all_entity_classes())() + entity = choices(Entity.get_all_entity_classes(),\ + weights = Entity.get_weights(), k=1)[0]() entity.move(y, x) self.add_entity(entity) @@ -349,10 +350,19 @@ class Entity: """ from squirrelbattle.entities.items import BodySnatchPotion, Bomb, Heart from squirrelbattle.entities.monsters import Tiger, Hedgehog, \ - Rabbit, TeddyBear + Rabbit, TeddyBear, GiantSeaEagle from squirrelbattle.entities.friendly import Merchant, Sunflower return [BodySnatchPotion, Bomb, Heart, Hedgehog, Rabbit, TeddyBear, - Sunflower, Tiger, Merchant] + Sunflower, Tiger, Merchant, GiantSeaEagle] + + @staticmethod + def get_weights() -> list: + """ + Returns a weigth list associated to the above function, to + be used to spawn random entities with a certain probability. + """ + return [3, 5, 6, 5, 5, 5, + 5, 4, 4, 1] @staticmethod def get_all_entity_classes_in_a_dict() -> dict: @@ -361,7 +371,7 @@ class Entity: """ from squirrelbattle.entities.player import Player from squirrelbattle.entities.monsters import Tiger, Hedgehog, Rabbit, \ - TeddyBear + TeddyBear, GiantSeaEagle from squirrelbattle.entities.friendly import Merchant, Sunflower from squirrelbattle.entities.items import BodySnatchPotion, Bomb, \ Heart, Sword @@ -377,6 +387,7 @@ class Entity: "Merchant": Merchant, "Sunflower": Sunflower, "Sword": Sword, + "Eagle": GiantSeaEagle, } def save_state(self) -> dict: From 601062237db8ffa1de7bb026d874eba68a2834be Mon Sep 17 00:00:00 2001 From: eichhornchen Date: Tue, 5 Jan 2021 19:50:25 +0100 Subject: [PATCH 10/13] Repairing part of the tests. --- squirrelbattle/tests/entities_test.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/squirrelbattle/tests/entities_test.py b/squirrelbattle/tests/entities_test.py index 70e3748..1d7a7a9 100644 --- a/squirrelbattle/tests/entities_test.py +++ b/squirrelbattle/tests/entities_test.py @@ -18,6 +18,7 @@ class TestEntities(unittest.TestCase): """ self.map = Map.load(ResourceManager.get_asset_path("example_map.txt")) self.player = Player() + self.player.constitution = 0 self.map.add_entity(self.player) self.player.move(self.map.start_y, self.map.start_x) @@ -54,6 +55,7 @@ class TestEntities(unittest.TestCase): self.assertTrue(entity.dead) entity = Rabbit() + entity.critical = 0 self.map.add_entity(entity) entity.move(15, 44) # Move randomly From f3fe04e13a217c1251310438f726e7bb06aff158 Mon Sep 17 00:00:00 2001 From: eichhornchen Date: Wed, 6 Jan 2021 10:46:36 +0100 Subject: [PATCH 11/13] The player now has two hands and a slot for a helmet and a chestplate. Accordingly, new classes of items have been added. --- squirrelbattle/display/statsdisplay.py | 22 ++++--- squirrelbattle/display/texturepack.py | 7 +++ squirrelbattle/entities/items.py | 84 +++++++++++++++++++++----- squirrelbattle/entities/player.py | 36 ++++++++--- 4 files changed, 118 insertions(+), 31 deletions(-) diff --git a/squirrelbattle/display/statsdisplay.py b/squirrelbattle/display/statsdisplay.py index b3ae831..e24c969 100644 --- a/squirrelbattle/display/statsdisplay.py +++ b/squirrelbattle/display/statsdisplay.py @@ -47,20 +47,28 @@ class StatsDisplay(Display): printed_items.append(item) self.addstr(self.pad, 9, 0, inventory_str) - if self.player.equipped_item: + if self.player.equipped_main: self.addstr(self.pad, 10, 0, - _("Equipped item:") + " " - f"{self.pack[self.player.equipped_item.name.upper()]}") - if self.player.equipped_armor: + _("Equipped main:") + " " + f"{self.pack[self.player.equipped_main.name.upper()]}") + if self.player.equipped_secondary: self.addstr(self.pad, 11, 0, - _("Equipped armor:") + " " + _("Equipped secondary:") + " " + f"{self.pack[self.player.equipped_secondary.name.upper()]}") + if self.player.equipped_armor: + self.addstr(self.pad, 12, 0, + _("Equipped chestplate:") + " " f"{self.pack[self.player.equipped_armor.name.upper()]}") + if self.player.equipped_helmet: + self.addstr(self.pad, 13, 0, + _("Equipped helmet:") + " " + f"{self.pack[self.player.equipped_helmet.name.upper()]}") - self.addstr(self.pad, 12, 0, f"{self.pack.HAZELNUT} " + self.addstr(self.pad, 14, 0, f"{self.pack.HAZELNUT} " f"x{self.player.hazel}") if self.player.dead: - self.addstr(self.pad, 14, 0, _("YOU ARE DEAD"), curses.COLOR_RED, + self.addstr(self.pad, 15, 0, _("YOU ARE DEAD"), curses.COLOR_RED, bold=True, blink=True, standout=True) def display(self) -> None: diff --git a/squirrelbattle/display/texturepack.py b/squirrelbattle/display/texturepack.py index ed89be6..8d4e785 100644 --- a/squirrelbattle/display/texturepack.py +++ b/squirrelbattle/display/texturepack.py @@ -31,6 +31,9 @@ class TexturePack: TIGER: str WALL: str EAGLE: str + SHIELD: str + CHESTPLATE: str + HELMET: str ASCII_PACK: "TexturePack" SQUIRREL_PACK: "TexturePack" @@ -78,6 +81,8 @@ TexturePack.ASCII_PACK = TexturePack( TIGER='n', WALL='#', EAGLE='ยต', + CHESTPLATE='(', + HELMET='0', ) TexturePack.SQUIRREL_PACK = TexturePack( @@ -106,4 +111,6 @@ TexturePack.SQUIRREL_PACK = TexturePack( TIGER='๐Ÿ…', WALL='๐Ÿงฑ', EAGLE='๐Ÿฆ…', + CHESTPLATE='๐Ÿฆบ', + HELMET='โ›‘๏ธ', ) diff --git a/squirrelbattle/entities/items.py b/squirrelbattle/entities/items.py index 6c54fef..8b99a8d 100644 --- a/squirrelbattle/entities/items.py +++ b/squirrelbattle/entities/items.py @@ -40,27 +40,53 @@ class Item(Entity): Indicates what should be done when the item is used. """ - def equip(self, armor: bool = False) -> None: + def equip(self) -> None: """ Indicates what should be done when the item is equipped. """ - if armor: + if isinstance(self, Chestplate): 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 - else: - if self.held_by.equipped_item: - self.held_by.equipped_item.unequip() + elif isinstance(self, Helmet): + if self.held_by.equipped_helmet: + self.held_by.equipped_helmet.unequip() self.held_by.remove_from_inventory(self) - self.held_by.equipped_item = self + self.held_by.equipped_helmet = self + elif isinstance(self, Weapon): + if self.held_by.equipped_main: + 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 + # For weapons, they are equipped as main only if main is empty. + else: + self.held_by.remove_from_inventory(self) + self.held_by.equipped_main = self + else: + # 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 def unequip(self) -> None: """ Indicates what should be done when the item is unequipped. """ + if isinstance(self, Chestplate): + self.held_by.equipped_armor = None + elif isinstance(self, Helmet): + self.held_by.equipped_helmet = None + elif isinstance(self, Weapon): + if self.held_by.equipped_main == self: + self.held_by.equipped_main = None + else: + self.held_by.equipped_secondary = None + else: + self.held_by.equipped_secondary = None self.held_by.add_to_inventory(self) - self.held_by.equipped_item = None def hold(self, holder: InventoryHolder) -> None: """ @@ -81,7 +107,8 @@ class Item(Entity): @staticmethod def get_all_items() -> list: - return [BodySnatchPotion, Bomb, Heart, Shield, Sword] + return [BodySnatchPotion, Bomb, Heart, Shield, Sword,\ + Chestplate, Helmet] def be_sold(self, buyer: InventoryHolder, seller: InventoryHolder) -> bool: """ @@ -226,7 +253,7 @@ class Weapon(Item): d["damage"] = self.damage return d - def equip(self, armor: bool = False) -> None: + def equip(self) -> None: """ When a weapon is equipped, the player gains strength. """ @@ -252,15 +279,18 @@ class Sword(Weapon): self.name = name -class Shield(Item): +class Armor(Item): + """ + Class of items that increase the player's constitution. + """ constitution: int - - def __init__(self, constitution: int = 2, *args, **kwargs): - super().__init__(name="shield", *args, **kwargs) + + def __init__(self, constitution: int, *args, **kwargs): + super().__init__(*args, **kwargs) self.constitution = constitution - def equip(self, armor: bool = True) -> None: - super().equip(armor) + def equip(self) -> None: + super().equip() self.held_by.constitution += self.constitution def unequip(self) -> None: @@ -272,6 +302,30 @@ class Shield(Item): d["constitution"] = self.constitution return d +class Shield(Armor): + """ + Class of shield items, they can be equipped in the other hand. + """ + + def __init__(self, constitution: int = 2, *args, **kwargs): + super().__init__(name="shield", constitution=constitution, *args, **kwargs) + +class Helmet(Armor): + """ + Class of helmet items, they can be equipped on the head. + """ + + def __init__(self, constitution: int = 2, *args, **kwargs): + super().__init__(name="helmet", constitution=constitution, *args, **kwargs) + +class Chestplate(Armor): + """ + Class of chestplate items, they can be equipped on the body. + """ + + def __init__(self, constitution: int = 4, *args, **kwargs): + super().__init__(name="chestplate", constitution=constitution, *args, **kwargs) + class BodySnatchPotion(Item): """ diff --git a/squirrelbattle/entities/player.py b/squirrelbattle/entities/player.py index 2a023d8..a0ddd6c 100644 --- a/squirrelbattle/entities/player.py +++ b/squirrelbattle/entities/player.py @@ -17,15 +17,19 @@ class Player(InventoryHolder, FightingEntity): current_xp: int = 0 max_xp: int = 10 paths: Dict[Tuple[int, int], Tuple[int, int]] - equipped_item: Optional[Item] + equipped_main: Optional[Item] + equipped_secondary: Optional[Item] + equipped_helmet: Optional[Item] equipped_armor: Optional[Item] def __init__(self, name: str = "player", maxhealth: int = 20, strength: int = 5, intelligence: int = 1, charisma: int = 1, dexterity: int = 1, constitution: int = 1, level: int = 1, current_xp: int = 0, max_xp: int = 10, inventory: list = None, - hazel: int = 42, equipped_item: Optional[Item] = None, + hazel: int = 42, equipped_main: Optional[Item] = None, equipped_armor: Optional[Item] = None, critical: int = 5,\ + equipped_secondary: Optional[Item] = None, \ + equipped_helmet: Optional[Item] = None, \ *args, **kwargs) -> None: super().__init__(name=name, maxhealth=maxhealth, strength=strength, intelligence=intelligence, charisma=charisma, @@ -36,12 +40,18 @@ class Player(InventoryHolder, FightingEntity): self.inventory = self.translate_inventory(inventory or []) self.paths = dict() self.hazel = hazel - if isinstance(equipped_item, dict): - equipped_item = self.dict_to_item(equipped_item) + if isinstance(equipped_main, dict): + equipped_main = self.dict_to_item(equipped_main) if isinstance(equipped_armor, dict): equipped_armor = self.dict_to_item(equipped_armor) - self.equipped_item = equipped_item + if isinstance(equipped_secondary, dict): + equipped_secondary = self.dict_to_item(equipped_secondary) + if isinstance(equipped_helmet, dict): + equipped_helmet = self.dict_to_item(equipped_helmet) + self.equipped_main = equipped_main self.equipped_armor = equipped_armor + self.equipped_secondary = equipped_secondary + self.equipped_helmet = equipped_helmet def move(self, y: int, x: int) -> None: """ @@ -79,10 +89,14 @@ class Player(InventoryHolder, FightingEntity): """ Remove the given item from the inventory, even if the item is equipped. """ - if obj == self.equipped_item: - self.equipped_item = None + if obj == self.equipped_main: + self.equipped_main = None elif obj == self.equipped_armor: self.equipped_armor = None + elif obj == self.equipped_secondary: + self.equipped_secondary = None + elif obj == self.equipped_helmet: + self.equipped_helmet = None else: return super().remove_from_inventory(obj) @@ -165,8 +179,12 @@ class Player(InventoryHolder, FightingEntity): d = super().save_state() d["current_xp"] = self.current_xp d["max_xp"] = self.max_xp - d["equipped_item"] = self.equipped_item.save_state()\ - if self.equipped_item else None + d["equipped_main"] = self.equipped_main.save_state()\ + if self.equipped_main else None d["equipped_armor"] = self.equipped_armor.save_state()\ if self.equipped_armor else None + d["equipped_secondary"] = self.equipped_secondary.save_state()\ + if self.equipped_secondary else None + d["equipped_helmet"] = self.equipped_helmet.save_state()\ + if self.equipped_helmet else None return d From a9aeb9ca3a9748234166a45771bb67c16a1da131 Mon Sep 17 00:00:00 2001 From: eichhornchen Date: Wed, 6 Jan 2021 11:13:17 +0100 Subject: [PATCH 12/13] Repaired the use functionnality of the main item, as well as the load system for Armor items. --- squirrelbattle/entities/items.py | 16 +++++++++------- squirrelbattle/game.py | 4 ++-- squirrelbattle/interfaces.py | 5 ++++- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/squirrelbattle/entities/items.py b/squirrelbattle/entities/items.py index 8b99a8d..05654e9 100644 --- a/squirrelbattle/entities/items.py +++ b/squirrelbattle/entities/items.py @@ -276,7 +276,6 @@ class Sword(Weapon): def __init__(self, name: str = "sword", price: int = 20, *args, **kwargs): super().__init__(name=name, price=price, *args, **kwargs) - self.name = name class Armor(Item): @@ -307,24 +306,27 @@ class Shield(Armor): Class of shield items, they can be equipped in the other hand. """ - def __init__(self, constitution: int = 2, *args, **kwargs): - super().__init__(name="shield", constitution=constitution, *args, **kwargs) + def __init__(self, name: str = "shield", constitution: int = 2,\ + price: int = 6, *args, **kwargs): + super().__init__(name=name, constitution=constitution, *args, **kwargs) class Helmet(Armor): """ Class of helmet items, they can be equipped on the head. """ - def __init__(self, constitution: int = 2, *args, **kwargs): - super().__init__(name="helmet", constitution=constitution, *args, **kwargs) + def __init__(self, name: str = "helmet", constitution: int = 2, \ + price: int = 8, *args, **kwargs): + super().__init__(name=name, constitution=constitution, *args, **kwargs) class Chestplate(Armor): """ Class of chestplate items, they can be equipped on the body. """ - def __init__(self, constitution: int = 4, *args, **kwargs): - super().__init__(name="chestplate", constitution=constitution, *args, **kwargs) + def __init__(self, name: str = "chestplate", constitution: int = 4,\ + price: int = 15, *args, **kwargs): + super().__init__(name=name, constitution=constitution, *args, **kwargs) class BodySnatchPotion(Item): diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index d0aaf84..939325c 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -127,8 +127,8 @@ class Game: elif key == KeyValues.INVENTORY: self.state = GameMode.INVENTORY self.display_actions(DisplayActions.UPDATE) - elif key == KeyValues.USE and self.player.equipped_item: - self.player.equipped_item.use() + elif key == KeyValues.USE and self.player.equipped_main: + self.player.equipped_main.use() elif key == KeyValues.SPACE: self.state = GameMode.MAINMENU elif key == KeyValues.CHAT: diff --git a/squirrelbattle/interfaces.py b/squirrelbattle/interfaces.py index 25a8baa..cc5b36e 100644 --- a/squirrelbattle/interfaces.py +++ b/squirrelbattle/interfaces.py @@ -374,7 +374,7 @@ class Entity: TeddyBear, GiantSeaEagle from squirrelbattle.entities.friendly import Merchant, Sunflower from squirrelbattle.entities.items import BodySnatchPotion, Bomb, \ - Heart, Sword + Heart, Sword, Shield, Chestplate, Helmet return { "Tiger": Tiger, "Bomb": Bomb, @@ -388,6 +388,9 @@ class Entity: "Sunflower": Sunflower, "Sword": Sword, "Eagle": GiantSeaEagle, + "Shield": Shield, + "Chestplate": Chestplate, + "Helmet": Helmet, } def save_state(self) -> dict: From 4ad7d6c37cca74080536c9a1f684d6138ce664b7 Mon Sep 17 00:00:00 2001 From: eichhornchen Date: Wed, 6 Jan 2021 11:44:52 +0100 Subject: [PATCH 13/13] Added rings that can augment the player's statistics. Also added a new statistic : xp_buff, which helps the player level up sooner. --- squirrelbattle/display/texturepack.py | 8 +++- squirrelbattle/entities/items.py | 68 ++++++++++++++++++++++++++- squirrelbattle/entities/player.py | 6 ++- squirrelbattle/interfaces.py | 4 +- 4 files changed, 81 insertions(+), 5 deletions(-) diff --git a/squirrelbattle/display/texturepack.py b/squirrelbattle/display/texturepack.py index 8d4e785..bd4b563 100644 --- a/squirrelbattle/display/texturepack.py +++ b/squirrelbattle/display/texturepack.py @@ -34,6 +34,8 @@ class TexturePack: SHIELD: str CHESTPLATE: str HELMET: str + RING_OF_MORE_EXPERIENCE: str + RING_OF_CRITICAL_DAMAGE: str ASCII_PACK: "TexturePack" SQUIRREL_PACK: "TexturePack" @@ -64,7 +66,7 @@ TexturePack.ASCII_PACK = TexturePack( entity_bg_color=curses.COLOR_BLACK, BODY_SNATCH_POTION='S', - BOMB='o', + BOMB='รง', EMPTY=' ', EXPLOSION='%', FLOOR='.', @@ -83,6 +85,8 @@ TexturePack.ASCII_PACK = TexturePack( EAGLE='ยต', CHESTPLATE='(', HELMET='0', + RING_OF_MORE_EXPERIENCE='o', + RING_OF_CRITICAL_DAMAGE='o', ) TexturePack.SQUIRREL_PACK = TexturePack( @@ -113,4 +117,6 @@ TexturePack.SQUIRREL_PACK = TexturePack( EAGLE='๐Ÿฆ…', CHESTPLATE='๐Ÿฆบ', HELMET='โ›‘๏ธ', + RING_OF_MORE_EXPERIENCE='๐Ÿ’', + RING_OF_CRITICAL_DAMAGE='๐Ÿ’', ) diff --git a/squirrelbattle/entities/items.py b/squirrelbattle/entities/items.py index 05654e9..336d3e5 100644 --- a/squirrelbattle/entities/items.py +++ b/squirrelbattle/entities/items.py @@ -108,7 +108,7 @@ class Item(Entity): @staticmethod def get_all_items() -> list: return [BodySnatchPotion, Bomb, Heart, Shield, Sword,\ - Chestplate, Helmet] + Chestplate, Helmet, RingCritical, RingXP] def be_sold(self, buyer: InventoryHolder, seller: InventoryHolder) -> bool: """ @@ -361,3 +361,69 @@ class BodySnatchPotion(Item): self.held_by.recalculate_paths() self.held_by.inventory.remove(self) + +class Ring(Item): + """ + A class of rings that boost the player's statistics. + """ + maxhealth: int + strength: int + intelligence: int + charisma: int + dexterity: int + constitution: int + critical: int + experience: float + + def __init__(self, maxhealth: int = 0, strength: int = 0,\ + intelligence: int = 0, charisma: int = 0,\ + dexterity: int = 0, constitution: int = 0,\ + critical: int = 0, experience: float = 0, *args, **kwargs): + super().__init__(*args, **kwargs) + self.maxhealth = maxhealth + self.strength = strength + self.intelligence = intelligence + self.charisma = charisma + self.dexterity = dexterity + self.constitution = constitution + self.critical = critical + self.experience = experience + + def equip(self) -> None: + super().equip() + self.held_by.maxhealth += self.maxhealth + self.held_by.strength += self.strength + self.held_by.intelligence += self.intelligence + self.held_by.charisma += self.charisma + self.held_by.dexterity += self.dexterity + self.held_by.constitution += self.constitution + self.held_by.critical += self.critical + self.held_by.xp_buff += self.experience + + def unequip(self) -> None: + super().unequip() + self.held_by.maxhealth -= self.maxhealth + self.held_by.strength -= self.strength + self.held_by.intelligence -= self.intelligence + self.held_by.charisma -= self.charisma + self.held_by.dexterity -= self.dexterity + self.held_by.constitution -= self.constitution + self.held_by.critical -= self.critical + self.held_by.xp_buff -= self.experience + + def save_state(self) -> dict: + d = super().save_state() + d["constitution"] = self.constitution + return d + +class RingCritical(Ring): + def __init__(self, name: str = "ring_of_critical_damage", price: int = 15, + critical: int = 20, *args, **kwargs): + super().__init__(name=name, price=price, critical=critical, \ + *args, **kwargs) + +class RingXP(Ring): + def __init__(self, name: str = "ring_of_more_experience", price: int = 25, + experience: float = 2, *args, **kwargs): + super().__init__(name=name, price=price, experience=experience, \ + *args, **kwargs) diff --git a/squirrelbattle/entities/player.py b/squirrelbattle/entities/player.py index a0ddd6c..854bd93 100644 --- a/squirrelbattle/entities/player.py +++ b/squirrelbattle/entities/player.py @@ -16,6 +16,7 @@ class Player(InventoryHolder, FightingEntity): """ current_xp: int = 0 max_xp: int = 10 + xp_buff: float = 1 paths: Dict[Tuple[int, int], Tuple[int, int]] equipped_main: Optional[Item] equipped_secondary: Optional[Item] @@ -29,7 +30,7 @@ class Player(InventoryHolder, FightingEntity): hazel: int = 42, equipped_main: Optional[Item] = None, equipped_armor: Optional[Item] = None, critical: int = 5,\ equipped_secondary: Optional[Item] = None, \ - equipped_helmet: Optional[Item] = None, \ + equipped_helmet: Optional[Item] = None, xp_buff: float = 1,\ *args, **kwargs) -> None: super().__init__(name=name, maxhealth=maxhealth, strength=strength, intelligence=intelligence, charisma=charisma, @@ -37,6 +38,7 @@ class Player(InventoryHolder, FightingEntity): level=level, critical=critical, *args, **kwargs) self.current_xp = current_xp self.max_xp = max_xp + self.xp_buff = xp_buff self.inventory = self.translate_inventory(inventory or []) self.paths = dict() self.hazel = hazel @@ -82,7 +84,7 @@ class Player(InventoryHolder, FightingEntity): Add some experience to the player. If the required amount is reached, level up. """ - self.current_xp += xp + self.current_xp += int(xp*self.xp_buff) self.level_up() def remove_from_inventory(self, obj: Item) -> None: diff --git a/squirrelbattle/interfaces.py b/squirrelbattle/interfaces.py index cc5b36e..b6a3a51 100644 --- a/squirrelbattle/interfaces.py +++ b/squirrelbattle/interfaces.py @@ -374,7 +374,7 @@ class Entity: TeddyBear, GiantSeaEagle from squirrelbattle.entities.friendly import Merchant, Sunflower from squirrelbattle.entities.items import BodySnatchPotion, Bomb, \ - Heart, Sword, Shield, Chestplate, Helmet + Heart, Sword, Shield, Chestplate, Helmet, RingCritical, RingXP return { "Tiger": Tiger, "Bomb": Bomb, @@ -391,6 +391,8 @@ class Entity: "Shield": Shield, "Chestplate": Chestplate, "Helmet": Helmet, + "RingCritical": RingCritical, + "RingXP": RingXP, } def save_state(self) -> dict: