Merge branch 'master' into 'mouse_interaction'

# Conflicts:
#   squirrelbattle/display/display_manager.py
#   squirrelbattle/display/menudisplay.py
#   squirrelbattle/entities/items.py
This commit is contained in:
ynerant
2020-12-11 18:38:13 +01:00
17 changed files with 865 additions and 118 deletions

View File

@ -0,0 +1,50 @@
from ..interfaces import FriendlyEntity, InventoryHolder
from ..translations import gettext as _
from .player import Player
from .items import Item
from random import choice
class Merchant(InventoryHolder, FriendlyEntity):
"""
The class for merchants in the dungeon
"""
def keys(self) -> list:
"""
Returns a friendly entitie's specific attributes
"""
return super().keys() + ["inventory", "hazel"]
def __init__(self, name: str = "merchant", inventory: list = None,
hazel: int = 75, *args, **kwargs):
super().__init__(name=name, *args, **kwargs)
self.inventory = self.translate_inventory(inventory or [])
self.hazel = hazel
if not self.inventory:
for i in range(5):
self.inventory.append(choice(Item.get_all_items())())
def talk_to(self, player: Player) -> str:
"""
This function is used to open the merchant's inventory in a menu,
and allow the player to buy/sell objects
"""
return _("I don't sell any squirrel")
def change_hazel_balance(self, hz: int) -> None:
"""
Change the number of hazel the merchant has by hz.
"""
self.hazel += hz
class Sunflower(FriendlyEntity):
"""
A friendly sunflower
"""
dialogue_option = [_("Flower power!!"), _("The sun is warm today")]
def __init__(self, maxhealth: int = 15,
*args, **kwargs) -> None:
super().__init__(name="sunflower", maxhealth=maxhealth, *args, **kwargs)

View File

@ -5,7 +5,7 @@ from random import choice, randint
from typing import Optional
from .player import Player
from ..interfaces import Entity, FightingEntity, Map
from ..interfaces import Entity, FightingEntity, Map, InventoryHolder
from ..translations import gettext as _
@ -14,13 +14,16 @@ class Item(Entity):
A class for items
"""
held: bool
held_by: Optional[Player]
held_by: Optional[InventoryHolder]
price: int
def __init__(self, held: bool = False, held_by: Optional[Player] = None,
*args, **kwargs):
def __init__(self, held: bool = False,
held_by: Optional[InventoryHolder] = None,
price: int = 2, *args, **kwargs):
super().__init__(*args, **kwargs)
self.held = held
self.held_by = held_by
self.price = price
def drop(self) -> None:
"""
@ -43,14 +46,14 @@ class Item(Entity):
Indicates what should be done when the item is equipped.
"""
def hold(self, player: "Player") -> None:
def hold(self, player: InventoryHolder) -> None:
"""
The item is taken from the floor and put into the inventory
"""
self.held = True
self.held_by = player
self.held_by.map.remove_entity(self)
player.inventory.append(self)
player.add_to_inventory(self)
def save_state(self) -> dict:
"""
@ -60,6 +63,25 @@ class Item(Entity):
d["held"] = self.held
return d
@staticmethod
def get_all_items() -> list:
return [BodySnatchPotion, Bomb, Heart, Sword]
def be_sold(self, buyer: InventoryHolder, seller: InventoryHolder) -> bool:
"""
Does all necessary actions when an object is to be sold.
Is overwritten by some classes that cannot exist in the player's
inventory
"""
if buyer.hazel >= self.price:
self.hold(buyer)
seller.remove_from_inventory(self)
buyer.change_hazel_balance(-self.price)
seller.change_hazel_balance(self.price)
return True
else:
return False
class Heart(Item):
"""
@ -67,16 +89,17 @@ class Heart(Item):
"""
healing: int
def __init__(self, name: str = "heart", healing: int = 5, *args, **kwargs):
super().__init__(name=name, *args, **kwargs)
def __init__(self, name: str = "heart", healing: int = 5, price: int = 3,
*args, **kwargs):
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)
self.map.remove_entity(self)
entity.health = min(entity.maxhealth, entity.health + self.healing)
entity.map.remove_entity(self)
def save_state(self) -> dict:
"""
@ -97,8 +120,8 @@ class Bomb(Item):
tick: int
def __init__(self, name: str = "bomb", damage: int = 5,
exploding: bool = False, *args, **kwargs):
super().__init__(name=name, *args, **kwargs)
exploding: bool = False, price: int = 4, *args, **kwargs):
super().__init__(name=name, price=price, *args, **kwargs)
self.damage = damage
self.exploding = exploding
self.tick = 4
@ -145,14 +168,43 @@ class Bomb(Item):
return d
class Weapon(Item):
"""
Non-throwable items that improve player damage
"""
damage: int
def __init__(self, damage: int = 3, *args, **kwargs):
super().__init__(*args, **kwargs)
self.damage = damage
def save_state(self) -> dict:
"""
Saves the state of the weapon into a dictionary
"""
d = super().save_state()
d["damage"] = self.damage
return d
class Sword(Weapon):
"""
A basic weapon
"""
def __init__(self, name: str = "sword", price: int = 20, *args, **kwargs):
super().__init__(name=name, price=price, *args, **kwargs)
self.name = name
class BodySnatchPotion(Item):
"""
The body-snatch potion allows to exchange all characteristics with a random
other entity.
"""
def __init__(self, name: str = "body_snatch_potion", *args, **kwargs):
super().__init__(name=name, *args, **kwargs)
def __init__(self, name: str = "body_snatch_potion", price: int = 14,
*args, **kwargs):
super().__init__(name=name, price=price, *args, **kwargs)
def use(self) -> None:
"""

View File

@ -6,23 +6,22 @@ from queue import PriorityQueue
from random import randint
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]]
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,
*args, **kwargs) \
hazel: int = 42, *args, **kwargs) \
-> None:
super().__init__(name=name, maxhealth=maxhealth, strength=strength,
intelligence=intelligence, charisma=charisma,
@ -30,13 +29,9 @@ class Player(FightingEntity):
level=level, *args, **kwargs)
self.current_xp = current_xp
self.max_xp = max_xp
self.inventory = inventory if inventory else list()
for i in range(len(self.inventory)):
if isinstance(self.inventory[i], dict):
entity_classes = self.get_all_entity_classes_in_a_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
def move(self, y: int, x: int) -> None:
"""
@ -149,5 +144,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]
return d