-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtext_rpg
More file actions
714 lines (596 loc) · 25.7 KB
/
text_rpg
File metadata and controls
714 lines (596 loc) · 25.7 KB
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
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
import random
from random import randint
from time import sleep
from colorama import Fore, Back, Style
import re
import sys
import json
import rich
class Person:
def __init__(
self, level, health, speed, attack, weapon, max_health=100): # initialize base stats of player
self.level = level
self.health = health
self.attack = attack
self.speed = speed
self.weapon = weapon
self.max_health = max_health
self.exp = 0
@property
def health(self):
return self._health
@health.setter # the property decorates with `.setter` to make it a setter
def health(self, new_value): # name, e.g. "health", is the same
if new_value < 0:
self._health = 0
else:
self._health = new_value
def exp_gain(self, amount):
self.exp += amount
if self.exp >= 100:
self.level_up()
def level_up(self):
self.max_health += 10
self.health = self.max_health
self.attack += 5
self.level += 1
self.exp = 0
print(
Fore.GREEN
+ Style.BRIGHT
+ f"Level {self.level} - {self.health} - {self.attack}"
+ Style.RESET_ALL
)
class Random_enemy(Person):
def __init__(self, level, health, speed, attack, type, exp_amount=0):
super().__init__(level, health, speed, attack, weapon=None, max_health=health)
self.type = type
self.exp_amount = random.randint(10, 20)
# Parse the JSON file
with open('monster_rarities.json', 'r') as f:
rarities = json.load(f)
# Create a list of tuples containing the name and weight of each rarity level
rarities_list = [(r['name'], r['weight']) for r in rarities['rarities']]
def make_enemy():
# Use the random.choices() function to choose a rarity level based on its weight
rarity = random.choices(rarities_list, weights=[r[1] for r in rarities_list])[0]
# create a variable to hold the rarity level name
rarity_name = rarity[0]
if rarity_name == 'Common':
rarity_name = f"{white}{rarity_name}{reset}"
elif rarity_name == 'Uncommon':
rarity_name = f"{green}{rarity_name}{reset}"
elif rarity_name == 'Rare':
rarity_name = f"{blue}{rarity_name}{reset}"
elif rarity_name == 'Epic':
rarity_name = f"{magenta}{rarity_name}{reset}"
elif rarity_name =='Legendary':
rarity_name = f"{cyan}{rarity_name}{reset}"
elif rarity_name == 'Mythical':
rarity_name = f"{yellow}{rarity_name}{reset}"
elif rarity_name == 'Divine':
rarity_name = f"{bright}{white}{rarity_name}{reset}"
elif rarity_name == 'Godly':
rarity_name = f"{bright}{blue}{rarity_name}{reset}"
else:
rarity_name = rarity_name
# Choose a random type from the monster_types list
type = f"{red}{rarity_name}{reset} {random.choice(monster_types)}"
# Get the rarity level values from the rarities list
rarity_values = None
for r in rarities['rarities']:
if r['name'] == rarity:
rarity_values = r
break
if rarity_values is None:
# Use default values if the rarity level is not found in the rarities list
health_multi = 1
attack_multi = 1
exp_multi = 1
else:
health_multi = rarity_values['health_multi']
attack_multi = rarity_values['attack_multi']
exp_multi = rarity_values['exp_multi']
# Generate the enemy with the appropriate multipliers applied
enemy = Random_enemy(
1,
random.randint(20, 40) * health_multi,
random.randint(50, 80),
random.randint(8, 11) * attack_multi,
type,
exp_amount=random.randint(10, 20) * exp_multi
)
return enemy
player_inventory = []
current_location = ""
previous_location = ""
green = Fore.GREEN
red = Fore.RED
yellow = Fore.YELLOW
blue = Fore.BLUE
magenta = Fore.MAGENTA
cyan = Fore.CYAN
white = Fore.WHITE
black = Fore.BLACK
reset = Style.RESET_ALL
bright = Style.BRIGHT
def generate_weapons():
# Generate a random number of weapons
num_weapons = randint(10, 20)
# Create a list of weapon names and materials
materials = ['gold', 'silver', 'bronze', 'copper', 'platinum', 'titanium', 'steel', 'iron', 'stone', 'obsidian', 'ruby', 'emerald', 'onyx', 'cobalt', 'brass', 'tin', 'aluminium', 'blue emerald', 'black diamond']
weapon_names = ['sword', 'dagger', 'spear', 'axe', 'mace', 'hammer', 'pike', 'katana', 'falchion',
'scimitar', 'rapier', 'sabre', 'cutlass', 'longsword', 'shortsword', 'broadsword',
'bastard sword', 'warhammer', 'mace', 'morningstar', 'flail', 'halberd', 'glaive',
'great sword', 'great axe', 'great mace', 'great hammer', 'great flail', 'great scythe',
'great club', 'great maul', 'great pick', 'great spade', 'great warhammer',
'great whip', 'great bow', 'great crossbow', 'great lance', 'great spear', 'great staff']
# Create an empty list to store the weapons
generated_weapons = []
rarity_weight = {"common": 100, "uncommon": 30, "rare": 10, "epic": 7, "legendary": 4, "mythical": 3, "divine": 2, "godly": 1}
rarity_list = [rarity for rarity, weight in rarity_weight.items() for _ in range(weight)]
for _ in range(num_weapons):
# Create a random weapon
weapon_name = weapon_names[randint(0, len(weapon_names) - 1)]
weapon_material = materials[randint(0, len(materials) - 1)]
weapon_rarity = random.choice(rarity_list)
if weapon_rarity == 'common':
weapon_dmg = randint(1,5)
elif weapon_rarity == 'uncommon':
weapon_dmg = randint(3,8)
elif weapon_rarity == 'rare':
weapon_dmg = randint(5,10)
elif weapon_rarity == 'epic':
weapon_dmg = randint(7,12)
elif weapon_rarity == 'legendary':
weapon_dmg = randint(9,15)
elif weapon_rarity =='mythical':
weapon_dmg = randint(10,15)
elif weapon_rarity == 'divine':
weapon_dmg = randint(15,20)
elif weapon_rarity == 'godly':
weapon_dmg = randint(20,30)
generated_weapons.append({
"name": f"{weapon_material.capitalize()} {weapon_name.capitalize()}",
"rarity": weapon_rarity,
"dmg": weapon_dmg
})
return generated_weapons
weapons = generate_weapons()
def equip_item(item_name):
# Iterate through the items in the player's inventory
for item in player_inventory:
# Check if the name of the item is contained in the item_name parameter and if the item is a weapon
if item in weapons and item != player.weapon:
# Equip the item by setting player.weapon to the item and increasing player.attack by the item's damage value
print(f"your damage is {player.attack}")
print("equipping item...")
sleep(1)
player.weapon = item
player.attack += item["dmg"]
print(f"you equipped the {item['name']}")
print(f"your damage is now {player.attack}")
with open("player_progress.json", "r") as f:
data = json.load(f)
data['current_weapon'] = player.weapon
return
elif item == player.weapon:
print("you already have that equipped")
return
# If the item is not a weapon or is not present in the inventory, print a message indicating that it cannot be equipped
else:
print(f"You cannot equip the {item_name}")
def healing(amount):
global player
player.health += amount
print(f"you regained {amount} health")
print(f"your health is now {player.health}")
def use_item(item_name):
# Iterate through the items in the player's inventory
for item in player_inventory:
# Check if the name of the item is equal to the item_name parameter
if item["name"] == item_name:
print(f"you attempt to use the {item_name}")
# check what type of item it is
if item.get("healing_value"):
if player.health == player.max_health:
print("you are already at full health")
else:
player_inventory.remove(item)
healing(item["healing_value"])
else:
print("this item has no effect")
# If the item is not useable, print a message indicating that it cannot be used
else:
print(f"You cannot use the {item_name}")
def inventory():
global player_inventory
while True:
# Print the items in the player's inventory, along with their indices
print("current inventory:")
for i, item in enumerate(player_inventory):
if item in weapons:
print(f"{i+1}. {item['name']} {blue}{item['dmg']}{reset} dmg")
else:
print(f"{i+1}. {item['name']}")
inventory_options = input(f"what would you like to do? {green}[1] use item{reset} {yellow}[2] drop item{reset} {blue}[3] equip item{reset} {red}[4] exit{reset} ")
if inventory_options == "1":
item_index = int(input("Enter the number for the item you want to use: ")) - 1
# Check if the selected index is valid
if item_index >= 0 and item_index < len(player_inventory):
item_to_use = player_inventory[item_index]
if item_to_use in weapons:
print("you cannot use weapons")
return
else:
use_item(item_to_use["name"])
return
else:
print("Item not found!")
return
elif inventory_options == "2":
item_index = int(input("Enter the number for the item you want to drop: ")) - 1
# Check if the selected index is valid
if item_index >= 0 and item_index < len(player_inventory):
item_to_drop = player_inventory[item_index]
player_inventory.remove(item_to_drop)
print(f"you dropped {item_to_drop['name']}")
else:
print("Item not found!")
elif inventory_options == "3":
try:
item_index = int(input("Enter the number for the item you want to equip: ")) - 1
# Check if the selected index is valid
if item_index >= 0 and item_index < len(player_inventory):
item_to_equip = player_inventory[item_index]
# Un-equip any previously equipped weapon
if "dmg" in player.weapon:
player.attack -= player.weapon["dmg"]
# Equip the new weapon
equip_item(item_to_equip)
break
else:
print("Item not found!")
except ValueError:
print("Invalid input!")
elif inventory_options == "4":
break
else:
print("invalid option")
def go_back(x):
# Define a dictionary that maps the values of x to the corresponding functions
locations = {
"hallway": hallway,
"cave": cave_one,
"dark_passage": dark_passage,
"kitchen": enter_kitchen,
"kitchen hallway": kitchen_hallway,
"dungeon": dungeon,
# Add more locations here as needed
}
if x not in locations:
return
# Call the function corresponding to the value of x
locations[x]()
def get_random_item(items):
total_weight = sum(item["weight"] for item in items)
random_weight = random.uniform(0, total_weight)
current_weight = 0
for item in items:
current_weight += item["weight"]
if current_weight > random_weight:
return item
# Open the items.json file and read its contents into a Python object
with open("items.json", "r") as f:
items = json.load(f)
# Get the items list from the object
kitchen_items = items["kitchen_items"]
level_one_items = items["level_one_items"]
level_two_items = items["level_two_items"]
def get_items(item_list):
global player_inventory
item = get_random_item(item_list)
player_inventory.append(item)
print(f"you found a {item['name']}")
def monster_attack_chance():
return random.randrange(0, 100)
monster_types = ["Zombie", "Slime", "Rat", "Snake", "Lizard", "Crow", "Spider", "Goblin"]
def escape():
return random.randrange(0, 100)
def get_hit(attacker, weapon=None):
if weapon is not None and weapon in player_inventory:
return round(random.randrange(1, attacker.attack) + weapon["dmg"])
else:
return round(random.randrange(1, attacker.attack))
def battle(player, enemy, current_location):
# Start the battle
while True:
# Prompt the player to choose an action
action = input(f"What do you want to do? {green}[a]{reset}ttack, {green}[r]{reset}un, or {green}[i]{reset}nventory: ")
# Make sure the player enters a valid action
while action not in ["a", "r", "i"]:
print("Invalid input. Try again.")
action = input(f"What do you want to do? {green}[a]{reset}ttack, {green}[r]{reset}un, or {green}[i]{reset}nventory: ")
# Carry out the chosen action
if action == "a":
enemy_hit = get_hit(player, player.weapon)
enemy.health -= enemy_hit
print(f"You hit the {green}{enemy.type}{reset} for {red}{enemy_hit}{reset} damage!")
print(f'{green}{enemy.type}{reset} health is: {green}{enemy.health}{reset}')
sleep(1)
if enemy.health <= 0:
print("You won the battle!")
exp_award = enemy.exp_amount
player.exp += exp_award
print(f"you gained {blue}{exp_award}{reset} exp")
# Generate a random number between 0 and 1
# If the number is less than 0.7, the player gets a weapon
if random.random() <= 0.15:
# Select a random weapon from the list
weapon = random.choice(weapons)
print(f"You found a {green}{weapon['name']}{reset}!")
player_inventory.append(weapon)
go_back(current_location)
print("Nothing found!")
go_back(current_location)
# The enemy attacks the player
player_hit = get_hit(enemy)
player.health -= get_hit(enemy)
print(f"The {green}{enemy.type}{reset} hit you for {red}{player_hit}{reset} damage!")
print(f'your health is: {green}{player.health}{reset}')
if player.health <= 0:
game_over(enemy.type)
elif action == "r":
# Try to run away
if random.randint(1,100) > 50:
print("You successfully ran away!")
go_back(current_location)
else:
print("You failed to run away!")
elif action == "i":
# Show the player's inventory
inventory()
def rng_battle(): # random battle simulator X
if monster_attack_chance() >= 60:
rnd_mob = make_enemy()
print(
f"you were attacked by an " + green + f"{rnd_mob.type}" + reset + " with " + green + f"{rnd_mob.health}" + reset + " health")
battle(player, rnd_mob, current_location)
def game_over(
*args,
): # tells you how you die etc. since args returns tuple had to convert to string, thanks stack overflow :D
death = args
s = "You died at the hands of a " + re.sub(r",(?=\))", "", str(death))
print(s)
print(f"\n do you know what IQ is?")
sys.exit("You were too weak adventurer, try again next time!")
def hallway():
global current_location
current_location = "hallway"
while True:
hallput = input(
f"you are in a hallway, what will you do?: {green}[d]{reset}escribe, {green}[l]{reset}eft, {green}[f]{reset}orwards or {green}[i]{reset}inventory "
)
while hallput not in ["f", "l", "d", "i"]:
print("ok, you lack brain-cells")
hallput = input(
f"you are in a hallway, what will you do?: {green}[d]{reset}escribe, {green}[l]{reset}eft, {green}[f]{reset}orwards or {green}[i]{reset}inventory "
)
if hallput == "d":
print("the walls are thickly lined in moss and dirt")
sleep(1)
print("there are stones and rocks littering the floor nothing interesting")
sleep(1)
print("old columns are along the walls crumbling and weakened")
sleep(1)
print("they have symbols on them")
elif hallput == "l":
rng_battle()
dark_passage()
elif hallput == "f":
rng_battle()
print("you leave the hallway and enter a kitchen")
enter_kitchen()
elif hallput == "i":
inventory()
def enter_cave(): # TODO sort out the json file and make it so that the player can save their progress
with open("player_progression.json", "r") as f:
progress = json.load(f)
trap_disarmed = False
have_key = False
described = False
if trap_disarmed == True:
trap_disarmed = True
if have_key == True:
have_key = True
if described == True:
described = True
cave_one(trap_disarmed, have_key, described)
def cave_one(trap_disarmed=False, have_key=False, described=False):
global current_location
current_location = "cave"
described = False
print("\nyou see a chest in the middle of the floor")
while True:
chestput = input(
f"\nwhat will you do? {green}[f]{reset}orwards, {green}[o]{reset}pen the chest, {green}[d]{reset}escribe the room, {green}[i]{reset}nventory: "
)
while chestput not in ["f", "o", "d", "i"]:
print("Sorry you dumb")
chestput = input(
f"\nwhat will you do? {green}[f]{reset}orwards, {green}[o]{reset}pen the chest, {green}[d]{reset}escribe the room, {green}[i]{reset}nventory: "
)
if chestput == "f":
rng_battle()
hallway()
elif chestput == "o" and have_key == True:
print("\nchest is locked")
elif chestput == "d":
if not described:
described = True
print("\nits pretty dank in here")
print(
"\nthe chest seems to be emblazoned with some sort of symbol denoting a trap, "
"better not open without disarming")
print("you notice a keyhole on the chest")
with open("grabbed.txt", "w") as f: # write to file
f.write(str(described))
elif chestput == "i":
# Show the player's inventory
inventory()
def dark_passage():
global current_location
current_location = "dark_passage"
while True:
print("you find yourself in a dark passage with barely any visibility")
sleep(1)
what = input(f"what whilst thou do?: {green}[d]{reset}escribe {green}[l]{reset}eave, {green}[i]{reset}nventory: ")
while what not in ["d", "l", "i"]:
print("grasping basic english isn't your strong suit is it?")
if what == "d": # describe the room
print("a cold wind passes you")
sleep(1)
print("you notice a darkened figure in the far reaches of the corridor")
sleep(1)
print("it seems to have not noticed you yet")
elif what == "l": # leave
rng_battle()
print("you quickly hurry into the hallway")
hallway()
elif what == "i": # inventory
inventory()
def enter_room(room): # TODO finish this
if room == "kitchen":
enter_kitchen()
elif room == "cave":
enter_cave()
elif room == "dark_passage":
dark_passage()
elif room == "hallway":
hallway()
def enter_kitchen():
with open("grabbed.txt", "r") as f:
grabbed = f.read()
if grabbed == "True":
grabbed = True
else:
grabbed = False
kitchen(grabbed)
def kitchen(grabbed):
global current_location
described = False
current_location = "kitchen"
# loop until the player leaves and while described remains false
while not described:
print("you enter what looks like a kitchen")
sleep(1)
options = input(f"what whilst thou do?: {green}[d]{reset}escribe {green}[l]{reset}eave, {green}[i]{reset}nventory: ")
sleep(1)
while options not in ["d", "l", "i"]:
print("grasping basic english isn't your strong suit is it?")
options = input(f"what whilst thou do?: {green}[d]{reset}escribe {green}[l]{reset}eave, {green}[i]{reset}nventory: ")
if options == "d":
if not described: # describe the room
described = True
print("there is a large table in the middle of the room")
sleep(1)
print("around you are many cabinets and shelves")
sleep(1)
print("there is a large pot on the stove with something bubbling inside")
sleep(1)
print("there is a door at the back of the room")
elif options == "l": # leave
rng_battle()
print("you hurry back into the hallway")
hallway()
elif options == "i": # inventory
inventory()
while True:
options = input(f"what whilst thou do?: {green}[d]{reset}escribe, {green}[g]{reset}rab the item out of the pot on the stove, {green}[i]{reset}nventory,{green}[u]{reset}se the door: ")
while options not in ["d", "g", "i", "u"]:
print("Cannot comprehend what you are saying")
options = input(f"what whilst thou do?: {green}[d]{reset}escribe, {green}[g]{reset}rab the item out of the pot on the stove, {green}[i]{reset}nventory,{green}[u]{reset}se the door: ")
if options == "d":
print("there is a large table in the middle of the room")
sleep(1)
print("around you are many cabinets and shelves")
sleep(1)
print("the pot on the stove is bubbling")
sleep(1)
print("there is a door at the back of the room")
elif options == "g" and not grabbed:
grabbed = True
with open("grabbed.txt", "w") as f:
f.write(str(grabbed))
print("you attempt to grab the item out of the pot")
sleep(1)
print("you burn your hand somewhat but manage to get the item")
sleep(1)
print("you lose 5 health")
player.health -= 5
print(f"you have {red}{player.health}{reset} health left")
sleep(1)
get_items(kitchen_items)
sleep(1)
elif options == "g" and grabbed:
print("you have already grabbed the item")
elif options == "i":
inventory()
elif options == "u":
print("you open the door and find yourself in a short passageway")
kitchen_hallway()
def kitchen_hallway():
global current_location
current_location = "kitchen_hallway"
while True:
print("you find yourself in a hallway with barely any visibility")
sleep(1)
what = input(f"what whilst thou do?: {green}[d]{reset}escribe {green}[l]{reset}eave, {green}[i]{reset}nventory, {green}[o]{reset}pen the gate: ")
while what not in ["d", "l", "i", "o"]:
print("cannot understand what you are saying")
if what == "d": # describe the room
print("a gate to some sort of dungeon is in front of you")
sleep(1)
print("the walls are covered in blood")
sleep(1)
print("you feel a sense of dread")
elif what == "l": # leave the room
rng_battle()
print("you quickly hurry back into the kitchen")
enter_kitchen()
elif what == "i": # inventory
inventory()
elif what == "o":
print("the gate is locked")
def dungeon():
global current_location
current_location = "dungeon"
while True:
print("you enter the dungeon")
sleep(1)
what = input(f"what whilst thou do?: {green}[d]{reset}escribe {green}[l]{reset}eave, {green}[i]{reset}nventory: ")
while what not in ["d", "l", "i"]:
print("cannot understand what you are saying")
what = input(f"what whilst thou do?: {green}[d]{reset}escribe {green}[l]{reset}eave, {green}[i]{reset}nventory: ")
sleep(1)
if what == "d": # describe the room
print("the floor is covered in blood and you can see what looks like a half eaten corpse!")
sleep(1)
print("all of a sudden what seemed like a nice dungeon turns into a nightmare")
sleep(1)
print("there are symbols on the floor that you don't understand")
elif what == "l": # leave the room
rng_battle()
print("you quickly hurry back into the kitchen hallway")
enter_room(kitchen_hallway)
elif what == "i": # inventory
inventory()
else:
print("cannot understand what you are saying")
if __name__ == "__main__":
player_one = input("what is your name?: ")
player = Person(1, 100, 20, 12, weapon={}, max_health=100)
print(f"Hello {green}{player_one}{reset} and welcome to your doom")
sleep(1)
print("you find yourself alone in an opening to some sort of dwelling\n")
cave_one()