示例#1
0
def cast_fireball(*args, **kwargs):
    entities = kwargs.get('entities')
    fov_map = kwargs.get('fov_map')
    damage = kwargs.get('damage')
    radius = kwargs.get('radius')
    target_x = kwargs.get('target_x')
    target_y = kwargs.get('target_y')

    results = []

    if not libtcod.map_is_in_fov(fov_map, target_x, target_y):
        results.append({'consumed': False,
                        'message': Message("You can't just go slinging fireballs without knowing where you're aiming!",
                                           libtcod.yellow)})
        return results

    results.append({'consumed': True,
                    'message': Message('The fireball explodes, burning everything within {0} tiles!'.format(radius),
                                       libtcod.orange)})

    for entity in entities:
        if entity.distance(target_x, target_y) <= radius and entity.combatant:
            results.append(
                {'message': Message('The {0} takes {1} fire damage!'.format(entity.name, damage), libtcod.orange)})
            results.extend(entity.combatant.lose_hp(damage))

    return results
示例#2
0
def cast_confuse(*args, **kwargs):
    entities = kwargs.get('entities')
    fov_map = kwargs.get('fov_map')
    target_x = kwargs.get('target_x')
    target_y = kwargs.get('target_y')

    results = []

    if not libtcod.map_is_in_fov(fov_map, target_x, target_y):
        results.append({'consumed': False,
                        'message': Message('You cannot target a tile outside your field of view.', libtcod.yellow)})
        return results
    for entity in entities:
        if entity.x == target_x and entity.y == target_y and entity.combatant.ai:
            confused_ai = ConfusedMonster(entity.combatant.ai, 10)

            confused_ai.owner = entity
            entity.combatant.ai = confused_ai

            results.append({'consumed': True, 'message': Message(
                'The eyes of the {0} look vacant, as they start to stumble around aimlessly...'.format(entity.name),
                libtcod.light_green)})
            break

    else:
        results.append(
            {'consumed': False, 'message': Message('There is no targetable enemy at that location.', libtcod.yellow)})

    return results
示例#3
0
def cast_lightning(*args, **kwargs):
    caster = args[0]
    entities = kwargs.get('entities')
    fov_map = kwargs.get('fov_map')
    damage = kwargs.get('damage')
    maximum_range = kwargs.get('maximum_range')

    results = []

    target = None
    closest_distance = maximum_range + 1

    for entity in entities:
        if entity.combatant and entity != caster and libtcod.map_is_in_fov(fov_map, entity.x, entity.y):
            distance = caster.distance_to(entity)

            if distance < closest_distance:
                target = entity
                closest_distance = distance

    if target:
        results.append({'consumed': True, 'target': target, 'message': Message(
            'A lightning bolt strikes the {0} with a loud thunder! {0} takes {1} damage!'.format(target.name, damage))})
        results.extend(target.combatant.lose_hp(damage))
    else:
        results.append(
            {'consumed': False, 'target': None, 'message': Message('No enemy is close enough to strike.', libtcod.red)})

    return results
示例#4
0
def attempt_pickup_item(party, entities):
    changes = []
    for entity in entities:
        if entity.x == party.x and entity.y == party.y and (party.inventory.unused_carry_capacity >= entity.mass):
            message = Message('{0} added to party inventory!'.format(entity.name), DARK_PURPLE)
            changes.extend([{'pickup_item': entity}, {'message': message}])
            break
    if len(entities) > 0 and len(changes) == 0:
        message = Message("That's too heavy! Get rid of some things or get stronger!", RED)
        changes.extend([{'message': message}])
    return changes
示例#5
0
def encounter_goto_life(self):
    changes = [{'state': 'life'}]
    xp = self.handler.loot.xp
    if xp > 0:
        changes.append({'xp': xp})
        message = Message('You gain {0} experience points!'.format(xp), DARK_ORANGE)
    else:
        message = Message("You didn't learn much there...", DARK_ORANGE)
    changes.append({'message': message})

    return changes
