From e6895bec04c9f3251e7dd6641d1e7ebb9dfc24bf Mon Sep 17 00:00:00 2001
From: Timothy Teakettle <59849408+timothyteakettle@users.noreply.github.com>
Date: Tue, 20 Oct 2020 21:02:17 +0100
Subject: [PATCH] better loadout
---
code/__DEFINES/citadel_defines.dm | 5 +++
code/modules/client/preferences.dm | 45 ++++++++++++++++-----
code/modules/client/preferences_savefile.dm | 38 ++++++++---------
3 files changed, 60 insertions(+), 28 deletions(-)
diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm
index 923355b340..e9aa603d8a 100644
--- a/code/__DEFINES/citadel_defines.dm
+++ b/code/__DEFINES/citadel_defines.dm
@@ -114,3 +114,8 @@
//special species definitions
#define MINIMUM_MUTANT_COLOR "#202020" //this is how dark players mutant parts and skin can be
+
+//loadout defines
+#define MAXIMUM_LOADOUT_SAVES 5
+#define LOADOUT_ITEM "loadout_item"
+#define LOADOUT_COLOR "loadout_color"
\ No newline at end of file
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index d817cc3a53..2fd42a1cd5 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -245,7 +245,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
///loadout stuff
var/gear_points = 10
var/list/gear_categories
- var/list/chosen_gear = list()
+ var/list/loadout_data = list()
+ var/loadout_slot = 1 //goes from 1 to MAXIMUM_LOADOUT_SAVES
+ var/list/chosen_gear = list() //your current set of items from loadout_data
var/gear_category
var/gear_subcategory
@@ -824,6 +826,18 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "
"
if(3)
+ //calculate your gear points from the chosen item
+ gear_points = CONFIG_GET(number/initial_gear_points)
+ var/chosen_gear = loadout_data["SAVE_[loadout_slot]"]
+ if(chosen_gear)
+ for(var/loadout_data in chosen_gear)
+ var/loadout_item = loadout_data[LOADOUT_ITEM]
+ if(loadout_item)
+ var/datum/gear/loadout_gear = text2path(loadout_item)
+ gear_points -= loadout
+ else
+ chosen_gear = list()
+
dat += "
"
dat += "| [gear_points] loadout points remaining. \[Clear Loadout\] |
"
dat += "| You can only choose one item per category, unless it's an item that spawns in your backpack or hands. |
"
@@ -879,7 +893,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(donoritem && !gear.donator_ckey_check(user.ckey))
continue
var/class_link = ""
- if(gear.type in chosen_gear)
+ if(has_loadout_gear(chosen_gear, gear.type))
class_link = "style='white-space:normal;' class='linkOn' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(name)];toggle_gear=0'"
else if(gear_points <= 0)
class_link = "style='white-space:normal;' class='linkOff'"
@@ -2606,8 +2620,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
current_tab = text2num(href_list["tab"])
if(href_list["preference"] == "gear")
if(href_list["clear_loadout"])
- chosen_gear = list()
- gear_points = CONFIG_GET(number/initial_gear_points)
+ loadout_data["SAVE_[loadout_slot]"] = list()
save_preferences()
if(href_list["select_category"])
gear_category = html_decode(href_list["select_category"])
@@ -2620,10 +2633,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(!G)
return
var/toggle = text2num(href_list["toggle_gear"])
- if(!toggle && (G.type in chosen_gear))//toggling off and the item effectively is in chosen gear)
- chosen_gear -= G.type
- gear_points += initial(G.cost)
- else if(toggle && (!(is_type_in_ref_list(G, chosen_gear))))
+ if(!toggle && has_loadout_gear(chosen_gear, G.type))//toggling off and the item effectively is in chosen gear)
+ remove_gear_from_loadout(chosen_gear, G.type)
+ else if(toggle && (!(has_loadout_gear(chosen_gear, G.type))))
if(!is_loadout_slot_available(G.category))
to_chat(user, "You cannot take this loadout, as you've already chosen too many of the same category!")
return
@@ -2631,8 +2643,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
to_chat(user, "This is an item intended for donator use only. You are not authorized to use this item.")
return
if(gear_points >= initial(G.cost))
- chosen_gear += G.type
- gear_points -= initial(G.cost)
+ if(loadout_data["SAVE_[loadout_slot]"])
+ loadout_data["SAVE_[loadout_slot]"] += list(list(LOADOUT_ITEM = G.type)) //double packed because it does the union of the CONTENTS of the lists
+ else
+ loadout_data["SAVE_[loadout_slot]"] = list(list(LOADOUT_ITEM = G.type)) //double packed because you somehow had no save slot in your loadout?
ShowChoices(user)
return 1
@@ -2855,6 +2869,17 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(L[slot] < DEFAULT_SLOT_AMT)
return TRUE
+/datum/preferences/proc/has_loadout_gear(gear_list, gear_type)
+ for(var/loadout_gear in gear_list)
+ if(loadout_gear["ITEM"] == gear_type)
+ return loadout_gear
+ return FALSE
+
+/datum/preferences/proc/remove_gear_from_loadout(gear_list, gear_type)
+ var/find_gear = has_loadout_gear(gear_list, gear_type)
+ if(find_gear)
+ gear_list -= find_gear
+
#undef DEFAULT_SLOT_AMT
#undef HANDS_SLOT_AMT
#undef BACKPACK_SLOT_AMT
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 3bad31a919..d0f9e9cb73 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
-#define SAVEFILE_VERSION_MAX 38
+#define SAVEFILE_VERSION_MAX 40
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -226,6 +226,20 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
left_eye_color = "#BAB99E"
right_eye_color = "#BAB99E"
+ if(current_version < 40) //loadout save gets changed to json
+ var/text_to_load
+ S["loadout"] >> text_to_load
+ var/list/saved_loadout_paths = splittext(text_to_load, "|")
+ //MAXIMUM_LOADOUT_SAVES save slots per loadout now
+ for(var/i=1, i<= MAXIMUM_LOADOUT_SAVES, i++)
+ loadout_data["SAVE_[i]"] = list()
+ for(var/some_gear_item in saved_loadout_paths)
+ if(!ispath(some_gear_item))
+ message_admins("Failed to copy item [some_gear_item] to new loadout system when migrating from version [current_version] to 40, issue: item is not a path")
+ continue
+ loadout_data["SAVE_1"] += list(list(LOADOUT_ITEM = some_gear_item)) //for the migration we put their old save into the first save slot, which is loaded by default!
+ //it's double packed into a list because += will union the two lists contents
+
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
if(!ckey)
return
@@ -669,20 +683,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
var/list/json_from_file = json_decode(file2text(char_vr_path))
if(json_from_file)
belly_prefs = json_from_file["belly_prefs"]
+
//gear loadout
- var/text_to_load
- S["loadout"] >> text_to_load
- var/list/saved_loadout_paths = splittext(text_to_load, "|")
- chosen_gear = list()
- gear_points = CONFIG_GET(number/initial_gear_points)
- for(var/i in saved_loadout_paths)
- var/datum/gear/path = text2path(i)
- if(path)
- var/init_cost = initial(path.cost)
- if(init_cost > gear_points)
- continue
- chosen_gear += path
- gear_points -= init_cost
+ loadout_data = safe_json_decode(S["loadout"])
//try to fix any outdated data if necessary
//preference updating will handle saving the updated data for us.
@@ -962,11 +965,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//gear loadout
- if(chosen_gear.len)
- var/text_to_save = chosen_gear.Join("|")
- S["loadout"] << text_to_save
+ if(length(loadout_data))
+ S["loadout"] << safe_json_encode(loadout_data)
else
- S["loadout"] << "" //empty string to reset the value
+ S["loadout"] << safe_json_encode(list())
cit_character_pref_save(S)