Ejemplo n.º 1
0
def dragonweed_pull(actor, target, context):
    if target.fighter.hp > 0:
        ui.message(
            "The dragonweed's stem lashes out at %s!" % syntax.name(target),
            libtcod.dark_green)
        result = combat.attack_ex(actor.fighter,
                                  target,
                                  0,
                                  accuracy_modifier=1.5,
                                  damage_multiplier=0.75,
                                  verb=('pull', 'pulls'))
        if result == 'hit' and target.fighter is not None:
            if 'displacement' in target.fighter.immunities:
                if fov.player_can_see(target.x, target.y):
                    ui.message(
                        '%s %s.' % (syntax.name(target).capitalize(),
                                    syntax.conjugate(target is player.instance,
                                                     ('resist', 'resists'))),
                        libtcod.gray)
                return 'success'
            beam = main.beam(actor.x, actor.y, target.x, target.y)
            pull_to = beam[max(len(beam) - 3, 0)]
            target.set_position(pull_to[0], pull_to[1])
            if main.roll_dice('1d10') <= 5:
                target.fighter.apply_status_effect(
                    effects.immobilized(duration=2), context['save_dc'], actor)
Ejemplo n.º 2
0
def zombie_on_hit(attacker, target, damage):
    if target.fighter is None:
        return
    if libtcod.random_get_int(0, 0, 100) < 20:
        ui.message(
            '%s grabs %s! %s cannot move!' %
            (syntax.name(attacker).capitalize(), syntax.name(target),
             syntax.pronoun(target).capitalize()), libtcod.yellow)
        target.fighter.apply_status_effect(effects.immobilized(3))
Ejemplo n.º 3
0
def knock_back(actor, target):
    # check for resistance
    if 'displacement' in target.fighter.immunities:
        if fov.player_can_see(target.x, target.y):
            ui.message(
                '%s %s.' % (syntax.name(target).capitalize(),
                            syntax.conjugate(target is player.instance,
                                             ('resist', 'resists'))),
                libtcod.gray)
        return 'resisted'

    # knock the target back one space. Stun it if it cannot move.
    direction = target.x - actor.x, target.y - actor.y  # assumes the instance is adjacent
    stun = False
    against = ''
    against_tile = main.current_map.tiles[target.x +
                                          direction[0]][target.y +
                                                        direction[1]]
    if against_tile.blocks and not against_tile.is_pit:
        stun = True
        against = main.current_map.tiles[target.x +
                                         direction[0]][target.y +
                                                       direction[1]].name
    elif against_tile.elevation != target.elevation and against_tile.tile_type != 'ramp' and \
                    main.current_map.tiles[target.x][target.y] != 'ramp':
        stun = True
        against = 'cliff'
    else:
        for obj in main.current_map.objects:
            if obj.x == target.x + direction[
                    0] and obj.y == target.y + direction[1] and obj.blocks:
                stun = True
                against = obj.name
                break

    if stun:
        #  stun the target
        if target.fighter.apply_status_effect(effects.stunned(duration=2)):
            ui.message(
                '%s %s with the %s, stunning %s!' %
                (syntax.name(target).capitalize(),
                 syntax.conjugate(target is actor,
                                  ('collide', 'collides')), against,
                 syntax.pronoun(target, objective=True)), libtcod.gold)
    else:
        ui.message(
            '%s %s knocked backwards.' %
            (syntax.name(target).capitalize(),
             syntax.conjugate(target is actor, ('are', 'is'))), libtcod.gray)
        target.set_position(target.x + direction[0], target.y + direction[1])
        main.render_map()
        libtcod.console_flush()
Ejemplo n.º 4
0
def heal_other(actor, target, context):
    if actor is player.instance:
        ui.message('Yo implement this', libtcod.red)
        return 'failure'

    ui.render_explosion(target.x, target.y, 0, libtcod.lightest_green,
                        libtcod.green)
    amount = main.roll_dice('3d4')
    target.fighter.heal(amount)
    ui.message(
        '%s %s %s for %d damage.' %
        (syntax.name(actor).capitalize(),
         syntax.conjugate(actor is player.instance, ('heal', 'heals')),
         syntax.name(target, reflexive=actor), amount), libtcod.green)
    return 'success'
Ejemplo n.º 5
0
def spawn_spiders(actor, target, context):
    #Filthy hackery to add some state
    if not hasattr(actor, 'summons'):
        actor.summons = []

    for s in actor.summons:  # clear dead things from summoned list
        if not s.fighter:
            actor.summons.remove(s)

    if len(actor.summons) < context['max_summons']:
        summon_tiles = []
        for y in range(3):
            for x in range(3):
                pos = actor.x - 1 + x, actor.y - 1 + y
                if main.in_bounds(pos[0], pos[1]) and not main.is_blocked(
                        pos[0], pos[1]):
                    summon_tiles.append(pos)
        summon_count = main.roll_dice(context['summons_per_cast'])
        for i in range(summon_count):
            if len(summon_tiles) > 0 and len(
                    actor.summons) < context['max_summons']:
                pos = summon_tiles[libtcod.random_get_int(
                    0, 0,
                    len(summon_tiles) - 1)]
                spawn = main.spawn_monster('monster_tunnel_spider', pos[0],
                                           pos[1])
                ui.message(
                    'A ' + spawn.name + " crawls from beneath %s cloak." %
                    syntax.name(actor, possesive=True), actor.color)
                actor.summons.append(spawn)
                summon_tiles.remove(pos)
        return 'success'
    return 'cancelled'
Ejemplo n.º 6
0
def blastcap_explode(blastcap, context):
    blastcap.fighter = None
    main.current_map.fighters.remove(blastcap)
    ui.render_explosion(blastcap.x,
                        blastcap.y,
                        1,
                        libtcod.gold,
                        libtcod.white,
                        distance_h='manhattan')
    ui.message('The blastcap explodes with a BANG, stunning nearby creatures!',
               libtcod.gold)
    for obj in main.current_map.fighters:
        if main.is_adjacent_orthogonal(blastcap.x, blastcap.y, obj.x, obj.y):
            if obj.fighter.apply_status_effect(
                    effects.stunned(duration=context['duration'])):
                ui.message(
                    '%s %s stunned!' %
                    (syntax.name(obj).capitalize(),
                     syntax.conjugate(obj is player.instance,
                                      ('are', 'is'))), libtcod.gold)

    if ui.selected_monster is blastcap:
        main.changed_tiles.append((blastcap.x, blastcap.y))
        ui.selected_monster = None
        ui.auto_target_monster()

    blastcap.destroy()
    return
Ejemplo n.º 7
0
def disarm(target):
    if target is None or target.fighter is None:
        return 'failure'
    weapon = main.get_equipped_in_slot(target.fighter.inventory, 'right hand')
    if weapon is None:
        return 'failure'
    weapon.dequip(no_message=True)
    possible_tiles = []
    for x in range(target.x - 1, target.x + 2):
        for y in range(target.y - 1, target.y + 2):
            if not main.is_blocked(
                    x, y, from_coord=(target.x, target.y), movement_type=1):
                possible_tiles.append((x, y))
    if len(possible_tiles) == 0:
        selected_tile = main.find_closest_open_tile(target.x, target.y)
    else:
        selected_tile = possible_tiles[libtcod.random_get_int(
            0, 0,
            len(possible_tiles) - 1)]
    weapon.owner.item.drop(no_message=True)
    weapon.owner.x = selected_tile[0]
    weapon.owner.y = selected_tile[1]
    ui.message(
        '%s %s disarmed!' % (syntax.name(target).capitalize(),
                             syntax.conjugate(target is player.instance,
                                              ('are', 'is'))), libtcod.red)
    return 'success'
