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
|
import random
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import TYPE_CHECKING, MutableSet, NoReturn
|
from typing import TYPE_CHECKING, MutableSet, NoReturn, Optional
|
||||||
|
|
||||||
import tcod
|
import tcod
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ class Engine:
|
||||||
self.message_log = MessageLog()
|
self.message_log = MessageLog()
|
||||||
|
|
||||||
self.event_handler: 'EventHandler' = MainGameEventHandler(self)
|
self.event_handler: 'EventHandler' = MainGameEventHandler(self)
|
||||||
|
self.current_mouse_point: Optional[Point] = None
|
||||||
|
|
||||||
self.hero = Hero(position=self.map.generator.rooms[0].center)
|
self.hero = Hero(position=self.map.generator.rooms[0].center)
|
||||||
self.entities: MutableSet[Entity] = {self.hero}
|
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))
|
messages_rect = Rect(Point(x=27, y=45), Size(width=40, height=5))
|
||||||
self.message_log.render_to_console(console, messages_rect)
|
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):
|
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)]:
|
if not self.map.visible[tuple(ent.position)]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
ent.print_to_console(console)
|
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:
|
def run_event_loop(self, context: tcod.context.Context, console: tcod.Console) -> NoReturn:
|
||||||
'''Run the event loop forever. This method never returns.'''
|
'''Run the event loop forever. This method never returns.'''
|
||||||
while True:
|
while True:
|
||||||
|
@ -118,7 +127,7 @@ class Engine:
|
||||||
context.present(console)
|
context.present(console)
|
||||||
|
|
||||||
self.begin_turn()
|
self.begin_turn()
|
||||||
self.event_handler.wait_for_events()
|
self.event_handler.handle_events(context)
|
||||||
self.finish_turn()
|
self.finish_turn()
|
||||||
|
|
||||||
def process_input_action(self, action: Action) -> ActionResult:
|
def process_input_action(self, action: Action) -> ActionResult:
|
||||||
|
@ -240,12 +249,10 @@ class Engine:
|
||||||
|
|
||||||
def kill_actor(self, actor: Actor) -> None:
|
def kill_actor(self, actor: Actor) -> None:
|
||||||
'''Kill an entity. Remove it from the game.'''
|
'''Kill an entity. Remove it from the game.'''
|
||||||
|
|
||||||
if actor == self.hero:
|
if actor == self.hero:
|
||||||
# When the hero dies, the game is over.
|
# When the hero dies, the game is over.
|
||||||
# TODO: Transition to game over state
|
log.ACTIONS.info('Time to die.')
|
||||||
log.ACTIONS.debug('Time to die.')
|
|
||||||
self.event_handler = GameOverEventHandler(self)
|
self.event_handler = GameOverEventHandler(self)
|
||||||
else:
|
else:
|
||||||
log.ACTIONS.debug('%s dies', actor)
|
log.ACTIONS.info('%s dies', actor)
|
||||||
self.entities.remove(actor)
|
self.entities.remove(actor)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import tcod
|
||||||
|
|
||||||
from . import log
|
from . import log
|
||||||
from .actions import Action, ExitAction, RegenerateRoomsAction, BumpAction, WaitAction
|
from .actions import Action, ExitAction, RegenerateRoomsAction, BumpAction, WaitAction
|
||||||
from .geometry import Direction
|
from .geometry import Direction, Point
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .engine import Engine
|
from .engine import Engine
|
||||||
|
@ -20,9 +20,10 @@ class EventHandler(tcod.event.EventDispatch[Action]):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.engine = engine
|
self.engine = engine
|
||||||
|
|
||||||
def wait_for_events(self):
|
def handle_events(self, context: tcod.context.Context):
|
||||||
'''Wait for events and handle them.'''
|
'''Wait for events and handle them.'''
|
||||||
for event in tcod.event.wait():
|
for event in tcod.event.wait():
|
||||||
|
context.convert_event(event)
|
||||||
self.handle_event(event)
|
self.handle_event(event)
|
||||||
|
|
||||||
def handle_event(self, event: tcod.event.Event) -> None:
|
def handle_event(self, event: tcod.event.Event) -> None:
|
||||||
|
@ -87,6 +88,12 @@ class MainGameEventHandler(EventHandler):
|
||||||
|
|
||||||
return action
|
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):
|
class GameOverEventHandler(EventHandler):
|
||||||
'''When the game is over (the hero dies, the player quits, etc), this event handler takes over.'''
|
'''When the game is over (the hero dies, the player quits, etc), this event handler takes over.'''
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ class Map:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def rooms(self) -> List['Room']:
|
def rooms(self) -> List['Room']:
|
||||||
|
'''The list of rooms in the map'''
|
||||||
return self.generator.rooms
|
return self.generator.rooms
|
||||||
|
|
||||||
def random_walkable_position(self) -> Point:
|
def random_walkable_position(self) -> Point:
|
||||||
|
@ -35,9 +36,11 @@ class Map:
|
||||||
return random_position_in_room
|
return random_position_in_room
|
||||||
|
|
||||||
def tile_is_in_bounds(self, point: Point) -> bool:
|
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
|
return 0 <= point.x < self.size.width and 0 <= point.y < self.size.height
|
||||||
|
|
||||||
def tile_is_walkable(self, point: Point) -> bool:
|
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']
|
return self.tiles[point.x, point.y]['walkable']
|
||||||
|
|
||||||
def print_to_console(self, console: tcod.Console) -> None:
|
def print_to_console(self, console: tcod.Console) -> None:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue