fork download
  1. # Online Python compiler (interpreter) to run Python online.
  2. # Write Python 3 code in this online editor and run it.
  3. import time
  4. import random as rand
  5. import copy
  6.  
  7. class Inventory:
  8. def __init__(self):
  9. self.itemInventory = ["Health Potion"] * 3
  10. self.amethysts = 0
  11. self.emeralds = 0
  12. self.itemEffects = {}
  13.  
  14. def defineItemEffects(self):
  15. self.itemEffects = {
  16. "Health Potion": "Heal 60",
  17. "Life Crystal": "MaxHealth 20"
  18. }
  19.  
  20. class Player:
  21. def __init__(self, maxHealth, attackDamage):
  22. self.maxHealth = maxHealth
  23. self.health = self.maxHealth
  24. self.attackDamage = attackDamage
  25. self.critChance = 0.10
  26. self.maxEnergy = 3
  27. self.energy = 0
  28. self.specialAttacks = {
  29. "Sweep": ["Attacks all enemies", 2] #attack:[desc, cost]
  30. }
  31.  
  32. def __str__(self):
  33. return self.name
  34.  
  35. class Enemy:
  36. def __init__(self, maxHealth, attackDamage, name, aDrop, eDrop):
  37. self.maxHealth = maxHealth
  38. self.health = self.maxHealth
  39. self.attackDamage = attackDamage
  40. self.name = name
  41. self.eDrop = eDrop
  42. self.aDrop = aDrop
  43. self.alive = True
  44.  
  45. def __str__(self):
  46. return self.name
  47.  
  48. #def reset(self):
  49. # self.__init__()
  50.  
  51. def introduction():
  52. print("Welcome to Text-Based RPG in Python!")
  53. print("\nIMPORTANT! At the top, on the same row as \"main.py\", there's a fullscreen button. See it? Make sure to click it! If you don't, you won't be able to scroll down to the bottom of the output!\n")
  54. print("This is a demo. Right now you battle five battles. Try to defeat King Slime!")
  55. print("The controls are simple. For now, all you need to know is: type in \"a\" for attack, \"i\" for items, and \"o\" for other. \nUsually, just type in the first letter of the option you choose.")
  56. global name
  57. name = input("Before we start, what's your name? ")
  58. if name == "":
  59. name = "Player"
  60. if "skibidi" in name.lower():
  61. name = "Arnav"
  62. print(f"All right, {name.title()}!")
  63. p.name = name.title()
  64. input("Enter key to start!")
  65.  
  66. #Battle Functions
  67.  
  68. def playerUI():
  69. print(f"{p.name}\'s Health: ♥ {p.health}/{p.maxHealth}")
  70. print(f"You have {inventory.amethysts} Amethysts and {inventory.emeralds} Emeralds")
  71.  
  72. def enemyUI(enemy, number):
  73. if not best[enemy.name]["Entry"][1]:
  74. print(f"[{number}] {enemy.name}\'s Health: ♥ {(enemy.health / enemy.maxHealth) * 100}%")
  75. else:
  76. print(f"[{number}]{enemy.name}\'s Health: ♥ {enemy.health}/{enemy.maxHealth}")
  77.  
  78. def battleUI():
  79. print("")
  80. enemyUI(e1, 1)
  81. if 'e2' in globals():
  82. enemyUI(e2, 2)
  83. if 'e3' in globals():
  84. enemyUI(e3, 3)
  85. print(f"{p.name}\'s Health: ♥ {p.health}/{p.maxHealth}")
  86. print(f"{p.name}\'s Energy: {p.energy}/{p.maxEnergy}")
  87.  
  88. def attack(target, attacker):
  89. global enemyCount
  90. if target == p:
  91. p.health -= attacker.attackDamage
  92. print(f"\n{attacker.name} attacked you.")
  93. else:
  94. if target == 'all':
  95. if enemyCount == 2:
  96. e1.health -= p.attackDamage
  97. e2.health -= p.attackDamage
  98. elif enemyCount == 3:
  99. e1.health -= p.attackDamage
  100. e2.health -= p.attackDamage
  101. e3.health -= p.attackDamage
  102. else:
  103. e1.health -= p.attackDamage
  104. if rand.random() < p.critChance:
  105. if enemyCount == 2:
  106. e1.health -= p.attackDamage *.5
  107. e2.health -= p.attackDamage *.5
  108. elif enemyCount == 3:
  109. e1.health -= p.attackDamage *.5
  110. e2.health -= p.attackDamage *.5
  111. e3.health -= p.attackDamage *.5
  112. else:
  113. e1.health -= p.attackDamage *.5
  114. else:
  115. target.health -= p.attackDamage
  116. if rand.random() < p.critChance:
  117. target.health -= p.attackDamage * .5
  118. print("\nCritical Hit!")
  119. else:
  120. print("\nYou attacked.")
  121. if target != 'all' and target.health <= 0 :
  122. target.health = 0
  123.  
  124. def useItem(toUse):
  125. itemToUse = inventory.itemInventory[toUse]
  126. effect = inventory.itemEffects[itemToUse]
  127. effect = effect.split(' ')
  128. type = effect[0]
  129. if type == 'Heal':
  130. p.health += int(effect[1])
  131. if p.health > p.maxHealth:
  132. p.health = p.maxHealth
  133. if type == 'MaxHealth':
  134. p.maxHealth += int(effect[1])
  135. p.health += int(effect[1])
  136. inventory.itemInventory.pop(toUse)
  137.  
  138. def useInventory():
  139. print(f"Your Item Inventory: {inventory.itemInventory}")
  140. item = input("Would you like to use an item? (Type the number of the item in the list, starting at one eg. for first item type 1. Type anything else, or nothing, to exit.) ")
  141. if item.isdigit() == True:
  142. if len(inventory.itemInventory) > int(item) - 1:
  143. useItem(int(item) - 1)
  144. return True
  145. else:
  146. print("Invalid Number")
  147. return False
  148. else:
  149. return False
  150.  
  151. def playerTurn():
  152. playerMove = input("| ️Attack | Item | Other | ").lower()
  153. time.sleep(0.25)
  154. if playerMove == "a":
  155. attackType = ''
  156. while not (attackType == 'r' or attackType == 's'):
  157. attackType = input("| ️Regular Attack | Special Attack | ").lower()
  158. specialAttackType = ""
  159. if attackType == 's':
  160. print("Your special attacks:\n")
  161. for attacktype, info in p.specialAttacks.items():
  162. print(f"{attacktype}: {info[0]}, costs {info[1]} energy.")
  163. specialAttackType = input("\nWhich one would you like to use? (type number, anything else to exit.) ").lower()
  164. if specialAttackType.isdigit():
  165. specialAttackType = int(specialAttackType) - 1
  166. try:
  167. p.energy -= (p.specialAttacks[list(p.specialAttacks.keys())[specialAttackType]][1])
  168. except:
  169. return playerTurn()
  170. if p.energy < 0:
  171. p.energy += p.specialAttacks[list(p.specialAttacks.keys())[specialAttackType]][1]
  172. print("Not enough energy.")
  173. return playerTurn()
  174. if specialAttackType == 0:
  175. attack('all', p)
  176. return None
  177. if enemyCount == 1:
  178. if attackType == "r":
  179. attack(e1, p)
  180. else:
  181. attacking = ""
  182. while not attacking.isdigit():
  183. attacking = input("Which enemy would you like to attack? (Type the number): ")
  184. if attacking.isdigit():
  185. if int(attacking) < 1 or int(attacking) > enemyCount:
  186. print("Invalid number. Choose again.")
  187. attacking = ""
  188. attacking = int(attacking)
  189. if attacking == 1:
  190. attack(e1, p)
  191. elif attacking == 2:
  192. attack(e2, p)
  193. elif attacking == 3:
  194. attack(e3, p)
  195. elif playerMove == 'i':
  196. if not useInventory():
  197. return playerTurn()
  198. return playerTurn()
  199. elif playerMove == 'o':
  200. otherMove = input("| ️Charge Energy | ").lower()
  201. if otherMove == 'c':
  202. p.energy += 1
  203. if p.energy > p.maxEnergy:
  204. p.energy = p.maxEnergy
  205. else:
  206. return playerTurn()
  207. else:
  208. return playerTurn()
  209.  
  210. def enemyTurn(enemy):
  211. if enemy == 1:
  212. enemy = e1
  213. elif enemy == 2:
  214. enemy = e2
  215. elif enemy == 3:
  216. enemy = e3
  217. if enemy.health <= 0:
  218. enemy.alive = False
  219. enemy.health = 0
  220. else:
  221. time.sleep(rand.randrange(10, 15, 1) / 10)
  222. attack(p, enemy)
  223.  
  224.  
  225. def battle():
  226. global enemyCount
  227. global e1
  228. global e2
  229. global e3
  230. if 'e2' in globals():
  231. if 'e3' in globals():
  232. condition = e1.alive or e2.alive or e3.alive
  233. else:
  234. condition = e1.alive or e2.alive
  235. else: condition = e1.alive
  236. while (condition == True) and p.health > 0:
  237. p.energy += 1;
  238. if p.energy > p.maxEnergy:
  239. p.energy = p.maxEnergy
  240. battleUI()
  241. playerTurn()
  242. time.sleep(0.5)
  243. battleUI()
  244. for i in range(1, enemyCount + 1):
  245. enemyTurn(i)
  246. if 'e2' in globals():
  247. if 'e3' in globals():
  248. condition = e1.alive or e2.alive or e3.alive
  249. else:
  250. condition = e1.alive or e2.alive
  251. else: condition = e1.alive
  252. time.sleep(0.5)
  253.  
  254. battleUI()
  255.  
  256. if p.health <= 0:
  257. p.health = 0
  258. if e1.health <= 0:
  259. e1.health = 0
  260. if 'e2' in globals():
  261. if e2.health <= 0:
  262. e2.health = 0
  263. if 'e3' in globals():
  264. if e3.health <= 0:
  265. e3.health = 0
  266.  
  267. if p.health <= 0:
  268. print('You Lose!')
  269. quit()
  270. else:
  271. print('\nYou Win!')
  272. if 'e2' in globals():
  273. if 'e3' in globals():
  274. inBattle = [e1, e2, e3]
  275. else:
  276. inBattle = [e1, e2]
  277. else:
  278. inBattle = [e1]
  279. for i in inBattle:
  280. inventory.amethysts += i.aDrop
  281. print(f'+{i.aDrop} Amethysts')
  282. if i.eDrop > 0:
  283. inventory.emeralds += i.eDrop
  284. print(f'+{i.eDrop} Emeralds')
  285. if len(i.specialDrops) > 0:
  286. print(f"Dropped {i.specialDrops}")
  287. inventory.itemInventory.extend(i.specialDrops)
  288. if not best[i.name]["Entry"][1]:
  289. best[i.name]["Entry"][1] = True
  290. print(f"{i.name} added to bestiary.")
  291.  
  292. def initiateBattle(wave):
  293. global e1
  294. global e2
  295. global e3
  296. global enemyCount
  297. e1 = copy.copy(waves[wave][1]["enemy"])
  298. e1.specialDrops = waves[wave][1]["specialDrops"]
  299. enemyCount = 1
  300. if len(waves[wave]) > 1:
  301. if waves[wave][2]["enemy"] == waves[wave][1]["enemy"]:
  302. e2 = copy.copy(e1)
  303. else:
  304. e2 = waves[wave][2]["enemy"]
  305. e2.specialDrops = waves[wave][2]["specialDrops"]
  306. enemyCount += 1
  307. if len(waves[wave]) == 3:
  308. if waves[wave][3]["enemy"] == waves[wave][1]["enemy"]:
  309. e3 = copy.copy(e1)
  310. if waves[wave][3]["enemy"] == waves[wave][2]["enemy"]:
  311. e3 = copy.copy(e2)
  312. e3 = waves[wave][3]["enemy"]
  313. e3.specialDrops = waves[wave][3]["specialDrops"]
  314. enemyCount += 1
  315. else:
  316. try:
  317. del e3
  318. except:
  319. pass
  320. else:
  321. try:
  322. del e2
  323. del e3
  324. except:
  325. pass
  326.  
  327.  
  328. if e1.name == "King Slime":
  329. print("\nBOSS BATTLE!")
  330. if enemyCount == 2:
  331. print(f"\n{p.name} vs. {e1.name}, {e2.name}")
  332. elif enemyCount == 3:
  333. print(f"\n{p.name} vs. {e1.name}, {e2.name}, {e3.name}")
  334. else:
  335. print(f"\n{p.name} vs. {e1.name}")
  336.  
  337. #End of batte functions
  338.  
  339. def viewBestiary():
  340. print("\nEnemies in your bestiary:")
  341. global best
  342. viewable = []
  343. for enemy in best:
  344. if best[enemy]["Entry"][1] == False:
  345. continue
  346. print(enemy)
  347. viewable.append(enemy)
  348. view = input("\nWhich entry would you like to view? (Type position of enemy in the list of enemies, eg. first type \"1\". Type anything else, or nothing, to exit.) ")
  349. if view.isdigit() == True:
  350. if int(view) - 1 < len(viewable):
  351. view = int(view) - 1
  352. print()
  353. print(viewable[view])
  354. print(best[viewable[view]]["Entry"][0])
  355. else:
  356. print("Invalid Number")
  357.  
  358. def rest():
  359. playerUI()
  360. exit = False
  361. while exit == False:
  362. print("\nWhat would you like to do?")
  363. choice = input("| Item | View Bestiary | (i for item, b for bestiary, anything else to exit) ").lower()
  364. if choice == "i":
  365. while useInventory():
  366. print()
  367. playerUI()
  368. elif choice == 'b':
  369. viewBestiary()
  370. else:
  371. exit = True;
  372.  
  373.  
  374. print("Text-Based RPG in Python, by Maxwell")
  375. p = Player(100, 20)
  376. inventory = Inventory()
  377. inventory.defineItemEffects()
  378. global playerMove
  379.  
  380.  
  381. best = {
  382. "Orange Slime": {
  383. "Enemy": Enemy(40, 10, "Orange Slime", 2, 0),
  384. "Entry": ["""Health: 40, Attack Damage: 10
  385. Just your regular orange slime boi.""", False]
  386. },
  387. "Blue Slime": {
  388. "Enemy": Enemy(60, 10, "Blue Slime", 3, 0),
  389. "Entry": ["""Health: 60, Attack Damage: 10
  390. Slightly more durable than the orange slime. Also, comes in a cool shade of blue! Although you can't really see that...""", False]
  391. },
  392. "King Slime": {
  393. "Enemy": Enemy(120, 20, "King Slime", 5, 1),
  394. "Entry": ["""Health: 120, Attack Damage: 20
  395. [BOSS] A king among slimes. Very strong, very large, and rocks a cool crown.""", False]
  396. }
  397. } #Short for "bestiary", basically a monster encyclopedia
  398.  
  399. waves = {
  400. 1 : {
  401. 1 : {
  402. "enemy" : best["Orange Slime"]["Enemy"],
  403. "specialDrops" : []
  404. }
  405. },
  406. 2 : {
  407. 1 : {
  408. "enemy" : best["Blue Slime"]["Enemy"],
  409. "specialDrops" : []
  410. }
  411. },
  412. 3 : {
  413. 1 : {
  414. "enemy" : best["Orange Slime"]["Enemy"],
  415. "specialDrops" : []
  416. },
  417. 2 : {
  418. "enemy" : best["Orange Slime"]["Enemy"],
  419. "specialDrops" : []
  420. }
  421. },
  422. 4 : {
  423. 1 : {
  424. "enemy" : best["Blue Slime"]["Enemy"],
  425. "specialDrops" : []
  426. },
  427. 2 : {
  428. "enemy" : best["Blue Slime"]["Enemy"],
  429. "specialDrops" : ["Health Potion"]
  430. }
  431. },
  432. 5 : {
  433. 1 : {
  434. "enemy" : best["King Slime"]["Enemy"],
  435. "specialDrops" : ["Life Crystal"]
  436. }
  437. }
  438. }
  439.  
  440. introduction()
  441.  
  442. for wave in range(1, len(waves) + 1):
  443. initiateBattle(wave)
  444. battle()
  445. rest()
  446. print(f"\nCongrats, {p.name}! You've beaten the demo.")
  447.  
  448.  
  449.  
  450. # To Do:
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459. #████████╗███████╗██╗ ██╗████████╗
  460. #╚══██╔══╝██╔════╝╚██╗██╔╝╚══██╔══╝
  461. # ██║ █████╗ ╚███╔╝ ██║ █████╗
  462. # ██║ ██╔══╝ ██╔██╗ ██║ ╚════╝
  463. # ██║ ███████╗██╔╝ ██╗ ██║
  464. # ╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═╝
  465. #
  466. #██████╗ █████╗ ███████╗███████╗██████╗ ██████╗ ██████╗ ██████╗
  467. #██╔══██╗██╔══██╗██╔════╝██╔════╝██╔══██╗ ██╔══██╗██╔══██╗██╔════╝
  468. #██████╔╝███████║███████╗█████╗ ██║ ██║ ██████╔╝██████╔╝██║ ███╗
  469. #██╔══██╗██╔══██║╚════██║██╔══╝ ██║ ██║ ██╔══██╗██╔═══╝ ██║ ██║
  470. #██████╔╝██║ ██║███████║███████╗██████╔╝ ██║ ██║██║ ╚██████╔╝
  471. #╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═════╝
