From 090272854d3cceeb11fe7d846055bbfdc96fc088 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sun, 15 May 2022 13:13:12 -0700 Subject: [PATCH] Add a turn count that increments after successfully handling actions for that turn --- erynrl/engine.py | 54 +++++++++++++++++++++++++++++++++++++++++++----- erynrl/events.py | 9 +------- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/erynrl/engine.py b/erynrl/engine.py index db237f1..638f635 100644 --- a/erynrl/engine.py +++ b/erynrl/engine.py @@ -48,12 +48,16 @@ class Engine: def __init__(self, configuration: Configuration): self.configuration = configuration + self.current_turn = 1 + self.did_begin_turn = False + self.did_successfully_process_actions_for_turn = False + self.rng = tcod.random.Random() self.map = Map(configuration.map_size) - self.hero = Hero(position=self.map.generator.rooms[0].center) self.event_handler: 'EventHandler' = MainGameEventHandler(self) + self.hero = Hero(position=self.map.generator.rooms[0].center) self.entities: MutableSet[Entity] = {self.hero} for room in self.map.rooms: should_spawn_monster_chance = random.random() @@ -78,18 +82,21 @@ class Engine: self.update_field_of_view() + # Interface elements self.hit_points_bar = Bar(position=Point(4, 47), width=20) def print_to_console(self, console): '''Print the whole game to the given console.''' self.map.print_to_console(console) - console.print(x=1, y=47, string=f'HP:') + console.print(x=1, y=47, string='HP:') hp, max_hp = self.hero.fighter.hit_points, self.hero.fighter.maximum_hit_points self.hit_points_bar.percent_filled = hp / max_hp self.hit_points_bar.render_to_console(console) console.print(x=6, y=47, string=f'{hp}/{max_hp}', fg=color.WHITE) + console.print(x=1, y=48, string=f'Turn: {self.current_turn}') + for ent in sorted(self.entities, key=lambda e: e.render_order.value): # Only print entities that are in the field of view if not self.map.visible[tuple(ent.position)]: @@ -103,16 +110,29 @@ class Engine: self.print_to_console(console) context.present(console) + self.begin_turn() self.event_handler.wait_for_events() + self.finish_turn() + + def process_input_action(self, action: Action) -> ActionResult: + '''Process an Action from player input''' - def process_hero_action(self, action: Action) -> ActionResult: - '''Process an Action for the hero.''' log.ACTIONS_TREE.info('Processing Hero Actions') log.ACTIONS_TREE.info('|-> %s', action.actor) - return self._perform_action_until_done(action) + result = self._perform_action_until_done(action) + + # Player's action failed, don't proceed with turn. + if not result.success and result.done: + self.did_successfully_process_actions_for_turn = False + return + + self.did_successfully_process_actions_for_turn = True + self.process_entity_actions() + self.update_field_of_view() def process_entity_actions(self): + '''Run AI for entities that have them, and process actions from those AIs''' hero_position = self.hero.position # Copy the list so we only act on the entities that exist at the start of this turn. Sort it by Euclidean @@ -187,6 +207,30 @@ class Engine: # Visible tiles should be added to the explored list self.map.explored |= self.map.visible + def begin_turn(self) -> None: + '''Begin the current turn''' + if self.did_begin_turn: + return + + if log.ROOT.isEnabledFor(log.INFO): + dashes = '-' * 20 + log.ROOT.info('%s Turn %d %s', dashes, self.current_turn, dashes) + + self.did_begin_turn = True + + def finish_turn(self) -> None: + '''Finish the current turn and prepare for the next turn''' + if not self.did_successfully_process_actions_for_turn: + return + + log.ROOT.info('Completed turn %d successfully', self.current_turn) + self._prepare_for_next_turn() + + def _prepare_for_next_turn(self) -> None: + self.current_turn += 1 + self.did_begin_turn = False + self.did_successfully_process_actions_for_turn = False + def kill_actor(self, actor: Actor) -> None: '''Kill an entity. Remove it from the game.''' diff --git a/erynrl/events.py b/erynrl/events.py index 9c82c9c..25ccd4d 100644 --- a/erynrl/events.py +++ b/erynrl/events.py @@ -42,14 +42,7 @@ class EventHandler(tcod.event.EventDispatch[Action]): log.EVENTS.debug('Unhandled event: %s', event) return - result = self.engine.process_hero_action(action) - - # Player's action failed, don't proceed with turn. - if not result.success and result.done: - return - - self.engine.process_entity_actions() - self.engine.update_field_of_view() + self.engine.process_input_action(action) def ev_quit(self, event: tcod.event.Quit) -> Optional[Action]: return ExitAction(self.engine.hero)