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'
def _dragonseed_ticker(ticker): if ticker.ticks >= ticker.max_ticks: ticker.dead = True ui.message("The dragonweed sapling matures.", libtcod.dark_chartreuse) x = ticker.seed.x y = ticker.seed.y ticker.seed.destroy() for obj in main.get_objects(x, y, lambda o: o.blocks): t = main.find_closest_open_tile(x, y) obj.set_position(t[0], t[1]) common.summon_ally('monster_dragonweed', 10 + libtcod.random_get_int(0, 0, 20), x, y)
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()
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()
def _get_ability_target(actor, info, target_override): targeting = info.get('targeting', 'pick') range = info.get('range', 1000) ground_targeting = info.get('target_ground', False) target = None burst = info.get('burst') if isinstance(target_override, main.GameObject): x = target_override.x y = target_override.y target_override = x, y if targeting == 'override': return (0, 0) if targeting == 'self' and burst is None: if ground_targeting: target = actor.x, actor.y else: target = actor if target is None and targeting is not None: if actor is player.instance: if targeting == 'self': # for self burst target = actor.x, actor.y else: ui.message_flush( 'Left-click a target tile, or right-click to cancel.', libtcod.white) default_target = None if info.get( 'intent', 'aggressive' ) == 'aggressive' and ui.selected_monster is not None: default_target = ui.selected_monster.x, ui.selected_monster.y target = ui.target_tile(range, targeting, default_target=default_target) else: if target_override is not None and targeting != 'self' and \ main.distance(actor.x, actor.y, target_override[0], target_override[1]) > range: target = None return target # out of range if targeting == 'pick': target = (target_override[0], target_override[1]) elif targeting == 'cone': target = main.cone(actor.x, actor.y, target_override[0], target_override[1], max_range=info['range']) elif targeting == 'beam': target = main.beam(actor.x, actor.y, target_override[0], target_override[1]) elif targeting == 'beam wide': # TODO: Support wide beam outside of player targeting raise Exception("Not supported") elif targeting == 'beam_interrupt': target = main.beam_interrupt(actor.x, actor.y, target_override[0], target_override[1]) elif targeting == 'summon': target = main.find_closest_open_tile(target_override[0], target_override[1]) elif targeting == 'self': target = actor.x, actor.y #Targeting failed if isinstance(target, tuple) and target[0] is None: target = None if target is None: return target if burst is not None and isinstance(target, tuple): if info.get('hits_friendlies', False): teams = None elif info.get('team') is not None: if info.get('allies_only') is not None: teams = lambda o: o.fighter.team == info.get('team') else: teams = lambda o: o.fighter.team != info.get('team') else: if info.get('allies_only') is not None: teams = lambda o: o.fighter.team == actor.fighter.team else: teams = lambda o: o.fighter.team != actor.fighter.team info['origin'] = target[0], target[1] if not ground_targeting: target = main.get_fighters_in_burst(target[0], target[1], burst, actor, teams) else: target = main.get_tiles_in_burst(target[0], target[1], burst) elif not ground_targeting and targeting != 'summon': if target is not None: if isinstance(target, list): target = [main.get_monster_at_tile(*t) for t in target] else: pos = target target = None for fighter in main.current_map.fighters: if fighter.x == pos[0] and fighter.y == pos[1]: target = fighter break #randomly select only some of the targets if info.get('random_select') is not None and not isinstance( target, tuple): mode = info.get('random_select') target = [ target[i] for i in random.sample(xrange(len(target)), mode) ] return target