Success #stdin #stdout 0.04s 25428KB
stdin
Standard input is empty
stdout
# Online Python compiler (interpreter) to run Python online.
# Write Python 3 code in this online editor and run it.
import time
import random as rand
import copy

class Inventory:
    def __init__(self):
        self.itemInventory = ["Health Potion"] * 3
        self.amethysts = 0
        self.emeralds = 0
        self.itemEffects = {}
        
    def defineItemEffects(self):
            self.itemEffects = {
                "Health Potion": "Heal 60",
                "Life Crystal": "MaxHealth 20"
            }

class Player:
    def __init__(self, maxHealth, attackDamage):
        self.maxHealth = maxHealth
        self.health = self.maxHealth
        self.attackDamage = attackDamage
        self.critChance = 0.10
        self.maxEnergy = 3
        self.energy = 0
        self.specialAttacks = {
            "Sweep": ["Attacks all enemies", 2] #attack:[desc, cost]
        }
    
    def __str__(self):
        return self.name
        
class Enemy:
    def __init__(self, maxHealth, attackDamage, name, aDrop, eDrop):
        self.maxHealth = maxHealth
        self.health = self.maxHealth
        self.attackDamage = attackDamage
        self.name = name
        self.eDrop = eDrop
        self.aDrop = aDrop
        self.alive = True
        
    def __str__(self):
        return self.name
        
    #def reset(self):
    #       self.__init__()

