Files
Bubberstation/code/modules/loadout/loadout_preference.dm
Rimi Nosha 6d8f4d1805 [SEMI-MODULAR] Multiple Loadout Presets! (#2540)
## About The Pull Request

Tin. Also made some QoL tweaks while I was at it!

Comprehensively:
- Removes the defunct job checkbox and replaces it with a dropdown.
- Adds a preference update message, cause it's otherwise silent.
- Stops the TGUI prefs migration message from showing when changing to a
brand new character.
- Adds the ability to create (nameable) loadout presets.
- The default preset can't be renamed or deleted. This was to make my
life easier, or I'd spend another day on this, which I'm not prepared to
do.
- Automatically COPIES your old loadout to the new system's default
loadout. The old preference value is ENTIRELY UNCHANGED, which should
mean this is entirely safe. **Back up the server playersave data,
regardless, though.**
- Fixes a funny bug where the blacklisted and whitelisted roles text was
the same.

## There's a default limit of 12 entries (including default.) I'm happy
to bump this up at maintainer request.

## Why It's Good For The Game

This is a thing folk have always wanted since the dawn of loadouts, and
the new loadout system is *surprisingly* hackable, so I did it!

Now you can set up multiple outfits for whatever occasion you want!

## Proof Of Testing
<details>
<summary>Screenshots/Videos</summary>


![image](https://github.com/user-attachments/assets/6cddb219-0c8e-44f1-aefe-d3f36a261555)



https://github.com/user-attachments/assets/9d4bd6f3-0dc7-4aaa-a6ad-989fc9cb987a

The total allowed loadout count, added after the video, so here's a
screencap instead!

![image](https://github.com/user-attachments/assets/0ffd72a4-ed4c-4b6d-8d77-83c0545e1171)

Renaming


https://github.com/user-attachments/assets/236d99c2-1bcf-4836-b32c-4bb4dd6227e0

</details>

## Changelog
🆑
add: Loadout presets! Make multiple loadouts, be able to switch between
them in a couple of clicks!
qol: Replaced the defunct job checkbox on the loadout page with a
working dropdown.
/🆑
2024-12-07 20:53:57 +01:00

70 lines
2.9 KiB
Plaintext

/datum/preference/loadout
savefile_key = "loadout_list"
savefile_identifier = PREFERENCE_CHARACTER
priority = PREFERENCE_PRIORITY_LOADOUT
can_randomize = FALSE
// BUBBER NOTE: This isn't accurate, this is now an assoc list of names to the stuff below. Yeah. - Rimi, the pref code slaughterer
// Loadout preference is an assoc list [item_path] = [loadout item information list]
//
// it may look something like
// - list(/obj/item/glasses = list())
// or
// - list(/obj/item/plush/lizard = list("name" = "Tests-The-Loadout", "color" = "#FF0000"))
// Loadouts are applied with job equip code.
/datum/preference/loadout/apply_to_human(mob/living/carbon/human/target, value)
return
// Sanitize on load to ensure no invalid paths from older saves get in
/datum/preference/loadout/deserialize(input, datum/preferences/preferences)
return sanitize_loadout_list(input, preferences.parent?.mob, preferences.parent) // SKYRAT EDIT CHANGE parent
// Default value is null - the loadout list is a lazylist
/datum/preference/loadout/create_default_value(datum/preferences/preferences)
return null
/datum/preference/loadout/is_valid(value)
return isnull(value) || islist(value)
/**
* Removes all invalid paths from loadout lists.
* This is a general sanitization for preference loading.
*
* Returns a list, or null if empty
*/
/datum/preference/loadout/proc/sanitize_loadout_list(list/passed_list, mob/optional_loadout_owner, client/owner_client) as /list // SKYRAT EDIT CHANGE - client/owner_client
var/list/sanitized_list
for(var/path in passed_list)
// Loading from json has each path in the list as a string that we need to convert back to typepath
var/obj/item/real_path = istext(path) ? text2path(path) : path
if(!ispath(real_path, /obj/item))
if(optional_loadout_owner)
to_chat(optional_loadout_owner, span_boldnotice("The following invalid item path was found \
in your character loadout: [real_path || "null"]. \
It has been removed, renamed, or is otherwise missing - \
You may want to check your loadout settings."))
continue
else if(!istype(GLOB.all_loadout_datums[real_path], /datum/loadout_item))
if(optional_loadout_owner)
to_chat(optional_loadout_owner, span_boldnotice("The following invalid loadout item was found \
in your character loadout: [real_path || "null"]. \
It has been removed, renamed, or is otherwise missing - \
You may want to check your loadout settings."))
continue
// SKYRAT EDIT ADDITION
else if(owner_client)
var/datum/loadout_item/loadout_item = GLOB.all_loadout_datums[real_path]
if(loadout_item?.ckeywhitelist && !(owner_client?.ckey in loadout_item.ckeywhitelist))
continue
if(loadout_item?.donator_only && !GLOB.donator_list[owner_client?.ckey])
continue
// SKYRAT EDIT END
// Set into sanitize list using converted path key
var/list/data = passed_list[path]
LAZYSET(sanitized_list, real_path, LAZYLISTDUPLICATE(data))
return sanitized_list