neelthee-mansion 3.19.12__py3-none-any.whl → 3.19.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- neelthee_mansion/Books.py +31 -29
- neelthee_mansion/Mansion_of_Amnesia.py +512 -341
- neelthee_mansion/Quests.py +16 -5
- neelthee_mansion/Rooms.py +1183 -1210
- neelthee_mansion/all_game_utils.py +3 -2
- neelthee_mansion/creatures.py +137 -85
- neelthee_mansion/items.py +40 -23
- neelthee_mansion/utils.py +141 -66
- {neelthee_mansion-3.19.12.dist-info → neelthee_mansion-3.19.14.dist-info}/METADATA +1 -1
- neelthee_mansion-3.19.14.dist-info/RECORD +16 -0
- neelthee_mansion-3.19.12.dist-info/RECORD +0 -16
- {neelthee_mansion-3.19.12.dist-info → neelthee_mansion-3.19.14.dist-info}/LICENSE.md +0 -0
- {neelthee_mansion-3.19.12.dist-info → neelthee_mansion-3.19.14.dist-info}/WHEEL +0 -0
- {neelthee_mansion-3.19.12.dist-info → neelthee_mansion-3.19.14.dist-info}/entry_points.txt +0 -0
- {neelthee_mansion-3.19.12.dist-info → neelthee_mansion-3.19.14.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
from .Rooms import *
|
1
|
+
from .Rooms import *
|
2
2
|
from .creatures import *
|
3
3
|
from .items import *
|
4
4
|
from .Quests import *
|
@@ -6,21 +6,21 @@ from .all_game_utils import *
|
|
6
6
|
|
7
7
|
|
8
8
|
GameState = {
|
9
|
-
|
10
|
-
|
9
|
+
"Enemies killed": 0,
|
10
|
+
"collected items": [],
|
11
11
|
}
|
12
12
|
|
13
13
|
|
14
|
-
|
14
|
+
"""
|
15
15
|
Neel-thee's Mansion of Amnesia
|
16
|
-
|
16
|
+
"""
|
17
17
|
|
18
18
|
global player, evil_mage, commands, NOTE_NUM, credits, color_coding, quest_manager, revealer, CHARACTERSLIST, BACKGROUNDS
|
19
19
|
|
20
20
|
BACKGROUNDS = {
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
"Adventurer": ["survival", "climbing"],
|
22
|
+
"Artist": ["painting", "sculpting"],
|
23
|
+
"Scholar": ["reading", "research"],
|
24
24
|
}
|
25
25
|
|
26
26
|
revealer = KeyRevealer()
|
@@ -29,68 +29,68 @@ quest_manager = QuestManager()
|
|
29
29
|
|
30
30
|
color_coding = False
|
31
31
|
|
32
|
-
credits =
|
32
|
+
credits = """
|
33
33
|
Made by: Alexander.E.F
|
34
|
-
AI assisted the creation
|
34
|
+
AI assisted the creation"""
|
35
35
|
|
36
36
|
|
37
|
-
name =
|
37
|
+
name = ""
|
38
38
|
age = 0
|
39
39
|
height = Height()
|
40
40
|
weight = 0
|
41
41
|
|
42
42
|
|
43
43
|
CHARACTERSLIST = [
|
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
|
-
{
|
44
|
+
{"name": "Jack", "age": 19, "height": Height("6ft 3"), "weight(LBs)": 213},
|
45
|
+
{"name": "Darcie-Mae", "age": 19, "height": Height("5ft 5"), "weight(LBs)": 150},
|
46
|
+
{"name": "John", "age": 25, "height": Height("5ft 10"), "weight(LBs)": 180},
|
47
|
+
{"name": "Emily", "age": 22, "height": Height("5ft 6"), "weight(LBs)": 135},
|
48
|
+
{"name": "William", "age": 30, "height": Height("6ft 1"), "weight(LBs)": 200},
|
49
|
+
{"name": "Samantha", "age": 28, "height": Height("5ft 8"), "weight(LBs)": 155},
|
50
|
+
{"name": "Mark", "age": 23, "height": Height("5ft 11"), "weight(LBs)": 185},
|
51
|
+
{"name": "Alex", "age": 27, "height": Height("6ft 0"), "weight(LBs)": 190},
|
52
|
+
{"name": "Sarah", "age": 20, "height": Height("5ft 4"), "weight(LBs)": 125},
|
53
|
+
{"name": "Natalie", "age": 24, "height": Height("5ft 7"), "weight(LBs)": 140},
|
54
|
+
{"name": "Michael", "age": 32, "height": Height("6ft 2"), "weight(LBs)": 200},
|
55
|
+
{"name": "Liam", "age": 29, "height": Height("5ft 10"), "weight(LBs)": 180},
|
56
|
+
{"name": "James", "age": 25, "height": Height("6ft 1"), "weight(LBs)": 195},
|
57
|
+
{"name": "Emma", "age": 22, "height": Height("5ft 6"), "weight(LBs)": 130},
|
58
|
+
{"name": "Olivia", "age": 26, "height": Height("5ft 8"), "weight(LBs)": 135},
|
59
|
+
{"name": "Sophia", "age": 28, "height": Height("5ft 5"), "weight(LBs)": 145},
|
60
|
+
{"name": "Daniel", "age": 28, "height": Height("6ft 0"), "weight(LBs)": 180},
|
61
|
+
{"name": "Matthew", "age": 31, "height": Height("5ft 11"), "weight(LBs)": 175},
|
62
|
+
{"name": "Jennifer", "age": 25, "height": Height("5ft 6"), "weight(LBs)": 140},
|
63
|
+
{"name": "Hannah", "age": 23, "height": Height("5ft 4"), "weight(LBs)": 130},
|
64
|
+
{"name": "Isabella", "age": 24, "height": Height("5ft 4"), "weight(LBs)": 132},
|
65
|
+
{"name": "Jake", "age": 29, "height": Height("5ft 6"), "weight(LBs)": 140},
|
66
|
+
{"name": "Zack", "age": 21, "height": Height("5ft 5"), "weight(LBs)": 125},
|
67
|
+
{"name": "Lucy", "age": 27, "height": Height("5ft 7"), "weight(LBs)": 135},
|
68
|
+
{"name": "Mia", "age": 25, "height": Height("5ft 3"), "weight(LBs)": 128},
|
69
|
+
{"name": "Brandon", "age": 30, "height": Height("6ft 1"), "weight(LBs)": 180},
|
70
|
+
{"name": "Ethan", "age": 28, "height": Height("6ft 0"), "weight(LBs)": 175},
|
71
|
+
{"name": "Andrew", "age": 28, "height": Height("6ft 0"), "weight(LBs)": 175},
|
72
|
+
{"name": "Nathan", "age": 26, "height": Height("5ft 10"), "weight(LBs)": 165},
|
73
|
+
{"name": "David", "age": 22, "height": Height("6ft 2"), "weight(LBs)": 185},
|
74
|
+
{"name": "Noah", "age": 25, "height": Height("5ft 11"), "weight(LBs)": 175},
|
75
|
+
{"name": "Aiden", "age": 30, "height": Height("6ft 0"), "weight(LBs)": 180},
|
76
|
+
{"name": "Lucas", "age": 28, "height": Height("5ft 10"), "weight(LBs)": 170},
|
77
|
+
{"name": "Ava", "age": 22, "height": Height("5ft 5"), "weight(LBs)": 130},
|
78
|
+
{"name": "Lily", "age": 26, "height": Height("5ft 6"), "weight(LBs)": 135},
|
79
|
+
{"name": "Grace", "age": 29, "height": Height("5ft 7"), "weight(LBs)": 140},
|
80
|
+
{"name": "Josh", "age": 26, "height": Height("5ft 6"), "weight(LBs)": 135},
|
81
|
+
{"name": "Luka", "age": 29, "height": Height("5ft 7"), "weight(LBs)": 140},
|
82
82
|
]
|
83
83
|
|
84
84
|
|
85
85
|
evil_mage = PC(
|
86
|
-
|
87
|
-
19836,
|
88
|
-
|
89
|
-
29,
|
90
|
-
|
91
|
-
Height(
|
92
|
-
222,
|
93
|
-
xp=99180,
|
86
|
+
"Neel-thee Contozt",
|
87
|
+
19836,
|
88
|
+
"Mage",
|
89
|
+
29,
|
90
|
+
"Evil prince",
|
91
|
+
Height("5ft 7.375"),
|
92
|
+
222,
|
93
|
+
xp=99180,
|
94
94
|
)
|
95
95
|
|
96
96
|
|
@@ -99,26 +99,26 @@ def parse_command(command_str: str, commands: dict):
|
|
99
99
|
global player
|
100
100
|
# Split the command string into parts
|
101
101
|
parts = command_str.split()
|
102
|
-
|
102
|
+
|
103
103
|
# Check for multi-word commands
|
104
104
|
for cmd in commands.keys():
|
105
105
|
cmd_parts = cmd.split()
|
106
|
-
if len(cmd_parts) > 1 and parts[:len(cmd_parts)] == cmd_parts:
|
107
|
-
action =
|
108
|
-
targets = parts[len(cmd_parts):]
|
106
|
+
if len(cmd_parts) > 1 and parts[: len(cmd_parts)] == cmd_parts:
|
107
|
+
action = " ".join(cmd_parts)
|
108
|
+
targets = parts[len(cmd_parts) :]
|
109
109
|
return action, targets
|
110
|
-
|
110
|
+
|
111
111
|
# Default single word command
|
112
112
|
action = parts[0]
|
113
113
|
targets = parts[1:] if len(parts) > 1 else []
|
114
114
|
return action, targets
|
115
115
|
|
116
116
|
|
117
|
-
|
118
117
|
def showInstructions():
|
119
118
|
global player
|
120
119
|
# Display the game instructions
|
121
|
-
type_text(
|
120
|
+
type_text(
|
121
|
+
"""
|
122
122
|
===========================
|
123
123
|
Commands:
|
124
124
|
go [%*GREEN*%direction%*RESET*%/%*GREEN*%teleport%*RESET*%/%*GREEN*%number%*RESET*%] - Move to another location
|
@@ -133,18 +133,21 @@ quit - Quit the game
|
|
133
133
|
help - Show these instructions
|
134
134
|
hint - Get a random hint for your current location
|
135
135
|
map - Display the map of places you have been to
|
136
|
-
|
136
|
+
""",
|
137
|
+
colorTrue=color_coding,
|
138
|
+
)
|
137
139
|
|
138
140
|
|
139
141
|
def showHint():
|
140
142
|
global player
|
141
|
-
if
|
143
|
+
if "Hints" in ROOMS[player.CURRENTROOM]:
|
142
144
|
type_text("You think:", colorTrue=color_coding)
|
143
|
-
hint = choice(ROOMS[player.CURRENTROOM][
|
145
|
+
hint = choice(ROOMS[player.CURRENTROOM]["Hints"])
|
144
146
|
type_text(hint, colorTrue=color_coding)
|
145
147
|
else:
|
146
148
|
type_text("You can't think of anything", colorTrue=color_coding)
|
147
149
|
|
150
|
+
|
148
151
|
def check_direction(var: str, directions: list):
|
149
152
|
global player
|
150
153
|
for direction in directions:
|
@@ -157,19 +160,25 @@ def End(text: str, win: bool = True):
|
|
157
160
|
global player
|
158
161
|
type_text(text, colorTrue=color_coding)
|
159
162
|
if win:
|
160
|
-
type_text(
|
163
|
+
type_text("Do you want to leave the game? Y/N", colorTrue=color_coding)
|
161
164
|
while True:
|
162
|
-
leave = input(
|
163
|
-
if leave ==
|
164
|
-
type_text(
|
165
|
+
leave = input(">").lower()
|
166
|
+
if leave == "n":
|
167
|
+
type_text("You decide to continue exploring.", colorTrue=color_coding)
|
165
168
|
break
|
166
|
-
elif leave ==
|
167
|
-
type_text(
|
169
|
+
elif leave == "y":
|
170
|
+
type_text(
|
171
|
+
"You escaped the house... %*BOLD*%GAME OVER, YOU WIN!",
|
172
|
+
colorTrue=color_coding,
|
173
|
+
)
|
168
174
|
commands["quit"]()
|
169
175
|
else:
|
170
|
-
type_text(
|
176
|
+
type_text(
|
177
|
+
"Sorry, that wasn't 'y' or 'n'. Please enter 'y' or 'n'.",
|
178
|
+
colorTrue=color_coding,
|
179
|
+
)
|
171
180
|
else:
|
172
|
-
type_text(
|
181
|
+
type_text("%*BOLD*%GAME OVER, YOU LOSE!", colorTrue=color_coding)
|
173
182
|
commands["quit"]()
|
174
183
|
|
175
184
|
|
@@ -180,7 +189,7 @@ def add_note(note, parchment_index=None):
|
|
180
189
|
global player, NOTE_NUM
|
181
190
|
player.NOTES.append(note)
|
182
191
|
NOTE_NUM += 1
|
183
|
-
inv_note =
|
192
|
+
inv_note = "note " + str(NOTE_NUM)
|
184
193
|
try:
|
185
194
|
del player.inventory[parchment_index]
|
186
195
|
except IndexError:
|
@@ -193,54 +202,71 @@ def Use_grappling_hook():
|
|
193
202
|
|
194
203
|
def swing_into_forest():
|
195
204
|
global player
|
196
|
-
type_text(
|
205
|
+
type_text(
|
206
|
+
"You throw your grappling-hook, it catches a branch of a nearby tree and hooks back onto itself. \nYou can swing into the forest!",
|
207
|
+
colorTrue=color_coding,
|
208
|
+
)
|
197
209
|
if ask_for_consent("Do you want to swing into the forest"):
|
198
210
|
type_text("You swing into the forest", colorTrue=color_coding)
|
199
|
-
Move(
|
211
|
+
Move("Forest Clearing")
|
200
212
|
else:
|
201
|
-
type_text(
|
213
|
+
type_text(
|
214
|
+
"You flick the rope and it unhooks. You continue exploring the house.",
|
215
|
+
colorTrue=color_coding,
|
216
|
+
)
|
202
217
|
|
203
218
|
def climb_into_house():
|
204
219
|
global player
|
205
|
-
type_text(
|
220
|
+
type_text(
|
221
|
+
"You throw your grappling-hook, it catches the railing of the nearby house and hooks back onto itself. \nYou can climb into the house!",
|
222
|
+
colorTrue=color_coding,
|
223
|
+
)
|
206
224
|
if ask_for_consent("Do you want to climb into the house"):
|
207
225
|
type_text("You climb into the house", colorTrue=color_coding)
|
208
|
-
Move(
|
226
|
+
Move("Balcony")
|
209
227
|
else:
|
210
|
-
type_text(
|
228
|
+
type_text(
|
229
|
+
"You flick the rope and it unhooks. You continue exploring the forest",
|
230
|
+
colorTrue=color_coding,
|
231
|
+
)
|
211
232
|
|
212
|
-
if player.CURRENTROOM ==
|
233
|
+
if player.CURRENTROOM == "Balcony" and "grappling-hook" in player.inventory:
|
213
234
|
swing_into_forest()
|
214
|
-
elif
|
235
|
+
elif (
|
236
|
+
player.CURRENTROOM == "Forest Clearing" and "grappling-hook" in player.inventory
|
237
|
+
):
|
215
238
|
climb_into_house()
|
216
239
|
|
217
240
|
|
218
241
|
def Use_quill():
|
219
242
|
global player
|
220
243
|
|
221
|
-
if all(item in player.inventory for item in [
|
222
|
-
parchment_index = player.inventory.index(
|
223
|
-
type_text(
|
224
|
-
write = str(input(
|
244
|
+
if all(item in player.inventory for item in ["ink-pot", "parchment", "quill"]):
|
245
|
+
parchment_index = player.inventory.index("parchment")
|
246
|
+
type_text("What do you want to write", colorTrue=color_coding)
|
247
|
+
write = str(input(">")).strip()
|
225
248
|
|
226
249
|
if write:
|
227
250
|
add_note(write, parchment_index)
|
228
251
|
else:
|
229
252
|
type_text("You can't write nothing", colorTrue=color_coding)
|
230
253
|
else:
|
231
|
-
type_text(
|
254
|
+
type_text(
|
255
|
+
"You need an ink pot, parchment, and a quill to write.",
|
256
|
+
colorTrue=color_coding,
|
257
|
+
)
|
232
258
|
|
233
259
|
|
234
260
|
def Use_note(note_number):
|
235
261
|
global player
|
236
262
|
"""Reads a specified note from the player's inventory."""
|
237
|
-
note_key = f
|
263
|
+
note_key = f"note {note_number}"
|
238
264
|
if note_key in player.inventory:
|
239
265
|
note_index = int(note_number) - 1
|
240
|
-
type_text(f
|
266
|
+
type_text(f"You read:", colorTrue=color_coding)
|
241
267
|
type_text(player.NOTES[note_index], colorTrue=color_coding)
|
242
268
|
else:
|
243
|
-
type_text(
|
269
|
+
type_text("You do not have that note", colorTrue=color_coding)
|
244
270
|
|
245
271
|
|
246
272
|
def Use(*Args):
|
@@ -253,15 +279,17 @@ def Use(*Args):
|
|
253
279
|
item_obj = player.inventory[player.inventory.index(Item)]
|
254
280
|
if isinstance(item_obj, item):
|
255
281
|
if item_obj.sell(player):
|
256
|
-
type_text(
|
282
|
+
type_text(
|
283
|
+
f"You sell the %*BLUE*%{Item}%*RESET*%", colorTrue=color_coding
|
284
|
+
)
|
257
285
|
player.inventory.remove(item_obj.name)
|
258
|
-
elif Item ==
|
286
|
+
elif Item == "quill":
|
259
287
|
Use_quill()
|
260
|
-
elif Item ==
|
288
|
+
elif Item == "grappling-hook":
|
261
289
|
Use_grappling_hook()
|
262
|
-
elif len(Item) >= 2 and Item[0] ==
|
290
|
+
elif len(Item) >= 2 and Item[0] == "note" and Item[1]:
|
263
291
|
Use_note(Item[1])
|
264
|
-
elif Item ==
|
292
|
+
elif Item == "0":
|
265
293
|
type_text("You can't use nothing", colorTrue=color_coding)
|
266
294
|
else:
|
267
295
|
type_text("You can't use that", colorTrue=color_coding)
|
@@ -271,85 +299,90 @@ def PickKey(locked_obj):
|
|
271
299
|
keys = player.inventory.keys()
|
272
300
|
if not isinstance(keys, list):
|
273
301
|
keys = [keys]
|
274
|
-
|
302
|
+
|
275
303
|
if keys:
|
276
304
|
while True:
|
277
|
-
type_text(
|
305
|
+
type_text(
|
306
|
+
f"Please pick which key you want to use in the lock. This is what you know about the lock: {locked_obj}. These are your keys:"
|
307
|
+
)
|
278
308
|
|
279
309
|
# Enumerate keys and display them
|
280
310
|
for idx, key in enumerate(keys, 1): # Starts numbering at 1
|
281
311
|
type_text(f"{idx}. {key.name} - {key.CurentRevealStr}")
|
282
|
-
|
312
|
+
|
283
313
|
# Use loop_til_valid_input to get a valid integer within the correct range
|
284
314
|
choice = loop_til_valid_input(
|
285
|
-
input_text="Enter the number of the key you'd like to use: ",
|
286
|
-
bad_text="That's not a valid choice, please try again.",
|
287
|
-
Class=int # Ensuring input is an integer
|
315
|
+
input_text="Enter the number of the key you'd like to use: ",
|
316
|
+
bad_text="That's not a valid choice, please try again.",
|
317
|
+
Class=int, # Ensuring input is an integer
|
288
318
|
)
|
289
319
|
|
290
320
|
# Since loop_til_valid_input ensures valid input, just return the selected key
|
291
321
|
if 1 <= choice <= len(keys):
|
292
322
|
return keys[choice - 1] # Fetch the key using 0-based index
|
293
|
-
|
323
|
+
|
294
324
|
return Key(KeyCode=None)
|
295
325
|
|
296
326
|
|
297
327
|
def Move(move):
|
298
328
|
global player
|
299
329
|
|
300
|
-
|
301
330
|
def attempt_charter():
|
302
331
|
global player
|
303
332
|
if player.money >= 10:
|
304
333
|
player.money -= 10
|
305
|
-
if
|
306
|
-
ROOMS[newRoom][
|
307
|
-
return ROOMS[player.CURRENTROOM][
|
334
|
+
if "descovered" in ROOMS[newRoom] and not ROOMS[newRoom]["descovered"]:
|
335
|
+
ROOMS[newRoom]["descovered"] = True
|
336
|
+
return ROOMS[player.CURRENTROOM]["directions"][move]
|
308
337
|
else:
|
309
|
-
type_text(
|
338
|
+
type_text(
|
339
|
+
"You don't have enough money to charter a ship.", colorTrue=color_coding
|
340
|
+
)
|
310
341
|
return player.CURRENTROOM
|
311
342
|
|
312
343
|
def attempt_move_to_garden():
|
313
344
|
global player
|
314
345
|
key = PickKey(Lock("629.IdnXwnt"))
|
315
346
|
if key.GetKeyCode() == "629.IdnXwnt":
|
316
|
-
End(
|
347
|
+
End("You unlock the gate to the garden with the key!")
|
317
348
|
return newRoom
|
318
|
-
type_text(
|
349
|
+
type_text("The gate is locked.", colorTrue=color_coding)
|
319
350
|
return newRoom
|
320
351
|
|
321
352
|
def move_to_room():
|
322
353
|
global player
|
323
354
|
player.LASTROOM = player.CURRENTROOM
|
324
|
-
if
|
325
|
-
ROOMS[newRoom][
|
326
|
-
if move ==
|
355
|
+
if "descovered" in ROOMS[newRoom] and not ROOMS[newRoom]["descovered"]:
|
356
|
+
ROOMS[newRoom]["descovered"] = True
|
357
|
+
if move == "0":
|
327
358
|
return attempt_charter()
|
328
|
-
elif newRoom ==
|
359
|
+
elif newRoom == "Garden":
|
329
360
|
return attempt_move_to_garden()
|
330
361
|
else:
|
331
362
|
return newRoom
|
332
363
|
|
333
|
-
if move in ROOMS[player.CURRENTROOM][
|
364
|
+
if move in ROOMS[player.CURRENTROOM]["directions"]:
|
334
365
|
newRoom = "Hall"
|
335
|
-
if isinstance(ROOMS[player.CURRENTROOM][
|
336
|
-
if isinstance(ROOMS[player.CURRENTROOM][
|
337
|
-
key = PickKey(ROOMS[player.CURRENTROOM][
|
338
|
-
ROOMS[player.CURRENTROOM][
|
339
|
-
newRoom = ROOMS[player.CURRENTROOM][
|
366
|
+
if isinstance(ROOMS[player.CURRENTROOM]["directions"][move], Door):
|
367
|
+
if isinstance(ROOMS[player.CURRENTROOM]["directions"][move].lock, Lock):
|
368
|
+
key = PickKey(ROOMS[player.CURRENTROOM]["directions"][move].lock)
|
369
|
+
ROOMS[player.CURRENTROOM]["directions"][move].Unlock(key, player)
|
370
|
+
newRoom = ROOMS[player.CURRENTROOM]["directions"][move].GetRoom(
|
371
|
+
player.CURRENTROOM
|
372
|
+
)
|
340
373
|
else:
|
341
|
-
newRoom = ROOMS[player.CURRENTROOM][
|
374
|
+
newRoom = ROOMS[player.CURRENTROOM]["directions"][move]
|
342
375
|
newRoom = move_to_room()
|
343
376
|
player.CURRENTROOM = newRoom
|
344
377
|
return
|
345
378
|
elif move in ROOMS:
|
346
379
|
newRoom = move
|
347
|
-
if newRoom ==
|
380
|
+
if newRoom == "Garden":
|
348
381
|
newRoom = attempt_move_to_garden()
|
349
382
|
player.LASTROOM = player.CURRENTROOM
|
350
383
|
player.CURRENTROOM = newRoom
|
351
|
-
if
|
352
|
-
for randomEvent in ROOMS[player.CURRENTROOM][
|
384
|
+
if "random_events" in ROOMS[player.CURRENTROOM]:
|
385
|
+
for randomEvent in ROOMS[player.CURRENTROOM]["random_events"]:
|
353
386
|
if isinstance(randomEvent, RandomEvent):
|
354
387
|
randomEvent.check_and_trigger(player)
|
355
388
|
return
|
@@ -359,7 +392,10 @@ def Move(move):
|
|
359
392
|
def start():
|
360
393
|
global player
|
361
394
|
# shows the main menu
|
362
|
-
type_text(
|
395
|
+
type_text(
|
396
|
+
f"\nHello %*MAGENTA*%{player.name}%*RESET*% and welcome to my Role Playing Game. \nI hope you have fun!",
|
397
|
+
colorTrue=color_coding,
|
398
|
+
)
|
363
399
|
showInstructions()
|
364
400
|
|
365
401
|
|
@@ -367,77 +403,82 @@ def showStatus():
|
|
367
403
|
global player
|
368
404
|
|
369
405
|
# Display player's current status
|
370
|
-
text = f
|
371
|
-
|
406
|
+
text = f"\n---------------------------"
|
407
|
+
|
372
408
|
# Display the current inventory
|
373
|
-
the_inventory = [
|
409
|
+
the_inventory = [
|
410
|
+
itemnum.name for itemnum in player.inventory if isinstance(itemnum, item)
|
411
|
+
]
|
374
412
|
text += f'\nInventory: %*BLUE*%{", ".join(the_inventory)}%*RESET*%; Money: {player.money}; XP: {player.xp}; Level: {player.Level}'
|
375
|
-
|
413
|
+
|
376
414
|
# Display possible directions of travel
|
377
415
|
text = display_directions(text)
|
378
416
|
|
379
417
|
# Display the map if available
|
380
|
-
if
|
418
|
+
if "map" in ROOMS[player.CURRENTROOM]:
|
381
419
|
text += f'\n\nKey: {"; ".join(KEY)}\n'
|
382
420
|
text += f'\n{ROOMS[player.CURRENTROOM]["map"]}\n'
|
383
421
|
|
384
422
|
# Display the description of the current room
|
385
|
-
text +=
|
423
|
+
text += "\n" + str(ROOMS[player.CURRENTROOM]["info"])
|
386
424
|
|
387
425
|
text += f"\n---------------------------"
|
388
|
-
|
426
|
+
|
389
427
|
type_text(text, colorTrue=color_coding)
|
390
|
-
|
428
|
+
|
391
429
|
# Optionally display additional room description
|
392
|
-
if
|
430
|
+
if "description" in ROOMS[player.CURRENTROOM] and ask_for_consent(
|
431
|
+
"Do you want to observe the area"
|
432
|
+
):
|
393
433
|
type_text("The area:", colorTrue=color_coding)
|
394
|
-
type_text(ROOMS[player.CURRENTROOM][
|
434
|
+
type_text(ROOMS[player.CURRENTROOM]["description"], colorTrue=color_coding)
|
395
435
|
|
396
436
|
|
397
437
|
def display_directions(text):
|
398
438
|
global player
|
399
|
-
directions = [
|
439
|
+
directions = ["north", "east", "south", "west", "up", "down", "teleport"]
|
400
440
|
direction_descriptions = {
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
441
|
+
"house": {
|
442
|
+
"north": "There is a door to the",
|
443
|
+
"east": "There is a door to the",
|
444
|
+
"south": "There is a door to the",
|
445
|
+
"west": "There is a door to the",
|
446
|
+
"up": "There is a staircase leading",
|
447
|
+
"down": "There is a staircase leading",
|
408
448
|
},
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
449
|
+
"forest": {
|
450
|
+
"north": "There is a path to the",
|
451
|
+
"east": "There is a path to the",
|
452
|
+
"south": "There is a path to the",
|
453
|
+
"west": "There is a path to the",
|
454
|
+
"up": "There is a ladder going",
|
455
|
+
"down": "There is a hole in the ground leading",
|
416
456
|
},
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
457
|
+
"cavern": {
|
458
|
+
"north": "There is a tunel to the",
|
459
|
+
"east": "There is a tunel to the",
|
460
|
+
"south": "There is a tunel to the",
|
461
|
+
"west": "There is a tunel to the",
|
462
|
+
"up": "There is a shoot with handhold going",
|
463
|
+
"down": "There is a shoot in the ground going",
|
424
464
|
},
|
425
465
|
}
|
426
466
|
|
427
|
-
room_type = ROOMS[player.CURRENTROOM][
|
467
|
+
room_type = ROOMS[player.CURRENTROOM]["room type"]
|
428
468
|
if room_type in direction_descriptions:
|
429
469
|
for direction in directions:
|
430
|
-
if direction in ROOMS[player.CURRENTROOM][
|
431
|
-
if direction !=
|
432
|
-
text += f
|
470
|
+
if direction in ROOMS[player.CURRENTROOM]["directions"]:
|
471
|
+
if direction != "teleport":
|
472
|
+
text += f"\n{direction_descriptions[room_type][direction]} %*GREEN*%{direction}%*RESET*%."
|
433
473
|
|
434
|
-
if
|
474
|
+
if "teleport" in ROOMS[player.CURRENTROOM]["directions"]:
|
435
475
|
text += "\nThere is a %*GREEN*%teleport%*RESET*%ation circle on the ground."
|
436
476
|
|
437
477
|
return text
|
438
478
|
|
479
|
+
|
439
480
|
def Examine(*Args):
|
440
|
-
Name =
|
481
|
+
Name = " ".join(Args)
|
441
482
|
item_index = player.inventory.index(Name) # Store the result of index in a variable
|
442
483
|
|
443
484
|
if item_index is not None: # Check explicitly if item_index is valid
|
@@ -445,30 +486,46 @@ def Examine(*Args):
|
|
445
486
|
if isinstance(_, item):
|
446
487
|
type_text("You look at your item and you figure out this about it:")
|
447
488
|
if not revealer.reveal_key_code(_):
|
448
|
-
if _.type ==
|
489
|
+
if _.type == "weapon":
|
449
490
|
type_text(f"This item is a weapon that adds {_.value} damage.")
|
450
|
-
elif _.type ==
|
451
|
-
if
|
491
|
+
elif _.type == "readable":
|
492
|
+
if "reading" in player.Skills:
|
452
493
|
type_text(f"You read {_.name} and it contains:")
|
453
494
|
if isinstance(_, Book):
|
454
495
|
type_text(_.GetContense())
|
455
496
|
else:
|
456
497
|
type_text(_.value)
|
457
|
-
elif Name in ROOMS[player.CURRENTROOM][
|
458
|
-
door = ROOMS[player.CURRENTROOM][
|
498
|
+
elif Name in ROOMS[player.CURRENTROOM]["directions"]: # Check exits in the room
|
499
|
+
door = ROOMS[player.CURRENTROOM]["directions"][Name]
|
459
500
|
if isinstance(door, Door):
|
460
501
|
if isinstance(door.lock, Lock):
|
461
|
-
type_text(
|
502
|
+
type_text(
|
503
|
+
(
|
504
|
+
"The door is locked,"
|
505
|
+
if door.lock.is_locked
|
506
|
+
else "The door is not locked,"
|
507
|
+
),
|
508
|
+
"you know this about its key code:",
|
509
|
+
)
|
462
510
|
revealer.reveal_key_code(door)
|
463
511
|
else:
|
464
512
|
type_text(f"The exit {Name} has no lock.")
|
465
513
|
else:
|
466
514
|
type_text(f"There is nothing special about the exit {Name}.")
|
467
|
-
elif
|
468
|
-
|
515
|
+
elif (
|
516
|
+
Name in ROOMS[player.CURRENTROOM]["containers"]
|
517
|
+
): # Check containers in the room
|
518
|
+
containerins = ROOMS[player.CURRENTROOM]["containers"][Name]
|
469
519
|
if isinstance(containerins, container):
|
470
520
|
if isinstance(containerins.lock, Lock):
|
471
|
-
type_text(
|
521
|
+
type_text(
|
522
|
+
(
|
523
|
+
"The container is locked,"
|
524
|
+
if containerins.lock.is_locked
|
525
|
+
else "The container is not locked,"
|
526
|
+
),
|
527
|
+
"you know this about its key code:",
|
528
|
+
)
|
472
529
|
revealer.reveal_key_code(containerins)
|
473
530
|
else:
|
474
531
|
type_text(f"The container {Name} has no lock.")
|
@@ -477,6 +534,7 @@ def Examine(*Args):
|
|
477
534
|
else:
|
478
535
|
type_text(f"There is nothing special about the {Name}.")
|
479
536
|
|
537
|
+
|
480
538
|
def battle(player: PC, good_guys: list, bad_guys: list, last_room):
|
481
539
|
"""
|
482
540
|
Simulate a battle between the player (and allies) and monsters.
|
@@ -515,7 +573,7 @@ def battle(player: PC, good_guys: list, bad_guys: list, last_room):
|
|
515
573
|
monster_turn(target, monster)
|
516
574
|
|
517
575
|
if player.hp <= 0:
|
518
|
-
End(f
|
576
|
+
End(f"The monsters defeat you!", win=False)
|
519
577
|
return good_guys, bad_guys
|
520
578
|
|
521
579
|
return good_guys, bad_guys
|
@@ -530,11 +588,11 @@ def player_turn(player: PC, monster: creature):
|
|
530
588
|
monster (creature): The monster being fought.
|
531
589
|
"""
|
532
590
|
player_action = loop_til_valid_input(
|
533
|
-
"Choose your action: (attack/defend/special): ",
|
534
|
-
"Invalid action. Please enter a valid action.",
|
535
|
-
PC_action
|
591
|
+
"Choose your action: (attack/defend/special): ",
|
592
|
+
"Invalid action. Please enter a valid action.",
|
593
|
+
PC_action,
|
536
594
|
).value.lower()
|
537
|
-
|
595
|
+
|
538
596
|
if player_action == "attack":
|
539
597
|
perform_attack(player, monster)
|
540
598
|
elif player_action == "defend":
|
@@ -596,16 +654,16 @@ def calculate_damage(attacker, defender) -> int:
|
|
596
654
|
"""
|
597
655
|
damage_min, damage_max = calculate_damage_range(attacker.atpw)
|
598
656
|
damage = randint(damage_min, damage_max)
|
599
|
-
|
657
|
+
|
600
658
|
if random() < attacker.crit_chance:
|
601
659
|
damage *= 2
|
602
660
|
type_text("Critical hit!", colorTrue=color_coding)
|
603
|
-
|
604
|
-
if hasattr(defender,
|
661
|
+
|
662
|
+
if hasattr(defender, "defending") and defender.defending:
|
605
663
|
damage //= 2
|
606
664
|
type_text("The attack is defended, reducing damage.", colorTrue=color_coding)
|
607
665
|
defender.defending = False
|
608
|
-
|
666
|
+
|
609
667
|
return damage
|
610
668
|
|
611
669
|
|
@@ -636,7 +694,10 @@ def use_special_ability(player: PC, monster: creature):
|
|
636
694
|
"""
|
637
695
|
if player.special_ability.ready:
|
638
696
|
player.special_ability.activate(monster)
|
639
|
-
type_text(
|
697
|
+
type_text(
|
698
|
+
f"You use your special ability: {player.special_ability.name}.",
|
699
|
+
colorTrue=color_coding,
|
700
|
+
)
|
640
701
|
player.special_ability.ready = False
|
641
702
|
else:
|
642
703
|
type_text("Your special ability is not ready yet.", colorTrue=color_coding)
|
@@ -661,7 +722,7 @@ def select_target(chooser, targets: list):
|
|
661
722
|
if enemy.hp > 0:
|
662
723
|
type_text(f"{index + 1}: {enemy.name} ({enemy.hp} HP)")
|
663
724
|
valid_targets.append(index)
|
664
|
-
|
725
|
+
|
665
726
|
# Prompt the player to select a target
|
666
727
|
while True:
|
667
728
|
try:
|
@@ -679,43 +740,48 @@ def select_target(chooser, targets: list):
|
|
679
740
|
return target
|
680
741
|
|
681
742
|
|
682
|
-
|
683
743
|
def command():
|
684
|
-
|
685
|
-
#try:
|
686
|
-
|
744
|
+
global player
|
745
|
+
# try:
|
746
|
+
ShouldBreak = False
|
687
747
|
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
else:
|
702
|
-
commands[action](player)
|
703
|
-
elif targets:
|
704
|
-
commands[action](*targets)
|
748
|
+
while True:
|
749
|
+
showStatus()
|
750
|
+
user_input = get_player_input(False)
|
751
|
+
|
752
|
+
if user_input:
|
753
|
+
commands_list = user_input.split(",")
|
754
|
+
for command_str in commands_list:
|
755
|
+
action, targets = parse_command(command_str.strip(), commands)
|
756
|
+
|
757
|
+
if action in commands:
|
758
|
+
if has_named_arg(commands[action], "player"):
|
759
|
+
if targets:
|
760
|
+
commands[action](player, *targets)
|
705
761
|
else:
|
706
|
-
commands[action]()
|
762
|
+
commands[action](player)
|
763
|
+
elif targets:
|
764
|
+
commands[action](*targets)
|
707
765
|
else:
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
766
|
+
commands[action]()
|
767
|
+
else:
|
768
|
+
type_text(
|
769
|
+
f"Unknown command '{action}'. Type 'help' for a list of commands.",
|
770
|
+
colorTrue=color_coding,
|
771
|
+
)
|
772
|
+
if action in commands:
|
773
|
+
ShouldBreak = True
|
774
|
+
if ShouldBreak:
|
775
|
+
return
|
776
|
+
|
777
|
+
|
778
|
+
# except KeyError as e:
|
779
|
+
# type_text(f"KeyError: {e} - This might be due to an undefined command or incorrect arguments.", colorTrue=color_coding)
|
780
|
+
# except ValueError as e:
|
781
|
+
# type_text(f"ValueError: {e} - This might be due to incorrect arguments provided.", colorTrue=color_coding)
|
782
|
+
# except Exception as e:
|
783
|
+
# type_text(f"Unexpected Error: {e}", colorTrue=color_coding)
|
784
|
+
|
719
785
|
|
720
786
|
def handle_sleep_command(player: PC):
|
721
787
|
type_text("You decide to rest for a while.", colorTrue=color_coding)
|
@@ -729,80 +795,111 @@ def handle_sleep_command(player: PC):
|
|
729
795
|
# Optional: Print a message or effect that happens during sleep
|
730
796
|
type_text("You feel refreshed after a good rest.", colorTrue=color_coding)
|
731
797
|
|
732
|
-
|
798
|
+
|
799
|
+
def get_player_input(split=True):
|
733
800
|
global player
|
734
|
-
move =
|
735
|
-
while move ==
|
736
|
-
move = str(input(
|
801
|
+
move = ""
|
802
|
+
while move == "":
|
803
|
+
move = str(input(">")).strip().lower()
|
737
804
|
if split:
|
738
805
|
return move.split()
|
739
806
|
return move
|
740
807
|
|
808
|
+
|
741
809
|
def handle_go_command(direction):
|
742
810
|
global player
|
743
811
|
Move(direction)
|
744
812
|
|
813
|
+
|
745
814
|
def handle_get_command(player: PC, *Args):
|
746
815
|
item_name = " ".join(Args)
|
747
|
-
if
|
748
|
-
for ItemName in ROOMS[player.CURRENTROOM][
|
816
|
+
if "items" in ROOMS[player.CURRENTROOM]:
|
817
|
+
for ItemName in ROOMS[player.CURRENTROOM]["items"].keys():
|
749
818
|
if item_name == ItemName:
|
750
|
-
player.inventory_add([ROOMS[player.CURRENTROOM][
|
751
|
-
del ROOMS[player.CURRENTROOM][
|
752
|
-
type_text(f
|
819
|
+
player.inventory_add([ROOMS[player.CURRENTROOM]["items"][ItemName]])
|
820
|
+
del ROOMS[player.CURRENTROOM]["items"][ItemName]
|
821
|
+
type_text(f"%*BLUE*%{item_name}%*RESET*% got!", colorTrue=color_coding)
|
753
822
|
return
|
754
823
|
type_text(f"Can't get {item_name}!", colorTrue=color_coding)
|
755
824
|
|
825
|
+
|
756
826
|
def handle_look_command():
|
757
827
|
global player
|
758
828
|
should_return = False
|
759
|
-
if
|
760
|
-
type_text(
|
829
|
+
if "items" in ROOMS[player.CURRENTROOM]:
|
830
|
+
type_text(
|
831
|
+
f'The items in the room: %*BLUE*%{", ".join(ROOMS[player.CURRENTROOM]["items"].keys())}%*RESET*%.',
|
832
|
+
colorTrue=color_coding,
|
833
|
+
)
|
761
834
|
should_return = True
|
762
|
-
if
|
763
|
-
type_text(
|
835
|
+
if "containers" in ROOMS[player.CURRENTROOM]:
|
836
|
+
type_text(
|
837
|
+
f"The containers here are: %*RED*%{', '.join(ROOMS[player.CURRENTROOM]['containers'].keys())}%*RESET*%",
|
838
|
+
colorTrue=color_coding,
|
839
|
+
)
|
764
840
|
should_return = True
|
765
841
|
if should_return:
|
766
842
|
return
|
767
|
-
type_text(
|
843
|
+
type_text("There is nothing of interest.", colorTrue=color_coding)
|
844
|
+
|
768
845
|
|
769
846
|
def handle_use_command(*Args):
|
770
847
|
global player
|
771
848
|
Use(Args)
|
772
849
|
|
850
|
+
|
773
851
|
def handle_search_command(player, *Args):
|
774
852
|
Container = " ".join(Args)
|
775
|
-
if
|
776
|
-
if Container in ROOMS[player.CURRENTROOM][
|
853
|
+
if "containers" in ROOMS[player.CURRENTROOM]:
|
854
|
+
if Container in ROOMS[player.CURRENTROOM]["containers"] and not all_same_value(
|
855
|
+
ROOMS[player.CURRENTROOM]["containers"][Container].contents, None
|
856
|
+
):
|
777
857
|
search_container(player, Container)
|
778
858
|
else:
|
779
859
|
type_text(f"You cannot search the {Container}", colorTrue=color_coding)
|
780
860
|
|
861
|
+
|
781
862
|
def search_container(player: PC, Container):
|
782
863
|
ContainerName = Container
|
783
|
-
Container = ROOMS[player.CURRENTROOM][
|
864
|
+
Container = ROOMS[player.CURRENTROOM]["containers"][Container]
|
784
865
|
if isinstance(Container, container):
|
785
866
|
if isinstance(Container.lock, Lock):
|
786
867
|
key = PickKey(Container.lock)
|
787
868
|
Container.Unlock(key, player)
|
788
|
-
type_text(
|
869
|
+
type_text(
|
870
|
+
f"You search the{' secret' if Container.secret else ''} %*RED*%{ContainerName}%*RESET*% and find a ",
|
871
|
+
newline=False,
|
872
|
+
colorTrue=color_coding,
|
873
|
+
)
|
789
874
|
for searchitem in Container.contents:
|
790
875
|
if searchitem:
|
791
876
|
if isinstance(searchitem, item):
|
792
|
-
end_str =
|
793
|
-
|
877
|
+
end_str = (
|
878
|
+
" and a "
|
879
|
+
if Container.contents.index(searchitem)
|
880
|
+
< last_index(Container.contents)
|
881
|
+
else "\n"
|
882
|
+
)
|
883
|
+
type_text(
|
884
|
+
f"%*BLUE*%{searchitem.name}%*RESET*%{end_str}",
|
885
|
+
newline=False,
|
886
|
+
colorTrue=color_coding,
|
887
|
+
)
|
794
888
|
Container.take_contents(player)
|
795
889
|
|
796
890
|
|
797
891
|
def handle_put_command(player: PC, *Args):
|
798
892
|
arguments = " ".join(Args)
|
799
893
|
Arguments = arguments.split(" in ")
|
800
|
-
|
894
|
+
|
801
895
|
# Ensure we have exactly two parts
|
802
896
|
if len(Arguments) < 2:
|
803
|
-
type_text(
|
897
|
+
type_text(
|
898
|
+
"You need to specify an item and where to put it (e.g., 'put book in drawer').",
|
899
|
+
colorTrue=color_coding,
|
900
|
+
)
|
804
901
|
return
|
805
|
-
|
902
|
+
|
806
903
|
# Strip whitespace
|
807
904
|
Arguments = [arg.strip() for arg in Arguments]
|
808
905
|
item_name = Arguments[0]
|
@@ -810,35 +907,48 @@ def handle_put_command(player: PC, *Args):
|
|
810
907
|
|
811
908
|
# Check if item is in inventory
|
812
909
|
if item_name not in [item.name for item in player.inventory]:
|
813
|
-
type_text(
|
910
|
+
type_text(
|
911
|
+
f"You don't have {item_name} in your inventory.", colorTrue=color_coding
|
912
|
+
)
|
814
913
|
return
|
815
914
|
|
816
915
|
# Retrieve item and container
|
817
|
-
PutItem = player.inventory[
|
818
|
-
|
916
|
+
PutItem = player.inventory[
|
917
|
+
[item.name for item in player.inventory].index(item_name)
|
918
|
+
]
|
919
|
+
if "containers" in ROOMS[player.CURRENTROOM]:
|
819
920
|
put_in_container(player, PutItem, container_name)
|
820
921
|
else:
|
821
|
-
type_text(
|
922
|
+
type_text(
|
923
|
+
f"You cannot put the {PutItem.name} in the {container_name}",
|
924
|
+
colorTrue=color_coding,
|
925
|
+
)
|
822
926
|
|
823
927
|
|
824
|
-
def put_in_container(player: PC, PutItem
|
928
|
+
def put_in_container(player: PC, PutItem=None, container=None):
|
825
929
|
player.inventory.remove(PutItem.name)
|
826
|
-
if not ROOMS[player.CURRENTROOM][
|
827
|
-
ROOMS[player.CURRENTROOM][
|
828
|
-
if not isinstance(
|
829
|
-
ROOMS[player.CURRENTROOM][
|
830
|
-
|
831
|
-
|
832
|
-
|
930
|
+
if not ROOMS[player.CURRENTROOM]["containers"][container].contents:
|
931
|
+
ROOMS[player.CURRENTROOM]["containers"][container].contents = []
|
932
|
+
if not isinstance(
|
933
|
+
ROOMS[player.CURRENTROOM]["containers"][container].contents, list
|
934
|
+
):
|
935
|
+
ROOMS[player.CURRENTROOM]["containers"][container].contents = [
|
936
|
+
ROOMS[player.CURRENTROOM]["containers"][container].contents
|
937
|
+
]
|
938
|
+
ROOMS[player.CURRENTROOM]["containers"][container].contents += [PutItem]
|
939
|
+
type_text(
|
940
|
+
f"You put you're %*BLUE*%{PutItem.name}%*RESET*% into the %*RED*%{container}%*RESET*%",
|
941
|
+
colorTrue=color_coding,
|
942
|
+
)
|
833
943
|
|
834
944
|
|
835
945
|
def handle_get_quest_command(questnum):
|
836
946
|
global player
|
837
|
-
if
|
838
|
-
if questnum in ROOMS[player.CURRENTROOM][
|
839
|
-
quest_manager.add_quest(ROOMS[player.CURRENTROOM][
|
840
|
-
quest_manager.start_quest(ROOMS[player.CURRENTROOM][
|
841
|
-
del ROOMS[player.CURRENTROOM][
|
947
|
+
if "quests" in ROOMS[player.CURRENTROOM]:
|
948
|
+
if questnum in ROOMS[player.CURRENTROOM]["quests"]:
|
949
|
+
quest_manager.add_quest(ROOMS[player.CURRENTROOM]["quests"][questnum])
|
950
|
+
quest_manager.start_quest(ROOMS[player.CURRENTROOM]["quests"][questnum])
|
951
|
+
del ROOMS[player.CURRENTROOM]["quests"][questnum]
|
842
952
|
|
843
953
|
|
844
954
|
def PrintMap():
|
@@ -849,72 +959,93 @@ def PrintMap():
|
|
849
959
|
# Define handling functions for different types of enemies
|
850
960
|
def handle_hungry_bear(player: PC, enemy: creature):
|
851
961
|
enemy_reacting = True
|
852
|
-
if
|
962
|
+
if "potion" in player.inventory:
|
853
963
|
if ask_for_consent("Do you want to throw your potion at the bear"):
|
854
964
|
enemy_reacting = False
|
855
|
-
del player.inventory[player.inventory.index(
|
856
|
-
type_text(
|
965
|
+
del player.inventory[player.inventory.index("potion")]
|
966
|
+
type_text(
|
967
|
+
f"You throw the potion at the bear and it explodes into a puff of magic smoke that stuns the bear!",
|
968
|
+
colorTrue=color_coding,
|
969
|
+
)
|
857
970
|
if enemy_reacting:
|
858
971
|
return [enemy, enemy_reacting]
|
859
972
|
|
973
|
+
|
860
974
|
def handle_grumpy_pig(player: PC, enemy: creature):
|
861
975
|
enemy_reacting = True
|
862
|
-
if
|
976
|
+
if "saddle" in player.inventory and "pig-rod" in player.inventory:
|
863
977
|
if ask_for_consent("Do you want to use your saddle and pig-rod on the pig"):
|
864
978
|
enemy_reacting = False
|
865
|
-
type_text(
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
player.
|
979
|
+
type_text(
|
980
|
+
f"You throw a saddle onto the pig and leap on steering it about with a pig fishing rod!",
|
981
|
+
colorTrue=color_coding,
|
982
|
+
)
|
983
|
+
del ROOMS[player.CURRENTROOM]["creatures stats"]
|
984
|
+
del player.inventory[player.inventory.index("saddle")]
|
985
|
+
del player.inventory[player.inventory.index("pig-rod")]
|
986
|
+
player.inventory_add(item["pig-steed"])
|
870
987
|
player.xp += 20
|
871
|
-
if
|
988
|
+
if "torch" in player.inventory:
|
872
989
|
if ask_for_consent("Do you want to use your torch to scare the pig away"):
|
873
990
|
enemy_reacting = False
|
874
|
-
type_text(
|
875
|
-
|
991
|
+
type_text(
|
992
|
+
f"You wave your torch at the pig and it runs away through a tiny open window.",
|
993
|
+
colorTrue=color_coding,
|
994
|
+
)
|
995
|
+
del ROOMS[player.CURRENTROOM]["creatures stats"][
|
996
|
+
ROOMS[player.CURRENTROOM]["creatures stats"].index(enemy)
|
997
|
+
]
|
876
998
|
player.xp += 5
|
877
|
-
if
|
999
|
+
if "rations" in player.inventory:
|
878
1000
|
if ask_for_consent("Do you want to throw your ration at the pig"):
|
879
1001
|
enemy_reacting = False
|
880
|
-
type_text(
|
881
|
-
|
1002
|
+
type_text(
|
1003
|
+
f"You quickly throw rations at the pig. It still doesn't look happy though.",
|
1004
|
+
colorTrue=color_coding,
|
1005
|
+
)
|
1006
|
+
del player.inventory[player.inventory.index("rations")]
|
882
1007
|
player.xp += 15
|
883
1008
|
|
884
1009
|
if enemy_reacting:
|
885
1010
|
return [enemy, enemy_reacting]
|
886
1011
|
|
1012
|
+
|
887
1013
|
def handle_greedy_goblin(player: PC, enemy: creature):
|
888
1014
|
enemy_reacting = True
|
889
1015
|
if player.money >= 15:
|
890
1016
|
if ask_for_consent("Do you want to pay the goblin to not attack you"):
|
891
1017
|
enemy_reacting = False
|
892
|
-
type_text(
|
1018
|
+
type_text(
|
1019
|
+
f"You pay the {enemy.name} to not attack you for now, but he says you should run.",
|
1020
|
+
colorTrue=color_coding,
|
1021
|
+
)
|
893
1022
|
player.money -= 15
|
894
1023
|
enemy.dropped_items[1].value += 15
|
895
1024
|
if enemy_reacting:
|
896
1025
|
return [enemy, enemy_reacting]
|
897
1026
|
|
1027
|
+
|
898
1028
|
commands = {
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
1029
|
+
"go": handle_go_command,
|
1030
|
+
"get quest": handle_get_quest_command,
|
1031
|
+
"get": handle_get_command,
|
1032
|
+
"look": handle_look_command,
|
1033
|
+
"use": handle_use_command,
|
1034
|
+
"search": handle_search_command,
|
1035
|
+
"quit": quit,
|
1036
|
+
"help": showInstructions,
|
1037
|
+
"hint": showHint,
|
1038
|
+
"sleep": handle_sleep_command,
|
1039
|
+
"put": handle_put_command,
|
1040
|
+
"map": PrintMap,
|
1041
|
+
"examine": Examine,
|
912
1042
|
}
|
913
1043
|
|
914
1044
|
|
915
1045
|
def quit():
|
916
1046
|
exit()
|
917
1047
|
|
1048
|
+
|
918
1049
|
guards = [
|
919
1050
|
Guard(
|
920
1051
|
name="Guard",
|
@@ -922,10 +1053,10 @@ guards = [
|
|
922
1053
|
atpw=4,
|
923
1054
|
description="A 5'8\" human guard who looks like he doesn't belong here.",
|
924
1055
|
flavor_text="A human guard spots you and says: 'You shouldn't be here.'",
|
925
|
-
type=creature_type(
|
1056
|
+
type=creature_type("humanoid", "human"),
|
926
1057
|
current_room="Bedroom",
|
927
1058
|
patrol_route=["Bedroom", "Office", "Tower Bottom", "Landing", "Bedroom"],
|
928
|
-
patrol_type=
|
1059
|
+
patrol_type="normal",
|
929
1060
|
),
|
930
1061
|
Guard(
|
931
1062
|
name="Wolf",
|
@@ -933,36 +1064,38 @@ guards = [
|
|
933
1064
|
atpw=4,
|
934
1065
|
description="A large wolf with blood covering its face.",
|
935
1066
|
flavor_text="A wolf spots you and growls.",
|
936
|
-
type=creature_type(
|
1067
|
+
type=creature_type("beast", "wolf"),
|
937
1068
|
current_room="Balcony",
|
938
|
-
patrol_type=
|
939
|
-
frendly_text="The wolf nuzzles you"
|
1069
|
+
patrol_type="random",
|
1070
|
+
frendly_text="The wolf nuzzles you",
|
940
1071
|
),
|
941
1072
|
]
|
942
1073
|
|
1074
|
+
|
943
1075
|
def handle_wolf(player: PC, wolf: Guard):
|
944
1076
|
enemy_reacting = True
|
945
|
-
if
|
1077
|
+
if "rations" in player.inventory:
|
946
1078
|
if ask_for_consent("Do you want to give your ration to the wolf"):
|
947
1079
|
enemy_reacting = False
|
948
1080
|
type_text(
|
949
|
-
"You quickly give your rations to the wolf. It looks happy, walks up to you, and nuzzles you.",
|
950
|
-
colorTrue=color_coding
|
1081
|
+
"You quickly give your rations to the wolf. It looks happy, walks up to you, and nuzzles you.",
|
1082
|
+
colorTrue=color_coding,
|
951
1083
|
)
|
952
|
-
player.inventory.remove(
|
1084
|
+
player.inventory.remove("rations")
|
953
1085
|
wolf.patrol_type = "follow"
|
954
1086
|
wolf.frendly = True
|
955
1087
|
return wolf
|
956
1088
|
if enemy_reacting:
|
957
1089
|
return [wolf, enemy_reacting]
|
958
1090
|
|
1091
|
+
|
959
1092
|
def handle_guard_action(guard):
|
960
1093
|
# Dynamically build the function name
|
961
1094
|
function_name = f"handle_{guard.name.lower()}"
|
962
|
-
|
1095
|
+
|
963
1096
|
# Use globals() to retrieve the function by name
|
964
1097
|
function_to_call = globals().get(function_name)
|
965
|
-
|
1098
|
+
|
966
1099
|
if function_to_call:
|
967
1100
|
# Call the found function
|
968
1101
|
guard = function_to_call(player, guard)
|
@@ -970,46 +1103,69 @@ def handle_guard_action(guard):
|
|
970
1103
|
else:
|
971
1104
|
return [False, [guard, True]] # Function was not found
|
972
1105
|
|
1106
|
+
|
973
1107
|
def initializer():
|
974
1108
|
global color_coding, player, CHARACTERSLIST
|
975
1109
|
df = pd.DataFrame(CHARACTERSLIST)
|
976
|
-
Standord_Player = loop_til_valid_input(
|
1110
|
+
Standord_Player = loop_til_valid_input(
|
1111
|
+
"Do you want to use a premade character?", "you didn't answer Y or N.", Y_N
|
1112
|
+
).value
|
977
1113
|
|
978
1114
|
if Standord_Player:
|
979
1115
|
while True:
|
980
1116
|
type_text("Who do you want to play as?", colorTrue=False)
|
981
1117
|
print(df)
|
982
1118
|
selected_character = loop_til_valid_input(
|
983
|
-
"Who do you want to play as? (please select the number to the left of there stats)",
|
984
|
-
"That wasn't one of the characters. Please choose one.",
|
985
|
-
int
|
1119
|
+
"Who do you want to play as? (please select the number to the left of there stats)",
|
1120
|
+
"That wasn't one of the characters. Please choose one.",
|
1121
|
+
int,
|
986
1122
|
)
|
987
1123
|
lstIndex = last_index(CHARACTERSLIST)
|
988
1124
|
if selected_character <= lstIndex:
|
989
1125
|
character_info = CHARACTERSLIST[selected_character]
|
990
|
-
name = character_info[
|
991
|
-
age = character_info[
|
992
|
-
height = character_info[
|
993
|
-
weight = character_info[
|
1126
|
+
name = character_info["name"]
|
1127
|
+
age = character_info["age"]
|
1128
|
+
height = character_info["height"]
|
1129
|
+
weight = character_info["weight(LBs)"]
|
994
1130
|
break
|
995
1131
|
else:
|
996
1132
|
type_text(colorTrue=False)
|
997
1133
|
|
998
1134
|
else:
|
999
|
-
type_text(
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1135
|
+
type_text(
|
1136
|
+
"You will now have to enter a name, age, height, and weight. Please enter the height in this format: _ft _. These will be used throughout the game.",
|
1137
|
+
colorTrue=False,
|
1138
|
+
)
|
1139
|
+
|
1140
|
+
name = loop_til_valid_input(
|
1141
|
+
"What is your name?",
|
1142
|
+
"You didn't enter a string. Please enter a string.",
|
1143
|
+
str,
|
1144
|
+
)
|
1145
|
+
age = loop_til_valid_input(
|
1146
|
+
"What is your age (in whole years)?",
|
1147
|
+
"You didn't enter an integer. Please enter an integer.",
|
1148
|
+
int,
|
1149
|
+
)
|
1150
|
+
height = loop_til_valid_input(
|
1151
|
+
"What is your height?",
|
1152
|
+
"You didn't enter your height in the correct format. Please enter your height in the correct format.",
|
1153
|
+
Height,
|
1154
|
+
)
|
1155
|
+
weight = loop_til_valid_input(
|
1156
|
+
"What is your weight (in lbs)?",
|
1157
|
+
"You didn't enter an integer. Please enter an integer.",
|
1158
|
+
int,
|
1159
|
+
)
|
1160
|
+
|
1161
|
+
color_coding = loop_til_valid_input(
|
1162
|
+
"Do you want color coding (Y/N)?", "you didn't answer Y or N.", Y_N
|
1163
|
+
).value
|
1008
1164
|
|
1009
1165
|
background_name = []
|
1010
1166
|
background_skills = []
|
1011
1167
|
|
1012
|
-
while True:
|
1168
|
+
while True:
|
1013
1169
|
type_text("") # Prints an empty line
|
1014
1170
|
type_text("0. Random")
|
1015
1171
|
|
@@ -1019,8 +1175,12 @@ def initializer():
|
|
1019
1175
|
type_text(f"{idx + 1}. {background_name} - {formatted_skills}")
|
1020
1176
|
|
1021
1177
|
# Prompt the user to pick a background by number.
|
1022
|
-
background = loop_til_valid_input(
|
1023
|
-
|
1178
|
+
background = loop_til_valid_input(
|
1179
|
+
"What background do you want? (please select the number to the left of them)",
|
1180
|
+
"You didn't pick one",
|
1181
|
+
int,
|
1182
|
+
)
|
1183
|
+
|
1024
1184
|
length = len(BACKGROUNDS)
|
1025
1185
|
if 1 <= background <= length:
|
1026
1186
|
# Get the background name and skills based on user choice.
|
@@ -1035,24 +1195,23 @@ def initializer():
|
|
1035
1195
|
else:
|
1036
1196
|
type_text("You didn't pick one")
|
1037
1197
|
|
1038
|
-
|
1039
1198
|
# start the player in the Hall and sets up everything else
|
1040
1199
|
player = PC(
|
1041
1200
|
name,
|
1042
1201
|
age,
|
1043
1202
|
background,
|
1044
1203
|
1,
|
1045
|
-
|
1204
|
+
"Soldier",
|
1046
1205
|
height,
|
1047
1206
|
weight,
|
1048
|
-
CURRENTROOM=
|
1207
|
+
CURRENTROOM="Hall",
|
1049
1208
|
Skills=background_skills,
|
1050
1209
|
)
|
1051
1210
|
|
1211
|
+
|
1052
1212
|
def main():
|
1053
1213
|
global player, color_coding
|
1054
1214
|
|
1055
|
-
|
1056
1215
|
# this is the initializer
|
1057
1216
|
initializer()
|
1058
1217
|
|
@@ -1063,8 +1222,8 @@ def main():
|
|
1063
1222
|
while True:
|
1064
1223
|
command()
|
1065
1224
|
|
1066
|
-
if
|
1067
|
-
for event in ROOMS[player.CURRENTROOM][
|
1225
|
+
if "random_events" in ROOMS[player.CURRENTROOM]:
|
1226
|
+
for event in ROOMS[player.CURRENTROOM]["random_events"]:
|
1068
1227
|
if isinstance(event, RandomEvent):
|
1069
1228
|
event.check_and_trigger(player)
|
1070
1229
|
|
@@ -1086,7 +1245,11 @@ def main():
|
|
1086
1245
|
guard_handled = [guard_handled]
|
1087
1246
|
|
1088
1247
|
# Get is_reacting from guard_handled
|
1089
|
-
is_reacting =
|
1248
|
+
is_reacting = (
|
1249
|
+
guard_handled[1][1]
|
1250
|
+
if isinstance(guard_handled[1], list)
|
1251
|
+
else True
|
1252
|
+
)
|
1090
1253
|
|
1091
1254
|
# Only update guard if the guard is reacting
|
1092
1255
|
if is_reacting:
|
@@ -1096,14 +1259,20 @@ def main():
|
|
1096
1259
|
bad_guys.append(guard)
|
1097
1260
|
|
1098
1261
|
if guard_handled[0]:
|
1099
|
-
guards[guards.index(guard)] =
|
1262
|
+
guards[guards.index(guard)] = (
|
1263
|
+
guard_handled[1][0]
|
1264
|
+
if isinstance(guard_handled[1], list)
|
1265
|
+
else guard_handled[1]
|
1266
|
+
)
|
1100
1267
|
|
1101
1268
|
# Handle creatures in the current room
|
1102
|
-
if
|
1269
|
+
if "creatures stats" in ROOMS[player.CURRENTROOM]:
|
1103
1270
|
is_reactings = []
|
1104
|
-
enemies = ROOMS[player.CURRENTROOM][
|
1271
|
+
enemies = ROOMS[player.CURRENTROOM]["creatures stats"]
|
1105
1272
|
if not isinstance(enemies, list):
|
1106
|
-
enemies = [
|
1273
|
+
enemies = [
|
1274
|
+
enemies
|
1275
|
+
] # Ensure enemies is a list even if there's only one creature
|
1107
1276
|
|
1108
1277
|
for enemy in enemies:
|
1109
1278
|
if isinstance(enemy, creature):
|
@@ -1113,11 +1282,11 @@ def main():
|
|
1113
1282
|
enemy.type_text_description()
|
1114
1283
|
|
1115
1284
|
# Handle specific creatures
|
1116
|
-
if enemy.name ==
|
1285
|
+
if enemy.name == "hungry bear":
|
1117
1286
|
enemy_REF = handle_hungry_bear(player, enemy)
|
1118
|
-
elif enemy.name ==
|
1287
|
+
elif enemy.name == "grumpy pig":
|
1119
1288
|
enemy_REF = handle_grumpy_pig(player, enemy)
|
1120
|
-
elif enemy.name ==
|
1289
|
+
elif enemy.name == "greedy goblin":
|
1121
1290
|
enemy_REF = handle_greedy_goblin(player, enemy)
|
1122
1291
|
else:
|
1123
1292
|
enemy_REF = enemy
|
@@ -1137,31 +1306,33 @@ def main():
|
|
1137
1306
|
bad_guys.append(enemy_REF)
|
1138
1307
|
|
1139
1308
|
if all_same_value(enemies, False):
|
1140
|
-
del ROOMS[player.CURRENTROOM][
|
1309
|
+
del ROOMS[player.CURRENTROOM]["creatures stats"]
|
1141
1310
|
else:
|
1142
|
-
ROOMS[player.CURRENTROOM][
|
1311
|
+
ROOMS[player.CURRENTROOM]["creatures stats"] = enemies
|
1143
1312
|
|
1144
1313
|
# Execute battle with separated good and bad guys
|
1145
1314
|
if bad_guys:
|
1146
1315
|
good_guys, bad_guys = battle(player, good_guys, bad_guys, player.LASTROOM)
|
1147
1316
|
|
1148
1317
|
# Handle NPC interactions
|
1149
|
-
if
|
1150
|
-
for npcname, npcstats in ROOMS[player.CURRENTROOM][
|
1151
|
-
if
|
1318
|
+
if "NPCs" in ROOMS[player.CURRENTROOM]:
|
1319
|
+
for npcname, npcstats in ROOMS[player.CURRENTROOM]["NPCs"].items():
|
1320
|
+
if (
|
1321
|
+
ask_for_consent("Do you want to interact with this NPC")
|
1322
|
+
or npcstats.aggressive
|
1323
|
+
):
|
1152
1324
|
npcstats.interact()
|
1153
1325
|
if npcstats.aggressive:
|
1154
|
-
ROOMS[player.CURRENTROOM][
|
1326
|
+
ROOMS[player.CURRENTROOM]["NPCs"][npcname] = battle(
|
1327
|
+
player, [], [npcstats], player.LASTROOM
|
1328
|
+
)[1]
|
1155
1329
|
|
1156
1330
|
player.special_ability.Tick()
|
1157
1331
|
quest_manager.update_objective(f"Kill {GameState['Enemies killed']} creatures")
|
1158
|
-
for Item in GameState[
|
1332
|
+
for Item in GameState["collected items"]:
|
1159
1333
|
if isinstance(Item, item):
|
1160
1334
|
quest_manager.update_objective(f"Collect {Item.name}")
|
1161
1335
|
|
1162
1336
|
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
1337
|
if __name__ == "__main__":
|
1167
1338
|
main()
|