diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 3def1e0390c..ca988698e47 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -62,7 +62,11 @@
# ninjanomnom
+/code/__DEFINES/dcs/ @ninjanomnom
+/code/controllers/subsystem/dcs.dm @ninjanomnom
/code/controllers/subsystem/shuttle.dm @ninjanomnom
+/code/datums/components/ @ninjanomnom
+/code/datums/elements/ @ninjanomnom
/code/modules/shuttle/ @ninjanomnom
# ShizCalev
@@ -83,10 +87,7 @@
# Multiple Owners
-/code/__DEFINES/components.dm @Cyberboss @ninjanomnom
/code/controllers/subsystem/air.dm @duncathan @MrStonedOne
-/code/datums/components/ @Cyberboss @ninjanomnom
-
#SIC SEMPER TYRANNIS
/code/modules/hydroponics/grown/citrus.dm @optimumtact
diff --git a/_maps/RandomZLevels/Academy.dmm b/_maps/RandomZLevels/Academy.dmm
index 7fa61edd43b..7b0f7df9201 100644
--- a/_maps/RandomZLevels/Academy.dmm
+++ b/_maps/RandomZLevels/Academy.dmm
@@ -3139,7 +3139,7 @@
/area/awaymission/academy/academyengine)
"mn" = (
/obj/structure/rack,
-/obj/item/gun/magic/wand,
+/obj/item/gun/magic/wand/nothing,
/turf/open/floor/plating,
/area/awaymission/academy/academyengine)
"mo" = (
diff --git a/_maps/map_files/Donutstation/Donutstation.dmm b/_maps/map_files/Donutstation/Donutstation.dmm
index 38425689ec1..079cbc7b9d7 100644
--- a/_maps/map_files/Donutstation/Donutstation.dmm
+++ b/_maps/map_files/Donutstation/Donutstation.dmm
@@ -18035,8 +18035,8 @@
},
/area/medical/genetics)
"aYg" = (
-/mob/living/carbon/monkey,
/obj/effect/landmark/start/geneticist,
+/mob/living/carbon/monkey,
/turf/open/floor/plasteel,
/area/medical/genetics)
"aYh" = (
@@ -38797,7 +38797,7 @@
dir = 8
},
/obj/item/toy/figure/mime,
-/obj/item/gun/magic/wand,
+/obj/item/gun/magic/wand/nothing,
/turf/open/floor/carpet,
/area/crew_quarters/theatre)
"cad" = (
diff --git a/_maps/multiz_debug.json b/_maps/multiz_debug.json
index a3e11abe7b6..e8a474161e7 100644
--- a/_maps/multiz_debug.json
+++ b/_maps/multiz_debug.json
@@ -2,5 +2,5 @@
"map_name": "MultiZ Debug",
"map_path": "map_files/debug",
"map_file": "multiz.dmm",
- "traits": [{"Up": 1}, {"Up": 1, "Down": -1, "Baseturf" : "/turf/open/openspace"}, {"Down": -1, "Baseturf" : "/turf/open/openspace"}]
+ "traits": [{"Up" : 1, "Linkage" : "Cross"}, {"Up" : 1, "Down" : -1, "Baseturf" : "/turf/open/openspace", "Linkage" : "Cross"}, {"Down" : -1, "Baseturf" : "/turf/open/openspace", "Linkage" : "Cross"}]
}
diff --git a/code/__DEFINES/dcs/flags.dm b/code/__DEFINES/dcs/flags.dm
new file mode 100644
index 00000000000..128c9f19387
--- /dev/null
+++ b/code/__DEFINES/dcs/flags.dm
@@ -0,0 +1,41 @@
+/// Return this from `/datum/component/Initialize` or `datum/component/OnTransfer` to have the component be deleted if it's applied to an incorrect type.
+/// `parent` must not be modified if this is to be returned.
+/// This will be noted in the runtime logs
+#define COMPONENT_INCOMPATIBLE 1
+/// Returned in PostTransfer to prevent transfer, similar to `COMPONENT_INCOMPATIBLE`
+#define COMPONENT_NOTRANSFER 2
+
+/// Return value to cancel attaching
+#define ELEMENT_INCOMPATIBLE 1
+
+// /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)
+
+// How multiple components of the exact same type are handled in the same datum
+/// old component is deleted (default)
+#define COMPONENT_DUPE_HIGHLANDER 0
+/// duplicates allowed
+#define COMPONENT_DUPE_ALLOWED 1
+/// new component is deleted
+#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
+
+//Redirection component init flags
+#define REDIRECT_TRANSFER_WITH_TURF 1
+
+//Arch
+#define ARCH_PROB "probability" //Probability for each item
+#define ARCH_MAXDROP "max_drop_amount" //each item's max drop amount
+
+//Ouch my toes!
+#define CALTROP_BYPASS_SHOES 1
+#define CALTROP_IGNORE_WALKERS 2
diff --git a/code/__DEFINES/dcs/helpers.dm b/code/__DEFINES/dcs/helpers.dm
new file mode 100644
index 00000000000..144e94f1fe0
--- /dev/null
+++ b/code/__DEFINES/dcs/helpers.dm
@@ -0,0 +1,15 @@
+/// Used to trigger signals and call procs registered for that signal
+/// The datum hosting the signal is automaticaly added as the first argument
+/// Returns a bitfield gathered from all registered procs
+/// Arguments given here are packaged in a list and given to _SendSignal
+#define SEND_SIGNAL(target, sigtype, arguments...) ( !target.comp_lookup || !target.comp_lookup[sigtype] ? NONE : target._SendSignal(sigtype, list(target, ##arguments)) )
+
+#define SEND_GLOBAL_SIGNAL(sigtype, arguments...) ( SEND_SIGNAL(SSdcs, sigtype, ##arguments) )
+
+/// A wrapper for _AddElement that allows us to pretend we're using normal named arguments
+#define AddElement(arguments...) _AddElement(list(##arguments))
+/// A wrapper for _RemoveElement that allows us to pretend we're using normal named arguments
+#define RemoveElement(arguments...) _RemoveElement(list(##arguments))
+
+/// A wrapper for _AddComponent that allows us to pretend we're using normal named arguments
+#define AddComponent(arguments...) _AddComponent(list(##arguments))
diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/dcs/signals.dm
similarity index 91%
rename from code/__DEFINES/components.dm
rename to code/__DEFINES/dcs/signals.dm
index badaaef9ce8..99637bb28c9 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -1,442 +1,391 @@
-/// Used to trigger signals and call procs registered for that signal
-/// The datum hosting the signal is automaticaly added as the first argument
-/// Returns a bitfield gathered from all registered procs
-/// Arguments given here are packaged in a list and given to _SendSignal
-#define SEND_SIGNAL(target, sigtype, arguments...) ( !target.comp_lookup || !target.comp_lookup[sigtype] ? NONE : target._SendSignal(sigtype, list(target, ##arguments)) )
-
-#define SEND_GLOBAL_SIGNAL(sigtype, arguments...) ( SEND_SIGNAL(SSdcs, sigtype, ##arguments) )
-
-/// Return this from `/datum/component/Initialize` or `datum/component/OnTransfer` to have the component be deleted if it's applied to an incorrect type.
-/// `parent` must not be modified if this is to be returned.
-/// This will be noted in the runtime logs
-#define COMPONENT_INCOMPATIBLE 1
-/// Returned in PostTransfer to prevent transfer, similar to `COMPONENT_INCOMPATIBLE`
-#define COMPONENT_NOTRANSFER 2
-
-/// Return value to cancel attaching
-#define ELEMENT_INCOMPATIBLE 1
-
-// /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)
-
-// How multiple components of the exact same type are handled in the same datum
-/// old component is deleted (default)
-#define COMPONENT_DUPE_HIGHLANDER 0
-/// duplicates allowed
-#define COMPONENT_DUPE_ALLOWED 1
-/// new component is deleted
-#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)
-// All signals send the source datum of the signal as the first argument
-
-// global signals
-// These are signals which can be listened to by any component on any parent
-// start global signals with "!", this used to be necessary but now it's just a formatting choice
-/// from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args)
-#define COMSIG_GLOB_NEW_Z "!new_z"
-/// called after a successful var edit somewhere in the world: (list/args)
-#define COMSIG_GLOB_VAR_EDIT "!var_edit"
-/// called after an explosion happened : (epicenter, devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range)
-#define COMSIG_GLOB_EXPLOSION "!explosion"
-/// mob was created somewhere : (mob)
-#define COMSIG_GLOB_MOB_CREATED "!mob_created"
-/// mob died somewhere : (mob , gibbed)
-#define COMSIG_GLOB_MOB_DEATH "!mob_death"
-/// global living say plug - use sparingly: (mob/speaker , message)
-#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special"
-/// called by datum/cinematic/play() : (datum/cinematic/new_cinematic)
-#define COMSIG_GLOB_PLAY_CINEMATIC "!play_cinematic"
- #define COMPONENT_GLOB_BLOCK_CINEMATIC 1
-/// ingame button pressed (/obj/machinery/button/button)
-#define COMSIG_GLOB_BUTTON_PRESSED "!button_pressed"
-
-// signals from globally accessible objects
-/// from SSsun when the sun changes position : (azimuth)
-#define COMSIG_SUN_MOVED "sun_moved"
-
-//////////////////////////////////////////////////////////////////
-
-// /datum signals
-/// when a component is added to a datum: (/datum/component)
-#define COMSIG_COMPONENT_ADDED "component_added"
-/// before a component is removed from a datum because of RemoveComponent: (/datum/component)
-#define COMSIG_COMPONENT_REMOVING "component_removing"
-/// before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation
-#define COMSIG_PARENT_PREQDELETED "parent_preqdeleted"
-/// 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
-#define COMSIG_PARENT_QDELETING "parent_qdeleting"
-/// generic topic handler (usr, href_list)
-#define COMSIG_TOPIC "handle_topic"
-
-// /atom signals
-#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params)
- #define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called
-#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human)
-#define COMSIG_ATOM_ATTACK_ANIMAL "attack_animal" //from base of atom/animal_attack(): (/mob/user)
-#define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob)
-#define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name" //from base of atom/get_examine_name(): (/mob, list/overrides)
- //Positions for overrides list
- #define EXAMINE_POSITION_ARTICLE 1
- #define EXAMINE_POSITION_BEFORE 2
- //End positions
- #define COMPONENT_EXNAME_CHANGED 1
-#define COMSIG_ATOM_UPDATE_ICON "atom_update_icon" //from base of atom/update_icon(): ()
- #define COMSIG_ATOM_NO_UPDATE_ICON_STATE 1
- #define COMSIG_ATOM_NO_UPDATE_OVERLAYS 2
-#define COMSIG_ATOM_UPDATE_OVERLAYS "atom_update_overlays" //from base of atom/update_overlays(): (list/new_overlays)
-#define COMSIG_ATOM_UPDATED_ICON "atom_updated_icon" //from base of atom/update_icon(): (signalOut, did_anything)
-#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable/entering, /atom)
-#define COMSIG_ATOM_EXIT "atom_exit" //from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc)
- #define COMPONENT_ATOM_BLOCK_EXIT 1
-#define COMSIG_ATOM_EXITED "atom_exited" //from base of atom/Exited(): (atom/movable/exiting, atom/newloc)
-#define COMSIG_ATOM_BUMPED "atom_bumped" //from base of atom/Bumped(): (/atom/movable)
-#define COMSIG_ATOM_EX_ACT "atom_ex_act" //from base of atom/ex_act(): (severity, target)
-#define COMSIG_ATOM_EMP_ACT "atom_emp_act" //from base of atom/emp_act(): (severity)
-#define COMSIG_ATOM_FIRE_ACT "atom_fire_act" //from base of atom/fire_act(): (exposed_temperature, exposed_volume)
-#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act" //from base of atom/bullet_act(): (/obj/projectile, def_zone)
-#define COMSIG_ATOM_BLOB_ACT "atom_blob_act" //from base of atom/blob_act(): (/obj/structure/blob)
-#define COMSIG_ATOM_ACID_ACT "atom_acid_act" //from base of atom/acid_act(): (acidpwr, acid_volume)
-#define COMSIG_ATOM_EMAG_ACT "atom_emag_act" //from base of atom/emag_act(): (/mob/user)
-#define COMSIG_ATOM_RAD_ACT "atom_rad_act" //from base of atom/rad_act(intensity)
-#define COMSIG_ATOM_NARSIE_ACT "atom_narsie_act" //from base of atom/narsie_act(): ()
-#define COMSIG_ATOM_RCD_ACT "atom_rcd_act" //from base of atom/rcd_act(): (/mob, /obj/item/construction/rcd, passed_mode)
-#define COMSIG_ATOM_SING_PULL "atom_sing_pull" //from base of atom/singularity_pull(): (S, current_size)
-#define COMSIG_ATOM_BSA_BEAM "atom_bsa_beam_pass" //from obj/machinery/bsa/full/proc/fire(): ()
- #define COMSIG_ATOM_BLOCKS_BSA_BEAM 1
-#define COMSIG_ATOM_SET_LIGHT "atom_set_light" //from base of atom/set_light(): (l_range, l_power, l_color)
-#define COMSIG_ATOM_DIR_CHANGE "atom_dir_change" //from base of atom/setDir(): (old_dir, new_dir)
-#define COMSIG_ATOM_CONTENTS_DEL "atom_contents_del" //from base of atom/handle_atom_del(): (atom/deleted)
-#define COMSIG_ATOM_HAS_GRAVITY "atom_has_gravity" //from base of atom/has_gravity(): (turf/location, list/forced_gravities)
-#define COMSIG_ATOM_RAD_PROBE "atom_rad_probe" //from proc/get_rad_contents(): ()
- #define COMPONENT_BLOCK_RADIATION 1
-#define COMSIG_ATOM_RAD_CONTAMINATING "atom_rad_contam" //from base of datum/radiation_wave/radiate(): (strength)
- #define COMPONENT_BLOCK_CONTAMINATION 1
-#define COMSIG_ATOM_RAD_WAVE_PASSING "atom_rad_wave_pass" //from base of datum/radiation_wave/check_obstructions(): (datum/radiation_wave, width)
- #define COMPONENT_RAD_WAVE_HANDLED 1
-#define COMSIG_ATOM_CANREACH "atom_can_reach" //from internal loop in atom/movable/proc/CanReach(): (list/next)
- #define COMPONENT_BLOCK_REACH 1
-#define COMSIG_ATOM_SCREWDRIVER_ACT "atom_screwdriver_act" //from base of atom/screwdriver_act(): (mob/living/user, obj/item/I)
-#define COMSIG_ATOM_WRENCH_ACT "atom_wrench_act" //from base of atom/wrench_act(): (mob/living/user, obj/item/I)
-#define COMSIG_ATOM_MULTITOOL_ACT "atom_multitool_act" //from base of atom/multitool_act(): (mob/living/user, obj/item/I)
-#define COMSIG_ATOM_WELDER_ACT "atom_welder_act" //from base of atom/welder_act(): (mob/living/user, obj/item/I)
-#define COMSIG_ATOM_WIRECUTTER_ACT "atom_wirecutter_act" //from base of atom/wirecutter_act(): (mob/living/user, obj/item/I)
-#define COMSIG_ATOM_CROWBAR_ACT "atom_crowbar_act" //from base of atom/crowbar_act(): (mob/living/user, obj/item/I)
-#define COMSIG_ATOM_ANALYSER_ACT "atom_analyser_act" //from base of atom/analyser_act(): (mob/living/user, obj/item/I)
- #define COMPONENT_BLOCK_TOOL_ATTACK 1
-#define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport" //called when teleporting into a protected turf: (channel, turf/origin)
- #define COMPONENT_BLOCK_TELEPORT 1
-#define COMSIG_ATOM_HEARER_IN_VIEW "atom_hearer_in_view" //called when an atom is added to the hearers on get_hearers_in_view(): (list/processing_list, list/hearers)
-#define COMSIG_ATOM_ORBIT_BEGIN "atom_orbit_begin" //called when an atom starts orbiting another atom: (atom)
-#define COMSIG_ATOM_ORBIT_STOP "atom_orbit_stop" //called when an atom stops orbiting another atom: (atom)
-/////////////////
-#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" //from base of atom/attack_ghost(): (mob/dead/observer/ghost)
-#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" //from base of atom/attack_hand(): (mob/user)
-#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw" //from base of atom/attack_paw(): (mob/user)
- #define COMPONENT_NO_ATTACK_HAND 1 //works on all 3.
-//This signal return value bitflags can be found in __DEFINES/misc.dm
-#define COMSIG_ATOM_INTERCEPT_Z_FALL "movable_intercept_z_impact" //called for each movable in a turf contents on /turf/zImpact(): (atom/movable/A, levels)
-#define COMSIG_ATOM_START_PULL "movable_start_pull" //called on a movable (NOT living) when someone starts pulling it (atom/movable/puller, state, force)
-#define COMSIG_LIVING_START_PULL "living_start_pull" //called on /living when someone starts pulling it (atom/movable/puller, state, force)
-
-/////////////////
-
-#define COMSIG_ENTER_AREA "enter_area" //from base of area/Entered(): (/area)
-#define COMSIG_EXIT_AREA "exit_area" //from base of area/Exited(): (/area)
-
-#define COMSIG_CLICK "atom_click" //from base of atom/Click(): (location, control, params, mob/user)
-#define COMSIG_CLICK_SHIFT "shift_click" //from base of atom/ShiftClick(): (/mob)
- #define COMPONENT_ALLOW_EXAMINATE 1 //Allows the user to examinate regardless of client.eye.
-#define COMSIG_CLICK_CTRL "ctrl_click" //from base of atom/CtrlClickOn(): (/mob)
-#define COMSIG_CLICK_ALT "alt_click" //from base of atom/AltClick(): (/mob)
-#define COMSIG_CLICK_CTRL_SHIFT "ctrl_shift_click" //from base of atom/CtrlShiftClick(/mob)
-#define COMSIG_MOUSEDROP_ONTO "mousedrop_onto" //from base of atom/MouseDrop(): (/atom/over, /mob/user)
- #define COMPONENT_NO_MOUSEDROP 1
-#define COMSIG_MOUSEDROPPED_ONTO "mousedropped_onto" //from base of atom/MouseDrop_T: (/atom/from, /mob/user)
-
-// /area signals
-#define COMSIG_AREA_ENTERED "area_entered" //from base of area/Entered(): (atom/movable/M)
-#define COMSIG_AREA_EXITED "area_exited" //from base of area/Exited(): (atom/movable/M)
-
-// /turf signals
-#define COMSIG_TURF_CHANGE "turf_change" //from base of turf/ChangeTurf(): (path, list/new_baseturfs, flags, list/transferring_comps)
-#define COMSIG_TURF_HAS_GRAVITY "turf_has_gravity" //from base of atom/has_gravity(): (atom/asker, list/forced_gravities)
-#define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new" //from base of turf/New(): (turf/source, direction)
-
-// /atom/movable signals
-#define COMSIG_MOVABLE_PRE_MOVE "movable_pre_move" //from base of atom/movable/Moved(): (/atom)
- #define COMPONENT_MOVABLE_BLOCK_PRE_MOVE 1
-#define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir)
-#define COMSIG_MOVABLE_CROSS "movable_cross" //from base of atom/movable/Cross(): (/atom/movable)
-#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable)
-#define COMSIG_MOVABLE_UNCROSS "movable_uncross" //from base of atom/movable/Uncross(): (/atom/movable)
- #define COMPONENT_MOVABLE_BLOCK_UNCROSS 1
-#define COMSIG_MOVABLE_UNCROSSED "movable_uncrossed" //from base of atom/movable/Uncrossed(): (/atom/movable)
-#define COMSIG_MOVABLE_BUMP "movable_bump" //from base of atom/movable/Bump(): (/atom)
-#define COMSIG_MOVABLE_IMPACT "movable_impact" //from base of atom/movable/throw_impact(): (/atom/hit_atom, /datum/thrownthing/throwingdatum)
-#define COMSIG_MOVABLE_IMPACT_ZONE "item_impact_zone" //from base of mob/living/hitby(): (mob/living/target, hit_zone)
-#define COMSIG_MOVABLE_BUCKLE "buckle" //from base of atom/movable/buckle_mob(): (mob, force)
-#define COMSIG_MOVABLE_UNBUCKLE "unbuckle" //from base of atom/movable/unbuckle_mob(): (mob, force)
-#define COMSIG_MOVABLE_PRE_THROW "movable_pre_throw" //from base of atom/movable/throw_at(): (list/args)
- #define COMPONENT_CANCEL_THROW 1
-#define COMSIG_MOVABLE_POST_THROW "movable_post_throw" //from base of atom/movable/throw_at(): (datum/thrownthing, spin)
-#define COMSIG_MOVABLE_Z_CHANGED "movable_ztransit" //from base of atom/movable/onTransitZ(): (old_z, new_z)
-#define COMSIG_MOVABLE_SECLUDED_LOCATION "movable_secluded" //called when the movable is placed in an unaccessible area, used for stationloving: ()
-#define COMSIG_MOVABLE_HEAR "movable_hear" //from base of atom/movable/Hear(): (proc args list(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode))
- #define HEARING_MESSAGE 1
- #define HEARING_SPEAKER 2
-// #define HEARING_LANGUAGE 3
- #define HEARING_RAW_MESSAGE 4
- /* #define HEARING_RADIO_FREQ 5
- #define HEARING_SPANS 6
- #define HEARING_MESSAGE_MODE 7 */
-#define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source)
-
-// /mob signals
-#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed)
-#define COMSIG_MOB_STATCHANGE "mob_statchange" //from base of mob/set_stat(): (new_stat)
-#define COMSIG_MOB_CLICKON "mob_clickon" //from base of mob/clickon(): (atom/A, params)
-#define COMSIG_MOB_MIDDLECLICKON "mob_middleclickon" //from base of mob/MiddleClickOn(): (atom/A)
-#define COMSIG_MOB_ALTCLICKON "mob_altclickon" //from base of mob/AltClickOn(): (atom/A)
- #define COMSIG_MOB_CANCEL_CLICKON 1
-
-#define COMSIG_MOB_ALLOWED "mob_allowed" //from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj
-#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (mob/user, magic, holy, tinfoil, chargecost, self, protection_sources)
- #define COMPONENT_BLOCK_MAGIC 1
-#define COMSIG_MOB_HUD_CREATED "mob_hud_created" //from base of mob/create_mob_hud(): ()
-#define COMSIG_MOB_ATTACK_HAND "mob_attack_hand" //from base of
-#define COMSIG_MOB_ITEM_ATTACK "mob_item_attack" //from base of /obj/item/attack(): (mob/M, mob/user)
- #define COMPONENT_ITEM_NO_ATTACK 1
-#define COMSIG_MOB_APPLY_DAMGE "mob_apply_damage" //from base of /mob/living/proc/apply_damage(): (damage, damagetype, def_zone)
-#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters)
-#define COMSIG_MOB_ITEM_ATTACK_QDELETED "mob_item_attack_qdeleted" //from base of obj/item/attack_qdeleted(): (atom/target, mob/user, proxiumity_flag, click_parameters)
-#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params)
-#define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target)
-#define COMSIG_MOB_EXAMINATE "mob_examinate" //from base of /mob/verb/examinate(): (atom/target)
-#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): ()
-#define COMSIG_MOB_SAY "mob_say" // from /mob/living/say(): ()
- #define COMPONENT_UPPERCASE_SPEECH 1
- // used to access COMSIG_MOB_SAY argslist
- #define SPEECH_MESSAGE 1
- // #define SPEECH_BUBBLE_TYPE 2
- #define SPEECH_SPANS 3
- /* #define SPEECH_SANITIZE 4
- #define SPEECH_LANGUAGE 5
- #define SPEECH_IGNORE_SPAM 6
- #define SPEECH_FORCED 7 */
-#define COMSIG_MOB_DEADSAY "mob_deadsay" // from /mob/say_dead(): (mob/speaker, message)
- #define MOB_DEADSAY_SIGNAL_INTERCEPT 1
-#define COMSIG_MOB_EMOTE "mob_emote" // from /mob/living/emote(): ()
-
-// /mob/living signals
-#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living)
-#define COMSIG_LIVING_IGNITED "living_ignite" //from base of mob/living/IgniteMob() (/mob/living)
-#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living)
-#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage, source, siemens_coeff, flags)
-#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: ()
-#define COMSIG_LIVING_REVIVE "living_revive" //from base of mob/living/revive() (full_heal, admin_revive)
-#define COMSIG_LIVING_REGENERATE_LIMBS "living_regen_limbs" //from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs)
-#define COMSIG_PROCESS_BORGCHARGER_OCCUPANT "living_charge" //sent from borg recharge stations: (amount, repairs)
-#define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login" //sent when a mob/login() finishes: (client)
-#define COMSIG_BORG_SAFE_DECONSTRUCT "borg_safe_decon" //sent from borg mobs to itself, for tools to catch an upcoming destroy() due to safe decon (rather than detonation)
-
-//ALL OF THESE DO NOT TAKE INTO ACCOUNT WHETHER AMOUNT IS 0 OR LOWER AND ARE SENT REGARDLESS!
-#define COMSIG_LIVING_STATUS_STUN "living_stun" //from base of mob/living/Stun() (amount, update, ignore)
-#define COMSIG_LIVING_STATUS_KNOCKDOWN "living_knockdown" //from base of mob/living/Knockdown() (amount, update, ignore)
-#define COMSIG_LIVING_STATUS_PARALYZE "living_paralyze" //from base of mob/living/Paralyze() (amount, update, ignore)
-#define COMSIG_LIVING_STATUS_IMMOBILIZE "living_immobilize" //from base of mob/living/Immobilize() (amount, update, ignore)
-#define COMSIG_LIVING_STATUS_UNCONSCIOUS "living_unconscious" //from base of mob/living/Unconscious() (amount, update, ignore)
-#define COMSIG_LIVING_STATUS_SLEEP "living_sleeping" //from base of mob/living/Sleeping() (amount, update, ignore)
- #define COMPONENT_NO_STUN 1 //For all of them
-#define COMSIG_LIVING_CAN_TRACK "mob_cantrack" //from base of /mob/living/can_track(): (mob/user)
- #define COMPONENT_CANT_TRACK 1
-
-// /mob/living/carbon signals
-#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity))
-#define COMSIG_CARBON_GAIN_ORGAN "carbon_gain_organ" //from /item/organ/proc/Insert() (/obj/item/organ/)
-#define COMSIG_CARBON_LOSE_ORGAN "carbon_lose_organ" //from /item/organ/proc/Remove() (/obj/item/organ/)
-
-// /mob/living/simple_animal/hostile signals
-#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget"
- #define COMPONENT_HOSTILE_NO_ATTACK 1
-
-// /obj signals
-#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct" //from base of obj/deconstruct(): (disassembled)
-#define COMSIG_OBJ_SETANCHORED "obj_setanchored" //called in /obj/structure/setAnchored(): (value)
-#define COMSIG_OBJ_DEFAULT_UNFASTEN_WRENCH "obj_default_unfasten_wrench" //from base of code/game/machinery
-
-// /obj/machinery signals
-#define COMSIG_MACHINERY_BROKEN "machinery_broken" //from /obj/machinery/obj_break(damage_flag): (damage_flag)
-#define COMSIG_MACHINERY_POWER_LOST "machinery_power_lost" //from base power_change() when power is lost
-#define COMSIG_MACHINERY_POWER_RESTORED "machinery_power_restored" //from base power_change() when power is restored
-
-// /obj/item signals
-#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user)
-#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob)
- #define COMPONENT_NO_INTERACT 1
-#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob)
- #define COMPONENT_NO_ATTACK_OBJ 1
-#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack" //from base of obj/item/pre_attack(): (atom/target, mob/user, params)
- #define COMPONENT_NO_ATTACK 1
-#define COMSIG_ITEM_AFTERATTACK "item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, params)
-#define COMSIG_ITEM_ATTACK_QDELETED "item_attack_qdeleted" //from base of obj/item/attack_qdeleted(): (atom/target, mob/user, params)
-#define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot)
-#define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (mob/user)
-#define COMSIG_ITEM_PICKUP "item_pickup" //from base of obj/item/pickup(): (/mob/taker)
-#define COMSIG_ITEM_ATTACK_ZONE "item_attack_zone" //from base of mob/living/carbon/attacked_by(): (mob/living/carbon/target, mob/living/user, hit_zone)
-#define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul" //return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/targeted/lichdom/cast(): (mob/user)
-#define COMSIG_ITEM_MARK_RETRIEVAL "item_mark_retrieval" //called before marking an object for retrieval, checked in /obj/effect/proc_holder/spell/targeted/summonitem/cast() : (mob/user)
- #define COMPONENT_BLOCK_MARK_RETRIEVAL 1
-#define COMSIG_ITEM_HIT_REACT "item_hit_react" //from base of obj/item/hit_reaction(): (list/args)
-#define COMSIG_ITEM_WEARERCROSSED "wearer_crossed" //called on item when crossed by something (): (/atom/movable, mob/living/crossed)
-#define COMSIG_ITEM_MICROWAVE_ACT "microwave_act" //called on item when microwaved (): (obj/machinery/microwave/M)
-
-
-// /obj/item/clothing signals
-#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): ()
-
-// /obj/item/implant signals
-#define COMSIG_IMPLANT_ACTIVATED "implant_activated" //from base of /obj/item/implant/proc/activate(): ()
-#define COMSIG_IMPLANT_IMPLANTING "implant_implanting" //from base of /obj/item/implant/proc/implant(): (list/args)
- #define COMPONENT_STOP_IMPLANTING 1
-#define COMSIG_IMPLANT_OTHER "implant_other" //called on already installed implants when a new one is being added in /obj/item/implant/proc/implant(): (list/args, obj/item/implant/new_implant)
- //#define COMPONENT_STOP_IMPLANTING 1 //The name makes sense for both
- #define COMPONENT_DELETE_NEW_IMPLANT 2
- #define COMPONENT_DELETE_OLD_IMPLANT 4
-#define COMSIG_IMPLANT_EXISTING_UPLINK "implant_uplink_exists" //called on implants being implanted into someone with an uplink implant: (datum/component/uplink)
- //This uses all return values of COMSIG_IMPLANT_OTHER
-
-// /obj/item/pda signals
-#define COMSIG_PDA_CHANGE_RINGTONE "pda_change_ringtone" //called on pda when the user changes the ringtone: (mob/living/user, new_ringtone)
- #define COMPONENT_STOP_RINGTONE_CHANGE 1
-#define COMSIG_PDA_CHECK_DETONATE "pda_check_detonate"
- #define COMPONENT_PDA_NO_DETONATE 1
-
-// /obj/item/radio signals
-#define COMSIG_RADIO_NEW_FREQUENCY "radio_new_frequency" //called from base of /obj/item/radio/proc/set_frequency(): (list/args)
-
-// /obj/item/pen signals
-#define COMSIG_PEN_ROTATED "pen_rotated" //called after rotation in /obj/item/pen/attack_self(): (rotation, mob/living/carbon/user)
-
-// /obj/item/gun signals
-#define COMSIG_MOB_FIRED_GUN "mob_fired_gun" //called in /obj/item/gun/process_fire (user, target, params, zone_override)
-
-// /obj/projectile signals (sent to the firer)
-#define COMSIG_PROJECTILE_ON_HIT "projectile_on_hit" // from base of /obj/projectile/proc/on_hit(): (atom/movable/firer, atom/target, Angle)
-#define COMSIG_PROJECTILE_BEFORE_FIRE "projectile_before_fire" // from base of /obj/projectile/proc/fire(): (obj/projectile, atom/original_target)
-#define COMSIG_PROJECTILE_FIRE "projectile_fire" // from the base of /obj/projectile/proc/fire(): ()
-#define COMSIG_PROJECTILE_PREHIT "com_proj_prehit" // sent to targets during the process_hit proc of projectiles
-
-// /obj/mecha signals
-#define COMSIG_MECHA_ACTION_ACTIVATE "mecha_action_activate" //sent from mecha action buttons to the mecha they're linked to
-
-// /mob/living/carbon/human signals
-#define COMSIG_HUMAN_EARLY_UNARMED_ATTACK "human_early_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target, proximity)
-#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target, proximity)
-#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker)
-#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit" //Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted)
-#define COMSIG_JOB_RECEIVED "job_received" //Whenever EquipRanked is called, called after job is set
-
-// /datum/species signals
-#define COMSIG_SPECIES_GAIN "species_gain" //from datum/species/on_species_gain(): (datum/species/new_species, datum/species/old_species)
-#define COMSIG_SPECIES_LOSS "species_loss" //from datum/species/on_species_loss(): (datum/species/lost_species)
-
-// /datum/song signals
-#define COMSIG_SONG_START "song_start" //sent to the instrument when a song starts playing
-#define COMSIG_SONG_END "song_end" //sent to the instrument when a song stops playing
-
-/*******Component Specific Signals*******/
-//Janitor
-#define COMSIG_TURF_IS_WET "check_turf_wet" //(): Returns bitflags of wet values.
-#define COMSIG_TURF_MAKE_DRY "make_turf_try" //(max_strength, immediate, duration_decrease = INFINITY): Returns bool.
-#define COMSIG_COMPONENT_CLEAN_ACT "clean_act" //called on an object to clean it of cleanables. Usualy with soap: (num/strength)
-
-//Creamed
-#define COMSIG_COMPONENT_CLEAN_FACE_ACT "clean_face_act" //called when you wash your face at a sink: (num/strength)
-
-//Food
-#define COMSIG_FOOD_EATEN "food_eaten" //from base of obj/item/reagent_containers/food/snacks/attack(): (mob/living/eater, mob/feeder)
-
-//Gibs
-#define COMSIG_GIBS_STREAK "gibs_streak" // from base of /obj/effect/decal/cleanable/blood/gibs/streak(): (list/directions, list/diseases)
-
-//Mood
-#define COMSIG_ADD_MOOD_EVENT "add_mood" //Called when you send a mood event from anywhere in the code.
-#define COMSIG_ADD_MOOD_EVENT_RND "RND_add_mood" //Mood event that only RnD members listen for
-#define COMSIG_CLEAR_MOOD_EVENT "clear_mood" //Called when you clear a mood event from anywhere in the code.
-
-//NTnet
-#define COMSIG_COMPONENT_NTNET_RECEIVE "ntnet_receive" //called on an object by its NTNET connection component on receive. (sending_id(number), sending_netname(text), data(datum/netdata))
-
-//Nanites
-#define COMSIG_HAS_NANITES "has_nanites" //() returns TRUE if nanites are found
-#define COMSIG_NANITE_IS_STEALTHY "nanite_is_stealthy" //() returns TRUE if nanites have stealth
-#define COMSIG_NANITE_DELETE "nanite_delete" //() deletes the nanite component
-#define COMSIG_NANITE_GET_PROGRAMS "nanite_get_programs" //(list/nanite_programs) - makes the input list a copy the nanites' program list
-#define COMSIG_NANITE_GET_VOLUME "nanite_get_volume" //(amount) Returns nanite amount
-#define COMSIG_NANITE_SET_VOLUME "nanite_set_volume" //(amount) Sets current nanite volume to the given amount
-#define COMSIG_NANITE_ADJUST_VOLUME "nanite_adjust" //(amount) Adjusts nanite volume by the given amount
-#define COMSIG_NANITE_SET_MAX_VOLUME "nanite_set_max_volume" //(amount) Sets maximum nanite volume to the given amount
-#define COMSIG_NANITE_SET_CLOUD "nanite_set_cloud" //(amount(0-100)) Sets cloud ID to the given amount
-#define COMSIG_NANITE_SET_CLOUD_SYNC "nanite_set_cloud_sync" //(method) Modify cloud sync status. Method can be toggle, enable or disable
-#define COMSIG_NANITE_SET_SAFETY "nanite_set_safety" //(amount) Sets safety threshold to the given amount
-#define COMSIG_NANITE_SET_REGEN "nanite_set_regen" //(amount) Sets regeneration rate to the given amount
-#define COMSIG_NANITE_SIGNAL "nanite_signal" //(code(1-9999)) Called when sending a nanite signal to a mob.
-#define COMSIG_NANITE_COMM_SIGNAL "nanite_comm_signal" //(comm_code(1-9999), comm_message) Called when sending a nanite comm signal to a mob.
-#define COMSIG_NANITE_SCAN "nanite_scan" //(mob/user, full_scan) - sends to chat a scan of the nanites to the user, returns TRUE if nanites are detected
-#define COMSIG_NANITE_UI_DATA "nanite_ui_data" //(list/data, scan_level) - adds nanite data to the given data list - made for ui_data procs
-#define COMSIG_NANITE_ADD_PROGRAM "nanite_add_program" //(datum/nanite_program/new_program, datum/nanite_program/source_program) Called when adding a program to a nanite component
- #define COMPONENT_PROGRAM_INSTALLED 1 //Installation successful
- #define COMPONENT_PROGRAM_NOT_INSTALLED 2 //Installation failed, but there are still nanites
-#define COMSIG_NANITE_SYNC "nanite_sync" //(datum/component/nanites, full_overwrite, copy_activation) Called to sync the target's nanites to a given nanite component
-
-// /datum/component/storage signals
-#define COMSIG_CONTAINS_STORAGE "is_storage" //() - returns bool.
-#define COMSIG_TRY_STORAGE_INSERT "storage_try_insert" //(obj/item/inserting, mob/user, silent, force) - returns bool
-#define COMSIG_TRY_STORAGE_SHOW "storage_show_to" //(mob/show_to, force) - returns bool.
-#define COMSIG_TRY_STORAGE_HIDE_FROM "storage_hide_from" //(mob/hide_from) - returns bool
-#define COMSIG_TRY_STORAGE_HIDE_ALL "storage_hide_all" //returns bool
-#define COMSIG_TRY_STORAGE_SET_LOCKSTATE "storage_lock_set_state" //(newstate)
-#define COMSIG_IS_STORAGE_LOCKED "storage_get_lockstate" //() - returns bool. MUST CHECK IF STORAGE IS THERE FIRST!
-#define COMSIG_TRY_STORAGE_TAKE_TYPE "storage_take_type" //(type, atom/destination, amount = INFINITY, check_adjacent, force, mob/user, list/inserted) - returns bool - type can be a list of types.
-#define COMSIG_TRY_STORAGE_FILL_TYPE "storage_fill_type" //(type, amount = INFINITY, force = FALSE) //don't fuck this up. Force will ignore max_items, and amount is normally clamped to max_items.
-#define COMSIG_TRY_STORAGE_TAKE "storage_take_obj" //(obj, new_loc, force = FALSE) - returns bool
-#define COMSIG_TRY_STORAGE_QUICK_EMPTY "storage_quick_empty" //(loc) - returns bool - if loc is null it will dump at parent location.
-#define COMSIG_TRY_STORAGE_RETURN_INVENTORY "storage_return_inventory" //(list/list_to_inject_results_into, recursively_search_inside_storages = TRUE)
-#define COMSIG_TRY_STORAGE_CAN_INSERT "storage_can_equip" //(obj/item/insertion_candidate, mob/user, silent) - returns bool
-
-// /datum/action signals
-#define COMSIG_ACTION_TRIGGER "action_trigger" //from base of datum/action/proc/Trigger(): (datum/action)
- #define COMPONENT_ACTION_BLOCK_TRIGGER 1
-
-/*******Non-Signal Component Related Defines*******/
-
-//Redirection component init flags
-#define REDIRECT_TRANSFER_WITH_TURF 1
-
-//Arch
-#define ARCH_PROB "probability" //Probability for each item
-#define ARCH_MAXDROP "max_drop_amount" //each item's max drop amount
-
-//Ouch my toes!
-#define CALTROP_BYPASS_SHOES 1
-#define CALTROP_IGNORE_WALKERS 2
-
-//Xenobio hotkeys
-#define COMSIG_XENO_SLIME_CLICK_CTRL "xeno_slime_click_ctrl" //from slime CtrlClickOn(): (/mob)
-#define COMSIG_XENO_SLIME_CLICK_ALT "xeno_slime_click_alt" //from slime AltClickOn(): (/mob)
-#define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift" //from slime ShiftClickOn(): (/mob)
-#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift" //from turf ShiftClickOn(): (/mob)
-#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob)
-#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob)
+// All signals. Format:
+// When the signal is called: (signal arguments)
+// All signals send the source datum of the signal as the first argument
+
+// global signals
+// These are signals which can be listened to by any component on any parent
+// start global signals with "!", this used to be necessary but now it's just a formatting choice
+/// from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args)
+#define COMSIG_GLOB_NEW_Z "!new_z"
+/// called after a successful var edit somewhere in the world: (list/args)
+#define COMSIG_GLOB_VAR_EDIT "!var_edit"
+/// called after an explosion happened : (epicenter, devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range)
+#define COMSIG_GLOB_EXPLOSION "!explosion"
+/// mob was created somewhere : (mob)
+#define COMSIG_GLOB_MOB_CREATED "!mob_created"
+/// mob died somewhere : (mob , gibbed)
+#define COMSIG_GLOB_MOB_DEATH "!mob_death"
+/// global living say plug - use sparingly: (mob/speaker , message)
+#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special"
+/// called by datum/cinematic/play() : (datum/cinematic/new_cinematic)
+#define COMSIG_GLOB_PLAY_CINEMATIC "!play_cinematic"
+ #define COMPONENT_GLOB_BLOCK_CINEMATIC 1
+/// ingame button pressed (/obj/machinery/button/button)
+#define COMSIG_GLOB_BUTTON_PRESSED "!button_pressed"
+
+// signals from globally accessible objects
+/// from SSsun when the sun changes position : (azimuth)
+#define COMSIG_SUN_MOVED "sun_moved"
+
+//////////////////////////////////////////////////////////////////
+
+// /datum signals
+/// when a component is added to a datum: (/datum/component)
+#define COMSIG_COMPONENT_ADDED "component_added"
+/// before a component is removed from a datum because of RemoveComponent: (/datum/component)
+#define COMSIG_COMPONENT_REMOVING "component_removing"
+/// before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation
+#define COMSIG_PARENT_PREQDELETED "parent_preqdeleted"
+/// 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
+#define COMSIG_PARENT_QDELETING "parent_qdeleting"
+/// generic topic handler (usr, href_list)
+#define COMSIG_TOPIC "handle_topic"
+
+// /atom signals
+#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params)
+ #define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called
+#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human)
+#define COMSIG_ATOM_ATTACK_ANIMAL "attack_animal" //from base of atom/animal_attack(): (/mob/user)
+#define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob)
+#define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name" //from base of atom/get_examine_name(): (/mob, list/overrides)
+ //Positions for overrides list
+ #define EXAMINE_POSITION_ARTICLE 1
+ #define EXAMINE_POSITION_BEFORE 2
+ //End positions
+ #define COMPONENT_EXNAME_CHANGED 1
+#define COMSIG_ATOM_UPDATE_ICON "atom_update_icon" //from base of atom/update_icon(): ()
+ #define COMSIG_ATOM_NO_UPDATE_ICON_STATE 1
+ #define COMSIG_ATOM_NO_UPDATE_OVERLAYS 2
+#define COMSIG_ATOM_UPDATE_OVERLAYS "atom_update_overlays" //from base of atom/update_overlays(): (list/new_overlays)
+#define COMSIG_ATOM_UPDATED_ICON "atom_updated_icon" //from base of atom/update_icon(): (signalOut, did_anything)
+#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable/entering, /atom)
+#define COMSIG_ATOM_EXIT "atom_exit" //from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc)
+ #define COMPONENT_ATOM_BLOCK_EXIT 1
+#define COMSIG_ATOM_EXITED "atom_exited" //from base of atom/Exited(): (atom/movable/exiting, atom/newloc)
+#define COMSIG_ATOM_BUMPED "atom_bumped" //from base of atom/Bumped(): (/atom/movable)
+#define COMSIG_ATOM_EX_ACT "atom_ex_act" //from base of atom/ex_act(): (severity, target)
+#define COMSIG_ATOM_EMP_ACT "atom_emp_act" //from base of atom/emp_act(): (severity)
+#define COMSIG_ATOM_FIRE_ACT "atom_fire_act" //from base of atom/fire_act(): (exposed_temperature, exposed_volume)
+#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act" //from base of atom/bullet_act(): (/obj/projectile, def_zone)
+#define COMSIG_ATOM_BLOB_ACT "atom_blob_act" //from base of atom/blob_act(): (/obj/structure/blob)
+#define COMSIG_ATOM_ACID_ACT "atom_acid_act" //from base of atom/acid_act(): (acidpwr, acid_volume)
+#define COMSIG_ATOM_EMAG_ACT "atom_emag_act" //from base of atom/emag_act(): (/mob/user)
+#define COMSIG_ATOM_RAD_ACT "atom_rad_act" //from base of atom/rad_act(intensity)
+#define COMSIG_ATOM_NARSIE_ACT "atom_narsie_act" //from base of atom/narsie_act(): ()
+#define COMSIG_ATOM_RCD_ACT "atom_rcd_act" //from base of atom/rcd_act(): (/mob, /obj/item/construction/rcd, passed_mode)
+#define COMSIG_ATOM_SING_PULL "atom_sing_pull" //from base of atom/singularity_pull(): (S, current_size)
+#define COMSIG_ATOM_BSA_BEAM "atom_bsa_beam_pass" //from obj/machinery/bsa/full/proc/fire(): ()
+ #define COMSIG_ATOM_BLOCKS_BSA_BEAM 1
+#define COMSIG_ATOM_SET_LIGHT "atom_set_light" //from base of atom/set_light(): (l_range, l_power, l_color)
+#define COMSIG_ATOM_DIR_CHANGE "atom_dir_change" //from base of atom/setDir(): (old_dir, new_dir)
+#define COMSIG_ATOM_CONTENTS_DEL "atom_contents_del" //from base of atom/handle_atom_del(): (atom/deleted)
+#define COMSIG_ATOM_HAS_GRAVITY "atom_has_gravity" //from base of atom/has_gravity(): (turf/location, list/forced_gravities)
+#define COMSIG_ATOM_RAD_PROBE "atom_rad_probe" //from proc/get_rad_contents(): ()
+ #define COMPONENT_BLOCK_RADIATION 1
+#define COMSIG_ATOM_RAD_CONTAMINATING "atom_rad_contam" //from base of datum/radiation_wave/radiate(): (strength)
+ #define COMPONENT_BLOCK_CONTAMINATION 1
+#define COMSIG_ATOM_RAD_WAVE_PASSING "atom_rad_wave_pass" //from base of datum/radiation_wave/check_obstructions(): (datum/radiation_wave, width)
+ #define COMPONENT_RAD_WAVE_HANDLED 1
+#define COMSIG_ATOM_CANREACH "atom_can_reach" //from internal loop in atom/movable/proc/CanReach(): (list/next)
+ #define COMPONENT_BLOCK_REACH 1
+#define COMSIG_ATOM_SCREWDRIVER_ACT "atom_screwdriver_act" //from base of atom/screwdriver_act(): (mob/living/user, obj/item/I)
+#define COMSIG_ATOM_WRENCH_ACT "atom_wrench_act" //from base of atom/wrench_act(): (mob/living/user, obj/item/I)
+#define COMSIG_ATOM_MULTITOOL_ACT "atom_multitool_act" //from base of atom/multitool_act(): (mob/living/user, obj/item/I)
+#define COMSIG_ATOM_WELDER_ACT "atom_welder_act" //from base of atom/welder_act(): (mob/living/user, obj/item/I)
+#define COMSIG_ATOM_WIRECUTTER_ACT "atom_wirecutter_act" //from base of atom/wirecutter_act(): (mob/living/user, obj/item/I)
+#define COMSIG_ATOM_CROWBAR_ACT "atom_crowbar_act" //from base of atom/crowbar_act(): (mob/living/user, obj/item/I)
+#define COMSIG_ATOM_ANALYSER_ACT "atom_analyser_act" //from base of atom/analyser_act(): (mob/living/user, obj/item/I)
+ #define COMPONENT_BLOCK_TOOL_ATTACK 1
+#define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport" //called when teleporting into a protected turf: (channel, turf/origin)
+ #define COMPONENT_BLOCK_TELEPORT 1
+#define COMSIG_ATOM_HEARER_IN_VIEW "atom_hearer_in_view" //called when an atom is added to the hearers on get_hearers_in_view(): (list/processing_list, list/hearers)
+#define COMSIG_ATOM_ORBIT_BEGIN "atom_orbit_begin" //called when an atom starts orbiting another atom: (atom)
+#define COMSIG_ATOM_ORBIT_STOP "atom_orbit_stop" //called when an atom stops orbiting another atom: (atom)
+/////////////////
+#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" //from base of atom/attack_ghost(): (mob/dead/observer/ghost)
+#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" //from base of atom/attack_hand(): (mob/user)
+#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw" //from base of atom/attack_paw(): (mob/user)
+ #define COMPONENT_NO_ATTACK_HAND 1 //works on all 3.
+//This signal return value bitflags can be found in __DEFINES/misc.dm
+#define COMSIG_ATOM_INTERCEPT_Z_FALL "movable_intercept_z_impact" //called for each movable in a turf contents on /turf/zImpact(): (atom/movable/A, levels)
+#define COMSIG_ATOM_START_PULL "movable_start_pull" //called on a movable (NOT living) when someone starts pulling it (atom/movable/puller, state, force)
+#define COMSIG_LIVING_START_PULL "living_start_pull" //called on /living when someone starts pulling it (atom/movable/puller, state, force)
+
+/////////////////
+
+#define COMSIG_ENTER_AREA "enter_area" //from base of area/Entered(): (/area)
+#define COMSIG_EXIT_AREA "exit_area" //from base of area/Exited(): (/area)
+
+#define COMSIG_CLICK "atom_click" //from base of atom/Click(): (location, control, params, mob/user)
+#define COMSIG_CLICK_SHIFT "shift_click" //from base of atom/ShiftClick(): (/mob)
+ #define COMPONENT_ALLOW_EXAMINATE 1 //Allows the user to examinate regardless of client.eye.
+#define COMSIG_CLICK_CTRL "ctrl_click" //from base of atom/CtrlClickOn(): (/mob)
+#define COMSIG_CLICK_ALT "alt_click" //from base of atom/AltClick(): (/mob)
+#define COMSIG_CLICK_CTRL_SHIFT "ctrl_shift_click" //from base of atom/CtrlShiftClick(/mob)
+#define COMSIG_MOUSEDROP_ONTO "mousedrop_onto" //from base of atom/MouseDrop(): (/atom/over, /mob/user)
+ #define COMPONENT_NO_MOUSEDROP 1
+#define COMSIG_MOUSEDROPPED_ONTO "mousedropped_onto" //from base of atom/MouseDrop_T: (/atom/from, /mob/user)
+
+// /area signals
+#define COMSIG_AREA_ENTERED "area_entered" //from base of area/Entered(): (atom/movable/M)
+#define COMSIG_AREA_EXITED "area_exited" //from base of area/Exited(): (atom/movable/M)
+
+// /turf signals
+#define COMSIG_TURF_CHANGE "turf_change" //from base of turf/ChangeTurf(): (path, list/new_baseturfs, flags, list/transferring_comps)
+#define COMSIG_TURF_HAS_GRAVITY "turf_has_gravity" //from base of atom/has_gravity(): (atom/asker, list/forced_gravities)
+#define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new" //from base of turf/New(): (turf/source, direction)
+
+// /atom/movable signals
+#define COMSIG_MOVABLE_PRE_MOVE "movable_pre_move" //from base of atom/movable/Moved(): (/atom)
+ #define COMPONENT_MOVABLE_BLOCK_PRE_MOVE 1
+#define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir)
+#define COMSIG_MOVABLE_CROSS "movable_cross" //from base of atom/movable/Cross(): (/atom/movable)
+#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable)
+#define COMSIG_MOVABLE_UNCROSS "movable_uncross" //from base of atom/movable/Uncross(): (/atom/movable)
+ #define COMPONENT_MOVABLE_BLOCK_UNCROSS 1
+#define COMSIG_MOVABLE_UNCROSSED "movable_uncrossed" //from base of atom/movable/Uncrossed(): (/atom/movable)
+#define COMSIG_MOVABLE_BUMP "movable_bump" //from base of atom/movable/Bump(): (/atom)
+#define COMSIG_MOVABLE_IMPACT "movable_impact" //from base of atom/movable/throw_impact(): (/atom/hit_atom, /datum/thrownthing/throwingdatum)
+#define COMSIG_MOVABLE_IMPACT_ZONE "item_impact_zone" //from base of mob/living/hitby(): (mob/living/target, hit_zone)
+#define COMSIG_MOVABLE_BUCKLE "buckle" //from base of atom/movable/buckle_mob(): (mob, force)
+#define COMSIG_MOVABLE_UNBUCKLE "unbuckle" //from base of atom/movable/unbuckle_mob(): (mob, force)
+#define COMSIG_MOVABLE_PRE_THROW "movable_pre_throw" //from base of atom/movable/throw_at(): (list/args)
+ #define COMPONENT_CANCEL_THROW 1
+#define COMSIG_MOVABLE_POST_THROW "movable_post_throw" //from base of atom/movable/throw_at(): (datum/thrownthing, spin)
+#define COMSIG_MOVABLE_Z_CHANGED "movable_ztransit" //from base of atom/movable/onTransitZ(): (old_z, new_z)
+#define COMSIG_MOVABLE_SECLUDED_LOCATION "movable_secluded" //called when the movable is placed in an unaccessible area, used for stationloving: ()
+#define COMSIG_MOVABLE_HEAR "movable_hear" //from base of atom/movable/Hear(): (proc args list(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode))
+ #define HEARING_MESSAGE 1
+ #define HEARING_SPEAKER 2
+// #define HEARING_LANGUAGE 3
+ #define HEARING_RAW_MESSAGE 4
+ /* #define HEARING_RADIO_FREQ 5
+ #define HEARING_SPANS 6
+ #define HEARING_MESSAGE_MODE 7 */
+#define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source)
+
+// /mob signals
+#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed)
+#define COMSIG_MOB_STATCHANGE "mob_statchange" //from base of mob/set_stat(): (new_stat)
+#define COMSIG_MOB_CLICKON "mob_clickon" //from base of mob/clickon(): (atom/A, params)
+#define COMSIG_MOB_MIDDLECLICKON "mob_middleclickon" //from base of mob/MiddleClickOn(): (atom/A)
+#define COMSIG_MOB_ALTCLICKON "mob_altclickon" //from base of mob/AltClickOn(): (atom/A)
+ #define COMSIG_MOB_CANCEL_CLICKON 1
+
+#define COMSIG_MOB_ALLOWED "mob_allowed" //from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj
+#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (mob/user, magic, holy, tinfoil, chargecost, self, protection_sources)
+ #define COMPONENT_BLOCK_MAGIC 1
+#define COMSIG_MOB_HUD_CREATED "mob_hud_created" //from base of mob/create_mob_hud(): ()
+#define COMSIG_MOB_ATTACK_HAND "mob_attack_hand" //from base of
+#define COMSIG_MOB_ITEM_ATTACK "mob_item_attack" //from base of /obj/item/attack(): (mob/M, mob/user)
+ #define COMPONENT_ITEM_NO_ATTACK 1
+#define COMSIG_MOB_APPLY_DAMGE "mob_apply_damage" //from base of /mob/living/proc/apply_damage(): (damage, damagetype, def_zone)
+#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters)
+#define COMSIG_MOB_ITEM_ATTACK_QDELETED "mob_item_attack_qdeleted" //from base of obj/item/attack_qdeleted(): (atom/target, mob/user, proxiumity_flag, click_parameters)
+#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params)
+#define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target)
+#define COMSIG_MOB_EXAMINATE "mob_examinate" //from base of /mob/verb/examinate(): (atom/target)
+#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): ()
+#define COMSIG_MOB_SAY "mob_say" // from /mob/living/say(): ()
+ #define COMPONENT_UPPERCASE_SPEECH 1
+ // used to access COMSIG_MOB_SAY argslist
+ #define SPEECH_MESSAGE 1
+ // #define SPEECH_BUBBLE_TYPE 2
+ #define SPEECH_SPANS 3
+ /* #define SPEECH_SANITIZE 4
+ #define SPEECH_LANGUAGE 5
+ #define SPEECH_IGNORE_SPAM 6
+ #define SPEECH_FORCED 7 */
+#define COMSIG_MOB_DEADSAY "mob_deadsay" // from /mob/say_dead(): (mob/speaker, message)
+ #define MOB_DEADSAY_SIGNAL_INTERCEPT 1
+#define COMSIG_MOB_EMOTE "mob_emote" // from /mob/living/emote(): ()
+
+// /mob/living signals
+#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living)
+#define COMSIG_LIVING_IGNITED "living_ignite" //from base of mob/living/IgniteMob() (/mob/living)
+#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living)
+#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage, source, siemens_coeff, flags)
+#define COMSIG_LIVING_SHOCK_PREVENTED "living_shock_prevented" //sent when items with siemen coeff. of 0 block a shock: (power_source, source, siemens_coeff, dist_check)
+#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: ()
+#define COMSIG_LIVING_REVIVE "living_revive" //from base of mob/living/revive() (full_heal, admin_revive)
+#define COMSIG_LIVING_REGENERATE_LIMBS "living_regen_limbs" //from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs)
+#define COMSIG_PROCESS_BORGCHARGER_OCCUPANT "living_charge" //sent from borg recharge stations: (amount, repairs)
+#define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login" //sent when a mob/login() finishes: (client)
+#define COMSIG_BORG_SAFE_DECONSTRUCT "borg_safe_decon" //sent from borg mobs to itself, for tools to catch an upcoming destroy() due to safe decon (rather than detonation)
+
+//ALL OF THESE DO NOT TAKE INTO ACCOUNT WHETHER AMOUNT IS 0 OR LOWER AND ARE SENT REGARDLESS!
+#define COMSIG_LIVING_STATUS_STUN "living_stun" //from base of mob/living/Stun() (amount, update, ignore)
+#define COMSIG_LIVING_STATUS_KNOCKDOWN "living_knockdown" //from base of mob/living/Knockdown() (amount, update, ignore)
+#define COMSIG_LIVING_STATUS_PARALYZE "living_paralyze" //from base of mob/living/Paralyze() (amount, update, ignore)
+#define COMSIG_LIVING_STATUS_IMMOBILIZE "living_immobilize" //from base of mob/living/Immobilize() (amount, update, ignore)
+#define COMSIG_LIVING_STATUS_UNCONSCIOUS "living_unconscious" //from base of mob/living/Unconscious() (amount, update, ignore)
+#define COMSIG_LIVING_STATUS_SLEEP "living_sleeping" //from base of mob/living/Sleeping() (amount, update, ignore)
+ #define COMPONENT_NO_STUN 1 //For all of them
+#define COMSIG_LIVING_CAN_TRACK "mob_cantrack" //from base of /mob/living/can_track(): (mob/user)
+ #define COMPONENT_CANT_TRACK 1
+
+// /mob/living/carbon signals
+#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity))
+#define COMSIG_CARBON_GAIN_ORGAN "carbon_gain_organ" //from /item/organ/proc/Insert() (/obj/item/organ/)
+#define COMSIG_CARBON_LOSE_ORGAN "carbon_lose_organ" //from /item/organ/proc/Remove() (/obj/item/organ/)
+
+// /mob/living/simple_animal/hostile signals
+#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget"
+ #define COMPONENT_HOSTILE_NO_ATTACK 1
+
+// /obj signals
+#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct" //from base of obj/deconstruct(): (disassembled)
+#define COMSIG_OBJ_SETANCHORED "obj_setanchored" //called in /obj/structure/setAnchored(): (value)
+#define COMSIG_OBJ_DEFAULT_UNFASTEN_WRENCH "obj_default_unfasten_wrench" //from base of code/game/machinery
+
+// /obj/machinery signals
+#define COMSIG_MACHINERY_BROKEN "machinery_broken" //from /obj/machinery/obj_break(damage_flag): (damage_flag)
+#define COMSIG_MACHINERY_POWER_LOST "machinery_power_lost" //from base power_change() when power is lost
+#define COMSIG_MACHINERY_POWER_RESTORED "machinery_power_restored" //from base power_change() when power is restored
+
+// /obj/item signals
+#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user)
+#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob)
+ #define COMPONENT_NO_INTERACT 1
+#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob)
+ #define COMPONENT_NO_ATTACK_OBJ 1
+#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack" //from base of obj/item/pre_attack(): (atom/target, mob/user, params)
+ #define COMPONENT_NO_ATTACK 1
+#define COMSIG_ITEM_AFTERATTACK "item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, params)
+#define COMSIG_ITEM_ATTACK_QDELETED "item_attack_qdeleted" //from base of obj/item/attack_qdeleted(): (atom/target, mob/user, params)
+#define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot)
+#define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (mob/user)
+#define COMSIG_ITEM_PICKUP "item_pickup" //from base of obj/item/pickup(): (/mob/taker)
+#define COMSIG_ITEM_ATTACK_ZONE "item_attack_zone" //from base of mob/living/carbon/attacked_by(): (mob/living/carbon/target, mob/living/user, hit_zone)
+#define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul" //return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/targeted/lichdom/cast(): (mob/user)
+#define COMSIG_ITEM_MARK_RETRIEVAL "item_mark_retrieval" //called before marking an object for retrieval, checked in /obj/effect/proc_holder/spell/targeted/summonitem/cast() : (mob/user)
+ #define COMPONENT_BLOCK_MARK_RETRIEVAL 1
+#define COMSIG_ITEM_HIT_REACT "item_hit_react" //from base of obj/item/hit_reaction(): (list/args)
+#define COMSIG_ITEM_WEARERCROSSED "wearer_crossed" //called on item when crossed by something (): (/atom/movable, mob/living/crossed)
+#define COMSIG_ITEM_MICROWAVE_ACT "microwave_act" //called on item when microwaved (): (obj/machinery/microwave/M)
+
+
+// /obj/item/clothing signals
+#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): ()
+
+// /obj/item/implant signals
+#define COMSIG_IMPLANT_ACTIVATED "implant_activated" //from base of /obj/item/implant/proc/activate(): ()
+#define COMSIG_IMPLANT_IMPLANTING "implant_implanting" //from base of /obj/item/implant/proc/implant(): (list/args)
+ #define COMPONENT_STOP_IMPLANTING 1
+#define COMSIG_IMPLANT_OTHER "implant_other" //called on already installed implants when a new one is being added in /obj/item/implant/proc/implant(): (list/args, obj/item/implant/new_implant)
+ //#define COMPONENT_STOP_IMPLANTING 1 //The name makes sense for both
+ #define COMPONENT_DELETE_NEW_IMPLANT 2
+ #define COMPONENT_DELETE_OLD_IMPLANT 4
+#define COMSIG_IMPLANT_EXISTING_UPLINK "implant_uplink_exists" //called on implants being implanted into someone with an uplink implant: (datum/component/uplink)
+ //This uses all return values of COMSIG_IMPLANT_OTHER
+
+// /obj/item/pda signals
+#define COMSIG_PDA_CHANGE_RINGTONE "pda_change_ringtone" //called on pda when the user changes the ringtone: (mob/living/user, new_ringtone)
+ #define COMPONENT_STOP_RINGTONE_CHANGE 1
+#define COMSIG_PDA_CHECK_DETONATE "pda_check_detonate"
+ #define COMPONENT_PDA_NO_DETONATE 1
+
+// /obj/item/radio signals
+#define COMSIG_RADIO_NEW_FREQUENCY "radio_new_frequency" //called from base of /obj/item/radio/proc/set_frequency(): (list/args)
+
+// /obj/item/pen signals
+#define COMSIG_PEN_ROTATED "pen_rotated" //called after rotation in /obj/item/pen/attack_self(): (rotation, mob/living/carbon/user)
+
+// /obj/item/gun signals
+#define COMSIG_MOB_FIRED_GUN "mob_fired_gun" //called in /obj/item/gun/process_fire (user, target, params, zone_override)
+
+// /obj/projectile signals (sent to the firer)
+#define COMSIG_PROJECTILE_ON_HIT "projectile_on_hit" // from base of /obj/projectile/proc/on_hit(): (atom/movable/firer, atom/target, Angle)
+#define COMSIG_PROJECTILE_BEFORE_FIRE "projectile_before_fire" // from base of /obj/projectile/proc/fire(): (obj/projectile, atom/original_target)
+#define COMSIG_PROJECTILE_FIRE "projectile_fire" // from the base of /obj/projectile/proc/fire(): ()
+#define COMSIG_PROJECTILE_PREHIT "com_proj_prehit" // sent to targets during the process_hit proc of projectiles
+
+// /obj/mecha signals
+#define COMSIG_MECHA_ACTION_ACTIVATE "mecha_action_activate" //sent from mecha action buttons to the mecha they're linked to
+
+// /mob/living/carbon/human signals
+#define COMSIG_HUMAN_EARLY_UNARMED_ATTACK "human_early_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target, proximity)
+#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target, proximity)
+#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker)
+#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit" //Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted)
+#define COMSIG_JOB_RECEIVED "job_received" //Whenever EquipRanked is called, called after job is set
+
+// /datum/species signals
+#define COMSIG_SPECIES_GAIN "species_gain" //from datum/species/on_species_gain(): (datum/species/new_species, datum/species/old_species)
+#define COMSIG_SPECIES_LOSS "species_loss" //from datum/species/on_species_loss(): (datum/species/lost_species)
+
+// /datum/song signals
+#define COMSIG_SONG_START "song_start" //sent to the instrument when a song starts playing
+#define COMSIG_SONG_END "song_end" //sent to the instrument when a song stops playing
+
+/*******Component Specific Signals*******/
+//Janitor
+#define COMSIG_TURF_IS_WET "check_turf_wet" //(): Returns bitflags of wet values.
+#define COMSIG_TURF_MAKE_DRY "make_turf_try" //(max_strength, immediate, duration_decrease = INFINITY): Returns bool.
+#define COMSIG_COMPONENT_CLEAN_ACT "clean_act" //called on an object to clean it of cleanables. Usualy with soap: (num/strength)
+
+//Creamed
+#define COMSIG_COMPONENT_CLEAN_FACE_ACT "clean_face_act" //called when you wash your face at a sink: (num/strength)
+
+//Food
+#define COMSIG_FOOD_EATEN "food_eaten" //from base of obj/item/reagent_containers/food/snacks/attack(): (mob/living/eater, mob/feeder)
+
+//Gibs
+#define COMSIG_GIBS_STREAK "gibs_streak" // from base of /obj/effect/decal/cleanable/blood/gibs/streak(): (list/directions, list/diseases)
+
+//Mood
+#define COMSIG_ADD_MOOD_EVENT "add_mood" //Called when you send a mood event from anywhere in the code.
+#define COMSIG_ADD_MOOD_EVENT_RND "RND_add_mood" //Mood event that only RnD members listen for
+#define COMSIG_CLEAR_MOOD_EVENT "clear_mood" //Called when you clear a mood event from anywhere in the code.
+
+//NTnet
+#define COMSIG_COMPONENT_NTNET_RECEIVE "ntnet_receive" //called on an object by its NTNET connection component on receive. (sending_id(number), sending_netname(text), data(datum/netdata))
+
+//Nanites
+#define COMSIG_HAS_NANITES "has_nanites" //() returns TRUE if nanites are found
+#define COMSIG_NANITE_IS_STEALTHY "nanite_is_stealthy" //() returns TRUE if nanites have stealth
+#define COMSIG_NANITE_DELETE "nanite_delete" //() deletes the nanite component
+#define COMSIG_NANITE_GET_PROGRAMS "nanite_get_programs" //(list/nanite_programs) - makes the input list a copy the nanites' program list
+#define COMSIG_NANITE_GET_VOLUME "nanite_get_volume" //(amount) Returns nanite amount
+#define COMSIG_NANITE_SET_VOLUME "nanite_set_volume" //(amount) Sets current nanite volume to the given amount
+#define COMSIG_NANITE_ADJUST_VOLUME "nanite_adjust" //(amount) Adjusts nanite volume by the given amount
+#define COMSIG_NANITE_SET_MAX_VOLUME "nanite_set_max_volume" //(amount) Sets maximum nanite volume to the given amount
+#define COMSIG_NANITE_SET_CLOUD "nanite_set_cloud" //(amount(0-100)) Sets cloud ID to the given amount
+#define COMSIG_NANITE_SET_CLOUD_SYNC "nanite_set_cloud_sync" //(method) Modify cloud sync status. Method can be toggle, enable or disable
+#define COMSIG_NANITE_SET_SAFETY "nanite_set_safety" //(amount) Sets safety threshold to the given amount
+#define COMSIG_NANITE_SET_REGEN "nanite_set_regen" //(amount) Sets regeneration rate to the given amount
+#define COMSIG_NANITE_SIGNAL "nanite_signal" //(code(1-9999)) Called when sending a nanite signal to a mob.
+#define COMSIG_NANITE_COMM_SIGNAL "nanite_comm_signal" //(comm_code(1-9999), comm_message) Called when sending a nanite comm signal to a mob.
+#define COMSIG_NANITE_SCAN "nanite_scan" //(mob/user, full_scan) - sends to chat a scan of the nanites to the user, returns TRUE if nanites are detected
+#define COMSIG_NANITE_UI_DATA "nanite_ui_data" //(list/data, scan_level) - adds nanite data to the given data list - made for ui_data procs
+#define COMSIG_NANITE_ADD_PROGRAM "nanite_add_program" //(datum/nanite_program/new_program, datum/nanite_program/source_program) Called when adding a program to a nanite component
+ #define COMPONENT_PROGRAM_INSTALLED 1 //Installation successful
+ #define COMPONENT_PROGRAM_NOT_INSTALLED 2 //Installation failed, but there are still nanites
+#define COMSIG_NANITE_SYNC "nanite_sync" //(datum/component/nanites, full_overwrite, copy_activation) Called to sync the target's nanites to a given nanite component
+
+// /datum/component/storage signals
+#define COMSIG_CONTAINS_STORAGE "is_storage" //() - returns bool.
+#define COMSIG_TRY_STORAGE_INSERT "storage_try_insert" //(obj/item/inserting, mob/user, silent, force) - returns bool
+#define COMSIG_TRY_STORAGE_SHOW "storage_show_to" //(mob/show_to, force) - returns bool.
+#define COMSIG_TRY_STORAGE_HIDE_FROM "storage_hide_from" //(mob/hide_from) - returns bool
+#define COMSIG_TRY_STORAGE_HIDE_ALL "storage_hide_all" //returns bool
+#define COMSIG_TRY_STORAGE_SET_LOCKSTATE "storage_lock_set_state" //(newstate)
+#define COMSIG_IS_STORAGE_LOCKED "storage_get_lockstate" //() - returns bool. MUST CHECK IF STORAGE IS THERE FIRST!
+#define COMSIG_TRY_STORAGE_TAKE_TYPE "storage_take_type" //(type, atom/destination, amount = INFINITY, check_adjacent, force, mob/user, list/inserted) - returns bool - type can be a list of types.
+#define COMSIG_TRY_STORAGE_FILL_TYPE "storage_fill_type" //(type, amount = INFINITY, force = FALSE) //don't fuck this up. Force will ignore max_items, and amount is normally clamped to max_items.
+#define COMSIG_TRY_STORAGE_TAKE "storage_take_obj" //(obj, new_loc, force = FALSE) - returns bool
+#define COMSIG_TRY_STORAGE_QUICK_EMPTY "storage_quick_empty" //(loc) - returns bool - if loc is null it will dump at parent location.
+#define COMSIG_TRY_STORAGE_RETURN_INVENTORY "storage_return_inventory" //(list/list_to_inject_results_into, recursively_search_inside_storages = TRUE)
+#define COMSIG_TRY_STORAGE_CAN_INSERT "storage_can_equip" //(obj/item/insertion_candidate, mob/user, silent) - returns bool
+
+// /datum/action signals
+#define COMSIG_ACTION_TRIGGER "action_trigger" //from base of datum/action/proc/Trigger(): (datum/action)
+ #define COMPONENT_ACTION_BLOCK_TRIGGER 1
+
+//Xenobio hotkeys
+#define COMSIG_XENO_SLIME_CLICK_CTRL "xeno_slime_click_ctrl" //from slime CtrlClickOn(): (/mob)
+#define COMSIG_XENO_SLIME_CLICK_ALT "xeno_slime_click_alt" //from slime AltClickOn(): (/mob)
+#define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift" //from slime ShiftClickOn(): (/mob)
+#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift" //from turf ShiftClickOn(): (/mob)
+#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob)
+#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob)
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index c2b75a0bf0f..59a0a4c22a7 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -95,7 +95,7 @@
#define STATUS_EFFECT_GO_AWAY /datum/status_effect/go_away //makes you launch through walls in a single direction for a while
-#define STATUS_EFFECT_STASIS /datum/status_effect/incapacitating/stasis //Halts biological functions like bleeding, chemical processing, blood regeneration, walking, etc
+#define STATUS_EFFECT_STASIS /datum/status_effect/grouped/stasis //Halts biological functions like bleeding, chemical processing, blood regeneration, walking, etc
#define STATUS_EFFECT_FAKE_VIRUS /datum/status_effect/fake_virus //gives you fluff messages for cough, sneeze, headache, etc but without an actual virus
@@ -125,6 +125,10 @@
#define STATUS_EFFECT_RAINBOWPROTECTION /datum/status_effect/rainbow_protection //Invulnerable and pacifistic
#define STATUS_EFFECT_SLIMESKIN /datum/status_effect/slimeskin //Increased armor
+// Grouped effect sources, see also code/__DEFINES/traits.dm
+
+#define STASIS_MACHINE_EFFECT "stasis_machine"
+
// Stasis helpers
#define IS_IN_STASIS(mob) (mob.has_status_effect(STATUS_EFFECT_STASIS))
diff --git a/code/controllers/subsystem/dcs.dm b/code/controllers/subsystem/dcs.dm
index 53c4b7fa311..8b068e5d675 100644
--- a/code/controllers/subsystem/dcs.dm
+++ b/code/controllers/subsystem/dcs.dm
@@ -7,22 +7,47 @@ PROCESSING_SUBSYSTEM_DEF(dcs)
/datum/controller/subsystem/processing/dcs/Recover()
comp_lookup = SSdcs.comp_lookup
-/datum/controller/subsystem/processing/dcs/proc/GetElement(datum/element/eletype, ...)
+/datum/controller/subsystem/processing/dcs/proc/GetElement(list/arguments)
+ var/datum/element/eletype = arguments[1]
var/element_id = eletype
-
+
+ if(!ispath(eletype, /datum/element))
+ CRASH("Attempted to instantiate [eletype] as a /datum/element")
+
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("&")
-
+ element_id = GetIdFromArguments(arguments)
+
. = elements_by_type[element_id]
if(.)
return
- if(!ispath(eletype, /datum/element))
- CRASH("Attempted to instantiate [eletype] as a /datum/element")
. = elements_by_type[element_id] = new eletype
+
+/****
+ * Generates an id for bespoke elements when given the argument list
+ * Generating the id here is a bit complex because we need to support named arguments
+ * Named arguments can appear in any order and we need them to appear after ordered arguments
+ * We assume that no one will pass in a named argument with a value of null
+ **/
+/datum/controller/subsystem/processing/dcs/proc/GetIdFromArguments(list/arguments)
+ var/datum/element/eletype = arguments[1]
+ var/list/fullid = list("[eletype]")
+ var/list/named_arguments = list()
+ for(var/i in initial(eletype.id_arg_index) to length(arguments))
+ var/key = arguments[i]
+ var/value
+ if(istext(key))
+ value = arguments[key]
+ if(!(istext(key) || isnum(key)))
+ key = REF(key)
+ key = "[key]" // Key is stringified so numbers dont break things
+ if(!isnull(value))
+ if(!(istext(value) || isnum(value)))
+ value = REF(value)
+ named_arguments["[key]"] = value
+ else
+ fullid += "[key]"
+
+ if(length(named_arguments))
+ named_arguments = sortList(named_arguments)
+ fullid += named_arguments
+ return list2params(fullid)
diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm
index 8a4c8f682ff..7a03d87fc4d 100644
--- a/code/datums/components/_component.dm
+++ b/code/datums/components/_component.dm
@@ -13,15 +13,15 @@
/// Defines how duplicate existing components are handled when added to a datum
/// See `COMPONENT_DUPE_*` definitions for available options
var/dupe_mode = COMPONENT_DUPE_HIGHLANDER
-
+
/// The type to check for duplication
/// `null` means exact match on `type` (default)
/// Any other type means that and all subtypes
var/dupe_type
-
+
/// The datum this components belongs to
var/datum/parent
-
+
/// Only set to true if you are able to properly transfer this component
/// At a minimum RegisterWithParent and UnregisterFromParent should be used
/// Make sure you also implement PostTransfer for any post transfer handling
@@ -34,14 +34,14 @@
* Arguments:
* * datum/P the parent datum this component reacts to signals from
*/
-/datum/component/New(datum/P, ...)
- parent = P
- var/list/arguments = args.Copy(2)
+/datum/component/New(list/raw_args)
+ parent = raw_args[1]
+ var/list/arguments = raw_args.Copy(2)
if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE)
qdel(src, TRUE, TRUE)
- CRASH("Incompatible [type] assigned to a [P.type]! args: [json_encode(arguments)]")
+ CRASH("Incompatible [type] assigned to a [parent.type]! args: [json_encode(arguments)]")
- _JoinParent(P)
+ _JoinParent(parent)
/**
* Called during component creation with the same arguments as in new excluding parent.
@@ -361,7 +361,8 @@
* 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
*/
-/datum/proc/AddComponent(new_type, ...)
+/datum/proc/_AddComponent(list/raw_args)
+ var/new_type = raw_args[1]
var/datum/component/nt = new_type
var/dm = initial(nt.dupe_mode)
var/dt = initial(nt.dupe_type)
@@ -376,7 +377,7 @@
new_comp = nt
nt = new_comp.type
- args[1] = src
+ raw_args[1] = src
if(dm != COMPONENT_DUPE_ALLOWED)
if(!dt)
@@ -387,24 +388,25 @@
switch(dm)
if(COMPONENT_DUPE_UNIQUE)
if(!new_comp)
- new_comp = new nt(arglist(args))
+ new_comp = new nt(raw_args)
if(!QDELETED(new_comp))
old_comp.InheritComponent(new_comp, TRUE)
QDEL_NULL(new_comp)
if(COMPONENT_DUPE_HIGHLANDER)
if(!new_comp)
- new_comp = new nt(arglist(args))
+ new_comp = new nt(raw_args)
if(!QDELETED(new_comp))
new_comp.InheritComponent(old_comp, FALSE)
QDEL_NULL(old_comp)
if(COMPONENT_DUPE_UNIQUE_PASSARGS)
if(!new_comp)
- var/list/arguments = args.Copy(2)
- old_comp.InheritComponent(null, TRUE, arguments)
+ var/list/arguments = raw_args.Copy(2)
+ arguments.Insert(1, null, TRUE)
+ old_comp.InheritComponent(arglist(arguments))
else
old_comp.InheritComponent(new_comp, TRUE)
if(COMPONENT_DUPE_SELECTIVE)
- var/list/arguments = args.Copy()
+ var/list/arguments = raw_args.Copy()
arguments[1] = new_comp
var/make_new_component = TRUE
for(var/i in GetComponents(new_type))
@@ -414,11 +416,11 @@
QDEL_NULL(new_comp)
break
if(!new_comp && make_new_component)
- new_comp = new nt(arglist(args))
+ new_comp = new nt(raw_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
+ new_comp = new nt(raw_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
+ new_comp = new nt(raw_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
SEND_SIGNAL(src, COMSIG_COMPONENT_ADDED, new_comp)
@@ -437,7 +439,7 @@
/datum/proc/LoadComponent(component_type, ...)
. = GetComponent(component_type)
if(!.)
- return AddComponent(arglist(args))
+ return _AddComponent(args)
/**
* Removes the component from parent, ends up with a null parent
diff --git a/code/datums/components/fantasy/_fantasy.dm b/code/datums/components/fantasy/_fantasy.dm
index 86e016784ad..a203264fae0 100644
--- a/code/datums/components/fantasy/_fantasy.dm
+++ b/code/datums/components/fantasy/_fantasy.dm
@@ -37,17 +37,16 @@
/datum/component/fantasy/UnregisterFromParent()
unmodify()
-/datum/component/fantasy/InheritComponent(datum/component/fantasy/newComp, original, list/arguments)
+/datum/component/fantasy/InheritComponent(datum/component/fantasy/newComp, original, quality, list/affixes, canFail, announce)
unmodify()
if(newComp)
- quality += newComp.quality
- canFail = newComp.canFail
- announce = newComp.announce
+ src.quality += newComp.quality
+ src.canFail = newComp.canFail
+ src.announce = newComp.announce
else
- arguments.len = 5 // This is done to replicate what happens when an arglist smaller than the necessary arguments is given
- quality += arguments[1]
- canFail = arguments[4] || canFail
- announce = arguments[5] || announce
+ src.quality += quality
+ src.canFail = canFail || src.canFail
+ src.announce = announce || src.announce
modify()
/datum/component/fantasy/proc/randomQuality()
diff --git a/code/datums/components/nanites.dm b/code/datums/components/nanites.dm
index dc1e73dd264..64870dfca6d 100644
--- a/code/datums/components/nanites.dm
+++ b/code/datums/components/nanites.dm
@@ -101,11 +101,11 @@
host_mob = null
return ..()
-/datum/component/nanites/InheritComponent(datum/component/nanites/new_nanites, i_am_original, list/arguments)
+/datum/component/nanites/InheritComponent(datum/component/nanites/new_nanites, i_am_original, amount, cloud)
if(new_nanites)
adjust_nanites(null, new_nanites.nanite_volume)
else
- adjust_nanites(null, arguments[1]) //just add to the nanite volume
+ adjust_nanites(null, amount) //just add to the nanite volume
/datum/component/nanites/process()
if(!IS_IN_STASIS(host_mob))
diff --git a/code/datums/components/orbiter.dm b/code/datums/components/orbiter.dm
index 44665479192..80e1bc59505 100644
--- a/code/datums/components/orbiter.dm
+++ b/code/datums/components/orbiter.dm
@@ -37,9 +37,9 @@
orbiters = null
return ..()
-/datum/component/orbiter/InheritComponent(datum/component/orbiter/newcomp, original, list/arguments)
- if(arguments)
- begin_orbit(arglist(arguments))
+/datum/component/orbiter/InheritComponent(datum/component/orbiter/newcomp, original, atom/movable/orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
+ if(!newcomp)
+ begin_orbit(arglist(args.Copy(3)))
return
// The following only happens on component transfers
orbiters += newcomp.orbiters
diff --git a/code/datums/components/radioactive.dm b/code/datums/components/radioactive.dm
index ed34ac90074..0b9b62eb7c6 100644
--- a/code/datums/components/radioactive.dm
+++ b/code/datums/components/radioactive.dm
@@ -18,7 +18,7 @@
hl3_release_date = _half_life
can_contaminate = _can_contaminate
- if(istype(parent, /atom))
+ if(istype(parent, /atom))
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/rad_examine)
if(istype(parent, /obj/item))
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/rad_attack)
@@ -47,7 +47,7 @@
qdel(src)
return PROCESS_KILL
-/datum/component/radioactive/InheritComponent(datum/component/C, i_am_original, list/arguments)
+/datum/component/radioactive/InheritComponent(datum/component/C, i_am_original, _strength, _source, _half_life, _can_contaminate)
if(!i_am_original)
return
if(!hl3_release_date) // Permanently radioactive things don't get to grow stronger
@@ -56,7 +56,7 @@
var/datum/component/radioactive/other = C
strength = max(strength, other.strength)
else
- strength = max(strength, arguments[1])
+ strength = max(strength, _strength)
/datum/component/radioactive/proc/rad_examine(datum/source, mob/user, atom/thing)
var/atom/master = parent
diff --git a/code/datums/components/remote_materials.dm b/code/datums/components/remote_materials.dm
index ab5dd224733..e4faab361a6 100644
--- a/code/datums/components/remote_materials.dm
+++ b/code/datums/components/remote_materials.dm
@@ -54,11 +54,22 @@ handles linking back and forth.
/datum/component/remote_materials/proc/_MakeLocal()
silo = null
- mat_container = parent.AddComponent(/datum/component/material_container,
- list(/datum/material/iron, /datum/material/glass, /datum/material/silver, /datum/material/gold, /datum/material/diamond, /datum/material/plasma, /datum/material/uranium, /datum/material/bananium, /datum/material/titanium, /datum/material/bluespace, /datum/material/plastic),
- local_size,
- FALSE,
- /obj/item/stack)
+
+ var/static/list/allowed_mats = list(
+ /datum/material/iron,
+ /datum/material/glass,
+ /datum/material/silver,
+ /datum/material/gold,
+ /datum/material/diamond,
+ /datum/material/plasma,
+ /datum/material/uranium,
+ /datum/material/bananium,
+ /datum/material/titanium,
+ /datum/material/bluespace,
+ /datum/material/plastic,
+ )
+
+ mat_container = parent.AddComponent(/datum/component/material_container, allowed_mats, local_size, allowed_types=/obj/item/stack)
/datum/component/remote_materials/proc/set_local_size(size)
local_size = size
diff --git a/code/datums/components/stationloving.dm b/code/datums/components/stationloving.dm
index 51d67e10e20..0282f247153 100644
--- a/code/datums/components/stationloving.dm
+++ b/code/datums/components/stationloving.dm
@@ -16,13 +16,13 @@
src.allow_death = allow_death
check_in_bounds() // Just in case something is being created outside of station/centcom
-/datum/component/stationloving/InheritComponent(datum/component/stationloving/newc, original, list/arguments)
+/datum/component/stationloving/InheritComponent(datum/component/stationloving/newc, original, inform_admins, allow_death)
if (original)
- if (istype(newc))
+ if (newc)
inform_admins = newc.inform_admins
allow_death = newc.allow_death
- else if (LAZYLEN(arguments))
- inform_admins = arguments[1]
+ else
+ inform_admins = inform_admins
/datum/component/stationloving/proc/relocate()
var/targetturf = find_safe_turf()
diff --git a/code/datums/components/stationstuck.dm b/code/datums/components/stationstuck.dm
index 5fd00d30119..b9027ef8115 100644
--- a/code/datums/components/stationstuck.dm
+++ b/code/datums/components/stationstuck.dm
@@ -15,11 +15,13 @@
stuck_zlevel = L.z
-/datum/component/stationstuck/InheritComponent(datum/component/stationstuck/newc, original, list/arguments)
- if(original)
- if(istype(newc))
- murder = newc.murder
- message = newc.message
+/datum/component/stationstuck/InheritComponent(datum/component/stationstuck/newc, original, _murder, _message)
+ if(newc)
+ murder = newc.murder
+ message = newc.message
+ else
+ murder = _murder
+ message = _message
/datum/component/stationstuck/proc/punish()
var/mob/living/L = parent
diff --git a/code/datums/components/thermite.dm b/code/datums/components/thermite.dm
index ce397f9fea5..b745e740571 100644
--- a/code/datums/components/thermite.dm
+++ b/code/datums/components/thermite.dm
@@ -52,13 +52,13 @@
master.cut_overlay(overlay)
return ..()
-/datum/component/thermite/InheritComponent(datum/component/thermite/newC, i_am_original, list/arguments)
+/datum/component/thermite/InheritComponent(datum/component/thermite/newC, i_am_original, _amount)
if(!i_am_original)
return
if(newC)
amount += newC.amount
else
- amount += arguments[1]
+ amount += _amount
/datum/component/thermite/proc/thermite_melt(mob/user)
var/turf/master = parent
diff --git a/code/datums/components/wet_floor.dm b/code/datums/components/wet_floor.dm
index 715c20e4219..fd2a82ce042 100644
--- a/code/datums/components/wet_floor.dm
+++ b/code/datums/components/wet_floor.dm
@@ -12,9 +12,9 @@
var/permanent = FALSE
var/last_process = 0
-/datum/component/wet_floor/InheritComponent(datum/newcomp, orig, argslist)
+/datum/component/wet_floor/InheritComponent(datum/newcomp, orig, strength, duration_minimum, duration_add, duration_maximum, _permanent)
if(!newcomp) //We are getting passed the arguments of a would-be new component, but not a new component
- add_wet(arglist(argslist))
+ add_wet(arglist(args.Copy(3)))
else //We are being passed in a full blown component
var/datum/component/wet_floor/WF = newcomp //Lets make an assumption
if(WF.gc()) //See if it's even valid, still. Also does LAZYLEN and stuff for us.
diff --git a/code/datums/elements/_element.dm b/code/datums/elements/_element.dm
index bf510e0f56f..f74dcd0b6e1 100644
--- a/code/datums/elements/_element.dm
+++ b/code/datums/elements/_element.dm
@@ -36,16 +36,16 @@
//DATUM PROCS
/// Finds the singleton for the element type given and attaches it to src
-/datum/proc/AddElement(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)]")
+/datum/proc/_AddElement(list/arguments)
+ var/datum/element/ele = SSdcs.GetElement(arguments)
+ arguments[1] = src
+ if(ele.Attach(arglist(arguments)) == ELEMENT_INCOMPATIBLE)
+ CRASH("Incompatible [arguments[1]] assigned to a [type]! args: [json_encode(args)]")
/**
* Finds the singleton for the element type given and detaches it from src
* You only need additional arguments beyond the type if you're using ELEMENT_BESPOKE
*/
-/datum/proc/RemoveElement(eletype, ...)
- var/datum/element/ele = SSdcs.GetElement(arglist(args))
+/datum/proc/_RemoveElement(list/arguments)
+ var/datum/element/ele = SSdcs.GetElement(arguments)
ele.Detach(src)
diff --git a/code/datums/materials/_material.dm b/code/datums/materials/_material.dm
index b5ba7246967..5e5a2eaca34 100644
--- a/code/datums/materials/_material.dm
+++ b/code/datums/materials/_material.dm
@@ -41,7 +41,7 @@ Simple datum which is instanced once per type and is used for every object of sa
source.name = "[name] [source.name]"
if(beauty_modifier)
- addtimer(CALLBACK(source, /datum.proc/AddComponent, /datum/component/beauty, beauty_modifier * amount), 0)
+ addtimer(CALLBACK(source, /datum.proc/_AddComponent, list(/datum/component/beauty, beauty_modifier * amount)), 0)
if(istype(source, /obj)) //objs
on_applied_obj(source, amount, material_flags)
diff --git a/code/datums/materials/basemats.dm b/code/datums/materials/basemats.dm
index 2f86e777029..839d6857401 100644
--- a/code/datums/materials/basemats.dm
+++ b/code/datums/materials/basemats.dm
@@ -99,12 +99,12 @@ Unless you know what you're doing, only use the first three numbers. They're in
/datum/material/plasma/on_applied(atom/source, amount, material_flags)
. = ..()
if(ismovableatom(source))
- source.AddElement(/datum/element/firestacker, 1)
+ source.AddElement(/datum/element/firestacker, amount=1)
source.AddComponent(/datum/component/explodable, 0, 0, amount / 2500, amount / 1250)
/datum/material/plasma/on_removed(atom/source, material_flags)
. = ..()
- source.RemoveElement(/datum/element/firestacker, 1)
+ source.RemoveElement(/datum/element/firestacker, amount=1)
qdel(source.GetComponent(/datum/component/explodable))
///Can cause bluespace effects on use. (Teleportation) (Not yet implemented)
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index 51794087288..6bb0bc4b6e9 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -98,43 +98,42 @@
icon_state = "asleep"
//STASIS
-/datum/status_effect/incapacitating/stasis
- id = "stasis"
- duration = -1
- tick_interval = 10
- alert_type = /obj/screen/alert/status_effect/stasis
- var/last_dead_time
+/datum/status_effect/grouped/stasis
+ id = "stasis"
+ duration = -1
+ tick_interval = 10
+ alert_type = /obj/screen/alert/status_effect/stasis
+ var/last_dead_time
-/datum/status_effect/incapacitating/stasis/proc/update_time_of_death()
- if(last_dead_time)
- var/delta = world.time - last_dead_time
- var/new_timeofdeath = owner.timeofdeath + delta
- owner.timeofdeath = new_timeofdeath
- owner.tod = station_time_timestamp(wtime=new_timeofdeath)
- last_dead_time = null
- if(owner.stat == DEAD)
- last_dead_time = world.time
+/datum/status_effect/grouped/stasis/proc/update_time_of_death()
+ if(last_dead_time)
+ var/delta = world.time - last_dead_time
+ var/new_timeofdeath = owner.timeofdeath + delta
+ owner.timeofdeath = new_timeofdeath
+ owner.tod = station_time_timestamp(wtime=new_timeofdeath)
+ last_dead_time = null
+ if(owner.stat == DEAD)
+ last_dead_time = world.time
-/datum/status_effect/incapacitating/stasis/on_creation(mob/living/new_owner, set_duration, updating_canmove)
- . = ..()
- update_time_of_death()
- owner.reagents?.end_metabolization(owner, FALSE)
+/datum/status_effect/grouped/stasis/on_creation(mob/living/new_owner, set_duration, updating_canmove)
+ . = ..()
+ if(.)
+ update_time_of_death()
+ owner.reagents?.end_metabolization(owner, FALSE)
+ owner.update_mobility()
-/datum/status_effect/incapacitating/stasis/tick()
- update_time_of_death()
+/datum/status_effect/grouped/stasis/tick()
+ update_time_of_death()
-/datum/status_effect/incapacitating/stasis/on_remove()
- update_time_of_death()
- return ..()
-
-/datum/status_effect/incapacitating/stasis/be_replaced()
- update_time_of_death()
- return ..()
+/datum/status_effect/grouped/stasis/on_remove()
+ owner.update_mobility()
+ update_time_of_death()
+ return ..()
/obj/screen/alert/status_effect/stasis
- name = "Stasis"
- desc = "Your biological functions have halted. You could live forever this way, but it's pretty boring."
- icon_state = "stasis"
+ name = "Stasis"
+ desc = "Your biological functions have halted. You could live forever this way, but it's pretty boring."
+ icon_state = "stasis"
//GOLEM GANG
diff --git a/code/datums/status_effects/status_effect.dm b/code/datums/status_effects/status_effect.dm
index 112d17c4e72..891102a291d 100644
--- a/code/datums/status_effects/status_effect.dm
+++ b/code/datums/status_effects/status_effect.dm
@@ -63,6 +63,9 @@
owner = null
qdel(src)
+/datum/status_effect/proc/before_remove() //! Called before being removed; returning FALSE will cancel removal
+ return TRUE
+
/datum/status_effect/proc/refresh()
var/original_duration = initial(duration)
if(original_duration == -1)
@@ -107,12 +110,13 @@
S1 = new effect(arguments)
. = S1
-/mob/living/proc/remove_status_effect(effect) //removes all of a given status effect from this mob, returning TRUE if at least one was removed
+/mob/living/proc/remove_status_effect(effect, ...) //removes all of a given status effect from this mob, returning TRUE if at least one was removed
. = FALSE
+ var/list/arguments = args.Copy(2)
if(status_effects)
var/datum/status_effect/S1 = effect
for(var/datum/status_effect/S in status_effects)
- if(initial(S1.id) == S.id)
+ if(initial(S1.id) == S.id && S.before_remove(arguments))
qdel(S)
. = TRUE
@@ -238,3 +242,22 @@
owner.underlays -= status_underlay
QDEL_NULL(status_overlay)
return ..()
+
+/// Status effect from multiple sources, when all sources are removed, so is the effect
+/datum/status_effect/grouped
+ status_type = STATUS_EFFECT_MULTIPLE //! Adds itself to sources and destroys itself if one exists already, there are never multiple
+ var/list/sources = list()
+
+/datum/status_effect/grouped/on_creation(mob/living/new_owner, source)
+ var/datum/status_effect/grouped/existing = new_owner.has_status_effect(type)
+ if(existing)
+ existing.sources |= source
+ qdel(src)
+ return FALSE
+ else
+ sources |= source
+ return ..()
+
+/datum/status_effect/grouped/before_remove(source)
+ sources -= source
+ return !length(sources)
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 32cf77212bf..8179e7f227c 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -48,23 +48,24 @@
)
/obj/machinery/autolathe/Initialize()
- AddComponent(/datum/component/material_container,
- list(/datum/material/iron,
- /datum/material/glass,
- /datum/material/gold,
- /datum/material/silver,
- /datum/material/diamond,
- /datum/material/uranium,
- /datum/material/plasma,
- /datum/material/bluespace,
- /datum/material/bananium,
- /datum/material/titanium,
- /datum/material/runite,
- /datum/material/plastic,
- /datum/material/adamantine,
- /datum/material/mythril,
- /datum/material/wood
- ), 0, TRUE, null, null, CALLBACK(src, .proc/AfterMaterialInsert))
+ var/static/list/allowed_types = list(
+ /datum/material/iron,
+ /datum/material/glass,
+ /datum/material/gold,
+ /datum/material/silver,
+ /datum/material/diamond,
+ /datum/material/uranium,
+ /datum/material/plasma,
+ /datum/material/bluespace,
+ /datum/material/bananium,
+ /datum/material/titanium,
+ /datum/material/runite,
+ /datum/material/plastic,
+ /datum/material/adamantine,
+ /datum/material/mythril,
+ /datum/material/wood,
+ )
+ AddComponent(/datum/component/material_container, allowed_types, _show_on_examine=TRUE, _after_insert=CALLBACK(src, .proc/AfterMaterialInsert))
. = ..()
wires = new /datum/wires/autolathe(src)
diff --git a/code/game/machinery/stasis.dm b/code/game/machinery/stasis.dm
index 5392608670e..8daab3a9e16 100644
--- a/code/game/machinery/stasis.dm
+++ b/code/game/machinery/stasis.dm
@@ -109,12 +109,12 @@
return
var/freq = rand(24750, 26550)
playsound(src, 'sound/effects/spray.ogg', 5, TRUE, 2, frequency = freq)
- target.apply_status_effect(STATUS_EFFECT_STASIS, null, TRUE)
+ target.apply_status_effect(STATUS_EFFECT_STASIS, STASIS_MACHINE_EFFECT)
target.ExtinguishMob()
use_power = ACTIVE_POWER_USE
/obj/machinery/stasis/proc/thaw_them(mob/living/target)
- target.remove_status_effect(STATUS_EFFECT_STASIS)
+ target.remove_status_effect(STATUS_EFFECT_STASIS, STASIS_MACHINE_EFFECT)
if(target == occupant)
use_power = IDLE_POWER_USE
diff --git a/code/game/objects/effects/contraband.dm b/code/game/objects/effects/contraband.dm
index bf7ff0818c0..c19561c22c5 100644
--- a/code/game/objects/effects/contraband.dm
+++ b/code/game/objects/effects/contraband.dm
@@ -68,7 +68,7 @@
name = "poster - [name]"
desc = "A large piece of space-resistant printed paper. [desc]"
- addtimer(CALLBACK(src, /datum.proc/AddComponent, /datum/component/beauty, 300), 0)
+ addtimer(CALLBACK(src, /datum.proc/_AddComponent, list(/datum/component/beauty, 300)), 0)
/obj/structure/sign/poster/proc/randomise(base_type)
var/list/poster_types = subtypesof(base_type)
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index c988704828b..b197c758c97 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -26,7 +26,7 @@
if(LAZYLEN(diseases_to_add))
AddComponent(/datum/component/infective, diseases_to_add)
- addtimer(CALLBACK(src, /datum.proc/AddComponent, /datum/component/beauty, beauty), 0)
+ addtimer(CALLBACK(src, /datum.proc/_AddComponent, list(/datum/component/beauty, beauty)), 0)
var/turf/T = get_turf(src)
if(T && is_station_level(T.z))
diff --git a/code/game/objects/items/grenades/antigravity.dm b/code/game/objects/items/grenades/antigravity.dm
index cf7dc928ae0..a4bc207be03 100644
--- a/code/game/objects/items/grenades/antigravity.dm
+++ b/code/game/objects/items/grenades/antigravity.dm
@@ -12,6 +12,6 @@
for(var/turf/T in view(range,src))
T.AddElement(/datum/element/forced_gravity, forced_value)
- addtimer(CALLBACK(T, /datum/.proc/RemoveElement, forced_value), duration)
+ addtimer(CALLBACK(T, /datum/.proc/_RemoveElement, list(forced_value)), duration)
qdel(src)
diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm
index 19e1eb3b1aa..aba03d32524 100644
--- a/code/game/objects/items/weaponry.dm
+++ b/code/game/objects/items/weaponry.dm
@@ -475,7 +475,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
/obj/item/statuebust/Initialize()
. = ..()
AddComponent(/datum/component/art, impressiveness)
- addtimer(CALLBACK(src, /datum.proc/AddComponent, /datum/component/beauty, 1000), 0)
+ addtimer(CALLBACK(src, /datum.proc/_AddComponent, list(/datum/component/beauty, 1000)), 0)
/obj/item/statuebust/hippocratic
name = "hippocrates bust"
diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm
index e6da6eaf8a0..5f18b4478b9 100644
--- a/code/game/objects/structures/flora.dm
+++ b/code/game/objects/structures/flora.dm
@@ -316,7 +316,7 @@
/obj/item/twohanded/required/kirbyplants/Initialize()
. = ..()
AddComponent(/datum/component/tactical)
- addtimer(CALLBACK(src, /datum.proc/AddComponent, /datum/component/beauty, 500), 0)
+ addtimer(CALLBACK(src, /datum.proc/_AddComponent, list(/datum/component/beauty, 500)), 0)
/obj/item/twohanded/required/kirbyplants/random
icon = 'icons/obj/flora/_flora.dmi'
diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm
index 11b5b51ba0f..548831ea061 100644
--- a/code/game/objects/structures/statues.dm
+++ b/code/game/objects/structures/statues.dm
@@ -15,7 +15,7 @@
/obj/structure/statue/Initialize()
. = ..()
AddComponent(art_type, impressiveness)
- addtimer(CALLBACK(src, /datum.proc/AddComponent, /datum/component/beauty, impressiveness * 75), 0)
+ addtimer(CALLBACK(src, /datum.proc/_AddComponent, list(/datum/component/beauty, impressiveness * 75)), 0)
/obj/structure/statue/attackby(obj/item/W, mob/living/user, params)
add_fingerprint(user)
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index 08a435634e9..666ea864260 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -315,13 +315,8 @@
/obj/structure/windoor_assembly/ComponentInitialize()
. = ..()
- AddComponent(
- /datum/component/simple_rotation,
- ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS,
- null,
- CALLBACK(src, .proc/can_be_rotated),
- CALLBACK(src,.proc/after_rotation)
- )
+ var/static/rotation_flags = ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS
+ AddComponent(/datum/component/simple_rotation, rotation_flags, can_be_rotated=CALLBACK(src, .proc/can_be_rotated), after_rotation=CALLBACK(src,.proc/after_rotation))
/obj/structure/windoor_assembly/proc/can_be_rotated(mob/user,rotation_type)
if(anchored)
diff --git a/code/modules/admin/view_variables/topic_basic.dm b/code/modules/admin/view_variables/topic_basic.dm
index 2a1d4c7a6ff..79d7379b8bf 100644
--- a/code/modules/admin/view_variables/topic_basic.dm
+++ b/code/modules/admin/view_variables/topic_basic.dm
@@ -69,10 +69,10 @@
lst.Insert(1, result)
if(result in componentsubtypes)
datumname = "component"
- target.AddComponent(arglist(lst))
+ target._AddComponent(lst)
else
datumname = "element"
- target.AddElement(arglist(lst))
+ target._AddElement(lst)
log_admin("[key_name(usr)] has added [result] [datumname] to [key_name(src)].")
message_admins("[key_name_admin(usr)] has added [result] [datumname] to [key_name_admin(src)].")
if(href_list[VV_HK_CALLPROC])
diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm
index 3dddae32abc..eb31d9faf27 100644
--- a/code/modules/assembly/holder.dm
+++ b/code/modules/assembly/holder.dm
@@ -16,9 +16,8 @@
/obj/item/assembly_holder/ComponentInitialize()
. = ..()
- AddComponent(
- /datum/component/simple_rotation,
- ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_FLIP | ROTATION_VERBS)
+ var/static/rotation_flags = ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_FLIP | ROTATION_VERBS
+ AddComponent(/datum/component/simple_rotation, rotation_flags)
/obj/item/assembly_holder/IsAssemblyHolder()
return TRUE
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index 9e7fc5b556e..8099d18fb93 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -23,13 +23,8 @@
/obj/item/assembly/infra/ComponentInitialize()
. = ..()
- AddComponent(
- /datum/component/simple_rotation,
- ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_FLIP | ROTATION_VERBS,
- null,
- null,
- CALLBACK(src,.proc/after_rotation)
- )
+ var/static/rotation_flags = ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_FLIP | ROTATION_VERBS
+ AddComponent(/datum/component/simple_rotation, rotation_flags, after_rotation=CALLBACK(src,.proc/after_rotation))
/obj/item/assembly/infra/proc/after_rotation()
refreshBeam()
diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm
index 67eb8435656..e4ea0fba14d 100644
--- a/code/modules/clothing/gloves/color.dm
+++ b/code/modules/clothing/gloves/color.dm
@@ -12,6 +12,53 @@
custom_price = 1200
custom_premium_price = 1200
+/obj/item/toy/sprayoncan
+ name = "spray-on insulation applicator"
+ desc = "What is the number one problem facing our station today?"
+ icon = 'icons/obj/clothing/gloves.dmi'
+ icon_state = "sprayoncan"
+
+/obj/item/toy/sprayoncan/afterattack(atom/target, mob/living/carbon/user, proximity)
+ if(iscarbon(target) && proximity)
+ var/mob/living/carbon/C = target
+ var/mob/living/carbon/U = user
+ var/success = C.equip_to_slot_if_possible(new /obj/item/clothing/gloves/color/yellow/sprayon, ITEM_SLOT_GLOVES, TRUE, TRUE)
+ if(success)
+ if(C == user)
+ C.visible_message("[U] sprays their hands with glittery rubber!")
+ else
+ C.visible_message("[U] sprays glittery rubber on the hands of [C]!")
+ else
+ C.visible_message("The rubber fails to stick to [C]'s hands!")
+
+ qdel(src)
+
+/obj/item/clothing/gloves/color/yellow/sprayon
+ desc = "How're you gonna get 'em off, nerd?"
+ name = "spray-on insulated gloves"
+ icon_state = "sprayon"
+ item_state = "sprayon"
+ permeability_coefficient = 0
+ resistance_flags = ACID_PROOF
+ var/shocks_remaining = 10
+
+/obj/item/clothing/gloves/color/yellow/sprayon/Initialize()
+ .=..()
+ ADD_TRAIT(src, TRAIT_NODROP, CLOTHING_TRAIT)
+
+/obj/item/clothing/gloves/color/yellow/sprayon/equipped(mob/user, slot)
+ . = ..()
+ RegisterSignal(user, COMSIG_LIVING_SHOCK_PREVENTED, .proc/Shocked)
+
+/obj/item/clothing/gloves/color/yellow/sprayon/proc/Shocked()
+ shocks_remaining--
+ if(shocks_remaining < 0)
+ qdel(src) //if we run out of uses, the gloves crumble away into nothing, just like my dreams after working with .dm
+
+/obj/item/clothing/gloves/color/yellow/sprayon/dropped()
+ .=..()
+ qdel(src) //loose nodrop items bad
+
/obj/item/clothing/gloves/color/fyellow //Cheap Chinese Crap
desc = "These gloves are cheap knockoffs of the coveted ones - no way this can end badly."
name = "budget insulated gloves"
diff --git a/code/modules/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm
index cb5c534bde6..dfa98dbe7d0 100644
--- a/code/modules/mapping/mapping_helpers.dm
+++ b/code/modules/mapping/mapping_helpers.dm
@@ -187,7 +187,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava)
if(target_type && !istype(A,target_type))
continue
var/cargs = build_args()
- A.AddComponent(arglist(cargs))
+ A._AddComponent(cargs)
qdel(src)
return
diff --git a/code/modules/mining/machine_silo.dm b/code/modules/mining/machine_silo.dm
index 92aadd3ca04..0f2b8d70613 100644
--- a/code/modules/mining/machine_silo.dm
+++ b/code/modules/mining/machine_silo.dm
@@ -15,14 +15,20 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
/obj/machinery/ore_silo/Initialize(mapload)
. = ..()
- AddComponent(/datum/component/material_container,
- list(/datum/material/iron, /datum/material/glass, /datum/material/silver, /datum/material/gold, /datum/material/diamond, /datum/material/plasma, /datum/material/uranium, /datum/material/bananium, /datum/material/titanium, /datum/material/bluespace, /datum/material/plastic),
- INFINITY,
- FALSE,
- /obj/item/stack,
- null,
- null,
- TRUE)
+ var/static/list/materials_list = list(
+ /datum/material/iron,
+ /datum/material/glass,
+ /datum/material/silver,
+ /datum/material/gold,
+ /datum/material/diamond,
+ /datum/material/plasma,
+ /datum/material/uranium,
+ /datum/material/bananium,
+ /datum/material/titanium,
+ /datum/material/bluespace,
+ /datum/material/plastic,
+ )
+ AddComponent(/datum/component/material_container, materials_list, INFINITY, allowed_types=/obj/item/stack, _disable_attackby=TRUE)
if (!GLOB.ore_silo_default && mapload && is_station_level(z))
GLOB.ore_silo_default = src
diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm
index 4552bdc9346..d9eb4ac9fb7 100644
--- a/code/modules/power/power.dm
+++ b/code/modules/power/power.dm
@@ -292,6 +292,7 @@
if(H.gloves)
var/obj/item/clothing/gloves/G = H.gloves
if(G.siemens_coefficient == 0)
+ SEND_SIGNAL(M, COMSIG_LIVING_SHOCK_PREVENTED, power_source, source, siemens_coeff, dist_check)
return 0 //to avoid spamming with insulated glvoes on
var/area/source_area
diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm
index 79c8346468b..7b8e2c79dfb 100644
--- a/code/modules/projectiles/guns/magic/wand.dm
+++ b/code/modules/projectiles/guns/magic/wand.dm
@@ -1,6 +1,6 @@
/obj/item/gun/magic/wand
name = "wand of nothing"
- desc = "It's not just a stick, it's a MAGIC stick!"
+ desc = "It's not just a stick, it's a MAGIC stick! You shouldn't have this."
ammo_type = /obj/item/ammo_casing/magic
icon_state = "nothingwand"
item_state = "wand"
@@ -233,4 +233,7 @@
/////////////////////////////////////
/obj/item/gun/magic/wand/nothing
+ desc = "It's not just a stick, it's a MAGIC stick?"
ammo_type = /obj/item/ammo_casing/magic/nothing
+
+
diff --git a/code/modules/research/bepis.dm b/code/modules/research/bepis.dm
index 6e0b22e0118..dcf9be28e91 100644
--- a/code/modules/research/bepis.dm
+++ b/code/modules/research/bepis.dm
@@ -36,7 +36,8 @@
var/minor_rewards = list(/obj/item/stack/circuit_stack/full, //To add a new minor reward, add it here.
/obj/item/airlock_painter/decal,
/obj/item/pen/survival,
- /obj/item/circuitboard/machine/sleeper/party)
+ /obj/item/circuitboard/machine/sleeper/party,
+ /obj/item/toy/sprayoncan)
var/static/list/item_list = list()
/obj/machinery/rnd/bepis/attackby(obj/item/O, mob/user, params)
diff --git a/code/modules/research/nanites/nanite_cloud_controller.dm b/code/modules/research/nanites/nanite_cloud_controller.dm
index 1a11e1ecdfa..208f562c12a 100644
--- a/code/modules/research/nanites/nanite_cloud_controller.dm
+++ b/code/modules/research/nanites/nanite_cloud_controller.dm
@@ -48,7 +48,7 @@
return
var/datum/nanite_cloud_backup/backup = new(src)
- var/datum/component/nanites/cloud_copy = new(backup)
+ var/datum/component/nanites/cloud_copy = backup.AddComponent(/datum/component/nanites)
backup.cloud_id = cloud_id
backup.nanites = cloud_copy
investigate_log("[key_name(user)] created a new nanite cloud backup with id #[cloud_id]", INVESTIGATE_NANITES)
@@ -213,7 +213,7 @@
var/datum/component/nanites/nanites = backup.nanites
var/datum/nanite_program/P = nanites.programs[text2num(params["program_id"])]
var/datum/nanite_rule/rule = rule_template.make_rule(P)
-
+
investigate_log("[key_name(usr)] added rule [rule.display()] to program [P.name] in cloud #[current_view]", INVESTIGATE_NANITES)
. = TRUE
if("remove_rule")
@@ -224,7 +224,7 @@
var/datum/nanite_program/P = nanites.programs[text2num(params["program_id"])]
var/datum/nanite_rule/rule = P.rules[text2num(params["rule_id"])]
rule.remove()
-
+
investigate_log("[key_name(usr)] removed rule [rule.display()] from program [P.name] in cloud #[current_view]", INVESTIGATE_NANITES)
. = TRUE
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index e9bdf785464..e532631a3af 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -704,7 +704,7 @@
if(timeleft > 1 HOURS)
return "--:--"
else if(timeleft > 0)
- return "[add_leading(num2text((timeleft / 60) % 60), 2, "0")]:[add_leading(num2text(timeleft % 60), 2, " ")]"
+ return "[add_leading(num2text((timeleft / 60) % 60), 2, "0")]:[add_leading(num2text(timeleft % 60), 2, "0")]"
else
return "00:00"
diff --git a/code/modules/vending/autodrobe.dm b/code/modules/vending/autodrobe.dm
index e47b2d8959f..da517e4ff7f 100644
--- a/code/modules/vending/autodrobe.dm
+++ b/code/modules/vending/autodrobe.dm
@@ -125,7 +125,7 @@
/obj/item/gohei = 1)
contraband = list(/obj/item/clothing/suit/judgerobe = 1,
/obj/item/clothing/head/powdered_wig = 1,
- /obj/item/gun/magic/wand = 2,
+ /obj/item/gun/magic/wand/nothing = 2,
/obj/item/clothing/glasses/sunglasses/garb = 2,
/obj/item/clothing/glasses/blindfold = 1,
/obj/item/clothing/mask/muzzle = 2)
diff --git a/html/changelogs/AutoChangeLog-pr-48996.yml b/html/changelogs/AutoChangeLog-pr-48996.yml
new file mode 100644
index 00000000000..5de8ede8768
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-48996.yml
@@ -0,0 +1,4 @@
+author: "yeeyeh"
+delete-after: True
+changes:
+ - rscadd: "Nanotrasen's research division's recent science fair has given light to an amazing, electrically-insulated compound that can be sprayed directly onto the skin. The initial idea was for footwear, but we all know what you're really going to do with it. Research can be continued at your station's B.E.P.I.S. unit."
diff --git a/html/changelogs/AutoChangeLog-pr-49237.yml b/html/changelogs/AutoChangeLog-pr-49237.yml
new file mode 100644
index 00000000000..66a6626171a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-49237.yml
@@ -0,0 +1,4 @@
+author: "JJRcop"
+delete-after: True
+changes:
+ - refactor: "Stasis now supports multiple sources."
diff --git a/html/changelogs/AutoChangeLog-pr-49339.yml b/html/changelogs/AutoChangeLog-pr-49339.yml
new file mode 100644
index 00000000000..11ffc496e98
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-49339.yml
@@ -0,0 +1,4 @@
+author: "Dennok"
+delete-after: True
+changes:
+ - bugfix: "Now MultiZ Debug connected to neighbor space, in strange way."
diff --git a/html/changelogs/AutoChangeLog-pr-49375.yml b/html/changelogs/AutoChangeLog-pr-49375.yml
new file mode 100644
index 00000000000..c4f41bc13dd
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-49375.yml
@@ -0,0 +1,4 @@
+author: "Capsandi"
+delete-after: True
+changes:
+ - imageadd: "added a new mortar sprite"
diff --git a/icons/mob/clothing/hands.dmi b/icons/mob/clothing/hands.dmi
index c493483ce13..09966df4ec3 100644
Binary files a/icons/mob/clothing/hands.dmi and b/icons/mob/clothing/hands.dmi differ
diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi
index 717d8dd574e..38ce95b8c0e 100644
Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ
diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi
index a90efcdfea1..7a3d72c8841 100644
Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index a5ec0a5b06c..1ed30f7e48a 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -34,7 +34,6 @@
#include "code\__DEFINES\cleaning.dm"
#include "code\__DEFINES\colors.dm"
#include "code\__DEFINES\combat.dm"
-#include "code\__DEFINES\components.dm"
#include "code\__DEFINES\configuration.dm"
#include "code\__DEFINES\construction.dm"
#include "code\__DEFINES\contracts.dm"
@@ -114,6 +113,9 @@
#include "code\__DEFINES\vv.dm"
#include "code\__DEFINES\wall_dents.dm"
#include "code\__DEFINES\wires.dm"
+#include "code\__DEFINES\dcs\flags.dm"
+#include "code\__DEFINES\dcs\helpers.dm"
+#include "code\__DEFINES\dcs\signals.dm"
#include "code\__HELPERS\_lists.dm"
#include "code\__HELPERS\_logging.dm"
#include "code\__HELPERS\_string_lists.dm"
@@ -2770,13 +2772,13 @@
#include "code\modules\ruins\spaceruin_code\crashedship.dm"
#include "code\modules\ruins\spaceruin_code\deepstorage.dm"
#include "code\modules\ruins\spaceruin_code\DJstation.dm"
-#include "code\modules\ruins\spaceruin_code\forgottenship.dm"
#include "code\modules\ruins\spaceruin_code\hellfactory.dm"
#include "code\modules\ruins\spaceruin_code\hilbertshotel.dm"
#include "code\modules\ruins\spaceruin_code\listeningstation.dm"
#include "code\modules\ruins\spaceruin_code\oldstation.dm"
#include "code\modules\ruins\spaceruin_code\originalcontent.dm"
#include "code\modules\ruins\spaceruin_code\spacehotel.dm"
+#include "code\modules\ruins\spaceruin_code\forgottenship.dm"
#include "code\modules\ruins\spaceruin_code\TheDerelict.dm"
#include "code\modules\ruins\spaceruin_code\whiteshipruin_box.dm"
#include "code\modules\security_levels\keycard_authentication.dm"