Added a Bow, related to #64
This commit is contained in:
		@@ -21,6 +21,7 @@ class TexturePack:
 | 
			
		||||
 | 
			
		||||
    BODY_SNATCH_POTION: str
 | 
			
		||||
    BOMB: str
 | 
			
		||||
    BOW: str
 | 
			
		||||
    CHESTPLATE: str
 | 
			
		||||
    EAGLE: str
 | 
			
		||||
    EMPTY: str
 | 
			
		||||
@@ -34,6 +35,7 @@ class TexturePack:
 | 
			
		||||
    RABBIT: str
 | 
			
		||||
    RING_OF_CRITICAL_DAMAGE: str
 | 
			
		||||
    RING_OF_MORE_EXPERIENCE: str
 | 
			
		||||
    RULER: str
 | 
			
		||||
    SCROLL_OF_DAMAGE: str
 | 
			
		||||
    SCROLL_OF_WEAKENING: str
 | 
			
		||||
    SHIELD: str
 | 
			
		||||
@@ -75,6 +77,7 @@ TexturePack.ASCII_PACK = TexturePack(
 | 
			
		||||
 | 
			
		||||
    BODY_SNATCH_POTION='S',
 | 
			
		||||
    BOMB='ç',
 | 
			
		||||
    BOW=')',
 | 
			
		||||
    CHESTPLATE='(',
 | 
			
		||||
    EAGLE='µ',
 | 
			
		||||
    EMPTY=' ',
 | 
			
		||||
@@ -90,6 +93,7 @@ TexturePack.ASCII_PACK = TexturePack(
 | 
			
		||||
    RABBIT='Y',
 | 
			
		||||
    RING_OF_CRITICAL_DAMAGE='o',
 | 
			
		||||
    RING_OF_MORE_EXPERIENCE='o',
 | 
			
		||||
    RULER='\\',
 | 
			
		||||
    SHIELD='D',
 | 
			
		||||
    SUNFLOWER='I',
 | 
			
		||||
    SWORD='\u2020',
 | 
			
		||||
@@ -112,6 +116,7 @@ TexturePack.SQUIRREL_PACK = TexturePack(
 | 
			
		||||
 | 
			
		||||
    BODY_SNATCH_POTION='🔀',
 | 
			
		||||
    BOMB='💣',
 | 
			
		||||
    BOW='🏹',
 | 
			
		||||
    CHESTPLATE='🦺',
 | 
			
		||||
    EAGLE='🦅',
 | 
			
		||||
    EMPTY='  ',
 | 
			
		||||
@@ -128,6 +133,7 @@ TexturePack.SQUIRREL_PACK = TexturePack(
 | 
			
		||||
    RABBIT='🐇',
 | 
			
		||||
    RING_OF_CRITICAL_DAMAGE='💍',
 | 
			
		||||
    RING_OF_MORE_EXPERIENCE='💍',
 | 
			
		||||
    RULER='📏',
 | 
			
		||||
    SHIELD='🛡️ ',
 | 
			
		||||
    SUNFLOWER='🌻',
 | 
			
		||||
    SWORD='🗡️ ',
 | 
			
		||||
 
 | 
			
		||||
@@ -40,6 +40,11 @@ class Item(Entity):
 | 
			
		||||
        Indicates what should be done when the item is used.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
    def throw(self, direction: int) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Indicates what should be done when the item is thrown.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
    def equip(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Indicates what should be done when the item is equipped.
 | 
			
		||||
@@ -81,7 +86,7 @@ class Item(Entity):
 | 
			
		||||
        """
 | 
			
		||||
        return [BodySnatchPotion, Bomb, Heart, Shield, Sword,\
 | 
			
		||||
                Chestplate, Helmet, RingCritical, RingXP, \
 | 
			
		||||
                ScrollofDamage, ScrollofWeakening]
 | 
			
		||||
                ScrollofDamage, ScrollofWeakening, Ruler, Bow]
 | 
			
		||||
 | 
			
		||||
    def be_sold(self, buyer: InventoryHolder, seller: InventoryHolder) -> bool:
 | 
			
		||||
        """
 | 
			
		||||
@@ -251,6 +256,13 @@ class Sword(Weapon):
 | 
			
		||||
                 *args, **kwargs):
 | 
			
		||||
        super().__init__(name=name, price=price, *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
class Ruler(Weapon):
 | 
			
		||||
    """
 | 
			
		||||
    A basic weapon
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, name: str = "ruler", price: int = 2,
 | 
			
		||||
                 damage: int = 1, *args, **kwargs):
 | 
			
		||||
        super().__init__(name=name, price=price, damage=damage, *args, **kwargs) 
 | 
			
		||||
 | 
			
		||||
class Armor(Item):
 | 
			
		||||
    """
 | 
			
		||||
@@ -428,7 +440,6 @@ class ScrollofDamage(Item):
 | 
			
		||||
    """
 | 
			
		||||
    A scroll that, when used, deals damage to all entities in a certain radius.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, name: str = "scroll_of_damage", price: int = 18,
 | 
			
		||||
                 *args, **kwargs):
 | 
			
		||||
        super().__init__(name=name, price=price, *args, **kwargs)
 | 
			
		||||
@@ -449,7 +460,6 @@ class ScrollofWeakening(Item):
 | 
			
		||||
    """
 | 
			
		||||
    A scroll that, when used, reduces the damage of the ennemies for 3 turn.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, name: str = "scroll_of_weakening", price: int = 13,
 | 
			
		||||
                 *args, **kwargs):
 | 
			
		||||
        super().__init__(name=name, price=price, *args, **kwargs)
 | 
			
		||||
@@ -459,10 +469,52 @@ class ScrollofWeakening(Item):
 | 
			
		||||
        Find all entities and reduce their damage.
 | 
			
		||||
        """
 | 
			
		||||
        for entity in self.held_by.map.entities:
 | 
			
		||||
            if entity.is_fighting_entity(): #and not entity == self.held_by:
 | 
			
		||||
            if entity.is_fighting_entity() and not entity == self.held_by:
 | 
			
		||||
                entity.strength = entity.strength - max(1, self.held_by.intelligence//2)
 | 
			
		||||
                entity.effects.append(["strength", \
 | 
			
		||||
                                       -max(1, self.held_by.intelligence//2), 3])
 | 
			
		||||
        self.held_by.map.logs.add_message(\
 | 
			
		||||
                _(f"The ennemies have -{max(1, self.held_by.intelligence//2)} strength for 3 turns"))    
 | 
			
		||||
        self.held_by.inventory.remove(self)
 | 
			
		||||
 | 
			
		||||
class Bow(Item):
 | 
			
		||||
    """
 | 
			
		||||
    A type of throwable weapon that deals damage based on the player's dexterity.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, name: str = "bow", price: int = 22, damage = 4,
 | 
			
		||||
                 rang = 3, *args, **kwargs):
 | 
			
		||||
        super().__init__(name=name, price=price, *args, **kwargs)
 | 
			
		||||
        self.damage = damage
 | 
			
		||||
        self.range = rang
 | 
			
		||||
 | 
			
		||||
    def throw(self, direction: int) -> str:
 | 
			
		||||
        to_kill = None
 | 
			
		||||
        for entity in self.held_by.map.entities:
 | 
			
		||||
            if entity.is_fighting_entity():
 | 
			
		||||
                if direction == 0 and self.held_by.x == entity.x \
 | 
			
		||||
                   and self.held_by.y-entity.y>0 and \
 | 
			
		||||
                   self.held_by.y-entity.y<=self.range:
 | 
			
		||||
                    to_kill = entity
 | 
			
		||||
                elif direction == 2 and self.held_by.x == entity.x \
 | 
			
		||||
                   and entity.y-self.held_by.y>0 and \
 | 
			
		||||
                   entity.y-self.held_by.y<=self.range:
 | 
			
		||||
                    to_kill = entity
 | 
			
		||||
                elif direction == 1 and self.held_by.y == entity.y \
 | 
			
		||||
                   and entity.x-self.held_by.x>0 and \
 | 
			
		||||
                   entity.x-self.held_by.x<=self.range:
 | 
			
		||||
                    to_kill = entity
 | 
			
		||||
                elif direction == 3 and self.held_by.y == entity.y \
 | 
			
		||||
                   and self.held_by.x-entity.x>0 and \
 | 
			
		||||
                   self.held_by.x-entity.x<=self.range:
 | 
			
		||||
                    to_kill = entity
 | 
			
		||||
        if to_kill:
 | 
			
		||||
            self.held_by.map.logs.add_message(_("{name} is shot by an arrow.")\
 | 
			
		||||
                                              .format(name=to_kill.translated_name.capitalize())+ " " \
 | 
			
		||||
                                              + to_kill.take_damage(self.held_by, self.damage + self.held_by.dexterity))
 | 
			
		||||
 | 
			
		||||
    def equip(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Equip the bow.
 | 
			
		||||
        """
 | 
			
		||||
        self.held_by.remove_from_inventory(self)
 | 
			
		||||
        self.held_by.equipped_main = self
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
from random import randint
 | 
			
		||||
from typing import Dict, Optional, Tuple
 | 
			
		||||
 | 
			
		||||
from .items import Item
 | 
			
		||||
from .items import Item, Bow
 | 
			
		||||
from ..interfaces import FightingEntity, InventoryHolder
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -38,6 +38,9 @@ class Player(InventoryHolder, FightingEntity):
 | 
			
		||||
        self.max_xp = max_xp
 | 
			
		||||
        self.xp_buff = xp_buff
 | 
			
		||||
        self.inventory = self.translate_inventory(inventory or [])
 | 
			
		||||
        b = Bow()
 | 
			
		||||
        b.held_by=self
 | 
			
		||||
        self.inventory.append(b)
 | 
			
		||||
        self.paths = dict()
 | 
			
		||||
        self.hazel = hazel
 | 
			
		||||
        self.equipped_main = self.dict_to_item(equipped_main) \
 | 
			
		||||
 
 | 
			
		||||
@@ -48,6 +48,7 @@ class KeyValues(Enum):
 | 
			
		||||
    CHAT = auto()
 | 
			
		||||
    WAIT = auto()
 | 
			
		||||
    LADDER = auto()
 | 
			
		||||
    LAUNCH = auto()
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def translate_key(key: str, settings: Settings) -> Optional["KeyValues"]:
 | 
			
		||||
@@ -84,4 +85,6 @@ class KeyValues(Enum):
 | 
			
		||||
            return KeyValues.WAIT
 | 
			
		||||
        elif key == settings.KEY_LADDER:
 | 
			
		||||
            return KeyValues.LADDER
 | 
			
		||||
        elif key == settings.KEY_LAUNCH:
 | 
			
		||||
            return KeyValues.LAUNCH
 | 
			
		||||
        return None
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,7 @@ class Game:
 | 
			
		||||
        """
 | 
			
		||||
        self.state = GameMode.MAINMENU
 | 
			
		||||
        self.waiting_for_friendly_key = False
 | 
			
		||||
        self.waiting_for_launch_key = False
 | 
			
		||||
        self.is_in_store_menu = True
 | 
			
		||||
        self.settings = Settings()
 | 
			
		||||
        self.settings.load_settings()
 | 
			
		||||
@@ -117,6 +118,9 @@ class Game:
 | 
			
		||||
            if self.waiting_for_friendly_key:
 | 
			
		||||
                # The player requested to talk with a friendly entity
 | 
			
		||||
                self.handle_friendly_entity_chat(key)
 | 
			
		||||
            elif self.waiting_for_launch_key:
 | 
			
		||||
                # The player requested to launch
 | 
			
		||||
                self.handle_launch(key)
 | 
			
		||||
            else:
 | 
			
		||||
                self.handle_key_pressed_play(key)
 | 
			
		||||
        elif self.state == GameMode.INVENTORY:
 | 
			
		||||
@@ -155,6 +159,9 @@ class Game:
 | 
			
		||||
                self.player.equipped_main.use()
 | 
			
		||||
            if self.player.equipped_secondary:
 | 
			
		||||
                self.player.equipped_secondary.use()
 | 
			
		||||
        elif key == KeyValues.LAUNCH:
 | 
			
		||||
            # Wait for the direction to launch in
 | 
			
		||||
            self.waiting_for_launch_key = True
 | 
			
		||||
        elif key == KeyValues.SPACE:
 | 
			
		||||
            self.state = GameMode.MAINMENU
 | 
			
		||||
        elif key == KeyValues.CHAT:
 | 
			
		||||
@@ -247,6 +254,31 @@ class Game:
 | 
			
		||||
                        self.store_menu.update_merchant(entity)
 | 
			
		||||
                        self.display_actions(DisplayActions.UPDATE)
 | 
			
		||||
 | 
			
		||||
    def handle_launch(self, key: KeyValues) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        If the player tries to throw something in a direction, the game looks
 | 
			
		||||
        for entities in that direction and within the range of the player's
 | 
			
		||||
        weapon and adds damage
 | 
			
		||||
        """
 | 
			
		||||
        if not self.waiting_for_launch_key:
 | 
			
		||||
            return
 | 
			
		||||
        self.waiting_for_launch_key = False
 | 
			
		||||
 | 
			
		||||
        if key == KeyValues.UP:
 | 
			
		||||
            direction = 0
 | 
			
		||||
        elif key == KeyValues.DOWN:
 | 
			
		||||
            direction = 2
 | 
			
		||||
        elif key == KeyValues.LEFT:
 | 
			
		||||
            direction = 3
 | 
			
		||||
        elif key == KeyValues.RIGHT:
 | 
			
		||||
            direction = 1
 | 
			
		||||
        else:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        if self.player.equipped_main:
 | 
			
		||||
            self.player.equipped_main.throw(direction)
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    def handle_key_pressed_inventory(self, key: KeyValues) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        In the inventory menu, we can interact with items or close the menu.
 | 
			
		||||
 
 | 
			
		||||
@@ -630,7 +630,7 @@ class Entity:
 | 
			
		||||
            Trumpet
 | 
			
		||||
        from squirrelbattle.entities.items import BodySnatchPotion, Bomb, \
 | 
			
		||||
            Heart, Sword, Shield, Chestplate, Helmet, RingCritical, RingXP, \
 | 
			
		||||
            ScrollofDamage, ScrollofWeakening
 | 
			
		||||
            ScrollofDamage, ScrollofWeakening, Ruler, Bow
 | 
			
		||||
        return {
 | 
			
		||||
            "Tiger": Tiger,
 | 
			
		||||
            "Bomb": Bomb,
 | 
			
		||||
@@ -650,8 +650,10 @@ class Entity:
 | 
			
		||||
            "Helmet": Helmet,
 | 
			
		||||
            "RingCritical": RingCritical,
 | 
			
		||||
            "RingXP": RingXP,
 | 
			
		||||
            "Ruler": Ruler,
 | 
			
		||||
            "ScrollofDamage": ScrollofDamage,
 | 
			
		||||
            "ScrollofWeakening": ScrollofWeakening,
 | 
			
		||||
            "Bow": Bow,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def save_state(self) -> dict:
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,7 @@ class Settings:
 | 
			
		||||
        self.KEY_CHAT = ['t', 'Key used to talk to a friendly entity']
 | 
			
		||||
        self.KEY_WAIT = ['w', 'Key used to wait']
 | 
			
		||||
        self.KEY_LADDER = ['<', 'Key used to use ladders']
 | 
			
		||||
        self.KEY_LAUNCH = ['l', 'Key used to use a bow']
 | 
			
		||||
        self.TEXTURE_PACK = ['ascii', 'Texture pack']
 | 
			
		||||
        self.LOCALE = [locale.getlocale()[0][:2], 'Language']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user