def introduction():
    print("Welcome to Text-Based RPG in Python!")
    print("\nIMPORTANT! At the top, on the same row as \"main.py\", there's a fullscreen button. See it? Make sure to click it! If you don't, you won't be able to scroll down to the bottom of the output!\n")
    print("This is a demo. Right now you battle five battles. Try to defeat King Slime!")
    print("The controls are simple. For now, all you need to know is: type in \"a\" for attack, \"i\" for items, and \"o\" for other. \nUsually, just type in the first letter of the option you choose.")
    global name
    name = input("Before we start, what's your name? ")
    if name == "":
        name = "Player"
    if "skibidi" in name.lower():
        name = "Arnav"
    print(f"All right, {name.title()}!")
    p.name = name.title()
    input("Enter key to start!")

#Battle Functions

def playerUI():
    print(f"{p.name}\'s Health: ♥ {p.health}/{p.maxHealth}")
    print(f"You have {inventory.amethysts} Amethysts and {inventory.emeralds} Emeralds")
    
def enemyUI(enemy, number):
    if not best[enemy.name]["Entry"][1]:
        print(f"[{number}] {enemy.name}\'s Health: ♥ {(enemy.health / enemy.maxHealth) * 100}%")
    else:
        print(f"[{number}]{enemy.name}\'s Health: ♥ {enemy.health}/{enemy.maxHealth}")
    
