Skip to content

Commit

Permalink
feat(loadout): departmental gear
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rufuszero committed Apr 12, 2024
1 parent fdce520 commit e01e6ee
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 103 deletions.
3 changes: 3 additions & 0 deletions code/game/jobs/job_controller.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
68 changes: 68 additions & 0 deletions code/modules/client/preference_setup/loadout/gear_tweaks.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
149 changes: 53 additions & 96 deletions code/modules/client/preference_setup/loadout/lists/suits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
33 changes: 30 additions & 3 deletions code/modules/client/preference_setup/loadout/loadout.dm
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,15 @@ var/list/hash_to_gear = list()
. += "<td style='white-space: nowrap; width: 40px;' class='block'>"
. += "<table>"
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 = ""
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -366,6 +372,11 @@ var/list/hash_to_gear = list()
. += "<br><b>Options:</b><br>"
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)
. += " <a href='?src=\ref[src];tweak=\ref[tweak];subtype=[tweak_contents[name]]'>[name]</a>"
. += "<br>"
continue
if(tweak_contents)
. += " <a href='?src=\ref[src];tweak=\ref[tweak]'>[tweak_contents]</a>"
. += "<br>"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
16 changes: 12 additions & 4 deletions code/modules/mob/new_player/preferences_setup.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit e01e6ee

Please sign in to comment.