mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2026-08-17 13:17:09 +01:00
485 lines
13 KiB
Plaintext
485 lines
13 KiB
Plaintext
////////////////////////////////////
|
|
//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"
|