Added a Bow, related to #64

This commit is contained in:
eichhornchen 2021-01-08 18:06:26 +01:00
parent bde33e9232
commit f6210a6356
7 changed files with 105 additions and 6 deletions

View File

@ -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='🗡️ ',

View File

@ -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

View File

@ -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) \

View File

@ -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

View File

@ -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.

View File

@ -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:

View File

@ -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']