diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 414a2d092a..be5f6b33db 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -5,11 +5,16 @@ /datum/datacore var/name = "datacore" - var/medical[] = list() - var/general[] = list() - var/security[] = list() + //For general station crew + var/static/list/medical = list() + var/static/list/general = list() + var/static/list/security = list() + //For offmap spawns so they can have records accessible by certain things + var/static/list/hidden_medical = list() + var/static/list/hidden_general = list() + var/static/list/hidden_security = list() //This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character(). - var/locked[] = list() + var/static/list/locked = list() /datum/datacore/proc/get_manifest(monochrome, OOC) @@ -22,6 +27,7 @@ var/list/pla = new() //VOREStation Edit var/list/civ = new() var/list/bot = new() + var/list/off = new() var/list/misc = new() var/list/isactive = new() var/dat = {" @@ -46,7 +52,7 @@ if(OOC) var/active = 0 for(var/mob/M in player_list) - if(M.real_name == name && M.client && M.client.inactivity <= 10 * 60 * 10) + if(M.real_name == name && M.client && M.client.inactivity <= 10 MINUTES) active = 1 break isactive[name] = active ? "Active" : "Inactive" @@ -84,6 +90,24 @@ if(!department && !(name in heads)) misc[name] = rank + //For the offmap spawns + if(OOC) + for(var/datum/data/record/t in hidden_general) + var/name = t.fields["name"] + var/rank = t.fields["rank"] + var/real_rank = make_list_rank(t.fields["real_rank"]) + + var/active = 0 + for(var/mob/M in player_list) + if(M.real_name == name && M.client && M.client.inactivity <= 10 MINUTES) + active = 1 + break + isactive[name] = active ? "Active" : "Inactive" + + var/datum/job/J = SSjob.get_job(real_rank) + if(J?.offmap_spawn) + off[name] = rank + // Synthetics don't have actual records, so we will pull them from here. for(var/mob/living/silicon/ai/ai in mob_list) bot[ai.name] = "Artificial Intelligence" @@ -142,6 +166,12 @@ for(name in bot) dat += "[name][bot[name]][isactive[name]]" even = !even + // offmap spawners + if(off.len > 0) + dat += "Offmap Spawns" + for(name in off) + dat += "[name][off[name]][isactive[name]]" + even = !even // misc guys if(misc.len > 0) dat += "Miscellaneous" @@ -154,6 +184,117 @@ dat = replacetext(dat, "\t", "") return dat +/* +We can't just insert in HTML into the nanoUI so we need the raw data to play with. +Instead of creating this list over and over when someone leaves their PDA open to the page +we'll only update it when it changes. The PDA_Manifest global list is zeroed out upon any change +using /datum/datacore/proc/manifest_inject( ), or manifest_insert( ) +*/ + +var/global/list/PDA_Manifest = list() + +/datum/datacore/proc/get_manifest_list() + if(PDA_Manifest.len) + return + var/list/heads = list() + var/list/sec = list() + var/list/eng = list() + var/list/med = list() + var/list/sci = list() + var/list/car = list() + var/list/pla = list() // Planetside crew: Explorers, Pilots, S&S + var/list/civ = list() + var/list/bot = list() + var/list/misc = list() + for(var/datum/data/record/t in data_core.general) + var/name = sanitize(t.fields["name"]) + var/rank = sanitize(t.fields["rank"]) + var/real_rank = make_list_rank(t.fields["real_rank"]) + + var/isactive = t.fields["p_stat"] + var/department = 0 + var/depthead = 0 // Department Heads will be placed at the top of their lists. + if(SSjob.is_job_in_department(real_rank, DEPARTMENT_COMMAND)) + heads[++heads.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + depthead = 1 + if(rank=="Colony Director" && heads.len != 1) + heads.Swap(1,heads.len) + + if(SSjob.is_job_in_department(real_rank, DEPARTMENT_SECURITY)) + sec[++sec.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + if(depthead && sec.len != 1) + sec.Swap(1,sec.len) + + if(SSjob.is_job_in_department(real_rank, DEPARTMENT_ENGINEERING)) + eng[++eng.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + if(depthead && eng.len != 1) + eng.Swap(1,eng.len) + + if(SSjob.is_job_in_department(real_rank, DEPARTMENT_MEDICAL)) + med[++med.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + if(depthead && med.len != 1) + med.Swap(1,med.len) + + if(SSjob.is_job_in_department(real_rank, DEPARTMENT_RESEARCH)) + sci[++sci.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + if(depthead && sci.len != 1) + sci.Swap(1,sci.len) + + if(SSjob.is_job_in_department(real_rank, DEPARTMENT_PLANET)) + pla[++pla.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + + if(SSjob.is_job_in_department(real_rank, DEPARTMENT_CARGO)) + car[++car.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + if(depthead && car.len != 1) + car.Swap(1,car.len) + + if(SSjob.is_job_in_department(real_rank, DEPARTMENT_CIVILIAN)) + civ[++civ.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + if(depthead && civ.len != 1) + civ.Swap(1,civ.len) + + if(SSjob.is_job_in_department(real_rank, DEPARTMENT_SYNTHETIC)) + bot[++bot.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + + if(!department && !(name in heads)) + misc[++misc.len] = list("name" = name, "rank" = rank, "active" = isactive) + + // Synthetics don't have actual records, so we will pull them from here. + // Synths don't have records, which is the means by which isactive is retrieved, so I'm hardcoding it to active, don't really have any better means + for(var/mob/living/silicon/ai/ai in mob_list) + bot[++bot.len] = list("name" = ai.real_name, "rank" = "Artificial Intelligence", "active" = "Active") + + for(var/mob/living/silicon/robot/robot in mob_list) + // No combat/syndicate cyborgs, no drones, and no AI shells. + if(robot.scrambledcodes || robot.shell || (robot.module && robot.module.hide_on_manifest)) + continue + + bot[++bot.len] = list("name" = robot.real_name, "rank" = "[robot.modtype] [robot.braintype]", "active" = "Active") + + + PDA_Manifest = list( + list("cat" = "Command", "elems" = heads), + list("cat" = "Security", "elems" = sec), + list("cat" = "Engineering", "elems" = eng), + list("cat" = "Medical", "elems" = med), + list("cat" = "Science", "elems" = sci), + list("cat" = "Cargo", "elems" = car), + list("cat" = "Exploration", "elems" = pla), // VOREStation Edit + list("cat" = "Civilian", "elems" = civ), + list("cat" = "Silicon", "elems" = bot), + list("cat" = "Miscellaneous", "elems" = misc) + ) + return + /datum/datacore/proc/manifest() spawn() for(var/mob/living/carbon/human/H in player_list) @@ -187,10 +328,13 @@ /datum/datacore/proc/manifest_inject(var/mob/living/carbon/human/H) if(H.mind && !player_is_antag(H.mind, only_offstation_roles = 1)) var/assignment = GetAssignment(H) + var/hidden + var/datum/job/J = SSjob.get_job(assignment) + hidden = J?.offmap_spawn var/id = generate_record_id() //General Record - var/datum/data/record/G = CreateGeneralRecord(H, id) + var/datum/data/record/G = CreateGeneralRecord(H, id, hidden) G.fields["name"] = H.real_name G.fields["real_rank"] = H.mind.assigned_role G.fields["rank"] = assignment @@ -212,7 +356,7 @@ G.fields["notes"] = H.gen_record //Medical Record - var/datum/data/record/M = CreateMedicalRecord(H.real_name, id) + var/datum/data/record/M = CreateMedicalRecord(H.real_name, id, hidden) M.fields["b_type"] = H.b_type M.fields["b_dna"] = H.dna.unique_enzymes M.fields["id_gender"] = gender2text(H.identifying_gender) @@ -224,7 +368,7 @@ M.fields["notes"] = H.med_record //Security Record - var/datum/data/record/S = CreateSecurityRecord(H.real_name, id) + var/datum/data/record/S = CreateSecurityRecord(H.real_name, id, hidden) if(H.get_FBP_type()) S.fields["brain_type"] = H.get_FBP_type() else @@ -257,6 +401,7 @@ L.fields["image"] = icon(cached_character_icon(H), dir = SOUTH) L.fields["antagfac"] = H.antag_faction L.fields["antagvis"] = H.antag_vis + L.fields["offmap"] = hidden if(H.exploit_record && !jobban_isbanned(H, "Records")) L.fields["exploit_record"] = H.exploit_record else @@ -267,7 +412,7 @@ /proc/generate_record_id() return add_zero(num2hex(rand(1, 65535)), 4) //no point generating higher numbers because of the limitations of num2hex -/datum/datacore/proc/CreateGeneralRecord(var/mob/living/carbon/human/H, var/id) +/datum/datacore/proc/CreateGeneralRecord(var/mob/living/carbon/human/H, var/id, var/hidden) ResetPDAManifest() var/icon/front var/icon/side @@ -301,11 +446,14 @@ G.fields["photo_front"] = front G.fields["photo_side"] = side G.fields["notes"] = "No notes found." - general += G + if(hidden) + hidden_general += G + else + general += G return G -/datum/datacore/proc/CreateSecurityRecord(var/name, var/id) +/datum/datacore/proc/CreateSecurityRecord(var/name, var/id, var/hidden) ResetPDAManifest() var/datum/data/record/R = new /datum/data/record() R.name = "Security Record #[id]" @@ -319,11 +467,14 @@ R.fields["ma_crim_d"] = "No major crime convictions." R.fields["notes"] = "No notes." R.fields["notes"] = "No notes." - data_core.security += R + if(hidden) + hidden_security += R + else + security += R return R -/datum/datacore/proc/CreateMedicalRecord(var/name, var/id) +/datum/datacore/proc/CreateMedicalRecord(var/name, var/id, var/hidden) ResetPDAManifest() var/datum/data/record/M = new() M.name = "Medical Record #[id]" @@ -342,7 +493,10 @@ M.fields["cdi"] = "None" M.fields["cdi_d"] = "No diseases have been diagnosed at the moment." M.fields["notes"] = "No notes found." - data_core.medical += M + if(hidden) + hidden_medical += M + else + medical += M return M diff --git a/code/defines/obj.dm b/code/defines/obj.dm index 293ea99e7f..187b69e021 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -52,120 +52,6 @@ return copytext(rank, 2+length(prefix)) return rank - -/* -We can't just insert in HTML into the nanoUI so we need the raw data to play with. -Instead of creating this list over and over when someone leaves their PDA open to the page -we'll only update it when it changes. The PDA_Manifest global list is zeroed out upon any change -using /datum/datacore/proc/manifest_inject( ), or manifest_insert( ) -*/ - -var/global/list/PDA_Manifest = list() - -/datum/datacore/proc/get_manifest_list() - if(PDA_Manifest.len) - return - var/list/heads = list() - var/list/sec = list() - var/list/eng = list() - var/list/med = list() - var/list/sci = list() - var/list/car = list() - var/list/pla = list() // Planetside crew: Explorers, Pilots, S&S - var/list/civ = list() - var/list/bot = list() - var/list/misc = list() - for(var/datum/data/record/t in data_core.general) - var/name = sanitize(t.fields["name"]) - var/rank = sanitize(t.fields["rank"]) - var/real_rank = make_list_rank(t.fields["real_rank"]) - - var/isactive = t.fields["p_stat"] - var/department = 0 - var/depthead = 0 // Department Heads will be placed at the top of their lists. - if(SSjob.is_job_in_department(real_rank, DEPARTMENT_COMMAND)) - heads[++heads.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - depthead = 1 - if(rank=="Colony Director" && heads.len != 1) - heads.Swap(1,heads.len) - - if(SSjob.is_job_in_department(real_rank, DEPARTMENT_SECURITY)) - sec[++sec.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && sec.len != 1) - sec.Swap(1,sec.len) - - if(SSjob.is_job_in_department(real_rank, DEPARTMENT_ENGINEERING)) - eng[++eng.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && eng.len != 1) - eng.Swap(1,eng.len) - - if(SSjob.is_job_in_department(real_rank, DEPARTMENT_MEDICAL)) - med[++med.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && med.len != 1) - med.Swap(1,med.len) - - if(SSjob.is_job_in_department(real_rank, DEPARTMENT_RESEARCH)) - sci[++sci.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && sci.len != 1) - sci.Swap(1,sci.len) - - if(SSjob.is_job_in_department(real_rank, DEPARTMENT_PLANET)) - pla[++pla.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - - if(SSjob.is_job_in_department(real_rank, DEPARTMENT_CARGO)) - car[++car.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && car.len != 1) - car.Swap(1,car.len) - - if(SSjob.is_job_in_department(real_rank, DEPARTMENT_CIVILIAN)) - civ[++civ.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && civ.len != 1) - civ.Swap(1,civ.len) - - if(SSjob.is_job_in_department(real_rank, DEPARTMENT_SYNTHETIC)) - bot[++bot.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - - if(!department && !(name in heads)) - misc[++misc.len] = list("name" = name, "rank" = rank, "active" = isactive) - - // Synthetics don't have actual records, so we will pull them from here. - // Synths don't have records, which is the means by which isactive is retrieved, so I'm hardcoding it to active, don't really have any better means - for(var/mob/living/silicon/ai/ai in mob_list) - bot[++bot.len] = list("name" = ai.real_name, "rank" = "Artificial Intelligence", "active" = "Active") - - for(var/mob/living/silicon/robot/robot in mob_list) - // No combat/syndicate cyborgs, no drones, and no AI shells. - if(robot.scrambledcodes || robot.shell || (robot.module && robot.module.hide_on_manifest)) - continue - - bot[++bot.len] = list("name" = robot.real_name, "rank" = "[robot.modtype] [robot.braintype]", "active" = "Active") - - - PDA_Manifest = list( - list("cat" = "Command", "elems" = heads), - list("cat" = "Security", "elems" = sec), - list("cat" = "Engineering", "elems" = eng), - list("cat" = "Medical", "elems" = med), - list("cat" = "Science", "elems" = sci), - list("cat" = "Cargo", "elems" = car), - list("cat" = "Exploration", "elems" = pla), // VOREStation Edit - list("cat" = "Civilian", "elems" = civ), - list("cat" = "Silicon", "elems" = bot), - list("cat" = "Miscellaneous", "elems" = misc) - ) - return - - - /obj/effect/laser name = "laser" desc = "IT BURNS!!!" diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index 6bc533370a..082753d0fc 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -30,6 +30,8 @@ var/outfit_type // What outfit datum does this job use in its default title? + var/offmap_spawn = FALSE // Do we require weird and special spawning and datacore handling? + // Description of the job's role and minimum responsibilities. var/job_description = "This Job doesn't have a description! Please report it!" @@ -67,7 +69,7 @@ //give them an account in the station database var/money_amount = (rand(15,40) + rand(15,40)) * income * economic_modifier * ECO_MODIFIER //VOREStation Edit - Smoothed peaks, ECO_MODIFIER rather than per-species ones. - var/datum/money_account/M = create_account(H.real_name, money_amount, null) + var/datum/money_account/M = create_account(H.real_name, money_amount, null, offmap_spawn) if(H.mind) var/remembered_info = "" remembered_info += "Your account number is: #[M.account_number]
" diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 3d6fa2045c..34e75f4320 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -357,7 +357,11 @@ var/global/datum/controller/occupations/job_master else var/list/spawn_props = LateSpawn(H.client, rank) var/turf/T = spawn_props["turf"] - H.forceMove(T) + if(!T) + to_chat(H, "You were unable to be spawned at your chosen late-join spawnpoint. Please verify your job/spawn point combination makes sense, and try another one.") + return + else + H.forceMove(T) // Moving wheelchair if they have one if(H.buckled && istype(H.buckled, /obj/structure/bed/chair/wheelchair)) @@ -458,8 +462,8 @@ var/global/datum/controller/occupations/job_master if("AI") return H if("Colony Director") - var/sound/announce_sound = (ticker.current_state <= GAME_STATE_SETTING_UP)? null : sound('sound/misc/boatswain.ogg', volume=20) - captain_announcement.Announce("All hands, [alt_title ? alt_title : "Colony Director"] [H.real_name] on deck!", new_sound=announce_sound) + var/sound/announce_sound = (ticker.current_state <= GAME_STATE_SETTING_UP) ? null : sound('sound/misc/boatswain.ogg', volume=20) + captain_announcement.Announce("All hands, [alt_title ? alt_title : "Colony Director"] [H.real_name] on deck!", new_sound = announce_sound, zlevel = H.z) //Deferred item spawning. if(spawn_in_storage && spawn_in_storage.len) @@ -608,12 +612,20 @@ var/global/datum/controller/occupations/job_master /datum/controller/occupations/proc/LateSpawn(var/client/C, var/rank) var/datum/spawnpoint/spawnpos + var/fail_deadly = FALSE + + var/datum/job/J = SSjob.get_job(rank) + fail_deadly = J?.offmap_spawn //Spawn them at their preferred one if(C && C.prefs.spawnpoint) if(!(C.prefs.spawnpoint in using_map.allowed_spawns)) - to_chat(C, "Your chosen spawnpoint ([C.prefs.spawnpoint]) is unavailable for the current map. Spawning you at one of the enabled spawn points instead.") - spawnpos = null + if(fail_deadly) + to_chat(C, "Your chosen spawnpoint is unavailable for this map and your job requires a specific spawnpoint. Please correct your spawn point choice.") + return + else + to_chat(C, "Your chosen spawnpoint ([C.prefs.spawnpoint]) is unavailable for the current map. Spawning you at one of the enabled spawn points instead.") + spawnpos = null else spawnpos = spawntypes[C.prefs.spawnpoint] @@ -623,12 +635,16 @@ var/global/datum/controller/occupations/job_master if(spawnpos.check_job_spawning(rank)) .["turf"] = spawnpos.get_spawn_position() .["msg"] = spawnpos.msg + .["channel"] = spawnpos.announce_channel else + if(fail_deadly) + to_chat(C, "Your chosen spawnpoint ([spawnpos.display_name]) is unavailable for your chosen job. Please correct your spawn point choice.") + return to_chat(C, "Your chosen spawnpoint ([spawnpos.display_name]) is unavailable for your chosen job. Spawning you at the Arrivals shuttle instead.") var/spawning = pick(latejoin) .["turf"] = get_turf(spawning) .["msg"] = "will arrive at the station shortly" //VOREStation Edit - Grammar but mostly 'shuttle' reference removal, and this also applies to notified spawn-character verb use - else + else if(!fail_deadly) var/spawning = pick(latejoin) .["turf"] = get_turf(spawning) .["msg"] = "has arrived on the station" diff --git a/code/game/world.dm b/code/game/world.dm index 52927b7dd7..bfcf691754 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -181,6 +181,17 @@ var/world_topic_spam_protect_time = world.timeofday if(!positions["misc"]) positions["misc"] = list() positions["misc"][name] = rank + + for(var/datum/data/record/t in data_core.hidden_general) + var/name = t.fields["name"] + var/rank = t.fields["rank"] + var/real_rank = make_list_rank(t.fields["real_rank"]) + + var/datum/job/J = SSjob.get_job(real_rank) + if(J?.offmap_spawn) + if(!positions["off"]) + positions["off"] = list() + positions["off"][name] = rank // Synthetics don't have actual records, so we will pull them from here. for(var/mob/living/silicon/ai/ai in mob_list) diff --git a/code/modules/client/preferences_spawnpoints.dm b/code/modules/client/preferences_spawnpoints.dm index c0c54169b2..acf1c771a7 100644 --- a/code/modules/client/preferences_spawnpoints.dm +++ b/code/modules/client/preferences_spawnpoints.dm @@ -12,6 +12,7 @@ var/list/spawntypes = list() var/display_name //Name used in preference setup. var/list/restrict_job = null var/list/disallow_job = null + var/announce_channel = "Common" proc/check_job_spawning(job) if(restrict_job && !(job in restrict_job)) @@ -20,6 +21,10 @@ var/list/spawntypes = list() if(disallow_job && (job in disallow_job)) return 0 + var/datum/job/J = SSjob.get_job(job) + if(J?.offmap_spawn && !(job in restrict_job)) + return 0 + return 1 /datum/spawnpoint/proc/get_spawn_position() diff --git a/code/modules/economy/Accounts.dm b/code/modules/economy/Accounts.dm index cfd720d4dc..37979f96c5 100644 --- a/code/modules/economy/Accounts.dm +++ b/code/modules/economy/Accounts.dm @@ -9,6 +9,7 @@ var/security_level = 0 //0 - auto-identify from worn ID, require only account number //1 - require manual login / account number and pin //2 - require card and manual login + var/offmap = FALSE //Should this account be hidden from station consoles? /datum/transaction var/target_name = "" @@ -18,10 +19,11 @@ var/time = "" var/source_terminal = "" -/proc/create_account(var/new_owner_name = "Default user", var/starting_funds = 0, var/obj/machinery/account_database/source_db) +/proc/create_account(var/new_owner_name = "Default user", var/starting_funds = 0, var/obj/machinery/account_database/source_db, var/offmap = FALSE) //create a new account var/datum/money_account/M = new() + M.offmap = offmap M.owner_name = new_owner_name M.remote_access_pin = rand(1111, 111111) M.money = starting_funds diff --git a/code/modules/economy/Accounts_DB.dm b/code/modules/economy/Accounts_DB.dm index 251ba09e36..9e116ecf60 100644 --- a/code/modules/economy/Accounts_DB.dm +++ b/code/modules/economy/Accounts_DB.dm @@ -14,31 +14,31 @@ var/creating_new_account = 0 var/const/fund_cap = 1000000 - proc/get_access_level() - if (!held_card) - return 0 - if(access_cent_captain in held_card.access) - return 2 - else if(access_hop in held_card.access || access_captain in held_card.access) - return 1 +/obj/machinery/account_database/proc/get_access_level() + if (!held_card) + return 0 + if(access_cent_captain in held_card.access) + return 2 + else if(access_hop in held_card.access || access_captain in held_card.access) + return 1 - proc/create_transation(target, reason, amount) - var/datum/transaction/T = new() - T.target_name = target - T.purpose = reason - T.amount = amount - T.date = current_date_string - T.time = stationtime2text() - T.source_terminal = machine_id - return T +/obj/machinery/account_database/proc/create_transation(target, reason, amount) + var/datum/transaction/T = new() + T.target_name = target + T.purpose = reason + T.amount = amount + T.date = current_date_string + T.time = stationtime2text() + T.source_terminal = machine_id + return T - proc/accounting_letterhead(report_name) - return {" -

