From 4e585a2650450812e99f20d6b31c9b17092db2f2 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sun, 15 May 2022 16:19:03 -0700 Subject: [PATCH] Implement passive healing --- erynrl/actions.py | 23 +++++++++++++++++++++++ erynrl/components.py | 20 +++++++++++++++++++- erynrl/events.py | 2 +- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/erynrl/actions.py b/erynrl/actions.py index d4d5fae..3e324c4 100644 --- a/erynrl/actions.py +++ b/erynrl/actions.py @@ -220,6 +220,12 @@ class WaitAction(Action): def perform(self, engine: 'Engine') -> ActionResult: log.ACTIONS.debug('%s is waiting a turn', self.actor) + + if self.actor == engine.hero: + should_recover_hit_points = self.actor.fighter.passively_recover_hit_points() + if should_recover_hit_points: + return ActionResult(self, alternate=HealAction(self.actor, 1)) + return self.success() class DieAction(Action): @@ -250,3 +256,20 @@ class DropItemAction(Action): def perform(self, engine: 'Engine') -> ActionResult: engine.entities.add(self.item) return self.success() + +class HealAction(Action): + '''Heal a target actor some number of hit points''' + + def __init__(self, actor: 'Actor', hit_points_to_recover: int): + super().__init__(actor) + self.hit_points_to_recover = hit_points_to_recover + + def perform(self, engine: 'Engine') -> ActionResult: + fighter = self.actor.fighter + if not fighter: + log.ACTIONS.error('Attempted to heal %s but it has no hit points', self.actor) + return self.failure() + + fighter.hit_points += self.hit_points_to_recover + + return self.success() \ No newline at end of file diff --git a/erynrl/components.py b/erynrl/components.py index 86b266f..ce5abde 100644 --- a/erynrl/components.py +++ b/erynrl/components.py @@ -1,8 +1,9 @@ # Eryn Wells +import random from typing import Optional -# pylint: disable=too-few-public-methods + class Component: '''A base, abstract Component that implement some aspect of an Entity's behavior.''' @@ -29,6 +30,9 @@ class Fighter(Component): self.attack_power = attack_power self.defense = defense + self.turns_since_last_heal = 0 + self.turn_for_next_passive_heal = random.randint(3, 7) + @property def hit_points(self) -> int: '''Number of hit points remaining. When a Fighter reaches 0 hit points, they die.''' @@ -42,3 +46,17 @@ class Fighter(Component): def is_dead(self) -> bool: '''True if the Fighter has died, i.e. reached 0 hit points''' return self.__hit_points == 0 + + def passively_recover_hit_points(self) -> bool: + '''Check the passive healing clock to see if this fighter should recover hit points. If not, increment the + counter.''' + if self.hit_points == self.maximum_hit_points: + self.turns_since_last_heal = 0 + + if self.turns_since_last_heal < self.turn_for_next_passive_heal: + self.turns_since_last_heal += 1 + return False + + self.turns_since_last_heal = 0 + self.turn_for_next_passive_heal = random.randint(3, 7) + return True diff --git a/erynrl/events.py b/erynrl/events.py index 25ccd4d..bb1ee7f 100644 --- a/erynrl/events.py +++ b/erynrl/events.py @@ -100,4 +100,4 @@ class GameOverEventHandler(EventHandler): case tcod.event.KeySym.ESCAPE: action = ExitAction(hero) - return action \ No newline at end of file + return action