diff --git a/code/__DEFINES/donator_groupings.dm b/code/__DEFINES/donator_groupings.dm new file mode 100644 index 0000000000..4b210609f2 --- /dev/null +++ b/code/__DEFINES/donator_groupings.dm @@ -0,0 +1,18 @@ +#define DONATOR_GROUP_TIER_1_CONFIG_PATH /datum/config_entry/keyed_list/donator_group/tier_1_donators +#define DONATOR_GROUP_TIER_2_CONFIG_PATH /datum/config_entry/keyed_list/donator_group/tier_2_donators +#define DONATOR_GROUP_TIER_3_CONFIG_PATH /datum/config_entry/keyed_list/donator_group/tier_3_donators + +#define DONATOR_GROUP_TIER_1_CONFIG_SUBPATH keyed_list/donator_group/tier_1_donators +#define DONATOR_GROUP_TIER_2_CONFIG_SUBPATH keyed_list/donator_group/tier_2_donators +#define DONATOR_GROUP_TIER_3_CONFIG_SUBPATH keyed_list/donator_group/tier_3_donators + +#define TIER_1_DONATORS CONFIG_GET(DONATOR_GROUP_TIER_1_CONFIG_SUBPATH) +#define TIER_2_DONATORS CONFIG_GET(DONATOR_GROUP_TIER_2_CONFIG_SUBPATH) +#define TIER_3_DONATORS CONFIG_GET(DONATOR_GROUP_TIER_3_CONFIG_SUBPATH) + +//flags +#define DONATOR_GROUP_TIER_1 "T1" +#define DONATOR_GROUP_TIER_2 "T2" +#define DONATOR_GROUP_TIER_3 "T3" + +#define IS_CKEY_DONATOR_GROUP(ckey, groupid) is_donator_group(ckey, groupid) diff --git a/code/__HELPERS/donator_groupings.dm b/code/__HELPERS/donator_groupings.dm new file mode 100644 index 0000000000..bdff20553a --- /dev/null +++ b/code/__HELPERS/donator_groupings.dm @@ -0,0 +1,25 @@ +/* +Current specifications: + +Donator groups in __DEFINES/donator_groupings.dm, config entries in controllers/configuration/entries/donator.dm + +3 groups, Tier 1/2/3 +Each tier includes the one before it (ascending) +For fast lookups, this is generated using regenerate_donator_grouping_list() + +*/ + +/proc/is_donator_group(ckey, group) + ckey = ckey(ckey) //make sure it's ckey'd. + var/list/L = GLOB.donators_by_group[group] + return L && L.Find(ckey) + +/proc/regenerate_donator_grouping_list() + GLOB.donators_by_group = list() //reinit everything + var/list/donator_list = GLOB.donators_by_group //cache + var/list/tier_1 = TIER_1_DONATORS + donator_list[DONATOR_GROUP_TIER_1] = tier_1.Copy() //The .Copy() is to "decouple"/make a new list, rather than letting the global list impact the config list. + var/list/tier_2 = tier_1 + TIER_2_DONATORS //Using + on lists implies making new lists, so we don't need to manually Copy(). + donator_list[DONATOR_GROUP_TIER_2] = tier_2 + var/list/tier_3 = tier_2 + TIER_3_DONATORS + donator_list[DONATOR_GROUP_TIER_3] = tier_3 diff --git a/code/_globalvars/lists/misc.dm b/code/_globalvars/lists/misc.dm new file mode 100644 index 0000000000..1dcde53a72 --- /dev/null +++ b/code/_globalvars/lists/misc.dm @@ -0,0 +1 @@ +GLOBAL_LIST_EMPTY(donators_by_group) //group id = donator list of ckeys diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm index 49ff1c8d49..3ac103affc 100644 --- a/code/controllers/configuration/config_entry.dm +++ b/code/controllers/configuration/config_entry.dm @@ -19,6 +19,7 @@ var/abstract_type = /datum/config_entry //do not instantiate if type matches this var/vv_VAS = TRUE //Force validate and set on VV. VAS proccall guard will run regardless. + var/postload_required = FALSE //requires running OnPostload() var/dupes_allowed = FALSE @@ -72,6 +73,9 @@ /datum/config_entry/proc/DeprecationUpdate(value) return +/datum/config_entry/proc/OnPostload() + return + /datum/config_entry/string config_entry_value = "" abstract_type = /datum/config_entry/string @@ -80,7 +84,7 @@ /datum/config_entry/string/vv_edit_var(var_name, var_value) return var_name != "auto_trim" && ..() -/datum/config_entry/string/ValidateAndSet(str_val) +/datum/config_entry/string/ValidateAndSet(str_val, during_load) if(!VASProcCallGuard(str_val)) return FALSE config_entry_value = auto_trim ? trim(str_val) : str_val diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index 0232081c1a..ea2919f342 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -101,6 +101,7 @@ log_config("Loading config file [filename]...") var/list/lines = world.file2list("[directory]/[filename]") var/list/_entries = entries + var/list/postload_required = list() for(var/L in lines) L = trim(L) if(!L) @@ -157,18 +158,24 @@ else warning("[new_ver.type] is deprecated but gave no proper return for DeprecationUpdate()") - var/validated = E.ValidateAndSet(value) + var/validated = E.ValidateAndSet(value, TRUE) if(!validated) log_config("Failed to validate setting \"[value]\" for [entry]") else if(E.modified && !E.dupes_allowed) log_config("Duplicate setting for [entry] ([value], [E.resident_file]) detected! Using latest.") + if(E.postload_required) + postload_required[E] = TRUE E.resident_file = filename if(validated) E.modified = TRUE + for(var/i in postload_required) + var/datum/config_entry/E = i + E.OnPostload() + ++. /datum/controller/configuration/can_vv_get(var_name) diff --git a/code/controllers/configuration/entries/donator.dm b/code/controllers/configuration/entries/donator.dm new file mode 100644 index 0000000000..b74d5f5839 --- /dev/null +++ b/code/controllers/configuration/entries/donator.dm @@ -0,0 +1,22 @@ +/datum/config_entry/keyed_list/donator_group + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_FLAG + abstract_type = /datum/config_entry/keyed_list/donator_group + +//If we're in the middle of a config load, only do the regeneration afterwards to prevent this from wasting a massive amount of CPU for list regenerations. +/datum/config_entry/keyed_list/donator_group/ValidateAndSet(str_val, during_load) + . = ..() + if(. && during_load) + regenerate_donator_grouping_list() + +/datum/config_entry/keyed_list/donator_group/OnPostload() + . = ..() + regenerate_donator_grouping_list() + +//This is kinda weird in that the config entries are defined here but all the handling/calculations are in __HELPERS/donator_groupings.dm + +/datum/config_entry/keyed_list/donator_group/tier_1_donators + +/datum/config_entry/keyed_list/donator_group/tier_2_donators + +/datum/config_entry/keyed_list/donator_group/tier_3_donators diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 64a1f48962..d487b873b1 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -919,11 +919,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Description" for(var/j in GLOB.loadout_items[gear_tab]) var/datum/gear/gear = GLOB.loadout_items[gear_tab][j] - var/donoritem - if(gear.ckeywhitelist && gear.ckeywhitelist.len) - donoritem = TRUE - if(!(user.ckey in gear.ckeywhitelist)) - continue + var/donoritem = gear.donoritem + if(donoritem && !gear.donator_ckey_check(user.ckey)) + continue var/class_link = "" if(gear.type in chosen_gear) class_link = "style='white-space:normal;' class='linkOn' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(j)];toggle_gear=0'" @@ -2245,7 +2243,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) 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 - if(G.ckeywhitelist && G.ckeywhitelist.len && !(user.ckey in G.ckeywhitelist)) + if(G.donoritem && !G.donator_ckey_check(user.ckey)) 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)) diff --git a/config/config.txt b/config/config.txt index 3bc9f873a9..a01f5424da 100644 --- a/config/config.txt +++ b/config/config.txt @@ -4,6 +4,7 @@ $include game_options.txt $include dbconfig.txt $include comms.txt $include antag_rep.txt +$include donator_groupings.txt # You can use the @ character at the beginning of a config option to lock it from being edited in-game # Example usage: diff --git a/config/donator_groupings.txt b/config/donator_groupings.txt new file mode 100644 index 0000000000..b26d1efe22 --- /dev/null +++ b/config/donator_groupings.txt @@ -0,0 +1,8 @@ +#this is a bad system but I'm lazy so it piggybacks off config loader system. +#Specify group followed by ckey for each ckey. + +#TIER_1_DONATORS test_ckey + +#TIER_2_DONATORS test_ckey + +#TIER_3_DONATORS test_ckey diff --git a/modular_citadel/code/controllers/subsystem/job.dm b/modular_citadel/code/controllers/subsystem/job.dm index c433042ae6..46aef6f529 100644 --- a/modular_citadel/code/controllers/subsystem/job.dm +++ b/modular_citadel/code/controllers/subsystem/job.dm @@ -13,7 +13,7 @@ var/permitted = TRUE if(G.restricted_roles && G.restricted_roles.len && !(M.mind.assigned_role in G.restricted_roles)) permitted = FALSE - if(G.ckeywhitelist && G.ckeywhitelist.len && !(the_mob.client.ckey in G.ckeywhitelist)) + if(G.donoritem && !G.donator_ckey_check(the_mob.client.ckey)) permitted = FALSE if(!equipbackpackstuff && G.category == SLOT_IN_BACKPACK)//snowflake check since plopping stuff in the backpack doesnt work for pre-job equip loadout stuffs permitted = FALSE diff --git a/modular_citadel/code/modules/client/loadout/loadout.dm b/modular_citadel/code/modules/client/loadout/_loadout.dm similarity index 79% rename from modular_citadel/code/modules/client/loadout/loadout.dm rename to modular_citadel/code/modules/client/loadout/_loadout.dm index 2e11519d0b..d48da1b863 100644 --- a/modular_citadel/code/modules/client/loadout/loadout.dm +++ b/modular_citadel/code/modules/client/loadout/_loadout.dm @@ -50,12 +50,32 @@ GLOBAL_LIST_EMPTY(loadout_whitelist_ids) var/path //item-to-spawn path var/cost = 1 //normally, each loadout costs a single point. var/geargroupID //defines the ID that the gear inherits from the config + + //NEW DONATOR SYTSEM STUFF + var/donoritem //autoset on new if null + var/donator_group_id //New donator group ID system. + //END + var/list/restricted_roles + + //Old donator system/snowflake ckey whitelist, used for single ckeys/exceptions var/list/ckeywhitelist + //END + var/restricted_desc /datum/gear/New() - ..() + if(isnull(donoritem)) + if(donator_group_id || ckeywhitelist) + donoritem = TRUE if(!description && path) var/obj/O = path description = initial(O.desc) + +//a comprehensive donator check proc is intentionally not implemented due to the fact that we (((might))) have job-whitelists for donator items in the future and I like to stay on the safe side. + +//ckey only check +/datum/gear/proc/donator_ckey_check(key) + if(ckeywhitelist && ckeywhitelist.Find(key)) + return TRUE + return IS_CKEY_DONATOR_GROUP(key, donator_group_id) diff --git a/tgstation.dme b/tgstation.dme index bc1c1a134b..f2ff65e3ff 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -41,6 +41,7 @@ #include "code\__DEFINES\cult.dm" #include "code\__DEFINES\diseases.dm" #include "code\__DEFINES\DNA.dm" +#include "code\__DEFINES\donator_groupings.dm" #include "code\__DEFINES\events.dm" #include "code\__DEFINES\exports.dm" #include "code\__DEFINES\flags.dm" @@ -115,6 +116,7 @@ #include "code\__HELPERS\AStar.dm" #include "code\__HELPERS\cmp.dm" #include "code\__HELPERS\dates.dm" +#include "code\__HELPERS\donator_groupings.dm" #include "code\__HELPERS\files.dm" #include "code\__HELPERS\game.dm" #include "code\__HELPERS\global_lists.dm" @@ -159,6 +161,7 @@ #include "code\_globalvars\lists\maintenance_loot.dm" #include "code\_globalvars\lists\mapping.dm" #include "code\_globalvars\lists\medals.dm" +#include "code\_globalvars\lists\misc.dm" #include "code\_globalvars\lists\mobs.dm" #include "code\_globalvars\lists\names.dm" #include "code\_globalvars\lists\objects.dm" @@ -218,6 +221,7 @@ #include "code\controllers\configuration\configuration.dm" #include "code\controllers\configuration\entries\comms.dm" #include "code\controllers\configuration\entries\dbconfig.dm" +#include "code\controllers\configuration\entries\donator.dm" #include "code\controllers\configuration\entries\game_options.dm" #include "code\controllers\configuration\entries\general.dm" #include "code\controllers\subsystem\acid.dm" @@ -2939,6 +2943,7 @@ #include "modular_citadel\code\modules\client\preferences_savefile.dm" #include "modular_citadel\code\modules\client\preferences_toggles.dm" #include "modular_citadel\code\modules\client\loadout\__donator.dm" +#include "modular_citadel\code\modules\client\loadout\_loadout.dm" #include "modular_citadel\code\modules\client\loadout\_medical.dm" #include "modular_citadel\code\modules\client\loadout\_security.dm" #include "modular_citadel\code\modules\client\loadout\_service.dm" @@ -2947,7 +2952,6 @@ #include "modular_citadel\code\modules\client\loadout\gloves.dm" #include "modular_citadel\code\modules\client\loadout\hands.dm" #include "modular_citadel\code\modules\client\loadout\head.dm" -#include "modular_citadel\code\modules\client\loadout\loadout.dm" #include "modular_citadel\code\modules\client\loadout\mask.dm" #include "modular_citadel\code\modules\client\loadout\neck.dm" #include "modular_citadel\code\modules\client\loadout\shoes.dm"