示例#6
0
    def logic(self):
        changes = [{'debug_message': Message('Command entered: ' + self.handler.current_input, WHITE)}]
        try:
            exec(self.handler.current_input, self.handler.allowed_inputs)
            changes.append({'debug_message': Message('COMMAND ACCEPTED', WHITE)})
            for message in self.handler.message_slot:
                changes.append({'debug_message': message})
            self.handler.current_input = ''
        except NameError:
            changes.append({'debug_message': Message('COMMAND NOT RECOGNIZED', WHITE)})

        return changes
示例#7
0
def heal(*args, **kwargs):
    combatant = args[0].combatant
    amount = kwargs.get('amount')

    results = []

    if combatant.attributes.current_hp == combatant.max_hp:
        results.append({'consumed': False, 'message': Message('You are already at full health!', libtcod.yellow)})
    else:
        combatant.gain_hp(amount)
        results.append({'consumed': True, 'message': Message('Your wounds start to heal!', libtcod.green)})

    return results
示例#8
0
def encounter_end_turn(self):
    changes = []
    if len(self.handler.combat.enemies.members) > 0:
        if self.handler.state is EncounterStates.ENEMY_TURN:
            changes.append({'substate': EncounterStates.THINKING})
        else:
            changes.append({'substate': EncounterStates.ENEMY_TURN})
            changes.append({'automate': 'enemy_turn'})
    else:
        changes.append({'message': Message('YOU WIN THE FIGHT!', BLACK)})
        changes.append({'message': Message('Press [Enter] to loot.', BLACK)})
        changes.append({'substate': EncounterStates.VICTORY})
    return changes
示例#9
0
    def str(self, obj, x, y):
        """Returns __str__ of obj on current map"""

        message = Message.placeholder()
        sub_obj = self.allowed_objs.get(obj)[y][x]
        message.text = str(sub_obj)
        self.message_slot = [message]
示例#10
0
    def spend_competence(self):

        comp_spender = self.owner
        if comp_spender.competence >= 0:
            results.append({
                'message':
                Message('What would you like to be better at?', libtcod.yellow)
            })
            return True
        else:
            results.append({
                'message':
                Message("You don't have the competence to spare!",
                        libtcod.yellow)
            })
            return False
示例#11
0
    def use(self, item_entity, **kwargs):
        results = []

        item_component = item_entity.item

        if item_component.equippable is not None:
            equippable_component = item_entity.item.equippable

            if equippable_component:
                results.append({'equip': item_entity})
            else:
                results.append({
                    'message':
                    Message('The {0} cannot be used'.format(item_entity.name),
                            YELLOW)
                })

        else:
            if item_component.useable.targeting and not (
                    kwargs.get('target_x') or kwargs.get('target_y')):
                results.append({'targeting': item_entity})
            else:
                kwargs = {**item_component.useable.function_kwargs, **kwargs}
                item_use_results = item_component.useable.use_function(
                    self.owner, **kwargs)

                for item_use_result in item_use_results:
                    if item_use_result.get('consumed'):
                        self.remove_item(item_entity)

                results.extend(item_use_results)

        return results
示例#12
0
    def name(self, obj, x, y):
        """Returns obj.name"""

        message = Message.placeholder()
        sub_obj = self.allowed_objs.get(obj)[y][x]
        if sub_obj is None:
            message.text = 'OBJECT NOT FOUND'
        else:
            message.text = sub_obj.name
        self.message_slot = [message]
示例#13
0
    def lose_hp(self, amount):
        
        results = []
        self.attributes.current_hp -= amount

        if self.attributes.current_hp <= 0:
            self.attributes.current_hp = 0
            # add overkill here later
            results.append({'dead': self.owner})
            results.append({'message': Message('{0} is dead!'.format(self.owner.name), DARK_RED)})

        return results
