Merge pull request #4480 from Citadel-Station-13/upstream-merge-33550
[MIRROR] Adds instanceless component dupe mode
This commit is contained in:
@@ -6,9 +6,10 @@
|
|||||||
|
|
||||||
// How multiple components of the exact same type are handled in the same datum
|
// How multiple components of the exact same type are handled in the same datum
|
||||||
|
|
||||||
#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default)
|
#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default)
|
||||||
#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed
|
#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed
|
||||||
#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted
|
#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted
|
||||||
|
#define COMPONENT_DUPE_UNIQUE_PASSARGS 4 //old component is given the initialization args of the new
|
||||||
|
|
||||||
// All signals. Format:
|
// All signals. Format:
|
||||||
// When the signal is called: (signal arguments)
|
// When the signal is called: (signal arguments)
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
|
|||||||
* `COMPONENT_DUPE_HIGHLANDER` (default): Old component will be deleted, new component will first have `/datum/component/proc/InheritComponent(datum/component/old, FALSE)` on it
|
* `COMPONENT_DUPE_HIGHLANDER` (default): Old component will be deleted, new component will first have `/datum/component/proc/InheritComponent(datum/component/old, FALSE)` on it
|
||||||
* `COMPONENT_DUPE_ALLOWED`: The components will be treated as separate, `GetComponent()` will return the first added
|
* `COMPONENT_DUPE_ALLOWED`: The components will be treated as separate, `GetComponent()` will return the first added
|
||||||
* `COMPONENT_DUPE_UNIQUE`: New component will be deleted, old component will first have `/datum/component/proc/InheritComponent(datum/component/new, TRUE)` on it
|
* `COMPONENT_DUPE_UNIQUE`: New component will be deleted, old component will first have `/datum/component/proc/InheritComponent(datum/component/new, TRUE)` on it
|
||||||
|
* `COMPONENT_DUPE_UNIQUE_PASSARGS`: New component will never exist and instead its initialization arguments will be passed on to the old component.
|
||||||
1. `/datum/component/var/dupe_type` (protected, type)
|
1. `/datum/component/var/dupe_type` (protected, type)
|
||||||
* Definition of a duplicate component type
|
* Definition of a duplicate component type
|
||||||
* `null` means exact match on `type` (default)
|
* `null` means exact match on `type` (default)
|
||||||
@@ -66,6 +67,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
|
|||||||
* All components a datum owns are deleted with the datum
|
* All components a datum owns are deleted with the datum
|
||||||
* Returns the component that was created. Or the old component in a dupe situation where `COMPONENT_DUPE_UNIQUE` was set
|
* Returns the component that was created. Or the old component in a dupe situation where `COMPONENT_DUPE_UNIQUE` was set
|
||||||
* If this tries to add an component to an incompatible type, the component will be deleted and the result will be `null`. This is very unperformant, try not to do it
|
* If this tries to add an component to an incompatible type, the component will be deleted and the result will be `null`. This is very unperformant, try not to do it
|
||||||
|
* Properly handles duplicate situations based on the `dupe_mode` var
|
||||||
1. `/datum/proc/LoadComponent(component_type(type), ...) -> datum/component` (public, final)
|
1. `/datum/proc/LoadComponent(component_type(type), ...) -> datum/component` (public, final)
|
||||||
* Equivalent to calling `GetComponent(component_type)` where, if the result would be `null`, returns `AddComponent(component_type, ...)` instead
|
* Equivalent to calling `GetComponent(component_type)` where, if the result would be `null`, returns `AddComponent(component_type, ...)` instead
|
||||||
1. `/datum/proc/ComponentActivated(datum/component/C)` (abstract, async)
|
1. `/datum/proc/ComponentActivated(datum/component/C)` (abstract, async)
|
||||||
@@ -104,9 +106,8 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
|
|||||||
* Allows the component to react to ownership transfers
|
* Allows the component to react to ownership transfers
|
||||||
1. `/datum/component/proc/_RemoveFromParent()` (private, final)
|
1. `/datum/component/proc/_RemoveFromParent()` (private, final)
|
||||||
* Clears `parent` and removes the component from it's component list
|
* Clears `parent` and removes the component from it's component list
|
||||||
1. `/datum/component/proc/_CheckDupesAndJoinParent` (private, final)
|
1. `/datum/component/proc/_JoinParent` (private, final)
|
||||||
* Tries to add the component to it's `parent`s `datum_components` list
|
* Tries to add the component to it's `parent`s `datum_components` list
|
||||||
* Properly handles duplicate situations based on the `dupe_mode` var
|
|
||||||
1. `/datum/component/proc/RegisterSignal(signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final) (Consider removing for performance gainz)
|
1. `/datum/component/proc/RegisterSignal(signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final) (Consider removing for performance gainz)
|
||||||
* If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments
|
* If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments
|
||||||
* Makes a component listen for the specified `signal` on it's `parent` datum.
|
* Makes a component listen for the specified `signal` on it's `parent` datum.
|
||||||
|
|||||||
@@ -6,54 +6,16 @@
|
|||||||
var/datum/parent
|
var/datum/parent
|
||||||
|
|
||||||
/datum/component/New(datum/P, ...)
|
/datum/component/New(datum/P, ...)
|
||||||
if(type == /datum/component)
|
|
||||||
qdel(src)
|
|
||||||
CRASH("[type] instantiated!")
|
|
||||||
|
|
||||||
//check for common mishaps
|
|
||||||
if(!isnum(dupe_mode))
|
|
||||||
qdel(src)
|
|
||||||
CRASH("[type]: Invalid dupe_mode!")
|
|
||||||
var/dt = dupe_type
|
|
||||||
if(dt && !ispath(dt))
|
|
||||||
qdel(src)
|
|
||||||
CRASH("[type]: Invalid dupe_type!")
|
|
||||||
|
|
||||||
parent = P
|
parent = P
|
||||||
var/list/arguments = args.Copy(2)
|
var/list/arguments = args.Copy(2)
|
||||||
if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE)
|
if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE)
|
||||||
qdel(src, TRUE, TRUE)
|
qdel(src, TRUE, TRUE)
|
||||||
return
|
return
|
||||||
|
|
||||||
_CheckDupesAndJoinParent(P)
|
_JoinParent(P)
|
||||||
|
|
||||||
/datum/component/proc/_CheckDupesAndJoinParent()
|
/datum/component/proc/_JoinParent()
|
||||||
var/datum/P = parent
|
var/datum/P = parent
|
||||||
var/dm = dupe_mode
|
|
||||||
|
|
||||||
var/datum/component/old
|
|
||||||
if(dm != COMPONENT_DUPE_ALLOWED)
|
|
||||||
var/dt = dupe_type
|
|
||||||
if(!dt)
|
|
||||||
old = P.GetExactComponent(type)
|
|
||||||
else
|
|
||||||
old = P.GetComponent(dt)
|
|
||||||
if(old)
|
|
||||||
//One or the other has to die
|
|
||||||
switch(dm)
|
|
||||||
if(COMPONENT_DUPE_UNIQUE)
|
|
||||||
old.InheritComponent(src, TRUE)
|
|
||||||
qdel(src, TRUE, TRUE)
|
|
||||||
return
|
|
||||||
if(COMPONENT_DUPE_HIGHLANDER)
|
|
||||||
InheritComponent(old, FALSE)
|
|
||||||
qdel(old, FALSE, TRUE)
|
|
||||||
|
|
||||||
//provided we didn't eat someone
|
|
||||||
if(!old)
|
|
||||||
//let the others know
|
|
||||||
P.SendSignal(COMSIG_COMPONENT_ADDED, src)
|
|
||||||
|
|
||||||
//lazy init the parent's dc list
|
//lazy init the parent's dc list
|
||||||
var/list/dc = P.datum_components
|
var/list/dc = P.datum_components
|
||||||
if(!dc)
|
if(!dc)
|
||||||
@@ -212,10 +174,59 @@
|
|||||||
return list(.)
|
return list(.)
|
||||||
|
|
||||||
/datum/proc/AddComponent(new_type, ...)
|
/datum/proc/AddComponent(new_type, ...)
|
||||||
var/nt = new_type
|
var/datum/component/nt = new_type
|
||||||
|
var/dm = initial(nt.dupe_mode)
|
||||||
|
var/dt = initial(nt.dupe_type)
|
||||||
|
|
||||||
|
var/datum/component/old_comp
|
||||||
|
var/datum/component/new_comp
|
||||||
|
|
||||||
|
if(ispath(nt))
|
||||||
|
if(nt == /datum/component)
|
||||||
|
CRASH("[nt] attempted instantiation!")
|
||||||
|
if(!isnum(dm))
|
||||||
|
CRASH("[nt]: Invalid dupe_mode ([dm])!")
|
||||||
|
if(dt && !ispath(dt))
|
||||||
|
CRASH("[nt]: Invalid dupe_type ([dt])!")
|
||||||
|
else
|
||||||
|
new_comp = nt
|
||||||
|
|
||||||
args[1] = src
|
args[1] = src
|
||||||
var/datum/component/C = new nt(arglist(args))
|
|
||||||
return QDELING(C) ? GetExactComponent(new_type) : C
|
if(dm != COMPONENT_DUPE_ALLOWED)
|
||||||
|
if(!dt)
|
||||||
|
old_comp = GetExactComponent(nt)
|
||||||
|
else
|
||||||
|
old_comp = GetComponent(dt)
|
||||||
|
if(old_comp)
|
||||||
|
switch(dm)
|
||||||
|
if(COMPONENT_DUPE_UNIQUE)
|
||||||
|
if(!new_comp)
|
||||||
|
new_comp = new nt(arglist(args))
|
||||||
|
if(!QDELETED(new_comp))
|
||||||
|
old_comp.InheritComponent(new_comp, TRUE)
|
||||||
|
qdel(new_comp)
|
||||||
|
if(COMPONENT_DUPE_HIGHLANDER)
|
||||||
|
if(!new_comp)
|
||||||
|
new_comp = new nt(arglist(args))
|
||||||
|
if(!QDELETED(new_comp))
|
||||||
|
new_comp.InheritComponent(old_comp, FALSE)
|
||||||
|
qdel(old_comp)
|
||||||
|
if(COMPONENT_DUPE_UNIQUE_PASSARGS)
|
||||||
|
if(!new_comp)
|
||||||
|
var/list/arguments = args.Copy(2)
|
||||||
|
old_comp.InheritComponent(null, TRUE, arguments)
|
||||||
|
else
|
||||||
|
old_comp.InheritComponent(new_comp, TRUE)
|
||||||
|
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)
|
||||||
|
new_comp = new nt(arglist(args)) // Dupes are allowed, act like normal
|
||||||
|
|
||||||
|
if(!old_comp && !QDELETED(new_comp)) // Nothing related to duplicate components happened and the new component is healthy
|
||||||
|
SendSignal(COMSIG_COMPONENT_ADDED, new_comp)
|
||||||
|
return new_comp
|
||||||
|
return old_comp
|
||||||
|
|
||||||
/datum/proc/LoadComponent(component_type, ...)
|
/datum/proc/LoadComponent(component_type, ...)
|
||||||
. = GetComponent(component_type)
|
. = GetComponent(component_type)
|
||||||
@@ -235,7 +246,8 @@
|
|||||||
C._RemoveFromParent()
|
C._RemoveFromParent()
|
||||||
helicopter.SendSignal(COMSIG_COMPONENT_REMOVING, C)
|
helicopter.SendSignal(COMSIG_COMPONENT_REMOVING, C)
|
||||||
C.parent = src
|
C.parent = src
|
||||||
C._CheckDupesAndJoinParent()
|
if(C == AddComponent(C))
|
||||||
|
C._JoinParent()
|
||||||
|
|
||||||
/datum/proc/TransferComponents(datum/target)
|
/datum/proc/TransferComponents(datum/target)
|
||||||
var/list/dc = datum_components
|
var/list/dc = datum_components
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#define RAD_AMOUNT_EXTREME 1000
|
#define RAD_AMOUNT_EXTREME 1000
|
||||||
|
|
||||||
/datum/component/radioactive
|
/datum/component/radioactive
|
||||||
dupe_mode = COMPONENT_DUPE_UNIQUE
|
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
|
||||||
|
|
||||||
var/source
|
var/source
|
||||||
|
|
||||||
@@ -47,13 +47,16 @@
|
|||||||
if(strength <= RAD_BACKGROUND_RADIATION)
|
if(strength <= RAD_BACKGROUND_RADIATION)
|
||||||
return PROCESS_KILL
|
return PROCESS_KILL
|
||||||
|
|
||||||
/datum/component/radioactive/InheritComponent(datum/component/C, i_am_original)
|
/datum/component/radioactive/InheritComponent(datum/component/C, i_am_original, list/arguments)
|
||||||
if(!i_am_original)
|
if(!i_am_original)
|
||||||
return
|
return
|
||||||
if(!hl3_release_date) // Permanently radioactive things don't get to grow stronger
|
if(!hl3_release_date) // Permanently radioactive things don't get to grow stronger
|
||||||
return
|
return
|
||||||
var/datum/component/radioactive/other = C
|
if(C)
|
||||||
strength = max(strength, other.strength)
|
var/datum/component/radioactive/other = C
|
||||||
|
strength = max(strength, other.strength)
|
||||||
|
else
|
||||||
|
strength = max(strength, arguments[1])
|
||||||
|
|
||||||
/datum/component/radioactive/proc/rad_examine(mob/user, atom/thing)
|
/datum/component/radioactive/proc/rad_examine(mob/user, atom/thing)
|
||||||
var/atom/master = parent
|
var/atom/master = parent
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/datum/component/thermite
|
/datum/component/thermite
|
||||||
dupe_mode = COMPONENT_DUPE_UNIQUE
|
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
|
||||||
var/amount
|
var/amount
|
||||||
var/overlay
|
var/overlay
|
||||||
|
|
||||||
@@ -46,10 +46,13 @@
|
|||||||
master.cut_overlay(overlay)
|
master.cut_overlay(overlay)
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/datum/component/thermite/InheritComponent(datum/component/thermite/newC, i_am_original)
|
/datum/component/thermite/InheritComponent(datum/component/thermite/newC, i_am_original, list/arguments)
|
||||||
if(!i_am_original)
|
if(!i_am_original)
|
||||||
return
|
return
|
||||||
amount += newC.amount
|
if(newC)
|
||||||
|
amount += newC.amount
|
||||||
|
else
|
||||||
|
amount += arguments[1]
|
||||||
|
|
||||||
/datum/component/thermite/proc/thermite_melt(mob/user)
|
/datum/component/thermite/proc/thermite_melt(mob/user)
|
||||||
var/turf/master = parent
|
var/turf/master = parent
|
||||||
|
|||||||
Reference in New Issue
Block a user