Show Entity under mouse cursor in a line above the hit points

This commit is contained in:
Eryn Wells 2022-05-15 16:50:24 -07:00
parent 4e585a2650
commit d4e4684694
3 changed files with 26 additions and 9 deletions

View file

@ -4,7 +4,7 @@
import random
from dataclasses import dataclass
from typing import TYPE_CHECKING, MutableSet, NoReturn
from typing import TYPE_CHECKING, MutableSet, NoReturn, Optional
import tcod
@ -58,6 +58,7 @@ class Engine:
self.message_log = MessageLog()
self.event_handler: 'EventHandler' = MainGameEventHandler(self)
self.current_mouse_point: Optional[Point] = None
self.hero = Hero(position=self.map.generator.rooms[0].center)
self.entities: MutableSet[Entity] = {self.hero}
@ -104,12 +105,20 @@ class Engine:
messages_rect = Rect(Point(x=27, y=45), Size(width=40, height=5))
self.message_log.render_to_console(console, messages_rect)
entities_at_mouse_position = []
for ent in sorted(self.entities, key=lambda e: e.render_order.value):
# Only print entities that are in the field of view
# Only process entities that are in the field of view
if not self.map.visible[tuple(ent.position)]:
continue
ent.print_to_console(console)
if ent.position == self.current_mouse_point:
entities_at_mouse_position.append(ent)
if len(entities_at_mouse_position) > 0:
console.print(x=1, y=43, string=', '.join(e.name for e in entities_at_mouse_position))
def run_event_loop(self, context: tcod.context.Context, console: tcod.Console) -> NoReturn:
'''Run the event loop forever. This method never returns.'''
while True:
@ -118,7 +127,7 @@ class Engine:
context.present(console)
self.begin_turn()
self.event_handler.wait_for_events()
self.event_handler.handle_events(context)
self.finish_turn()
def process_input_action(self, action: Action) -> ActionResult:
@ -240,12 +249,10 @@ class Engine:
def kill_actor(self, actor: Actor) -> None:
'''Kill an entity. Remove it from the game.'''
if actor == self.hero:
# When the hero dies, the game is over.
# TODO: Transition to game over state
log.ACTIONS.debug('Time to die.')
log.ACTIONS.info('Time to die.')
self.event_handler = GameOverEventHandler(self)
else:
log.ACTIONS.debug('%s dies', actor)
log.ACTIONS.info('%s dies', actor)
self.entities.remove(actor)

View file

@ -8,7 +8,7 @@ import tcod
from . import log
from .actions import Action, ExitAction, RegenerateRoomsAction, BumpAction, WaitAction
from .geometry import Direction
from .geometry import Direction, Point
if TYPE_CHECKING:
from .engine import Engine
@ -20,9 +20,10 @@ class EventHandler(tcod.event.EventDispatch[Action]):
super().__init__()
self.engine = engine
def wait_for_events(self):
def handle_events(self, context: tcod.context.Context):
'''Wait for events and handle them.'''
for event in tcod.event.wait():
context.convert_event(event)
self.handle_event(event)
def handle_event(self, event: tcod.event.Event) -> None:
@ -87,6 +88,12 @@ class MainGameEventHandler(EventHandler):
return action
def ev_mousemotion(self, event: tcod.event.MouseMotion) -> Optional[Action]:
mouse_point = Point(event.tile.x, event.tile.y)
if not self.engine.map.tile_is_in_bounds(mouse_point):
mouse_point = None
self.engine.current_mouse_point = mouse_point
class GameOverEventHandler(EventHandler):
'''When the game is over (the hero dies, the player quits, etc), this event handler takes over.'''

View file

@ -25,6 +25,7 @@ class Map:
@property
def rooms(self) -> List['Room']:
'''The list of rooms in the map'''
return self.generator.rooms
def random_walkable_position(self) -> Point:
@ -35,9 +36,11 @@ class Map:
return random_position_in_room
def tile_is_in_bounds(self, point: Point) -> bool:
'''Return True if the given point is inside the bounds of the map'''
return 0 <= point.x < self.size.width and 0 <= point.y < self.size.height
def tile_is_walkable(self, point: Point) -> bool:
'''Return True if the tile at the given point is walkable'''
return self.tiles[point.x, point.y]['walkable']
def print_to_console(self, console: tcod.Console) -> None: