Show Entity under mouse cursor in a line above the hit points
This commit is contained in:
parent
4e585a2650
commit
d4e4684694
3 changed files with 26 additions and 9 deletions
|
@ -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)
|
||||
|
|
|
@ -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.'''
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue