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:
|
||||
from engine import Engine
|
||||
from entity import Entity
|
||||
from entity import Actor, Entity
|
||||
|
||||
|
||||
class Action:
|
||||
def __init__(self, entity: Entity) -> None:
|
||||
def __init__(self, entity: Actor) -> None:
|
||||
super().__init__()
|
||||
self.entity = entity
|
||||
|
||||
@ -40,7 +40,7 @@ class WaitAction(Action):
|
||||
|
||||
|
||||
class ActionWithDirection(Action):
|
||||
def __init__(self, entity, dx: int, dy: int):
|
||||
def __init__(self, entity: Actor, dx: int, dy: int):
|
||||
super().__init__(entity)
|
||||
|
||||
self.dx = dx
|
||||
@ -56,14 +56,26 @@ class ActionWithDirection(Action):
|
||||
"""Return the blocking entity at this action's destination."""
|
||||
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):
|
||||
def perform(self) -> None:
|
||||
target = self.blocking_entity
|
||||
target = self.target_actor
|
||||
if not target:
|
||||
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):
|
||||
@ -82,7 +94,7 @@ class MovementAction(ActionWithDirection):
|
||||
|
||||
class BumpAction(ActionWithDirection):
|
||||
def perform(self) -> None:
|
||||
if self.blocking_entity:
|
||||
if self.target_actor:
|
||||
return MeleeAction(self.entity, self.dx, self.dy).perform()
|
||||
else:
|
||||
return MovementAction(self.entity, self.dx, self.dy).perform()
|
||||
|
@ -33,7 +33,7 @@ class BaseAI(Action, BaseComponent):
|
||||
cost[entity.x, entity.y] += 10
|
||||
|
||||
# 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.add_root((self.entity.x, self.entity.y)) # Start position
|
||||
@ -69,7 +69,7 @@ class HostileEnemy(BaseAI):
|
||||
return MovementAction(
|
||||
self.entity,
|
||||
dest_x - self.entity.x,
|
||||
dest_y - self.entity.y
|
||||
dest_y - self.entity.y,
|
||||
).perform()
|
||||
|
||||
return WaitAction(self.entity).perform()
|
@ -86,7 +86,7 @@ class Actor(Entity):
|
||||
blocks_movement=True
|
||||
)
|
||||
|
||||
self.ai = Optional[BaseAI] = ai_cls(self)
|
||||
self.ai: Optional[BaseAI] = ai_cls(self)
|
||||
|
||||
self.fighter = fighter
|
||||
self.fighter.entity = self
|
||||
|
@ -4,11 +4,49 @@ from typing import Optional, TYPE_CHECKING
|
||||
|
||||
import tcod.event
|
||||
|
||||
from actions import Action, EscapeAction, BumpAction
|
||||
from actions import Action, BumpAction, EscapeAction, WaitAction
|
||||
|
||||
if TYPE_CHECKING:
|
||||
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]):
|
||||
def __init__(self, engine: Engine):
|
||||
@ -33,14 +71,11 @@ class EventHandler(tcod.event.EventDispatch[Action]):
|
||||
|
||||
player = self.engine.player
|
||||
|
||||
if key == tcod.event.K_UP:
|
||||
action = BumpAction(player, dx=0, dy=-1)
|
||||
elif key == tcod.event.K_DOWN:
|
||||
action = BumpAction(player, dx=0, dy=1)
|
||||
elif key == tcod.event.K_LEFT:
|
||||
action = BumpAction(player, dx=-1, dy=0)
|
||||
elif key == tcod.event.K_RIGHT:
|
||||
action = BumpAction(player, dx=1, dy=0)
|
||||
if key in MOVE_KEYS:
|
||||
dx, dy = MOVE_KEYS[key]
|
||||
action = BumpAction(player, dx, dy)
|
||||
elif key in WAIT_KEYS:
|
||||
action = WaitAction(player)
|
||||
|
||||
elif key == tcod.event.K_ESCAPE:
|
||||
action = EscapeAction(player)
|
||||
|
Loading…
Reference in New Issue
Block a user