Ejemplo n.º 8
0
def strangleweeds(actor, target, context):
    hit = False
    for f in main.get_fighters_in_burst(
            actor.x, actor.y, context['range'], actor,
            lambda o: o.fighter.team != actor.fighter.team):
        tile = main.current_map.tiles[f.x][f.y]
        if tile.tile_type == 'grass floor':
            if actor is player.instance or fov.player_can_see(f.x, f.y):
                ui.message(
                    'Writhing vines grip %s and hold %s in place!' %
                    (syntax.name(f), syntax.pronoun(f)),
                    spells.essence_colors['life'])
            f.fighter.apply_status_effect(
                effects.immobilized(duration=context['duration']))
            f.fighter.apply_status_effect(
                effects.StatusEffect(
                    'strangleweeds',
                    time_limit=context['duration'],
                    color=libtcod.lime,
                    on_tick=strangleweed_on_tick,
                    message='The strangleweeds crush you!',
                    description='This unit will take damage every turn',
                    cleanseable=True))
            hit = True
    if hit:
        return 'success'
    else:
        if actor is player.instance:
            ui.message("You can't see any susceptible targets.", libtcod.gray)
        return 'cancelled'
Ejemplo n.º 9
0
def flash_frost(actor, target, context):
    target.fighter.apply_status_effect(effects.frozen(5))
    if actor is player.instance or fov.player_can_see(target.x, target.y):
        ui.message(
            '%s %s frozen solid!' %
            (syntax.name(target).capitalize(),
             syntax.conjugate(target is player.instance,
                              ('are', 'is'))), spells.essence_colors['cold'])
Ejemplo n.º 10
0
def teleport(actor, x, y):
    if actor is None:
        actor = player.instance

    if actor is player.instance or fov.player_can_see(actor.x, actor.y):
        ui.message(
            '%s %s in a crackle of magical energy!' %
            (syntax.name(actor).capitalize(),
             syntax.conjugate(actor is player.instance,
                              ('vanish', 'vanishes'))),
            spells.essence_colors['arcane'])
    actor.set_position(x, y)
    if actor is not player.instance and fov.player_can_see(actor.x, actor.y):
        ui.message(
            '%s appears out of thin air!' % syntax.name(actor).capitalize(),
            spells.essence_colors['arcane'])
    return 'success'
Ejemplo n.º 11
0
def on_hit_knockback(attacker, target, damage, force=6):
    if target.fighter is None:
        return

    if 'displacement' in target.fighter.immunities:
        if fov.player_can_see(target.x, target.y):
            ui.message(
                '%s %s.' % (syntax.name(target).capitalize(),
                            syntax.conjugate(target is player.instance,
                                             ('resist', 'resists'))),
                libtcod.gray)
        return

    diff_x = target.x - attacker.x
    diff_y = target.y - attacker.y
    if diff_x > 0:
        diff_x = diff_x / abs(diff_x)
    if diff_y > 0:
        diff_y = diff_y / abs(diff_y)
    direction = (diff_x, diff_y)

    steps = 0
    while steps <= force:
        steps += 1
        against = main.get_objects(target.x + direction[0],
                                   target.y + direction[1], lambda o: o.blocks)
        if against is None or len(against) == 0:
            against = syntax.name(
                main.current_map.tiles[target.x + direction[0]][target.y +
                                                                direction[1]])
        else:
            against = 'the ' + against.name
        if not target.move(direction[0], direction[1]):
            # Could not move
            damage = combat.roll_damage('%dd4' % steps, '0d0',
                                        target.fighter.armor, 0, 'budgeoning',
                                        1.0, target.fighter.resistances)
            ui.message(
                '%s %s backwards and collides with %s, taking %d damage.' %
                (syntax.name(target).capitalize(),
                 syntax.conjugate(target is player.instance,
                                  ('fly', 'flies')), against, damage),
                libtcod.gray)
            target.fighter.take_damage(damage, attacker=attacker)
            steps = force + 1
Ejemplo n.º 12
0
def step_on_blightweed(weed, obj):
    if obj.fighter:
        obj.fighter.time_since_last_damaged = 0
        if obj.fighter.armor > 0:
            obj.fighter.get_shredded(1)
            if fov.player_can_see(obj.x, obj.y):
                ui.message(
                    'The blightweed thorns shred %s armor!' %
                    syntax.name(obj, possesive=True), libtcod.desaturated_red)
Ejemplo n.º 13
0
def web_bomb(actor, target, context):
    if actor is player.instance:
        ui.message('Yo implement this', libtcod.red)
        return 'failure'

    main.tunnel_spider_spawn_web(target)
    if actor is player.instance or fov.player_can_see(target.x, target.y):
        ui.message('%s summons spiderwebs.' % syntax.name(actor).capitalize(),
                   actor.color)
    return 'success'
Ejemplo n.º 14
0
def hardness(target):
    target.fighter.shred = 0
    target.fighter.apply_status_effect(effects.stoneskin(21))
    if target is player.instance or fov.player_can_see(target.x, target.y):
        ui.message(
            '%s armor is repaired and %s skin becomes as hard as stone.' %
            (syntax.name(target, possesive=True).capitalize(),
             syntax.pronoun(target, possesive=True)),
            spells.essence_colors['earth'])
    return 'success'
Ejemplo n.º 15
0
def haste(actor, target, context):
    target.fighter.apply_status_effect(
        effects.hasted(duration=context['duration']))
    ui.render_explosion(target.x, target.y, 0, libtcod.lightest_fuchsia,
                        libtcod.fuchsia)
    ui.message(
        '%s %s hasted.' % (syntax.name(target).capitalize(),
                           syntax.conjugate(target is player.instance,
                                            ('are', 'is'))),
        spells.essence_colors['arcane'])
    return 'success'
Ejemplo n.º 16
0
def berserk_self(actor, target, context):
    if not actor.fighter.has_status(
            'berserk') and not actor.fighter.has_status('exhausted'):
        actor.fighter.apply_status_effect(effects.berserk())
        if actor is not player.instance:
            ui.message(
                '%s %s!' % (syntax.name(actor).capitalize(),
                            syntax.conjugate(False, ('roar', 'roars'))),
                libtcod.red)
        return 'success'
    else:
        if actor is player.instance:
            ui.message("You cannot go berserk right now.", libtcod.yellow)
Ejemplo n.º 17
0
 def sh_raise(self):
     self.sh_timer = 0
     if not self.raised and (self.holder is player.instance
                             or fov.monster_can_see_object(
                                 self.holder, player.instance)):
         ui.message(
             '%s %s %s shield.' %
             (syntax.name(self.holder).capitalize(),
              syntax.conjugate(self.holder is player.instance,
                               ('raise', 'raises')),
              syntax.pronoun(self.holder, possesive=True)), libtcod.blue)
     self.raised = True
     self.sh_points = self.sh_max
Ejemplo n.º 18
0
def lightning_storm(actor, target, context):
    for tile in target:
        obj = main.get_monster_at_tile(tile[0], tile[1])
        ui.render_explosion(tile[0], tile[1], 0, libtcod.light_green,
                            libtcod.lightest_blue, chr(251))
        if obj is not None and obj is not actor:
            if fov.player_can_see(tile[0],
                                  tile[1]) or actor is player.instance:
                ui.message(
                    '%s is struck by a bolt of lightning!' %
                    syntax.name(obj).capitalize(), libtcod.lightest_blue)
            combat.attack_magical(actor.fighter, obj,
                                  'ability_lightning_storm')
Ejemplo n.º 19
0
def frog_tongue(actor, target, context):
    if target.fighter.hp > 0:
        ui.message("The frog's tongue lashes out at %s!" % syntax.name(target),
                   libtcod.dark_green)
        result = combat.attack_ex(actor.fighter,
                                  target,
                                  0,
                                  accuracy_modifier=1.5,
                                  damage_multiplier=1.5,
                                  verb=('pull', 'pulls'))
        if result == 'hit':
            if 'displacement' in target.fighter.immunities:
                if fov.player_can_see(target.x, target.y):
                    ui.message(
                        '%s %s.' % (syntax.name(target).capitalize(),
                                    syntax.conjugate(target is player.instance,
                                                     ('resist', 'resists'))),
                        libtcod.gray)
                return 'success'
            beam = main.beam(actor.x, actor.y, target.x, target.y)
            pull_to = beam[max(len(beam) - 3, 0)]
            target.set_position(pull_to[0], pull_to[1])
Ejemplo n.º 20
0
def confuse(actor, target, context):
    import consts
    if target.fighter.apply_status_effect(
            effects.StatusEffect(
                'confusion',
                consts.CONFUSE_NUM_TURNS,
                color=libtcod.pink,
            )):
        ui.message(
            '%s %s confused!' % (syntax.name(target).capitalize(),
                                 syntax.conjugate(target is player.instance,
                                                  ('are', 'is'))),
            libtcod.light_blue)
Ejemplo n.º 21
0
def silence(actor, target, context):
    if target.fighter.apply_status_effect(
            effects.silence(duration=context.get('duration', 10)),
            dc=context.get('base_dc', 20) +
            actor.fighter.spell_power(['arcane']),
            source_fighter=actor.fighter,
            supress_message=True):
        if actor is player.instance or target is player.instance or fov.player_can_see(
                target.x, target.y):
            ui.message(
                '%s %s silenced!' %
                (syntax.name(target).capitalize(),
                 syntax.conjugate(target is player.instance,
                                  ('are', 'is'))), libtcod.light_blue)
Ejemplo n.º 22
0
def throw_net(actor, target, context):
    if actor is player.instance:
        ui.message('Yo implement this', libtcod.red)
        return 'failure'

    dist = actor.distance_to(target)
    if dist > context['range']:
        return 'cancelled'

    ui.message(
        '%s %s a net at %s.' %
        (syntax.name(actor).capitalize(),
         syntax.conjugate(actor is player.instance,
                          ('throw', 'throws')), syntax.name(target)),
        libtcod.gold)
    ui.render_projectile((actor.x, actor.y), (target.x, target.y),
                         libtcod.gold,
                         character='#')
    target.fighter.apply_status_effect(
        effects.immobilized(duration=context['duration']),
        context['save_dc'],
        source_fighter=actor)

    return 'success'
Ejemplo n.º 23
0
def fungal_growth(actor, target, context):
    x, y = target
    corpse = main.get_objects(x, y, lambda o: o.is_corpse)
    if len(corpse) == 0:
        ui.message('No suitable corpses here.', libtcod.gray)
        return 'cancelled'
    target = corpse[0]

    if not target.is_corpse:
        return 'failure'
    main.spawn_monster('monster_blastcap', target.x, target.y)
    if actor is player.instance or fov.player_can_see(target.x, target.y):
        ui.message('A blastcap grows from %s.' % syntax.name(target),
                   spells.essence_colors['life'])
    target.destroy()
    return 'success'
Ejemplo n.º 24
0
def dig_line(x, y, dx, dy, length, actor=None):
    if actor is None: actor = player.instance
    result = 'failure'
    for i in range(length):
        d = dig(x + dx * i, y + dy * i)
        if result != 'success':
            result = d
    if result == 'success':
        if actor is player.instance or fov.player_can_see(actor.x, actor.y):
            ui.message('The earth parts before %s.' % syntax.name(actor),
                       spells.essence_colors['earth'])
    else:
        if actor is player.instance:
            ui.message('There is nothing to dig in that direction.',
                       libtcod.gray)
    return result
Ejemplo n.º 25
0
def scum_glob_death(glob, context):
    ui.message('%s divides!' % syntax.name(glob).capitalize(), libtcod.red)
    pos = glob.x, glob.y
    glob.fighter = None
    glob.destroy()
    for i in range(3):
        spawn = main.find_closest_open_tile(pos[0], pos[1])
        main.spawn_monster('monster_scum_glob_small', spawn[0], spawn[1])
        tile = main.current_map.tiles[spawn[0]][spawn[1]]
        if not tile.is_water and not tile.tile_type == 'oil' and not tile.is_ramp:
            tile.tile_type = 'oil'

    if ui.selected_monster is glob:
        main.changed_tiles.append(pos)
        ui.selected_monster = None
        ui.auto_target_monster()
Ejemplo n.º 26
0
def raise_zombie(actor, target, context):
    corpse = None
    for tile in target:
        corpses_here = main.get_objects(
            tile[0], tile[1], lambda o: o.name.startswith('remains of'))
        if len(corpses_here) > 0:
            corpse = corpses_here[0]
            break

    if corpse is not None:
        ui.message(
            'A dark aura emanates from %s... a corpse walks again.' %
            syntax.name(actor), libtcod.dark_violet)
        main.raise_dead(actor, corpse)
        return 'rasied-zombie'
    else:
        return 'didnt-take-turn'
