-
Notifications
You must be signed in to change notification settings - Fork 0
/
actions.py
142 lines (103 loc) · 4.16 KB
/
actions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from engine import Engine
from entity import Entity
from message_log import MessageLog
class Action:
def perform(self, engine: Engine, entity: Entity, message_log: MessageLog) -> None:
"""Perform this action with the objects needed to determine its scope.
`engine` is the scope this action is being performed in.
`entity` is the object performing the action.
This method must be overridden by Action subclasses.
"""
raise NotImplementedError()
class EscapeAction(Action):
def perform(self, engine: Engine, entity: Entity, message_log: MessageLog) -> None:
raise SystemExit()
class DirectionalAction(Action):
def __init__(self, dx: int, dy: int):
self.dx = dx
self.dy = dy
class BumpAction(DirectionalAction):
def perform(self, engine: Engine, entity: Entity, message_log: MessageLog) -> None:
dest_x = entity.x + self.dx
dest_y = entity.y + self.dy
if engine.game_map.get_creature_at(dest_x, dest_y) or (engine.player.x, engine.player.y) == (dest_x, dest_y):
return MeleeAction(self.dx, self.dy).perform(engine, entity, message_log)
else:
return MovementAction(self.dx, self.dy).perform(engine, entity, message_log)
class MovementAction(DirectionalAction):
def __init__(self, dx: int, dy: int):
super().__init__(dx, dy)
self.dx = dx
self.dy = dy
def perform(self, engine: Engine, entity: Entity, message_log: MessageLog) -> None:
dest_x = entity.x + self.dx
dest_y = entity.y + self.dy
if not engine.game_map.in_bounds(dest_x, dest_y):
return True # Destination is out of bounds.
if not engine.game_map.tiles["walkable"][dest_x, dest_y]:
return True # Destination is blocked by a tile.
entity.move(self.dx, self.dy)
def construct_attack_sentence(attacker, target, player):
text = ""
if attacker == player:
text += "You hit "
else:
text += "The " + attacker.name + " hits "
if target == player:
text += "you"
else:
text += "the " + target.name
text += "!"
if target == player:
text_color = (255, 0, 0)
elif attacker == player:
text_color = (54, 131, 255)
else:
text_color = (255, 255, 255)
return text, text_color
class MeleeAction(DirectionalAction):
def perform(self, engine: Engine, entity: Entity, message_log: MessageLog) -> None:
dest_x = entity.x + self.dx
dest_y = entity.y + self.dy
target = engine.game_map.get_creature_at(dest_x, dest_y)
if not target:
target = engine.player
attacker = entity
target.hp -= 1
message_log.log(
*construct_attack_sentence(attacker, target, engine.player)
)
class WaitAction(Action):
def __init__(self):
super().__init__()
def perform(self, engine: Engine, entity: Entity, message_log: MessageLog) -> None:
# The entity waits for one turn.
pass
class PickUpAction(Action):
def perform(self, engine: Engine, entity: Entity, message_log: MessageLog):
x = engine.player.x
y = engine.player.y
if engine.game_map.get_item_at(x,y):
item = engine.game_map.get_item_at(x,y)
engine.player.pick_up(item, engine.game_map)
message_log.log(f"You pick up the {item.name}.", (0,255,0))
else:
message_log.log("There are no items here.")
return True
class DropAction(Action):
def perform(self, engine: Engine, entity: Entity, message_log: MessageLog):
if engine.player.has_items():
engine.add_menu('drop')
else:
engine.message_log.log('You are carrying nothing.')
return 1
class ViewInventoryAction(Action):
def perform(self, engine: Engine, entity: Entity, message_log: MessageLog) -> None:
if engine.player.has_items():
engine.add_menu('inventory')
else:
engine.message_log.log('You are carrying nothing.')
return 1