def battleUI():
    print("")
    enemyUI(e1, 1)
    if 'e2' in globals():
        enemyUI(e2, 2)
    if 'e3' in globals():
        enemyUI(e3, 3)
    print(f"{p.name}\'s Health: ♥ {p.health}/{p.maxHealth}")
    print(f"{p.name}\'s Energy: {p.energy}/{p.maxEnergy}")
    
def attack(target, attacker):
    global enemyCount
    if target == p:
        p.health -= attacker.attackDamage
        print(f"\n{attacker.name} attacked you.")
    else:
        if target == 'all':
            if enemyCount == 2:
                e1.health -= p.attackDamage
                e2.health -= p.attackDamage
            elif enemyCount == 3:
                e1.health -= p.attackDamage
                e2.health -= p.attackDamage
                e3.health -= p.attackDamage
            else:
                e1.health -= p.attackDamage
            if rand.random() < p.critChance:
                if enemyCount == 2:
                    e1.health -= p.attackDamage  *.5
                    e2.health -= p.attackDamage *.5
                elif enemyCount == 3:
                    e1.health -= p.attackDamage *.5
                    e2.health -= p.attackDamage *.5
                    e3.health -= p.attackDamage *.5
                else:
                    e1.health -= p.attackDamage *.5
        else:
            target.health -= p.attackDamage
            if rand.random() < p.critChance:
                target.health -= p.attackDamage * .5
                print("\nCritical Hit!")
            else:
                print("\nYou attacked.")
    if target != 'all' and target.health <= 0 :
        target.health = 0
        
