From 4714bd901238deeaa2c8edbc5d0e494b155fe5fc Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Thu, 28 Nov 2019 23:08:32 -0700
Subject: [PATCH] initial element
---
code/__DEFINES/components.dm | 8 +++-
code/controllers/subsystem/dcs.dm | 15 ++++++--
code/controllers/subsystem/garbage.dm | 4 +-
code/datums/components/earhealing.dm | 30 ---------------
code/datums/components/mood.dm | 2 +-
code/datums/elements/_element.dm | 29 +++++++++++++++
.../{components => elements}/cleaning.dm | 29 +++++++--------
code/datums/elements/earhealing.dm | 37 +++++++++++++++++++
code/modules/clothing/ears/_ears.dm | 2 +-
.../modules/mob/living/silicon/robot/robot.dm | 4 +-
.../mob/living/simple_animal/hostile/alien.dm | 2 +-
code/modules/vehicles/pimpin_ride.dm | 4 +-
tgstation.dme | 5 ++-
13 files changed, 110 insertions(+), 61 deletions(-)
delete mode 100644 code/datums/components/earhealing.dm
create mode 100644 code/datums/elements/_element.dm
rename code/datums/{components => elements}/cleaning.dm (64%)
create mode 100644 code/datums/elements/earhealing.dm
diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index d155f3f2..81155b29 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -25,8 +25,7 @@
//////////////////////////////////////////////////////////////////
// /datum signals
-#define COMSIG_PARENT_QDELETED "parent_qdeleted" //after a datum's Destroy() is called: (force, qdel_hint), at this point none of the other components chose to interrupt qdel and Destroy has been called
-
+#define COMSIG_PARENT_QDELETING "parent_qdeleting" //just before a datum's Destroy() is called: (force), at this point none of the other components chose to interrupt qdel and Destroy will be called
// /atom signals
//Positions for overrides list
//End positions
@@ -96,3 +95,8 @@
//Ouch my toes!
#define CALTROP_BYPASS_SHOES 1
#define CALTROP_IGNORE_WALKERS 2
+
+#define ELEMENT_INCOMPATIBLE 1 // Return value to cancel attaching
+
+// /datum/element flags
+#define ELEMENT_DETACH (1 << 0)
diff --git a/code/controllers/subsystem/dcs.dm b/code/controllers/subsystem/dcs.dm
index c1e101a0..e94f233f 100644
--- a/code/controllers/subsystem/dcs.dm
+++ b/code/controllers/subsystem/dcs.dm
@@ -1,6 +1,15 @@
-SUBSYSTEM_DEF(dcs)
+PROCESSING_SUBSYSTEM_DEF(dcs)
name = "Datum Component System"
- flags = SS_NO_INIT | SS_NO_FIRE
+ flags = SS_NO_INIT
+ var/list/elements_by_type = list()
-/datum/controller/subsystem/dcs/Recover()
+/datum/controller/subsystem/processing/dcs/Recover()
comp_lookup = SSdcs.comp_lookup
+
+/datum/controller/subsystem/processing/dcs/proc/GetElement(eletype)
+ . = elements_by_type[eletype]
+ 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
diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm
index eec9f63a..f8ca1e7e 100644
--- a/code/controllers/subsystem/garbage.dm
+++ b/code/controllers/subsystem/garbage.dm
@@ -98,7 +98,7 @@ SUBSYSTEM_DEF(garbage)
state = SS_RUNNING
break
-
+
/datum/controller/subsystem/garbage/proc/HandleQueue(level = GC_QUEUE_CHECK)
@@ -266,8 +266,8 @@ SUBSYSTEM_DEF(garbage)
D.gc_destroyed = GC_CURRENTLY_BEING_QDELETED
var/start_time = world.time
var/start_tick = world.tick_usage
+ SEND_SIGNAL(D, COMSIG_PARENT_QDELETING, force) // Let the (remaining) components know about the result of Destroy
var/hint = D.Destroy(arglist(args.Copy(2))) // Let our friend know they're about to get fucked up.
- SEND_SIGNAL(D, COMSIG_PARENT_QDELETED, force, hint) // Let the (remaining) components know about the result of Destroy
if(world.time != start_time)
I.slept_destroy++
else
diff --git a/code/datums/components/earhealing.dm b/code/datums/components/earhealing.dm
deleted file mode 100644
index bd3d5748..00000000
--- a/code/datums/components/earhealing.dm
+++ /dev/null
@@ -1,30 +0,0 @@
-// An item worn in the ear slot with this component will heal your ears each
-// Life() tick, even if normally your ears would be too damaged to heal.
-
-/datum/component/earhealing
- var/mob/living/carbon/wearer
-
-/datum/component/earhealing/Initialize()
- if(!isitem(parent))
- return COMPONENT_INCOMPATIBLE
- RegisterSignal(parent, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), .proc/equippedChanged)
-
-/datum/component/earhealing/proc/equippedChanged(datum/source, mob/living/carbon/user, slot)
- if (slot == SLOT_EARS && istype(user))
- if (!wearer)
- START_PROCESSING(SSobj, src)
- wearer = user
- else
- if (wearer)
- STOP_PROCESSING(SSobj, src)
- wearer = null
-
-/datum/component/earhealing/process()
- if (!wearer)
- STOP_PROCESSING(SSobj, src)
- return
- if(!HAS_TRAIT(wearer, TRAIT_DEAF))
- var/obj/item/organ/ears/ears = wearer.getorganslot(ORGAN_SLOT_EARS)
- if (ears)
- ears.deaf = max(ears.deaf - 1, (ears.damage < ears.maxHealth ? 0 : 1)) // Do not clear deafness if our ears are too damaged
- ears.damage = max(ears.damage - 0.1, 0)
diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm
index eb381af5..883dc656 100644
--- a/code/datums/components/mood.dm
+++ b/code/datums/components/mood.dm
@@ -280,7 +280,7 @@
var/datum/hud/hud = owner.hud_used
screen_obj = new
hud.infodisplay += screen_obj
- RegisterSignal(hud, COMSIG_PARENT_QDELETED, .proc/unmodify_hud)
+ RegisterSignal(hud, COMSIG_PARENT_QDELETING, .proc/unmodify_hud)
RegisterSignal(screen_obj, COMSIG_CLICK, .proc/hud_click)
/datum/component/mood/proc/unmodify_hud(datum/source)
diff --git a/code/datums/elements/_element.dm b/code/datums/elements/_element.dm
new file mode 100644
index 00000000..f12835d2
--- /dev/null
+++ b/code/datums/elements/_element.dm
@@ -0,0 +1,29 @@
+/datum/element
+ var/element_flags = NONE
+
+/datum/element/proc/Attach(datum/target)
+ if(type == /datum/element)
+ return ELEMENT_INCOMPATIBLE
+ if(element_flags & ELEMENT_DETACH)
+ RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/Detach)
+
+/datum/element/proc/Detach(datum/source, force)
+ UnregisterSignal(source, COMSIG_PARENT_QDELETING)
+
+/datum/element/Destroy(force)
+ if(!force)
+ return QDEL_HINT_LETMELIVE
+ SSdcs.elements_by_type -= type
+ return ..()
+
+//DATUM PROCS
+
+/datum/proc/AddElement(eletype, ...)
+ var/datum/element/ele = SSdcs.GetElement(eletype)
+ args[1] = src
+ if(ele.Attach(arglist(args)) == ELEMENT_INCOMPATIBLE)
+ CRASH("Incompatible [eletype] assigned to a [type]! args: [json_encode(args)]")
+
+/datum/proc/RemoveElement(eletype)
+ var/datum/element/ele = SSdcs.GetElement(eletype)
+ ele.Detach(src)
diff --git a/code/datums/components/cleaning.dm b/code/datums/elements/cleaning.dm
similarity index 64%
rename from code/datums/components/cleaning.dm
rename to code/datums/elements/cleaning.dm
index 05c26efc..02084a88 100644
--- a/code/datums/components/cleaning.dm
+++ b/code/datums/elements/cleaning.dm
@@ -1,19 +1,18 @@
-/datum/component/cleaning
- dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
+/datum/element/cleaning/Attach(datum/target)
+ . = ..()
+ if(!ismovableatom(target))
+ return ELEMENT_INCOMPATIBLE
+ RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/Clean)
-/datum/component/cleaning/Initialize()
- if(!ismovableatom(parent))
- return COMPONENT_INCOMPATIBLE
- RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/Clean)
+/datum/element/cleaning/Detach(datum/target)
+ . = ..()
+ UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
-/datum/component/cleaning/proc/Clean()
- var/atom/movable/AM = parent
- var/turf/tile = AM.loc
- if(!isturf(tile))
- return
-
- SEND_SIGNAL(tile, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- for(var/A in tile)
+/datum/element/cleaning/proc/Clean(datum/source)
+ var/atom/movable/AM = source
+ var/turf/T = AM.loc
+ SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ for(var/A in T)
if(is_cleanable(A))
qdel(A)
else if(istype(A, /obj/item))
@@ -36,4 +35,4 @@
SEND_SIGNAL(cleaned_human, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
cleaned_human.wash_cream()
cleaned_human.regenerate_icons()
- to_chat(cleaned_human, "[AM] cleans your face!")
+ to_chat(cleaned_human, "[src] cleans your face!")
diff --git a/code/datums/elements/earhealing.dm b/code/datums/elements/earhealing.dm
new file mode 100644
index 00000000..74777426
--- /dev/null
+++ b/code/datums/elements/earhealing.dm
@@ -0,0 +1,37 @@
+
+/datum/element/earhealing
+ element_flags = ELEMENT_DETACH
+ var/list/user_by_item = list()
+
+/datum/element/earhealing/New()
+ START_PROCESSING(SSdcs, src)
+
+/datum/element/earhealing/Attach(datum/target)
+ . = ..()
+ if(!isitem(target))
+ return ELEMENT_INCOMPATIBLE
+
+ RegisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), .proc/equippedChanged)
+
+/datum/element/earhealing/Detach(datum/target)
+ . = ..()
+ UnregisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED))
+ user_by_item -= target
+
+/datum/element/earhealing/proc/equippedChanged(datum/source, mob/living/carbon/user, slot)
+ if(slot == SLOT_EARS && istype(user))
+ user_by_item[source] = user
+ else
+ user_by_item -= source
+
+/datum/element/earhealing/process()
+ for(var/i in user_by_item)
+ var/mob/living/carbon/user = user_by_item[i]
+ if(HAS_TRAIT(user, TRAIT_DEAF))
+ continue
+ var/obj/item/organ/ears/ears = user.getorganslot(ORGAN_SLOT_EARS)
+ if(!ears)
+ continue
+ ears.deaf = max(ears.deaf - 0.25, (ears.damage < ears.maxHealth ? 0 : 1)) // Do not clear deafness if our ears are too damaged
+ ears.damage = max(ears.damage - 0.025, 0)
+ CHECK_TICK
diff --git a/code/modules/clothing/ears/_ears.dm b/code/modules/clothing/ears/_ears.dm
index 1dcaeb35..6775279e 100644
--- a/code/modules/clothing/ears/_ears.dm
+++ b/code/modules/clothing/ears/_ears.dm
@@ -18,7 +18,7 @@
/obj/item/clothing/ears/earmuffs/ComponentInitialize()
. = ..()
- AddComponent(/datum/component/earhealing)
+ AddElement(/datum/element/earhealing)
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
/obj/item/clothing/ears/headphones
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 29fbd39e..f066bdf1 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -1078,9 +1078,9 @@
status_flags &= ~CANPUSH
if(module.clean_on_move)
- AddComponent(/datum/component/cleaning)
+ AddElement(/datum/element/cleaning)
else
- qdel(GetComponent(/datum/component/cleaning))
+ RemoveElement(/datum/element/cleaning)
hat_offset = module.hat_offset
diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm
index 3d92912f..79a90132 100644
--- a/code/modules/mob/living/simple_animal/hostile/alien.dm
+++ b/code/modules/mob/living/simple_animal/hostile/alien.dm
@@ -168,7 +168,7 @@
/mob/living/simple_animal/hostile/alien/maid/Initialize(mapload)
. = ..()
- AddComponent(/datum/component/cleaning)
+ AddElement(/datum/element/cleaning)
/mob/living/simple_animal/hostile/alien/maid/AttackingTarget()
if(ismovableatom(target))
diff --git a/code/modules/vehicles/pimpin_ride.dm b/code/modules/vehicles/pimpin_ride.dm
index 53f60788..9d313e9b 100644
--- a/code/modules/vehicles/pimpin_ride.dm
+++ b/code/modules/vehicles/pimpin_ride.dm
@@ -14,7 +14,7 @@
D.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 7), TEXT_EAST = list(-12, 7), TEXT_WEST = list( 12, 7)))
if(floorbuffer)
- AddComponent(/datum/component/cleaning)
+ AddElement(/datum/element/cleaning)
/obj/vehicle/ridden/janicart/Destroy()
if(mybag)
@@ -50,7 +50,7 @@
floorbuffer = TRUE
qdel(I)
to_chat(user, "You upgrade [src] with the floor buffer.")
- AddComponent(/datum/component/cleaning)
+ AddElement(/datum/element/cleaning)
update_icon()
else
return ..()
diff --git a/tgstation.dme b/tgstation.dme
index 6c595015..c65c76ec 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -354,10 +354,8 @@
#include "code\datums\components\butchering.dm"
#include "code\datums\components\caltrop.dm"
#include "code\datums\components\chasm.dm"
-#include "code\datums\components\cleaning.dm"
#include "code\datums\components\construction.dm"
#include "code\datums\components\decal.dm"
-#include "code\datums\components\earhealing.dm"
#include "code\datums\components\earprotection.dm"
#include "code\datums\components\edit_complainer.dm"
#include "code\datums\components\empprotection.dm"
@@ -455,6 +453,9 @@
#include "code\datums\diseases\advance\symptoms\vomit.dm"
#include "code\datums\diseases\advance\symptoms\weight.dm"
#include "code\datums\diseases\advance\symptoms\youth.dm"
+#include "code\datums\elements\_element.dm"
+#include "code\datums\elements\cleaning.dm"
+#include "code\datums\elements\earhealing.dm"
#include "code\datums\helper_datums\events.dm"
#include "code\datums\helper_datums\getrev.dm"
#include "code\datums\helper_datums\icon_snapshot.dm"