Esempio n. 1
0
    def use(self, item_entity, **kwargs):
        results = []

        item_component = item_entity.item

        if item_component.use_function is None:
            equippable_component = item_entity.equippable

            if equippable_component:
                results.append({'equip': item_entity})
            else:
                results.append({
                    'message':
                    Message('The {0} cannot be used'.format(item_entity.name),
                            libtcod.yellow)
                })
        else:
            if item_component.targeting and not (kwargs.get('target_x')
                                                 or kwargs.get('target_y')):
                results.append({'targeting': item_entity})
            else:
                kwargs = {**item_component.function_kwargs, **kwargs}
                item_use_results = item_component.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
Esempio n. 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.ai:
            confused_ai = ConfusedMonster(entity.ai, 10)

            confused_ai.owner = entity
            entity.ai = confused_ai

            results.append({
                'consumed':
                True,
                'message':
                Message(
                    'The eyes of the {0} look vacant, as he starts to stumble around!'
                    .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
Esempio n. 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.fighter 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 lighting bolt strikes the {0} with a loud thunder! The damage is {1}'
                .format(target.name, damage))
        })
        results.extend(target.fighter.take_damage(damage))
    else:
        results.append({
            'consumed':
            False,
            'target':
            None,
            'message':
            Message('No enemy is close enough to strike.', libtcod.red)
        })

    return results
Esempio n. 4
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 cannot target a tile outside your field of view.',
                    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.fighter:
            results.append({
                'message':
                Message(
                    'The {0} gets burned for {1} hit points.'.format(
                        entity.name, damage), libtcod.orange)
            })
            results.extend(entity.fighter.take_damage(damage))

    return results
Esempio n. 5
0
    def add_item(self, item):
        results = []

        if len(self.items) >= self.capacity:
            results.append({
                'item_added':
                None,
                'message':
                Message('You cannot carry any more, your inventory is full',
                        libtcod.yellow)
            })
        else:
            results.append({
                'item_added':
                item,
                'message':
                Message('You pick up the {0}!'.format(item.name), libtcod.blue)
            })

            self.items.append(item)

        return results
Esempio n. 6
0
def kill_monster(monster):
    death_message = Message('{0} is dead!'.format(monster.name.capitalize()),
                            libtcod.orange)

    monster.char = '%'
    monster.color = libtcod.dark_red
    monster.blocks = False
    monster.fighter = None
    monster.ai = None
    monster.name = 'remains of ' + monster.name
    monster.render_order = RenderOrder.CORPSE

    return death_message
Esempio n. 7
0
def heal(*args, **kwargs):
    entity = args[0]
    amount = kwargs.get('amount')

    results = []

    if entity.fighter.hp == entity.fighter.max_hp:
        results.append({
            'consumed':
            False,
            'message':
            Message('You are already at full health', libtcod.yellow)
        })
    else:
        entity.fighter.heal(amount)
        results.append({
            'consumed':
            True,
            'message':
            Message('Your wounds start to feel better!', libtcod.green)
        })

    return results
Esempio n. 8
0
    def attack(self, target):
        results = []

        damage = self.power - target.fighter.defense

        if damage > 0:
            results.append({
                'message':
                Message(
                    '{0} attacks {1} for {2} hit points.'.format(
                        self.owner.name.capitalize(), target.name,
                        str(damage)), libtcod.white)
            })
            results.extend(target.fighter.take_damage(damage))
        else:
            results.append({
                'message':
                Message(
                    '{0} attacks {1} but does no damage.'.format(
                        self.owner.name.capitalize(), target.name),
                    libtcod.white)
            })

        return results
Esempio n. 9
0
    def next_floor(self, player, message_log, constants):
        self.dungeon_level += 1
        entities = [player]

        self.tiles = self.initialize_tiles()
        self.make_map(constants['max_rooms'], constants['room_min_size'],
                      constants['room_max_size'], constants['map_width'],
                      constants['map_height'], player, entities)

        player.fighter.heal(player.fighter.max_hp // 2)

        message_log.add_message(
            Message('You take a moment to rest, and recover your strength.',
                    libtcod.light_violet))

        return entities
Esempio n. 10
0
    def drop_item(self, item):
        results = []

        if self.owner.equipment.main_hand == item or self.owner.equipment.off_hand == item:
            self.owner.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), libtcod.yellow)
        })

        return results
Esempio n. 11
0
    def from_json(json_data):
        use_function_name = json_data.get('use_function')
        targeting = json_data.get('targeting')
        targeting_message_json = json_data.get('targeting_message')
        function_kwargs = json_data.get('function_kwargs', {})

        if use_function_name:
            use_function = getattr(item_functions, use_function_name)
        else:
            use_function = None

        if targeting_message_json:
            targeting_message = Message.from_json(targeting_message_json)
        else:
            targeting_message = None

        item = Item(use_function, targeting, targeting_message,
                    **function_kwargs)

        return item
Esempio n. 12
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
Esempio n. 13
0
    def place_entities(self, room, entities):
        max_monsters_per_room = from_dungeon_level([[2, 1], [3, 4], [5, 6]],
                                                   self.dungeon_level)
        max_items_per_room = from_dungeon_level([[1, 1], [2, 4]],
                                                self.dungeon_level)

        # Get a random number of monsters
        number_of_monsters = randint(0, max_monsters_per_room)

        # Get a random number of items
        number_of_items = randint(0, max_items_per_room)

        monster_chances = {
            'orc':
            80,
            'troll':
            from_dungeon_level([[15, 3], [30, 5], [60, 7]], self.dungeon_level)
        }

        item_chances = {
            'healing_potion': 35,
            'sword': from_dungeon_level([[5, 4]], self.dungeon_level),
            'shield': from_dungeon_level([[15, 8]], self.dungeon_level),
            'lightning_scroll': from_dungeon_level([[25, 4]],
                                                   self.dungeon_level),
            'fireball_scroll': from_dungeon_level([[25, 6]],
                                                  self.dungeon_level),
            'confusion_scroll': from_dungeon_level([[10, 2]],
                                                   self.dungeon_level)
        }

        for i in range(number_of_monsters):
            # Choose a random location in the room
            x = randint(room.x1 + 1, room.x2 - 1)
            y = randint(room.y1 + 1, room.y2 - 1)

            # Check if an entity is already in that location
            if not any([
                    entity
                    for entity in entities if entity.x == x and entity.y == y
            ]):
                monster_choice = random_choice_from_dict(monster_chances)

                if monster_choice == 'orc':
                    fighter_component = Fighter(hp=20,
                                                defense=0,
                                                power=4,
                                                xp=35)
                    ai_component = BasicMonster()

                    monster = Entity(x,
                                     y,
                                     'o',
                                     libtcod.desaturated_green,
                                     'Orc',
                                     blocks=True,
                                     render_order=RenderOrder.ACTOR,
                                     fighter=fighter_component,
                                     ai=ai_component)
                else:
                    fighter_component = Fighter(hp=30,
                                                defense=2,
                                                power=8,
                                                xp=100)
                    ai_component = BasicMonster()

                    monster = Entity(x,
                                     y,
                                     'T',
                                     libtcod.darker_green,
                                     'Troll',
                                     blocks=True,
                                     fighter=fighter_component,
                                     render_order=RenderOrder.ACTOR,
                                     ai=ai_component)

                entities.append(monster)

        for i in range(number_of_items):
            x = randint(room.x1 + 1, room.x2 - 1)
            y = randint(room.y1 + 1, room.y2 - 1)

            if not any([
                    entity
                    for entity in entities if entity.x == x and entity.y == y
            ]):
                item_choice = random_choice_from_dict(item_chances)

                if item_choice == 'healing_potion':
                    item_component = Item(use_function=heal, amount=40)
                    item = Entity(x,
                                  y,
                                  '!',
                                  libtcod.violet,
                                  'Healing Potion',
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                elif item_choice == 'sword':
                    equippable_component = Equippable(EquipmentSlots.MAIN_HAND,
                                                      power_bonus=3)
                    item = Entity(x,
                                  y,
                                  '/',
                                  libtcod.sky,
                                  'Sword',
                                  equippable=equippable_component)
                elif item_choice == 'shield':
                    equippable_component = Equippable(EquipmentSlots.OFF_HAND,
                                                      defense_bonus=1)
                    item = Entity(x,
                                  y,
                                  '[',
                                  libtcod.darker_orange,
                                  'Shield',
                                  equippable=equippable_component)
                elif item_choice == 'fireball_scroll':
                    item_component = Item(
                        use_function=cast_fireball,
                        targeting=True,
                        targeting_message=Message(
                            'Left-click a target tile for the fireball, or right-click to cancel.',
                            libtcod.light_cyan),
                        damage=25,
                        radius=3)
                    item = Entity(x,
                                  y,
                                  '#',
                                  libtcod.red,
                                  'Fireball Scroll',
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                elif item_choice == 'confusion_scroll':
                    item_component = Item(
                        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(x,
                                  y,
                                  '#',
                                  libtcod.light_pink,
                                  'Confusion Scroll',
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                else:
                    item_component = Item(use_function=cast_lightning,
                                          damage=40,
                                          maximum_range=5)
                    item = Entity(x,
                                  y,
                                  '#',
                                  libtcod.yellow,
                                  'Lightning Scroll',
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)

                entities.append(item)
Esempio n. 14
0
def kill_player(player):
    player.char = '%'
    player.color = libtcod.dark_red

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