diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index 9c1853f7d02..0a4ac519d9e 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -1,5 +1,7 @@
#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) )
+
//shorthand
#define GET_COMPONENT_FROM(varname, path, target) var##path/##varname = ##target.GetComponent(##path)
#define GET_COMPONENT(varname, path) GET_COMPONENT_FROM(varname, path, src)
@@ -8,15 +10,25 @@
// How multiple components of the exact same type are handled in the same datum
-#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default)
-#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed
-#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted
-#define COMPONENT_DUPE_UNIQUE_PASSARGS 4 //old component is given the initialization args of the new
+#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default)
+#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed
+#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted
+#define COMPONENT_DUPE_UNIQUE_PASSARGS 4 //old component is given the initialization args of the new
// All signals. Format:
// 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
+#define COMSIG_GLOB_NEW_Z "!new_z" //from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args)
+#define COMSIG_GLOB_VAR_EDIT "!var_edit" //called after a successful var edit somewhere in the world: (list/args)
+#define COMSIG_GLOB_MOB_CREATED "!mob_created" //mob was created somewhere : (mob)
+#define COMSIG_GLOB_MOB_DEATH "!mob_death" //mob died somewhere : (mob , gibbed)
+
+//////////////////////////////////////////////////////////////////
+
// /datum signals
#define COMSIG_COMPONENT_ADDED "component_added" //when a component is added to a datum: (/datum/component)
#define COMSIG_COMPONENT_REMOVING "component_removing" //before a component is removed from a datum because of RemoveComponent: (/datum/component)
@@ -35,6 +47,8 @@
//End positions
#define COMPONENT_EXNAME_CHANGED 1
#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_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)
@@ -49,9 +63,18 @@
#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_SET_LIGHT "atom_set_light" //from base of atom/set_light(): (l_range, l_power, l_color)
-#define COMSIG_ATOM_ROTATE "atom_rotate" //from base of atom/shuttleRotate(): (rotation, params)
#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_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)
@@ -62,7 +85,7 @@
#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)
+#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 COMSIG_CLICK_CTRL "ctrl_click" //from base of atom/CtrlClickOn(): (/mob)
#define COMSIG_CLICK_ALT "alt_click" //from base of atom/AltClick(): (/mob)
@@ -75,44 +98,117 @@
#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)
+
// /atom/movable signals
#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_COLLIDE "movable_collide" //from base of atom/movable/Collide(): (/atom)
+#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_THROW "movable_throw" //from base of atom/movable/throw_at(): (datum/thrownthing, spin)
+#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_HEAR "movable_hear" //from base of atom/movable/Hear(): (message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
+#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_CLICKON "mob_clickon" //from base of mob/clickon(): (atom/A, params)
+ #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(): (magic, holy, 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 COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_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_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): ()
+
+// /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)
+#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: ()
+
+//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
+
+// /mob/living/carbon signals
+#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity))
// /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)
// /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_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot)
-#define COMSIG_ITEM_DROPPED "item_drop"
+#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_HIT_REACT "item_hit_react" //from base of obj/item/hit_reaction(): (list/args)
// /obj/item/clothing signals
#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): ()
-// /obj/machinery signals
-#define COMSIG_MACHINE_PROCESS "machine_process" //from machinery subsystem fire(): ()
-#define COMSIG_MACHINE_PROCESS_ATMOS "machine_process_atmos" //from air subsystem process_atmos_machinery(): ()
+// /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
+
+// /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)
+
// /mob/living/carbon/human signals
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target)
#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)
+// /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)
+
/*******Component Specific Signals*******/
//Janitor
#define COMSIG_TURF_IS_WET "check_turf_wet" //(): Returns bitflags of wet values.
@@ -127,7 +223,24 @@
#define COMSIG_CLEAR_MOOD_EVENT "clear_mood" //Called when you clear a mood event from anywhere in the code.
//NTnet
-#define COMSIG_COMPONENT_NTNET_RECIEVE "ntnet_recieve" //called on an object by its NTNET connection component on recieve. (sending_id(number), sending_netname(text), data(datum/netdata))
+#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_GET_PROGRAMS "nanite_get_programs" //(list/nanite_programs) - makes the input list a copy the nanites' program list
+#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_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_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.
@@ -141,15 +254,22 @@
#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)
+#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
+#define CALTROP_IGNORE_WALKERS 2
\ No newline at end of file
diff --git a/code/_globalvars/lists/typecache.dm b/code/_globalvars/lists/typecache.dm
new file mode 100644
index 00000000000..2600e5c287f
--- /dev/null
+++ b/code/_globalvars/lists/typecache.dm
@@ -0,0 +1,12 @@
+//please store common type caches here.
+//type caches should only be stored here if used in mutiple places or likely to be used in mutiple places.
+
+//Note: typecache can only replace istype if you know for sure the thing is at least a datum.
+
+GLOBAL_LIST_INIT(typecache_mob, typecacheof(/mob))
+
+GLOBAL_LIST_INIT(typecache_living, typecacheof(/mob/living))
+
+GLOBAL_LIST_INIT(typecache_stack, typecacheof(/obj/item/stack))
+
+GLOBAL_LIST_INIT(typecache_machine_or_structure, typecacheof(list(/obj/machinery, /obj/structure)))
\ No newline at end of file
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 78dde4e95f9..9e8b9b9c3a6 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -14,7 +14,9 @@
// No comment
/atom/proc/attackby(obj/item/W, mob/user, params)
- return SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, params)
+ if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, params) & COMPONENT_NO_AFTERATTACK)
+ return TRUE
+ return FALSE
/obj/attackby(obj/item/I, mob/living/user, params)
return ..() || (can_be_hit && I.attack_obj(src, user))
diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm
index 457ea9513ab..9b802291d84 100644
--- a/code/controllers/subsystem/garbage.dm
+++ b/code/controllers/subsystem/garbage.dm
@@ -261,7 +261,7 @@ SUBSYSTEM_DEF(garbage)
if(isnull(D.gc_destroyed))
- if(SEND_SIGNAL(D, COMSIG_PARENT_QDELETED, force)) // Give the components a chance to prevent their parent from being deleted
+ if(SEND_SIGNAL(D, COMSIG_PARENT_PREQDELETED, force)) // Give the components a chance to prevent their parent from being deleted
return
D.gc_destroyed = GC_CURRENTLY_BEING_QDELETED
var/start_time = world.time
diff --git a/code/datums/components/README.md b/code/datums/components/README.md
index 4eecdce18ca..9d06a255dd7 100644
--- a/code/datums/components/README.md
+++ b/code/datums/components/README.md
@@ -26,15 +26,18 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
### Defines
-1. `COMPONENT_INCOMPATIBLE` 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.
-
+1. `COMPONENT_INCOMPATIBLE` 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
### Vars
1. `/datum/var/list/datum_components` (private)
* Lazy associated list of type -> component/list of components.
-1. `/datum/component/var/enabled` (protected, boolean)
- * If the component is enabled. If not, it will not react to signals
+1. `/datum/var/list/comp_lookup` (private)
+ * Lazy associated list of signal -> registree/list of registrees
+1. `/datum/var/list/signal_procs` (private)
+ * Associated lazy list of signals -> `/datum/callback`s that will be run when the parent datum receives that signal
+1. `/datum/var/signal_enabled` (protected, boolean)
+ * If the datum is signal enabled. If not, it will not react to signals
* `FALSE` by default, set to `TRUE` when a signal is registered
1. `/datum/component/var/dupe_mode` (protected, enum)
* How duplicate component types are handled when added to the datum.
@@ -46,11 +49,12 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* Definition of a duplicate component type
* `null` means exact match on `type` (default)
* Any other type means that and all subtypes
-1. `/datum/component/var/list/signal_procs` (private)
- * Associated lazy list of signals -> `/datum/callback`s that will be run when the parent datum recieves that signal
1. `/datum/component/var/datum/parent` (protected, read-only)
* The datum this component belongs to
* Never `null` in child procs
+1. `report_signal_origin` (protected, boolean)
+ * If `TRUE`, will invoke the callback when signalled with the signal type as the first argument.
+ * `FALSE` by default.
### Procs
@@ -77,7 +81,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
1. `/datum/proc/LoadComponent(component_type(type), ...) -> datum/component` (public, final)
* Equivalent to calling `GetComponent(component_type)` where, if the result would be `null`, returns `AddComponent(component_type, ...)` instead
1. `/datum/proc/ComponentActivated(datum/component/C)` (abstract, async)
- * Called on a component's `parent` after a signal recieved causes it to activate. `src` is the parameter
+ * Called on a component's `parent` after a signal received causes it to activate. `src` is the parameter
* Will only be called if a component's callback returns `TRUE`
1. `/datum/proc/TakeComponent(datum/component/C)` (public, final)
* Properly transfers ownership of a component from one datum to another
@@ -86,13 +90,21 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
1. `/datum/proc/_SendSignal(signal, list/arguments)` (private, final)
* Handles most of the actual signaling procedure
* Will runtime if used on datums with an empty component list
+1. `/datum/proc/RegisterSignal(datum/target, signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final)
+ * If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments
+ * Makes the datum listen for the specified `signal` on it's `parent` datum.
+ * When that signal is received `proc_ref` will be called on the component, along with associated arguments
+ * Example proc ref: `.proc/OnEvent`
+ * If a previous registration is overwritten by the call, a runtime occurs. Setting `override` to TRUE prevents this
+ * These callbacks run asyncronously
+ * Returning `TRUE` from these callbacks will trigger a `TRUE` return from the `SendSignal()` that initiated it
1. `/datum/component/New(datum/parent, ...)` (private, final)
* Runs internal setup for the component
* Extra arguments are passed to `Initialize()`
1. `/datum/component/Initialize(...)` (abstract, no-sleep)
* Called by `New()` with the same argments excluding `parent`
* Component does not exist in `parent`'s `datum_components` list yet, although `parent` is set and may be used
- * Signals will not be recieved while this function is running
+ * Signals will not be received while this function is running
* Component may be deleted after this function completes without being attached
* Do not call `qdel(src)` from this function
1. `/datum/component/Destroy(force(bool), silent(bool))` (virtual, no-sleep)
@@ -113,13 +125,11 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* Clears `parent` and removes the component from it's component list
1. `/datum/component/proc/_JoinParent` (private, final)
* Tries to add the component to it's `parent`s `datum_components` list
-1. `/datum/component/proc/RegisterSignal(datum/target, signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final)
- * If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments
- * Makes a component listen for the specified `signal` on it's `parent` datum.
- * When that signal is recieved `proc_ref` will be called on the component, along with associated arguments
- * Example proc ref: `.proc/OnEvent`
- * If a previous registration is overwritten by the call, a runtime occurs. Setting `override` to TRUE prevents this
- * These callbacks run asyncronously
- * Returning `TRUE` from these callbacks will trigger a `TRUE` return from the `_SendSignal()` that initiated it
+1. `/datum/component/proc/RegisterWithParent` (abstract, no-sleep)
+ * Used to register the signals that should be on the `parent` object
+ * Use this if you plan on the component transfering between parents
+1. `/datum/component/proc/UnregisterFromParent` (abstract, no-sleep)
+ * Counterpart to `RegisterWithParent()`
+ * Used to unregister the signals that should only be on the `parent` object
### See/Define signals and their arguments in __DEFINES\components.dm
diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm
index 7621828d970..580d397c225 100644
--- a/code/datums/components/_component.dm
+++ b/code/datums/components/_component.dm
@@ -1,8 +1,6 @@
/datum/component
- var/enabled = FALSE
var/dupe_mode = COMPONENT_DUPE_HIGHLANDER
var/dupe_type
- var/list/signal_procs
var/datum/parent
/datum/component/New(datum/P, ...)
@@ -10,7 +8,7 @@
var/list/arguments = args.Copy(2)
if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE)
qdel(src, TRUE, TRUE)
- CRASH("Incompatible [type] assigned to a [P]!")
+ CRASH("Incompatible [type] assigned to a [P.type]! args: [json_encode(arguments)]")
_JoinParent(P)
@@ -47,19 +45,21 @@
else //only component of this type, no list
dc[I] = src
+ RegisterWithParent()
+
+// If you want/expect to be moving the component around between parents, use this to register on the parent for signals
+/datum/component/proc/RegisterWithParent()
+ return
+
/datum/component/proc/Initialize(...)
return
/datum/component/Destroy(force=FALSE, silent=FALSE)
- enabled = FALSE
- var/datum/P = parent
- if(!force)
+ if(!force && parent)
_RemoveFromParent()
if(!silent)
- SEND_SIGNAL(P, COMSIG_COMPONENT_REMOVING, src)
+ SEND_SIGNAL(parent, COMSIG_COMPONENT_REMOVING, src)
parent = null
- for(var/target in signal_procs)
- UnregisterSignal(target, signal_procs[target])
return ..()
/datum/component/proc/_RemoveFromParent()
@@ -78,7 +78,12 @@
if(!dc.len)
P.datum_components = null
-/datum/component/proc/RegisterSignal(datum/target, sig_type_or_types, proc_or_callback, override = FALSE)
+ UnregisterFromParent()
+
+/datum/component/proc/UnregisterFromParent()
+ return
+
+/datum/proc/RegisterSignal(datum/target, sig_type_or_types, proc_or_callback, override = FALSE)
if(QDELETED(src) || QDELETED(target))
return
@@ -100,6 +105,7 @@
stack_trace("[sig_type] overridden. Use override = TRUE to suppress this warning")
procs[target][sig_type] = proc_or_callback
+
if(!lookup[sig_type]) // Nothing has registered here yet
lookup[sig_type] = src
else if(lookup[sig_type] == src) // We already registered here
@@ -110,8 +116,9 @@
else // Many other things have registered here
lookup[sig_type][src] = TRUE
- enabled = TRUE
-/datum/component/proc/UnregisterSignal(datum/target, sig_type_or_types)
+ signal_enabled = TRUE
+
+/datum/proc/UnregisterSignal(datum/target, sig_type_or_types)
var/list/lookup = target.comp_lookup
if(!signal_procs || !signal_procs[target] || !lookup)
return
@@ -137,24 +144,19 @@
lookup[sig] -= src
signal_procs[target] -= sig_type_or_types
- if(length(signal_procs[target]))
+ if(!signal_procs[target].len)
signal_procs -= target
/datum/component/proc/InheritComponent(datum/component/C, i_am_original)
return
-/datum/component/proc/OnTransfer(datum/new_parent)
+/datum/component/proc/PreTransfer()
+ return
+
+/datum/component/proc/PostTransfer()
return
/datum/component/proc/_GetInverseTypeList(our_type = type)
- #if DM_VERSION >= 513
- #warn 512 is definitely stable now, remove the old code
- #endif
-
- #if DM_VERSION < 512
- //remove this when we use 512 full time
- set invisibility = 101
- #endif
//we can do this one simple trick
var/current_type = parent_type
. = list(our_type, current_type)
@@ -166,15 +168,15 @@
/datum/proc/_SendSignal(sigtype, list/arguments)
var/target = comp_lookup[sigtype]
if(!length(target))
- var/datum/component/C = target
- if(!C.enabled)
+ var/datum/C = target
+ if(!C.signal_enabled)
return NONE
var/datum/callback/CB = C.signal_procs[src][sigtype]
return CB.InvokeAsync(arglist(arguments))
. = NONE
for(var/I in target)
- var/datum/component/C = I
- if(!C.enabled)
+ var/datum/C = I
+ if(!C.signal_enabled)
continue
var/datum/callback/CB = C.signal_procs[src][sigtype]
. |= CB.InvokeAsync(arglist(arguments))
@@ -218,12 +220,9 @@
if(ispath(nt))
if(nt == /datum/component)
CRASH("[nt] attempted instantiation!")
- if(!isnum(dm))
- CRASH("[nt]: Invalid dupe_mode ([dm])!")
- if(dt && !ispath(dt))
- CRASH("[nt]: Invalid dupe_type ([dt])!")
else
new_comp = nt
+ nt = new_comp.type
args[1] = src
@@ -267,21 +266,27 @@
if(!.)
return AddComponent(arglist(args))
-/datum/proc/TakeComponent(datum/component/C)
- if(!C)
+/datum/component/proc/RemoveComponent()
+ if(!parent)
return
- var/datum/helicopter = C.parent
- if(helicopter == src)
- //if we're taking to the same thing no need for anything
+ var/datum/old_parent = parent
+ PreTransfer()
+ _RemoveFromParent()
+ parent = null
+ SEND_SIGNAL(old_parent, COMSIG_COMPONENT_REMOVING, src)
+
+/datum/proc/TakeComponent(datum/component/target)
+ if(!target || target.parent == src)
return
- if(C.OnTransfer(src) == COMPONENT_INCOMPATIBLE)
- qdel(C)
- return
- C._RemoveFromParent()
- SEND_SIGNAL(helicopter, COMSIG_COMPONENT_REMOVING, C)
- C.parent = src
- if(C == AddComponent(C))
- C._JoinParent()
+ if(target.parent)
+ target.RemoveComponent()
+ target.parent = src
+ if(target.PostTransfer() == COMPONENT_INCOMPATIBLE)
+ var/c_type = target.type
+ qdel(target)
+ CRASH("Incompatible [c_type] transfer attempt to a [type]!")
+ if(target == AddComponent(target))
+ target._JoinParent()
/datum/proc/TransferComponents(datum/target)
var/list/dc = datum_components
@@ -295,4 +300,4 @@
target.TakeComponent(comps)
/datum/component/nano_host()
- return parent
+ return parent
\ No newline at end of file
diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm
index 4ae7d08f3ea..92c8c6b108d 100644
--- a/code/datums/components/material_container.dm
+++ b/code/datums/components/material_container.dm
@@ -15,18 +15,25 @@
var/sheet_type
var/list/materials
var/show_on_examine
+ var/disable_attackby
var/list/allowed_typecache
var/last_inserted_id
var/precise_insertion = FALSE
var/datum/callback/precondition
var/datum/callback/after_insert
-/datum/component/material_container/Initialize(list/mat_list, max_amt = 0, _show_on_examine = FALSE, list/allowed_types, datum/callback/_precondition, datum/callback/_after_insert)
+/datum/component/material_container/Initialize(list/mat_list, max_amt = 0, _show_on_examine = FALSE, list/allowed_types, datum/callback/_precondition, datum/callback/_after_insert, _disable_attackby)
materials = list()
max_amount = max(0, max_amt)
show_on_examine = _show_on_examine
+ disable_attackby = _disable_attackby
+
if(allowed_types)
- allowed_typecache = typecacheof(allowed_types)
+ if(ispath(allowed_types) && allowed_types == /obj/item/stack)
+ allowed_typecache = GLOB.typecache_stack
+ else
+ allowed_typecache = typecacheof(allowed_types)
+
precondition = _precondition
after_insert = _after_insert
@@ -43,16 +50,21 @@
materials[id] = new mat_path()
/datum/component/material_container/proc/OnExamine(datum/source, mob/user)
- for(var/I in materials)
- var/datum/material/M = materials[I]
- var/amt = amount(M.id)
- if(amt)
- to_chat(user, "It has [amt] units of [lowertext(M.name)] stored.")
+ if(show_on_examine)
+ for(var/I in materials)
+ var/datum/material/M = materials[I]
+ var/amt = amount(M.id)
+ if(amt)
+ to_chat(user, "It has [amt] units of [lowertext(M.name)] stored.")
/datum/component/material_container/proc/OnAttackBy(datum/source, obj/item/I, mob/living/user)
var/list/tc = allowed_typecache
+ if(disable_attackby)
+ return
if(user.a_intent != INTENT_HELP)
return
+ if(I.flags & ABSTRACT)
+ return
if((I.flags_2 & (HOLOGRAM_2 | NO_MAT_REDEMPTION_2)) || (tc && !is_type_in_typecache(I, tc)))
to_chat(user, "[parent] won't accept [I]!")
return
@@ -88,10 +100,9 @@
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I
to_chat(user, "You insert [inserted] [S.singular_name][inserted>1 ? "s" : ""] into [parent].")
- if(!QDELETED(I))
- if(!user.put_in_hands(I))
- stack_trace("Warning: User could not put object back in hand during material container insertion, line [__LINE__]! This can lead to issues.")
- I.forceMove(user.loc)
+ if(!QDELETED(I) && !user.put_in_hands(I))
+ stack_trace("Warning: User could not put object back in hand during material container insertion, line [__LINE__]! This can lead to issues.")
+ I.forceMove(user.drop_location())
else
to_chat(user, "You insert a material total of [inserted] into [parent].")
qdel(I)
@@ -235,24 +246,25 @@
//For spawning mineral sheets; internal use only
/datum/component/material_container/proc/retrieve(sheet_amt, datum/material/M, target = null)
if(!M.sheet_type)
- return FALSE
- if(sheet_amt > 0)
- if(M.amount < (sheet_amt * MINERAL_MATERIAL_AMOUNT))
- sheet_amt = round(M.amount / MINERAL_MATERIAL_AMOUNT)
- var/count = 0
- while(sheet_amt > MAX_STACK_SIZE)
- new M.sheet_type(get_turf(parent), MAX_STACK_SIZE)
- count += MAX_STACK_SIZE
- use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
- sheet_amt -= MAX_STACK_SIZE
- if(round((sheet_amt * MINERAL_MATERIAL_AMOUNT) / MINERAL_MATERIAL_AMOUNT))
- var/obj/item/stack/sheet/s = new M.sheet_type(get_turf(parent), sheet_amt)
- if(target)
- s.forceMove(target)
- count += sheet_amt
- use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
- return count
- return FALSE
+ return 0
+ if(sheet_amt <= 0)
+ return 0
+
+ if(!target)
+ target = get_turf(parent)
+ if(M.amount < (sheet_amt * MINERAL_MATERIAL_AMOUNT))
+ sheet_amt = round(M.amount / MINERAL_MATERIAL_AMOUNT)
+ var/count = 0
+ while(sheet_amt > MAX_STACK_SIZE)
+ new M.sheet_type(target, MAX_STACK_SIZE)
+ count += MAX_STACK_SIZE
+ use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
+ sheet_amt -= MAX_STACK_SIZE
+ if(sheet_amt >= 1)
+ new M.sheet_type(target, sheet_amt)
+ count += sheet_amt
+ use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
+ return count
/datum/component/material_container/proc/retrieve_sheets(sheet_amt, id, target = null)
if(materials[id])
@@ -386,4 +398,4 @@
/datum/material/plastic
name = "Plastic"
id = MAT_PLASTIC
- sheet_type = /obj/item/stack/sheet/plastic
+ sheet_type = /obj/item/stack/sheet/plastic
\ No newline at end of file
diff --git a/code/datums/datum.dm b/code/datums/datum.dm
index 2db8c0cad89..290f2eda770 100644
--- a/code/datums/datum.dm
+++ b/code/datums/datum.dm
@@ -3,6 +3,8 @@
var/list/active_timers //for SStimer
var/list/datum_components //for /datum/components
var/list/comp_lookup
+ var/list/signal_procs
+ var/signal_enabled = FALSE
var/var_edited = FALSE //Warranty void if seal is broken
var/tmp/unique_datum_id = null
@@ -26,6 +28,9 @@
continue
qdel(timer)
+ //BEGIN: ECS SHIT
+ signal_enabled = FALSE
+
var/list/dc = datum_components
if(dc)
var/all_components = dc[/datum/component]
@@ -51,6 +56,10 @@
comp.UnregisterSignal(src, sig)
comp_lookup = lookup = null
+ for(var/target in signal_procs)
+ UnregisterSignal(target, signal_procs[target])
+ //END: ECS SHIT
+
return QDEL_HINT_QUEUE
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 426ca39edb6..0f1f7123c5b 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -38,7 +38,7 @@
var/list/categories = list("Tools", "Electronics", "Construction", "Communication", "Security", "Machinery", "Medical", "Miscellaneous", "Dinnerware", "Imported")
/obj/machinery/autolathe/New()
- AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS), 0, FALSE, null, null, CALLBACK(src, .proc/AfterMaterialInsert))
+ AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS), 0, TRUE, null, null, CALLBACK(src, .proc/AfterMaterialInsert))
..()
component_parts = list()
component_parts += new /obj/item/circuitboard/autolathe(null)
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index 72c0cd91002..0141d3af493 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -18,7 +18,8 @@ var/const/SAFETY_COOLDOWN = 100
var/item_recycle_sound = 'sound/machines/recycler.ogg'
/obj/machinery/recycler/New()
- AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_URANIUM, MAT_BANANIUM, MAT_TRANQUILLITE, MAT_TITANIUM, MAT_PLASTIC, MAT_BLUESPACE))
+ AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_URANIUM, MAT_BANANIUM, MAT_TRANQUILLITE, MAT_TITANIUM, MAT_PLASTIC, MAT_BLUESPACE), 0,
+ TRUE, null, null, null, TRUE)
..()
component_parts = list()
component_parts += new /obj/item/circuitboard/recycler(null)
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 86640958a72..3db9272cce8 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -39,7 +39,7 @@
/obj/machinery/mecha_part_fabricator/New()
var/datum/component/material_container/materials = AddComponent(/datum/component/material_container,
list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TRANQUILLITE, MAT_TITANIUM, MAT_BLUESPACE), 0,
- FALSE, list(/obj/item/stack, /obj/item/stack/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert))
+ FALSE, /obj/item/stack, CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert))
materials.precise_insertion = TRUE
..()
component_parts = list()
diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm
index 6b62f07c103..c6749528908 100644
--- a/code/modules/mining/equipment_locker.dm
+++ b/code/modules/mining/equipment_locker.dm
@@ -28,7 +28,7 @@
/obj/machinery/mineral/ore_redemption/New()
..()
- AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TRANQUILLITE, MAT_TITANIUM, MAT_BLUESPACE),INFINITY)
+ AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TRANQUILLITE, MAT_TITANIUM, MAT_BLUESPACE), INFINITY, FALSE, /obj/item/stack)
files = new /datum/research/smelter(src)
component_parts = list()
component_parts += new /obj/item/circuitboard/ore_redemption(null)
diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm
index 3fc2980ddc2..860692673a5 100644
--- a/code/modules/mining/machine_processing.dm
+++ b/code/modules/mining/machine_processing.dm
@@ -83,7 +83,7 @@
/obj/machinery/mineral/processing_unit/New()
..()
- AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TRANQUILLITE, MAT_TITANIUM, MAT_BLUESPACE), INFINITY)
+ AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TRANQUILLITE, MAT_TITANIUM, MAT_BLUESPACE), INFINITY, TRUE, /obj/item/stack)
files = new /datum/research/smelter(src)
/obj/machinery/mineral/processing_unit/Destroy()
diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm
index 794f7542252..dd428341959 100644
--- a/code/modules/mining/mint.dm
+++ b/code/modules/mining/mint.dm
@@ -16,7 +16,7 @@
/obj/machinery/mineral/mint/New()
..()
- AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_URANIUM, MAT_DIAMOND, MAT_BANANIUM, MAT_TRANQUILLITE), MINERAL_MATERIAL_AMOUNT * 50)
+ AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_URANIUM, MAT_DIAMOND, MAT_BANANIUM, MAT_TRANQUILLITE), MINERAL_MATERIAL_AMOUNT * 50, FALSE, /obj/item/stack)
/obj/machinery/mineral/mint/process()
var/turf/T = get_step(src, input_dir)
diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm
index 328faf6d645..f6fc35932bc 100644
--- a/code/modules/research/rdmachines.dm
+++ b/code/modules/research/rdmachines.dm
@@ -22,7 +22,7 @@
/obj/machinery/r_n_d/New()
materials = AddComponent(/datum/component/material_container,
list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TRANQUILLITE, MAT_TITANIUM, MAT_BLUESPACE, MAT_PLASTIC), 0,
- FALSE, list(/obj/item/stack, /obj/item/stack/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert))
+ TRUE, /obj/item/stack, CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert))
materials.precise_insertion = TRUE
..()
wires["Red"] = 0
diff --git a/paradise.dme b/paradise.dme
index 499fa3f0b1f..12ee7e0948d 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -108,6 +108,7 @@
#include "code\_globalvars\lists\names.dm"
#include "code\_globalvars\lists\objects.dm"
#include "code\_globalvars\lists\reagents.dm"
+#include "code\_globalvars\lists\typecache.dm"
#include "code\_onclick\adjacent.dm"
#include "code\_onclick\ai.dm"
#include "code\_onclick\click.dm"