//////////////////////////////////// //Mob spawner structure. This one is an on map structure that players can see, sometimes break. //////////////////////////////////// /obj/structure/mob_spawner name = "mob spawner" desc = "This shouldn't be seen, yell at a dev." icon = 'icons/effects/effects.dmi' icon_state = "rift" anchored = 1 integrity_flags = INTEGRITY_INDESTRUCTIBLE var/last_spawn = 0 var/spawn_delay = 10 MINUTES var/list/spawn_types = list( /mob/living/simple_mob/animal/passive/dog/corgi = 100, /mob/living/simple_mob/animal/passive/cat = 25 ) var/total_spawns = -1 //Total mob spawns, over all time, -1 for no limiteee var/simultaneous_spawns = 3 //Max spawned mobs active at one time var/mob_faction var/list/spawned_mobs = list() /obj/structure/mob_spawner/Initialize(mapload) . = ..() START_PROCESSING(SSobj, src) last_spawn = world.time + rand(0,spawn_delay) /obj/structure/mob_spawner/Destroy() STOP_PROCESSING(SSobj, src) for(var/mob/living/L in spawned_mobs) L.source_spawner = null spawned_mobs.Cut() return ..() /obj/structure/mob_spawner/process() if(!can_spawn()) return for(var/mob/M as anything in spawned_mobs) if(!istype(M)) spawned_mobs -= M if(QDELETED(M)) spawned_mobs -= M var/chosen_mob = choose_spawn() if(chosen_mob) do_spawn(chosen_mob) /obj/structure/mob_spawner/proc/can_spawn() if(!total_spawns) return 0 if(spawned_mobs.len >= simultaneous_spawns) return 0 if(world.time < last_spawn + spawn_delay) return 0 return 1 /obj/structure/mob_spawner/proc/choose_spawn() return pickweight(spawn_types) /obj/structure/mob_spawner/proc/do_spawn(var/mob_path) if(!ispath(mob_path)) return 0 var/mob/living/L = new mob_path(get_turf(src)) L.source_spawner = src spawned_mobs.Add(L) last_spawn = world.time if(total_spawns > 0) total_spawns-- if(mob_faction) L.set_iff_factions(mob_faction) return L /obj/structure/mob_spawner/clear_zlevel/can_spawn() if(!..()) return 0 var/turf/T = get_turf(src) if(!T) return 0 for(var/mob/living/L in GLOB.player_list) var/turf/L_T if(L.stat == DEAD) continue L_T = get_turf(L) if(T.z == L_T.z) return 0 return 1 /* This code is based on the mob spawner and the proximity sensor, the idea is to lazy load mobs to avoid having the server use mobs when they arent needed. It also makes it so a ghost wont know where all the goodies/mobs are. */ /obj/structure/mob_spawner/scanner name ="Lazy Mob Spawner" var/range = 10 //range in tiles from the spawner to detect moving stuff /obj/structure/mob_spawner/scanner/process() if(!can_spawn()) return if(world.time > last_spawn + spawn_delay) var/turf/mainloc = get_turf(src) for(var/mob/living/A in range(range,mainloc)) if (((!mob_faction || !A.has_iff_faction(mob_faction))) && (A.move_speed < 12)) var/chosen_mob = choose_spawn() if(chosen_mob) do_spawn(chosen_mob) ////////////// // Spawners // ///////////// //Non-Scanners /obj/structure/mob_spawner/goliath name = "Deep Warrens Rift" desc = "This hole leads deep underground. Although possibly large enough for you to enter, something seems to compel you not to. Occasionally, a deep, choral rumbling can be heard far below." icon_state = "tunnel_hole" spawn_delay = 20 MINUTES simultaneous_spawns = 1 mob_faction = MOB_IFF_FACTION_BIND_TO_MAP total_spawns = 6 integrity_flags = NONE anchored = 1 integrity = 500 spawn_types = list( /mob/living/simple_mob/animal/goliath = 100 ) /obj/structure/mob_spawner/gutshank name = "Gutshank Hive" desc = "This telltale pile of debris and hardened sand marks this as the entrance to a Gutshank hive." icon_state = "eggy_tunnel" spawn_delay = 10 MINUTES simultaneous_spawns = 3 mob_faction = MOB_IFF_FACTION_BIND_TO_MAP total_spawns = 12 anchored = 1 integrity_flags = NONE integrity = 400 spawn_types = list( /mob/living/simple_mob/animal/gutshank = 100 ) /obj/structure/mob_spawner/stormdrifter name = "Violent Downdraft" desc = "The air here seems especially hot. A swirling wind agitates the ash and sand, kicking up eddies and small dust devils." icon_state = "punch" spawn_delay = 10 MINUTES simultaneous_spawns = 6 mob_faction = MOB_IFF_FACTION_BIND_TO_MAP total_spawns = 12 anchored = 1 integrity_flags = NONE integrity = 1000 spawn_types = list( /mob/living/simple_mob/animal/stormdrifter = 60, /mob/living/simple_mob/animal/stormdrifter/bull = 30 ) /obj/structure/mob_spawner/sandsifter name = "Sand Sifter Colony" desc = "A pile of rocks and other debris sand sifters often nest in." icon_state = "boulder1" spawn_delay = 5 MINUTES simultaneous_spawns = 8 mob_faction = MOB_IFF_FACTION_BIND_TO_MAP total_spawns = 36 anchored = 1 integrity_flags = NONE integrity = 100 spawn_types = list( /mob/living/simple_mob/animal/sandsifter = 100 ) //Scanners /obj/structure/mob_spawner/scanner/corgi name = "Corgi Lazy Spawner" desc = "This is a proof of concept, not sure why you would use this one" spawn_delay = 3 MINUTES mob_faction = "Corgi" spawn_types = list( /mob/living/simple_mob/animal/passive/dog/corgi = 75, /mob/living/simple_mob/animal/passive/dog/corgi/puppy = 50 ) simultaneous_spawns = 5 range = 7 integrity_flags = NONE integrity = 200 total_spawns = 100 /obj/structure/mob_spawner/scanner/wild_animals name = "Wilderness Lazy Spawner" spawn_delay = 10 MINUTES range = 10 simultaneous_spawns = 1 mob_faction = "wild animal" total_spawns = -1 integrity_flags = INTEGRITY_INDESTRUCTIBLE anchored = 1 invisibility = 101 spawn_types = list( /mob/living/simple_mob/animal/passive/gaslamp = 20, // /mob/living/simple_mob/otie/feral = 10, /mob/living/simple_mob/vore/aggressive/dino/virgo3b = 5, /mob/living/simple_mob/vore/aggressive/dragon/virgo3b = 1 ) /obj/structure/mob_spawner/scanner/xenos name = "Xenomorph Egg" spawn_delay = 10 MINUTES range = 10 simultaneous_spawns = 1 mob_faction = "xeno" total_spawns = -1 integrity_flags = NONE integrity = 50 anchored = 1 icon = 'icons/screen/actions/actions.dmi' icon_state = "alien_egg" spawn_types = list( /mob/living/simple_mob/animal/space/xenomorph/drone = 20, /mob/living/simple_mob/animal/space/xenomorph/warrior = 10, /mob/living/simple_mob/animal/space/xenomorph/vanguard = 5 ) /obj/structure/mob_spawner/scanner/xenos/royal name = "Royal Xenomorph Egg" spawn_delay = 10 MINUTES range = 10 simultaneous_spawns = 1 mob_faction = "xeno" total_spawns = 1 integrity_flags = NONE integrity = 50 anchored = 1 icon = 'icons/screen/actions/actions.dmi' icon_state = "alien_egg" //////////////////////////////////// //Invisible mob spawner. This one spawns mobs until depleted. Often used in caves. //////////////////////////////////// /obj/mob_spawner name = "RENAME ME, JERK" desc = "Spawns the mobs!" icon = 'icons/mob/screen1.dmi' icon_state = "x" invisibility = 101 mouse_opacity = 0 density = 0 anchored = 1 //Weighted with values (not %chance, but relative weight) //Can be left value-less for all equally likely var/list/mobs_to_pick_from //When the below chance fails, the spawner is marked as depleted and stops spawning var/prob_spawn = 100 //Chance of spawning a mob whenever they don't have one var/prob_fall = 5 //Above decreases by this much each time one spawns //Settings to help mappers/coders have their mobs do what they want in this case var/faction //To prevent infighting if it spawns various mobs, set a faction var/atmos_comp //TRUE will set all their survivability to be within 20% of the current air //var/guard //# will set the mobs to remain nearby their spawn point within this dist //Internal use only var/mob/living/simple_mob/my_mob var/depleted = FALSE /obj/mob_spawner/Initialize(mapload) . = ..() if(!LAZYLEN(mobs_to_pick_from)) log_world("Mob spawner at [x],[y],[z] ([get_area(src)]) had no mobs_to_pick_from set on it!") return INITIALIZE_HINT_QDEL START_PROCESSING(SSobj, src) /obj/mob_spawner/process() if(my_mob && my_mob.stat != DEAD) return //No need if(LAZYLEN(loc.human_mobs(world.view))) return //I'll wait. if(prob(prob_spawn)) prob_spawn -= prob_fall var/picked_type = pickweight(mobs_to_pick_from) my_mob = new picked_type(get_turf(src)) my_mob.low_priority = TRUE if(faction) my_mob.set_iff_factions(faction) if(atmos_comp) var/turf/T = get_turf(src) var/datum/gas_mixture/env = T.return_air() if(env) my_mob.minbodytemp = env.temperature * 0.8 my_mob.maxbodytemp = env.temperature * 1.2 var/list/gaslist = env.gas my_mob.min_oxy = gaslist[GAS_ID_OXYGEN] * 0.8 my_mob.min_tox = gaslist[GAS_ID_PHORON] * 0.8 my_mob.min_n2 = gaslist[GAS_ID_NITROGEN] * 0.8 my_mob.min_co2 = gaslist[GAS_ID_CARBON_DIOXIDE] * 0.8 my_mob.max_oxy = gaslist[GAS_ID_OXYGEN] * 1.2 my_mob.max_tox = gaslist[GAS_ID_PHORON] * 1.2 my_mob.max_n2 = gaslist[GAS_ID_NITROGEN] * 1.2 my_mob.max_co2 = gaslist[GAS_ID_CARBON_DIOXIDE] * 1.2 return else STOP_PROCESSING(SSobj, src) depleted = TRUE return /obj/mob_spawner/carp name = "Carp Spawner" prob_fall = 15 mobs_to_pick_from = list( /mob/living/simple_mob/animal/space/carp = 3, /mob/living/simple_mob/animal/space/carp/large = 1 ) /obj/mob_spawner/carp/small prob_fall = 30 mobs_to_pick_from = list( /mob/living/simple_mob/animal/space/carp = 3, /mob/living/simple_mob/animal/space/carp/large = 1, ) /obj/mob_spawner/carp/hard mobs_to_pick_from = list( /mob/living/simple_mob/animal/space/carp/large = 2, /mob/living/simple_mob/animal/space/carp/large/huge = 1 ) /obj/mob_spawner/carp/medium prob_fall = 10 mobs_to_pick_from = list( /mob/living/simple_mob/animal/space/carp = 5, /mob/living/simple_mob/animal/space/carp/large = 2 ) /obj/mob_spawner/carp/large name = "Carp Horde Spawner" prob_fall = 10 mobs_to_pick_from = list( /mob/living/simple_mob/animal/space/carp = 8, /mob/living/simple_mob/animal/space/carp/large = 3, /mob/living/simple_mob/animal/space/carp/large/huge = 1 ) /obj/mob_spawner/derelict name = "Derelict random mob spawner" faction = "derelict" mobs_to_pick_from = list( /mob/living/simple_mob/mechanical/corrupt_maint_drone = 2, /mob/living/simple_mob/mechanical/infectionbot = 3, /mob/living/simple_mob/mechanical/combat_drone = 1 ) /obj/mob_spawner/derelict/corrupt_maint_swarm name = "Derelict maint swarm" faction = "derelict" mobs_to_pick_from = list( /mob/living/simple_mob/mechanical/corrupt_maint_drone = 4 ) /obj/mob_spawner/derelict/mech_wizard name = "Derelict wizard" faction = "derelict" mobs_to_pick_from = list( /mob/living/simple_mob/mechanical/technomancer_golem = 2 ) /obj/mob_spawner/hound_spawner name = "Corrupt Hound Spawner" prob_fall = 50 mobs_to_pick_from = list( /mob/living/simple_mob/vore/aggressive/corrupthound = 1 ) /obj/mob_spawner/drone_spawner name = "Drone Swarm Spawner" prob_fall = 10 mobs_to_pick_from = list( /mob/living/simple_mob/mechanical/corrupt_maint_drone = 3 ) /obj/mob_spawner/alien name = "Alien Spawner" prob_fall = 10 mobs_to_pick_from = list( /mob/living/simple_mob/animal/space/xenomorph/drone = 1 ) /obj/mob_spawner/alien/easy name = "Easy Alien Spawner" mobs_to_pick_from = list( /mob/living/simple_mob/animal/space/xenomorph/warrior = 1, /mob/living/simple_mob/animal/space/xenomorph/drone = 2, /mob/living/simple_mob/animal/space/xenomorph/neurotoxin_spitter = 1, ) /obj/mob_spawner/alien/medium name = "Medium Alien Spawner" mobs_to_pick_from = list( /mob/living/simple_mob/animal/space/xenomorph/warrior = 2, /mob/living/simple_mob/animal/space/xenomorph/drone = 3, /mob/living/simple_mob/animal/space/xenomorph/neurotoxin_spitter = 2, ) /obj/mob_spawner/alien/hard name = "Hard Alien Spawner" mobs_to_pick_from = list( /mob/living/simple_mob/animal/space/xenomorph/warrior = 4, /mob/living/simple_mob/animal/space/xenomorph/acid_spitter = 4, ) /obj/structure/mob_spawner/scanner/corgi name = "Corgi Lazy Spawner" desc = "This is a proof of concept, not sure why you would use this one" spawn_delay = 3 MINUTES mob_faction = "Corgi" spawn_types = list( /mob/living/simple_mob/animal/passive/dog/corgi = 75, /mob/living/simple_mob/animal/passive/dog/corgi/puppy = 50 ) simultaneous_spawns = 5 range = 7 integrity_flags = NONE integrity = 200 total_spawns = 100 /obj/structure/mob_spawner/scanner/wild_animals name = "Wilderness Lazy Spawner" spawn_delay = 10 MINUTES range = 10 simultaneous_spawns = 1 mob_faction = "wild animal" total_spawns = -1 integrity_flags = INTEGRITY_INDESTRUCTIBLE anchored = 1 invisibility = 101 spawn_types = list( /mob/living/simple_mob/animal/passive/gaslamp = 20, // /mob/living/simple_mob/otie/feral = 10, /mob/living/simple_mob/vore/aggressive/dino/virgo3b = 5, /mob/living/simple_mob/vore/aggressive/dragon/virgo3b = 1 ) /obj/structure/mob_spawner/scanner/xenos name = "Xenomorph Egg" spawn_delay = 10 MINUTES range = 10 simultaneous_spawns = 1 mob_faction = "xeno" total_spawns = -1 integrity_flags = NONE integrity = 50 anchored = 1 icon = 'icons/screen/actions/actions.dmi' icon_state = "alien_egg" spawn_types = list( /mob/living/simple_mob/animal/space/xenomorph/drone = 20, /mob/living/simple_mob/animal/space/xenomorph/warrior = 10, /mob/living/simple_mob/animal/space/xenomorph/neurotoxin_spitter = 5, ) /obj/structure/mob_spawner/scanner/xenos/royal name = "Royal Xenomorph Egg" spawn_delay = 10 MINUTES range = 10 simultaneous_spawns = 1 mob_faction = "xeno" total_spawns = 1 integrity_flags = NONE integrity = 50 anchored = 1 icon = 'icons/screen/actions/actions.dmi' icon_state = "alien_egg"