11from __future__ import annotations
22
3- from typing import TYPE_CHECKING
3+ from typing import Optional , Tuple , TYPE_CHECKING
44
55if TYPE_CHECKING :
66 from engine import Engine
77 from entity import Entity
88
99
1010class Action :
11- def perform (self , engine : Engine , entity : Entity ) -> None :
11+ def __init__ (self , entity : Entity ) -> None :
12+ super ().__init__ ()
13+ self .entity = entity
14+
15+ @property
16+ def engine (self ) -> Engine :
17+ """Return the engine this action belongs to."""
18+ return self .entity .gamemap .engine
19+
20+ def perform (self ) -> None :
1221 """Perform this action with the objects needed to determine its scope.
1322
14- `engine` is the scope this action is being performed in.
23+ `self. engine` is the scope this action is being performed in.
1524
16- `entity` is the object performing the action.
25+ `self. entity` is the object performing the action.
1726
1827 This method must be overridden by Action subclasses.
1928 """
2029 raise NotImplementedError ()
2130
2231class ActionWithDirection (Action ):
23- def __init__ (self , dx : int , dy : int ):
24- super ().__init__ ()
32+ def __init__ (self , entity : Entity , dx : int , dy : int ):
33+ super ().__init__ (entity )
2534
2635 self .dx = dx
2736 self .dy = dy
2837
2938 def perform (self , engine : Engine , entity : Entity ) -> None :
3039 raise NotImplementedError ()
40+
41+ @property
42+ def dest_xy (self ) -> Tuple [int , int ]:
43+ """Returns this actions destination."""
44+ return self .entity .x + self .dx , self .entity .y + self .dy
45+
46+ @property
47+ def blocking_entity (self ) -> Optional [Entity ]:
48+ """Return the blocking entity at this actions destination.."""
49+ return self .engine .game_map .get_blocking_entity_at_location (* self .dest_xy )
3150
3251class EscapeAction (Action ):
33- def perform (self , engine : Engine , entity : Entity ) -> None :
52+
53+ def perform (self ) -> None :
3454 raise SystemExit ()
3555
3656class MeleeAction (ActionWithDirection ):
37- def perform (self , engine : Engine , entity : Entity ) -> None :
38- dest_x = entity .x + self .dx
39- dest_y = entity .y + self .dy
40- target = engine .game_map .get_blocking_entity_at_location (dest_x , dest_y )
57+ def perform (self ) -> None :
58+ target = self .blocking_entity
4159 if not target :
4260 return # No entity to attack.
4361
4462 print (f"You punch the { target .name } , it does not seem to be doing much damage..." )
4563
4664class MovementAction (ActionWithDirection ):
47- def perform (self , engine : Engine , entity : Entity ) -> None :
48- dest_x = entity .x + self .dx
49- dest_y = entity .y + self .dy
65+ def perform (self ) -> None :
66+ dest_x , dest_y = self .dest_xy
5067
51- if not engine .game_map .in_bounds (dest_x , dest_y ):
68+ if not self . engine .game_map .in_bounds (dest_x , dest_y ):
5269 return # Destination is out of bounds.
53- if not engine .game_map .tiles ["walkable" ][dest_x , dest_y ]:
70+ if not self . engine .game_map .tiles ["walkable" ][dest_x , dest_y ]:
5471 return # Destination is blocked by a tile.
55- if engine .game_map .get_blocking_entity_at_location (dest_x , dest_y ):
72+ if self . engine .game_map .get_blocking_entity_at_location (dest_x , dest_y ):
5673 return # Destination is blocked by an entity.
5774
5875
59- entity .move (self .dx , self .dy )
76+ self . entity .move (self .dx , self .dy )
6077
6178
6279class BumpAction (ActionWithDirection ):
63- def perform (self , engine : Engine , entity : Entity ) -> None :
64- dest_x = entity .x + self .dx
65- dest_y = entity .y + self .dy
66-
67- if engine .game_map .get_blocking_entity_at_location (dest_x , dest_y ):
68- return MeleeAction (self .dx , self .dy ).perform (engine , entity )
80+ def perform (self ) -> None :
81+ if self .blocking_entity is not None :
82+ return MeleeAction (self .entity , self .dx , self .dy ).perform ()
6983
7084 else :
71- return MovementAction (self .dx , self .dy ).perform (engine , entity )
85+ return MovementAction (self .entity , self . dx , self .dy ).perform ()
0 commit comments