def useItem(toUse):
    itemToUse = inventory.itemInventory[toUse]
    effect = inventory.itemEffects[itemToUse]
    effect = effect.split(' ')
    type = effect[0]
    if type == 'Heal':
        p.health += int(effect[1])
        if p.health > p.maxHealth:
            p.health = p.maxHealth
    if type == 'MaxHealth':
        p.maxHealth += int(effect[1])
        p.health += int(effect[1])
    inventory.itemInventory.pop(toUse)

def useInventory():
    print(f"Your Item Inventory: {inventory.itemInventory}")
    item = input("Would you like to use an item? (Type the number of the item in the list, starting at one eg. for first item type 1. Type anything else, or nothing, to exit.) ")
    if item.isdigit() == True: 
        if len(inventory.itemInventory) > int(item) - 1:
            useItem(int(item) - 1)
            return True
        else:
            print("Invalid Number")
            return False
    else:
        return False

def playerTurn():
    playerMove = input("| ️Attack | Item | Other | ").lower()
    time.sleep(0.25)
    if playerMove == "a":
        attackType = ''
        while not (attackType == 'r' or attackType == 's'):
            attackType = input("| ️Regular Attack | Special Attack |  ").lower()
        specialAttackType = ""
        if attackType == 's':
            print("Your special attacks:\n")
            for attacktype, info in p.specialAttacks.items():
                print(f"{attacktype}: {info[0]}, costs {info[1]} energy.")
            specialAttackType = input("\nWhich one would you like to use? (type number, anything else to exit.) ").lower()
            if specialAttackType.isdigit():
                specialAttackType = int(specialAttackType) - 1
            try:
                p.energy -= (p.specialAttacks[list(p.specialAttacks.keys())[specialAttackType]][1])
            except:
                return playerTurn()
            if p.energy < 0:
                p.energy += p.specialAttacks[list(p.specialAttacks.keys())[specialAttackType]][1]
                print("Not enough energy.")
                return playerTurn()
        if specialAttackType == 0:
            attack('all', p)
            return None
        if enemyCount == 1:
            if attackType == "r":
                attack(e1, p)
        else:
            attacking = ""
            while not attacking.isdigit():
                attacking = input("Which enemy would you like to attack? (Type the number): ")
                if attacking.isdigit():
                    if int(attacking) < 1 or int(attacking) > enemyCount:
                        print("Invalid number. Choose again.")
                        attacking = ""
            attacking = int(attacking)
            if attacking == 1:
                attack(e1, p)
            elif attacking == 2:
                attack(e2, p)
            elif attacking == 3:
                attack(e3, p)
    elif playerMove == 'i':
        if not useInventory():
            return playerTurn()
        return playerTurn()
    elif playerMove == 'o':
        otherMove = input("| ️Charge Energy |  ").lower()
        if otherMove == 'c':
            p.energy += 1
            if p.energy > p.maxEnergy:
                p.energy = p.maxEnergy
        else:
            return playerTurn()
    else:
        return playerTurn()

