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