diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index 4215151058..9847ab32e7 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -131,9 +131,12 @@ return //Removes any null entries from the list +//Returns TRUE if the list had nulls, FALSE otherwise /proc/listclearnulls(list/L) - var/list/N = new(L.len) + var/start_len = L.len + var/list/N = new(start_len) L -= N + return L.len < start_len /* * Returns list containing all the entries from first list that are not present in second. diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index c7ee4e93f8..d604319929 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -507,7 +507,8 @@ return //First we spawn a dude. - var/mob/living/carbon/human/new_character = new(pick(GLOB.latejoin))//The mob being spawned. + var/mob/living/carbon/human/new_character = new//The mob being spawned. + SSjob.SendToLateJoin(new_character) G_found.client.prefs.copy_to(new_character) new_character.dna.update_dna_identity() diff --git a/code/_globalvars/lists/mapping.dm b/code/_globalvars/lists/mapping.dm index eece2b4ca8..e874c97c17 100644 --- a/code/_globalvars/lists/mapping.dm +++ b/code/_globalvars/lists/mapping.dm @@ -32,7 +32,6 @@ GLOBAL_LIST_EMPTY(generic_event_spawns) //list of all spawns for events GLOBAL_LIST_EMPTY(wizardstart) GLOBAL_LIST_EMPTY(newplayer_start) -GLOBAL_LIST_EMPTY(latejoin) GLOBAL_LIST_EMPTY(prisonwarp) //prisoners go to these GLOBAL_LIST_EMPTY(holdingfacility) //captured people go here GLOBAL_LIST_EMPTY(xeno_spawn)//Aliens spawn at these. diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index c37e10b28c..43f7535298 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -11,6 +11,7 @@ SUBSYSTEM_DEF(job) var/initial_players_to_assign = 0 //used for checking against population caps var/list/prioritized_jobs = list() + var/list/latejoin_trackers = list() //Don't read this list, use GetLateJoinTurfs() instead /datum/controller/subsystem/job/Initialize(timeofday) if(!occupations.len) @@ -380,21 +381,7 @@ SUBSYSTEM_DEF(job) break if(!S) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper log_world("Couldn't find a round start spawn point for [rank]") - S = get_turf(pick(GLOB.latejoin)) - if(!S) //final attempt, lets find some area in the arrivals shuttle to spawn them in to. - log_world("Couldn't find a round start latejoin spawn point.") - for(var/turf/T in get_area_turfs(/area/shuttle/arrival)) - if(!T.density) - var/clear = 1 - for(var/obj/O in T) - if(O.density) - clear = 0 - break - if(clear) - S = T - continue - if(istype(S, /obj/effect/landmark) && isturf(S.loc)) - H.loc = S.loc + SendToLateJoin(H) if(H.mind) H.mind.assigned_role = rank @@ -516,3 +503,45 @@ SUBSYSTEM_DEF(job) newjob.total_positions = J.total_positions newjob.spawn_positions = J.spawn_positions newjob.current_positions = J.current_positions + +/datum/controller/subsystem/job/proc/SendToAtom(mob/M, atom/A, buckle) + if(buckle && isliving(M) && istype(A, /obj/structure/chair)) + var/obj/structure/chair/C = A + if(C.buckle_mob(M, FALSE, FALSE)) + return + M.forceMove(get_turf(A)) + +/datum/controller/subsystem/job/proc/SendToLateJoin(mob/M, buckle = TRUE) + if(latejoin_trackers.len) + SendToAtom(M, pick(latejoin_trackers), buckle) + else + //bad mojo + var/area/shuttle/arrival/A = locate() in GLOB.sortedAreas + if(A) + //first check if we can find a chair + var/obj/structure/chair/C = locate() in A + if(C) + SendToAtom(M, C, buckle) + return + else //last hurrah + var/list/avail = list() + for(var/turf/T in A) + if(!is_blocked_turf(T, TRUE)) + avail += T + if(avail.len) + SendToAtom(M, pick(avail), FALSE) + return + + //pick an open spot on arrivals and dump em + var/list/arrivals_turfs = shuffle(get_area_turfs(/area/shuttle/arrival)) + if(arrivals_turfs.len) + for(var/turf/T in arrivals_turfs) + if(!is_blocked_turf(T, TRUE)) + SendToAtom(M, T, FALSE) + return + //last chance, pick ANY spot on arrivals and dump em + SendToAtom(M, arrivals_turfs[1], FALSE) + else + var/msg = "Unable to send mob [M] to late join!" + message_admins(msg) + CRASH(msg) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index e85667e29a..be5180c2ae 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1447,7 +1447,7 @@ special_role = "Wizard" assigned_role = "Wizard" if(!GLOB.wizardstart.len) - current.loc = pick(GLOB.latejoin) + SSjob.SendToLateJoin(current) to_chat(current, "HOT INSERTION, GO GO GO") else current.loc = pick(GLOB.wizardstart) diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm index 2bd7fd17fa..553276e6aa 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm @@ -212,13 +212,12 @@ /obj/machinery/abductor/experiment/proc/SendBack(mob/living/carbon/human/H) H.Sleeping(8) + H.uncuff() if(console && console.pad && console.pad.teleport_target) H.forceMove(console.pad.teleport_target) - H.uncuff() return //Area not chosen / It's not safe area - teleport to arrivals - H.forceMove(pick(GLOB.latejoin)) - H.uncuff() + SSjob.SendToLateJoin(H, FALSE) return diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm index d8bf34c99e..06ba9ec2b5 100644 --- a/code/game/gamemodes/wizard/raginmages.dm +++ b/code/game/gamemodes/wizard/raginmages.dm @@ -142,7 +142,8 @@ return //First we spawn a dude. - var/mob/living/carbon/human/new_character = new(pick(GLOB.latejoin))//The mob being spawned. + var/mob/living/carbon/human/new_character = new//The mob being spawned. + SSjob.SendToLateJoin(new_character) G_found.client.prefs.copy_to(new_character) new_character.dna.update_dna_identity() diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 5ce88f1c27..2c701ee274 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -182,7 +182,7 @@ /obj/effect/landmark/latejoin/Initialize(mapload) ..() - GLOB.latejoin += loc + SSjob.latejoin_trackers += loc qdel(src) // carp. diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index 7202aeae1c..e1531b4ef7 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -25,7 +25,7 @@ return ..() /obj/structure/chair/proc/RemoveFromLatejoin() - GLOB.latejoin -= src //These may be here due to the arrivals shuttle + SSjob.latejoin_trackers -= src //These may be here due to the arrivals shuttle /obj/structure/chair/deconstruct() // If we have materials, and don't have the NOCONSTRUCT flag diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index b89d219245..cca58f90f3 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -590,7 +590,7 @@ set category = "Admin" set name = "Unprison" if (M.z == ZLEVEL_CENTCOM) - M.loc = pick(GLOB.latejoin) + SSjob.SendToLateJoin(M) message_admins("[key_name_admin(usr)] has unprisoned [key_name_admin(M)]") log_admin("[key_name(usr)] has unprisoned [key_name(M)]") else diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index ecb4f7a993..c31ec9b537 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -227,7 +227,7 @@ return 0 var/alien_caste = input(usr, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Praetorian","Hunter","Sentinel","Drone","Larva") - var/obj/effect/landmark/spawn_here = GLOB.xeno_spawn.len ? pick(GLOB.xeno_spawn) : pick(GLOB.latejoin) + var/obj/effect/landmark/spawn_here = GLOB.xeno_spawn.len ? pick(GLOB.xeno_spawn) : null var/mob/living/carbon/alien/new_xeno switch(alien_caste) if("Queen") @@ -244,6 +244,8 @@ new_xeno = new /mob/living/carbon/alien/larva(spawn_here) else return 0 + if(!spawn_here) + SSjob.SendToLateJoin(new_xeno, FALSE) new_xeno.ckey = ckey var/msg = "[key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste]." @@ -284,8 +286,6 @@ Traitors and the like can also be revived with the previous role mostly intact. var/turf/T if(GLOB.xeno_spawn.len) T = pick(GLOB.xeno_spawn) - else - T = pick(GLOB.latejoin) var/mob/living/carbon/alien/new_xeno switch(G_found.mind.special_role)//If they have a mind, we can determine which caste they were. @@ -302,6 +302,9 @@ Traitors and the like can also be revived with the previous role mostly intact. else//If we don't know what special role they have, for whatever reason, or they're a larva. create_xeno(G_found.ckey) return + + if(!T) + SSjob.SendToLateJoin(new_xeno, FALSE) //Now to give them their mind back. G_found.mind.transfer_to(new_xeno) //be careful when doing stuff like this! I've already checked the mind isn't in use @@ -315,7 +318,8 @@ Traitors and the like can also be revived with the previous role mostly intact. //check if they were a monkey else if(findtext(G_found.real_name,"monkey")) if(alert("This character appears to have been a monkey. Would you like to respawn them as such?",,"Yes","No")=="Yes") - var/mob/living/carbon/monkey/new_monkey = new(pick(GLOB.latejoin)) + var/mob/living/carbon/monkey/new_monkey = new + SSjob.SendToLateJoin(new_monkey) G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use new_monkey.key = G_found.key to_chat(new_monkey, "You have been fully respawned. Enjoy the game.") @@ -326,7 +330,8 @@ Traitors and the like can also be revived with the previous role mostly intact. //Ok, it's not a xeno or a monkey. So, spawn a human. - var/mob/living/carbon/human/new_character = new(pick(GLOB.latejoin))//The mob being spawned. + var/mob/living/carbon/human/new_character = new//The mob being spawned. + SSjob.SendToLateJoin(new_character) var/datum/data/record/record_found //Referenced to later to either randomize or not randomize the character. if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something diff --git a/code/modules/events/devil.dm b/code/modules/events/devil.dm index 69648fa95a..e155e6c558 100644 --- a/code/modules/events/devil.dm +++ b/code/modules/events/devil.dm @@ -14,9 +14,7 @@ /datum/round_event/ghost_role/devil/spawn_role() //selecting a spawn_loc - var/list/spawn_locs = GLOB.latejoin - var/spawn_loc = pick(spawn_locs) - if(!spawn_loc) + if(!SSjob.latejoin_trackers.len) return MAP_ERROR //selecting a candidate player @@ -45,6 +43,8 @@ /proc/create_event_devil(spawn_loc) var/mob/living/carbon/human/new_devil = new(spawn_loc) + if(!spawn_loc) + SSjob.SendToLateJoin(new_devil) var/datum/preferences/A = new() //Randomize appearance for the devil. A.copy_to(new_devil) new_devil.dna.update_dna_identity() diff --git a/code/modules/events/devil.dm.rej b/code/modules/events/devil.dm.rej new file mode 100644 index 0000000000..460aca4f5a --- /dev/null +++ b/code/modules/events/devil.dm.rej @@ -0,0 +1,10 @@ +diff a/code/modules/events/devil.dm b/code/modules/events/devil.dm (rejected hunks) +@@ -30,7 +28,7 @@ + var/datum/mind/Mind = create_devil_mind(key) + Mind.active = 1 + +- var/mob/living/carbon/human/devil = create_event_devil(spawn_loc) ++ var/mob/living/carbon/human/devil = create_event_devil() + Mind.transfer_to(devil) + SSticker.mode.finalize_devil(Mind, FALSE) + SSticker.mode.add_devil_objectives(src, 2) diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index e3943d07e6..dab0cca302 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -322,28 +322,9 @@ if(isliving(equip)) //Borgs get borged in the equip, so we need to make sure we handle the new mob. character = equip - var/D - if(GLOB.latejoin.len) - D = get_turf(pick(GLOB.latejoin)) - if(!D) - for(var/turf/T in get_area_turfs(/area/shuttle/arrival)) - if(!T.density) - var/clear = 1 - for(var/obj/O in T) - if(O.density) - clear = 0 - break - if(clear) - D = T - continue - - character.loc = D + SSjob.SendToLateJoin(character) character.update_parallax_teleport() - var/atom/movable/chair = locate(/obj/structure/chair) in character.loc - if(chair) - chair.buckle_mob(character) - SSticker.minds += character.mind var/mob/living/carbon/human/humanc diff --git a/code/modules/shuttle/arrivals.dm b/code/modules/shuttle/arrivals.dm index 7cb347d429..d6aed6d5b0 100644 --- a/code/modules/shuttle/arrivals.dm +++ b/code/modules/shuttle/arrivals.dm @@ -48,16 +48,16 @@ console = locate(/obj/machinery/requests_console) in A areas += A - if(GLOB.latejoin.len) + if(SSjob.latejoin_trackers.len) WARNING("Map contains predefined latejoin spawn points and an arrivals shuttle. Using the arrivals shuttle.") if(!new_latejoin.len) WARNING("Arrivals shuttle contains no chairs for spawn points. Reverting to latejoin landmarks.") - if(!GLOB.latejoin.len) + if(!SSjob.latejoin_trackers.len) WARNING("No latejoin landmarks exist. Players will spawn unbuckled on the shuttle.") return - GLOB.latejoin = new_latejoin + SSjob.latejoin_trackers = new_latejoin /obj/docking_port/mobile/arrivals/dockRoundstart() SSshuttle.generate_transit_dock(src) @@ -114,7 +114,7 @@ Launch(FALSE) /obj/docking_port/mobile/arrivals/proc/CheckTurfsPressure() - for(var/I in GLOB.latejoin) + for(var/I in SSjob.latejoin_trackers) var/turf/open/T = get_turf(I) var/pressure = T.air.return_pressure() if(pressure < HAZARD_LOW_PRESSURE || pressure > HAZARD_HIGH_PRESSURE) //simple safety check