From 9ce2bdae8caf2e65800dc34505dfeec6977189bf Mon Sep 17 00:00:00 2001 From: spookydonut Date: Thu, 26 Dec 2019 14:02:27 +0800 Subject: [PATCH] COMPONENT_DUPE_SELECTIVE (#48021) * COMPONENT_DUPE_SELECTIVE * a * changes per review * webedit --- code/__DEFINES/components.dm | 2 ++ code/datums/components/_component.dm | 27 +++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 6d9cbf639d3..f4060495d61 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -34,6 +34,8 @@ #define COMPONENT_DUPE_UNIQUE 2 /// old component is given the initialization args of the new #define COMPONENT_DUPE_UNIQUE_PASSARGS 4 +/// each component of the same type is consulted as to whether the duplicate should be allowed +#define COMPONENT_DUPE_SELECTIVE 5 // All signals. Format: // When the signal is called: (signal arguments) diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index 13c8a733c28..88e13ae5ffe 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -233,6 +233,17 @@ /datum/component/proc/InheritComponent(datum/component/C, i_am_original) return + +/** + * Called on a component when a component of the same type was added to the same parent with COMPONENT_DUPE_SELECTIVE + * See `/datum/component/var/dupe_mode` + * `C`'s type will always be the same of the called component + * return TRUE if you are absorbing the component, otherwise FALSE if you are fine having it exist as a duplicate component + */ +/datum/component/proc/CheckDupeComponent(datum/component/C, ...) + return + + /** * Callback Just before this component is transferred * @@ -295,7 +306,7 @@ */ /datum/proc/GetComponent(datum/component/c_type) RETURN_TYPE(c_type) - if(initial(c_type.dupe_mode) == COMPONENT_DUPE_ALLOWED) + if(initial(c_type.dupe_mode) == COMPONENT_DUPE_ALLOWED || initial(c_type.dupe_mode) == COMPONENT_DUPE_SELECTIVE) stack_trace("GetComponent was called to get a component of which multiple copies could be on an object. This can easily break and should be changed. Type: \[[c_type]\]") var/list/dc = datum_components if(!dc) @@ -314,7 +325,7 @@ */ /datum/proc/GetExactComponent(datum/component/c_type) RETURN_TYPE(c_type) - if(initial(c_type.dupe_mode) == COMPONENT_DUPE_ALLOWED) + if(initial(c_type.dupe_mode) == COMPONENT_DUPE_ALLOWED || initial(c_type.dupe_mode) == COMPONENT_DUPE_SELECTIVE) stack_trace("GetComponent was called to get a component of which multiple copies could be on an object. This can easily break and should be changed. Type: \[[c_type]\]") var/list/dc = datum_components if(!dc) @@ -390,6 +401,18 @@ old_comp.InheritComponent(null, TRUE, arguments) else old_comp.InheritComponent(new_comp, TRUE) + if(COMPONENT_DUPE_SELECTIVE) + var/list/arguments = args.Copy() + arguments[1] = new_comp + var/make_new_component = TRUE + for(var/i in GetComponents(new_type)) + var/datum/component/C = i + if(C.CheckDupeComponent(arglist(arguments))) + make_new_component = FALSE + QDEL_NULL(new_comp) + break + if(!new_comp && make_new_component) + new_comp = new nt(arglist(args)) else if(!new_comp) new_comp = new nt(arglist(args)) // There's a valid dupe mode but there's no old component, act like normal else if(!new_comp)