From e01e6eef9d09dd57fc0d3355052ce203d22deb99 Mon Sep 17 00:00:00 2001 From: RufusZero Date: Fri, 12 Apr 2024 21:39:00 +0300 Subject: [PATCH] feat(loadout): departmental gear Add new "departmental" gear tweak Apply departmental gear tweak to winter coats Change behavior of character preview, low and medium job preferences are used if high is not set Add support for mutiple gear tweak options via "subtype" param --- code/game/jobs/job_controller.dm | 3 + .../preference_setup/loadout/gear_tweaks.dm | 68 ++++++++ .../preference_setup/loadout/lists/suits.dm | 149 +++++++----------- .../preference_setup/loadout/loadout.dm | 33 +++- .../mob/new_player/preferences_setup.dm | 16 +- 5 files changed, 166 insertions(+), 103 deletions(-) diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index bfecf943081..ea83529d4c6 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -424,6 +424,9 @@ var/global/datum/controller/occupations/job_master to_chat(H, SPAN("warning", "Your current species, job, whitelist status or loadout configuration does not permit you to spawn with [thing]!")) continue + if(G.is_departmental()) + G.set_selected_jobs(job, null) + if(!G.slot || G.slot == slot_tie || G.slot == slot_belt ||(G.slot in loadout_taken_slots) || !G.spawn_on_mob(H, H.client.prefs.Gear()[G.display_name])) spawn_in_storage.Add(G) else diff --git a/code/modules/client/preference_setup/loadout/gear_tweaks.dm b/code/modules/client/preference_setup/loadout/gear_tweaks.dm index 1ddadf7f32f..5190f177835 100644 --- a/code/modules/client/preference_setup/loadout/gear_tweaks.dm +++ b/code/modules/client/preference_setup/loadout/gear_tweaks.dm @@ -132,6 +132,74 @@ var/obj/O = valid_paths[metadata] return initial(O.desc) || description +/* +* Departmental auto-adjustment +*/ + +/datum/gear_tweak/departmental + var/list/jobs_to_paths + + var/datum/job/current_job + var/list/selected_jobs + +/datum/gear_tweak/departmental/New(list/jobs_to_paths) + src.jobs_to_paths = jobs_to_paths + +/datum/gear_tweak/departmental/proc/set_selected_jobs(current_job, selected_jobs) + if(current_job && !istype(current_job,/datum/job)) + CRASH("Expected /datum/job, got [current_job]") + if(selected_jobs && !islist(selected_jobs)) + CRASH("Expected list, got [selected_jobs]") + src.current_job = current_job + src.selected_jobs = selected_jobs + +/datum/gear_tweak/departmental/get_contents(metadata) + . = list() + LAZYINITLIST(metadata) + for(var/datum/job/job in selected_jobs) + var/list/choices = jobs_to_paths[job.type] + if(!(job.type in jobs_to_paths) || length(choices) < 2) + continue + var/choice = text2path(metadata["[job.type]"]) || choices[1] + .["[job.title]: [get_initial_name(choice)]"] = job.type + +/datum/gear_tweak/departmental/get_metadata(user, metadata, subtype) + LAZYINITLIST(metadata) + ASSERT(istext(subtype)) + var/job_path = text2path(subtype) + if(!job_path || !(job_path in jobs_to_paths)) + CRASH("Expected subtype to be in the list of jobs to select gear for") + var/default = null + var/old_choice = text2path(metadata[subtype]) + if(old_choice) + default = get_initial_name(old_choice) + var/list/choices = atomtypes2nameassoclist(jobs_to_paths[job_path]) + var/choice = input(user, "Choose a type.", CHARACTER_PREFERENCE_INPUT_TITLE, default) as null|anything in choices + if(choice) + metadata[subtype] = "[choices[choice]]" + return metadata + +/datum/gear_tweak/departmental/tweak_gear_data(metadata, datum/gear_data/gear_data) + LAZYINITLIST(metadata) + var/datum/job/job = get_valid_current_job() + if(!istype(job)) + return + var/text_path = metadata["[job.type]"] + gear_data.path = text2path(text_path) + if(!gear_data.path) + gear_data.path = jobs_to_paths[job.type][1] + +/datum/gear_tweak/departmental/proc/get_valid_current_job() + if(current_job && (current_job.type in jobs_to_paths)) + return current_job + if(!length(selected_jobs)) + return + for(var/datum/job/job in selected_jobs) + if(!istype(job)) + CRASH("Expected /datum/job, got [job]") + if(job.type in jobs_to_paths) + return job + /* * Content adjustment */ diff --git a/code/modules/client/preference_setup/loadout/lists/suits.dm b/code/modules/client/preference_setup/loadout/lists/suits.dm index 3e9253c4557..280a029650f 100644 --- a/code/modules/client/preference_setup/loadout/lists/suits.dm +++ b/code/modules/client/preference_setup/loadout/lists/suits.dm @@ -113,104 +113,61 @@ jackets += /obj/item/clothing/suit/storage/black_jacket_long gear_tweaks += new /datum/gear_tweak/path/specified_types_list(jackets) -/datum/gear/suit/wintercoat - display_name = "winter coat" +/datum/gear/suit/department_wintercoat + display_name = "departmental winter coat" path = /obj/item/clothing/suit/storage/hooded/wintercoat -/datum/gear/suit/captain_wintercoat - display_name = "winter coat, captain" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/captain - allowed_roles = list(/datum/job/captain) - -/datum/gear/suit/security_wintercoat - display_name = "winter coat, security" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/security - allowed_roles = SECURITY_ROLES - -/datum/gear/suit/ce_wintercoat - display_name = "winter coat, chief engineer" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/ce - allowed_roles = list(/datum/job/chief_engineer) - -/datum/gear/suit/engineering_wintercoat - display_name = "winter coat, engineer" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/engineering - allowed_roles = ENGINEERING_ROLES - -/datum/gear/suit/atmos_wintercoat - display_name = "winter coat, atmospheric" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/engineering/atmos - allowed_roles = ENGINEERING_ROLES - -/datum/gear/suit/hop_wintercoat - display_name = "winter coat, head of personal" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/hop - allowed_roles = list(/datum/job/hop) - -/datum/gear/suit/qm_wintercoat - display_name = "winter coat, quartermaster" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/qm - allowed_roles = list(/datum/job/qm) - -/datum/gear/suit/cargotech_wintercoat - display_name = "winter coat, cargo" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/cargo - allowed_roles = SUPPLY_ROLES - -/datum/gear/suit/mining_wintercoat - display_name = "winter coat, miner" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/miner - allowed_roles = list(/datum/job/mining, /datum/job/qm) - -/datum/gear/suit/janitor_wintercoat - display_name = "winter coat, janitor" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/janitor - allowed_roles = list(/datum/job/janitor) - -/datum/gear/suit/botanist_wintercoat - display_name = "winter coat, botanist" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/hydro - allowed_roles = list(/datum/job/hydro, /datum/job/xenobiologist) - -/datum/gear/suit/cmo_wintercoat - display_name = "winter coat, chief medical officer" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/cmo - allowed_roles = list(/datum/job/cmo) - -/datum/gear/suit/medical_wintercoat - display_name = "winter coat, medical" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/medical - allowed_roles = MEDICAL_ROLES - -/datum/gear/suit/chemist_wintercoat - display_name = "winter coat, chemist" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/chemistry - allowed_roles = list(/datum/job/chemist, /datum/job/cmo) - -/datum/gear/suit/virologist_wintercoat - display_name = "winter coat, virologist" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/viro - allowed_roles = list(/datum/job/virologist, /datum/job/cmo) - -/datum/gear/suit/paramedic_wintercoat - display_name = "winter coat, paramedic" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/paramed - allowed_roles = MEDICAL_ROLES - -/datum/gear/suit/rd_wintercoat - display_name = "winter coat, research director" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/rd - allowed_roles = list(/datum/job/rd) - -/datum/gear/suit/science_wintercoat - display_name = "winter coat, scientist" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/science - allowed_roles = RESEARCH_ROLES - -/datum/gear/suit/roboticist_wintercoat - display_name = "winter coat, roboticist" - path = /obj/item/clothing/suit/storage/hooded/wintercoat/robotics - allowed_roles = list(/datum/job/roboticist, /datum/job/rd) +/datum/gear/suit/department_wintercoat/New() + ..() + var/list/paths_to_jobs = list( + /datum/job = list(/obj/item/clothing/suit/storage/hooded/wintercoat), + /datum/job/captain = list(/obj/item/clothing/suit/storage/hooded/wintercoat/captain), + /datum/job/hos = list(/obj/item/clothing/suit/storage/hooded/wintercoat/security), + /datum/job/warden = list(/obj/item/clothing/suit/storage/hooded/wintercoat/security), + /datum/job/detective = list(/obj/item/clothing/suit/storage/hooded/wintercoat/security), + /datum/job/officer = list(/obj/item/clothing/suit/storage/hooded/wintercoat/security), + /datum/job/chief_engineer = list(/obj/item/clothing/suit/storage/hooded/wintercoat/ce), + /datum/job/engineer = list( + /obj/item/clothing/suit/storage/hooded/wintercoat/engineering, + /obj/item/clothing/suit/storage/hooded/wintercoat/engineering/atmos), + /datum/job/hop = list(/obj/item/clothing/suit/storage/hooded/wintercoat/hop), + /datum/job/qm = list( + /obj/item/clothing/suit/storage/hooded/wintercoat/qm, + /obj/item/clothing/suit/storage/hooded/wintercoat/cargo), + /datum/job/cargo_tech = list(/obj/item/clothing/suit/storage/hooded/wintercoat/cargo), + /datum/job/mining = list( + /obj/item/clothing/suit/storage/hooded/wintercoat/miner, + /obj/item/clothing/suit/storage/hooded/wintercoat/cargo), + /datum/job/janitor = list(/obj/item/clothing/suit/storage/hooded/wintercoat/janitor), + /datum/job/hydro = list(/obj/item/clothing/suit/storage/hooded/wintercoat/hydro), + /datum/job/cmo = list( + /obj/item/clothing/suit/storage/hooded/wintercoat/cmo, + /obj/item/clothing/suit/storage/hooded/wintercoat/medical), + /datum/job/doctor = list(/obj/item/clothing/suit/storage/hooded/wintercoat/medical), + /datum/job/psychiatrist = list(/obj/item/clothing/suit/storage/hooded/wintercoat/medical), + /datum/job/chemist = list( + /obj/item/clothing/suit/storage/hooded/wintercoat/chemistry, + /obj/item/clothing/suit/storage/hooded/wintercoat/medical), + /datum/job/virologist = list( + /obj/item/clothing/suit/storage/hooded/wintercoat/viro, + /obj/item/clothing/suit/storage/hooded/wintercoat/medical), + /datum/job/paramedic = list( + /obj/item/clothing/suit/storage/hooded/wintercoat/paramed, + /obj/item/clothing/suit/storage/hooded/wintercoat/medical), + /datum/job/rd = list( + /obj/item/clothing/suit/storage/hooded/wintercoat/rd, + /obj/item/clothing/suit/storage/hooded/wintercoat/science), + /datum/job/scientist = list( + /obj/item/clothing/suit/storage/hooded/wintercoat/science), + /datum/job/xenobiologist = list( + /obj/item/clothing/suit/storage/hooded/wintercoat/science, + /obj/item/clothing/suit/storage/hooded/wintercoat/hydro), + /datum/job/roboticist = list( + /obj/item/clothing/suit/storage/hooded/wintercoat/robotics, + /obj/item/clothing/suit/storage/hooded/wintercoat/science), + ) + + gear_tweaks += new /datum/gear_tweak/departmental(paths_to_jobs) /datum/gear/suit/track display_name = "track jacket selection" diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm index 4f0e917267c..61f1bfe906a 100644 --- a/code/modules/client/preference_setup/loadout/loadout.dm +++ b/code/modules/client/preference_setup/loadout/loadout.dm @@ -208,12 +208,15 @@ var/list/hash_to_gear = list() . += "" . += "" var/datum/loadout_category/LC = loadout_categories[current_tab] + var/datum/job/selected_job_high var/list/selected_jobs = new if(job_master) - for(var/job_title in (pref.job_medium|pref.job_low|pref.job_high)) + selected_job_high = job_master.occupations_by_title[pref.job_high] + var/selected_job_titles = (pref.job_high ? list(pref.job_high) : list()) | pref.job_medium | pref.job_low + for(var/job_title in selected_job_titles) var/datum/job/J = job_master.occupations_by_title[job_title] if(J) - dd_insertObjectList(selected_jobs, J) + selected_jobs += J var/purchased_gears = "" var/paid_gears = "" @@ -274,6 +277,9 @@ var/list/hash_to_gear = list() if(selected_gear) var/ticked = (selected_gear.display_name in pref.gear_list[pref.gear_slot]) + if(selected_gear.is_departmental()) + selected_gear.set_selected_jobs(selected_job_high, selected_jobs) + var/datum/gear_data/gd = new(selected_gear.path) for(var/datum/gear_tweak/gt in selected_gear.gear_tweaks) gt.tweak_gear_data(selected_tweaks["[gt]"], gd) @@ -366,6 +372,11 @@ var/list/hash_to_gear = list() . += "
Options:
" for(var/datum/gear_tweak/tweak in selected_gear.gear_tweaks) var/tweak_contents = tweak.get_contents(selected_tweaks["[tweak]"]) + if(islist(tweak_contents)) + for(var/name in tweak_contents) + . += " [name]" + . += "
" + continue if(tweak_contents) . += " [tweak_contents]" . += "
" @@ -443,7 +454,7 @@ var/list/hash_to_gear = list() if(!tweak || !istype(selected_gear) || !(tweak in selected_gear.gear_tweaks)) pref.loadout_is_busy = FALSE return TOPIC_NOACTION - var/metadata = tweak.get_metadata(user, get_tweak_metadata(selected_gear, tweak)) + var/metadata = tweak.get_metadata(user, get_tweak_metadata(selected_gear, tweak), href_list["subtype"]) if(!metadata || !CanUseTopic(user)) pref.loadout_is_busy = FALSE return TOPIC_NOACTION @@ -667,6 +678,22 @@ var/list/hash_to_gear = list() /datum/gear/proc/is_allowed_to_display(mob/user) return TRUE +/datum/gear/proc/is_departmental() + for(var/datum/gear_tweak/gt in gear_tweaks) + if(istype(gt, /datum/gear_tweak/departmental)) + return TRUE + return FALSE + +/datum/gear/proc/set_selected_jobs(job_high, selected_jobs) + if(job_high && !istype(job_high,/datum/job)) + CRASH("Expected /datum/job, got [job_high]") + if(selected_jobs && !islist(selected_jobs)) + CRASH("Expected list, got [selected_jobs]") + for(var/datum/gear_tweak/departmental/gt in gear_tweaks) + if(!istype(gt, /datum/gear_tweak/departmental)) + continue + gt.set_selected_jobs(job_high, selected_jobs) + /datum/gear_data var/path var/location diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index b08bdfa3fce..b874c45d988 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -67,14 +67,16 @@ mannequin.update_icon = TRUE var/datum/job/previewJob + var/list/selected_jobs = (job_high ? list(job_high) : list()) | job_medium | job_low if(equip_preview_mob && job_master) - // Determine what job is marked as 'High' priority, and dress them up as such. + // Determine what job is the highest priority, and dress them up as such. + // Order of the same priority jobs is not enforced. if("Assistant" in job_low) previewJob = job_master.GetJob("Assistant") else - for(var/datum/job/job in job_master.occupations) - if(job.title == job_high) - previewJob = job + for(var/job_title in selected_jobs) + previewJob = job_master.occupations_by_title[job_title] + if(previewJob) break else return @@ -114,6 +116,12 @@ if(!permitted) continue + if(G.is_departmental() && previewJob) + if(previewJob) + G.set_selected_jobs(previewJob, selected_jobs) + else + G.set_selected_jobs(new DEFAULT_JOB_TYPE(), selected_jobs) + if(G.slot == slot_tie) accessories.Add(G) continue