def ranged_attack(actor, target, context): spent = actor.fighter.adjust_ammo(-1) if spent != 0 and actor.fighter is not None: weapon = main.get_equipped_in_slot(actor.fighter.inventory, 'right hand') ui.render_projectile((actor.x, actor.y), (target.x, target.y), libtcod.white) result = combat.attack_ex(actor.fighter, target, 0, verb=("shoot", "shoots"), weapon=weapon, ranged=True) if result == 'failed': actor.fighter.adjust_ammo(-spent, False) # Refund ammo return 'didnt-take-turn' if result == 'miss' or target.fighter is None: # ammo lands on the ground main.drop_ammo(target.x, target.y, -spent) else: # target was hit, ammo sticks in them if hasattr(target, 'recoverable_ammo'): target.recoverable_ammo += -spent else: target.recoverable_ammo = -spent else: return 'didnt-take-turn'
def arcane_arrow(actor, target, context): ui.render_projectile((actor.x, actor.y), (target.x, target.y), libtcod.fuchsia, None) combat.attack_magical(actor.fighter, target, 'ability_arcane_arrow', accuracy_bonus=actor.fighter.spell_power(['arcane']))
def acid_flask(actor, target, context): (x, y) = context['origin'] ui.render_projectile((actor.x, actor.y), (x, y), libtcod.lime, character='!') ui.render_explosion(x, y, 1, libtcod.lightest_lime, libtcod.dark_lime) for t in target: combat.attack_magical(actor.fighter, t, 'ability_acid_flask')
def bow_shot(actor, target, context): weapon = main.get_equipped_in_slot(actor.fighter.inventory, 'right hand') ui.render_projectile((actor.x, actor.y), (target.x, target.y), libtcod.white) combat.attack_ex(actor.fighter, target, 0, verb=("shoot", "shoots"), weapon=weapon, ranged=True)
def heat_ray(actor, target, context): end = (target[len(target) - 1][0], target[len(target) - 1][1]) ui.render_projectile((actor.x, actor.y), end, libtcod.flame, libtcod.CHAR_BLOCK3) for obj in main.current_map.fighters: for l in target: if obj.x == l[0] and obj.y == l[1]: combat.attack_magical(actor.fighter, obj, 'ability_heat_ray') main.melt_ice(end[0], end[1])
def firebomb(actor, target, context): (x, y) = context['origin'] ui.render_projectile((actor.x, actor.y), (x, y), spells.essence_colors['fire'], chr(7)) ui.render_explosion(x, y, 1, libtcod.yellow, libtcod.flame) if actor is player.instance or fov.player_can_see(x, y): ui.message('The firebomb explodes!', spells.essence_colors['fire']) for f in target: if combat.attack_magical( actor.fighter, f, 'ability_fire_bomb') == 'hit' and f.fighter is not None: f.fighter.apply_status_effect(effects.burning())
def icebomb(actor, target, context): (x, y) = context['origin'] ui.render_projectile((actor.x, actor.y), (x, y), spells.essence_colors['cold'], chr(7)) ui.render_explosion(x, y, 1, libtcod.white, libtcod.light_sky) if actor is player.instance or fov.player_can_see(x, y): ui.message('The icebomb explodes!', spells.essence_colors['cold']) for f in target: if combat.attack_magical( actor.fighter, f, 'ability_ice_bomb') == 'hit' and f.fighter is not None: f.fighter.apply_status_effect( effects.frozen(duration=context['freeze_duration']))
def holy_water(actor, target, context): import monsters if not target.fighter.has_flag(monsters.EVIL): if actor is player.instance: ui.message('That target is not vulnerable to holy water.', libtcod.gray) return 'cancelled' ui.render_projectile((actor.x, actor.y), (target.x, target.y), color=spells.essence_colors['water'], character=libtcod.CHAR_BLOCK2) combat.attack_magical(actor.fighter, target, 'ability_holy_water') if target.fighter is not None: target.fighter.apply_status_effect( effects.stunned(duration=(3 + main.roll_dice('1d6')))) return 'success'
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'
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()