Refactor movement to allow diagonal movement, add basic attack logs
This commit is contained in:
parent
be433a9449
commit
018dbe35b8
24
actions.py
24
actions.py
@ -4,11 +4,11 @@ from typing import Optional, Tuple, TYPE_CHECKING, overload
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from engine import Engine
|
from engine import Engine
|
||||||
from entity import Entity
|
from entity import Actor, Entity
|
||||||
|
|
||||||
|
|
||||||
class Action:
|
class Action:
|
||||||
def __init__(self, entity: Entity) -> None:
|
def __init__(self, entity: Actor) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.entity = entity
|
self.entity = entity
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ class WaitAction(Action):
|
|||||||
|
|
||||||
|
|
||||||
class ActionWithDirection(Action):
|
class ActionWithDirection(Action):
|
||||||
def __init__(self, entity, dx: int, dy: int):
|
def __init__(self, entity: Actor, dx: int, dy: int):
|
||||||
super().__init__(entity)
|
super().__init__(entity)
|
||||||
|
|
||||||
self.dx = dx
|
self.dx = dx
|
||||||
@ -56,14 +56,26 @@ class ActionWithDirection(Action):
|
|||||||
"""Return the blocking entity at this action's destination."""
|
"""Return the blocking entity at this action's destination."""
|
||||||
return self.engine.game_map.get_blocking_entity_at_location(*self.dest_xy)
|
return self.engine.game_map.get_blocking_entity_at_location(*self.dest_xy)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_actor(self) -> Optional[Actor]:
|
||||||
|
"""Return the actor at this action's destination."""
|
||||||
|
return self.engine.game_map.get_actor_at_location(*self.dest_xy)
|
||||||
|
|
||||||
|
|
||||||
class MeleeAction(ActionWithDirection):
|
class MeleeAction(ActionWithDirection):
|
||||||
def perform(self) -> None:
|
def perform(self) -> None:
|
||||||
target = self.blocking_entity
|
target = self.target_actor
|
||||||
if not target:
|
if not target:
|
||||||
return # No entity to attack.
|
return # No entity to attack.
|
||||||
|
|
||||||
print(f"You kick the {target.name}, much to its annoyance!")
|
damage = self.entity.fighter.power - target.fighter.defense
|
||||||
|
|
||||||
|
attack_desc = f"{self.entity.name.capitalize()} attacks {target.name}"
|
||||||
|
if damage > 0:
|
||||||
|
print(f"{attack_desc} for {damage} hit points.")
|
||||||
|
target.fighter.hp -= damage
|
||||||
|
else:
|
||||||
|
print(f"{attack_desc} but does no damage.")
|
||||||
|
|
||||||
|
|
||||||
class MovementAction(ActionWithDirection):
|
class MovementAction(ActionWithDirection):
|
||||||
@ -82,7 +94,7 @@ class MovementAction(ActionWithDirection):
|
|||||||
|
|
||||||
class BumpAction(ActionWithDirection):
|
class BumpAction(ActionWithDirection):
|
||||||
def perform(self) -> None:
|
def perform(self) -> None:
|
||||||
if self.blocking_entity:
|
if self.target_actor:
|
||||||
return MeleeAction(self.entity, self.dx, self.dy).perform()
|
return MeleeAction(self.entity, self.dx, self.dy).perform()
|
||||||
else:
|
else:
|
||||||
return MovementAction(self.entity, self.dx, self.dy).perform()
|
return MovementAction(self.entity, self.dx, self.dy).perform()
|
||||||
|
@ -33,7 +33,7 @@ class BaseAI(Action, BaseComponent):
|
|||||||
cost[entity.x, entity.y] += 10
|
cost[entity.x, entity.y] += 10
|
||||||
|
|
||||||
# Create a graph from the cost array and pass that graph to a new pathfinder.
|
# Create a graph from the cost array and pass that graph to a new pathfinder.
|
||||||
graph = tcod.path.SimpleGraph(cost, cardinal=2, diagonal=3)
|
graph = tcod.path.SimpleGraph(cost=cost, cardinal=2, diagonal=3)
|
||||||
pathfinder = tcod.path.Pathfinder(graph)
|
pathfinder = tcod.path.Pathfinder(graph)
|
||||||
|
|
||||||
pathfinder.add_root((self.entity.x, self.entity.y)) # Start position
|
pathfinder.add_root((self.entity.x, self.entity.y)) # Start position
|
||||||
@ -69,7 +69,7 @@ class HostileEnemy(BaseAI):
|
|||||||
return MovementAction(
|
return MovementAction(
|
||||||
self.entity,
|
self.entity,
|
||||||
dest_x - self.entity.x,
|
dest_x - self.entity.x,
|
||||||
dest_y - self.entity.y
|
dest_y - self.entity.y,
|
||||||
).perform()
|
).perform()
|
||||||
|
|
||||||
return WaitAction(self.entity).perform()
|
return WaitAction(self.entity).perform()
|
@ -86,7 +86,7 @@ class Actor(Entity):
|
|||||||
blocks_movement=True
|
blocks_movement=True
|
||||||
)
|
)
|
||||||
|
|
||||||
self.ai = Optional[BaseAI] = ai_cls(self)
|
self.ai: Optional[BaseAI] = ai_cls(self)
|
||||||
|
|
||||||
self.fighter = fighter
|
self.fighter = fighter
|
||||||
self.fighter.entity = self
|
self.fighter.entity = self
|
||||||
|
@ -4,11 +4,49 @@ from typing import Optional, TYPE_CHECKING
|
|||||||
|
|
||||||
import tcod.event
|
import tcod.event
|
||||||
|
|
||||||
from actions import Action, EscapeAction, BumpAction
|
from actions import Action, BumpAction, EscapeAction, WaitAction
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from engine import Engine
|
from engine import Engine
|
||||||
|
|
||||||
|
MOVE_KEYS = {
|
||||||
|
# Arrow keys
|
||||||
|
tcod.event.K_UP: (0, -1),
|
||||||
|
tcod.event.K_DOWN: (0, 1),
|
||||||
|
tcod.event.K_LEFT: (-1, 0),
|
||||||
|
tcod.event.K_RIGHT: (1, 0),
|
||||||
|
tcod.event.K_HOME: (-1, -1),
|
||||||
|
tcod.event.K_END: (-1, 1),
|
||||||
|
tcod.event.K_PAGEUP: (1, -1),
|
||||||
|
tcod.event.K_PAGEDOWN: (1, 1),
|
||||||
|
|
||||||
|
# Numpad keys
|
||||||
|
tcod.event.K_KP_1: (-1, 1),
|
||||||
|
tcod.event.K_KP_2: (0, 1),
|
||||||
|
tcod.event.K_KP_3: (1, 1),
|
||||||
|
tcod.event.K_KP_4: (-1, 0),
|
||||||
|
tcod.event.K_KP_6: (1, 0),
|
||||||
|
tcod.event.K_KP_7: (-1, -1),
|
||||||
|
tcod.event.K_KP_8: (0, -1),
|
||||||
|
tcod.event.K_KP_9: (1, -1),
|
||||||
|
|
||||||
|
# Vi keys
|
||||||
|
tcod.event.K_h: (-1, 0),
|
||||||
|
tcod.event.K_j: (0, 1),
|
||||||
|
tcod.event.K_k: (0, -1),
|
||||||
|
tcod.event.K_l: (1, 0),
|
||||||
|
tcod.event.K_y: (-1, -1),
|
||||||
|
tcod.event.K_u: (1, -1),
|
||||||
|
tcod.event.K_b: (-1, 1),
|
||||||
|
tcod.event.K_n: (1, 1),
|
||||||
|
}
|
||||||
|
|
||||||
|
WAIT_KEYS = {
|
||||||
|
tcod.event.K_PERIOD,
|
||||||
|
tcod.event.K_KP_5,
|
||||||
|
tcod.event.K_CLEAR,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class EventHandler(tcod.event.EventDispatch[Action]):
|
class EventHandler(tcod.event.EventDispatch[Action]):
|
||||||
def __init__(self, engine: Engine):
|
def __init__(self, engine: Engine):
|
||||||
@ -33,14 +71,11 @@ class EventHandler(tcod.event.EventDispatch[Action]):
|
|||||||
|
|
||||||
player = self.engine.player
|
player = self.engine.player
|
||||||
|
|
||||||
if key == tcod.event.K_UP:
|
if key in MOVE_KEYS:
|
||||||
action = BumpAction(player, dx=0, dy=-1)
|
dx, dy = MOVE_KEYS[key]
|
||||||
elif key == tcod.event.K_DOWN:
|
action = BumpAction(player, dx, dy)
|
||||||
action = BumpAction(player, dx=0, dy=1)
|
elif key in WAIT_KEYS:
|
||||||
elif key == tcod.event.K_LEFT:
|
action = WaitAction(player)
|
||||||
action = BumpAction(player, dx=-1, dy=0)
|
|
||||||
elif key == tcod.event.K_RIGHT:
|
|
||||||
action = BumpAction(player, dx=1, dy=0)
|
|
||||||
|
|
||||||
elif key == tcod.event.K_ESCAPE:
|
elif key == tcod.event.K_ESCAPE:
|
||||||
action = EscapeAction(player)
|
action = EscapeAction(player)
|
||||||
|
Loading…
Reference in New Issue
Block a user