diff --git a/citadel.dme b/citadel.dme
index f0c65208395..68b56425e5c 100644
--- a/citadel.dme
+++ b/citadel.dme
@@ -574,6 +574,7 @@
#include "code\controllers\repository\material_traits.dm"
#include "code\controllers\repository\materials.dm"
#include "code\controllers\repository\poster_designs.dm"
+#include "code\controllers\repository\roles.dm"
#include "code\controllers\repository\structs.dm"
#include "code\controllers\subsystem\ai_holders.dm"
#include "code\controllers\subsystem\ai_legacy.dm"
@@ -661,7 +662,6 @@
#include "code\controllers\subsystem\job\_legacy_job_stuff.dm"
#include "code\controllers\subsystem\job\access.dm"
#include "code\controllers\subsystem\job\jexp.dm"
-#include "code\controllers\subsystem\job\job_manager.dm"
#include "code\controllers\subsystem\job\joining.dm"
#include "code\controllers\subsystem\job\roundstart.dm"
#include "code\controllers\subsystem\job\spawnpoints.dm"
@@ -3154,19 +3154,20 @@
#include "code\modules\gateway\stargate\stargate-station.dm"
#include "code\modules\gateway\stargate\stargate.dm"
#include "code\modules\genetics\side_effects.dm"
-#include "code\modules\ghostroles\instantiator.dm"
-#include "code\modules\ghostroles\menu.dm"
-#include "code\modules\ghostroles\role.dm"
-#include "code\modules\ghostroles\spawner.dm"
-#include "code\modules\ghostroles\spawnpoint.dm"
-#include "code\modules\ghostroles\roles\ashlander.dm"
-#include "code\modules\ghostroles\roles\hermit.dm"
-#include "code\modules\ghostroles\roles\lythios_colonist.dm"
-#include "code\modules\ghostroles\roles\occulum_agent.dm"
-#include "code\modules\ghostroles\roles\pirate.dm"
-#include "code\modules\ghostroles\roles\salvager.dm"
-#include "code\modules\ghostroles\roles\sapient_mob.dm"
-#include "code\modules\ghostroles\roles\sdf.dm"
+#include "code\modules\roles\role_tweak.dm"
+#include "code\modules\roles\ghostroles\instantiator.dm"
+#include "code\modules\roles\ghostroles\menu.dm"
+#include "code\modules\roles\ghostroles\role.dm"
+#include "code\modules\roles\ghostroles\spawner.dm"
+#include "code\modules\roles\ghostroles\spawnpoint.dm"
+#include "code\modules\roles\ghostroles\roles\ashlander.dm"
+#include "code\modules\roles\ghostroles\roles\hermit.dm"
+#include "code\modules\roles\ghostroles\roles\lythios_colonist.dm"
+#include "code\modules\roles\ghostroles\roles\occulum_agent.dm"
+#include "code\modules\roles\ghostroles\roles\pirate.dm"
+#include "code\modules\roles\ghostroles\roles\salvager.dm"
+#include "code\modules\roles\ghostroles\roles\sapient_mob.dm"
+#include "code\modules\roles\ghostroles\roles\sdf.dm"
#include "code\modules\ghosttrap\trap.dm"
#include "code\modules\guidebook\guidebook.dm"
#include "code\modules\guidebook\guidebook_section.dm"
@@ -3318,84 +3319,84 @@
#include "code\modules\integrated_electronics\tools\debugger.dm"
#include "code\modules\integrated_electronics\tools\wirer.dm"
#include "code\modules\integrated_electronics\~defines\~defines.dm"
-#include "code\modules\jobs\access.dm"
-#include "code\modules\jobs\alt_title.dm"
-#include "code\modules\jobs\department.dm"
-#include "code\modules\jobs\job.dm"
-#include "code\modules\jobs\jobs.dm"
-#include "code\modules\jobs\outfit.dm"
-#include "code\modules\jobs\whitelist.dm"
-#include "code\modules\jobs\departments\cargo.dm"
-#include "code\modules\jobs\departments\centcom.dm"
-#include "code\modules\jobs\departments\civillian.dm"
-#include "code\modules\jobs\departments\command.dm"
-#include "code\modules\jobs\departments\engineering.dm"
-#include "code\modules\jobs\departments\medical.dm"
-#include "code\modules\jobs\departments\misc.dm"
-#include "code\modules\jobs\departments\offduty.dm"
-#include "code\modules\jobs\departments\planetside.dm"
-#include "code\modules\jobs\departments\research.dm"
-#include "code\modules\jobs\departments\security.dm"
-#include "code\modules\jobs\departments\silicon.dm"
-#include "code\modules\jobs\departments\unlisted.dm"
-#include "code\modules\jobs\job_types\station.dm"
-#include "code\modules\jobs\job_types\station\admin\centcom_officer.dm"
-#include "code\modules\jobs\job_types\station\admin\emergency_responder.dm"
-#include "code\modules\jobs\job_types\station\civillian\assistant.dm"
-#include "code\modules\jobs\job_types\station\civillian\chaplain.dm"
-#include "code\modules\jobs\job_types\station\civillian\clown.dm"
-#include "code\modules\jobs\job_types\station\civillian\entertainer.dm"
-#include "code\modules\jobs\job_types\station\civillian\internals_affairs_agent.dm"
-#include "code\modules\jobs\job_types\station\civillian\librarian.dm"
-#include "code\modules\jobs\job_types\station\civillian\mime.dm"
-#include "code\modules\jobs\job_types\station\civillian\outsider.dm"
-#include "code\modules\jobs\job_types\station\civillian\pilot.dm"
-#include "code\modules\jobs\job_types\station\command\blueshield.dm"
-#include "code\modules\jobs\job_types\station\command\captain.dm"
-#include "code\modules\jobs\job_types\station\command\command_secretary.dm"
-#include "code\modules\jobs\job_types\station\command\head_of_personnel.dm"
-#include "code\modules\jobs\job_types\station\engineering\atmospherics_technician.dm"
-#include "code\modules\jobs\job_types\station\engineering\chief_engineer.dm"
-#include "code\modules\jobs\job_types\station\engineering\senior_engineer.dm"
-#include "code\modules\jobs\job_types\station\engineering\station_engineer.dm"
-#include "code\modules\jobs\job_types\station\exploration\explorer.dm"
-#include "code\modules\jobs\job_types\station\exploration\field_medic.dm"
-#include "code\modules\jobs\job_types\station\exploration\pathfinder.dm"
-#include "code\modules\jobs\job_types\station\medical\chemist.dm"
-#include "code\modules\jobs\job_types\station\medical\chief_medical_officer.dm"
-#include "code\modules\jobs\job_types\station\medical\geneticist.dm"
-#include "code\modules\jobs\job_types\station\medical\head_nurse.dm"
-#include "code\modules\jobs\job_types\station\medical\medical_doctor.dm"
-#include "code\modules\jobs\job_types\station\medical\paramedic.dm"
-#include "code\modules\jobs\job_types\station\medical\psychiatrist.dm"
-#include "code\modules\jobs\job_types\station\offduty\_offduty.dm"
-#include "code\modules\jobs\job_types\station\offduty\civillian.dm"
-#include "code\modules\jobs\job_types\station\offduty\command.dm"
-#include "code\modules\jobs\job_types\station\offduty\engineering.dm"
-#include "code\modules\jobs\job_types\station\offduty\exploration.dm"
-#include "code\modules\jobs\job_types\station\offduty\medical.dm"
-#include "code\modules\jobs\job_types\station\offduty\science.dm"
-#include "code\modules\jobs\job_types\station\offduty\security.dm"
-#include "code\modules\jobs\job_types\station\offduty\supply.dm"
-#include "code\modules\jobs\job_types\station\science\research_director.dm"
-#include "code\modules\jobs\job_types\station\science\roboticist.dm"
-#include "code\modules\jobs\job_types\station\science\scientist.dm"
-#include "code\modules\jobs\job_types\station\science\senior_researcher.dm"
-#include "code\modules\jobs\job_types\station\science\xenobiologist.dm"
-#include "code\modules\jobs\job_types\station\science\xenobotanist.dm"
-#include "code\modules\jobs\job_types\station\security\detective.dm"
-#include "code\modules\jobs\job_types\station\security\head_of_security.dm"
-#include "code\modules\jobs\job_types\station\security\security_officer.dm"
-#include "code\modules\jobs\job_types\station\security\warden.dm"
-#include "code\modules\jobs\job_types\station\service\bartender.dm"
-#include "code\modules\jobs\job_types\station\service\botanist.dm"
-#include "code\modules\jobs\job_types\station\service\chef.dm"
-#include "code\modules\jobs\job_types\station\service\janitor.dm"
-#include "code\modules\jobs\job_types\station\silicon\ai.dm"
-#include "code\modules\jobs\job_types\station\silicon\cyborg.dm"
-#include "code\modules\jobs\job_types\station\supply\cargo_technician.dm"
-#include "code\modules\jobs\job_types\station\supply\quartermaster.dm"
-#include "code\modules\jobs\job_types\station\supply\shaft_miner.dm"
+#include "code\modules\roles\jobs\access.dm"
+#include "code\modules\roles\jobs\alt_title.dm"
+#include "code\modules\roles\jobs\department.dm"
+#include "code\modules\roles\jobs\job.dm"
+#include "code\modules\roles\jobs\jobs.dm"
+#include "code\modules\roles\jobs\outfit.dm"
+#include "code\modules\roles\jobs\whitelist.dm"
+#include "code\modules\roles\jobs\departments\cargo.dm"
+#include "code\modules\roles\jobs\departments\centcom.dm"
+#include "code\modules\roles\jobs\departments\civillian.dm"
+#include "code\modules\roles\jobs\departments\command.dm"
+#include "code\modules\roles\jobs\departments\engineering.dm"
+#include "code\modules\roles\jobs\departments\medical.dm"
+#include "code\modules\roles\jobs\departments\misc.dm"
+#include "code\modules\roles\jobs\departments\offduty.dm"
+#include "code\modules\roles\jobs\departments\planetside.dm"
+#include "code\modules\roles\jobs\departments\research.dm"
+#include "code\modules\roles\jobs\departments\security.dm"
+#include "code\modules\roles\jobs\departments\silicon.dm"
+#include "code\modules\roles\jobs\departments\unlisted.dm"
+#include "code\modules\roles\jobs\job_types\station.dm"
+#include "code\modules\roles\jobs\job_types\station\admin\centcom_officer.dm"
+#include "code\modules\roles\jobs\job_types\station\admin\emergency_responder.dm"
+#include "code\modules\roles\jobs\job_types\station\civillian\assistant.dm"
+#include "code\modules\roles\jobs\job_types\station\civillian\chaplain.dm"
+#include "code\modules\roles\jobs\job_types\station\civillian\clown.dm"
+#include "code\modules\roles\jobs\job_types\station\civillian\entertainer.dm"
+#include "code\modules\roles\jobs\job_types\station\civillian\internals_affairs_agent.dm"
+#include "code\modules\roles\jobs\job_types\station\civillian\librarian.dm"
+#include "code\modules\roles\jobs\job_types\station\civillian\mime.dm"
+#include "code\modules\roles\jobs\job_types\station\civillian\outsider.dm"
+#include "code\modules\roles\jobs\job_types\station\civillian\pilot.dm"
+#include "code\modules\roles\jobs\job_types\station\command\blueshield.dm"
+#include "code\modules\roles\jobs\job_types\station\command\captain.dm"
+#include "code\modules\roles\jobs\job_types\station\command\command_secretary.dm"
+#include "code\modules\roles\jobs\job_types\station\command\head_of_personnel.dm"
+#include "code\modules\roles\jobs\job_types\station\engineering\atmospherics_technician.dm"
+#include "code\modules\roles\jobs\job_types\station\engineering\chief_engineer.dm"
+#include "code\modules\roles\jobs\job_types\station\engineering\senior_engineer.dm"
+#include "code\modules\roles\jobs\job_types\station\engineering\station_engineer.dm"
+#include "code\modules\roles\jobs\job_types\station\exploration\explorer.dm"
+#include "code\modules\roles\jobs\job_types\station\exploration\field_medic.dm"
+#include "code\modules\roles\jobs\job_types\station\exploration\pathfinder.dm"
+#include "code\modules\roles\jobs\job_types\station\medical\chemist.dm"
+#include "code\modules\roles\jobs\job_types\station\medical\chief_medical_officer.dm"
+#include "code\modules\roles\jobs\job_types\station\medical\geneticist.dm"
+#include "code\modules\roles\jobs\job_types\station\medical\head_nurse.dm"
+#include "code\modules\roles\jobs\job_types\station\medical\medical_doctor.dm"
+#include "code\modules\roles\jobs\job_types\station\medical\paramedic.dm"
+#include "code\modules\roles\jobs\job_types\station\medical\psychiatrist.dm"
+#include "code\modules\roles\jobs\job_types\station\offduty\_offduty.dm"
+#include "code\modules\roles\jobs\job_types\station\offduty\civillian.dm"
+#include "code\modules\roles\jobs\job_types\station\offduty\command.dm"
+#include "code\modules\roles\jobs\job_types\station\offduty\engineering.dm"
+#include "code\modules\roles\jobs\job_types\station\offduty\exploration.dm"
+#include "code\modules\roles\jobs\job_types\station\offduty\medical.dm"
+#include "code\modules\roles\jobs\job_types\station\offduty\science.dm"
+#include "code\modules\roles\jobs\job_types\station\offduty\security.dm"
+#include "code\modules\roles\jobs\job_types\station\offduty\supply.dm"
+#include "code\modules\roles\jobs\job_types\station\science\research_director.dm"
+#include "code\modules\roles\jobs\job_types\station\science\roboticist.dm"
+#include "code\modules\roles\jobs\job_types\station\science\scientist.dm"
+#include "code\modules\roles\jobs\job_types\station\science\senior_researcher.dm"
+#include "code\modules\roles\jobs\job_types\station\science\xenobiologist.dm"
+#include "code\modules\roles\jobs\job_types\station\science\xenobotanist.dm"
+#include "code\modules\roles\jobs\job_types\station\security\detective.dm"
+#include "code\modules\roles\jobs\job_types\station\security\head_of_security.dm"
+#include "code\modules\roles\jobs\job_types\station\security\security_officer.dm"
+#include "code\modules\roles\jobs\job_types\station\security\warden.dm"
+#include "code\modules\roles\jobs\job_types\station\service\bartender.dm"
+#include "code\modules\roles\jobs\job_types\station\service\botanist.dm"
+#include "code\modules\roles\jobs\job_types\station\service\chef.dm"
+#include "code\modules\roles\jobs\job_types\station\service\janitor.dm"
+#include "code\modules\roles\jobs\job_types\station\silicon\ai.dm"
+#include "code\modules\roles\jobs\job_types\station\silicon\cyborg.dm"
+#include "code\modules\roles\jobs\job_types\station\supply\cargo_technician.dm"
+#include "code\modules\roles\jobs\job_types\station\supply\quartermaster.dm"
+#include "code\modules\roles\jobs\job_types\station\supply\shaft_miner.dm"
#include "code\modules\keybindings\bindings_atom.dm"
#include "code\modules\keybindings\bindings_client.dm"
#include "code\modules\keybindings\focus.dm"
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 7f83266b782..845b2960a06 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -129,7 +129,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
#define ANNOUNCER_NAME "Facility PA"
-#define DEFAULT_JOB_TYPE /datum/role/job/station/assistant
+#define DEFAULT_JOB_TYPE /datum/prototype/role/job/station/assistant
//Assistant/Visitor/Whatever
#define USELESS_JOB "Visitor"
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index c8389b64385..58784fb09f8 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -38,7 +38,7 @@ var/datum/category_collection/underwear/global_underwear = new()
//!Backpacks - The load order here is important to maintain. Don't go swapping these around.
var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt", "Messenger Bag", "RIG", "Duffle Bag")
var/global/list/pdachoicelist = list("Default", "Slim", "Old", "Rugged","Minimalist", "Holographic", "Wrist-Bound")
-var/global/list/exclude_jobs = list(/datum/role/job/station/ai,/datum/role/job/station/cyborg)
+var/global/list/exclude_jobs = list(/datum/prototype/role/job/station/ai,/datum/prototype/role/job/station/cyborg)
//* Visual nets
GLOBAL_LIST_EMPTY(visual_nets)
diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm
index 0e01f3b00c8..eccd6076553 100644
--- a/code/__HELPERS/names.dm
+++ b/code/__HELPERS/names.dm
@@ -199,7 +199,7 @@ var/syndicate_code_response//Code response for traitors.
code_phrase += " "
code_phrase += pick(GLOB.last_names)
if(2)
- code_phrase += pick(SSjob.all_job_titles())//Returns a job.
+ code_phrase += pick(RSroles.legacy_all_job_titles())//Returns a job.
safety -= 1
if(2)
switch(rand(1,2))//Places or things.
diff --git a/code/__HELPERS/sorts/comparators.dm b/code/__HELPERS/sorts/comparators.dm
index 5049291233e..2ddba2e3594 100644
--- a/code/__HELPERS/sorts/comparators.dm
+++ b/code/__HELPERS/sorts/comparators.dm
@@ -113,7 +113,7 @@ GLOBAL_VAR_INIT(cmp_field, "name")
/**
* Sorts jobs by department, and then by flag within department.
*/
-/proc/cmp_job_datums(datum/role/job/a, datum/role/job/b)
+/proc/cmp_job_datums(datum/prototype/role/job/a, datum/prototype/role/job/b)
. = 0
if( LAZYLEN(a.departments) && LAZYLEN(b.departments) )
// Makes a list that contains only departments that were in both.
diff --git a/code/___compile_options.dm b/code/___compile_options.dm
index 23bd1793dd0..f072c633d66 100644
--- a/code/___compile_options.dm
+++ b/code/___compile_options.dm
@@ -127,6 +127,8 @@
#define REFERENCE_TRACKING_DEBUG
#define FIND_REF_NO_CHECK_TICK
#define GC_FAILURE_HARD_LOOKUP
+ // Test init.
+ #define CF_ATOM_TRACE_INIT_EARLY_QDEL
//Ensures all early assets can actually load early
#define DO_NOT_DEFER_ASSETS
//Test at full capacity, the extra cost doesn't matter
diff --git a/code/controllers/repository/roles.dm b/code/controllers/repository/roles.dm
new file mode 100644
index 00000000000..2cd2b85dde8
--- /dev/null
+++ b/code/controllers/repository/roles.dm
@@ -0,0 +1,90 @@
+//* This file is explicitly licensed under the MIT license. *//
+//* Copyright (c) 2025 Citadel Station Developers *//
+
+REPOSITORY_DEF(roles)
+ name = "Repository - Roles"
+ expected_type = /datum/prototype/role
+
+ /**
+ * Jobs by title.
+ * * Only populated for /role/job for legacy lookups.
+ */
+ var/list/legacy_job_title_lookup = list()
+
+/datum/controller/repository/roles/load(datum/prototype/role/instance)
+ . = ..()
+ if(!.)
+ return
+ if(istype(instance, /datum/prototype/role/job))
+ var/datum/prototype/role/job/casted_job = instance
+ if(legacy_job_title_lookup[casted_job.title])
+ stack_trace("collision on '[casted_job.title]' job title between [casted_job.type] and [legacy_job_title_lookup[casted_job.title]:title]")
+ else
+ legacy_job_title_lookup[casted_job.title] = casted_job
+
+
+/datum/controller/repository/roles/unload(datum/prototype/role/instance)
+ . = ..()
+ if(!.)
+ return
+ if(istype(instance, /datum/prototype/role/job))
+ var/datum/prototype/role/job/casted_job = instance
+ if(legacy_job_title_lookup[casted_job.title] == casted_job)
+ legacy_job_title_lookup -= casted_job.title
+
+/**
+ * Only returns /datum/prototype/role/job
+ */
+/datum/controller/repository/roles/proc/legacy_job_by_title(title) as /datum/prototype/role/job
+ return legacy_job_title_lookup[title]
+
+/**
+ * Only returns /datum/prototype/role/job
+ */
+/datum/controller/repository/roles/proc/legacy_job_by_id(id) as /datum/prototype/role/job
+ return fetch_local_or_throw(id)
+
+/**
+ * Only returns /datum/prototype/role/job
+ */
+/datum/controller/repository/roles/proc/legacy_job_by_type(type) as /datum/prototype/role/job
+ return fetch_local_or_throw(type)
+
+/**
+ * Only returns /datum/prototype/role/job
+ */
+/datum/controller/repository/roles/proc/legacy_all_job_ids(filter_faction) as /list
+ . = list()
+ for(var/datum/prototype/role/job/r as anything in fetch_subtypes_immutable(/datum/prototype/role/job))
+ . += r.id
+
+/**
+ * Only returns /datum/prototype/role/job
+ */
+/datum/controller/repository/roles/proc/legacy_all_job_types(filter_faction) as /list
+ . = list()
+ for(var/datum/prototype/role/job/r as anything in fetch_subtypes_immutable(/datum/prototype/role/job))
+ . += r.type
+
+/**
+ * Only returns /datum/prototype/role/job
+ */
+/datum/controller/repository/roles/proc/legacy_all_job_titles(filter_faction) as /list
+ . = list()
+ for(var/datum/prototype/role/job/r as anything in fetch_subtypes_immutable(/datum/prototype/role/job))
+ . += r.title
+
+/**
+ * Only returns /datum/prototype/role/job
+ */
+/datum/controller/repository/roles/proc/legacy_all_job_datums(filter_faction) as /list
+ . = list()
+ for(var/datum/prototype/role/job/r as anything in fetch_subtypes_immutable(/datum/prototype/role/job))
+ . += r
+
+/**
+ * Only returns /datum/prototype/role/job
+ */
+/datum/controller/repository/roles/proc/legacy_all_sorted_job_datums(filter_faction) as /list
+ . = legacy_all_job_datums(filter_faction)
+ tim_sort(., /proc/cmp_job_datums)
diff --git a/code/controllers/subsystem/job/_job.dm b/code/controllers/subsystem/job/_job.dm
index dc63fb444b0..ea10b1237d4 100644
--- a/code/controllers/subsystem/job/_job.dm
+++ b/code/controllers/subsystem/job/_job.dm
@@ -4,14 +4,6 @@ SUBSYSTEM_DEF(job)
init_stage = INIT_STAGE_EARLY
subsystem_flags = SS_NO_FIRE
- /// List of all jobs
- var/list/occupations
- /// Dict of all jobs, keys are titles
- var/list/datum/role/job/name_occupations
- /// Dict of all jobs, keys are types
- var/list/type_occupations
- /// jobs by id
- var/list/job_lookup
/// job preferences ui cache - cache[faction string][department name] = list(job ids)
var/list/job_pref_ui_cache
/// jobs per column
@@ -25,34 +17,25 @@ SUBSYSTEM_DEF(job)
init_access()
if(!length(department_datums))
setup_departments()
- if(!length(occupations))
- setup_occupations()
reconstruct_job_ui_caches()
return SS_INIT_SUCCESS
/datum/controller/subsystem/job/Recover()
init_access()
- occupations = SSjob.occupations
- name_occupations = SSjob.name_occupations
- job_lookup = SSjob.job_lookup
- type_occupations = SSjob.type_occupations
-
reconstruct_spawnpoints()
reconstruct_job_ui_caches()
-
return ..()
/datum/controller/subsystem/job/proc/reconstruct_job_ui_caches()
// todo: this is shit but it works
job_pref_ui_cache = list()
- for(var/id in job_lookup)
- var/datum/role/job/J = job_lookup[id]
+ for(var/datum/prototype/role/job/J as anything in RSroles.legacy_all_sorted_job_datums())
if(!(J.join_types & JOB_ROUNDSTART))
continue
var/faction = J.faction
LAZYINITLIST(job_pref_ui_cache[faction])
var/department = LAZYACCESS(J.departments, 1) || "Misc"
- LAZYADD(job_pref_ui_cache[faction][department], id)
+ LAZYADD(job_pref_ui_cache[faction][department], J.id)
// todo: why
for(var/fname in job_pref_ui_cache)
var/list/faction = job_pref_ui_cache[fname]
@@ -65,49 +48,7 @@ SUBSYSTEM_DEF(job)
for(var/depname in asinine_sort)
faction[depname] = asinine_sort[depname]
-/datum/controller/subsystem/job/proc/setup_occupations()
- occupations = list()
- job_lookup = list()
- name_occupations = list()
- type_occupations = list()
- var/list/all_jobs = subtypesof(/datum/role/job)
- if(!all_jobs.len)
- to_chat(world, SPAN_WARNING( "Error setting up jobs, no job datums found"))
- return FALSE
-
- for(var/J in all_jobs)
- var/datum/role/job/job = J
- if(initial(job.abstract_type) == J)
- continue
- job = new J
- occupations += job
- if(!job.id)
- stack_trace("no job id for [J]")
- continue
- if(!job.title)
- stack_trace("no job title for [J]")
- continue
- if(job_lookup[job.id])
- stack_trace("job id collision on [job.id] for [J]")
- continue
- if(name_occupations[job.title])
- stack_trace("job title collision on [job.title] for [J]")
- continue
- name_occupations[job.title] = job
- type_occupations[J] = job
- job_lookup[job.id] = job
- if(LAZYLEN(job.departments))
- add_to_departments(job)
-
- tim_sort(occupations, GLOBAL_PROC_REF(cmp_job_datums))
- for(var/D in department_datums)
- var/datum/department/dept = department_datums[D]
- tim_sort(dept.jobs, GLOBAL_PROC_REF(cmp_job_datums), TRUE)
- tim_sort(dept.primary_jobs, GLOBAL_PROC_REF(cmp_job_datums), TRUE)
-
- return TRUE
-
-/datum/controller/subsystem/job/proc/add_to_departments(datum/role/job/J)
+/datum/controller/subsystem/job/proc/add_to_departments(datum/prototype/role/job/J)
// Adds to the regular job lists in the departments, which allow multiple departments for a job.
for(var/D in J.departments)
var/datum/department/dept = LAZYACCESS(department_datums, D)
@@ -133,17 +74,21 @@ SUBSYSTEM_DEF(job)
tim_sort(department_datums, GLOBAL_PROC_REF(cmp_department_datums), TRUE)
+ for(var/datum/prototype/role/job/job as anything in RSroles.legacy_all_job_datums())
+ if(LAZYLEN(job.departments))
+ add_to_departments(job)
+
+ for(var/D in department_datums)
+ var/datum/department/dept = department_datums[D]
+ tim_sort(dept.jobs, GLOBAL_PROC_REF(cmp_job_datums), TRUE)
+ tim_sort(dept.primary_jobs, GLOBAL_PROC_REF(cmp_job_datums), TRUE)
+
/datum/controller/subsystem/job/proc/get_all_department_datums()
var/list/dept_datums = list()
for(var/D in department_datums)
dept_datums += department_datums[D]
return dept_datums
-/datum/controller/subsystem/job/proc/get_job(rank)
- if(!occupations.len)
- setup_occupations()
- return name_occupations[rank]
-
// Determines if a job title is inside of a specific department.
// Useful to replace the old `if(job_title in command_positions)` code.
/datum/controller/subsystem/job/proc/is_job_in_department(rank, target_department_name)
@@ -166,12 +111,12 @@ SUBSYSTEM_DEF(job)
// Returns a reference to the primary department datum that a job is in.
// Can receive job datum refs, typepaths, or job title strings.
-/datum/controller/subsystem/job/proc/get_primary_department_of_job(datum/role/job/J)
- if(!istype(J, /datum/role/job))
+/datum/controller/subsystem/job/proc/get_primary_department_of_job(datum/prototype/role/job/J)
+ if(!istype(J, /datum/prototype/role/job))
if(ispath(J))
- J = job_by_type(J)
+ J = RSroles.legacy_job_by_type(J)
else if(istext(J))
- J = get_job(J)
+ J = RSroles.legacy_job_by_title(J)
if(!istype(J))
job_debug_message("Was asked to get department for job '[J]', but input could not be resolved into a job datum.")
@@ -188,12 +133,6 @@ SUBSYSTEM_DEF(job)
return department_datums[primary_department]
-// Someday it might be good to port code/game/jobs/job_controller.dm to here and clean it up.
-
-
-
-
-
/datum/controller/subsystem/job/proc/job_debug_message(message)
if(debug_messages)
log_debug(SPAN_DEBUG("JOB DEBUG: [message]"))
diff --git a/code/controllers/subsystem/job/_legacy_job_stuff.dm b/code/controllers/subsystem/job/_legacy_job_stuff.dm
index 4b3dd334331..8747ac23ccf 100644
--- a/code/controllers/subsystem/job/_legacy_job_stuff.dm
+++ b/code/controllers/subsystem/job/_legacy_job_stuff.dm
@@ -11,12 +11,12 @@
return TRUE
/datum/controller/subsystem/job/proc/GetPlayerAltTitle(mob/new_player/player, rank)
- return player.client.prefs.get_job_alt_title_name(get_job(rank))
+ return player.client.prefs.get_job_alt_title_name(RSroles.legacy_job_by_title(rank))
/datum/controller/subsystem/job/proc/AssignRole(mob/new_player/player, rank, latejoin = 0)
job_debug("Running AR, Player: [player], Rank: [rank], LJ: [latejoin]")
if(player && player.mind && rank)
- var/datum/role/job/job = get_job(rank)
+ var/datum/prototype/role/job/job = RSroles.legacy_job_by_title(rank)
var/reasons = job.check_client_availability_one(player.client)
if(reasons != ROLE_AVAILABLE)
job_debug("AR failed: player [player], rank [rank], latejoin [latejoin], failed for [reasons]")
@@ -34,13 +34,13 @@
/// Making additional slot on the fly.
/datum/controller/subsystem/job/proc/FreeRole(rank)
- var/datum/role/job/job = get_job(rank)
+ var/datum/prototype/role/job/job = RSroles.legacy_job_by_title(rank)
if(job && job.total_positions != -1)
job.total_positions++
return 1
return 0
-/datum/controller/subsystem/job/proc/FindOccupationCandidates(datum/role/job/job, level)
+/datum/controller/subsystem/job/proc/FindOccupationCandidates(datum/prototype/role/job/job, level)
job_debug("Running FOC, Job: [job], Level: [level]")
var/list/candidates = list()
for(var/mob/new_player/player in divide_unassigned)
@@ -56,7 +56,7 @@
/datum/controller/subsystem/job/proc/GiveRandomJob(mob/new_player/player)
job_debug("GRJ Giving random job, Player: [player]")
- for(var/datum/role/job/job in shuffle(occupations))
+ for(var/datum/prototype/role/job/job in shuffle(RSroles.legacy_all_job_datums()))
var/reasons = job.check_client_availability_one(player.client)
if(reasons != ROLE_AVAILABLE)
job_debug("GRJ failed for [reasons] on [job.id]")
@@ -75,7 +75,7 @@
/datum/controller/subsystem/job/proc/FillHeadPosition()
for(var/level in JOB_PRIORITY_HIGH to JOB_PRIORITY_LOW step -1)
for(var/command_position in SSjob.get_job_titles_in_department(DEPARTMENT_COMMAND))
- var/datum/role/job/job = get_job(command_position)
+ var/datum/prototype/role/job/job = RSroles.legacy_job_by_title(command_position)
if(!job)
continue
var/list/candidates = FindOccupationCandidates(job, level)
@@ -125,7 +125,7 @@
*/
/datum/controller/subsystem/job/proc/CheckHeadPositions(level)
for(var/command_position in SSjob.get_job_titles_in_department(DEPARTMENT_COMMAND))
- var/datum/role/job/job = get_job(command_position)
+ var/datum/prototype/role/job/job = RSroles.legacy_job_by_title(command_position)
if(!job || (job.current_positions >= job.spawn_positions))
continue
var/list/candidates = FindOccupationCandidates(job, level)
@@ -149,7 +149,7 @@
//Holder for Triumvirate is stored in the SSticker, this just processes it
if(SSticker && SSticker.triai)
- for(var/datum/role/job/A in occupations)
+ for(var/datum/prototype/role/job/A in RSroles.legacy_all_job_datums())
if(A.title == "AI")
A.spawn_positions = 3
break
@@ -166,7 +166,7 @@
//People who wants to be assistants, sure, go on.
job_debug("DO, Running Assistant Check 1")
- var/datum/role/job/assist = new DEFAULT_JOB_TYPE ()
+ var/datum/prototype/role/job/assist = new DEFAULT_JOB_TYPE ()
var/list/assistant_candidates = FindOccupationCandidates(assist, JOB_PRIORITY_HIGH)
job_debug("AC1, Candidates: [assistant_candidates.len]")
for(var/mob/new_player/player in assistant_candidates)
@@ -189,7 +189,7 @@
// Hopefully this will add more randomness and fairness to job giving.
// Loop through all levels from high to low
- var/list/shuffledoccupations = shuffle(occupations)
+ var/list/shuffledoccupations = shuffle(RSroles.legacy_all_job_datums())
// var/list/disabled_jobs = SSticker.mode.disabled_jobs // So we can use .Find down below without a colon.
for(var/level in JOB_PRIORITY_HIGH to JOB_PRIORITY_LOW step -1)
//Check the head jobs first each level
@@ -199,7 +199,7 @@
for(var/mob/new_player/player in divide_unassigned)
// Loop through all jobs
- for(var/datum/role/job/job in shuffledoccupations) // SHUFFLE ME BABY
+ for(var/datum/prototype/role/job/job in shuffledoccupations) // SHUFFLE ME BABY
if(job.title in SSticker.mode.disabled_jobs)
continue
var/reasons = job.check_client_availability_one(player.client)
@@ -245,7 +245,7 @@
if(!H)
return null
- var/datum/role/job/job = get_job(rank)
+ var/datum/prototype/role/job/job = RSroles.legacy_job_by_title(rank)
if(!joined_late)
var/obj/landmark/spawnpoint/S = SSjob.get_roundstart_spawnpoint(H, H.client, job.type, job.faction)
@@ -419,7 +419,7 @@
continue
if(name && value)
- var/datum/role/job/J = get_job(name)
+ var/datum/prototype/role/job/J = RSroles.legacy_job_by_title(name)
if(!J) continue
J.total_positions = text2num(value)
J.spawn_positions = text2num(value)
@@ -430,7 +430,7 @@
/datum/controller/subsystem/job/proc/HandleFeedbackGathering()
- for(var/datum/role/job/job in occupations)
+ for(var/datum/prototype/role/job/job in RSroles.legacy_all_job_datums())
var/tmp_str = "|[job.title]|"
var/level1 = 0 //high
@@ -465,7 +465,7 @@
var/fail_deadly = FALSE
- var/datum/role/job/J = SSjob.get_job(rank)
+ var/datum/prototype/role/job/J = RSroles.legacy_job_by_title(rank)
fail_deadly = J?.offmap_spawn
var/preferred_method
var/datum/spawnpoint/spawnpos
diff --git a/code/controllers/subsystem/job/job_manager.dm b/code/controllers/subsystem/job/job_manager.dm
deleted file mode 100644
index d3e1972f884..00000000000
--- a/code/controllers/subsystem/job/job_manager.dm
+++ /dev/null
@@ -1,73 +0,0 @@
-//* This file is explicitly licensed under the MIT license. *//
-//* Copyright (c) 2023 Citadel Station developers. *//
-
-// todo: refactor _job.dm
-/datum/controller/subsystem/job
-
-//? Jobs
-
-/datum/controller/subsystem/job/proc/job_by_id(id)
- RETURN_TYPE(/datum/role/job)
- return job_lookup[id]
-
-/datum/controller/subsystem/job/proc/job_by_type(path)
- RETURN_TYPE(/datum/role/job)
- return type_occupations[path]
-
-// todo: this should not be used most of the time, id/type is better
-/datum/controller/subsystem/job/proc/job_by_title(title)
- RETURN_TYPE(/datum/role/job)
- return name_occupations[title]
-
-/datum/controller/subsystem/job/proc/all_job_ids(faction)
- RETURN_TYPE(/list)
- . = list()
- if(faction)
- for(var/datum/role/job/J as anything in occupations)
- if(J.faction != faction)
- continue
- . += J.id
- else
- for(var/id as anything in job_lookup)
- . += id
-
-/datum/controller/subsystem/job/proc/all_job_types(faction)
- RETURN_TYPE(/list)
- . = list()
- if(faction)
- for(var/datum/role/job/J as anything in occupations)
- if(J.faction != faction)
- continue
- . += J.type
- else
- for(var/path as anything in type_occupations)
- . += path
-
-// todo: avoid doing this where possible, id/type is better
-/datum/controller/subsystem/job/proc/all_job_titles(faction)
- RETURN_TYPE(/list)
- . = list()
- if(faction)
- for(var/datum/role/job/J as anything in occupations)
- if(J.faction != faction)
- continue
- . += J.title
- else
- for(var/title as anything in name_occupations)
- . += title
-
-/datum/controller/subsystem/job/proc/all_jobs(faction)
- RETURN_TYPE(/list)
- . = list()
- if(faction)
- for(var/datum/role/job/J as anything in occupations)
- if(J.faction != faction)
- continue
- . += J
- else
- for(var/datum/role/job/J as anything in occupations)
- . += J
-
-//? Departments
-
-// todo: dept stuff
diff --git a/code/controllers/subsystem/job/joining.dm b/code/controllers/subsystem/job/joining.dm
index 9cf7c50a7cf..789b3895a5e 100644
--- a/code/controllers/subsystem/job/joining.dm
+++ b/code/controllers/subsystem/job/joining.dm
@@ -1,5 +1,5 @@
/*
-/datum/controller/subsystem/job/proc/ProcessRoundstartPlayer(mob/M, datum/role/job/J, loadout = TRUE, client/C)
+/datum/controller/subsystem/job/proc/ProcessRoundstartPlayer(mob/M, datum/prototype/role/job/J, loadout = TRUE, client/C)
// autodetect
if(!C)
C = M.client
@@ -16,7 +16,7 @@
SendToRoundstart(M, C, J)
PostJoin(M, J, C, FALSE)
-/datum/controller/subsystem/job/proc/ProcessLatejoinPlayer(mob/M, datum/role/job/J, loadout = TRUE, client/C)
+/datum/controller/subsystem/job/proc/ProcessLatejoinPlayer(mob/M, datum/prototype/role/job/J, loadout = TRUE, client/C)
// autodetect
if(!C)
C = M.client
@@ -33,7 +33,7 @@
SendToLatejoin(M, C, job = J)
PostJoin(M, J, C, TRUE)
-/datum/controller/subsystem/job/proc/GreetPlayer(mob/M, datum/role/job/J, latejoin, client/C)
+/datum/controller/subsystem/job/proc/GreetPlayer(mob/M, datum/prototype/role/job/J, latejoin, client/C)
var/client/output = C || M.client
if(!J)
return
@@ -52,7 +52,7 @@
to_chat(output, "Your account ID is [wageslave.account_id].")
M.add_memory("Your account ID is [wageslave.account_id].")
-/datum/controller/subsystem/job/proc/EquipPlayer(mob/M, datum/role/job/J, loadout = TRUE, datum/preferences/prefs, announce, latejoin, client/C)
+/datum/controller/subsystem/job/proc/EquipPlayer(mob/M, datum/prototype/role/job/J, loadout = TRUE, datum/preferences/prefs, announce, latejoin, client/C)
if(!istype(J))
J = GetJobAuto(J)
ASSERT(istype(J))
@@ -73,7 +73,7 @@
HandleLoadoutLeftovers(M, leftovers, null, C)
-/datum/controller/subsystem/job/proc/PostJoin(mob/M, datum/role/job/J, client/C, latejoin)
+/datum/controller/subsystem/job/proc/PostJoin(mob/M, datum/prototype/role/job/J, client/C, latejoin)
// job handling
if(J)
SSpersistence.antag_rep_change[M.client.ckey] += J.GetAntagRep()
@@ -110,7 +110,7 @@
if(latejoin)
AnnounceJoin(M, J, C)
-/datum/controller/subsystem/job/proc/AnnounceJoin(mob/M, datum/role/job/J, client/C)
+/datum/controller/subsystem/job/proc/AnnounceJoin(mob/M, datum/prototype/role/job/J, client/C)
if(istype(get_area(M), /area/shuttle/arrival) && SSshuttle.arrivals)
SSshuttle.arrivals.QueueAnnounce(M, J.title)
else
@@ -123,7 +123,7 @@
* - latejoin - latejoining mob?
* - force - bypass checks
*/
-/datum/controller/subsystem/job/proc/Assign(datum/mind/M, datum/role/job/J, latejoin = FALSE, force = FALSE)
+/datum/controller/subsystem/job/proc/Assign(datum/mind/M, datum/prototype/role/job/J, latejoin = FALSE, force = FALSE)
if(ismob(M))
var/mob/_M = M
M = _M.mind
@@ -145,7 +145,7 @@
J.current_positions++
return TRUE
-/datum/controller/subsystem/job/proc/CanAssign(M, datum/role/job/J, latejoin)
+/datum/controller/subsystem/job/proc/CanAssign(M, datum/prototype/role/job/J, latejoin)
var/mob/checking = ismob(M) && M
if(!checking)
if(istype(M, /datum/mind))
@@ -175,7 +175,7 @@
*/
/datum/controller/subsystem/job/proc/SendToLatejoin(mob/M, client/C = M.client, faction, job, method, override)
if(!override && M.mind?.assigned_role)
- var/datum/role/job/J = SSjob.GetJobName(M.mind.assigned_role)
+ var/datum/prototype/role/job/J = SSjob.GetJobName(M.mind.assigned_role)
if(J)
faction = J.faction
job = J.GetID()
@@ -193,7 +193,7 @@
subsystem_log(error_message)
CRASH(error_message) // this is serious.
-/datum/controller/subsystem/job/proc/SendToRoundstart(mob/M, client/C, datum/role/job/J)
+/datum/controller/subsystem/job/proc/SendToRoundstart(mob/M, client/C, datum/prototype/role/job/J)
var/atom/movable/landmark/spawnpoint/S = GetRoundstartSpawnpoint(M, C, J.GetID(), J.faction)
if(!S)
stack_trace("Couldn't find a roundstart spawnpoint for [M] ([C]) - [J.type] ([J.faction]).")
@@ -206,7 +206,7 @@
/datum/controller/subsystem/job/proc/handle_auto_deadmin_roles(client/C, rank)
if(!C?.holder)
return TRUE
- var/datum/role/job/job = GetJobAuto(rank)
+ var/datum/prototype/role/job/job = GetJobAuto(rank)
if(!job)
return
if((job.auto_deadmin_role_flags & DEADMIN_POSITION_HEAD) && (CONFIG_GET(flag/auto_deadmin_heads) || (C.prefs?.deadmin & DEADMIN_POSITION_HEAD)))
diff --git a/code/controllers/subsystem/job/roundstart.dm b/code/controllers/subsystem/job/roundstart.dm
index f813b903a3b..5f386714fec 100644
--- a/code/controllers/subsystem/job/roundstart.dm
+++ b/code/controllers/subsystem/job/roundstart.dm
@@ -12,7 +12,8 @@
if(NP?.mind)
NP.mind.assigned_role = null
NP.mind.special_role = null
- setup_occupations()
+ for(var/datum/prototype/role/job/job as anything in RSroles.legacy_all_job_datums())
+ job.current_positions = 0
/datum/controller/subsystem/job/proc/gather_unassigned()
//Get the players who are ready
@@ -44,7 +45,7 @@
// i'm going to figure out if i can speed it up BEFORE rewriting everything.
/*
-/datum/controller/subsystem/job/proc/FindOccupationCandidates(datum/role/job/job, level, flag)
+/datum/controller/subsystem/job/proc/FindOccupationCandidates(datum/prototype/role/job/job, level, flag)
JobDebug("Running FOC, Job: [job], Level: [level], Flag: [flag]")
var/list/candidates = list()
for(var/mob/new_player/player in unassigned)
@@ -74,7 +75,7 @@
/datum/controller/subsystem/job/proc/GiveRandomJob(mob/new_player/player)
JobDebug("GRJ Giving random job, Player: [player]")
. = FALSE
- for(var/datum/role/job/job in shuffle(GetAllJobs()))
+ for(var/datum/prototype/role/job/job in shuffle(GetAllJobs()))
if(!job)
continue
@@ -127,7 +128,7 @@
//This is basically to ensure that there's atleast a few heads in the round
/datum/controller/subsystem/job/proc/FillHeadPosition()
for(var/level in level_order)
- for(var/datum/role/job/job as anything in GetDepartmentJobDatums(/datum/department/command))
+ for(var/datum/prototype/role/job/job as anything in GetDepartmentJobDatums(/datum/department/command))
if(!job)
continue
if((job.current_positions >= job.total_positions) && job.total_positions != -1)
@@ -143,7 +144,7 @@
//This proc is called at the start of the level loop of DivideOccupations() and will cause head jobs to be checked before any other jobs of the same level
//This is also to ensure we get as many heads as possible
/datum/controller/subsystem/job/proc/CheckHeadPositions(level)
- for(var/datum/role/job/job as anything in GetDepartmentJobDatums(/datum/department/command))
+ for(var/datum/prototype/role/job/job as anything in GetDepartmentJobDatums(/datum/department/command))
if(!job)
continue
if((job.current_positions >= job.total_positions) && job.total_positions != -1)
@@ -156,7 +157,7 @@
/datum/controller/subsystem/job/proc/FillAIPosition()
var/ai_selected = 0
- var/datum/role/job/job = GetJobType(/datum/role/job/ai)
+ var/datum/prototype/role/job/job = GetJobType(/datum/prototype/role/job/ai)
if(!job)
return 0
for(var/i = job.total_positions, i > 0, i--)
@@ -182,7 +183,7 @@
//Holder for Triumvirate is stored in the SSticker, this just processes it
if(SSticker.triai)
- for(var/datum/role/job/ai/A in GetAllJobs())
+ for(var/datum/prototype/role/job/ai/A in GetAllJobs())
A.roundstart_positions = 3
var/left = 2
for(var/atom/movable/landmark/spawnpoint/job/ai/secondary/S in GetAllSpawnpoints())
@@ -220,7 +221,7 @@
//People who wants to be the overflow role, sure, go on.
JobDebug("DO, Running Overflow Check 1")
- var/datum/role/job/overflow = GetJobName(SSjob.overflow_role)
+ var/datum/prototype/role/job/overflow = GetJobName(SSjob.overflow_role)
var/list/overflow_candidates = FindOccupationCandidates(overflow, JP_LOW)
JobDebug("AC1, Candidates: [overflow_candidates?.len]")
for(var/mob/new_player/player in overflow_candidates)
@@ -259,7 +260,7 @@
RejectPlayer(player)
// Loop through all jobs
- for(var/datum/role/job/job in shuffledoccupations) // SHUFFLE ME BABY
+ for(var/datum/prototype/role/job/job in shuffledoccupations) // SHUFFLE ME BABY
if(!job)
continue
@@ -318,7 +319,7 @@
for(var/required_group in required_jobs)
var/group_ok = TRUE
for(var/rank in required_group)
- var/datum/role/job/J = GetJobName(rank)
+ var/datum/prototype/role/job/J = GetJobName(rank)
if(!J)
SSticker.mode.setup_error = "Invalid job [rank] in gamemode required jobs."
return FALSE
@@ -355,7 +356,7 @@
/datum/controller/subsystem/job/proc/setup_officer_positions()
- var/datum/role/job/J = SSjob.GetJobType(/datum/role/job/officer)
+ var/datum/prototype/role/job/J = SSjob.GetJobType(/datum/prototype/role/job/officer)
if(!J)
CRASH("setup_officer_positions(): Security officer job is missing")
diff --git a/code/controllers/subsystem/playtime.dm b/code/controllers/subsystem/playtime.dm
index d72fff1d77f..27fb7727e16 100644
--- a/code/controllers/subsystem/playtime.dm
+++ b/code/controllers/subsystem/playtime.dm
@@ -63,7 +63,7 @@ SUBSYSTEM_DEF(playtime)
else
. = list(PLAYER_PLAYTIME_LIVING)
var/best_effort_attempt_at_resolving_legacy_name_based_roles = M.mind?.assigned_role
- var/datum/role/job/J = SSjob.job_by_title(best_effort_attempt_at_resolving_legacy_name_based_roles)
+ var/datum/prototype/role/job/J = RSroles.legacy_job_by_title(best_effort_attempt_at_resolving_legacy_name_based_roles)
if(J)
. += PLAYER_PLAYTIME_ROLE(J.id)
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index 4a31cfc29ad..15a37feef33 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -102,7 +102,7 @@
break
isactive[name] = active ? "Active" : "Inactive"
- var/datum/role/job/J = SSjob.get_job(real_rank)
+ var/datum/prototype/role/job/J = RSroles.legacy_job_by_title(real_rank)
if(J?.offmap_spawn)
off[name] = rank
@@ -310,7 +310,7 @@ GLOBAL_LIST_EMPTY(PDA_Manifest)
var/list/all_jobs = get_job_datums()
- for(var/datum/role/job/J in all_jobs)
+ for(var/datum/prototype/role/job/J in all_jobs)
if(J.title == rank) //If we have a rank, just default to using that.
real_title = rank
break
@@ -331,7 +331,7 @@ GLOBAL_LIST_EMPTY(PDA_Manifest)
if(H.mind && !player_is_antag(H.mind, only_offstation_roles = 1))
var/assignment = GetAssignment(H)
var/hidden
- var/datum/role/job/J = SSjob.get_job(H.mind.assigned_role)
+ var/datum/prototype/role/job/J = RSroles.legacy_job_by_title(H.mind.assigned_role)
hidden = J?.offmap_spawn
/* Note: Due to cached_character_icon, a number of emergent properties occur due to the initialization
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 3dbeb041241..0f0c1df04bf 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -62,12 +62,12 @@
// todo: id, not title
var/assigned_role
- // todo: id, not title; also unify /datum/role/(job | antagonist | ghostrole)?
+ // todo: id, not title; also unify /datum/prototype/role/(job | antagonist | ghostrole)?
var/special_role
var/role_alt_title
- var/datum/role/job/assigned_job
+ var/datum/prototype/role/job/assigned_job
var/list/datum/objective/objectives = list()
var/list/datum/objective/special_verbs = list()
@@ -263,7 +263,7 @@
if(antag) antag.place_mob(src.current)
else if (href_list["role_edit"])
- var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in SSjob.all_job_titles()
+ var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in RSroles.legacy_all_job_titles()
if (!new_role) return
assigned_role = new_role
diff --git a/code/datums/prototype.dm b/code/datums/prototype.dm
index c831af87c80..2506947f599 100644
--- a/code/datums/prototype.dm
+++ b/code/datums/prototype.dm
@@ -61,6 +61,14 @@
if(anonymous && isnull(id))
id = generate_anonymous_uid()
+/**
+ * Override this to false if your type has non-cache temporaries.
+ * * Using this is usually a bad idea but sometimes it's better to keep something loaded
+ * than to fuck around with '/datum/role_round_context' or something.
+ */
+/datum/prototype/proc/can_be_unloaded()
+ return TRUE
+
/datum/prototype/proc/generate_anonymous_uid()
// unique always, even across rounds
// todo: use SSpersistence persistence ID or something; maybe persistence ID should just be a global thing on the databse?
diff --git a/code/game/landmarks/spawnpoint/_spawnpoint.dm b/code/game/landmarks/spawnpoint/_spawnpoint.dm
index 595a3a830d1..f00c7d6d72e 100644
--- a/code/game/landmarks/spawnpoint/_spawnpoint.dm
+++ b/code/game/landmarks/spawnpoint/_spawnpoint.dm
@@ -136,7 +136,7 @@
* name - spawnee's name
* job_name - job's name - useful for alt titles
*/
-/obj/landmark/spawnpoint/proc/RenderAnnounceMessage(mob/M, client/C, datum/role/job/J, name, job_name)
+/obj/landmark/spawnpoint/proc/RenderAnnounceMessage(mob/M, client/C, datum/prototype/role/job/J, name, job_name)
return "[name || "Unknown"] will arrive shortly."
/**
diff --git a/code/game/landmarks/spawnpoint/station/jobs.dm b/code/game/landmarks/spawnpoint/station/jobs.dm
index 8b01ed2aaa8..7c3b5d6266d 100644
--- a/code/game/landmarks/spawnpoint/station/jobs.dm
+++ b/code/game/landmarks/spawnpoint/station/jobs.dm
@@ -1,7 +1,7 @@
/obj/landmark/spawnpoint/job/assistant
name = "Assistant"
icon_state = "Assistant"
- job_path = /datum/role/job/station/assistant
+ job_path = /datum/prototype/role/job/station/assistant
/obj/landmark/spawnpoint/job/assistant/override
spawns_left = INFINITY
@@ -11,7 +11,7 @@
/obj/landmark/spawnpoint/job/outsider
name = "Traveler"
icon_state = "Assistant"
- job_path = /datum/role/job/station/outsider
+ job_path = /datum/prototype/role/job/station/outsider
/obj/landmark/spawnpoint/job/outsider/override
spawns_left = INFINITY
@@ -21,205 +21,205 @@
/obj/landmark/spawnpoint/job/janitor
name = "Janitor"
icon_state = "Janitor"
- job_path = /datum/role/job/station/janitor
+ job_path = /datum/prototype/role/job/station/janitor
/obj/landmark/spawnpoint/job/cargo_technician
name = "Cargo Technician"
icon_state = "Cargo Technician"
- job_path = /datum/role/job/station/cargo_tech
+ job_path = /datum/prototype/role/job/station/cargo_tech
/obj/landmark/spawnpoint/job/bartender
name = "Bartender"
icon_state = "Bartender"
- job_path = /datum/role/job/station/bartender
+ job_path = /datum/prototype/role/job/station/bartender
/obj/landmark/spawnpoint/job/clown
name = "Clown"
icon_state = "Clown"
- job_path = /datum/role/job/station/clown
+ job_path = /datum/prototype/role/job/station/clown
/obj/landmark/spawnpoint/job/mime
name = "Mime"
icon_state = "Mime"
- job_path = /datum/role/job/station/mime
+ job_path = /datum/prototype/role/job/station/mime
/obj/landmark/spawnpoint/job/quartermaster
name = "Quartermaster"
icon_state = "Quartermaster"
- job_path = /datum/role/job/station/quartermaster
+ job_path = /datum/prototype/role/job/station/quartermaster
/obj/landmark/spawnpoint/job/atmospheric_technician
name = "Atmospheric Technician"
icon_state = "Atmospheric Technician"
- job_path = /datum/role/job/station/atmos
+ job_path = /datum/prototype/role/job/station/atmos
/obj/landmark/spawnpoint/job/chef
name = "Cook"
icon_state = "Cook"
- job_path = /datum/role/job/station/chef
+ job_path = /datum/prototype/role/job/station/chef
/obj/landmark/spawnpoint/job/shaft_miner
name = "Shaft Miner"
icon_state = "Shaft Miner"
- job_path = /datum/role/job/station/mining
+ job_path = /datum/prototype/role/job/station/mining
/obj/landmark/spawnpoint/job/security_officer
name = "Security Officer"
icon_state = "Security Officer"
- job_path = /datum/role/job/station/officer
+ job_path = /datum/prototype/role/job/station/officer
/obj/landmark/spawnpoint/job/botanist
name = "Botanist"
icon_state = "Botanist"
- job_path = /datum/role/job/station/hydro
+ job_path = /datum/prototype/role/job/station/hydro
/obj/landmark/spawnpoint/job/head_of_security
name = "Head of Security"
icon_state = "Head of Security"
- job_path = /datum/role/job/station/head_of_security
+ job_path = /datum/prototype/role/job/station/head_of_security
/obj/landmark/spawnpoint/job/captain
name = "Captain"
icon_state = "Captain"
- job_path = /datum/role/job/station/captain
+ job_path = /datum/prototype/role/job/station/captain
/obj/landmark/spawnpoint/job/blueshield
name = "Blueshield"
icon_state = "Blueshield"
- job_path = /datum/role/job/station/blueshield
+ job_path = /datum/prototype/role/job/station/blueshield
/obj/landmark/spawnpoint/job/detective
name = "Detective"
icon_state = "Detective"
- job_path = /datum/role/job/station/detective
+ job_path = /datum/prototype/role/job/station/detective
/obj/landmark/spawnpoint/job/warden
name = "Warden"
icon_state = "Warden"
- job_path = /datum/role/job/station/warden
+ job_path = /datum/prototype/role/job/station/warden
/obj/landmark/spawnpoint/job/chief_engineer
name = "Chief Engineer"
icon_state = "Chief Engineer"
- job_path = /datum/role/job/station/chief_engineer
+ job_path = /datum/prototype/role/job/station/chief_engineer
/obj/landmark/spawnpoint/job/senior_engineer
name = "Senior Engineer"
icon_state = "Chief Engineer"
- job_path = /datum/role/job/station/senior_engineer
+ job_path = /datum/prototype/role/job/station/senior_engineer
/obj/landmark/spawnpoint/job/head_of_personnel
name = "Head of Personnel"
icon_state = "Head of Personnel"
- job_path = /datum/role/job/station/head_of_personnel
+ job_path = /datum/prototype/role/job/station/head_of_personnel
/obj/landmark/spawnpoint/job/librarian
name = "Curator"
icon_state = "Curator"
- job_path = /datum/role/job/station/librarian
+ job_path = /datum/prototype/role/job/station/librarian
/obj/landmark/spawnpoint/job/lawyer
name = "Lawyer"
icon_state = "Lawyer"
- job_path = /datum/role/job/station/lawyer
+ job_path = /datum/prototype/role/job/station/lawyer
/obj/landmark/spawnpoint/job/station_engineer
name = "Station Engineer"
icon_state = "Station Engineer"
- job_path = /datum/role/job/station/engineer
+ job_path = /datum/prototype/role/job/station/engineer
/obj/landmark/spawnpoint/job/medical_doctor
name = "Medical Doctor"
icon_state = "Medical Doctor"
- job_path = /datum/role/job/station/doctor
+ job_path = /datum/prototype/role/job/station/doctor
/obj/landmark/spawnpoint/job/head_nurse
name = "Senior Physician"
// icon_state = "Medical Doctor"
- job_path = /datum/role/job/station/senior_physician
+ job_path = /datum/prototype/role/job/station/senior_physician
/obj/landmark/spawnpoint/job/paramedic
name = "Paramedic"
icon_state = "Paramedic"
- job_path = /datum/role/job/station/paramedic
+ job_path = /datum/prototype/role/job/station/paramedic
/obj/landmark/spawnpoint/job/scientist
name = "Scientist"
icon_state = "Scientist"
- job_path = /datum/role/job/station/scientist
+ job_path = /datum/prototype/role/job/station/scientist
/obj/landmark/spawnpoint/job/senior_researcher
name = "Senior Researcher"
// icon_state = "Scientist"
- job_path = /datum/role/job/station/senior_researcher
+ job_path = /datum/prototype/role/job/station/senior_researcher
/obj/landmark/spawnpoint/job/chemist
name = "Chemist"
icon_state = "Chemist"
- job_path = /datum/role/job/station/chemist
+ job_path = /datum/prototype/role/job/station/chemist
/obj/landmark/spawnpoint/job/roboticist
name = "Roboticist"
icon_state = "Roboticist"
- job_path = /datum/role/job/station/roboticist
+ job_path = /datum/prototype/role/job/station/roboticist
/obj/landmark/spawnpoint/job/research_director
name = "Research Director"
icon_state = "Research Director"
- job_path = /datum/role/job/station/research_director
+ job_path = /datum/prototype/role/job/station/research_director
// /obj/landmark/spawnpoint/job/geneticist
// name = "Geneticist"
// icon_state = "Geneticist"
-// job_path = /datum/role/job/station/geneticist
+// job_path = /datum/prototype/role/job/station/geneticist
/obj/landmark/spawnpoint/job/chief_medical_officer
name = "Chief Medical Officer"
icon_state = "Chief Medical Officer"
- job_path = /datum/role/job/station/chief_medical_officer
+ job_path = /datum/prototype/role/job/station/chief_medical_officer
// /obj/landmark/spawnpoint/job/virologist
// name = "Virologist"
// icon_state = "Virologist"
-// job_path = /datum/role/job/station/virologist
+// job_path = /datum/prototype/role/job/station/virologist
/obj/landmark/spawnpoint/job/chaplain
name = "Chaplain"
icon_state = "Chaplain"
- job_path = /datum/role/job/station/chaplain
+ job_path = /datum/prototype/role/job/station/chaplain
/obj/landmark/spawnpoint/job/cyborg
name = "Cyborg"
icon_state = "Cyborg"
- job_path = /datum/role/job/station/cyborg
+ job_path = /datum/prototype/role/job/station/cyborg
/obj/landmark/spawnpoint/job/entertainer
name = "Entertainer"
- job_path = /datum/role/job/station/entertainer
+ job_path = /datum/prototype/role/job/station/entertainer
/obj/landmark/spawnpoint/job/pilot
name = "Pilot"
- job_path = /datum/role/job/station/pilot
+ job_path = /datum/prototype/role/job/station/pilot
/obj/landmark/spawnpoint/job/command_secretary
name = "Command Secretary"
- job_path = /datum/role/job/station/command_secretary
+ job_path = /datum/prototype/role/job/station/command_secretary
/obj/landmark/spawnpoint/job/explorer
name = "Explorer"
- job_path = /datum/role/job/station/explorer
+ job_path = /datum/prototype/role/job/station/explorer
/obj/landmark/spawnpoint/job/field_medic
name = "Field Medic"
- job_path = /datum/role/job/station/field_medic
+ job_path = /datum/prototype/role/job/station/field_medic
/obj/landmark/spawnpoint/job/pathfinder
name = "Pathfinder"
- job_path = /datum/role/job/station/pathfinder
+ job_path = /datum/prototype/role/job/station/pathfinder
/obj/landmark/spawnpoint/job/psychiatrist
name = "Psychiatrist"
- job_path = /datum/role/job/station/psychiatrist
+ job_path = /datum/prototype/role/job/station/psychiatrist
/obj/landmark/spawnpoint/job/xenobotanist
name = "Xenobotanist"
@@ -232,7 +232,7 @@
icon_state = "AI"
latejoin = TRUE // AIize in transform_procs.dm uses get_latejoin_spawnpoint() for spawning in a AI -- including at roundstart.
delete_on_roundstart = TRUE
- job_path = /datum/role/job/station/ai
+ job_path = /datum/prototype/role/job/station/ai
prevent_mob_stack = FALSE
spawns_left = 1
var/primary_ai = TRUE
diff --git a/code/game/landmarks/spawnpoint/tradeport.dm b/code/game/landmarks/spawnpoint/tradeport.dm
index 40f217d262a..f1cdd09c0a3 100644
--- a/code/game/landmarks/spawnpoint/tradeport.dm
+++ b/code/game/landmarks/spawnpoint/tradeport.dm
@@ -1,6 +1,6 @@
/obj/landmark/spawnpoint/job/trader
name = "Trader"
- job_path = /datum/role/job/trader
+ job_path = /datum/prototype/role/job/trader
latejoin = TRUE
latejoin_override = TRUE
@@ -10,7 +10,7 @@
/obj/landmark/spawnpoint/job/outsider
name = "Traveler"
- job_path = /datum/role/job/station/outsider
+ job_path = /datum/prototype/role/job/station/outsider
latejoin = TRUE
latejoin_override = TRUE
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 23663839544..d17e876ee1c 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -391,7 +391,7 @@
answer = text2num(answer)
if(field == "rank")
- if(answer in SSjob.all_job_titles())
+ if(answer in RSroles.legacy_all_job_titles())
active1.fields["real_rank"] = answer
if(field == "criminal")
diff --git a/code/game/machinery/computer/timeclock_vr.dm b/code/game/machinery/computer/timeclock_vr.dm
index ee6f24c97b8..11ab1cad34c 100644
--- a/code/game/machinery/computer/timeclock_vr.dm
+++ b/code/game/machinery/computer/timeclock_vr.dm
@@ -93,7 +93,7 @@
if(card)
data["card"] = "[card]"
data["assignment"] = card.assignment
- var/datum/role/job/job = SSjob.get_job(card.rank)
+ var/datum/prototype/role/job/job = RSroles.legacy_job_by_title(card.rank)
if(job)
data["job_datum"] = list(
"title" = job.title,
@@ -155,7 +155,7 @@
/obj/machinery/computer/timeclock/proc/getOpenOnDutyJobs(var/mob/user, var/department)
var/list/available_jobs = list()
- for(var/datum/role/job/job in SSjob.occupations)
+ for(var/datum/prototype/role/job/job in RSroles.legacy_all_job_datums())
if(isOpenOnDutyJob(user, department, job))
var/list/titles = available_titles(user, job)
if(!length(titles))
@@ -163,11 +163,11 @@
available_jobs[job.title] = titles
return available_jobs
-/obj/machinery/computer/timeclock/proc/available_titles(mob/user, var/datum/role/job/job)
+/obj/machinery/computer/timeclock/proc/available_titles(mob/user, var/datum/prototype/role/job/job)
var/list/datum/lore/character_background/backgrounds = user.mind?.original_background_ids()
return job.alt_title_query(backgrounds)
-/obj/machinery/computer/timeclock/proc/isOpenOnDutyJob(var/mob/user, var/department, var/datum/role/job/job)
+/obj/machinery/computer/timeclock/proc/isOpenOnDutyJob(var/mob/user, var/department, var/datum/prototype/role/job/job)
return job \
&& job.is_position_available() \
&& !job.whitelist_only \
@@ -179,8 +179,8 @@
&& (job.check_mob_availability_one(user) == ROLE_AVAILABLE)
/obj/machinery/computer/timeclock/proc/makeOnDuty(var/newrank, var/newassignment)
- var/datum/role/job/oldjob = SSjob.get_job(card.rank)
- var/datum/role/job/newjob = SSjob.get_job(newrank)
+ var/datum/prototype/role/job/oldjob = RSroles.legacy_job_by_title(card.rank)
+ var/datum/prototype/role/job/newjob = RSroles.legacy_job_by_title(newrank)
if(!oldjob || !isOpenOnDutyJob(usr, oldjob.pto_type, newjob))
return
if(newassignment != newjob.title && !(newassignment in newjob.alt_titles))
@@ -203,12 +203,12 @@
return
/obj/machinery/computer/timeclock/proc/makeOffDuty()
- var/datum/role/job/foundjob = SSjob.get_job(card.rank)
+ var/datum/prototype/role/job/foundjob = RSroles.legacy_job_by_title(card.rank)
if(!foundjob)
return
var/new_dept = foundjob.pto_type || PTO_CIVILIAN
- var/datum/role/job/ptojob = null
- for(var/datum/role/job/job in SSjob.occupations)
+ var/datum/prototype/role/job/ptojob = null
+ for(var/datum/prototype/role/job/job in RSroles.legacy_all_job_datums())
if(job.pto_type == new_dept && job.is_off_duty)
ptojob = job
break
diff --git a/code/game/objects/items/id_cards/contractor_ids.dm b/code/game/objects/items/id_cards/contractor_ids.dm
index 02378f77e4b..b18a75c5c9a 100644
--- a/code/game/objects/items/id_cards/contractor_ids.dm
+++ b/code/game/objects/items/id_cards/contractor_ids.dm
@@ -18,7 +18,7 @@
/obj/item/card/id/contractor/update_icon_state()
. = ..()
- var/datum/role/job/J = SSjob.get_job(rank)
+ var/datum/prototype/role/job/J = RSroles.legacy_job_by_title(rank)
var/department = lowertext(LAZYACCESS(J?.departments,1))
switch(department)
if("security")
diff --git a/code/game/objects/items/id_cards/station_ids.dm b/code/game/objects/items/id_cards/station_ids.dm
index 99aca9d5b13..010c8c01044 100644
--- a/code/game/objects/items/id_cards/station_ids.dm
+++ b/code/game/objects/items/id_cards/station_ids.dm
@@ -31,7 +31,7 @@
var/primary_color = rgb(0,0,0) // Obtained by eyedroppering the stripe in the middle of the card
var/secondary_color = rgb(0,0,0) // Likewise for the oval in the top-left corner
- var/datum/role/job/job_access_type = /datum/role/job/station/assistant // Job type to acquire access rights from, if any
+ var/datum/prototype/role/job/job_access_type = /datum/prototype/role/job/station/assistant // Job type to acquire access rights from, if any
//alt titles are handled a bit weirdly in order to unobtrusively integrate into existing ID system
var/assignment = null //can be alt title or the actual job
@@ -45,13 +45,13 @@
/obj/item/card/id/Initialize(mapload)
. = ..()
- var/datum/role/job/getting_from
+ var/datum/prototype/role/job/getting_from
if(ispath(job_access_type))
- job_access_type = SSjob.job_by_type(job_access_type)
+ job_access_type = RSroles.legacy_job_by_type(job_access_type)
if(istype(job_access_type))
getting_from = job_access_type
else
- getting_from = SSjob.get_job(rank)
+ getting_from = RSroles.legacy_job_by_title(rank)
if(!isnull(getting_from))
access = getting_from.get_access()
job_access_type = getting_from
@@ -252,20 +252,20 @@
name = "secretary ID"
assignment = "Command Secretary"
rank = "Command Secretary"
- job_access_type = /datum/role/job/station/command_secretary
+ job_access_type = /datum/prototype/role/job/station/command_secretary
/obj/item/card/id/silver/hop
name = "\improper HoP ID"
assignment = "Head of Personnel"
rank = "Head of Personnel"
desc = "A card which represents the balance between those that serve and those that are served."
- job_access_type = /datum/role/job/station/head_of_personnel
+ job_access_type = /datum/prototype/role/job/station/head_of_personnel
/obj/item/card/id/silver/blueshield
name = "\improper Blueshield ID"
assignment = "Blueshield"
rank = "Blueshield"
- job_access_type = /datum/role/job/station/blueshield
+ job_access_type = /datum/prototype/role/job/station/blueshield
/obj/item/card/id/gold
name = "gold identification card"
@@ -278,14 +278,14 @@
name = "\improper Captain's ID"
assignment = "Captain"
rank = "Captain"
- job_access_type = /datum/role/job/station/captain
+ job_access_type = /datum/prototype/role/job/station/captain
/obj/item/card/id/gold/captain/spare
name = "\improper Captain's Spare ID"
desc = "The spare ID of the High Lord himself."
registered_name = "Captain"
icon_state = "gold-id-alternate"
- job_access_type = /datum/role/job/station/captain
+ job_access_type = /datum/prototype/role/job/station/captain
/obj/item/card/id/synthetic
name = "\improper Synthetic ID"
@@ -349,31 +349,31 @@
name = "doctor ID"
assignment = "Medical Doctor"
rank = "Medical Doctor"
- job_access_type = /datum/role/job/station/doctor
+ job_access_type = /datum/prototype/role/job/station/doctor
/obj/item/card/id/medical/chemist
name = "chemist ID"
assignment = "Chemist"
rank = "Chemist"
- job_access_type = /datum/role/job/station/chemist
+ job_access_type = /datum/prototype/role/job/station/chemist
/obj/item/card/id/medical/geneticist
name = "geneticist ID"
assignment = "Geneticist"
rank = "Geneticist"
- job_access_type = /datum/role/job/station/doctor //geneticist
+ job_access_type = /datum/prototype/role/job/station/doctor //geneticist
/obj/item/card/id/medical/psychiatrist
name = "psychiatrist ID"
assignment = "Psychiatrist"
rank = "Psychiatrist"
- job_access_type = /datum/role/job/station/psychiatrist
+ job_access_type = /datum/prototype/role/job/station/psychiatrist
/obj/item/card/id/medical/paramedic
name = "paramedic ID"
assignment = "Paramedic"
rank = "Paramedic"
- job_access_type = /datum/role/job/station/paramedic
+ job_access_type = /datum/prototype/role/job/station/paramedic
/obj/item/card/id/medical/head
name = "\improper CMO ID"
@@ -382,7 +382,7 @@
secondary_color = rgb(255,223,127)
assignment = "Chief Medical Officer"
rank = "Chief Medical Officer"
- job_access_type = /datum/role/job/station/chief_medical_officer
+ job_access_type = /datum/prototype/role/job/station/chief_medical_officer
/obj/item/card/id/security
name = "security identification card"
@@ -395,19 +395,19 @@
name = "officer ID"
assignment = "Security Officer"
rank = "Security Officer"
- job_access_type = /datum/role/job/station/officer
+ job_access_type = /datum/prototype/role/job/station/officer
/obj/item/card/id/security/detective
name = "detective ID"
assignment = "Detective"
rank = "Detective"
- job_access_type = /datum/role/job/station/detective
+ job_access_type = /datum/prototype/role/job/station/detective
/obj/item/card/id/security/warden
name = "warden ID"
assignment = "Warden"
rank = "Warden"
- job_access_type = /datum/role/job/station/warden
+ job_access_type = /datum/prototype/role/job/station/warden
/obj/item/card/id/security/head
name = "\improper HoS ID"
@@ -416,7 +416,7 @@
secondary_color = rgb(255,223,127)
assignment = "Head of Security"
rank = "Head of Security"
- job_access_type = /datum/role/job/station/head_of_security
+ job_access_type = /datum/prototype/role/job/station/head_of_security
/obj/item/card/id/prisoner
@@ -480,13 +480,13 @@
name = "engineer ID"
assignment = "Station Engineer"
rank = "Station Engineer"
- job_access_type = /datum/role/job/station/engineer
+ job_access_type = /datum/prototype/role/job/station/engineer
/obj/item/card/id/engineering/atmos
name = "atmospherics ID"
assignment = "Atmospheric Technician"
rank = "Atmospheric Technician"
- job_access_type = /datum/role/job/station/atmos
+ job_access_type = /datum/prototype/role/job/station/atmos
/obj/item/card/id/engineering/head
name = "\improper CE ID"
@@ -495,7 +495,7 @@
secondary_color = rgb(255,223,127)
assignment = "Chief Engineer"
rank = "Chief Engineer"
- job_access_type = /datum/role/job/station/chief_engineer
+ job_access_type = /datum/prototype/role/job/station/chief_engineer
/obj/item/card/id/science
name = "science identification card"
@@ -508,19 +508,19 @@
name = "scientist ID"
assignment = "Scientist"
rank = "Scientist"
- job_access_type = /datum/role/job/station/scientist
+ job_access_type = /datum/prototype/role/job/station/scientist
/obj/item/card/id/science/xenobiologist
name = "xenobiologist ID"
assignment = "Xenobiologist"
rank = "Xenobiologist"
- job_access_type = /datum/role/job/station/scientist // /datum/role/job/station/xenobiologist
+ job_access_type = /datum/prototype/role/job/station/scientist // /datum/prototype/role/job/station/xenobiologist
/obj/item/card/id/science/roboticist
name = "roboticist ID"
assignment = "Roboticist"
rank = "Roboticist"
- job_access_type = /datum/role/job/station/roboticist
+ job_access_type = /datum/prototype/role/job/station/roboticist
/obj/item/card/id/science/head
name = "\improper RD ID"
@@ -529,7 +529,7 @@
secondary_color = rgb(255,223,127)
assignment = "Research Director"
rank = "Research Director"
- job_access_type = /datum/role/job/station/research_director
+ job_access_type = /datum/prototype/role/job/station/research_director
/obj/item/card/id/cargo
name = "cargo identification card"
@@ -542,13 +542,13 @@
name = "cargo ID"
assignment = "Cargo Technician"
rank = "Cargo Technician"
- job_access_type = /datum/role/job/station/cargo_tech
+ job_access_type = /datum/prototype/role/job/station/cargo_tech
/obj/item/card/id/cargo/mining
name = "mining ID"
assignment = "Shaft Miner"
rank = "Shaft Miner"
- job_access_type = /datum/role/job/station/mining
+ job_access_type = /datum/prototype/role/job/station/mining
/obj/item/card/id/cargo/head
name = "\improper Quartermaster's ID"
@@ -557,12 +557,12 @@
secondary_color = rgb(255,223,127)
assignment = "Quartermaster"
rank = "Quartermaster"
- job_access_type = /datum/role/job/station/quartermaster
+ job_access_type = /datum/prototype/role/job/station/quartermaster
/obj/item/card/id/assistant
assignment = USELESS_JOB
rank = USELESS_JOB
- job_access_type = /datum/role/job/station/assistant
+ job_access_type = /datum/prototype/role/job/station/assistant
/obj/item/card/id/civilian
name = "civilian identification card"
@@ -572,61 +572,61 @@
secondary_color = rgb(95,159,191)
assignment = "Civilian"
rank = "Assistant"
- job_access_type = /datum/role/job/station/assistant
+ job_access_type = /datum/prototype/role/job/station/assistant
/obj/item/card/id/civilian/bartender
name = "bartender ID"
assignment = "Bartender"
rank = "Bartender"
- job_access_type = /datum/role/job/station/bartender
+ job_access_type = /datum/prototype/role/job/station/bartender
/obj/item/card/id/civilian/botanist
name = "botanist ID"
assignment = "Botanist"
rank = "Botanist"
- job_access_type = /datum/role/job/station/hydro
+ job_access_type = /datum/prototype/role/job/station/hydro
/obj/item/card/id/civilian/chaplain
name = "chaplain ID"
assignment = "Chaplain"
rank = "Chaplain"
- job_access_type = /datum/role/job/station/chaplain
+ job_access_type = /datum/prototype/role/job/station/chaplain
/obj/item/card/id/civilian/chef
name = "chef ID"
assignment = "Chef"
rank = "Chef"
- job_access_type = /datum/role/job/station/chef
+ job_access_type = /datum/prototype/role/job/station/chef
/obj/item/card/id/civilian/internal_affairs_agent
name = "internal affairs ID"
assignment = "Internal Affairs Agent"
rank = "Internal Affairs Agent"
- job_access_type = /datum/role/job/station/lawyer
+ job_access_type = /datum/prototype/role/job/station/lawyer
/obj/item/card/id/civilian/janitor
name = "janitor ID"
assignment = "Janitor"
rank = "Janitor"
- job_access_type = /datum/role/job/station/janitor
+ job_access_type = /datum/prototype/role/job/station/janitor
/obj/item/card/id/civilian/librarian
name = "librarian ID"
assignment = "Librarian"
rank = "Librarian"
- job_access_type = /datum/role/job/station/librarian
+ job_access_type = /datum/prototype/role/job/station/librarian
/obj/item/card/id/civilian/clown
name = "clown ID"
assignment = "Clown"
rank = "Clown"
- job_access_type = /datum/role/job/station/clown
+ job_access_type = /datum/prototype/role/job/station/clown
/obj/item/card/id/civilian/mime
name = "mime ID"
assignment = "Mime"
rank = "Mime"
- job_access_type = /datum/role/job/station/mime
+ job_access_type = /datum/prototype/role/job/station/mime
/obj/item/card/id/civilian/head //This is not the HoP. There's no position that uses this right now.
name = "\improper Services Officer ID"
@@ -647,7 +647,7 @@
icon_state = "chit"
//primary_color = rgb(142,94,0)
//secondary_color = rgb(191,159,95)
- job_access_type = /datum/role/job/trader
+ job_access_type = /datum/prototype/role/job/trader
var/random_color = TRUE
/obj/item/card/id/external/merchant/Initialize(mapload)
@@ -683,7 +683,7 @@
rank = "Field Medic"
primary_color = rgb(47,189,189)
secondary_color = rgb(127,223,223)
- job_access_type = /datum/role/job/station/field_medic
+ job_access_type = /datum/prototype/role/job/station/field_medic
/obj/item/card/id/explorer
name = "identification card"
@@ -694,12 +694,12 @@
/obj/item/card/id/explorer/pilot
assignment = "Pilot"
rank = "Pilot"
- job_access_type = /datum/role/job/station/pilot
+ job_access_type = /datum/prototype/role/job/station/pilot
/obj/item/card/id/explorer/explorer
assignment = "Explorer"
rank = "Explorer"
- job_access_type = /datum/role/job/station/explorer
+ job_access_type = /datum/prototype/role/job/station/explorer
/obj/item/card/id/explorer/head
name = "identification card"
@@ -711,7 +711,7 @@
/obj/item/card/id/explorer/head/pathfinder
assignment = "Pathfinder"
rank = "Pathfinder"
- job_access_type = /datum/role/job/station/pathfinder
+ job_access_type = /datum/prototype/role/job/station/pathfinder
/obj/item/card/id/external/gaia
name = "Happy Trails Resort Company Day Pass"
diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm
index e332f48c88f..177b8756990 100644
--- a/code/modules/admin/DB ban/functions.dm
+++ b/code/modules/admin/DB ban/functions.dm
@@ -346,7 +346,7 @@
output += "
| Duration: | "
output += "Job: |