def summon_ally(name, duration, x=None, y=None): adj = main.adjacent_tiles_diagonal(player.instance.x, player.instance.y) # Get viable summoning position. Return failure if no position is available if x is None or y is None: summon_positions = [] for tile in adj: if not main.is_blocked(tile[0], tile[1]): summon_positions.append(tile) if len(summon_positions) == 0: ui.message('There is no room to summon an ally here.') return summon_pos = summon_positions[libtcod.random_get_int( 0, 0, len(summon_positions) - 1)] else: summon_pos = (x, y) # Select monster type - default to goblin import monsters if name in monsters.proto.keys(): summon = main.spawn_monster(name, summon_pos[0], summon_pos[1], team='ally') if summon is not None: if summon.behavior is not None: summon.behavior.follow_target = player.instance # Set summon duration summon.summon_time = duration + libtcod.random_get_int( 0, 0, duration) return 'success' else: return 'didnt-take-turn'
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'
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 spawn_vermin(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_choice = main.random_choice_index( [e['weight'] for e in context['summons']]) summon_tiles = [] for y in range(5): for x in range(5): pos = actor.x - 2 + x, actor.y - 2 + y if main.in_bounds(pos[0], pos[1]) and not main.is_blocked( pos[0], pos[1]): summon_tiles.append(pos) for i in range(context['summons'][summon_choice]['count']): if len(summon_tiles) > 0: pos = summon_tiles[libtcod.random_get_int( 0, 0, len(summon_tiles) - 1)] spawn = main.spawn_monster( context['summons'][summon_choice]['monster'], pos[0], pos[1]) ui.message( 'A ' + spawn.name + " crawls from beneath the verman's cloak.", actor.color) spawn.fighter.loot_table = None actor.summons.append(spawn) summon_tiles.remove(pos)
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'
def on_death_summon(obj, context): ui.message('%s is dead!' % syntax.name(obj).capitalize(), libtcod.red) obj.fighter = None main.current_map.fighters.remove(obj) obj.destroy() if context.get('require_tile') is not None: tile_at_location = main.current_map.tiles[obj.x][obj.y] if context['require_tile'] != tile_at_location.tile_type: return if 'message' in context.keys(): ui.message(context['message']) monster = main.spawn_monster(context['monster'], obj.x, obj.y) monster.fighter.apply_status_effect( effects.stunned(1)) #summoning sickness if 'duration' in context: monster.summon_time = context['duration'] if ui.selected_monster is obj: main.changed_tiles.append((obj.x, obj.y)) ui.selected_monster = None ui.auto_target_monster()
def summon_roaches(actor, attacker, damage): if not hasattr(actor, 'summon_limit') or not hasattr(actor, 'summons'): actor.summon_limit = 8 actor.summons = [] remove = [] for s in actor.summons: if s.fighter is None or not s in main.current_map.fighters: remove.append(s) for s in remove: actor.summons.remove(s) if len(actor.summons) >= actor.summon_limit: return if fov.player_can_see(actor.x, actor.y): ui.message( 'Cockroaches crawl from %s wounds!' % syntax.name(actor, possesive=True), libtcod.dark_magenta) for adj in main.adjacent_tiles_diagonal(actor.x, actor.y): if len(actor.summons) >= actor.summon_limit: break if not main.is_blocked( adj[0], adj[1]) and libtcod.random_get_int(0, 1, 10) <= 5: actor.summons.append( main.spawn_monster('monster_cockroach', adj[0], adj[1]))
def summon_demon(actor, data): choice = main.random_choice(data['summons']) actor.fighter.take_damage(100000) main.spawn_monster(choice, actor.x, actor.y)