1
0

Refactor movement to allow diagonal movement, add basic attack logs

This commit is contained in:
Timothy Warren 2022-01-10 13:47:10 -05:00
parent be433a9449
commit 018dbe35b8
4 changed files with 66 additions and 19 deletions

View File

@ -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()

View File

@ -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()

View File

@ -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

View File

@ -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)