Пример #1
0
def handle_loot(character: Character, monster: Monster):
    """ Display the loot dropped from the monster and listen for input if the player wants to take any"""
    print_loot_table(monster.loot)
    while True:
        command = input()

        if command == 'take all':
            # takes everything

            gold = monster.give_loot('gold')
            if gold:  # if it's successful
                character.award_gold(gold)
                print(f'{character.name} has looted {gold} gold.')

            monster_loot = list(
                monster.loot.keys())  # list of strings, the item's names
            for item_name in monster_loot:
                # loop through them and get every one
                item: 'Item' = monster.give_loot(item_name=item_name)

                if item:  # if the loot is successful
                    character.award_item(item=item)
                    print(f'{character.name} has looted {item_name}.')

        elif "take" in command:
            item_name = command[5:]

            if item_name == "gold":
                gold = monster.give_loot("gold")

                if gold:  # if it's successful
                    character.award_gold(gold)
                    print(f'{character.name} has looted {gold} gold.')
            else:  # if we want to take an item
                item = monster.give_loot(item_name=item_name)

                if item:  # if the loot is successful
                    character.award_item(item=item)
                    print(f'{character.name} has looted {item_name}.')
        elif command == "?":
            pac_looting()
        elif command == "exit":  # end the looting process
            print('-' * 40)
            break
        else:
            print("Invalid command.")

        if not monster.loot:  # if the loot is empty, exit the loot window
            print('-' * 40)
            break

        print_loot_table(
            monster.loot
        )  # print the updated table each time we take something
Пример #2
0
def handle_loot(character: Character, monster: Monster):
    """ Display the loot dropped from the monster and listen for input if the player wants to take any"""
    print_loot_table(monster.loot)
    while True:
        command = input()

        if command == 'take all':
            # takes everything

            gold = monster.give_loot('gold')
            if gold:  # if it's successful
                character.award_gold(gold)
                print(f'{character.name} has looted {gold} gold.')

            monster_loot = list(monster.loot.keys())  # list of strings, the item's names
            for item_name in monster_loot:
                # loop through them and get every one
                item: 'Item' = monster.give_loot(item_name=item_name)

                if item:  # if the loot is successful
                    character.award_item(item=item)
                    print(f'{character.name} has looted {item_name}.')

        elif "take" in command:
            item_name = command[5:]

            if item_name == "gold":
                gold = monster.give_loot("gold")

                if gold:  # if it's successful
                    character.award_gold(gold)
                    print(f'{character.name} has looted {gold} gold.')
            else:  # if we want to take an item
                item = monster.give_loot(item_name=item_name)

                if item:  # if the loot is successful
                    character.award_item(item=item)
                    print(f'{character.name} has looted {item_name}.')
        elif command == "?":
            pac_looting()
        elif command == "exit":  # end the looting process
            print('-' * 40)
            break
        else:
            print("Invalid command.")

        if not monster.loot:  # if the loot is empty, exit the loot window
            print('-' * 40)
            break

        print_loot_table(monster.loot)  # print the updated table each time we take something
Пример #3
0
    def attack(self, victim: Monster):
        attacker_swing: (Damage, int) = self.get_auto_attack_damage(victim.level)

        auto_attack: Damage = attacker_swing[0]  # type: Damage
        # the sor_damage below is used just to check for printing
        sor_damage: int = attacker_swing[1]  # if the seal isn't active the damage will be 0

        auto_attack_print = victim.get_take_attack_damage_repr(auto_attack, self.level)
        if sor_damage:
            print(f'{self.name} attacks {victim.name} for {auto_attack_print} from {self.KEY_SEAL_OF_RIGHTEOUSNESS}!')
        else:
            print(f'{self.name} attacks {victim.name} for {auto_attack_print}!')

        victim.take_attack(auto_attack, self.level)
Пример #4
0
    def spell_melting_strike(self, spell: PaladinSpell, target: Monster):
        """ Damages the enemy for DAMAGE_1 damage and puts a DoT effect, the index of which is EFFECT
        :return successful cast or not"""
        mana_cost: int = spell.mana_cost
        damage: Damage = Damage(phys_dmg=spell.damage1)
        dot: 'DoT' = spell.harmful_effect
        dot.update_caster_level(self.level)

        self.mana -= mana_cost
        # damage the target and add the DoT
        print(f'{spell.name} damages {target.name} for {damage}!')
        target.take_attack(damage, self.level)
        target.add_buff(dot)

        return True
Пример #5
0
    def spell_melting_strike(self, spell: PaladinSpell, target: Monster):
        """ Damages the enemy for DAMAGE_1 damage and puts a DoT effect, the index of which is EFFECT
        :return successful cast or not"""
        mana_cost: int = spell.mana_cost
        damage: Damage = Damage(phys_dmg=spell.damage1)
        dot: 'DoT' = spell.harmful_effect
        dot.update_caster_level(self.level)

        self.mana -= mana_cost
        # damage the target and add the DoT
        print(f'{spell.name} damages {target.name} for {damage}!')
        target.take_attack(damage, self.level)
        target.add_buff(dot)

        return True
