Merging master into village, conflicts were solved
This commit is contained in:
@ -1,10 +1,12 @@
|
||||
# Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from random import choice, randint
|
||||
from typing import Optional
|
||||
|
||||
from .player import Player
|
||||
from ..interfaces import Entity, FightingEntity, Map
|
||||
from ..translations import gettext as _
|
||||
|
||||
|
||||
class Item(Entity):
|
||||
@ -20,16 +22,26 @@ class Item(Entity):
|
||||
self.held = held
|
||||
self.held_by = held_by
|
||||
|
||||
def drop(self, y: int, x: int) -> None:
|
||||
def drop(self) -> None:
|
||||
"""
|
||||
The item is dropped from the inventory onto the floor
|
||||
"""
|
||||
if self.held:
|
||||
self.held_by.inventory.remove(self)
|
||||
self.map.add_entity(self)
|
||||
self.move(self.held_by.y, self.held_by.x)
|
||||
self.held = False
|
||||
self.held_by = None
|
||||
self.map.add_entity(self)
|
||||
self.move(y, x)
|
||||
|
||||
def use(self) -> None:
|
||||
"""
|
||||
Indicates what should be done when the item is used.
|
||||
"""
|
||||
|
||||
def equip(self) -> None:
|
||||
"""
|
||||
Indicates what should be done when the item is equipped.
|
||||
"""
|
||||
|
||||
def hold(self, player: "Player") -> None:
|
||||
"""
|
||||
@ -55,8 +67,8 @@ class Heart(Item):
|
||||
"""
|
||||
healing: int
|
||||
|
||||
def __init__(self, healing: int = 5, *args, **kwargs):
|
||||
super().__init__(name="heart", *args, **kwargs)
|
||||
def __init__(self, name: str = "heart", healing: int = 5, *args, **kwargs):
|
||||
super().__init__(name=name, *args, **kwargs)
|
||||
self.healing = healing
|
||||
|
||||
def hold(self, player: "Player") -> None:
|
||||
@ -81,26 +93,47 @@ class Bomb(Item):
|
||||
"""
|
||||
damage: int = 5
|
||||
exploding: bool
|
||||
owner: Optional["Player"]
|
||||
tick: int
|
||||
|
||||
def __init__(self, damage: int = 5, exploding: bool = False,
|
||||
*args, **kwargs):
|
||||
super().__init__(name="bomb", *args, **kwargs)
|
||||
def __init__(self, name: str = "bomb", damage: int = 5,
|
||||
exploding: bool = False, *args, **kwargs):
|
||||
super().__init__(name=name, *args, **kwargs)
|
||||
self.damage = damage
|
||||
self.exploding = exploding
|
||||
self.tick = 4
|
||||
self.owner = None
|
||||
|
||||
def drop(self, x: int, y: int) -> None:
|
||||
super().drop(x, y)
|
||||
self.exploding = True
|
||||
def use(self) -> None:
|
||||
"""
|
||||
When the bomb is used, throw it and explodes it.
|
||||
"""
|
||||
if self.held:
|
||||
self.owner = self.held_by
|
||||
super().drop()
|
||||
self.exploding = True
|
||||
|
||||
def act(self, m: Map) -> None:
|
||||
"""
|
||||
Special exploding action of the bomb
|
||||
"""
|
||||
if self.exploding:
|
||||
for e in m.entities.copy():
|
||||
if abs(e.x - self.x) + abs(e.y - self.y) <= 1 and \
|
||||
isinstance(e, FightingEntity):
|
||||
e.take_damage(self, self.damage)
|
||||
if self.tick > 0:
|
||||
# The bomb will explode in <tick> moves
|
||||
self.tick -= 1
|
||||
else:
|
||||
# The bomb is exploding.
|
||||
# Each entity that is close to the bomb takes damages.
|
||||
# The player earn XP if the entity was killed.
|
||||
log_message = _("Bomb is exploding.")
|
||||
for e in m.entities.copy():
|
||||
if abs(e.x - self.x) + abs(e.y - self.y) <= 3 and \
|
||||
isinstance(e, FightingEntity):
|
||||
log_message += " " + e.take_damage(self, self.damage)
|
||||
if e.dead:
|
||||
self.owner.add_xp(randint(3, 7))
|
||||
m.logs.add_message(log_message)
|
||||
m.entities.remove(self)
|
||||
|
||||
def save_state(self) -> dict:
|
||||
"""
|
||||
@ -110,7 +143,7 @@ class Bomb(Item):
|
||||
d["exploding"] = self.exploding
|
||||
d["damage"] = self.damage
|
||||
return d
|
||||
|
||||
|
||||
class Weapon(Item):
|
||||
"""
|
||||
Non-throwable items that improve player damage
|
||||
@ -136,4 +169,35 @@ class Sword(Weapon) :
|
||||
def __init__(self, name: int, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.name = "sword"
|
||||
|
||||
|
||||
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 use(self) -> None:
|
||||
"""
|
||||
Find a valid random entity, then exchange characteristics.
|
||||
"""
|
||||
valid_entities = self.held_by.map.find_entities(FightingEntity)
|
||||
valid_entities.remove(self.held_by)
|
||||
entity = choice(valid_entities)
|
||||
entity_state = entity.save_state()
|
||||
player_state = self.held_by.save_state()
|
||||
self.held_by.__dict__.update(entity_state)
|
||||
entity.__dict__.update(player_state)
|
||||
self.held_by.map.currenty, self.held_by.map.currentx = self.held_by.y,\
|
||||
self.held_by.x
|
||||
|
||||
self.held_by.map.logs.add_message(
|
||||
_("{player} exchanged its body with {entity}.").format(
|
||||
player=self.held_by.translated_name.capitalize(),
|
||||
entity=entity.translated_name))
|
||||
|
||||
self.held_by.recalculate_paths()
|
||||
|
||||
self.held_by.inventory.remove(self)
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from random import choice
|
||||
from random import shuffle
|
||||
|
||||
from .player import Player
|
||||
from ..interfaces import FightingEntity, Map
|
||||
@ -49,9 +49,13 @@ class Monster(FightingEntity):
|
||||
if not moved and self.distance_squared(target) <= 1:
|
||||
self.map.logs.add_message(self.hit(target))
|
||||
else:
|
||||
for _ in range(100):
|
||||
if choice([self.move_up, self.move_down,
|
||||
self.move_left, self.move_right])():
|
||||
# Move in a random direction
|
||||
# If the direction is not available, try another one
|
||||
moves = [self.move_up, self.move_down,
|
||||
self.move_left, self.move_right]
|
||||
shuffle(moves)
|
||||
for move in moves:
|
||||
if move():
|
||||
break
|
||||
|
||||
|
||||
@ -59,9 +63,9 @@ class Tiger(Monster):
|
||||
"""
|
||||
A tiger monster
|
||||
"""
|
||||
def __init__(self, strength: int = 2, maxhealth: int = 20,
|
||||
*args, **kwargs) -> None:
|
||||
super().__init__(name="tiger", strength=strength,
|
||||
def __init__(self, name: str = "tiger", strength: int = 2,
|
||||
maxhealth: int = 20, *args, **kwargs) -> None:
|
||||
super().__init__(name=name, strength=strength,
|
||||
maxhealth=maxhealth, *args, **kwargs)
|
||||
|
||||
|
||||
@ -69,9 +73,9 @@ class Hedgehog(Monster):
|
||||
"""
|
||||
A really mean hedgehog monster
|
||||
"""
|
||||
def __init__(self, strength: int = 3, maxhealth: int = 10,
|
||||
*args, **kwargs) -> None:
|
||||
super().__init__(name="hedgehog", strength=strength,
|
||||
def __init__(self, name: str = "hedgehog", strength: int = 3,
|
||||
maxhealth: int = 10, *args, **kwargs) -> None:
|
||||
super().__init__(name=name, strength=strength,
|
||||
maxhealth=maxhealth, *args, **kwargs)
|
||||
|
||||
|
||||
@ -79,9 +83,9 @@ class Rabbit(Monster):
|
||||
"""
|
||||
A rabbit monster
|
||||
"""
|
||||
def __init__(self, strength: int = 1, maxhealth: int = 15,
|
||||
*args, **kwargs) -> None:
|
||||
super().__init__(name="rabbit", strength=strength,
|
||||
def __init__(self, name: str = "rabbit", strength: int = 1,
|
||||
maxhealth: int = 15, *args, **kwargs) -> None:
|
||||
super().__init__(name=name, strength=strength,
|
||||
maxhealth=maxhealth, *args, **kwargs)
|
||||
|
||||
|
||||
@ -89,7 +93,7 @@ class TeddyBear(Monster):
|
||||
"""
|
||||
A cute teddybear monster
|
||||
"""
|
||||
def __init__(self, strength: int = 0, maxhealth: int = 50,
|
||||
*args, **kwargs) -> None:
|
||||
super().__init__(name="teddy_bear", strength=strength,
|
||||
def __init__(self, name: str = "teddy_bear", strength: int = 0,
|
||||
maxhealth: int = 50, *args, **kwargs) -> None:
|
||||
super().__init__(name=name, strength=strength,
|
||||
maxhealth=maxhealth, *args, **kwargs)
|
||||
|
@ -17,17 +17,24 @@ class Player(FightingEntity):
|
||||
paths: Dict[Tuple[int, int], Tuple[int, int]]
|
||||
hazel: int #It is the currency of this game
|
||||
|
||||
def __init__(self, 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, hazel: int = 42, *args, **kwargs) -> None:
|
||||
super().__init__(name="player", maxhealth=maxhealth, strength=strength,
|
||||
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) \
|
||||
-> None:
|
||||
super().__init__(name=name, maxhealth=maxhealth, strength=strength,
|
||||
intelligence=intelligence, charisma=charisma,
|
||||
dexterity=dexterity, constitution=constitution,
|
||||
level=level, *args, **kwargs)
|
||||
self.current_xp = current_xp
|
||||
self.max_xp = max_xp
|
||||
self.inventory = list()
|
||||
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.paths = dict()
|
||||
self.hazel = hazel
|
||||
|
||||
@ -130,4 +137,5 @@ 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
|
||||
|
Reference in New Issue
Block a user