def take_item(self, obj): """ This method allows the Player to remove items from their current location and adds them into their inventory """ """ It will take the dictionary key of the item from the Player's location items attribute, then it will remove it from the Room object and add it to Players bag attribute.""" if obj in self.location.items: # Testing if "item" key exist in the dictionary if obj in self.bag: # Testing if the "item" key already exist in the Players bag attribute typewriter.typing(f"=>{obj} already in bag", 0.035) # If the "item" key does'nt exist in the Players bag attribute elif len( self.bag ) < self.BAG_CAP: # Testing if Player has reached bag capacity self.bag[obj] = self.location.items[ obj] # Appending object to Player's bag attribute, with relevant key del self.location.items[ obj] # Removing object from Player's current location typewriter.typing(f"=>{obj} is packed in the bag", 0.035) else: # If bag is full typewriter.typing(f"=>Bag is full", 0.035) typewriter.typing( "=>Use the \"throw {item name}\" to make space", 0.035) else: # If the "item" key is not found typewriter.typing(f"=>{obj} not in {self.location.name}", 0.035)
def talk(self, npc): """ Uses 'npc' as key to access the people attribute of Player's location""" if npc in self.location.people: # Testing key exits # Accessing the conversation method of the NPC object in people attribute of Player's location self.location.people[npc].conversation() else: # If key doesn't exist typewriter.typing(f"=>{npc} is not in the room")
def conversation(self): """ Select at random a text from the list of the NPC's text_opt attribute and prints it out""" selector = random(0, len(self.text_opt) - 1) # Creating the random selector reply = self.text_opt[ selector] # Using the selector to pick text from NPC's text_opt attribute typewriter.typing(reply, 0.1)
def examine_item(self, item): """ Using 'item' as the key to the item in the Player's bag attribute, it will access that items full_desc method """ if item in self.bag: # Testing if the key exist # Accessing the full description method of the item object self.bag[item].full_desc() else: # If the key is not found typewriter.typing(f"={item} not in bag", 0.035)
def show_move(self, move): """ Using 'move' as the key to the fighting move object in the Player's fighting_moves attribute, it will access the fighting_move's full_desc method """ if not (move in self.fight_moves): # Testing if key exists typewriter.typing(f"=>{self.name} doesnt know this move", 0.035) else: # If key exist self.fight_moves[move].full_desc( ) # Accessing the full description method of the fight_move object
def _battle_math(self, player, enemy, player_move): """ Displays the effects of the the Players fight_move and displays the effects""" # ==>>Player's move affects Enemy first if player_move in player.fight_moves: # testing if the key to Player object's fight_moves is valid fight_move = player.fight_moves[ player_move] # Getting the fight_move object Player object typewriter.typing( "\n>>" + "--" * 7 + f"{player.name}" + "--" * 7 + "<<", 0.035) index = len(fight_move.atck_desc ) # Getting len of attack descriptions list text = fight_move.atck_desc[random( 0, index - 1)] # Getting the attack description typewriter.typing(f"==>>{text} \n", 0.035) # displaying the attack description self._damage_effect( player, enemy, player_move) # calculates the effects of the move # testing if enemy is dead if enemy.hp < 1: return else: # If key does'nt exist typewriter.typing( f"=>{player.name} does not know how to {player_move}") return 0 # =============================================================================================== # enemy's turn to fight move_keys = list(enemy.fight_moves) # length of enemy's fight_moves enemy_move = move_keys[random( 0, len(move_keys) - 1)] # random pick of enemy move from their list fight_move = enemy.fight_moves[ enemy_move] # Getting the fight_move object of Enemy object typewriter.typing( "\n>>" + "--" * 7 + f"{enemy.name}" + "--" * 7 + "<<", 0.030) index = len( fight_move.atck_desc) # Getting len of attack descriptions list text = fight_move.atck_desc[random( 0, index - 1)] # Getting the attack description typewriter.typing(f"==>>{text} \n", 0.090) # displaying the attack description self._damage_effect(enemy, player, enemy_move) # calculates the effects of the move
def throw(self, item): """ Uses the 'item' as a key to access the Item object in the Player's bag attribute, the item is removed from the bag attribute and is appended into the items dictionary of the Players current location """ if item in self.bag: # Testing if key exist self.location.items[item] = self.bag[ item] # Appending the item to the items dictionary attribute del self.bag[item] # Removing the item from Players bag attribute typewriter.typing(f"=>{item} is thrown away", 0.035) else: # if key doesn't exist typewriter.typing(f"=>{item} not in bag", 0.035)
def eat(self, food): """ Uses 'food' as key to the Food object in the Players bag attribute """ if food in self.bag: # Testing if key exist if self.bag[ food].type == "Consumable": # Testing if the item from Player's bag is "Consume" type if not ( self.hp == self._MAX_HP ): # Test if Player's hp attribute is equal to the MAX_HP attribute self.hp += self.bag[food].regen if self.hp > self._MAX_HP: # If Players hp attribute exceeds the MAX_HP attribute self.hp = self._MAX_HP typewriter.typing(f"=>Health +{self.bag[food].regen}", 0.085) del self.bag[ food] # Removing the item from Player's bag Attribute else: # If Players hp attribute is equal to the MAX_HP attribute typewriter.typing(f"=>{self.name} is full", 0.035) else: # Item is not "Consumable" type typewriter.typing(f"=>{food} is not Consumable type", 0.035) else: # If key does;nt exist typewriter.typing(f"=>{food} not in bag", 0.035)
def _damage_effect(self, fighter, enemy, move): """ Calculates the values of the fight move used against an opponent""" damage = fighter.fight_moves[move].damage # defence affect if not (random(0, 1) == random(0, 1)) and enemy.defence != 0: damage -= enemy.defence # Subtracting damage from defence value of opponent if damage < 1: # If damage value results in a negative value damage = 1 percent = self._percent_absorption( fighter.fight_moves[move].damage, damage) # Calculating percent absorbed typewriter.typing( f"=>{enemy.name} blocked {percent}% of the attack") # subtracting enemy health by fighter damage enemy.hp -= damage
def full_desc(self): """ This method will print out the useful info about the item""" # printing object description typewriter.typing(f"==>>{self.name} description: {self.desc}<<== \n", 0.035) # printing object type typewriter.typing(f"=>Type: {self.type}", 0.085) # printing fight style value typewriter.typing(f"=>Style target: {self.style}", 0.085) # printing damage increase typewriter.typing(f"=>Damage: +{self.damage}", 0.085)
def full_desc(self): """ This method will print out the useful info about the fight move""" # print the description of the move typewriter.typing(f"==>{self.name} description: {self.desc}", 0.1) # print damage typewriter.typing(f"=>Damage: {self.damage}", 0.085) # print fighting style typewriter.typing(f"=>Style: {self.style} \n", 0.085)
def full_desc(self): """ This method will print out the useful info about the item""" # printing object description typewriter.typing(f"==>>{self.name} description: {self.desc}<<== \n", 0.035) # printing object type typewriter.typing(f"=>Type: {self.type}", 0.085) # printing regeneration value typewriter.typing(f"=>Regeneration: +{self.regen}", 0.085)
def full_desc(self): """ This method will print out the useful info about the item""" # printing object description typewriter.typing(f"==>>{self.name} description: {self.desc}", 0.035) # printing object type typewriter.typing(f"=>Type: {self.type} \n", 0.085) # printing the fighting moves typewriter.typing(f"=>The {self.name} scroll reads: ") for moves in self.fight_moves: self.fight_moves[moves].full_desc()
def search_inv(self): """Displays the dictionary of items in Player's bag attribute""" if len( self.bag ) < 1: # Testing if there are items to display from the Player's bag attribute typewriter.typing(f"=>Bag is empty", 0.035) else: # If the PLayer's bag attribute as items to display typewriter.typing(f"=>Items in bag:", 0.035) for item in self.bag: # Accessing the names of items from the Players bag attribute typewriter.typing(f"==>>{item}", 0.035)
def enhance(self, enhancer): """ Uses 'enhancer' as key to the Enhancement object in the Player's bag attribute, it will increase the damage dealt of specific fight moves from Player's fighting_moves attribute""" if enhancer in self.bag: # Testing if key exist if self.bag[ enhancer].type == "Improve": # Testing if item is Improve" type executed = False # Indicates that no fight move has been affected for fighting_move in self.fight_moves: # Increase damage of relevant fighting move(s) # Testing if fight move is the same style as the Enhancer object if self.fight_moves[fighting_move].style == self.bag[ enhancer].style: self.fight_moves[fighting_move].damage += self.bag[ enhancer].damage executed = True # testing if a move has been improved if not executed: typewriter.typing( f"=>No battle move is {self.bag[enhancer].style} style", 0.035) else: # If a fight move has been improved typewriter.typing( f"=>{self.bag[enhancer].style} style fighting moves increased damage by +{self.bag[enhancer].damage}", 0.065) del self.bag[enhancer] # removing the enhancer from bag else: # If item is not "Improve type" typewriter.typing(f"=>{enhancer} is not Improve type", 0.035) else: # If key doesn't exist typewriter.typing(f"=>{enhancer} not in bag")
def goto(self, new_location): """ Ues 'new_location' key to access the location from near_room attribute of Players current location """ if new_location == self.location.name: # Testing if Player's location attribute is the same as new_location typewriter.typing(f"=>Already in {new_location}", 0.035) # testing if new_location is in the near_rooms attribute of Player's location attribute elif not (new_location in self.location.near_rooms): # If new_location is not in the near_rooms attribute of Player's location typewriter.typing( f"=>{new_location} is far from {self.location.name}", 0.035) else: # If new_location is in the near_rooms attribute of Player's location self.location = self.location.near_rooms[ new_location] # Changing value of Player's location attribute typewriter.typing(f"=>You have entered {new_location}", 0.035)
def equip(self, armor): """ Uses 'armor' as key to the Armor object in Player's bag attribute, and replaces the Player's defence value with Armor object's defence value""" if armor in self.bag: # Testing if key exist if self.bag[ armor].type == "Armor": # Testing if item is "Armor" type self.defence = self.bag[ armor].defence # changing players defence value typewriter.typing(f"=>{armor} is equipped", 0.085) del self.bag[armor] # removing Armor object from bag else: # If item is not "Armor" type typewriter.typing(f"=>{armor} is not Armor type") else: # If key does'nt exist typewriter.typing(f"=>{armor} not in bag")
def learn(self, scroll): """ Uses 'scroll' as key to access the Scroll object from Player's bag attribute and replaces Player's fighting_moves dictionary attribute with the Scroll object's fighting_moves""" if scroll in self.bag: # Testing if key exists if self.bag[ scroll].type == "Learn": # Testing if item is "Learn" type # Replacing Player's fighting move attribute with Scroll objects's fighting move self.fight_moves = self.bag[scroll].fight_moves typewriter.typing( f"=>{self.name} has learnt the {scroll} scroll", 0.035) del self.bag[scroll] # removing Scroll object from bag else: # If item is not "Learn" type typewriter.typing(f"=>{scroll} is not Learn type", 0.035) else: # If key does'nt exist typewriter.typing(f"=>{scroll} not in bag", 0.035)
def my_story(self): # Prints the Players back story typewriter.typing(self.backstory, 0.035)
def look_around(self): # Displays useful info about Player's location # Printing out the description of the Player's location typewriter.typing(self.location.desc, 0.035) # Displaying items in Player's location if len(self.location.items ) < 1: # Testing if Player's location has Item instances typewriter.typing(f"=>{self.location.name} is empty\n") else: # Display the items in the Player's location typewriter.typing(f"\n=>Item to take:") # Accessing the items using the dictionary keys from the Player's location items dictionary for item in self.location.items: typewriter.typing(f"==>>{self.location.items[item].name}", 0.035) # ============================= # Displays the nearby Room exits in Player's location if len( self.location.near_rooms ) < 1: # Testing if Player's location has exits to other Room instances typewriter.typing(f"\n=>No room nearby") else: # Display the nearby Room instances typewriter.typing(f"\n=>Nearby rooms:") # Accessing the rooms using the dictionary keys from the near_room dictionary of Player's location for exits in self.location.near_rooms: typewriter.typing( f"==>>{self.location.near_rooms[exits].name}", 0.035) typewriter.typing("\n") # ============================= # Display the NPC's in the Player's location if len(self.location.people ) < 1: # Testing if the Player's location has NPCs typewriter.typing(f"\n=>Nobody in room") else: typewriter.typing(f"=>People to talk to:") # Accessing the NPCs using the dictionary keys from the people dictionary for person in self.location.people: typewriter.typing( f"==>>Name: {self.location.people[person].name}", 0.035)
def battle_loop(self, player, enemy, music_dir=None, start_pos=0.0): """ Takes Player and Enemy objects and a music directory that will play in the back ground""" # Playing background music try: mixer.music.load(music_dir) mixer.music.play(-1, start_pos) except (TypeError, error): # If music_dir is equal to "None" pass # ========================= while True: # ==>Displaying Player object battle stats typewriter.typing(("==" * 20), 0.00085) typewriter.typing(f"=>{player.name}'s condition:", 0.00005) typewriter.typing(f"=>Health: {player.hp}") typewriter.typing(f"=>Defence: {player.defence} \n", 0.00005) # ======================================== # ==>Displaying Enemy object battle stats typewriter.typing(f"==>>{enemy.name}'s condition:", 0.00005) typewriter.typing(f"=>Health: {enemy.hp}", 0.00005) typewriter.typing(f"=>Defence: {enemy.defence}", 0.00005) typewriter.typing(("==" * 20), 0.00085) # ======================================= # ==>Collecting player input/command player_move = input("Command: ") # ================================= # ==>Running input through CMD objects to collect relevant info for command in self.command_variant: test = command.breaker(player_move) if test: # Testing if input matches any CMD object try: # For input that has more to extract command_verb = command.name # Extracting the the player action/verb arg1 = test.group("arg1") # Object of the verb break except IndexError: # If verb is'nt paired with object command_verb = command.name break else: # If player_input doesnt have match typewriter.typing("!!>Action/verb is'nt understood<!!") continue # ===================================================== # ==>effects of player command" if command_verb == "show_move": # if player wishes to display their fighting move and its description player.show_move(arg1) elif command_verb == "battle_help": typewriter.typing(self.battle_help, 0.00005) elif command_verb == "stats": # display players stats , mainly to show them their fighting moves player.stats() elif command_verb == "attack": # when player wishes use a move to fight enemy self._battle_math(player, enemy, arg1) # ==>ending if player or enemy is dead if player.hp <= 1: # Testing if Player has 0 hp attribute player.hp = 1 # setting player health to 1 typewriter.typing(f"=>{player.name} has been defeated") typewriter.typing("=>YOU LOSE!!!") return 0 elif enemy.hp <= 1: # Testing if Enemy has 0 hp attribute typewriter.typing(f"=>{enemy.name} has been defeated") typewriter.typing("=>YOU WIN!!!") return 1 # ===================================== elif command_verb == "eat": # when player wants to increase their player player.eat(arg1) else: # If player inputs a command not related to battle_loop typewriter.typing( f"!!>{command_verb} not a Battle scene action<!!") try: mixer.music.fadeout(1000) except (TypeError, error): pass
def explore_loop(self, player, music_dir=None, start_pos=0.0): """ Take Player object and a music directory that will play in the back ground""" player.location = self.level_rooms # Setting the Player object's initial location # Playing background music try: mixer.music.load(music_dir) mixer.music.play(-1, start_pos) except (TypeError, error): # If music_dir is equal to "None" pass # ========================= while True: # ==>Collecting players input/command player_input = input("Command: ") # ================================ # ==>Running input through CMD objects to collect relevant info for command in self.command_variant: test = command.breaker(player_input) if test: # Testing if input matches any CMD object try: # For input that has more to extract command_verb = command.name # Extracting the the player action/verb arg1 = test.group("arg1") # Object of the verb break except IndexError: # If verb isn't paired with object command_verb = command.name break else: # If player_input doesnt have match typewriter.typing("!!>Action/verb isn't understood<!!") continue # ===================================================== # ==>effect of the players command if command_verb == "ex_help": typewriter.typing(self._explore_help, 0.0005) elif command_verb == "goto": # Change Player's location attribute player.goto(arg1) elif command_verb == "look_around": # display players location description player.look_around() elif command_verb == "examine_item": # Displays item description player.examine_item(arg1) elif command_verb == "throw": # Removing item from Player objects bag attribute player.throw(arg1) elif command_verb == "talk": # Print conversation text of NPC player.talk(arg1) elif command_verb == "take_item": # Removes item from Player object's location into bag attribute player.take_item(arg1) elif command_verb == "search_inv": # Displays Item objects that are in Player object's bag attribute player.search_inv() elif command_verb == "stats": # Displays useful info about the Player object player.stats() elif command_verb == "my_story": # Displays Player object's backstory attribute player.my_story() elif command_verb == "show_move": # Displays info about Player object's fight_move instance player.show_move(arg1) elif command_verb == "eat": # increase hp attribute of Player object player.eat(arg1) elif command_verb == "learn": # Changes the fighting_moves attribute of Player object player.learn(arg1) elif command_verb == "enhance": # increase the damage dealt of specific fight moves from Player's fighting_moves player.enhance(arg1) elif command_verb == "equip": # replaces the Player's defence value with Armor object's defence value player.equip(arg1) elif command_verb == "proceed": break # Fade out of background music try: mixer.music.fadeout(1000) except (TypeError, error): pass
def full_desc(self): typewriter.typing(f"==>>{self.name} description: {self.desc}<<== \n", 0.05)
def stats(self): """ Displays certain Player attributes on the screen""" typewriter.typing(f"=>{self.name}'s statistics:", 0.035) typewriter.typing(f"==>>Health: {self.hp}", 0.035) # Displaying Player's current hp value typewriter.typing(f"==>>Defence: {self.defence}", 0.035) # Displaying Player's current defence value try: typewriter.typing(f"==>>location: {self.location.name}", 0.035) except AttributeError: # If Player is not in a specific room pass typewriter.typing("\n=>Moves for battle:", 0.035) for moves in self.fight_moves: # Displaying the Player's fighting moves typewriter.typing(f"==>>{moves}", 0.035)