-
Notifications
You must be signed in to change notification settings - Fork 6
/
command_handler.py
315 lines (240 loc) · 11.9 KB
/
command_handler.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
302
303
304
305
306
307
308
309
310
311
312
313
314
"""
This module will handle the player's commands
"""
from zones.zone import Zone
from models.characters.saver import save_character
from commands import pac_main_ooc, pac_map_directions, pac_in_combat, pac_vendor_dialogue, pac_opened_inventory
from information_printer import (print_live_npcs, print_live_monsters, print_quest_item_choices,
print_available_quests, print_in_combat_stats, print_character_xp_bar,
print_character_equipment, print_inventory)
from constants import ZONE_MOVE_BLOCK_SPECIAL_KEY
from utils.helper import get_guid_by_name
from information_printer import print_quest_log, print_vendor_products_for_sale
# handlers here!
def handle_talk_to_command(command: str, character, zone_object: Zone):
alive_npcs, guid_name_set = zone_object.get_cs_npcs()
target = command[8:] # name of NPC
# return the guid for the npc we want to target, or None if there is no such one
target_guid = get_guid_by_name(target, guid_name_set)
# using the guid, target him from the alive_monsters dictionary
if target_guid in alive_npcs.keys():
target = alive_npcs[target_guid]
target.talk(character.name)
else:
print(f'Could not find NPC {target}.')
def handle_engage_command(command: str, character, zone_object: Zone):
"""
This checks if there is a hostile monster with the name provided in the command.
If there is, we engage in combat with him by going into the engage_combat function in the
combat.py module.
:param command: the player's command
:param character: The player's character, a Character object
:param zone_object: a Zone object from which we will get the monsters
:return:
"""
from combat import engage_combat
alive_monsters, guid_name_set = zone_object.get_cs_monsters()
target = command[7:] # name of monster to engage
# return the guid for the monster we want to target, or None if there is no such one
target_guid = get_guid_by_name(target, guid_name_set)
# using the guid, target him from the alive_monsters dictionary
if target_guid in alive_monsters.keys():
target = alive_monsters[target_guid] # convert the string to a Monster object
engage_combat(character, target, alive_monsters, guid_name_set, target_guid)
else:
print(f'Could not find creature {target}.')
def handle_accept_quest_command(command: str, character, available_quests: dict):
quest_to_accept = command[7:] # name of quest to accept
if quest_to_accept in available_quests.keys():
quest = available_quests[quest_to_accept]
if character.level >= quest.required_level:
print(f'Accepted Quest - {quest.name}')
character.add_quest(quest)
del available_quests[quest_to_accept] # removes it from the dictionary
else:
print(f'You need to be level {quest.required_level} to accept {quest.name}')
else:
print("No such quest.")
def handle_buy_from_command(command: str, character, zone_object: Zone):
""" check to see if there is such a vendor, if it is, go to the handle_vendor_sale function
which initiates the while loop for browsing the vendor's inventory """
target = command[9:] # name of Vendor
alive_npcs, guid_name_set = zone_object.get_cs_npcs()
# return the guid for the npc we want to target, or None if there is no such one
target_guid = get_guid_by_name(target, guid_name_set)
# using the guid, target him from the alive_monsters dictionary
if target_guid in alive_npcs.keys():
target = alive_npcs[target_guid]
handle_vendor_sale(character, target)
else:
print(f'Could not find Vendor {target}')
def handle_vendor_sale(character, vendor):
while True:
print_vendor_products_for_sale(vendor_name=vendor.name, vendor_inventory=vendor.inventory)
command = input()
if command == 'exit':
break
elif 'buy ' in command:
item = command[4:] # name of the item
if not vendor.has_item(item):
print(f'{vendor.name} does not have {item} in stock.')
continue
# check if the player has enough gold
if not character.has_enough_gold(vendor.get_item_price(item)):
print(f'You do not have enough gold to buy {item}!\n')
continue
character.buy_item(vendor.sell_item(item))
print(f'{character.name} has bought {item} from {vendor.name}!')
elif 'sell ' in command:
item = command[5:] # name of the item
if character.has_item(item):
character.sell_item(item)
else:
print(f'You do not have {item} in your inventory!')
print()
elif 'info' in command:
item_name = command[:-5] # name of item
item = vendor.get_item_info(item_name)
print("\t", item, "\n") if item else None
elif command == '?':
pac_vendor_dialogue()
def handle_open_inventory_command(character):
"""
This command opens the inventory of the character and lets him fiddle with the items there
"""
print_inventory(character)
while True:
command = input(">inventory ")
to_print = True
if command == "?":
pac_opened_inventory()
to_print = False
elif command == "exit":
print("-" * 40)
break
elif "equip" in command:
""" Equips the item """
item_name = command[6:]
# failsafe check if the item is in the inventory of the player. if it's not it will return a None object,
# which will not pass the if checks in the equip_item method
item, _ = character.inventory.get(item_name, (None, None))
character.equip_item(item)
elif "use" in command:
""" Consumes a consumable item"""
item_name = command[4:]
# failsafe check if the item is in the inventory of the player. if it's not it will return a None object,
# which will not pass the if checks in the consume_item method
item, _ = character.inventory.get(item_name, (None, None))
character.consume_item(item)
if to_print: # we've tried to modify the inventory in some way
""" item and item_name are assigned if we manage to pass this if check """
if item:
# we've modified the inventory (consumed/equipped an item)
print_inventory(character)
else:
# we've tried to modify the inventory but unsuccessfuly, therefore item is None
print(f'{item_name} is not in your inventory.')
def handle_go_to_command(command: str, character, zone_object: Zone):
destination = command[6:]
"""
move_player will usually return a boolean if we can initiate the move or not.
However, there's a special case: If it returns SPECIAL_ZONE_BLOCK_KEY,
it means that we cannot initiate the move and that the printing is handled by the method itself.
"""
valid_move = zone_object.move_player(character.current_subzone, destination, character)
if valid_move == ZONE_MOVE_BLOCK_SPECIAL_KEY:
return
if valid_move:
# if the move has been successful
character.current_subzone = destination
# update _map directions
print(f'Moved to {character.current_subzone}')
zone_object.engage_zone_entered_script(character) # engage a script if there is one
print_live_npcs(zone_object, print_all=True)
print_live_monsters(zone_object)
else:
print(f'No such destination as {destination} that is connected to your current subzone.')
def handle_quest_item_choice(item_rewards: dict):
"""
This function opens a window where the player selects which item he wants to take from the quest
:param item_rewards: a dictionary key: item name, value: instance of class Item
:return: an instance of Item (the item object the player selected)
"""
print_quest_item_choices(item_rewards)
while True:
command = input()
if "choose" in command:
""" Takes the item the player chooses """
item_name = command[7:]
if item_name in item_rewards.keys():
return item_rewards[item_name]
else:
print("No such item as ", item_name)
elif command == "?":
print("Available commands:")
print("\tchoose [Item Name]")
print("\t\tTakes the item\n")
def prompt_revive(character):
"""
Prompt if the Player wants to revive his character after death
"""
print("Do you want to restart? Y/N")
if input() in 'Yy':
character.revive()
print(f'Character {character.name} has been revived!')
else:
raise SystemExit # quit the game
def handle_save_character_command(main_character):
""" this function handles the 'save' command"""
save_character(main_character)
def handle_help_command():
""" this function handles the '?' command, displaying the user with all his possible commands"""
pac_main_ooc() # print available commands in the main loop when out of combat
def handle_go_to_help_command(zone_object):
""" this function handles the 'go to ?' command, displaying the user with all the possible routes he can take"""
pac_map_directions(possible_routes=zone_object.get_cs_map())
def handle_paq_command(zone_object, main_character):
""" this function handles the 'print available quests' or 'paq' command, showing the player all the quests
he is eligible to take """
print_available_quests(available_quests=zone_object.get_cs_quests(), players_level=main_character.level)
def handle_pql_command(main_character):
""" this function handles the 'print quest log' or 'pql' command, showing the player all the quests he is
currently on """
print_quest_log(main_character.quest_log)
def handle_print_inventory_command(main_character):
""" this function handles the 'print inventory' command, showing the player's inventory """
print_inventory(main_character)
def handle_print_equipment_command(main_character):
""" this function handles the 'print equipment' command, showing the player's equipment """
print_character_equipment(main_character.equipment)
def handle_pam_command(zone_object, print_all: bool=False):
"""
this function handles the 'print alive monsters' or 'pam' command, showing the player all the
live creatures in his current zone
:param print_all: on a default print, we print only 5 alive monsters. If we want to print all of the live monsters
in the current zone, this boolean muut be set to True
"""
print_live_monsters(zone_object, print_all)
def handle_pan_command(zone_object, print_all: bool=False):
"""
this function handles the 'print alive npcs' or 'pan' command, showing the player all the live NPCs
in his current zone
:param print_all: on a default print, we print only 5 alive NPCs. If we want to print all of the live monsters
in the current zone, this boolean must be set to True
"""
print_live_npcs(zone_object, print_all)
# IN COMBAT COMMANDS
# COMMANDS THAT DO NOT END THE TURN
def handle_combat_help_command(character):
""" this function handles the '?' command when it is entered in combat, displaying the player's
available commands """
pac_in_combat(character) # print available commands
def handle_combat_print_stats_command(character, monster):
"""
this function handles the 'print stats' command, showing the stats of the player and the monster he's fighting
while in combat.
"""
print_in_combat_stats(character, monster)
def handle_combat_print_xp_command(character):
""" this function handles the 'print xp' command, showing the player's current experience bar while in combat """
print_character_xp_bar(character)