def enemyTurn(enemy):
    if enemy == 1:
        enemy = e1
    elif enemy == 2:
        enemy = e2
    elif enemy == 3:
        enemy = e3
    if enemy.health <= 0:
        enemy.alive = False
        enemy.health = 0
    else:
        time.sleep(rand.randrange(10, 15, 1) / 10)
        attack(p, enemy)
    

def battle():
    global enemyCount
    global e1
    global e2
    global e3
    if 'e2' in globals():
        if 'e3' in globals():
            condition = e1.alive or e2.alive or e3.alive
        else:
            condition = e1.alive or e2.alive
    else: condition = e1.alive
    while (condition == True) and p.health > 0:
        p.energy += 1; 
        if p.energy > p.maxEnergy: 
            p.energy = p.maxEnergy
        battleUI()
        playerTurn()
        time.sleep(0.5)
        battleUI()
        for i in range(1, enemyCount + 1):
            enemyTurn(i)
        if 'e2' in globals():
            if 'e3' in globals():
                condition = e1.alive or e2.alive or e3.alive
            else:
                condition = e1.alive or e2.alive
        else: condition = e1.alive
        time.sleep(0.5)
    
    battleUI()
    
    if p.health <= 0:
        p.health = 0
    if  e1.health <= 0:
        e1.health = 0
    if 'e2' in globals():
        if e2.health <= 0:
            e2.health = 0
    if 'e3' in globals():
        if e3.health <= 0:
            e3.health = 0
    
    if p.health <= 0:
        print('You Lose!')
        quit()
    else:
        print('\nYou Win!')
        if 'e2' in globals():
            if 'e3' in globals():
                inBattle = [e1, e2, e3]
            else:
                inBattle = [e1, e2]
        else: 
            inBattle = [e1]
        for i in inBattle:
            inventory.amethysts += i.aDrop
            print(f'+{i.aDrop} Amethysts')
            if i.eDrop > 0:
                inventory.emeralds += i.eDrop
                print(f'+{i.eDrop} Emeralds')
            if len(i.specialDrops) > 0:
                print(f"Dropped {i.specialDrops}")
                inventory.itemInventory.extend(i.specialDrops)
            if not best[i.name]["Entry"][1]:
                best[i.name]["Entry"][1] = True
                print(f"{i.name} added to bestiary.")