Пример #6
0
    def convert_to_living_thing_object(self) -> VendorNPC or FriendlyNPC or Monster:
        """ Converts the Creature to whatever object he is according to his type column """
        # TODO: move to creature_template.py
        entry: int = self.creature_id
        name: str = self.creature.name
        type_: str = self.creature.type
        level: int = parse_int(self.creature.level)
        health: int = parse_int(self.creature.health)
        mana: int = parse_int(self.creature.mana)
        armor: int = parse_int(self.creature.armor)
        min_dmg: int = parse_int(self.creature.min_dmg)
        max_dmg: int = parse_int(self.creature.max_dmg)
        quest_relation_id: int = parse_int(self.creature.quest_relation_id)
        loot_table: 'LootTable' = self.creature.loot_table
        gossip: str = self.creature.gossip
        respawnable: bool = self.creature.respawnable

        if type_ == "fnpc":
            return FriendlyNPC(name=name, health=health,
                               mana=mana, level=level,
                               min_damage=min_dmg,
                               max_damage=max_dmg,
                               quest_relation_id=quest_relation_id,
                               loot_table=loot_table,
                               gossip=gossip)

        elif type_ == "vendor":
            vendor_inventory = self.creature.build_vendor_inventory()
            return VendorNPC(name=name, entry=entry,
                             health=health, mana=mana, level=level,
                             min_damage=min_dmg,
                             max_damage=max_dmg,
                             quest_relation_id=quest_relation_id,
                             loot_table=loot_table,
                             inventory=vendor_inventory,
                             gossip=gossip)
        elif type_ == "monster":
            gold_to_give_range = (CREATURE_DEFAULT_VALUES[level]['min_gold_reward'],
                                  CREATURE_DEFAULT_VALUES[level]['max_gold_reward'])
            xp_to_give = CREATURE_DEFAULT_VALUES[level]['xp_reward']
            armor = armor if armor else CREATURE_DEFAULT_VALUES[level]['armor']
            return Monster(monster_id=entry,
                           name=name,
                           health=health,
                           mana=mana,
                           armor=armor,
                           level=level,
                           min_damage=min_dmg,
                           max_damage=max_dmg,
                           quest_relation_id=quest_relation_id,
                           loot_table=loot_table,
                           xp_to_give=xp_to_give,
                           gold_to_give_range=gold_to_give_range,
                           gossip=gossip,
                           respawnable=respawnable)
        else:
            raise Exception(f'{type_} is not a valid creature type!')
Пример #7
0
    def attack(self, victim: Monster):
        attacker_swing: (Damage,
                         int) = self.get_auto_attack_damage(victim.level)

        auto_attack: Damage = attacker_swing[0]  # type: Damage
        # the sor_damage below is used just to check for printing
        sor_damage: int = attacker_swing[
            1]  # if the seal isn't active the damage will be 0

        auto_attack_print = victim.get_take_attack_damage_repr(
            auto_attack, self.level)
        if sor_damage:
            print(
                f'{self.name} attacks {victim.name} for {auto_attack_print} from {self.KEY_SEAL_OF_RIGHTEOUSNESS}!'
            )
        else:
            print(
                f'{self.name} attacks {victim.name} for {auto_attack_print}!')

        victim.take_attack(auto_attack, self.level)
Пример #8
0
 def setUp(self):
     """
     Test loading three different types of monsters - vendor, fnpc, monster
     """
     self.monster_entry = 16
     self.monster_guid = 15
     self.monster_type = 'monster'
     self.monster_zone = 'Northshire Abbey'
     self.monster_subzone = 'A Peculiar Hut'
     self.monster_gold_range = range(5, 9)
     self.monster_respawnable = False
     self.monster = Monster(monster_id=self.monster_entry, name="Brother Paxton", health=25, mana=0, armor=80, level=3,
                            min_damage=7, max_damage=10, quest_relation_id=0, xp_to_give=100,
                            gold_to_give_range=(5, 8), loot_table=None, gossip="Nobody will foil our plans!")
