From 9f5e1cdbbc1058af57716fbdfd8d53dbeadf5974 Mon Sep 17 00:00:00 2001 From: mochi Date: Wed, 15 Jul 2020 12:53:17 +0200 Subject: [PATCH] Refactor spawning on vents into one proc --- code/__HELPERS/game.dm | 36 +++++++++++++++++++ .../gamemodes/miniantags/borer/borer_event.dm | 10 ++---- code/modules/events/alien_infestation.dm | 13 +++---- code/modules/events/blob.dm | 14 ++++---- code/modules/events/spider_infestation.dm | 18 ++++------ code/modules/events/spider_terror.dm | 26 ++++---------- code/modules/mob/mob.dm | 19 ++++------ 7 files changed, 69 insertions(+), 67 deletions(-) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index bd077204f00..325dbb7ba62 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -512,3 +512,39 @@ proc/pollCandidates(Question, be_special_type, antag_age_check = FALSE, poll_tim if(!C || !C.prefs.windowflashing) return winset(C, "mainwindow", "flash=5") + +/** + * Returns a list of vents that can be used as a potential spawn if they meet the criteria set by the arguments + * + * Will not include parent-less vents to the returned list. + * Only returns vents in the main station + * Arguments: + * * unwelded_only - Whether the list should only include vents that are unwelded + * * min_network_size - The minimum length (non-inclusive) of the vent's parent network. A smaller number means vents in small networks (Security, Virology) will appear in the list + * * station_levels_only - Whether to only consider vents that are in a Z-level with a STATION_LEVEL trait + * * z_level - The Z-level number to look for vents in. Defaults to all + */ +/proc/get_valid_vent_spawns(unwelded_only = TRUE, min_network_size = 50, station_levels_only = TRUE, z_level = 0) + ASSERT(min_network_size >= 0) + ASSERT(z_level >= 0) + + var/num_z_levels = length(GLOB.space_manager.z_list) + var/list/non_station_levels[num_z_levels] // Cache so we don't do is_station_level for every vent! + + . = list() + for(var/object in GLOB.all_vent_pumps) // This only contains vent_pumps so don't bother with type checking + var/obj/machinery/atmospherics/unary/vent_pump/vent = object + var/vent_z = vent.z + if(z_level && vent_z != z_level) + continue + if(station_levels_only && (non_station_levels[vent_z] || !is_station_level(vent_z))) + non_station_levels[vent_z] = TRUE + continue + if(unwelded_only && vent.welded) + continue + if(!vent.parent) // This seems to have been an issue in the past, so this is here until it's definitely fixed + log_debug("get_valid_vent_spawns(), vent has no parent: [vent], qdeled: [QDELETED(vent)], loc: [vent.loc]") + continue + if(length(vent.parent.other_atmosmch) <= min_network_size) + continue + . += vent diff --git a/code/game/gamemodes/miniantags/borer/borer_event.dm b/code/game/gamemodes/miniantags/borer/borer_event.dm index f5a3b7aa4af..dcb01518025 100644 --- a/code/game/gamemodes/miniantags/borer/borer_event.dm +++ b/code/game/gamemodes/miniantags/borer/borer_event.dm @@ -15,14 +15,8 @@ GLOB.command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') /datum/event/borer_infestation/start() - var/list/vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in SSair.atmos_machinery) - if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) - //Stops cortical borers getting stuck in small networks. See: Security, Virology - if(temp_vent.parent.other_atmosmch.len > 50) - vents += temp_vent - - while(spawncount >= 1 && vents.len) + var/list/vents = get_valid_vent_spawns() + while(spawncount && length(vents)) var/obj/vent = pick_n_take(vents) new /mob/living/simple_animal/borer(vent.loc) successSpawn = TRUE diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm index 8c01d5c7cc2..51a1536d75d 100644 --- a/code/modules/events/alien_infestation.dm +++ b/code/modules/events/alien_infestation.dm @@ -3,7 +3,7 @@ var/highpop_trigger = 80 var/spawncount = 2 var/list/playercount - var/successSpawn = 0 //So we don't make a command report if nothing gets spawned. + var/successSpawn = FALSE //So we don't make a command report if nothing gets spawned. /datum/event/alien_infestation/setup() announceWhen = rand(announceWhen, announceWhen + 50) @@ -13,19 +13,14 @@ GLOB.event_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') /datum/event/alien_infestation/start() - var/list/vents = list() + var/list/vents = get_valid_vent_spawns() playercount = length(GLOB.clients)//grab playercount when event starts not when game starts if(playercount >= highpop_trigger) //spawn with 4 if highpop spawncount = 4 - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in SSair.atmos_machinery) - if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) - if(temp_vent.parent.other_atmosmch.len > 50) //Stops Aliens getting stuck in small networks. See: Security, Virology - vents += temp_vent spawn() var/list/candidates = pollCandidates("Do you want to play as an alien?", ROLE_ALIEN, 1) - - while(spawncount > 0 && vents.len && candidates.len) + while(spawncount && length(vents) && length(candidates)) var/obj/vent = pick_n_take(vents) var/mob/C = pick_n_take(candidates) if(C) @@ -37,4 +32,4 @@ SSticker.mode.xenos += new_xeno.mind spawncount-- - successSpawn = 1 + successSpawn = TRUE diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index caec11de9f2..573ec182659 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -1,9 +1,11 @@ /datum/event/blob announceWhen = 180 endWhen = 240 + var/successSpawn = FALSE //So we don't make a command report if nothing gets spawned. /datum/event/blob/announce() - GLOB.event_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg') + if(successSpawn) + GLOB.event_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg') /datum/event/blob/start() processing = FALSE //so it won't fire again in next tick @@ -16,12 +18,9 @@ if(!candidates.len) return kill() - var/list/vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in GLOB.all_vent_pumps) - if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) - if(temp_vent.parent.other_atmosmch.len > 50) - vents += temp_vent - + var/list/vents = get_valid_vent_spawns() + if(!length(vents)) + return var/obj/vent = pick(vents) var/mob/living/simple_animal/mouse/blobinfected/B = new(vent.loc) var/mob/M = pick(candidates) @@ -30,4 +29,5 @@ to_chat(B, "You are now a mouse, infected with blob spores. Find somewhere isolated... before you burst and become the blob! Use ventcrawl (alt-click on vents) to move around.") notify_ghosts("Infected Mouse has appeared in [get_area(B)].", source = B) + successSpawn = TRUE processing = TRUE // Let it naturally end, if it runs successfully diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm index 694f8e98c89..419a4ce10fc 100644 --- a/code/modules/events/spider_infestation.dm +++ b/code/modules/events/spider_infestation.dm @@ -3,6 +3,7 @@ GLOBAL_VAR_INIT(sent_spiders_to_station, 0) /datum/event/spider_infestation announceWhen = 400 var/spawncount = 1 + var/successSpawn = FALSE //So we don't make a command report if nothing gets spawned. /datum/event/spider_infestation/setup() announceWhen = rand(announceWhen, announceWhen + 50) @@ -10,20 +11,15 @@ GLOBAL_VAR_INIT(sent_spiders_to_station, 0) GLOB.sent_spiders_to_station = 1 /datum/event/spider_infestation/announce() - GLOB.event_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') + if(successSpawn) + GLOB.event_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') /datum/event/spider_infestation/start() - - var/list/vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in SSair.atmos_machinery) - if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) - if(temp_vent.parent.other_atmosmch.len > 50) - vents += temp_vent - - while((spawncount >= 1) && vents.len) - var/obj/vent = pick(vents) + var/list/vents = get_valid_vent_spawns() + while(spawncount && length(vents)) + var/obj/vent = pick_n_take(vents) var/obj/structure/spider/spiderling/S = new(vent.loc) if(prob(66)) S.grow_as = /mob/living/simple_animal/hostile/poison/giant_spider/nurse - vents -= vent spawncount-- + successSpawn = TRUE diff --git a/code/modules/events/spider_terror.dm b/code/modules/events/spider_terror.dm index 75b86d20cb0..c5db5c5ce9e 100644 --- a/code/modules/events/spider_terror.dm +++ b/code/modules/events/spider_terror.dm @@ -2,25 +2,18 @@ /datum/event/spider_terror announceWhen = 240 var/spawncount = 1 + var/successSpawn = FALSE //So we don't make a command report if nothing gets spawned. /datum/event/spider_terror/setup() announceWhen = rand(announceWhen, announceWhen + 30) spawncount = 1 /datum/event/spider_terror/announce() - GLOB.command_announcement.Announce("Confirmed outbreak of level 3 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/effects/siren-spooky.ogg') + if(successSpawn) + GLOB.command_announcement.Announce("Confirmed outbreak of level 3 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/effects/siren-spooky.ogg') /datum/event/spider_terror/start() - - var/list/vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in GLOB.all_vent_pumps) - if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) - if(!temp_vent.parent) - // Issue happening more often with vents. Log and continue. Delete once solved - log_debug("spider_terror/start(), vent has no parent: [temp_vent], qdeled: [QDELETED(temp_vent)], loc: [temp_vent.loc]") - continue - if(temp_vent.parent.other_atmosmch.len > 50) - vents += temp_vent + var/list/vents = get_valid_vent_spawns() var/spider_type var/infestation_type = pick(1, 2, 3, 4, 5) switch(infestation_type) @@ -39,15 +32,9 @@ if(5) spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/princess spawncount = 2 - while(spawncount >= 1 && vents.len) - var/obj/machinery/atmospherics/unary/vent_pump/vent = pick(vents) - - if(vent.welded) - vents -= vent - continue - + while(spawncount && length(vents)) + var/obj/vent = pick(vents) // If the vent we picked has any living mob nearby, just remove it from the list, loop again, and pick something else. - var/turf/T = get_turf(vent) var/hostiles_present = FALSE for(var/mob/living/L in viewers(T)) @@ -59,4 +46,5 @@ if(!hostiles_present) new spider_type(vent.loc) spawncount-- + successSpawn = TRUE diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 3b86faeb7e6..2d9d49f3fdc 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1094,21 +1094,14 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \ return //find a viable mouse candidate - var/mob/living/simple_animal/mouse/host - var/obj/machinery/atmospherics/unary/vent_pump/vent_found - var/list/found_vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/v in SSair.atmos_machinery) - if(!v.welded && v.z == src.z) - found_vents.Add(v) - if(found_vents.len) - vent_found = pick(found_vents) - host = new /mob/living/simple_animal/mouse(vent_found.loc) - else - to_chat(src, "Unable to find any unwelded vents to spawn mice at.") - - if(host) + var/list/found_vents = get_valid_vent_spawns(min_network_size = 0, station_levels_only = FALSE, z_level = z) + if(length(found_vents)) + var/obj/vent_found = pick(found_vents) + var/mob/living/simple_animal/mouse/host = new(vent_found.loc) host.ckey = src.ckey to_chat(host, "You are now a mouse. Try to avoid interaction with players, and do not give hints away that you are more than a simple rodent.") + else + to_chat(src, "Unable to find any unwelded vents to spawn mice at.") /mob/proc/assess_threat() //For sec bot threat assessment return 5