def initiateBattle(wave):
    global e1
    global e2
    global e3
    global enemyCount
    e1 = copy.copy(waves[wave][1]["enemy"])
    e1.specialDrops = waves[wave][1]["specialDrops"]
    enemyCount = 1
    if len(waves[wave]) > 1:
        if waves[wave][2]["enemy"] == waves[wave][1]["enemy"]:
            e2 = copy.copy(e1)
        else:
            e2 = waves[wave][2]["enemy"]
        e2.specialDrops = waves[wave][2]["specialDrops"]
        enemyCount += 1
        if len(waves[wave]) == 3:
            if waves[wave][3]["enemy"] == waves[wave][1]["enemy"]:
                e3 = copy.copy(e1)
            if waves[wave][3]["enemy"] == waves[wave][2]["enemy"]:
                e3 = copy.copy(e2)
            e3 = waves[wave][3]["enemy"]
            e3.specialDrops = waves[wave][3]["specialDrops"]
            enemyCount += 1
        else:
            try:
                del e3
            except:
                pass
    else:
        try:
            del e2
            del e3
        except:
            pass
    
    
    if e1.name == "King Slime":
        print("\nBOSS BATTLE!")
    if enemyCount == 2:
        print(f"\n{p.name} vs. {e1.name}, {e2.name}")
    elif enemyCount == 3:
        print(f"\n{p.name} vs. {e1.name}, {e2.name}, {e3.name}")
    else:
        print(f"\n{p.name} vs. {e1.name}")

#End of batte functions 

