def eat(element: Food, scenario: Scenario): __element = system_name(element) if Hero.has_item(__element): this_item = Hero.get_item_from_inventory(__element) if type(this_item) == Food: print(f'You eat {system_name_with_article(this_item.name)}.') this_item.remove(1) if this_item.quantity == 0: print(f'You have no more {this_item.name}s left.') Hero.inventory.remove(this_item) elif any(system_name(__item.name).split()[-1] == __element for __item in scenario.elements) or \ any(system_name(__something.name).split()[-1] == __element for __something in scenario.floor): print_cinematics('You can only eat things that you have with you.') elif any( system_name(__something.name).startswith('body') for __something in scenario.floor) and 'body' in __element: for __something in scenario.floor: if element.startswith('body') and system_name( __something.name).startswith('body'): print( f'You would need to be really starving to death to even think about eating the {__something.name}.' ) # print( # f'The {__something.name} laying on the floor {__something.verb} {__something.description}.') # if type(__something) == NPC: # looking_body(__something, scenario) else: print_cinematics(f'You can\'t eat that.')
def simultaneous_damage(results_number_hero: int, Hero: Hero, results_number_enemy: int, enemy: NPC) -> None: ''' It is called whenever the Hero and the enemy cause mutual damage. Calculates damage, checks if both are hurt or dead and calls next round. ''' new_hero_hp = Hero.hp - abs(results_number_enemy) Hero.hp = new_hero_hp Hero.set_status() new_enemy_hp = enemy.hp - abs(results_number_hero) enemy.hp = new_enemy_hp enemy.set_status() print('Current HPs after the simultaneous attack:') print(f'You: {Hero.hp}') print(f'{enemy.name}: {enemy.hp}') print_cinematics(Hero.declare_status) print_cinematics(enemy.declare_status) if Hero.status == 'dead' and enemy.status == 'dead': reset_rounds() death.mutual_death_by_combat(enemy) elif Hero.status == 'dead': reset_rounds() death.death_by_simultaneous_attack(enemy, results_number_hero) elif enemy.status == 'dead': reset_rounds() kills.killed_enemy_on_simultaneous_attack(Hero, enemy) else: cinematics_block() if results_number_hero > 0 and results_number_enemy > 0: print_cinematics( f'You and {enemy.name} hit each other at the same time, causing mutual damage.' ) elif results_number_hero > 0: print_cinematics( f'You parry the {enemy.name} attack and hit {enemy.pronom[3]}, causing some damage.' ) elif results_number_enemy > 0: print_cinematics( f'Taking advantage of your innefective attack, {enemy.name} strikes you a blow.' ) else: print_cinematics( f'You clash with {enemy.name}, but but your attaks block each other.' ) cinematics_block() print('\nStart next round.\n') next_round(Hero, enemy)
def drop(element: Union[str, NPC], scenario: Scenario) -> None: ''' Function fired when the Player wants the Hero to drop something. ''' if not element: print('Which item would you like to drop?') Hero.declare_inventory() which_item = input('> ') __element: str = system_name(which_item) else: __element: str = system_name(element) this_element: Item = Hero.get_item_from_inventory(__element) if this_element: if this_element not in scenario.floor: scenario.add_to_floor(this_element) Hero.drop_item(this_element) else: equiped_item: Item = Hero.get_equiped_item(__element) if equiped_item: scenario.add_to_floor(equiped_item) Hero.drop_item(equiped_item) else: print('You can\'t drop items that you don\'t have.')
def search(element: str, scenario: Scenario) -> None: ''' It is called when the Hero searches somewhere. ''' __element = system_name(element) if any(system_name(__item).split()[-1] == __element for __item in scenario.ambient): print_cinematics(f'You search the {element} but you find nothing.') elif any(system_name(__item).split()[-1] == __element for __item in scenario.far_away): print_cinematics(f'It is too far away.') elif any(system_name(__item.name).split()[-1] == __element for __item in scenario.elements): searching_element = scenario.get_element(element) searching_element.on_searching() elif any(system_name(__item.name).startswith('body') for __item in Hero.inventory) and \ element.startswith('body'): print_cinematics( f'You can\'t search the body while you are carrying it.') elif any(system_name(__item.name).split()[-1] == __element for __item in Hero.inventory): __item_from_inv: Item = Hero.get_item_from_inventory(element) __item_from_inv.on_searching() elif any(system_name(__something.name).split()[-1] == __element for __something in scenario.floor) or \ any(system_name(__something.name).startswith('body') for __something in scenario.floor) and 'body' in __element: for __something in scenario.floor: if element.startswith('body') and system_name(__something.name).startswith('body'): in_inventory = __something.declare_inventory() for __item in __something.inventory: scenario.add_to_floor(__item) __something.inventory.remove(__item) searching_body(in_inventory, __something, scenario) elif system_name(__something.name).split()[-1] == __element: __something.on_searching() else: print_cinematics( f'There is nothing to be found.')
# ELEMENTS THAT CAN BE LIMITEDLY INTERACTED WITH. testing_forest.ambient = ['trail', 'field'] testing_forest.far_away = ['river', 'old bridge'] # ELEMENTS THAT CAN BE USED AS SAFE PLACES FOT THE HERO TO HIDE AND REST. testing_forest.safe_places = ['bushes'] # EXIT POINTS THAT CONNECT TO OTHER SCENARIOS. # GLOBAL CONTAINERS FROM THE SCENARIO THAT CAN BE IMMEDIATELLY INTERACTED WITH. trees = Container('trees', 'big and very green apple trees') bushes = Container('bushes', '3 feet green bushes full of leaves') bushes.searching_effect = [ 'You spend a very long time searching the bushes and start to feel tired.', lambda: Hero.set_status('tired') ] # TODO: up one degree.. well -> tired -> very tired # SPECIFIC ITEMS THAT CANNOT BE IMMEDIATELLY INTERACTED WITH. trees.add_item(apple) apple.add() # apple.on_taking = lambda: 'keep' bushes.add_item(golden_coin, 'hidden') golden_coin.hidden = True # ADDS GLOBAL CONTAINERS TO THE SCENARIO INSTANCE SO THEY CAN BE INTERACTED WITH. testing_forest.add_to_scenario('bushes', bushes) testing_forest.add_to_scenario('trees', trees)
def equip(item: str) -> None: ''' Function fired when the Player wants the Hero to equip a weapon, shield or armor. ''' Hero.equip(item)
def take(element: str, scenario: Scenario) -> None: ''' Function fired when the Player wants the Hero to take something from the Scenario. ''' Hero.update_weigth() element = system_name(element) if any(__item.endswith(element) for __item in scenario.ambient): print('There\'s no point in doing it.') elif any(__item.endswith(element) for __item in scenario.far_away): print('Even if you could take it, it is too far away.') elif any(system_name(__item.name).endswith(element) for __item in scenario.floor) or \ element.startswith('body'): for __item in scenario.floor: __item: Union[Item, NPC] if system_name(__item.name).startswith('body') and system_name(element).startswith('body') or \ system_name(__item.name).endswith(element) and system_name(__item.name).startswith('body'): __item.update_weigth() if Hero.carrying_weigth + __item.weight > Hero.weigth_capacity: print('It is too much for you to carry.') else: moving_body(__item, scenario) Hero.take_item(__item) scenario.floor.remove(__item) elif system_name(__item.name).endswith(element): if Hero.carrying_weigth + __item.weight > Hero.weigth_capacity: print('It is too much for you to carry.') else: if Hero.has_item(__item): owned_item = Hero.get_item_from_inventory(__item) owned_item.change_quantity(__item.quantity) Item_name_in_singular = owned_item.name[:-1] print( f'You get another {Item_name_in_singular}.') else: if hasattr(__item, 'on_taking') and __item.on_taking() == 'keep': __item = copy.copy(__item) else: scenario.floor.remove(__item) Hero.take_item(__item) elif any(system_name(__item.name).endswith(element) for __item in scenario.elements): this_element: Element = scenario.get_element(element) if type(this_element) == Container: print('You cannot take it.') elif Hero.carrying_weigth + this_element.weight > Hero.weigth_capacity: print('It is too much for you to carry.') elif Hero.has_item(this_element): owned_item = Hero.get_item_from_inventory(this_element) owned_item.add(this_element.quantity) Item_name_in_singular = owned_item.name[:-1] print( f'You get another {Item_name_in_singular}.') else: Hero.take_item(this_element) if not hasattr(this_element, 'on_taking') or this_element.on_taking() != 'keep': scenario.elements.remove(this_element) elif element.endswith('armor') and \ any(type(__thing) == NPC and __thing.armor.container != None for __thing in scenario.floor): for __thing in scenario.floor: if type(__thing) == NPC: if __thing.armor != None: __thing.armor.on_taking() __thing.armor.container = None Hero.take_item(__thing.armor) __thing.armor = None else: print(f'You don\'t see any {element} nearby to take it.')
def basic_actions(scenario: Scenario) -> None: ''' It is called to check Player decisions related to no-combat actions. ''' print_cinematics('What do you do?') while True: action = await_for_action() if action.startswith('look'): what = action.replace('look', '').replace( ' at ', '').replace(' the ', '').lstrip() look(what, scenario) elif action.startswith('search'): if action == 'search': print('You need to tell where would you like to search.') else: place: str = action.replace( 'search', '').replace('the', '').lstrip() search(place, scenario) elif action.startswith('take') or action.startswith('get'): what: str = action.replace('take', '').replace('get', '').lstrip() take(what, scenario) elif 'inventory' in action or 'items' in action: Hero.declare_inventory() elif 'bad inv' in action: print('$$$ Enemy Items', list( __this.name for __this in ugly_monster.inventory)) print('$$$ Enemy Weapons', list([getattr(ugly_monster.weapon, 'name', None), getattr(ugly_monster.armor, 'name', None), getattr(ugly_monster.shield, 'name', None)])) elif 'status' in action in action: print_cinematics(Hero.declare_status) elif action.startswith('draw'): item: str = action.replace( 'draw', '').replace('weapon', '').lstrip() if not Hero.weapon: print('You have no weapons.') else: weapon = Hero.get_equiped_item(item) if not weapon: print(f'{item.title()} is not your main weapon.') else: print(f'{Hero.draw_weapon}.') elif action.startswith('drop'): what: str = action.replace('drop', '').lstrip() drop(what, scenario) elif action.startswith('equip'): what: str = action.replace('equip', '').lstrip() equip(what) elif action.startswith('eat'): what: List = action.split(' ', 1)[1] eat(what, scenario) else: print('You can\'t do that.')
def look(element: str, scenario: Scenario) -> None: ''' It is called when the Hero looks at something. ''' __element = system_name(element) if __element == 'me': print_cinematics(f'You are {Hero.appearance}.') elif __element == 'floor': if len(scenario.floor) == 0: print('There\'s nothing special on the floor.') else: message = 'Looking at the floor you see' if len(scenario.floor) == 1: print_cinematics( f'{message} {scenario.floor[0].article[1]}{scenario.floor[0].name}.') else: print_cinematics( f'{message} {", ".join(f"{item.article[1]}{item.name}" for item in scenario.floor[: -1])} and {f"{scenario.floor[-1].article[0]}{scenario.floor[-1].name}"}.') elif __element == '' or __element == 'around': print_cinematics( f'You look around and you see {scenario.description}.') # elements derivated from the Class Item can be accessed by the final word of their names (ej. "sword" matches for "short sword") elif any(system_name(__item).split()[-1] == __element for __item in scenario.ambient): print_cinematics( f'You see nothing special about the {element}.') elif any(system_name(__item).split()[-1] == __element for __item in scenario.far_away): print_cinematics( f'You look at the {element}, but is too far away to see any details.') elif any(system_name(__item.name).split()[-1] == __element for __item in scenario.elements): looking_element = scenario.get_element(system_name(element)) print_cinematics( f'The {looking_element.name} {looking_element.verb} {looking_element.description}.') looking_element.on_looking() elif Hero.has_item(__element): this_item = Hero.get_item_from_inventory(__element) enough_for = '' if type(this_item) == Food: # I consider that the weight of food is enough for a full day, so multiplying quantity by the food weight returns for how many days one portion of this food is capable of sustaining the Hero. enough_for = f', enough for {int(this_item.quantity * this_item.unity_weight)} days' print( f'The {this_item.name} on your inventory {this_item.verb} {this_item.description}{enough_for}.') elif any(system_name(__something.name).split()[-1] == __element for __something in scenario.floor) or \ any(system_name(__something.name).startswith('body') for __something in scenario.floor) and 'body' in __element: for __something in scenario.floor: if element.startswith('body') and system_name(__something.name).startswith('body') or \ system_name(__something.name).endswith(__element): print( f'The {__something.name} laying on the floor {__something.verb} {__something.description}.') if type(__something) == NPC: looking_body(__something, scenario) else: print_cinematics( f'There is nothing to be seen.')