Пример #9
0
def engage_combat(character: Character, monster: Monster, alive_monsters: dict, guid_name_set: set, monster_GUID: int):
    """
    This is where we handle the turn based combat of the game
    available_spells - set of string commands that enable our character to use the spells he has available.

    First we get both parties to enter combat. We start the loop and have the monster attack and
    immediately check if the character is not dead from the blow.
    If not, we take his command and if said command is one that does not end the turn (ie. wants to print some
    information about the fight) we enter an inner loop handling such commands and
    which continues to take commands until it gets one that does end the turn.
    We handle the command (which is most likely a spell or auto attack) and check if the monster is dead.
    :param character: the player
    :param monster: the monster that the player has attacked
    Parameters below are used solely to delete the monster from the dict & set once he's dead
    :param alive_monsters: Dictionary with the alive monsters in the subzone the player is in
    :param guid_name_set: Set which holds the name of each monster_GUID
    :param monster_GUID: The monster GUID
    """
    # Load all of the currently available spells for our character
    available_spells: set() = get_available_spells(character)
    will_end_turn = True  # Dictates if we are going to count the iteration of the loop as a turn

    character.enter_combat()
    monster.enter_combat()
    if monster.gossip:  # if the monster has gossip
        monster.say_gossip()
        sleep(2)

    while character.is_in_combat():
        # We start off the combat with the monster dealing the first blow
        if not will_end_turn:  # skip attack if the turn has not ended
            # skip turn based things
            will_end_turn = True
        else:
            monster.start_turn_update()
            character.start_turn_update()

            if monster.is_alive():
                monster.attack(character)
            else:  # monster has died, most probably from a DoT
                handle_monster_death(character, monster, alive_monsters, guid_name_set, monster_GUID)
                break

        if not character.is_alive():
            monster.leave_combat()
            print(f'{monster.name} has slain character {character.name}')

            prompt_revive(character)
            break

        command = input()
        # check if the command does not end the turn, if it doesn't the same command gets returned
        command = route_in_combat_non_ending_turn_commands(command, character, monster)

        if command == 'attack':
            character.attack(monster)
        elif command in available_spells:
            # try to execute the spell and return if it managed to or not
            successful_cast = character.spell_handler(command, monster)
            if not successful_cast:
                # skip the next attack, don't count this iteration as a turn and load a command again
                will_end_turn = False

        if will_end_turn:
            monster.end_turn_update()
            character.end_turn_update()

        if not monster.is_alive():
            handle_monster_death(character, monster, alive_monsters, guid_name_set, monster_GUID)
            break
Пример #10
0
def engage_combat(character: Character, monster: Monster, alive_monsters: dict,
                  guid_name_set: set, monster_GUID: int):
    """
    This is where we handle the turn based combat of the game
    available_spells - set of string commands that enable our character to use the spells he has available.

    First we get both parties to enter combat. We start the loop and have the monster attack and
    immediately check if the character is not dead from the blow.
    If not, we take his command and if said command is one that does not end the turn (ie. wants to print some
    information about the fight) we enter an inner loop handling such commands and
    which continues to take commands until it gets one that does end the turn.
    We handle the command (which is most likely a spell or auto attack) and check if the monster is dead.
    :param character: the player
    :param monster: the monster that the player has attacked
    Parameters below are used solely to delete the monster from the dict & set once he's dead
    :param alive_monsters: Dictionary with the alive monsters in the subzone the player is in
    :param guid_name_set: Set which holds the name of each monster_GUID
    :param monster_GUID: The monster GUID
    """
    # Load all of the currently available spells for our character
    available_spells: set() = get_available_spells(character)
    will_end_turn = True  # Dictates if we are going to count the iteration of the loop as a turn

    character.enter_combat()
    monster.enter_combat()
    if monster.gossip:  # if the monster has gossip
        monster.say_gossip()
        sleep(2)

    while character.is_in_combat():
        # We start off the combat with the monster dealing the first blow
        if not will_end_turn:  # skip attack if the turn has not ended
            # skip turn based things
            will_end_turn = True
        else:
            monster.start_turn_update()
            character.start_turn_update()

            if monster.is_alive():
                monster.attack(character)
            else:  # monster has died, most probably from a DoT
                handle_monster_death(character, monster, alive_monsters,
                                     guid_name_set, monster_GUID)
                break

        if not character.is_alive():
            monster.leave_combat()
            print(f'{monster.name} has slain character {character.name}')

            prompt_revive(character)
            break

        command = input()
        # check if the command does not end the turn, if it doesn't the same command gets returned
        command = route_in_combat_non_ending_turn_commands(
            command, character, monster)

        if command == 'attack':
            character.attack(monster)
        elif command in available_spells:
            # try to execute the spell and return if it managed to or not
            successful_cast = character.spell_handler(command, monster)
            if not successful_cast:
                # skip the next attack, don't count this iteration as a turn and load a command again
                will_end_turn = False

        if will_end_turn:
            monster.end_turn_update()
            character.end_turn_update()

        if not monster.is_alive():
            handle_monster_death(character, monster, alive_monsters,
                                 guid_name_set, monster_GUID)
            break
Пример #11
0
 def create_monster(self):
     MONSTER_MAX_HEALTH = 100
     monster_name = 'potwór_'+str(uuid.uuid4())[0:8]
     return Monster(monster_name, MONSTER_MAX_HEALTH)