示例#14
0
def attempt_equip_item(party: PartyHandler, menu: AbstractMenu):
    slot = menu.pointer_data.item.equippable.slot
    currently_equipped = party.p1.combatant.equipment.slots_dict.get(slot)
    changes = []
    if currently_equipped:
        # check weight limit later
        changes.append({'dequipped': slot})
    changes.append({'equipped': menu})
    message = Message('{0} equipped the {1}!'.format(party.p1.name, menu.pointer_data.name), MIDNIGHT_BLUE)
    changes.append({'message': message})
    changes.append({'subsubstate': 2})
    return changes
示例#15
0
def interact(self):
    changes = []
    changes.extend(attempt_pickup_item(self.game.model.party, self.game.model.world.current_map.items))

    for entity in self.game.model.world.current_map.conversers:
        if entity.x == self.game.model.party.x and entity.y == self.game.model.party.y:
            self.game.dialogue.partner = entity
            self.game.dialogue.set_real_talk()
            self.game.state_handler = self.game.dialogue
            self.game.options.current = entity.converser.dialogue
    if len(changes) == 0:
        message = Message('Nothing to see here, move along...', DARK_BLUE)
        changes.append({'message': message})
    return changes
示例#16
0
    def attack(self, target):
        compare_slash = self.power_slash - target.combatant.resist_slash
        compare_pierce = self.power_pierce - target.combatant.resist_pierce
        compare_blunt = self.power_blunt - target.combatant.resist_blunt
        attack_type = None
        attack = None
        best_attack = max(compare_slash, compare_pierce, compare_blunt)
        if best_attack == compare_slash:
            attack_type, attack, resist_type = self.power_slash, 'slash', target.combatant.resist_slash
        elif best_attack == compare_pierce:
            attack_type, attack, resist_type = self.power_pierce, 'pierce', target.combatant.resist_pierce
        elif best_attack == compare_blunt:
            attack_type, attack, resist_type = self.power_blunt, 'blunt', target.combatant.resist_blunt

        results = []
        hit_vs_dodge = self.accuracy - target.combatant.dodge + random.randrange(100) - 50
        
        if hit_vs_dodge >= 0:
        
            #damage + or - 5% variation, rounded down
            damage = math.floor(((attack_type ** 2) - (resist_type))*((random.randrange(10)+95)/100))
            
            if damage > 0:
                results.append({'message': Message('{0} attacks {1} for {2} {3} damage.'.format(self.owner.name, target.name, str(damage), attack), BLACK)})
                results.extend(target.combatant.lose_hp(damage))

            else:
                results.append({'message': Message('{0} attacks {1} but does no damage!.'.format(self.owner.name, target.name), BLACK)})

            
        else:
        
            results.append({'message': Message('{0} attacks, but {1} dodges!'.format(self.owner.name, target.name), BLACK)})

        results.append({'end_turn': True})
        return results
示例#17
0
    def drop_item(self, item):
        results = []

        if self.owner.combatant.equipment.main_hand == item or self.owner.combatant.equipment.off_hand == item or self.owner.combatant.equipment.head == item or self.owner.combatant.equipment.body == item or self.owner.combatant.equipment.feet == item or self.owner.combatant.equipment.belt == item or self.owner.combatant.equipment.hands == item or self.owner.combatant.equipment.finger == item or self.owner.combatant.equipment.neck == item or self.owner.combatant.equipment.back == item or self.owner.combatant.equipment.accessory == item:
            self.owner.combatant.equipment.toggle_equip(item)

        item.x = self.owner.x
        item.y = self.owner.y
        self.remove_item(item)
        results.append({
            'item_dropped':
            item,
            'message':
            Message('You dropped the {0}!'.format(item.name), YELLOW)
        })

        return results
示例#18
0
 def bool_map(self, obj):
     """Returns current map as ASCII made of 1's and 0's based on existence of obj"""
     mes = []
     tiles = self.owner.world.current_map.tiles
     obj_dict = {
         'transition':
         [[tile.floor.transition for tile in row] for row in tiles],
     }
     vals = obj_dict.get(obj)
     for row in vals:
         message = Message.placeholder()
         text = ''
         for val in row:
             if val is not None:
                 text += '1 '
             else:
                 text += '0 '
         message.text = text
         mes.append(message)
     self.message_slot = mes
