diff --git a/code/__DEFINES/job.dm b/code/__DEFINES/job.dm
index 0173a55e2d17..a2dfbb559769 100644
--- a/code/__DEFINES/job.dm
+++ b/code/__DEFINES/job.dm
@@ -213,6 +213,9 @@ GLOBAL_LIST_INIT(job_command_roles, JOB_COMMAND_ROLES_LIST)
#define ROLES_WY_CORPORATE list(JOB_EXECUTIVE_SUPERVISOR, JOB_EXECUTIVE_SPECIALIST, JOB_SENIOR_EXECUTIVE, JOB_EXECUTIVE, JOB_JUNIOR_EXECUTIVE, JOB_TRAINEE)
#define ROLES_WY_LEADERSHIP list(JOB_DIRECTOR, JOB_PMC_DIRECTOR, JOB_CHIEF_EXECUTIVE, JOB_DIVISION_MANAGER, JOB_ASSISTANT_MANAGER)
+#define JOB_CORPORATE_ROLES /datum/timelock/corporate
+#define JOB_CORPORATE_ROLES_LIST list(JOB_CORPORATE_LIAISON, JOB_WO_CORPORATE_LIAISON, JOB_DIRECTOR, JOB_PMC_DIRECTOR, JOB_CHIEF_EXECUTIVE, JOB_DIVISION_MANAGER, JOB_ASSISTANT_MANAGER, JOB_EXECUTIVE_SUPERVISOR, JOB_EXECUTIVE_SPECIALIST, JOB_SENIOR_EXECUTIVE, JOB_EXECUTIVE, JOB_JUNIOR_EXECUTIVE, JOB_TRAINEE)
+
//-------- WY Goons --------//
#define JOB_WY_GOON "WY Corporate Security"
#define JOB_WY_GOON_TECH "WY Corporate Security Technician"
@@ -366,6 +369,21 @@ GLOBAL_LIST_INIT(job_command_roles, JOB_COMMAND_ROLES_LIST)
#define DUTCH_JOB_LIST list(JOB_DUTCH_ARNOLD, JOB_DUTCH_RIFLEMAN, JOB_DUTCH_MINIGUNNER, JOB_DUTCH_FLAMETHROWER, JOB_DUTCH_MEDIC)
+//---------- RESPONDERS ----------//
+/// This root job should never appear ingame, it's used to select the character slot.
+#define JOB_FAX_RESPONDER "Fax Responder"
+#define JOB_FAX_RESPONDER_USCM_HC "USCM-HC Communications Officer"
+#define JOB_FAX_RESPONDER_USCM_PVST "Provost Communications Officer"
+#define JOB_FAX_RESPONDER_WY "WY Communications Executive"
+#define JOB_FAX_RESPONDER_UPP "UPP Communications Officer"
+#define JOB_FAX_RESPONDER_TWE "TWE Communications Officer"
+#define JOB_FAX_RESPONDER_CLF "CLF Information Correspondant"
+#define JOB_FAX_RESPONDER_CMB "CMB Deputy Operations Officer"
+
+#define FAX_RESPONDER_JOB_LIST list(JOB_FAX_RESPONDER_USCM_HC, JOB_FAX_RESPONDER_USCM_PVST, JOB_FAX_RESPONDER_WY, JOB_FAX_RESPONDER_UPP, JOB_FAX_RESPONDER_TWE, JOB_FAX_RESPONDER_CLF, JOB_FAX_RESPONDER_CMB)
+
+
+//---------- ANTAG ----------//
#define JOB_PREDATOR "Predator"
#define JOB_XENOMORPH "Xenomorph"
#define JOB_XENOMORPH_QUEEN "Queen"
diff --git a/code/__DEFINES/mode.dm b/code/__DEFINES/mode.dm
index 04c7993bd9f2..afa922c73314 100644
--- a/code/__DEFINES/mode.dm
+++ b/code/__DEFINES/mode.dm
@@ -117,6 +117,7 @@
#define ROLE_WHITELISTED 16
#define ROLE_NO_ACCOUNT 32
#define ROLE_CUSTOM_SPAWN 64
+#define ROLE_HIDDEN 128
//=================================================
//Role defines, specifically lists of roles for job bans, crew manifests and the like.
@@ -137,7 +138,7 @@ GLOBAL_LIST_INIT(ROLES_WO, list(JOB_WO_CO, JOB_WO_XO, JOB_WO_CORPORATE_LIAISON,
//Groundside roles
GLOBAL_LIST_INIT(ROLES_XENO, list(JOB_XENOMORPH_QUEEN, JOB_XENOMORPH))
-GLOBAL_LIST_INIT(ROLES_WHITELISTED, list(JOB_SYNTH_SURVIVOR, JOB_CO_SURVIVOR, JOB_PREDATOR))
+GLOBAL_LIST_INIT(ROLES_WHITELISTED, list(JOB_SYNTH_SURVIVOR, JOB_CO_SURVIVOR, JOB_PREDATOR, JOB_FAX_RESPONDER))
GLOBAL_LIST_INIT(ROLES_SPECIAL, list(JOB_SURVIVOR))
GLOBAL_LIST_INIT(ROLES_USCM, ROLES_CIC + GLOB.ROLES_POLICE + GLOB.ROLES_AUXIL_SUPPORT + GLOB.ROLES_MISC + GLOB.ROLES_ENGINEERING + GLOB.ROLES_REQUISITION + GLOB.ROLES_MEDICAL + GLOB.ROLES_MARINES - ROLES_WO)
@@ -195,13 +196,8 @@ GLOBAL_LIST_INIT(whitelist_hierarchy, list(WHITELIST_NORMAL, WHITELIST_COUNCIL,
///Senior Enlisted Advisor, auto granted by R_MENTOR
#define WHITELIST_MENTOR (1<<15)
-
-#define WHITELISTS_GENERAL (WHITELIST_YAUTJA|WHITELIST_COMMANDER|WHITELIST_SYNTHETIC|WHITELIST_MENTOR|WHITELIST_JOE)
-#define WHITELISTS_COUNCIL (WHITELIST_YAUTJA_COUNCIL|WHITELIST_COMMANDER_COUNCIL|WHITELIST_SYNTHETIC_COUNCIL)
-#define WHITELISTS_LEGACY_COUNCIL (WHITELIST_YAUTJA_COUNCIL_LEGACY|WHITELIST_COMMANDER_COUNCIL_LEGACY|WHITELIST_SYNTHETIC_COUNCIL_LEGACY)
-#define WHITELISTS_LEADER (WHITELIST_YAUTJA_LEADER|WHITELIST_COMMANDER_LEADER|WHITELIST_SYNTHETIC_LEADER)
-
-#define WHITELIST_EVERYTHING (WHITELISTS_GENERAL|WHITELISTS_COUNCIL|WHITELISTS_LEADER)
+///Fax Responder
+#define WHITELIST_FAX_RESPONDER (1<<16)
#define COUNCIL_LIST list(WHITELIST_COMMANDER_COUNCIL, WHITELIST_SYNTHETIC_COUNCIL, WHITELIST_YAUTJA_COUNCIL)
#define SENATOR_LIST list(WHITELIST_COMMANDER_LEADER, WHITELIST_SYNTHETIC_LEADER, WHITELIST_YAUTJA_LEADER)
@@ -225,6 +221,7 @@ DEFINE_BITFIELD(whitelist_status, list(
"WHITELIST_SYNTHETIC_COUNCIL_LEGACY" = WHITELIST_SYNTHETIC_COUNCIL_LEGACY,
"WHITELIST_SYNTHETIC_LEADER" = WHITELIST_SYNTHETIC_LEADER,
"WHITELIST_MENTOR" = WHITELIST_MENTOR,
+ "WHITELIST_FAX_RESPONDER" = WHITELIST_FAX_RESPONDER,
))
//=================================================
diff --git a/code/__DEFINES/paperwork.dm b/code/__DEFINES/paperwork.dm
new file mode 100644
index 000000000000..0acefb182979
--- /dev/null
+++ b/code/__DEFINES/paperwork.dm
@@ -0,0 +1,8 @@
+#define PAPER_CATEGORY_USCM "USCM"
+#define PAPER_CATEGORY_USCM_HC "USCM HC"
+#define PAPER_CATEGORY_PROVOST "Provost"
+#define PAPER_CATEGORY_WEYYU "Weyland Yutani"
+#define PAPER_CATEGORY_UPP "UPP"
+#define PAPER_CATEGORY_CMB "CMB"
+#define PAPER_CATEGORY_MP "Military Police"
+#define PAPER_CATEGORY_LIAISON "WY Liaison"
diff --git a/code/__DEFINES/urls.dm b/code/__DEFINES/urls.dm
index 5d3fca1a2032..2745b41336d4 100644
--- a/code/__DEFINES/urls.dm
+++ b/code/__DEFINES/urls.dm
@@ -9,3 +9,4 @@
#define URL_WIKI_MACROS "Macros"
#define URL_WIKI_SOP "Standard_Operating_Procedure"
#define URL_WIKI_CO_RULES "CO_Council_Rulings"
+#define URL_WIKI_FAX_RESPONDER "Fax_Responder"
diff --git a/code/datums/emergency_calls/emergency_call.dm b/code/datums/emergency_calls/emergency_call.dm
index e956a9731c7c..8a96d73eb4de 100644
--- a/code/datums/emergency_calls/emergency_call.dm
+++ b/code/datums/emergency_calls/emergency_call.dm
@@ -9,6 +9,7 @@
var/list/datum/emergency_call/all_calls = list() //initialized at round start and stores the datums.
var/datum/emergency_call/picked_calls[] = list() //Which distress calls are currently active
var/ert_dispatched = FALSE
+ var/loaded_fax_base = FALSE
/datum/game_mode/proc/ares_online()
var/name = "ARES Online"
diff --git a/code/datums/emergency_calls/ert_stations.dm b/code/datums/emergency_calls/ert_stations.dm
index 5a129723bad0..947007d25d70 100644
--- a/code/datums/emergency_calls/ert_stations.dm
+++ b/code/datums/emergency_calls/ert_stations.dm
@@ -18,3 +18,6 @@
/datum/lazy_template/ert/uscm_station
map_name = "uscm_ert_station"
+
+/datum/lazy_template/fax_response_base
+ map_name = "fax_responder_base"
diff --git a/code/datums/skills/civilian.dm b/code/datums/skills/civilian.dm
index ff9cadf02913..66bca6b0fbef 100644
--- a/code/datums/skills/civilian.dm
+++ b/code/datums/skills/civilian.dm
@@ -224,3 +224,15 @@ CIVILIAN
SKILL_FIREARMS = SKILL_FIREARMS_TRAINED,
SKILL_LEADERSHIP = SKILL_LEAD_TRAINED,
)
+
+/datum/skills/civilian/fax_responder
+ name = "Comms Relay Worker" //Used for fax responder presets, allowing use of appropriate HUDs and basics.
+ skills = list(
+ SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
+ SKILL_LEADERSHIP = SKILL_LEAD_MASTER,
+ SKILL_OVERWATCH = SKILL_OVERWATCH_TRAINED,
+ SKILL_MEDICAL = SKILL_MEDICAL_TRAINED,
+ SKILL_ENGINEER = SKILL_ENGINEER_NOVICE,
+ SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
+ SKILL_INTEL = SKILL_INTEL_EXPERT,
+ )
diff --git a/code/game/area/admin_level.dm b/code/game/area/admin_level.dm
index 9dc43256f4de..f522ca24cd16 100644
--- a/code/game/area/admin_level.dm
+++ b/code/game/area/admin_level.dm
@@ -142,6 +142,10 @@
soundscape_playlist = SCAPE_PL_ELEVATOR_MUSIC
icon_state = "yellow"
+/area/adminlevel/ert_station/fax_response_station
+ name = "Sector Comms Relay"
+ icon_state = "green"
+
//Simulation area
/area/adminlevel/simulation
name = "Simulated Reality"
diff --git a/code/game/gamemodes/cm_initialize.dm b/code/game/gamemodes/cm_initialize.dm
index 4a208b00a796..d7568b349618 100644
--- a/code/game/gamemodes/cm_initialize.dm
+++ b/code/game/gamemodes/cm_initialize.dm
@@ -254,6 +254,106 @@ Additional game mode variables.
return new_predator
+//===================================================\\
+
+ //FAX RESPONDER INITIATLIZE\\
+
+//===================================================\\
+
+/datum/game_mode/proc/check_fax_responder_late_join(mob/responder, show_warning = TRUE)
+ if(!responder.client)
+ return FALSE
+ if(!(responder?.client.check_whitelist_status(WHITELIST_FAX_RESPONDER)))
+ if(show_warning)
+ to_chat(responder, SPAN_WARNING("You are not whitelisted!"))
+ return FALSE
+ if(show_warning && tgui_alert(responder, "Confirm joining as a Fax Responder.", "Confirmation", list("Yes", "No"), 10 SECONDS) != "Yes")
+ return FALSE
+ if(!get_fax_responder_slots(responder))
+ if(show_warning)
+ to_chat(responder, SPAN_WARNING("No slots available!"))
+ return FALSE
+ return TRUE
+
+/datum/game_mode/proc/get_fax_responder_slots(mob/responder_candidate)
+ var/list/options = list()
+ if(!responder_candidate.client)
+ return FALSE
+ if(!(responder_candidate.client.check_whitelist_status(WHITELIST_FAX_RESPONDER)))
+ to_chat(responder_candidate, SPAN_WARNING("You are not whitelisted!"))
+ return FALSE
+
+ for(var/job in FAX_RESPONDER_JOB_LIST)
+ var/datum/job/fax_responder_job = GLOB.RoleAuthority.roles_by_name[job]
+ var/job_max = fax_responder_job.total_positions
+ if((fax_responder_job.current_positions < job_max) && fax_responder_job.can_play_role(responder_candidate.client))
+ options += job
+ return options
+
+/datum/game_mode/proc/attempt_to_join_as_fax_responder(mob/responder_candidate, from_lobby = FALSE)
+ var/list/options = get_fax_responder_slots(responder_candidate)
+ if(!options || !options.len)
+ to_chat(responder_candidate, SPAN_WARNING("No Available Slot!"))
+ if(from_lobby)
+ var/mob/new_player/lobbied = responder_candidate
+ lobbied.new_player_panel()
+ return FALSE
+
+ var/choice = tgui_input_list(responder_candidate, "What Fax Responder do you want to join as?", "Which Responder?", options, 30 SECONDS)
+ if(!(choice in FAX_RESPONDER_JOB_LIST))
+ to_chat(responder_candidate, SPAN_WARNING("Error: No valid responder selected."))
+ if(from_lobby)
+ var/mob/new_player/lobbied = responder_candidate
+ lobbied.new_player_panel()
+ return FALSE
+
+ if(!transform_fax_responder(responder_candidate, choice))
+ if(from_lobby)
+ var/mob/new_player/lobbied = responder_candidate
+ lobbied.new_player_panel()
+ return FALSE
+
+ if(responder_candidate)
+ responder_candidate.moveToNullspace() //Nullspace it for garbage collection later.
+ return TRUE
+
+/datum/game_mode/proc/transform_fax_responder(mob/responder_candidate, sub_job)
+ //set waitfor = FALSE
+
+ if(!(sub_job in FAX_RESPONDER_JOB_LIST))
+ return FALSE
+
+ if(!responder_candidate.client) // Legacy - probably due to spawn code sync sleeps
+ log_debug("Null client attempted to transform_fax_responder")
+ return FALSE
+ if(!loaded_fax_base)
+ loaded_fax_base = SSmapping.lazy_load_template(/datum/lazy_template/fax_response_base, force = TRUE)
+ if(!loaded_fax_base)
+ log_debug("Error loading fax response base!")
+ return FALSE
+
+ responder_candidate.client.prefs.find_assigned_slot(JOB_FAX_RESPONDER)
+
+ var/turf/spawn_point = get_turf(pick(GLOB.latejoin_by_job[sub_job]))
+ var/mob/living/carbon/human/new_responder = new(spawn_point)
+ responder_candidate.mind.transfer_to(new_responder, TRUE)
+ new_responder.client?.prefs.copy_all_to(new_responder, JOB_FAX_RESPONDER, TRUE, FALSE)
+
+ var/datum/job/fax_responder_job = GLOB.RoleAuthority.roles_by_name[sub_job]
+
+ if(!fax_responder_job)
+ qdel(new_responder)
+ return FALSE
+
+ // This is usually done in assign_role, a proc which is not executed in this case, since check_fax_responder_late_join is running its own checks.
+ fax_responder_job.current_positions++
+ GLOB.RoleAuthority.equip_role(new_responder, fax_responder_job, new_responder.loc)
+ SSticker.minds += new_responder.mind
+
+ message_admins(FONT_SIZE_XL(SPAN_RED("([new_responder.key]) joined as a [sub_job], [new_responder.real_name].")))
+
+ return TRUE
+
//===================================================\\
diff --git a/code/game/gamemodes/colonialmarines/whiskey_outpost.dm b/code/game/gamemodes/colonialmarines/whiskey_outpost.dm
index 7554bb781f6d..17a96ede6b09 100644
--- a/code/game/gamemodes/colonialmarines/whiskey_outpost.dm
+++ b/code/game/gamemodes/colonialmarines/whiskey_outpost.dm
@@ -26,7 +26,7 @@
/datum/job/civilian/doctor/whiskey = JOB_DOCTOR,
/datum/job/civilian/researcher/whiskey = JOB_RESEARCHER,
/datum/job/logistics/engineering/whiskey = JOB_CHIEF_ENGINEER,
- /datum/job/logistics/tech/maint/whiskey = JOB_MAINT_TECH,
+ /datum/job/logistics/maint/whiskey = JOB_MAINT_TECH,
/datum/job/logistics/cargo/whiskey = JOB_CARGO_TECH,
/datum/job/civilian/liaison/whiskey = JOB_CORPORATE_LIAISON,
/datum/job/marine/leader/whiskey = JOB_SQUAD_LEADER,
diff --git a/code/game/gamemodes/colonialmarines/whiskey_outpost/equipping.dm b/code/game/gamemodes/colonialmarines/whiskey_outpost/equipping.dm
index d5ff07391b5e..617f957f9aec 100644
--- a/code/game/gamemodes/colonialmarines/whiskey_outpost/equipping.dm
+++ b/code/game/gamemodes/colonialmarines/whiskey_outpost/equipping.dm
@@ -189,12 +189,12 @@ Ensure power is up, and the bunker is well defended. You share your bunker crew
//*************************************
//---------------MAINT TECH-------------
//*************************************/
-/datum/job/logistics/tech/maint/whiskey
+/datum/job/logistics/maint/whiskey
title = JOB_WO_ORDNANCE_TECH
supervisors = "the bunker crew master and the quartermaster"
gear_preset = /datum/equipment_preset/wo/bc
-/datum/job/logistics/tech/maint/whiskey/generate_entry_message(mob/living/carbon/human/H)
+/datum/job/logistics/maint/whiskey/generate_entry_message(mob/living/carbon/human/H)
. = {"You've worked here for a while, figuring it was a pretty comfy job. Now you gotta fight for your life. Have fun with that.
Assist both the Bunker Crew Master and the Quartermaster in their duties."}
diff --git a/code/game/jobs/job/civilians/civilian.dm b/code/game/jobs/job/civilians/civilian.dm
index a9631f2ed9c1..86b237816217 100644
--- a/code/game/jobs/job/civilians/civilian.dm
+++ b/code/game/jobs/job/civilians/civilian.dm
@@ -7,3 +7,10 @@
/datum/timelock/medic/New(name, time_required, list/roles)
. = ..()
src.roles = JOB_MEDIC_ROLES_LIST
+
+/datum/timelock/corporate
+ name = "Corporate Roles"
+
+/datum/timelock/corporate/New(name, time_required, list/roles)
+ . = ..()
+ src.roles = JOB_CORPORATE_ROLES_LIST
diff --git a/code/game/jobs/job/special/responders.dm b/code/game/jobs/job/special/responders.dm
new file mode 100644
index 000000000000..9bc5d88b9d19
--- /dev/null
+++ b/code/game/jobs/job/special/responders.dm
@@ -0,0 +1,75 @@
+/datum/job/fax_responder
+ title = JOB_FAX_RESPONDER
+ gear_preset = /datum/equipment_preset/fax_responder
+ selection_class = "job_command"
+ supervisors = "CMSS13 Administration Staff"
+ total_positions = 1
+ spawn_positions = 1
+
+ late_joinable = FALSE
+
+ flags_startup_parameters = ROLE_ADMIN_NOTIFY|ROLE_WHITELISTED|ROLE_NO_ACCOUNT|ROLE_CUSTOM_SPAWN|ROLE_HIDDEN
+ flags_whitelist = WHITELIST_FAX_RESPONDER
+
+/datum/job/fax_responder/on_config_load()
+ entry_message_body = "Your job is to answer faxes sent to your fax machine. You are answering on behalf of the CMSS13 staff team and are therefore expected to behave appropriately. Failure to adhere to expectations may result in loss of the role or a server ban. Non-staff players of this role are not able to authorise ERTs through their faxes."
+ return ..()
+
+/datum/job/fax_responder/uscm_hc
+ title = JOB_FAX_RESPONDER_USCM_HC
+ gear_preset = /datum/equipment_preset/fax_responder/uscm
+
+AddTimelock(/datum/job/fax_responder/uscm_hc, list(
+ JOB_POLICE_ROLES = 25 HOURS,
+ JOB_COMMAND_ROLES = 75 HOURS,
+))
+
+/datum/job/fax_responder/uscm_pvst
+ title = JOB_FAX_RESPONDER_USCM_PVST
+ gear_preset = /datum/equipment_preset/fax_responder/uscm/provost
+
+AddTimelock(/datum/job/fax_responder/uscm_pvst, list(
+ JOB_POLICE_ROLES = 150 HOURS,
+ JOB_COMMAND_ROLES = 75 HOURS,
+))
+
+/datum/job/fax_responder/wy
+ title = JOB_FAX_RESPONDER_WY
+ gear_preset = /datum/equipment_preset/fax_responder/wey_yu
+
+AddTimelock(/datum/job/fax_responder/wy, list(
+ JOB_CORPORATE_ROLES = 150 HOURS,
+))
+
+/datum/job/fax_responder/upp
+ title = JOB_FAX_RESPONDER_UPP
+ gear_preset = /datum/equipment_preset/fax_responder/upp
+
+AddTimelock(/datum/job/fax_responder/upp, list(
+ JOB_COMMAND_ROLES = 75 HOURS,
+))
+
+/datum/job/fax_responder/twe
+ title = JOB_FAX_RESPONDER_TWE
+ gear_preset = /datum/equipment_preset/fax_responder/twe
+
+AddTimelock(/datum/job/fax_responder/twe, list(
+ JOB_COMMAND_ROLES = 75 HOURS,
+))
+
+/datum/job/fax_responder/clf
+ title = JOB_FAX_RESPONDER_CLF
+ gear_preset = /datum/equipment_preset/fax_responder/clf
+
+AddTimelock(/datum/job/fax_responder/clf, list(
+ JOB_COMMAND_ROLES = 75 HOURS,
+))
+
+/datum/job/fax_responder/cmb
+ title = JOB_FAX_RESPONDER_CMB
+ gear_preset = /datum/equipment_preset/fax_responder/cmb
+
+AddTimelock(/datum/job/fax_responder/cmb, list(
+ JOB_POLICE_ROLES = 75 HOURS,
+ JOB_COMMAND_ROLES = 25 HOURS,
+))
diff --git a/code/game/jobs/whitelist.dm b/code/game/jobs/whitelist.dm
index 8cd91a494c83..0c87fcbb52d0 100644
--- a/code/game/jobs/whitelist.dm
+++ b/code/game/jobs/whitelist.dm
@@ -44,8 +44,9 @@
#define WL_PANEL_RIGHT_YAUTJA (1<<2)
#define WL_PANEL_RIGHT_MENTOR (1<<3)
#define WL_PANEL_RIGHT_OVERSEER (1<<4)
+#define WL_PANEL_RIGHT_MANAGER (1<<5)
#define WL_PANEL_ALL_COUNCILS (WL_PANEL_RIGHT_CO|WL_PANEL_RIGHT_SYNTH|WL_PANEL_RIGHT_YAUTJA)
-#define WL_PANEL_ALL_RIGHTS (WL_PANEL_RIGHT_CO|WL_PANEL_RIGHT_SYNTH|WL_PANEL_RIGHT_YAUTJA|WL_PANEL_RIGHT_MENTOR|WL_PANEL_RIGHT_OVERSEER)
+#define WL_PANEL_ALL_RIGHTS (WL_PANEL_RIGHT_CO|WL_PANEL_RIGHT_SYNTH|WL_PANEL_RIGHT_YAUTJA|WL_PANEL_RIGHT_MENTOR|WL_PANEL_RIGHT_OVERSEER|WL_PANEL_RIGHT_MANAGER)
/datum/whitelist_panel
var/viewed_player = list()
@@ -68,7 +69,7 @@
if(person.check_whitelist_status(WHITELIST_YAUTJA_LEADER))
rights |= WL_PANEL_RIGHT_YAUTJA
if(rights == WL_PANEL_ALL_COUNCILS)
- return WL_PANEL_ALL_RIGHTS
+ rights |= WL_PANEL_RIGHT_OVERSEER
return rights
/datum/whitelist_panel/tgui_interact(mob/user, datum/tgui/ui)
@@ -122,6 +123,7 @@ GLOBAL_LIST_INIT(yaut_flags, list(
GLOBAL_LIST_INIT(misc_flags, list(
list(name = "Senior Enlisted Advisor", bitflag = WHITELIST_MENTOR, permission = WL_PANEL_RIGHT_MENTOR),
list(name = "Working Joe", bitflag = WHITELIST_JOE, permission = WL_PANEL_RIGHT_SYNTH),
+ list(name = "Fax Responder", bitflag = WHITELIST_FAX_RESPONDER, permission = WL_PANEL_RIGHT_MANAGER),
))
/datum/whitelist_panel/ui_static_data(mob/user)
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index ac6de251ab45..eee97c0e2ec0 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -477,7 +477,7 @@
var/datum/asset/asset = get_asset_datum(/datum/asset/simple/paper)
var/obj/item/paper/P = new /obj/item/paper( src.loc )
P.name = text("Scan: [], []",record.fields["name"],worldtime2text())
- P.info += text("
Official Weyland-Yutani Document
Scan Record
[]
\n",record.fields["name"])
+ P.info += text("
Official Weyland-Yutani Document
Scan Record
[]
\n",record.fields["name"])
for(var/datum/data/record/R as anything in GLOB.data_core.medical)
if (R.fields["name"] == record.fields["name"])
if(R.fields["last_scan_time"] && R.fields["last_scan_result"])
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index 45a57eb96392..4baaafd9eb01 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -8,7 +8,7 @@
//Used for logging people entering cryosleep and important items they are carrying.
GLOBAL_LIST_EMPTY(frozen_crew)
-GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = list(), SQUAD_MARINE_3 = list(), SQUAD_MARINE_4 = list(), "MP" = list(), "REQ" = list(), "Eng" = list(), "Med" = list(), "Yautja" = list()))
+GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = list(), SQUAD_MARINE_3 = list(), SQUAD_MARINE_4 = list(), "MP" = list(), "REQ" = list(), "Eng" = list(), "Med" = list(), "Yautja" = list(), "Responders" = list()))
//Main cryopod console.
@@ -226,12 +226,15 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li
switch(H.job)
if(JOB_POLICE, JOB_WARDEN, JOB_CHIEF_POLICE)
dept_console = GLOB.frozen_items["MP"]
- if("Nurse", "Doctor","Researcher","Chief Medical Officer")
+ if(JOB_NURSE, JOB_DOCTOR, JOB_RESEARCHER, JOB_CMO)
dept_console = GLOB.frozen_items["Med"]
- if("Maintenance Technician", "Ordnance Technician","Chief Engineer")
+ if(JOB_MAINT_TECH, JOB_ORDNANCE_TECH, JOB_CHIEF_ENGINEER)
dept_console = GLOB.frozen_items["Eng"]
- if("Predator")
+ if(JOB_PREDATOR)
dept_console = GLOB.frozen_items["Yautja"]
+ if(JOB_FAX_RESPONDER_USCM_HC, JOB_FAX_RESPONDER_USCM_PVST, JOB_FAX_RESPONDER_WY, JOB_FAX_RESPONDER_TWE, JOB_FAX_RESPONDER_UPP, JOB_FAX_RESPONDER_CLF, JOB_FAX_RESPONDER_CMB)
+ dept_console = GLOB.frozen_items["Responders"]
+
H.species.handle_cryo(H)
var/list/deleteempty = list(/obj/item/storage/backpack/marine/satchel)
@@ -254,7 +257,7 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li
item_loop:
for(var/obj/item/W in items)
- if(((W.flags_inventory & CANTSTRIP) || (W.flags_item & NODROP) || (W.flags_item & NO_CRYO_STORE)) && !isyautja(occupant)) //We don't keep donor items, undroppable/unremovable items, and specifically filtered items
+ if(((W.flags_inventory & CANTSTRIP) || (W.flags_item & NODROP) || (W.flags_item & NO_CRYO_STORE)) && !gearless_role(occupant)) //We don't keep donor items, undroppable/unremovable items, and specifically filtered items
if(istype(W, /obj/item/clothing/suit/storage))
var/obj/item/clothing/suit/storage/SS = W
for(var/obj/item/I in SS.pockets) //But we keep stuff inside them
@@ -359,7 +362,7 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li
//Make an announcement and log the person entering storage.
GLOB.frozen_crew += "[occupant.real_name] ([occupant.job])"
- if(!isyautja(occupant))
+ if(!gearless_role(occupant))
ai_silent_announcement("[occupant.real_name], [occupant.job], has entered long-term hypersleep storage. Belongings moved to hypersleep inventory.")
visible_message(SPAN_NOTICE("[src] hums and hisses as it moves [occupant.real_name] into hypersleep storage."))
@@ -539,6 +542,13 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li
move_inside(target)
+/obj/structure/machinery/cryopod/proc/gearless_role(mob/occupant)
+ if(isyautja(occupant))
+ return TRUE
+ if(occupant.job in FAX_RESPONDER_JOB_LIST)
+ return TRUE
+ return FALSE
+
/obj/structure/machinery/cryopod/tutorial
silent_exit = TRUE
diff --git a/code/game/machinery/fax_machine.dm b/code/game/machinery/fax_machine.dm
index b15117bb2554..2c5addb5e6d6 100644
--- a/code/game/machinery/fax_machine.dm
+++ b/code/game/machinery/fax_machine.dm
@@ -1,5 +1,6 @@
-GLOBAL_LIST_INIT_TYPED(allfaxes, /obj/structure/machinery/faxmachine, list())
-GLOBAL_LIST_EMPTY(alldepartments)
+GLOBAL_LIST_INIT_TYPED(all_faxmachines, /obj/structure/machinery/faxmachine, list())
+GLOBAL_LIST_EMPTY(all_fax_departments)
+GLOBAL_LIST_EMPTY(all_faxcodes)
#define DEPARTMENT_WY "Weyland-Yutani"
#define DEPARTMENT_HC "USCM High Command"
@@ -9,8 +10,23 @@ GLOBAL_LIST_EMPTY(alldepartments)
#define DEPARTMENT_TWE "Three World Empire"
#define DEPARTMENT_UPP "Union of Progress Peoples"
#define DEPARTMENT_CLF "Colonial Liberation Front"
+#define DEPARTMENT_TARGET "Specific Machine Code"//Used to send to a single specific machine.
#define HIGHCOM_DEPARTMENTS list(DEPARTMENT_WY, DEPARTMENT_HC, DEPARTMENT_CMB, DEPARTMENT_PROVOST, DEPARTMENT_PRESS, DEPARTMENT_TWE, DEPARTMENT_UPP, DEPARTMENT_CLF)
+#define FAX_NET_USCM "USCM Encrypted Network"
+#define FAX_NET_USCM_HC "USCM High Command Quantum Relay"
+#define FAX_NET_WY "Weyland-Yutani Secure Network"
+#define FAX_NET_WY_COL "Weyland-Yutani Public Network"
+#define FAX_NET_WY_HC "Weyland-Yutani Quantum Relay"
+#define FAX_NET_CMB "NC4 UA Federal Secure Network - CMB Relay"
+#define FAX_NET_TWE "TWE Encrypted Network"
+#define FAX_NET_TWE_HC "TWE Imperial Command Quantum Relay"
+#define FAX_NET_UPP "UPP Encrypted Network"
+#define FAX_NET_UPP_HC "UPP High Command Quantum Relay"
+#define FAX_NET_CLF "Peridia Encrypted Network"
+#define FAX_NET_CLF_HC "Peridia Quantum Relay"
+#define FAX_HC_NETWORKS list(FAX_NET_USCM_HC, FAX_NET_WY_HC, FAX_NET_CMB, FAX_NET_TWE_HC, FAX_NET_UPP_HC, FAX_NET_CLF_HC)
+
/obj/structure/machinery/faxmachine // why not fax_machine?
name = "\improper General Purpose Fax Machine"
icon = 'icons/obj/structures/machinery/library.dmi'
@@ -35,24 +51,73 @@ GLOBAL_LIST_EMPTY(alldepartments)
///Target department
var/target_department = DEPARTMENT_WY
+ var/target_machine_id = "No ID Selected"
// list for img and their photo reference to be stored into the admin's cache.
var/list/photo_list = list()
///Fluff network shown by fax machine when logged in
- var/network = "Weyland-Yutani Public Network"
+ var/network = FAX_NET_WY_COL
///storer var for cooldown on sending faxes
var/fax_cooldown = 300
COOLDOWN_DECLARE(send_cooldown)
+ var/machine_id_tag
+
/obj/structure/machinery/faxmachine/Initialize(mapload, ...)
. = ..()
- GLOB.allfaxes += src
+ GLOB.all_faxmachines += src
update_departments()
+ generate_id_tag()
+
+/obj/structure/machinery/faxmachine/proc/generate_id_tag()
+ if(machine_id_tag)
+ GLOB.all_faxcodes -= machine_id_tag
+
+ var/id_tag_prefix
+ var/id_tag_suffix = "[rand(1000, 9999)][pick(GLOB.alphabet_uppercase)][pick(GLOB.alphabet_uppercase)]"
+ var/id_tag_final
+ switch(network)
+ if(FAX_NET_USCM)
+ id_tag_prefix = "UA-M"//United Americas Military
+ if(FAX_NET_USCM_HC)
+ id_tag_final = FAX_NET_USCM_HC
+ if(FAX_NET_CMB)
+ id_tag_final = FAX_NET_CMB
+ if(FAX_NET_WY)
+ id_tag_prefix = "WY-SCN"//Weyland Yutani Secure Corporate Network
+ if(FAX_NET_WY_COL)
+ id_tag_prefix = "WYC"//Weyland Yutani Communications
+ if(FAX_NET_WY_HC)
+ id_tag_final = FAX_NET_WY_HC
+ if(FAX_NET_TWE)
+ id_tag_prefix = "ICN"//Imperial Communication Network
+ if(FAX_NET_TWE_HC)
+ id_tag_final = FAX_NET_TWE_HC
+ if(FAX_NET_UPP)
+ id_tag_prefix = "UFR"//Union Fax Relay
+ if(FAX_NET_UPP_HC)
+ id_tag_final = FAX_NET_UPP_HC
+ if(FAX_NET_CLF)
+ id_tag_prefix = "PRD"//PeRiDia
+ if(FAX_NET_CLF_HC)
+ id_tag_final = FAX_NET_CLF_HC
+
+ if(!id_tag_final)
+ id_tag_final = "[id_tag_prefix]-[id_tag_suffix]"
+ if(id_tag_final in GLOB.all_faxcodes)
+ generate_id_tag()
+ return FALSE
+
+ machine_id_tag = id_tag_final
+ if(machine_id_tag == network)
+ return TRUE
+ GLOB.all_faxcodes += id_tag_final
+ return TRUE
/obj/structure/machinery/faxmachine/Destroy()
- GLOB.allfaxes -= src
+ GLOB.all_faxmachines -= src
. = ..()
/obj/structure/machinery/faxmachine/initialize_pass_flags(datum/pass_flags_container/PF)
@@ -129,24 +194,26 @@ GLOBAL_LIST_EMPTY(alldepartments)
return
/obj/structure/machinery/faxmachine/proc/update_departments()
- if( !("[department]" in GLOB.alldepartments) ) //Initialize departments. This will work with multiple fax machines.
- GLOB.alldepartments += department
- if(!(DEPARTMENT_WY in GLOB.alldepartments))
- GLOB.alldepartments += DEPARTMENT_WY
- if(!(DEPARTMENT_HC in GLOB.alldepartments))
- GLOB.alldepartments += DEPARTMENT_HC
- if(!(DEPARTMENT_PROVOST in GLOB.alldepartments))
- GLOB.alldepartments += DEPARTMENT_PROVOST
- if(!(DEPARTMENT_CMB in GLOB.alldepartments))
- GLOB.alldepartments += DEPARTMENT_CMB
- if(!(DEPARTMENT_PRESS in GLOB.alldepartments))
- GLOB.alldepartments += DEPARTMENT_PRESS
- if(!(DEPARTMENT_TWE in GLOB.alldepartments))
- GLOB.alldepartments += DEPARTMENT_TWE
- if(!(DEPARTMENT_UPP in GLOB.alldepartments))
- GLOB.alldepartments += DEPARTMENT_UPP
- if(!(DEPARTMENT_CLF in GLOB.alldepartments))
- GLOB.alldepartments += DEPARTMENT_CLF
+ if(!(DEPARTMENT_TARGET in GLOB.all_fax_departments))
+ GLOB.all_fax_departments += DEPARTMENT_TARGET
+ if( !("[department]" in GLOB.all_fax_departments) ) //Initialize departments. This will work with multiple fax machines.
+ GLOB.all_fax_departments += department
+ if(!(DEPARTMENT_WY in GLOB.all_fax_departments))
+ GLOB.all_fax_departments += DEPARTMENT_WY
+ if(!(DEPARTMENT_HC in GLOB.all_fax_departments))
+ GLOB.all_fax_departments += DEPARTMENT_HC
+ if(!(DEPARTMENT_PROVOST in GLOB.all_fax_departments))
+ GLOB.all_fax_departments += DEPARTMENT_PROVOST
+ if(!(DEPARTMENT_CMB in GLOB.all_fax_departments))
+ GLOB.all_fax_departments += DEPARTMENT_CMB
+ if(!(DEPARTMENT_PRESS in GLOB.all_fax_departments))
+ GLOB.all_fax_departments += DEPARTMENT_PRESS
+ if(!(DEPARTMENT_TWE in GLOB.all_fax_departments))
+ GLOB.all_fax_departments += DEPARTMENT_TWE
+ if(!(DEPARTMENT_UPP in GLOB.all_fax_departments))
+ GLOB.all_fax_departments += DEPARTMENT_UPP
+ if(!(DEPARTMENT_CLF in GLOB.all_fax_departments))
+ GLOB.all_fax_departments += DEPARTMENT_CLF
// TGUI SHIT \\
@@ -169,6 +236,7 @@ GLOBAL_LIST_EMPTY(alldepartments)
data["department"] = department
data["network"] = network
+ data["machine_id_tag"] = machine_id_tag
return data
@@ -181,7 +249,10 @@ GLOBAL_LIST_EMPTY(alldepartments)
data["paper_name"] = original_fax.name
data["authenticated"] = authenticated
+
data["target_department"] = target_department
+ if(target_department == DEPARTMENT_TARGET)
+ data["target_department"] = target_machine_id
data["worldtime"] = world.time
data["nextfaxtime"] = send_cooldown
@@ -266,8 +337,15 @@ GLOBAL_LIST_EMPTY(alldepartments)
if("select")
var/last_target_department = target_department
- target_department = tgui_input_list(ui.user, "Which department?", "Choose a department", GLOB.alldepartments)
- if(!target_department) target_department = last_target_department
+ target_department = tgui_input_list(ui.user, "Which department?", "Choose a department", GLOB.all_fax_departments)
+ if(!target_department)
+ target_department = last_target_department
+ if(target_department == DEPARTMENT_TARGET)
+ var/new_target_machine_id = tgui_input_list(ui.user, "Which machine?", "Choose a machine code", GLOB.all_faxcodes)
+ if(!new_target_machine_id)
+ target_department = last_target_department
+ else
+ target_machine_id = new_target_machine_id
. = TRUE
if("auth")
@@ -335,10 +413,13 @@ GLOBAL_LIST_EMPTY(alldepartments)
GLOB.fax_contents += faxcontents
var/scan_department = target_department
+ var/the_target_department = target_department
if(department in HIGHCOM_DEPARTMENTS)
scan_department = department
+ else if(target_department == DEPARTMENT_TARGET)
+ the_target_department = "Fax Machine [target_machine_id]"
- var/msg_admin = SPAN_STAFF_IC("[target_department]: [key_name(user, 1)] ")
+ var/msg_admin = SPAN_STAFF_IC("[the_target_department]: [key_name(user, 1)] ")
msg_admin += "[CC_MARK(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_JMP_USER(user)] "
switch(scan_department)
@@ -372,7 +453,7 @@ GLOBAL_LIST_EMPTY(alldepartments)
msg_admin += SPAN_STAFF_IC("Receiving fax via secure connection ... view message")
- var/msg_ghost = SPAN_NOTICE("[target_department]: ")
+ var/msg_ghost = SPAN_NOTICE("[the_target_department]: ")
msg_ghost += "Receiving fax via secure connection ... view message"
send_fax(faxcontents)
@@ -404,80 +485,73 @@ GLOBAL_LIST_EMPTY(alldepartments)
/obj/structure/machinery/faxmachine/proc/send_fax(datum/fax/faxcontents)
- for(var/obj/structure/machinery/faxmachine/F in GLOB.allfaxes)
- if(F != src && F.department == target_department)
- if(!faxcontents)
- return
- if(! (F.inoperable() ) )
-
- flick("[initial(icon_state)]receive", F)
-
- // give the sprite some time to flick
- spawn(30)
- var/obj/item/paper/P = new(F.loc,faxcontents.photo_list)
- P.name = "faxed message"
- P.info = "[faxcontents.data]"
- P.update_icon()
-
- switch(network)
- if("USCM High Command Quantum Relay")
- var/image/stampoverlay = image('icons/obj/items/paper.dmi')
- stampoverlay.icon_state = "paper_stamp-uscm"
- P.stamps += "
This paper has been stamped by the USCM High Command Quantum Relay."
- if("NC4 UA Federal Secure Network - CMB Relay")
- var/image/stampoverlay = image('icons/obj/items/paper.dmi')
- stampoverlay.icon_state = "paper_stamp-cmb"
- if(!P.stamped)
- P.stamped = new
- P.stamped += /obj/item/tool/stamp
- P.overlays += stampoverlay
- P.stamps += "
This paper has been stamped by The Office of Colonial Marshals."
- if("Weyland-Yutani Quantum Relay")
- var/image/stampoverlay = image('icons/obj/items/paper.dmi')
- stampoverlay.icon_state = "paper_stamp-weyyu"
- if(!P.stamped)
- P.stamped = new
- P.stamped += /obj/item/tool/stamp
- P.overlays += stampoverlay
- P.stamps += "
This paper has been stamped and encrypted by the Weyland-Yutani Quantum Relay (tm)."
- if("TWE Royal Marines Commando Quantum Relay")
- var/image/stampoverlay = image('icons/obj/items/paper.dmi')
- stampoverlay.icon_state = "paper_stamp-twe"
- if(!P.stamped)
- P.stamped = new
- P.stamped += /obj/item/tool/stamp
- P.overlays += stampoverlay
- P.stamps += "
This paper has been stamped by the TWE Royal Marines Commando Quantum Relay."
- if("UPP High Kommand Quantum Relay")
- var/image/stampoverlay = image('icons/obj/items/paper.dmi')
- stampoverlay.icon_state = "paper_stamp-upp"
- if(!P.stamped)
- P.stamped = new
- P.stamped += /obj/item/tool/stamp
- P.overlays += stampoverlay
- P.stamps += "
This paper has been stamped by the UPP High Kommand Quantum Relay."
- if("CLF Gureilla Command Quantum Relay")
- var/image/stampoverlay = image('icons/obj/items/paper.dmi')
- stampoverlay.icon_state = "paper_stamp-clf"
- if(!P.stamped)
- P.stamped = new
- P.stamped += /obj/item/tool/stamp
- P.overlays += stampoverlay
- P.stamps += "
This paper has been stamped and encrypted by the CLF Gureilla Command Quantum Relay."
-
- playsound(F.loc, "sound/items/polaroid1.ogg", 15, 1)
+ var/list/target_machines = list()
+ for(var/obj/structure/machinery/faxmachine/pos_target in GLOB.all_faxmachines)
+ if(target_department == DEPARTMENT_TARGET)
+ if(pos_target != src && pos_target.machine_id_tag == target_machine_id)
+ target_machines += pos_target
+ else
+ if(pos_target != src && pos_target.department == target_department)
+ target_machines += pos_target
+
+ for(var/obj/structure/machinery/faxmachine/target in target_machines)
+ if(!faxcontents)
+ return
+ if(!(target.inoperable()))
+
+ flick("[initial(icon_state)]receive", target)
+
+ // give the sprite some time to flick
+ spawn(30)
+ var/obj/item/paper/P = new(target.loc,faxcontents.photo_list)
+ P.name = "faxed message"
+ P.info = "[faxcontents.data]"
+ P.update_icon()
+ var/image/stampoverlay = image('icons/obj/items/paper.dmi')
+ var/encrypted = FALSE
+
+ switch(network)
+ if(FAX_NET_USCM_HC)
+ stampoverlay.icon_state = "paper_stamp-uscm"
+ encrypted = TRUE
+ if(FAX_NET_CMB)
+ stampoverlay.icon_state = "paper_stamp-cmb"
+ network = "NC4 UA Federal Secure Network."
+ encrypted = TRUE
+ if(FAX_NET_WY_HC)
+ stampoverlay.icon_state = "paper_stamp-weyyu"
+ encrypted = TRUE
+ if(FAX_NET_TWE_HC)
+ stampoverlay.icon_state = "paper_stamp-twe"
+ encrypted = TRUE
+ if(FAX_NET_UPP_HC)
+ stampoverlay.icon_state = "paper_stamp-upp"
+ encrypted = TRUE
+ if(FAX_NET_CLF_HC)
+ stampoverlay.icon_state = "paper_stamp-clf"
+ encrypted = TRUE
+
+
+ if(encrypted)
+ if(!P.stamped)
+ P.stamped = new
+ P.stamped += /obj/item/tool/stamp
+ P.overlays += stampoverlay
+ P.stamps += "
This paper has been stamped and encrypted by the [network]."
+ else
+ P.stamps += "
This paper has been sent by [machine_id_tag]."
+ playsound(target.loc, "sound/items/polaroid1.ogg", 15, 1)
qdel(faxcontents)
/obj/structure/machinery/faxmachine/cmb
name = "\improper CMB Incident Command Center Fax Machine"
- department = "Colonial Marshal Bureau, Anchorpoint Station"
- network = "NC4 UA Federal Secure Network - CMB Relay"
+ network = FAX_NET_CMB
department = DEPARTMENT_CMB
/obj/structure/machinery/faxmachine/corporate
name = "\improper W-Y Corporate Fax Machine"
department = "W-Y Local Office"
- network = "Weyland-Yutani Secure Network"
+ network = FAX_NET_WY
/obj/structure/machinery/faxmachine/corporate/liaison
department = "W-Y Liaison"
@@ -485,12 +559,12 @@ GLOBAL_LIST_EMPTY(alldepartments)
/obj/structure/machinery/faxmachine/corporate/highcom
department = DEPARTMENT_WY
target_department = "W-Y Liaison"
- network = "Weyland-Yutani Quantum Relay"
+ network = FAX_NET_WY_HC
/obj/structure/machinery/faxmachine/uscm
name = "\improper USCM Military Fax Machine"
department = "USCM Local Operations"
- network = "USCM Encrypted Network"
+ network = FAX_NET_USCM
target_department = DEPARTMENT_HC
/obj/structure/machinery/faxmachine/uscm/command
@@ -502,7 +576,7 @@ GLOBAL_LIST_EMPTY(alldepartments)
/obj/structure/machinery/faxmachine/uscm/command/highcom
department = DEPARTMENT_HC
target_department = "Commanding Officer"
- network = "USCM High Command Quantum Relay"
+ network = FAX_NET_USCM_HC
/obj/structure/machinery/faxmachine/uscm/brig
name = "\improper USCM Provost Fax Machine"
@@ -515,8 +589,40 @@ GLOBAL_LIST_EMPTY(alldepartments)
/obj/structure/machinery/faxmachine/uscm/brig/provost
department = DEPARTMENT_PROVOST
target_department = "Brig"
- network = "USCM High Command Quantum Relay"
-
+ network = FAX_NET_USCM_HC
+
+/obj/structure/machinery/faxmachine/upp
+ name = "\improper UPP Military Fax Machine"
+ department = "UPP Local Operations"
+ network = FAX_NET_UPP
+ target_department = DEPARTMENT_UPP
+
+/obj/structure/machinery/faxmachine/upp/highcom
+ department = DEPARTMENT_UPP
+ network = FAX_NET_UPP_HC
+ target_department = "UPP Local Operations"
+
+/obj/structure/machinery/faxmachine/clf
+ name = "\improper Hacked General Purpose Fax Machine"
+ department = "CLF Local Operations"
+ network = FAX_NET_CLF
+ target_department = DEPARTMENT_CLF
+
+/obj/structure/machinery/faxmachine/clf/highcom
+ department = DEPARTMENT_CLF
+ network = FAX_NET_CLF_HC
+ target_department = "CLF Local Operations"
+
+/obj/structure/machinery/faxmachine/twe
+ name = "\improper TWE Military Fax Machine"
+ department = "TWE Local Operations"
+ network = FAX_NET_TWE
+ target_department = DEPARTMENT_TWE
+
+/obj/structure/machinery/faxmachine/twe/highcom
+ department = DEPARTMENT_TWE
+ network = FAX_NET_TWE_HC
+ target_department = "TWE Local Operations"
///The deployed fax machine backpack
/obj/structure/machinery/faxmachine/backpack
diff --git a/code/game/machinery/vending/vending_types.dm b/code/game/machinery/vending/vending_types.dm
index 85d08641bfdf..f9734a04bcc6 100644
--- a/code/game/machinery/vending/vending_types.dm
+++ b/code/game/machinery/vending/vending_types.dm
@@ -442,7 +442,7 @@
/obj/item/tool/pen = 10,
/obj/item/tool/pen/blue = 10,
/obj/item/tool/pen/red = 10,
- /obj/item/tool/pen/fountain = 3,
+ /obj/item/tool/pen/multicolor/fountain = 3,
/obj/item/storage/fancy/cigarettes/trading_card = 20,
/obj/item/storage/fancy/trading_card = 20,
/obj/item/toy/trading_card = 50,
@@ -473,7 +473,7 @@
/obj/item/tool/pen = 2,
/obj/item/tool/pen/blue = 2,
/obj/item/tool/pen/red = 2,
- /obj/item/tool/pen/fountain = 30,
+ /obj/item/tool/pen/multicolor/fountain = 30,
/obj/item/storage/fancy/cigarettes/trading_card = 30,
/obj/item/storage/fancy/trading_card = 20,
/obj/item/toy/trading_card = 5,
diff --git a/code/game/objects/effects/landmarks/landmarks.dm b/code/game/objects/effects/landmarks/landmarks.dm
index f5f0e0b50c05..4988e60e0014 100644
--- a/code/game/objects/effects/landmarks/landmarks.dm
+++ b/code/game/objects/effects/landmarks/landmarks.dm
@@ -321,10 +321,10 @@
job = /datum/job/logistics/engineering/whiskey
/obj/effect/landmark/start/whiskey/maint
- job = /datum/job/logistics/tech/maint/whiskey
+ job = /datum/job/logistics/maint/whiskey
/obj/effect/landmark/start/whiskey/tech
- job = /datum/job/logistics/tech //Need to create a WO variant in the future
+ job = /datum/job/logistics/otech //Need to create a WO variant in the future
//****************************************** MILITARY POLICE- HONOR-GUARD ************************************************/
/obj/effect/landmark/start/whiskey/warrant
@@ -452,6 +452,35 @@
GLOB.latejoin -= src
return ..()
+
+/obj/effect/landmark/late_join/responder/uscm
+ name = "USCM HC Fax Responder late join"
+ job = JOB_FAX_RESPONDER_USCM_HC
+
+/obj/effect/landmark/late_join/responder/uscm/provost
+ name = "USCM Provost Fax Responder late join"
+ job = JOB_FAX_RESPONDER_USCM_PVST
+
+/obj/effect/landmark/late_join/responder/wey_yu
+ name = "W-Y Fax Responder late join"
+ job = JOB_FAX_RESPONDER_WY
+
+/obj/effect/landmark/late_join/responder/upp
+ name = "UPP Fax Responder late join"
+ job = JOB_FAX_RESPONDER_UPP
+
+/obj/effect/landmark/late_join/responder/twe
+ name = "TWE Fax Responder late join"
+ job = JOB_FAX_RESPONDER_TWE
+
+/obj/effect/landmark/late_join/responder/clf
+ name = "CLF Fax Responder late join"
+ job = JOB_FAX_RESPONDER_CLF
+
+/obj/effect/landmark/late_join/responder/cmb
+ name = "CMB Fax Responder late join"
+ job = JOB_FAX_RESPONDER_CMB
+
//****************************************** STATIC COMMS ************************************************//
/obj/effect/landmark/static_comms
name = "static comms"
diff --git a/code/game/objects/effects/spawners/random.dm b/code/game/objects/effects/spawners/random.dm
index 388e9f289cd7..8df88e607efa 100644
--- a/code/game/objects/effects/spawners/random.dm
+++ b/code/game/objects/effects/spawners/random.dm
@@ -203,7 +203,7 @@
/obj/item/storage/belt/champion,\
/obj/item/tool/soap/deluxe,\
/obj/item/tool/pickaxe/silver,\
- /obj/item/tool/pen/invisible,\
+ /obj/item/tool/pen/white,\
/obj/item/explosive/grenade/smokebomb,\
/obj/item/corncob,\
/obj/item/poster,\
diff --git a/code/game/objects/items/gift_wrappaper.dm b/code/game/objects/items/gift_wrappaper.dm
index ea2c19639b7a..4009cf2a172f 100644
--- a/code/game/objects/items/gift_wrappaper.dm
+++ b/code/game/objects/items/gift_wrappaper.dm
@@ -72,7 +72,7 @@
/obj/item/storage/belt/champion,
/obj/item/tool/soap/deluxe,
/obj/item/tool/pickaxe/silver,
- /obj/item/tool/pen/invisible,
+ /obj/item/tool/pen/white,
/obj/item/explosive/grenade/smokebomb,
/obj/item/corncob,
/obj/item/poster,
diff --git a/code/game/objects/items/tools/misc_tools.dm b/code/game/objects/items/tools/misc_tools.dm
index b016f0e67b33..afa7ad0d2a41 100644
--- a/code/game/objects/items/tools/misc_tools.dm
+++ b/code/game/objects/items/tools/misc_tools.dm
@@ -58,10 +58,10 @@
if(isturf(A))
to_chat(user, SPAN_WARNING("The label won't stick to that."))
return
- if(istype(A, /obj/item/storage/pill_bottle))
+ if(istype(A, /obj/item/storage/pill_bottle))
var/obj/item/storage/pill_bottle/target_pill_bottle = A
target_pill_bottle.choose_color(user)
-
+
if(!label || !length(label))
remove_label(A, user)
return
@@ -186,6 +186,16 @@
if(on)
overlays += "+[pen_color]_tip"
+/obj/item/tool/pen/attack(mob/M as mob, mob/user as mob)
+ if(!ismob(M))
+ return
+ to_chat(user, SPAN_WARNING("You stab [M] with the pen."))
+ M.last_damage_data = create_cause_data(initial(name), user)
+ M.attack_log += text("\[[time_stamp()]\] Has been stabbed with [name] by [key_name(user)]")
+ user.attack_log += text("\[[time_stamp()]\] Used the [name] to stab [key_name(M)]")
+ msg_admin_attack("[key_name(user)] Used the [name] to stab [key_name(M)] in [get_area(user)] ([user.loc.x],[user.loc.y],[user.loc.z]).", user.loc.x, user.loc.y, user.loc.z)
+ return
+
/obj/item/tool/pen/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
if(!isobj(target))
@@ -275,77 +285,78 @@
name = "WY green pen"
clicky = TRUE
-/obj/item/tool/pen/invisible
- desc = "It's an invisible pen marker."
+/obj/item/tool/pen/white
+ desc = "It's a rare white ink pen."
pen_color = "white"
-/obj/item/tool/pen/fountain
+/obj/item/tool/pen/white/clicky
+ desc = "It's a WY brand extra clicky white ink pen."
+ name = "WY white pen"
+ clicky = TRUE
+
+/obj/item/tool/pen/multicolor
+ name = "multicolor pen"
+ desc = "A color switching pen!"
+ var/list/colour_list = list("red", "blue", "black")
+ var/current_colour_index = 1
+
+/obj/item/tool/pen/multicolor/attack_self(mob/living/carbon/human/user)
+ if(on)
+ current_colour_index = (current_colour_index % length(colour_list)) + 1
+ pen_color = colour_list[current_colour_index]
+ balloon_alert(user,"you twist the pen and change the ink color to [pen_color].")
+ if(clicky)
+ playsound(user.loc, 'sound/items/pen_click_on.ogg', 100, 1, 5)
+ update_pen_state()
+ else
+ ..()
+
+/obj/item/tool/pen/multicolor/fountain
desc = "A lavish testament to the ingenuity of ARMAT's craftsmanship, this fountain pen is a paragon of design and functionality. Detailed with golden accents and intricate mechanics, the pen allows for a swift change between a myriad of ink colors with a simple twist. A product of precision engineering, each mechanism inside the pen is designed to provide a seamless, effortless transition from one color to the next, creating an instrument of luxurious versatility."
desc_lore = "More than just a tool for writing, ARMAT's fountain pen is a symbol of distinction and authority within the ranks of the United States Colonial Marine Corps (USCM). It is a legacy item, exclusively handed out to the top-tier command personnel, each pen a tribute to the recipient's leadership and dedication.\n \nARMAT, renowned for their weapons technology, took a different approach in crafting this piece. The fountain pen, though seemingly a departure from their usual field, is deeply ingrained with the company's engineering philosophy, embodying precision, functionality, and robustness.\n \nThe golden accents are not mere embellishments; they're an identifier, setting apart these pens and their owners from the rest. The gold is meticulously alloyed with a durable metallic substance, granting it resilience to daily wear and tear. Such resilience is symbolic of the tenacity and perseverance required of USCM command personnel.\n \nEach pen is equipped with an intricate color changing mechanism, allowing the user to switch between various ink colors. This feature, inspired by the advanced targeting systems of ARMAT's weaponry, uses miniaturized actuators and precision-ground components to smoothly transition the ink flow. A simple twist of the pen's body activates the change, rotating the internal ink cartridges into place with mechanical grace, ready for the user's command.\n \nThe ink colors are not chosen arbitrarily. Each represents a different echelon within the USCM, allowing the pen's owner to write in the hue that corresponds with their rank or the rank of the recipient of their written orders. This acts as a silent testament to the authority of their words, as if each stroke of the pen echoes through the halls of USCM authority.\n \nDespite its ornate appearance, the pen is as robust as any ARMAT weapon, reflecting the company's commitment to reliability and durability. The metal components are corrosion-resistant, ensuring the pen's longevity, even under the challenging conditions often faced by USCM high command.\n \nThe fusion of luxury and utility, the blend of gold and metal, is an embodiment of the hard-won elegance of command, of the fusion between power and grace. It's more than a writing instrument - it's an emblem of leadership, an accolade to the dedication and strength of those who bear it. ARMAT's fountain pen stands as a monument to the precision, integrity, and courage embodied by the USCM's highest-ranking officers."
name = "fountain pen"
icon_state = "fountain_pen"
item_state = "fountain_pen"
matter = list("metal" = 20, "gold" = 10)
- var/static/list/color_list = list("red", "blue", "green", "yellow", "purple", "pink", "brown", "black", "orange") // Can add more colors as required
- var/current_color_index = 1
+ colour_list = list("red", "blue", "green", "yellow", "purple", "pink", "brown", "black", "orange") // Can add more colors as required
var/owner_name
-/obj/item/tool/pen/fountain/pickup(mob/user, silent)
+/obj/item/tool/pen/multicolor/fountain/pickup(mob/user, silent)
. = ..()
if(!owner_name)
RegisterSignal(user, COMSIG_POST_SPAWN_UPDATE, PROC_REF(set_owner), override = TRUE)
///Sets the owner of the pen to who it spawns with, requires var/source for signals
-/obj/item/tool/pen/fountain/proc/set_owner(datum/source)
+/obj/item/tool/pen/multicolor/fountain/proc/set_owner(datum/source)
SIGNAL_HANDLER
UnregisterSignal(source, COMSIG_POST_SPAWN_UPDATE)
var/mob/living/carbon/human/user = source
owner_name = user.name
-/obj/item/tool/pen/fountain/get_examine_text(mob/user)
+/obj/item/tool/pen/multicolor/fountain/get_examine_text(mob/user)
. = ..()
if(owner_name)
. += "There's a laser engraving of [owner_name] on it."
-/obj/item/tool/pen/fountain/attack_self(mob/living/carbon/human/user)
- if(on)
- current_color_index = (current_color_index % length(color_list)) + 1
- pen_color = color_list[current_color_index]
- balloon_alert(user,"you twist the pen and change the ink color to [pen_color].")
- if(clicky)
- playsound(user.loc, 'sound/items/pen_click_on.ogg', 100, 1, 5)
- update_pen_state()
- else
- ..()
-
-/obj/item/tool/pen/attack(mob/M as mob, mob/user as mob)
- if(!ismob(M))
- return
- to_chat(user, SPAN_WARNING("You stab [M] with the pen."))
-// to_chat(M, SPAN_WARNING("You feel a tiny prick!")) //That's a whole lot of meta!
- M.last_damage_data = create_cause_data(initial(name), user)
- M.attack_log += text("\[[time_stamp()]\] Has been stabbed with [name] by [key_name(user)]")
- user.attack_log += text("\[[time_stamp()]\] Used the [name] to stab [key_name(M)]")
- msg_admin_attack("[key_name(user)] Used the [name] to stab [key_name(M)] in [get_area(user)] ([user.loc.x],[user.loc.y],[user.loc.z]).", user.loc.x, user.loc.y, user.loc.z)
- return
-
+/obj/item/tool/pen/multicolor/provost
+ name = "provost pen"
+ desc = "A sleek black shell pen with the Provost Office sigil engraved into the side. It can change colors as needed for various functions within the Provost and Military Police."
+ icon_state = "provost_pen"
+ colour_list = list("blue", "green", "black", "orange", "red", "white")
/*
- * Sleepy Pens
+ * Antag pens
*/
/obj/item/tool/pen/sleepypen
desc = "It's a black ink pen with a sharp point and a carefully engraved \"Waffle Co.\""
flags_atom = FPRINT|OPENCONTAINER
flags_equip_slot = SLOT_WAIST
-
-
/obj/item/tool/pen/sleepypen/Initialize()
. = ..()
create_reagents(30)
reagents.add_reagent("chloralhydrate", 22)
-
/obj/item/tool/pen/sleepypen/attack(mob/M as mob, mob/user as mob)
if(!(istype(M,/mob)))
return
@@ -354,16 +365,10 @@
if(M.reagents) reagents.trans_to(M, 50)
return
-
-/*
- * Parapens
- */
/obj/item/tool/pen/paralysis
flags_atom = FPRINT|OPENCONTAINER
flags_equip_slot = SLOT_WAIST
-
-
/obj/item/tool/pen/paralysis/attack(mob/living/M as mob, mob/user as mob)
if(!(istype(M)))
return
@@ -378,6 +383,9 @@
reagents.add_reagent("zombiepowder", 10)
reagents.add_reagent("cryptobiolin", 15)
+/*
+ * Stamps
+ */
/obj/item/tool/stamp
name = "rubber stamp"
desc = "A rubber stamp for stamping important documents."
diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm
index 8974eb36187f..fc5744dcbbf1 100644
--- a/code/game/supplyshuttle.dm
+++ b/code/game/supplyshuttle.dm
@@ -1141,7 +1141,7 @@ GLOBAL_DATUM_INIT(supply_controller, /datum/controller/supply, new())
temp += "Back to all categories
"
temp += SPAN_DANGER("ERR0R UNK7OWN C4T2G#!$0-
")
if(black_market_lockout)
- temp += "Unauthorized Access Removed.
This console is currently under CMB investigation.
Thank you for your cooperation. "
+ temp += "Unauthorized Access Removed.
This console is currently under CMB investigation.
Thank you for your cooperation. "
return
temp += "KHZKNHZH#0-"
if(!GLOB.supply_controller.mendoza_status) // he's daed
diff --git a/code/modules/admin/fax_templates.dm b/code/modules/admin/fax_templates.dm
index 2522acf92b3b..210915a3f7b8 100644
--- a/code/modules/admin/fax_templates.dm
+++ b/code/modules/admin/fax_templates.dm
@@ -7,7 +7,7 @@
dat += "body {"
dat += "margin:0 auto;"
dat += "padding:0;"
- dat += "background-image: url('[asset.get_url_mappings()["faxbackground.jpg"]]');"
+ dat += "background-image: url('[asset.get_url_mappings()["background_white.jpg"]]');"
dat += "font-family: monospace;"
dat += "}"
@@ -65,7 +65,7 @@
if(show_wy_logo)
dat += ""
- dat += "
"
+ dat += "
"
dat += "
"
dat += "