diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 386d67fd..bab1e65d 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -98,4 +98,10 @@ #define ELEMENT_INCOMPATIBLE 1 // Return value to cancel attaching // /datum/element flags +/// Causes the detach proc to be called when the host object is being deleted #define ELEMENT_DETACH (1 << 0) +/** + * Only elements created with the same arguments given after `id_arg_index` share an element instance + * The arguments are the same when the text and number values are the same and all other values have the same ref + */ +#define ELEMENT_BESPOKE (1 << 1) diff --git a/code/controllers/subsystem/dcs.dm b/code/controllers/subsystem/dcs.dm index e94f233f..faf95fd3 100644 --- a/code/controllers/subsystem/dcs.dm +++ b/code/controllers/subsystem/dcs.dm @@ -6,10 +6,22 @@ PROCESSING_SUBSYSTEM_DEF(dcs) /datum/controller/subsystem/processing/dcs/Recover() comp_lookup = SSdcs.comp_lookup -/datum/controller/subsystem/processing/dcs/proc/GetElement(eletype) - . = elements_by_type[eletype] +/datum/controller/subsystem/processing/dcs/proc/GetElement(datum/element/eletype, ...) + var/element_id = eletype + + if(initial(eletype.element_flags) & ELEMENT_BESPOKE) + var/list/fullid = list("[eletype]") + for(var/i in initial(eletype.id_arg_index) to length(args)) + var/argument = args[i] + if(istext(argument) || isnum(argument)) + fullid += "[argument]" + else + fullid += "[REF(argument)]" + element_id = fullid.Join("&") + + . = elements_by_type[element_id] if(.) return if(!ispath(eletype, /datum/element)) CRASH("Attempted to instantiate [eletype] as a /datum/element") - . = elements_by_type[eletype] = new eletype \ No newline at end of file + . = elements_by_type[element_id] = new eletype \ No newline at end of file diff --git a/code/datums/elements/_element.dm b/code/datums/elements/_element.dm index 1a5b5148..17e2b122 100644 --- a/code/datums/elements/_element.dm +++ b/code/datums/elements/_element.dm @@ -1,5 +1,11 @@ /datum/element var/element_flags = NONE + /** + * The index of the first attach argument to consider for duplicate elements + * Is only used when flags contains ELEMENT_BESPOKE + * This is infinity so you must explicitly set this + */ + var/id_arg_index = INFINITY /datum/element/proc/Attach(datum/target) if(type == /datum/element) @@ -19,7 +25,7 @@ //DATUM PROCS /datum/proc/AddElement(eletype, ...) - var/datum/element/ele = SSdcs.GetElement(eletype) + var/datum/element/ele = SSdcs.GetElement(arglist(args)) args[1] = src if(ele.Attach(arglist(args)) == ELEMENT_INCOMPATIBLE) CRASH("Incompatible [eletype] assigned to a [type]! args: [json_encode(args)]")