From f6af059a0619a22fa5d1a660a70a97e57e382b65 Mon Sep 17 00:00:00 2001 From: Metis <100518708+sheepishgoat@users.noreply.github.com> Date: Sat, 2 Nov 2024 03:16:16 -0400 Subject: [PATCH] job titles --- code/__HELPERS/game.dm | 5 +- code/controllers/subsystem/job.dm | 5 +- code/datums/datacore.dm | 10 +- code/game/machinery/announcement_system.dm | 15 +-- code/modules/client/preferences.dm | 28 ++++- code/modules/client/preferences_savefile.dm | 9 ++ code/modules/jobs/job_titles.dm | 109 ++++++++++++++++++ code/modules/jobs/job_types/_job.dm | 15 ++- code/modules/jobs/job_types/captain.dm | 5 +- .../modules/mob/dead/new_player/new_player.dm | 3 + tgstation.dme | 1 + 11 files changed, 189 insertions(+), 16 deletions(-) create mode 100644 code/modules/jobs/job_titles.dm diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index e177fa2860..cb68fe61fd 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -581,8 +581,11 @@ if((character.mind.assigned_role == "Cyborg") || (character.mind.assigned_role == character.mind.special_role)) return + var/displayed_rank = rank + if(character.client && character.client.prefs && character.client?.prefs?.alt_titles_preferences[rank]) + displayed_rank = character.client?.prefs?.alt_titles_preferences[rank] var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems) - announcer.announce("ARRIVAL", character.real_name, rank, list()) //make the list empty to make it announce it in common + announcer.announce("ARRIVAL", character.real_name, displayed_rank, list()) //make the list empty to make it announce it in common /proc/lavaland_equipment_pressure_check(turf/T) . = FALSE diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index b8f5c68dee..af28f2edf3 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -464,7 +464,10 @@ SUBSYSTEM_DEF(job) else handle_auto_deadmin_roles(M.client, rank) - to_chat(M, "You are the [rank].") + var/display_rank = rank + if(M.client && M.client.prefs && M.client?.prefs?.alt_titles_preferences[rank]) + display_rank = M.client?.prefs?.alt_titles_preferences[rank] + to_chat(M, "You are the [display_rank].") if(job) to_chat(M, "As the [rank] you answer directly to [job.supervisors]. Special circumstances may change this.") job.radio_help_message(M) diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 8195666783..bb0f786fc5 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -138,12 +138,18 @@ var/static/list/show_directions = list(SOUTH, WEST) if(H.mind && (H.mind.assigned_role != H.mind.special_role)) var/assignment + var/displayed_rank if(H.mind.assigned_role) assignment = H.mind.assigned_role else if(H.job) assignment = H.job else assignment = "Unassigned" + if(C && C.prefs && C.prefs.alt_titles_preferences[assignment]) + assignment = C.prefs.alt_titles_preferences[assignment] + + if(assignment) + displayed_rank = C.prefs.alt_titles_preferences[assignment] var/static/record_id_num = 1001 var/id = num2hex(record_id_num++,6) @@ -166,7 +172,7 @@ var/datum/data/record/G = new() G.fields["id"] = id G.fields["name"] = H.real_name - G.fields["rank"] = assignment + G.fields["rank"] = displayed_rank G.fields["age"] = H.age G.fields["species"] = H.dna.species.name G.fields["fingerprint"] = md5(H.dna.uni_identity) @@ -213,7 +219,7 @@ var/datum/data/record/L = new() L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]") //surely this should just be id, like the others? L.fields["name"] = H.real_name - L.fields["rank"] = H.mind.assigned_role + L.fields["rank"] = displayed_rank L.fields["age"] = H.age if(H.gender == MALE) G.fields["gender"] = "Male" diff --git a/code/game/machinery/announcement_system.dm b/code/game/machinery/announcement_system.dm index d06366c021..1919d424ee 100644 --- a/code/game/machinery/announcement_system.dm +++ b/code/game/machinery/announcement_system.dm @@ -17,9 +17,9 @@ GLOBAL_LIST_EMPTY(announcement_systems) circuit = /obj/item/circuitboard/machine/announcement_system var/obj/item/radio/headset/radio - var/arrival = "%PERSON has signed up as %RANK" + var/arrival = "%PERSON has signed up as %DISP_RANK (%RANK)" var/arrivalToggle = TRUE - var/newhead = "%PERSON, %RANK, is the department head." + var/newhead = "%PERSON, %DISP_RANK (%RANK), is the department head." var/newheadToggle = TRUE var/cryostorage = "%PERSON, %RANK, has been moved into cryogenic storage." // this shouldnt be changed @@ -70,23 +70,24 @@ GLOBAL_LIST_EMPTY(announcement_systems) else return ..() -/obj/machinery/announcement_system/proc/CompileText(str, user, rank) //replaces user-given variables with actual thingies. +/obj/machinery/announcement_system/proc/CompileText(str, user, rank, displayed_rank) //replaces user-given variables with actual thingies. str = replacetext(str, "%PERSON", "[user]") str = replacetext(str, "%RANK", "[rank]") + str = replacetext(str, "%DISP_RANK", "[displayed_rank]") return str -/obj/machinery/announcement_system/proc/announce(message_type, user, rank, list/channels) +/obj/machinery/announcement_system/proc/announce(message_type, user, rank, displayed_rank, list/channels) if(!is_operational()) return var/message if(message_type == "ARRIVAL" && arrivalToggle) - message = CompileText(arrival, user, rank) + message = CompileText(arrival, user, rank, displayed_rank) else if(message_type == "NEWHEAD" && newheadToggle) - message = CompileText(newhead, user, rank) + message = CompileText(newhead, user, rank, displayed_rank) else if(message_type == "CRYOSTORAGE") - message = CompileText(cryostorage, user, rank) + message = CompileText(cryostorage, user, rank, displayed_rank) else if(message_type == "ARRIVALS_BROKEN") message = "The arrivals shuttle has been damaged. Docking for repairs..." diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index ddf2d71cec..2f1234f46d 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -101,6 +101,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/pda_style = MONO var/pda_color = "#808000" var/pda_skin = PDA_SKIN_ALT + var/list/alt_titles_preferences = list() var/uses_glasses_colour = 0 @@ -1449,6 +1450,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) HTML += "" var/rank = job.title + var/displayed_rank = rank + if(job.alt_titles.len && (rank in alt_titles_preferences)) + displayed_rank = alt_titles_preferences[rank] lastJob = job if(jobban_isbanned(user, rank)) HTML += "[rank] BANNED" @@ -1470,10 +1474,15 @@ GLOBAL_LIST_EMPTY(preferences_datums) if((job_preferences["[SSjob.overflow_role]"] == JP_LOW) && (rank != SSjob.overflow_role) && !jobban_isbanned(user, SSjob.overflow_role)) HTML += "[rank]" continue + var/rank_title_line = "[displayed_rank]" if((rank in GLOB.command_positions) || (rank == "AI"))//Bold head jobs - HTML += "[rank]" + rank_title_line = "[rank_title_line]" + if(job.alt_titles.len) + rank_title_line = "[rank_title_line]" + else - HTML += "[rank]" + rank_title_line = "[rank_title_line]" //Make it dark if we're not adding a button for alt titles + HTML += rank_title_line HTML += "" @@ -1727,6 +1736,21 @@ GLOBAL_LIST_EMPTY(preferences_datums) SetChoices(user) if("setJobLevel") UpdateJobPreference(user, href_list["text"], text2num(href_list["level"])) + if("alt_title") + var/job_title = href_list["job_title"] + var/titles_list = list(job_title) + var/datum/job/J = SSjob.GetJob(job_title) + for(var/i in J.alt_titles) + titles_list += i + var/chosen_title + chosen_title = input(user, "Choose your job's title:", "Job Preference") as null|anything in titles_list + if(chosen_title) + if(chosen_title == job_title) + if(alt_titles_preferences[job_title]) + alt_titles_preferences.Remove(job_title) + else + alt_titles_preferences[job_title] = chosen_title + SetChoices(user) else SetChoices(user) return TRUE diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 1f74ca9031..5ff539497d 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -910,6 +910,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car if(json_from_file) belly_prefs = json_from_file["belly_prefs"] + S["alt_titles_preferences"] >> alt_titles_preferences //gear loadout if(istext(S["loadout"])) loadout_data = safe_json_decode(S["loadout"]) @@ -1098,6 +1099,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car loadout_slot = sanitize_num_clamp(loadout_slot, 1, MAXIMUM_LOADOUT_SAVES, 1, TRUE) + alt_titles_preferences = SANITIZE_LIST(alt_titles_preferences) + if(SSjob) + for(var/datum/job/job in SSjob.occupations) + if(alt_titles_preferences[job.title]) + if(!(alt_titles_preferences[job.title] in job.alt_titles)) + alt_titles_preferences.Remove(job.title) + cit_character_pref_load(S) return TRUE @@ -1214,6 +1222,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["feature_butt_color"], features["butt_color"]) WRITE_FILE(S["feature_butt_size"], features["butt_size"]) WRITE_FILE(S["feature_butt_visibility"], features["butt_visibility"]) + WRITE_FILE(S["alt_titles_preferences"], alt_titles_preferences) WRITE_FILE(S["feature_ooc_notes"], features["ooc_notes"]) diff --git a/code/modules/jobs/job_titles.dm b/code/modules/jobs/job_titles.dm new file mode 100644 index 0000000000..9f516940ae --- /dev/null +++ b/code/modules/jobs/job_titles.dm @@ -0,0 +1,109 @@ +//This file also determines the order for the choose your occupation chances screen. + +//Engineering +/datum/job/chief_engineer + alt_titles = list("Head Engineer", "Construction Coordinator", "Project Manager", "Power Plant Director") + +/datum/job/engineer + alt_titles = list("Maintenance Technician", "Engine Technician", "Electrician", "Structural Engineer", "Mechanic", "Station Architect", "Nuclear Plant Operator") + +/datum/job/atmos + alt_titles = list("Firefighter", "Life Support Specialist", "Disposals Technician") + +/datum/job/junior_engineer + +//Service +/datum/job/assistant + alt_titles = list("Civilian", "Morale Officer", "Stripper", "Off-Duty", "Escort", "Visitor", "Businessman", "Trader", "Entertainer", "Tourist") + +/datum/job/cook + alt_titles = list("Cook", "Culinary Artist", "Butcher", "Chef de partie", "Poissonier", "Baker", "Taste Tester") + +/datum/job/hydro + alt_titles = list("Gardener", "Herbalist", "Botanical Researcher", "Hydroponicist", "Farmer", "Beekeeper", "Vintner") + +/datum/job/curator + alt_titles = list("Journalist", "Librarian", "Keeper") + +/datum/job/chaplain + alt_titles = list("Priest", "Priestess", "Prior", "Monk", "Nun", "Counselor") + +/datum/job/janitor + alt_titles = list("Custodian", "Sanitation Technician", "Maid", "Trash Can", "Disposal Unit") + +/datum/job/lawyer + alt_titles = list("Human Resources Agent", "Internal Affairs Agent", "Attorney") + +/datum/job/clown + alt_titles = list("Jester", "Comedian") + +/datum/job/mime + alt_titles = list("Performer", "Pantomime", "Mimic") + +/datum/job/bartender + alt_titles = list("Mixologist", "Sommelier", "Bar Owner", "Barmaid", "Expediter") + +//Science +/datum/job/rd + alt_titles = list("Research Manager", "Science Administrator") + +/datum/job/scientist + alt_titles = list("Circuitry Designer", "Xenobiologist", "Xenobotanist", "Xenoarcheologist", "Chemical Researcher", "Researcher", "Pyrotechnician") + +/datum/job/roboticist + alt_titles = list("Biomechanical Engineer", "Mechatronic Engineer", "Mechanic") + +/datum/job/junior_scientist + +//Medical +/datum/job/cmo + alt_titles = list("Medical Director", "Medical Administrator") + +/datum/job/doctor + alt_titles = list("Nurse", "Surgeon", "Physician", "Paramedic", "Trophologist", "Nutritionist") + +/datum/job/chemist + alt_titles = list("Pharmacist", "Pharmacologist") + +/datum/job/virologist + alt_titles = list("Microbiologist", "Biochemist", "Pathologist") + +/datum/job/geneticist + alt_titles = list("Gene Therapist", "Genetics Researcher") + +/datum/job/psychologist + alt_titles = list("Therapist", "Psychiatrist") + +/datum/job/junior_doctor + +//Security +/datum/job/hos + alt_titles = list("Chief of Security", "Security Commander", "Sheriff") + +/datum/job/warden + alt_titles = list("Prison Chief", "Armory Manager", "Prison Administrator", "Brig Superintendent") + +/datum/job/officer + alt_titles = list("Security Agent", "Probation Officer", "Security Peacekeeper", "Security Guard", "Guardsman", "Security Cadet") + +/datum/job/detective + alt_titles = list("Forensics Technician", "Private Investigator", "Gumshoe") + +/datum/job/junior_officer + +//Supply +/datum/job/qm + alt_titles = list("Supply Chief") + +/datum/job/cargo_tech + alt_titles = list("Mail Man", "Mail Woman", "Mailroom Technician", "Deliveries Officer", "Logistics Technician") + +/datum/job/mining + alt_titles = list("Exotic Ore Miner", "Fauna Hunter", "Explorer", "Digger") //Just because you're a hunter does not excuse you from rock collecting!!!!!!!!!!!! + +//Command +/datum/job/captain + alt_titles = list("Station Director", "Station Commander", "Station Overseer", "Stationmaster", "Commissar") + +/datum/job/hop + alt_titles = list("Personnel Manager", "Staff Administrator", "Records Administrator") diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index 969a39b560..f9140cfc43 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -63,6 +63,9 @@ var/list/mind_traits // Traits added to the mind of the mob assigned this job var/list/blacklisted_quirks //list of quirk typepaths blacklisted. + /// What alternate titles does this job currently have? + var/list/alt_titles = list() + /// Should this job be allowed to be picked for the bureaucratic error event? var/allow_bureaucratic_error = TRUE @@ -211,7 +214,7 @@ /datum/job/proc/announce_head(var/mob/living/carbon/human/H, var/channels) //tells the given channel that the given mob is the new department head. See communications.dm for valid channels. if(H && GLOB.announcement_systems.len) //timer because these should come after the captain announcement - SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(_addtimer), CALLBACK(pick(GLOB.announcement_systems), TYPE_PROC_REF(/obj/machinery/announcement_system, announce), "NEWHEAD", H.real_name, H.job, channels), 1)) + SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(_addtimer), CALLBACK(pick(GLOB.announcement_systems), TYPE_PROC_REF(/obj/machinery/announcement_system, announce), "NEWHEAD", H.real_name, H.job, H.client?.prefs.alt_titles_preferences[H.job], channels), 1)) //If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1 /datum/job/proc/player_old_enough(client/C) @@ -314,7 +317,11 @@ shuffle_inplace(C.access) // Shuffle access list to make NTNet passkeys less predictable C.registered_name = H.real_name C.assignment = J.title - C.update_label() + if(preference_source && preference_source.prefs && preference_source.prefs.alt_titles_preferences[J.title]) + C.update_label(C.registered_name, preference_source.prefs.alt_titles_preferences[J.title]) + else + C.update_label() + for(var/A in SSeconomy.bank_accounts) var/datum/bank_account/B = A if(B.account_id == H.account_id) @@ -326,6 +333,10 @@ var/obj/item/pda/PDA = H.get_item_by_slot(pda_slot) if(istype(PDA)) PDA.owner = H.real_name + if(preference_source && preference_source.prefs && preference_source.prefs.alt_titles_preferences[J.title]) + PDA.ownjob = preference_source.prefs.alt_titles_preferences[J.title] + else + PDA.ownjob = J.title PDA.ownjob = J.title PDA.update_label() if(preference_source && !PDA.equipped) //PDA's screen color, font style and look depend on client preferences. diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm index fe594e4660..e217b3c0d2 100644 --- a/code/modules/jobs/job_types/captain.dm +++ b/code/modules/jobs/job_types/captain.dm @@ -50,7 +50,10 @@ /datum/job/captain/announce(mob/living/carbon/human/H) ..() - SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(minor_announce), "Captain [H.nameless ? "" : "[H.real_name] "]on deck!")) + var/displayed_rank = H.client?.prefs?.alt_titles_preferences[title] + if(!displayed_rank) //Default to Captain + displayed_rank = "Captain" + SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(minor_announce), "[displayed_rank] [H.nameless ? "" : "[H.real_name] "]on deck!")) /datum/outfit/job/captain name = "Captain" diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index b3811b8fef..330d9b36db 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -606,6 +606,9 @@ dept_dat += "[job_datum.title] ([num_positions_current]/[num_positions_total])" else dept_dat += "[job_datum.title] ([num_positions_current]/[num_positions_total])" + if(client && client.prefs && client?.prefs?.alt_titles_preferences[job_datum.title]) + dept_dat += "
(as [client?.prefs?.alt_titles_preferences[job_datum.title]])" + if(!dept_dat.len) dept_dat += "No positions open." dat += jointext(dept_dat, "") diff --git a/tgstation.dme b/tgstation.dme index 4a116ff9fd..0d49f689c2 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2472,6 +2472,7 @@ #include "code\modules\jobs\access.dm" #include "code\modules\jobs\job_exp.dm" #include "code\modules\jobs\job_report.dm" +#include "code\modules\jobs\job_titles.dm" #include "code\modules\jobs\jobs.dm" #include "code\modules\jobs\job_types\_job.dm" #include "code\modules\jobs\job_types\ai.dm"