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")