From dd9116ee7073a92b5c47c4531804123a502e2c67 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Thu, 28 Nov 2019 01:47:20 +0100 Subject: [PATCH 1/2] Ports elements: Lightweight shared/global components. --- code/__DEFINES/components.dm | 7 +++- code/controllers/subsystem/dcs.dm | 15 ++++++-- code/controllers/subsystem/garbage.dm | 4 +- code/datums/components/earprotection.dm | 11 ------ code/datums/components/mood.dm | 2 +- code/datums/components/virtual_reality.dm | 6 +-- code/datums/elements/_element.dm | 29 +++++++++++++++ .../{components => elements}/cleaning.dm | 20 +++++----- 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 | 1 + code/modules/vehicles/pimpin_ride.dm | 4 +- tgstation.dme | 5 ++- 14 files changed, 110 insertions(+), 37 deletions(-) delete mode 100644 code/datums/components/earprotection.dm create mode 100644 code/datums/elements/_element.dm rename code/datums/{components => elements}/cleaning.dm (79%) create mode 100644 code/datums/elements/earhealing.dm diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index b79f1c2e59..9dad2926f8 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -5,6 +5,11 @@ #define COMPONENT_INCOMPATIBLE 1 #define COMPONENT_NOTRANSFER 2 +#define ELEMENT_INCOMPATIBLE 1 // Return value to cancel attaching + +// /datum/element flags +#define ELEMENT_DETACH (1 << 0) + // How multiple components of the exact same type are handled in the same datum #define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default) @@ -28,7 +33,7 @@ #define COMSIG_COMPONENT_ADDED "component_added" //when a component is added to a datum: (/datum/component) #define COMSIG_COMPONENT_REMOVING "component_removing" //before a component is removed from a datum because of RemoveComponent: (/datum/component) #define COMSIG_PARENT_PREQDELETED "parent_preqdeleted" //before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation -#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 #define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params) diff --git a/code/controllers/subsystem/dcs.dm b/code/controllers/subsystem/dcs.dm index c1e101a0e7..e94f233f04 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 eec9f63a12..f8ca1e7eae 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/earprotection.dm b/code/datums/components/earprotection.dm deleted file mode 100644 index 9256c4310a..0000000000 --- a/code/datums/components/earprotection.dm +++ /dev/null @@ -1,11 +0,0 @@ -/datum/component/wearertargeting/earprotection - signals = list(COMSIG_CARBON_SOUNDBANG) - mobtype = /mob/living/carbon - proctype = .proc/reducebang - -/datum/component/wearertargeting/earprotection/Initialize(_valid_slots) - . = ..() - valid_slots = _valid_slots - -/datum/component/wearertargeting/earprotection/proc/reducebang(datum/source, list/reflist) - reflist[1]-- diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index b46919a6c6..a0e6f97de0 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -248,7 +248,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/components/virtual_reality.dm b/code/datums/components/virtual_reality.dm index f8f0679e9b..7bad836e47 100644 --- a/code/datums/components/virtual_reality.dm +++ b/code/datums/components/virtual_reality.dm @@ -12,7 +12,7 @@ return COMPONENT_INCOMPATIBLE var/mob/vr_M = parent mastermind = M.mind - RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETED), .proc/game_over) + RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING), .proc/game_over) RegisterSignal(M, COMSIG_MOB_KEY_CHANGE, .proc/switch_player) RegisterSignal(mastermind, COMSIG_MIND_TRANSFER, .proc/switch_player) you_die_in_the_game_you_die_for_real = yolo @@ -32,7 +32,7 @@ current_mind = M.mind quit_action.Grant(M) RegisterSignal(quit_action, COMSIG_ACTION_TRIGGER, .proc/revert_to_reality) - RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETED), .proc/game_over) + RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING), .proc/game_over) RegisterSignal(M, COMSIG_MOB_GHOSTIZE, .proc/be_a_quitter) RegisterSignal(M, COMSIG_MOB_KEY_CHANGE, .proc/pass_me_the_remote) RegisterSignal(current_mind, COMSIG_MIND_TRANSFER, .proc/pass_me_the_remote) @@ -42,7 +42,7 @@ /datum/component/virtual_reality/UnregisterFromParent() quit_action.Remove(parent) - UnregisterSignal(parent, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETED, COMSIG_MOB_KEY_CHANGE, COMSIG_MOB_GHOSTIZE)) + UnregisterSignal(parent, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING, COMSIG_MOB_KEY_CHANGE, COMSIG_MOB_GHOSTIZE)) UnregisterSignal(current_mind, COMSIG_MIND_TRANSFER) UnregisterSignal(quit_action, COMSIG_ACTION_TRIGGER) current_mind = null diff --git a/code/datums/elements/_element.dm b/code/datums/elements/_element.dm new file mode 100644 index 0000000000..f12835d2e2 --- /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 79% rename from code/datums/components/cleaning.dm rename to code/datums/elements/cleaning.dm index 5324a87fee..e4fb3edd48 100644 --- a/code/datums/components/cleaning.dm +++ b/code/datums/elements/cleaning.dm @@ -1,13 +1,15 @@ -/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 +/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) @@ -43,4 +45,4 @@ cleaned_human.clean_blood() cleaned_human.wash_cream() cleaned_human.regenerate_icons() - to_chat(cleaned_human, "[src] cleans your face!") \ No newline at end of file + 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 0000000000..7477742673 --- /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 1dcaeb35fa..6775279ef6 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 c7aa882620..4f844151a2 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1098,9 +1098,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 5240b4d06c..bb51358192 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -168,6 +168,7 @@ /mob/living/simple_animal/hostile/alien/maid/Initialize(mapload) . = ..() + 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 31d0a243e7..c398b528d8 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 532422e792..f47c5bea71 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -354,11 +354,9 @@ #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" #include "code\datums\components\footstep.dm" @@ -464,6 +462,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" From 1795072f94ccba48012b6c9d01cc095621ba9f0e Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Thu, 28 Nov 2019 02:47:09 +0100 Subject: [PATCH 2/2] Mistakes were made. --- code/datums/components/earhealing.dm | 30 ------------------------- code/datums/components/earprotection.dm | 11 +++++++++ tgstation.dme | 2 +- 3 files changed, 12 insertions(+), 31 deletions(-) delete mode 100644 code/datums/components/earhealing.dm create mode 100644 code/datums/components/earprotection.dm diff --git a/code/datums/components/earhealing.dm b/code/datums/components/earhealing.dm deleted file mode 100644 index bd3d57480d..0000000000 --- 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/earprotection.dm b/code/datums/components/earprotection.dm new file mode 100644 index 0000000000..9256c4310a --- /dev/null +++ b/code/datums/components/earprotection.dm @@ -0,0 +1,11 @@ +/datum/component/wearertargeting/earprotection + signals = list(COMSIG_CARBON_SOUNDBANG) + mobtype = /mob/living/carbon + proctype = .proc/reducebang + +/datum/component/wearertargeting/earprotection/Initialize(_valid_slots) + . = ..() + valid_slots = _valid_slots + +/datum/component/wearertargeting/earprotection/proc/reducebang(datum/source, list/reflist) + reflist[1]-- diff --git a/tgstation.dme b/tgstation.dme index f47c5bea71..4b5d36399a 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -356,7 +356,7 @@ #include "code\datums\components\chasm.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" #include "code\datums\components\footstep.dm"