-
Notifications
You must be signed in to change notification settings - Fork 4
/
inputactor.py
301 lines (263 loc) · 14.7 KB
/
inputactor.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
from actor import Actor
from entityeffect import StatusAdder, StatusRemover
from equipment import EquipmentSlots
import monster
import settings
import spawner
import menu
from missileaction import PlayerShootWeaponAction, PlayerSlingStoneAction
from statusflags import StatusFlags
import console
import gametime
import inputhandler
import menufactory
import positionexaminer
import util
from weapon import new_dagger, new_spear, new_morning_star, new_sword, RangeWeaponType, new_kris, new_katar, new_cestus, new_iron_hand, new_claw, new_rapier, new_scimitar, new_club, new_flail, new_hammer, new_chain_and_ball, new_halberd, new_trident, new_whip, new_axe, new_gun, new_sling, new_flame_orb
DEV_EQUIPMENT_FACTORY_LIST = \
[new_dagger, new_kris, new_katar, new_cestus, new_iron_hand, new_claw, new_sword,
new_rapier, new_scimitar, new_club, new_morning_star, new_flail, new_hammer,
new_chain_and_ball, new_spear, new_halberd, new_trident, new_whip, new_axe, new_gun, new_sling, new_flame_orb]
class InputActor(Actor):
def __init__(self):
super(InputActor, self).__init__()
def act(self):
self.newly_spent_energy = 0
self.handle_mouse_input()
self.step_path()
if len(self.parent.vision.get_seen_entities()) > 0:
self.parent.path.clear()
else:
self.handle_auto_pick_up()
if self.newly_spent_energy < 1:
self.handle_keyboard_input()
return self.newly_spent_energy
def handle_mouse_input(self):
inputhandler.handler.update_keys()
mouse_position = inputhandler.handler.get_mouse_position()
if not mouse_position is None:
if inputhandler.handler.get_left_mouse_press():
self.set_path_destination(self.parent.game_state.value.camera.
screen_to_dungeon_position(mouse_position))
def handle_context_action(self):
context_menu_options = []
player = self.parent
state_stack = player.game_state.value.menu_prompt_stack
stack_pop_function = menu.BackToGameFunction(state_stack)
if player.pick_up_item_action.can_act(source_entity=self.parent,
target_entity=self.parent,
game_state=self.parent.game_state.value):
pickup_option = player.pick_up_item_action.delayed_act(source_entity=player,
target_entity=player,
game_state=player.game_state.value)
functions = [pickup_option, stack_pop_function]
context_menu_options.append(menu.MenuOption(player.pick_up_item_action.name, functions))
context_menu_options.extend(menufactory.get_dungeon_feature_menu_options(player, stack_pop_function))
if len(context_menu_options) == 1 and context_menu_options[0].can_activate:
context_menu_options[0].activate()
elif len(context_menu_options) > 1:
tile_menu = menufactory.get_menu_with_options(context_menu_options, state_stack)
self.parent.game_state.value.start_prompt(tile_menu)
def handle_auto_pick_up(self):
dungeon_level = self.parent.dungeon_level.value
position = self.parent.position.value
item = dungeon_level.get_tile(position).get_first_item()
if item and item.has("player_auto_pick_up"):
self.handle_pick_up()
def handle_dev_mode_commands(self, key):
if key == inputhandler.TWO:
self.parent.health_modifier.heal(300)
elif key == inputhandler.THREE:
global DEV_EQUIPMENT_FACTORY_LIST
self.parent.equipment.force_equip(DEV_EQUIPMENT_FACTORY_LIST[0](self.parent.game_state.value))
DEV_EQUIPMENT_FACTORY_LIST = DEV_EQUIPMENT_FACTORY_LIST[1:] + DEV_EQUIPMENT_FACTORY_LIST[:1]
self.newly_spent_energy += gametime.single_turn
elif key == inputhandler.FOUR:
self.toggle_invisibility()
elif key == inputhandler.FIVE:
spawner.place_piece_on_random_walkable_tile(monster.new_ratman(self.parent.game_state.value),
self.parent.dungeon_level.value)
self.newly_spent_energy += gametime.single_turn
elif key == inputhandler.SIX:
spawner.place_piece_on_random_walkable_tile(monster.new_ghost(self.parent.game_state.value),
self.parent.dungeon_level.value)
self.newly_spent_energy += gametime.single_turn
elif key == inputhandler.NINE:
for entity in self.parent.dungeon_level.value.entities:
if not entity is self.parent:
entity.health_modifier.kill()
self.newly_spent_energy += gametime.single_turn
elif key == inputhandler.ZERO:
self.parent.game_state.value.has_won = True
self.newly_spent_energy += gametime.single_turn
elif key == inputhandler.END:
self.newly_spent_energy += gametime.single_turn
current_depth = self.parent.dungeon_level.value.depth
next_dungeon_level = self.parent.dungeon_level.value.dungeon.get_dungeon_level(current_depth + 1)
self.newly_spent_energy += gametime.single_turn
if next_dungeon_level is None:
return
destination_position = next_dungeon_level.up_stairs[0].position.value
self.parent.mover.move_push_over(destination_position, next_dungeon_level)
def handle_pick_up(self):
if self.parent.pick_up_item_action.can_act(source_entity=self.parent, target_entity=self.parent,
game_state=self.parent.game_state.value):
self.parent.pick_up_item_action.act(source_entity=self.parent, target_entity=self.parent,
game_state=self.parent.game_state.value)
else:
self.parent.pick_up_item_action.print_player_error(source_entity=self.parent, target_entity=self.parent,
game_state=self.parent.game_state.value)
def handle_keyboard_input(self):
key = inputhandler.handler.get_keypress()
if key in inputhandler.move_controls or key in inputhandler.vi_move_controls:
self.handle_move_input(key)
elif key == inputhandler.ENTER:
self.spawn_context_menu()
elif key == inputhandler.PRINTSCREEN:
console.console.print_screen()
elif key == inputhandler.TAB:
self.toggle_command_list()
elif key == inputhandler.USE_PICK_UP:
self.handle_context_action()
elif key == inputhandler.PICKUP: # Pick up
self.handle_pick_up()
elif key == inputhandler.FIRE:
self.throw_or_shoot()
elif key == inputhandler.ESCAPE:
self.save_and_quit()
elif key == inputhandler.REST: # Rest
self.newly_spent_energy += gametime.single_turn
elif key == inputhandler.EXAMINE:
self.start_examine()
elif key == inputhandler.AUTO_EXPLORE:
self.auto_explore()
elif key == inputhandler.INVENTORY:
self.try_open_inventory()
elif key == inputhandler.EQUIPMENT:
self.open_equipment()
elif key == inputhandler.WEAR_WIELD:
self.open_wear_wield_item_action_menu()
elif key == inputhandler.DRINK:
self.open_drink_item_action_menu()
elif key == inputhandler.READ:
self.open_read_item_action_menu()
if settings.DEV_MODE_FLAG:
self.handle_dev_mode_commands(key)
def step_path(self):
if self.parent.path.has_path():
self.newly_spent_energy = self.parent.path.try_step_path()
def set_path_destination(self, destination):
if not destination is None:
if self.parent.memory_map.has_seen_position(destination):
self.parent.path.compute_path(destination)
else:
self.parent.path.set_line_path(destination)
def handle_move_input(self, key):
if key in inputhandler.move_controls:
direction = inputhandler.move_controls[key]
else:
direction = inputhandler.vi_move_controls[key]
self.newly_spent_energy += self.parent.stepper.try_step_in_direction(direction)
def spawn_context_menu(self):
context_menu = menufactory.context_menu(self.parent, self.parent.game_state.value.menu_prompt_stack)
self.parent.game_state.value.start_prompt(context_menu)
def start_examine(self):
destination_selector = positionexaminer.PositionSelector(self.parent.game_state.value,
self.parent.position.value)
self.parent.game_state.value.start_prompt(destination_selector)
destination = destination_selector.selected_position
self.set_path_destination(destination)
def try_open_inventory(self):
if not self.parent.inventory.is_empty():
inventory_menu = menufactory.inventory_menu(self.parent, self.parent.game_state.value.menu_prompt_stack)
self.parent.game_state.value.start_prompt(inventory_menu)
def open_equipment(self):
equipment_menu = menufactory.equipment_menu(self.parent, self.parent.game_state.value.menu_prompt_stack)
self.parent.game_state.value.start_prompt(equipment_menu)
def auto_explore(self):
closest_enemy = next((entity for entity in self.parent.vision.get_seen_entities_closest_first()
if not entity.position.value == self.parent.position.value), None)
if closest_enemy and not closest_enemy.position.value == self.parent.position.value:
self.parent.path.compute_path(closest_enemy.position.value)
else:
destination = util.get_closest_unseen_walkable_position(self.parent, self.parent.position.value,
self.parent.dungeon_level.value)
if destination:
self.parent.path.compute_path(destination)
return
fountain = next((f for f in
self.parent.dungeon_level.value.dungeon_features
if f.has("drink_action") and (not f.position.value == self.parent.position.value)), None)
if fountain:
destination = fountain.position.value
self.parent.path.compute_path(destination)
return
if 0 < len(self.parent.dungeon_level.value.down_stairs):
stairs_down = self.parent.dungeon_level.value.down_stairs[0]
self.parent.path.compute_path(stairs_down.position.value)
def toggle_command_list(self):
self.parent.game_state.value.command_list_bar.turn_page()
def toggle_invisibility(self):
invisible_flag = StatusFlags.INVISIBILE
if not self.parent.status_flags.has_status(invisible_flag):
effect = StatusAdder(self.parent, invisible_flag, time_to_live=float("inf"))
self.parent.effect_queue.add(effect)
else:
invisible_status = StatusFlags.INVISIBILE
effect = StatusRemover(self.parent, invisible_status, time_to_live=1)
self.parent.effect_queue.add(effect)
self.newly_spent_energy += gametime.single_turn
def shoot_gun(self, weapon):
shooting = PlayerShootWeaponAction(weapon)
game_state = self.parent.game_state.value
if shooting.can_act(source_entity=self.parent, game_state=game_state):
shooting.act(source_entity=self.parent, game_state=game_state)
def shoot_sling(self, weapon):
shooting = PlayerSlingStoneAction(weapon)
game_state = self.parent.game_state.value
if shooting.can_act(source_entity=self.parent, game_state=game_state):
shooting.act(source_entity=self.parent, game_state=game_state)
def throw_or_shoot(self):
if not self.parent.equipment.slot_is_equiped(EquipmentSlots.RANGED_WEAPON):
self.throw_rock()
return
weapon = self.parent.equipment.get(EquipmentSlots.RANGED_WEAPON)
if weapon.range_weapon_type.value == RangeWeaponType.GUN:
self.shoot_gun(weapon)
elif weapon.range_weapon_type.value == RangeWeaponType.SLING:
self.shoot_sling(weapon)
elif weapon.range_weapon_type.value == RangeWeaponType.MAGIC:
weapon.magic_effect.cast_magic(source_entity=self.parent)
else:
raise Exception("Tried to shoot weapon without range_weapon_type")
def throw_rock(self):
rock_throwing = self.parent.throw_stone_action
game_state = self.parent.game_state.value
if (rock_throwing.can_act(source_entity=self.parent,
game_state=game_state)):
rock_throwing.act(source_entity=self.parent,
game_state=game_state)
def save_and_quit(self):
save_quit_menu = menufactory.get_save_quit_menu(self.parent, self.parent.game_state.value.menu_prompt_stack)
self.parent.game_state.value.start_prompt(save_quit_menu)
def open_wear_wield_item_action_menu(self):
reequip_tag = "reequip_action"
if menufactory._has_item_with_action_tag(self.parent, reequip_tag):
equip_menu = menufactory.filtered_by_action_item_menu(self.parent,
self.parent.game_state.value.menu_prompt_stack,
reequip_tag, "Wear / Wield")
self.parent.game_state.value.start_prompt(equip_menu)
def open_drink_item_action_menu(self):
drink_tag = "drink_action"
if menufactory._has_item_with_action_tag(self.parent, drink_tag):
equip_menu = menufactory.filtered_by_action_item_menu(self.parent,
self.parent.game_state.value.menu_prompt_stack,
drink_tag, "Drink")
self.parent.game_state.value.start_prompt(equip_menu)
def open_read_item_action_menu(self):
read_tag = "read_action"
if menufactory._has_item_with_action_tag(self.parent, read_tag):
equip_menu = menufactory.filtered_by_action_item_menu(self.parent,
self.parent.game_state.value.menu_prompt_stack,
read_tag, "Read")
self.parent.game_state.value.start_prompt(equip_menu)