Ejemplo n.º 27
0
def great_dive(actor, target, context):
    ui.message("{} {} into the ground!".format(
        syntax.name(actor).capitalize(),
        syntax.conjugate(actor is player.instance, ['slam', 'slams'])))

    for obj in main.current_map.fighters:
        if (obj.x, obj.y) in target:
            combat.attack_ex(actor.fighter, obj, 0)

    x, y = context['origin']
    if not main.is_blocked(x, y):
        actor.set_position(x, y)
    else:
        for t in target:
            if not main.is_blocked(t[0], t[1]):
                actor.set_position(t[0], t[1])
                break
Ejemplo n.º 28
0
def bramble(actor, target, context):
    ui.message(
        'Thorny brambles spring from %s fingertips!' %
        syntax.name(actor, possesive=True), spells.essence_colors['life'])
    for tile in target:
        _bramble = main.GameObject(
            tile[0],
            tile[1],
            'x',
            'bramble',
            libtcod.dark_lime,
            on_step=bramble_on_step,
            summon_time=context['duration_base'] +
            main.roll_dice(context['duration_variance']))
        _bramble.summoner = actor
        _bramble.spell_power = actor.fighter.spell_power(['life'])
        main.current_map.add_object(_bramble)
    return 'success'
Ejemplo n.º 29
0
def boomerang(actor, target, context):
    sprites = ['<', 'v', '>', '^']
    ui.render_projectile((actor.x, actor.y), (target.x, target.y),
                         libtcod.yellow, sprites)
    attack_result = actor.fighter.attack(target)
    if attack_result == 'failed':
        return 'didnt-take-turn'
    catch_skill = 30
    if actor.player_stats:
        catch_skill = actor.player_stats.agi
    if main.roll_dice('1d' + str(catch_skill)) >= 10:
        #catch boomerang
        ui.render_projectile((target.x, target.y), (actor.x, actor.y),
                             libtcod.yellow, sprites)
        if actor is player.instance:
            ui.message('You catch the boomerang as it returns to you',
                       libtcod.gray)
    else:
        possible_tiles = []
        for y in range(actor.y - 2, actor.y + 2):
            for x in range(actor.x - 2, actor.x + 2):
                if x >= 0 and y >= 0 and x < consts.MAP_WIDTH and y < consts.MAP_HEIGHT and not main.is_blocked(
                        x, y):
                    possible_tiles.append((x, y))
        if len(possible_tiles) == 0:
            selected_tile = main.find_closest_open_tile(target.x, target.y)
        else:
            selected_tile = possible_tiles[libtcod.random_get_int(
                0, 0,
                len(possible_tiles) - 1)]
        ui.render_projectile((target.x, target.y),
                             (selected_tile[0], selected_tile[1]),
                             libtcod.yellow, sprites)
        weapon = main.get_equipped_in_slot(actor.fighter.inventory,
                                           'right hand')
        weapon.owner.item.drop(no_message=True)
        weapon.owner.x = selected_tile[0]
        weapon.owner.y = selected_tile[1]
        if actor is player.instance or fov.player_can_see(actor.x, actor.y):
            ui.message(
                '%s boomerang falls to the ground.' %
                syntax.name(target, possesive=True).capitalize(), libtcod.gray)
        libtcod.console_flush()
Ejemplo n.º 30
0
def bomb_beetle_death(beetle, context):

    ui.message('%s is dead!' % syntax.name(beetle).capitalize(), libtcod.red)
    beetle.char = 149
    beetle.color = libtcod.black
    beetle.blocks = True
    beetle.fighter = None
    beetle.behavior = None
    beetle.name = 'beetle bomb'
    beetle.description = 'The explosive carapace of a blast beetle. In a few turns, it will explode!'
    beetle.bomb_timer = 3
    beetle.on_tick = bomb_beetle_corpse_tick
    if hasattr(beetle, 'recoverable_ammo'):
        main.drop_ammo(beetle.x, beetle.y, beetle.recoverable_ammo)
        del beetle.recoverable_ammo
    main.current_map.fighters.remove(beetle)

    if ui.selected_monster is beetle:
        main.changed_tiles.append((beetle.x, beetle.y))
        ui.selected_monster = None
        ui.auto_target_monster()