[report_name]

-
[station_name()] Accounting Report
-
- Generated By: [held_card.registered_name], [held_card.assignment]
- "} +/obj/machinery/account_database/proc/accounting_letterhead(report_name) + return {" +

[report_name]

+
[station_name()] Accounting Report
+
+ Generated By: [held_card.registered_name], [held_card.assignment]
+ "} /obj/machinery/account_database/New() machine_id = "[station_name()] Acc. DB #[num_financial_terminals++]" @@ -98,6 +98,8 @@ var/list/accounts[0] for(var/i=1, i<=all_money_accounts.len, i++) var/datum/money_account/D = all_money_accounts[i] + if(D.offmap) + continue accounts.Add(list(list(\ "account_number"=D.account_number,\ "owner_name"=D.owner_name,\ diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 799e177304..ae07a7dfe4 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -368,8 +368,13 @@ //Find our spawning point. var/list/join_props = job_master.LateSpawn(client, rank) + + if(!join_props) + return + var/turf/T = join_props["turf"] var/join_message = join_props["msg"] + var/announce_channel = join_props["channel"] || "Common" if(!T || !join_message) return 0 @@ -451,6 +456,8 @@ dat += "Choose from the following open/valid positions:
" dat += "[show_hidden_jobs ? "Hide":"Show"] Hidden Jobs.
" + + var/deferred = "" for(var/datum/job/job in job_master.occupations) if(job && IsJobAvailable(job.title)) // Checks for jobs with minimum age requirements @@ -464,9 +471,17 @@ continue var/active = 0 // Only players with the job assigned and AFK for less than 10 minutes count as active - for(var/mob/M in player_list) if(M.mind && M.client && M.mind.assigned_role == job.title && M.client.inactivity <= 10 * 60 * 10) + for(var/mob/M in player_list) if(M.mind && M.client && M.mind.assigned_role == job.title && M.client.inactivity <= 10 MINUTES) active++ - dat += "[job.title] ([job.current_positions]) (Active: [active])
" + + var/string = "[job.title] ([job.current_positions]) (Active: [active])
" + + if(job.offmap_spawn) //At the bottom + deferred += string + else + dat += string + + dat += deferred dat += "" src << browse(dat, "window=latechoices;size=300x640;can_close=1")