def viewBestiary():
    print("\nEnemies in your bestiary:")
    global best
    viewable = []
    for enemy in best:
        if best[enemy]["Entry"][1] == False:
                continue
        print(enemy)
        viewable.append(enemy)
    view = input("\nWhich entry would you like to view? (Type position of enemy in the list of enemies, eg. first type \"1\". Type anything else, or nothing, to exit.) ")
    if view.isdigit() == True:
        if int(view) - 1 < len(viewable):
            view = int(view) - 1
            print()
            print(viewable[view])
            print(best[viewable[view]]["Entry"][0])
        else:
            print("Invalid Number")

def rest():
    playerUI()
    exit = False
    while exit == False:
        print("\nWhat would you like to do?")
        choice = input("| Item | View Bestiary | (i for item, b for bestiary, anything else to exit) ").lower()
        if choice == "i":
            while useInventory():
                print()
                playerUI()
        elif choice == 'b':
            viewBestiary()
        else:
            exit = True;


print("Text-Based RPG in Python, by Maxwell")
p = Player(100, 20)
inventory = Inventory()
inventory.defineItemEffects()
global playerMove


best = { 
    "Orange Slime": {
        "Enemy": Enemy(40, 10, "Orange Slime", 2, 0),
        "Entry": ["""Health: 40, Attack Damage: 10
        Just your regular orange slime boi.""", False]
    },
    "Blue Slime": {
        "Enemy": Enemy(60, 10, "Blue Slime", 3, 0),
        "Entry": ["""Health: 60, Attack Damage: 10
        Slightly more durable than the orange slime. Also, comes in a cool shade of blue! Although you can't really see that...""", False]
    },
    "King Slime": {
        "Enemy": Enemy(120, 20, "King Slime", 5, 1),
        "Entry": ["""Health: 120, Attack Damage: 20
        [BOSS] A king among slimes. Very strong, very large, and rocks a cool crown.""", False]
    }
} #Short for "bestiary", basically a monster encyclopedia

waves = {
    1 : {
        1 : {
            "enemy" : best["Orange Slime"]["Enemy"],
            "specialDrops" : []
        }
    },
    2 : {
        1 : {
            "enemy" : best["Blue Slime"]["Enemy"],
            "specialDrops" : []
        }
    },
    3 : {
        1 : {
            "enemy" : best["Orange Slime"]["Enemy"],
            "specialDrops" : []
        },
        2 : {
            "enemy" : best["Orange Slime"]["Enemy"],
            "specialDrops" : []
        }
    },
    4 : {
        1 : {
            "enemy" : best["Blue Slime"]["Enemy"],
            "specialDrops" : []
        },
        2 : {
            "enemy" : best["Blue Slime"]["Enemy"],
            "specialDrops" : ["Health Potion"]
        }
    },
    5 : {
        1 : {
            "enemy" : best["King Slime"]["Enemy"],
            "specialDrops" : ["Life Crystal"]
        }
    }
}

introduction()

for wave in range(1, len(waves) + 1):
    initiateBattle(wave)
    battle()
    rest()
print(f"\nCongrats, {p.name}! You've beaten the demo.")



# To Do: 








#████████╗███████╗██╗  ██╗████████╗                                   
#╚══██╔══╝██╔════╝╚██╗██╔╝╚══██╔══╝                                   
#   ██║   █████╗   ╚███╔╝    ██║       █████╗                         
#   ██║   ██╔══╝   ██╔██╗    ██║       ╚════╝                         
#   ██║   ███████╗██╔╝ ██╗   ██║                                      
#   ╚═╝   ╚══════╝╚═╝  ╚═╝   ╚═╝                                      
#                                                                     
#██████╗  █████╗ ███████╗███████╗██████╗     ██████╗ ██████╗  ██████╗ 
#██╔══██╗██╔══██╗██╔════╝██╔════╝██╔══██╗    ██╔══██╗██╔══██╗██╔════╝ 
#██████╔╝███████║███████╗█████╗  ██║  ██║    ██████╔╝██████╔╝██║  ███╗
#██╔══██╗██╔══██║╚════██║██╔══╝  ██║  ██║    ██╔══██╗██╔═══╝ ██║   ██║
#██████╔╝██║  ██║███████║███████╗██████╔╝    ██║  ██║██║     ╚██████╔╝
#╚═════╝ ╚═╝  ╚═╝╚══════╝╚══════╝╚═════╝     ╚═╝  ╚═╝╚═╝      ╚═════╝