示例#19
0
    def take_turn(self, target, fov_map, game_map, entities):
        results = []

        if self.number_of_turns > 0:
            random_x = self.owner.x + randint(0, 2) - 1
            random_y = self.owner.y + randint(0, 2) - 1

            if random_x != self.owner.x and random_y != self.owner.y:
                self.owner.move_towards(random_x, random_y, game_map, entities)

            self.number_of_turns -= 1
        else:
            self.owner.ai = self.previous_ai
            results.append({
                'message':
                Message(
                    'The {0} is no longer confused!'.format(self.owner.name),
                    libtcod.red)
            })

        return results
示例#20
0
def drop_item(party: PartyHandler, menu: AbstractMenu):
    message = Message('{0} was dropped on the ground.'.format(menu.pointer_data.name), BLACK)
    return [{'drop_item': menu}, {'message': message}, {'subsubstate': 2}]
示例#21
0
def make_item(item_choice):
    """Will be reworked along with item update, but still functional as is"""

    if item_choice == 'healing_potion':

        item_component = Item(5,
                              useable=Useable('Healing Potion',
                                              BUNDLE_POTION,
                                              use_function=heal,
                                              amount=400))
        item = Entity(0, 0, render_order=RenderOrder.ITEM, item=item_component)
    elif item_choice == 'sword':
        image = BUNDLE_WEAPONS.get('longsword')
        equippable_core = EquippableCore('longsword', image)
        equippable_material = EquippableMaterial('wood')
        equippable_quality = EquippableQuality('average')

        equippable_component = Equippable('Sword', image,
                                          EquipmentSlots.MAIN_HAND,
                                          equippable_core, equippable_material,
                                          equippable_quality)
        item_component = Item(equippable_component)
        item = Entity(0, 0, item=item_component)
    elif item_choice == 'shield':
        image = BUNDLE_WEAPONS.get('shield')
        equippable_core = EquippableCore('shield', image)
        equippable_material = EquippableMaterial('iron')
        equippable_quality = EquippableQuality('average')

        equippable_component = Equippable('Shield', image,
                                          EquipmentSlots.OFF_HAND,
                                          equippable_core, equippable_material,
                                          equippable_quality)
        item_component = Item(equippable_component)
        item = Entity(0, 0, item=item_component)
    elif item_choice == 'fireball_scroll':
        image = SCROLL
        msg = 'Left-click a target tile for the fireball, or right-click to rethink your life decisions.'
        item_component = Item(
            useable=Useable('Fireball Scroll',
                            image,
                            use_function=cast_fireball,
                            targeting=True,
                            targeting_message=Message(msg, libtcod.light_cyan),
                            damage=250,
                            radius=3))
        item = Entity(0, 0, render_order=RenderOrder.ITEM, item=item_component)
    elif item_choice == 'confusion_scroll':
        image = SCROLL
        item_component = Item(useable=Useable(
            'Confusion Scroll',
            image,
            use_function=cast_confuse,
            targeting=True,
            targeting_message=Message(
                'Left-click an enemy to confuse it, or right-click to cancel.',
                libtcod.light_cyan)))
        item = Entity(0, 0, render_order=RenderOrder.ITEM, item=item_component)
    elif item_choice == 'lightning_scroll':
        image = SCROLL
        item_component = Item(useable=Useable('Lightning Scroll',
                                              image,
                                              use_function=cast_lightning,
                                              damage=400,
                                              maximum_range=5))
        item = Entity(0, 0, render_order=RenderOrder.ITEM, item=item_component)

    return item
示例#22
0
def kill_player(player):
    make_corpse(player)

    return Message('You died!', RED), GameStates.PLAYER_DEAD