diff --git a/code/datums/components/archaeology.dm b/code/datums/components/archaeology.dm
deleted file mode 100644
index b5740650e9f..00000000000
--- a/code/datums/components/archaeology.dm
+++ /dev/null
@@ -1,95 +0,0 @@
-/datum/component/archaeology
- dupe_mode = COMPONENT_DUPE_UNIQUE
- var/list/archdrops = list(/obj/item/bikehorn = list(ARCH_PROB = 100, ARCH_MAXDROP = 1)) // honk~
- var/prob2drop
- var/dug
- var/datum/callback/callback
-
-/datum/component/archaeology/Initialize(list/_archdrops = list(), datum/callback/_callback)
- archdrops = _archdrops
- for(var/i in archdrops)
- if(isnull(archdrops[i][ARCH_MAXDROP]))
- archdrops[i][ARCH_MAXDROP] = 1
- stack_trace("ARCHAEOLOGY WARNING: [parent] contained a null max_drop value in [i].")
- if(isnull(archdrops[i][ARCH_PROB]))
- archdrops[i][ARCH_PROB] = 100
- stack_trace("ARCHAEOLOGY WARNING: [parent] contained a null probability value in [i].")
- callback = _callback
- RegisterSignal(parent, COMSIG_PARENT_ATTACKBY,.proc/Dig)
- RegisterSignal(parent, COMSIG_ATOM_EX_ACT, .proc/BombDig)
- RegisterSignal(parent, COMSIG_ATOM_SING_PULL, .proc/SingDig)
-
-/datum/component/archaeology/InheritComponent(datum/component/archaeology/A, i_am_original)
- var/list/other_archdrops = A.archdrops
- var/list/_archdrops = archdrops
- for(var/I in other_archdrops)
- _archdrops[I] += other_archdrops[I]
-
-/datum/component/archaeology/proc/Dig(datum/source, obj/item/I, mob/living/user)
- if(dug)
- to_chat(user, "Looks like someone has dug here already.")
- return
-
- if(!isturf(user.loc))
- return
-
- if(I.tool_behaviour == TOOL_SHOVEL || I.tool_behaviour == TOOL_MINING)
- to_chat(user, "You start digging...")
-
- if(I.use_tool(parent, user, 40, volume=50))
- to_chat(user, "You dig a hole.")
- gets_dug()
- dug = TRUE
- SSblackbox.record_feedback("tally", "pick_used_mining", 1, I.type)
- return COMPONENT_NO_AFTERATTACK
-
-/datum/component/archaeology/proc/gets_dug()
- if(dug)
- return
- else
- var/turf/open/OT = get_turf(parent)
- for(var/thing in archdrops)
- var/maxtodrop = archdrops[thing][ARCH_MAXDROP]
- for(var/i in 1 to maxtodrop)
- if(prob(archdrops[thing][ARCH_PROB])) // can't win them all!
- new thing(OT)
-
- if(isopenturf(OT))
- if(OT.postdig_icon_change)
- if(istype(OT, /turf/open/floor/plating/asteroid/) && !OT.postdig_icon)
- var/turf/open/floor/plating/asteroid/AOT = parent
- AOT.icon_plating = "[AOT.environment_type]_dug"
- AOT.icon_state = "[AOT.environment_type]_dug"
- else
- if(isplatingturf(OT))
- var/turf/open/floor/plating/POT = parent
- POT.icon_plating = "[POT.postdig_icon]"
- POT.icon_state = "[OT.postdig_icon]"
-
- if(OT.slowdown) //Things like snow slow you down until you dig them.
- OT.slowdown = 0
- dug = TRUE
- if(callback)
- callback.Invoke()
-
-/datum/component/archaeology/proc/SingDig(datum/source, S, current_size)
- switch(current_size)
- if(STAGE_THREE)
- if(prob(30))
- gets_dug()
- if(STAGE_FOUR)
- if(prob(50))
- gets_dug()
- else
- if(current_size >= STAGE_FIVE && prob(70))
- gets_dug()
-
-/datum/component/archaeology/proc/BombDig(datum/source, severity, target)
- switch(severity)
- if(3)
- return
- if(2)
- if(prob(20))
- gets_dug()
- if(1)
- gets_dug()
diff --git a/code/datums/components/art.dm b/code/datums/components/art.dm
deleted file mode 100644
index 125e2c4313d..00000000000
--- a/code/datums/components/art.dm
+++ /dev/null
@@ -1,40 +0,0 @@
-/datum/component/art
- var/impressiveness = 0
-
-/datum/component/art/Initialize(impress)
- impressiveness = impress
- if(isobj(parent))
- RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_obj_examine)
- else
- RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_other_examine)
- if(isstructure(parent))
- RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand)
- if(isitem(parent))
- RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/apply_moodlet)
-
-/datum/component/art/proc/apply_moodlet(mob/M, impress)
- M.visible_message("[M] stops and looks intently at [parent].", \
- "You stop to take in [parent].")
- switch(impress)
- if (0 to BAD_ART)
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad)
- if (BAD_ART to GOOD_ART)
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artok", /datum/mood_event/artok)
- if (GOOD_ART to GREAT_ART)
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgood", /datum/mood_event/artgood)
- if(GREAT_ART to INFINITY)
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat)
-
-
-/datum/component/art/proc/on_other_examine(datum/source, mob/M)
- apply_moodlet(M, impressiveness)
-
-/datum/component/art/proc/on_obj_examine(datum/source, mob/M)
- var/obj/O = parent
- apply_moodlet(M, impressiveness *(O.obj_integrity/O.max_integrity))
-
-/datum/component/art/proc/on_attack_hand(datum/source, mob/M)
- to_chat(M, "You start examining [parent].")
- if(!do_after(M, 20, target = parent))
- return
- on_obj_examine(source, M)
diff --git a/code/datums/components/bane.dm b/code/datums/components/bane.dm
deleted file mode 100644
index aac56d099e5..00000000000
--- a/code/datums/components/bane.dm
+++ /dev/null
@@ -1,45 +0,0 @@
-/datum/component/bane
- dupe_mode = COMPONENT_DUPE_ALLOWED
-
- var/mobtype
- var/speciestype
- var/damage_multiplier
-
-/datum/component/bane/Initialize(mobtype, damage_multiplier=1)
- if(!isitem(parent))
- return COMPONENT_INCOMPATIBLE
-
- if(ispath(mobtype, /mob/living))
- src.mobtype = mobtype
- else if(ispath(mobtype, /datum/species))
- speciestype = mobtype
- else
- return COMPONENT_INCOMPATIBLE
-
- src.damage_multiplier = damage_multiplier
-
-/datum/component/bane/RegisterWithParent()
- if(speciestype)
- RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/speciesCheck)
- else
- RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/mobCheck)
-
-/datum/component/bane/UnregisterFromParent()
- UnregisterSignal(parent, COMSIG_ITEM_AFTERATTACK)
-
-/datum/component/bane/proc/speciesCheck(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
- if(!is_species(target, speciestype))
- return
- activate(source, target, user)
-
-/datum/component/bane/proc/mobCheck(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
- if(!istype(target, mobtype))
- return
- activate(source, target, user)
-
-/datum/component/bane/proc/activate(obj/item/source, mob/living/target, mob/attacker)
- if(attacker.a_intent != INTENT_HARM)
- return
-
- var/extra_damage = max(0, source.force * damage_multiplier)
- target.apply_damage(extra_damage, source.damtype, attacker.zone_selected)
diff --git a/code/datums/components/beetlejuice.dm b/code/datums/components/beetlejuice.dm
deleted file mode 100644
index 8df118565a3..00000000000
--- a/code/datums/components/beetlejuice.dm
+++ /dev/null
@@ -1,60 +0,0 @@
-/datum/component/beetlejuice
- var/keyword
- var/list/first_heard
- var/list/count
- var/max_delay = 3 SECONDS //How fast they need to be said
- var/min_count = 3
- var/cooldown = 30 SECONDS //Delay between teleports
- var/active = TRUE
- var/case_sensitive = FALSE
- var/regex/R
-
-/datum/component/beetlejuice/Initialize()
- if(!ismovable(parent))
- return COMPONENT_INCOMPATIBLE
-
- first_heard = list()
- count = list()
-
- var/atom/movable/O = parent
- keyword = O.name
- if(ismob(O))
- var/mob/M = parent
- keyword = M.real_name
- update_regex()
-
- RegisterSignal(SSdcs, COMSIG_GLOB_LIVING_SAY_SPECIAL, .proc/say_react)
-
-/datum/component/beetlejuice/proc/update_regex()
- R = regex("[REGEX_QUOTE(keyword)]","g[case_sensitive ? "" : "i"]")
-
-/datum/component/beetlejuice/vv_edit_var(var_name, var_value)
- . = ..()
- if (var_name == NAMEOF(src, keyword) || var_name == NAMEOF(src, case_sensitive))
- update_regex()
-
-/datum/component/beetlejuice/proc/say_react(datum/source, mob/speaker,message)
- if(!speaker || !message || !active)
- return
- var/found = R.Find(message)
- if(found)
- var/occurences = 1
- while(R.Find(message))
- occurences++
- R.next = 1
-
- if(!first_heard[speaker] || (first_heard[speaker] + max_delay < world.time))
- first_heard[speaker] = world.time
- count[speaker] = 0
- count[speaker] += occurences
- if(count[speaker] >= min_count)
- first_heard -= speaker
- count -= speaker
- apport(speaker)
-
-
-/datum/component/beetlejuice/proc/apport(atom/target)
- var/atom/movable/AM = parent
- do_teleport(AM,get_turf(target))
- active = FALSE
- addtimer(VARSET_CALLBACK(src, active, TRUE), cooldown)
diff --git a/code/datums/components/butchering.dm b/code/datums/components/butchering.dm
deleted file mode 100644
index 5232a74b8e1..00000000000
--- a/code/datums/components/butchering.dm
+++ /dev/null
@@ -1,94 +0,0 @@
-//This is mostly translated and ready to go here, minus correcting a few things in other areas of the code. I just don't want to refactor meat harvesting at the moment. Maybe later.
-
-/datum/component/butchering
- var/speed = 80 //time in deciseconds taken to butcher something
- var/effectiveness = 100 //percentage effectiveness; numbers above 100 yield extra drops
- var/bonus_modifier = 0 //percentage increase to bonus item chance
- var/butcher_sound = 'sound/weapons/slice.ogg' //sound played when butchering
- var/butchering_enabled = TRUE
- var/can_be_blunt = FALSE
-
-/datum/component/butchering/Initialize(_speed, _effectiveness, _bonus_modifier, _butcher_sound, disabled, _can_be_blunt)
- if(_speed)
- speed = _speed
- if(_effectiveness)
- effectiveness = _effectiveness
- if(_bonus_modifier)
- bonus_modifier = _bonus_modifier
- if(_butcher_sound)
- butcher_sound = _butcher_sound
- if(disabled)
- butchering_enabled = FALSE
- if(_can_be_blunt)
- can_be_blunt = _can_be_blunt
- if(isitem(parent))
- RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/onItemAttack)
-
-/datum/component/butchering/proc/onItemAttack(obj/item/source, mob/living/M, mob/living/user)
- if(user.a_intent == INTENT_HARM && M.stat == DEAD && (M.butcher_results || M.guaranteed_butcher_results)) //can we butcher it?
- if(butchering_enabled && (can_be_blunt || source.sharp))
- INVOKE_ASYNC(src, .proc/startButcher, source, M, user)
- return COMPONENT_ITEM_NO_ATTACK
-
-/datum/component/butchering/proc/startButcher(obj/item/source, mob/living/M, mob/living/user)
- to_chat(user, "You begin to butcher [M]...")
- playsound(M.loc, butcher_sound, 50, TRUE, -1)
- if(do_mob(user, M, speed) && M.Adjacent(source))
- Butcher(user, M)
-
-/datum/component/butchering/proc/Butcher(mob/living/butcher, mob/living/meat)
- var/turf/T = meat.drop_location()
- var/final_effectiveness = effectiveness - meat.butcher_difficulty
- var/bonus_chance = max(0, (final_effectiveness - 100) + bonus_modifier) //so 125 total effectiveness = 25% extra chance
- for(var/V in meat.butcher_results)
- var/obj/bones = V
- var/amount = meat.butcher_results[bones]
- for(var/_i in 1 to amount)
- if(!prob(final_effectiveness))
- if(butcher)
- to_chat(butcher, "You fail to harvest some of the [initial(bones.name)] from [meat].")
- else if(prob(bonus_chance))
- if(butcher)
- to_chat(butcher, "You harvest some extra [initial(bones.name)] from [meat]!")
- for(var/i in 1 to 2)
- new bones (T)
- else
- new bones (T)
- meat.butcher_results.Remove(bones) //in case you want to, say, have it drop its results on gib
- for(var/V in meat.guaranteed_butcher_results)
- var/obj/sinew = V
- var/amount = meat.guaranteed_butcher_results[sinew]
- for(var/i in 1 to amount)
- new sinew (T)
- meat.guaranteed_butcher_results.Remove(sinew)
- if(butcher)
- butcher.visible_message("[butcher] butchers [meat].", \
- "You butcher [meat].")
- ButcherEffects(meat)
- meat.harvest(butcher)
- meat.gib(FALSE, FALSE, TRUE)
-
-/datum/component/butchering/proc/ButcherEffects(mob/living/meat) //extra effects called on butchering, override this via subtypes
- return
-
-/* I believe I want this for disposals eventually? Commenting out for now to silence its errors.
-///Special snowflake component only used for the recycler.
-/datum/component/butchering/recycler
-
-/datum/component/butchering/recycler/Initialize(_speed, _effectiveness, _bonus_modifier, _butcher_sound, disabled, _can_be_blunt)
- if(!istype(parent, /obj/machinery/recycler)) //EWWW
- return COMPONENT_INCOMPATIBLE
- . = ..()
- if(. == COMPONENT_INCOMPATIBLE)
- return
- RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/onCrossed)
-
-/datum/component/butchering/recycler/proc/onCrossed(datum/source, mob/living/L)
- if(!istype(L))
- return
- var/obj/machinery/recycler/eater = parent
- if(eater.safety_mode || (eater.stat & (BROKEN|NOPOWER))) //I'm so sorry.
- return
- if(L.stat == DEAD && (L.butcher_results || L.guaranteed_butcher_results))
- Butcher(parent, L)
-*/
diff --git a/code/datums/components/caltrop.dm b/code/datums/components/caltrop.dm
deleted file mode 100644
index cdf852f82a1..00000000000
--- a/code/datums/components/caltrop.dm
+++ /dev/null
@@ -1,62 +0,0 @@
-/datum/component/caltrop
- var/min_damage
- var/max_damage
- var/probability
- var/flags
-
- var/cooldown = 0
-
-/datum/component/caltrop/Initialize(_min_damage = 0, _max_damage = 0, _probability = 100, _flags = NONE)
- min_damage = _min_damage
- max_damage = max(_min_damage, _max_damage)
- probability = _probability
- flags = _flags
-
- RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED), .proc/Crossed)
-
-/datum/component/caltrop/proc/Crossed(datum/source, atom/movable/AM)
- var/atom/A = parent
- if(!A.has_gravity())
- return
-
- if(!prob(probability))
- return
-
- if(ishuman(AM))
- var/mob/living/carbon/human/H = AM
- if(HAS_TRAIT(H, TRAIT_PIERCEIMMUNE))
- return
-
- if((flags & CALTROP_IGNORE_WALKERS) && H.m_intent == MOVE_INTENT_WALK)
- return
-
- var/picked_def_zone = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
- var/obj/item/bodypart/O = H.get_bodypart(picked_def_zone)
- if(!istype(O))
- return
- if(O.status == BODYPART_ROBOTIC)
- return
-
- var/feetCover = (H.wear_suit && (H.wear_suit.body_cover_flags & FEET)) || (H.w_uniform && (H.w_uniform.body_cover_flags & FEET))
-
- if(!(flags & CALTROP_BYPASS_SHOES) && (H.shoes || feetCover))
- return
-
- if((H.movement_type & MOVEMENT_FLYING) || H.buckled)
- return
-
- var/damage = rand(min_damage, max_damage)
- if(HAS_TRAIT(H, TRAIT_LIGHT_STEP))
- damage *= 0.75
- H.apply_damage(damage, BRUTE, picked_def_zone)
-
- if(cooldown < world.time - 10) //cooldown to avoid message spam.
- if(!H.incapacitated(ignore_restraints = TRUE))
- H.visible_message("[H] steps on [A].", \
- "You step on [A]!")
- else
- H.visible_message("[H] slides on [A]!", \
- "You slide on [A]!")
-
- cooldown = world.time
- H.Paralyze(60)
diff --git a/code/datums/components/chasm.dm b/code/datums/components/chasm.dm
deleted file mode 100644
index 8a8aca2080a..00000000000
--- a/code/datums/components/chasm.dm
+++ /dev/null
@@ -1,143 +0,0 @@
-// Used by /turf/open/chasm and subtypes to implement the "dropping" mechanic
-/datum/component/chasm
- var/turf/target_turf
- var/fall_message = "GAH! Ah... where are you?"
- var/oblivion_message = "You stumble and stare into the abyss before you. It stares back, and you fall into the enveloping dark."
-
- var/static/list/falling_atoms = list() // Atoms currently falling into chasms
- var/static/list/forbidden_types = typecacheof(list(
- /obj/singularity,
- /obj/docking_port,
- /obj/structure/lattice,
- /obj/structure/stone_tile,
- /obj/projectile,
- /obj/effect/projectile,
- /obj/effect/portal,
- /obj/effect/abstract,
- /obj/effect/hotspot,
- /obj/landmark,
- /obj/effect/temp_visual,
- /obj/effect/light_emitter/tendril,
- /obj/effect/collapse,
- /obj/effect/particle_effect/ion_trails,
- /obj/effect/dummy/phased_mob
- ))
-
-/datum/component/chasm/Initialize(turf/target)
- RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Entered)
- target_turf = target
- START_PROCESSING(SSobj, src) // process on create, in case stuff is still there
-
-/datum/component/chasm/proc/Entered(datum/source, atom/movable/AM)
- START_PROCESSING(SSobj, src)
- drop_stuff(AM)
-
-/datum/component/chasm/process(delta_time)
- if (!drop_stuff())
- STOP_PROCESSING(SSobj, src)
-
-/datum/component/chasm/proc/is_safe()
- //if anything matching this typecache is found in the chasm, we don't drop things
- var/static/list/chasm_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile))
-
- var/atom/parent = src.parent
- var/list/found_safeties = typecache_filter_list(parent.contents, chasm_safeties_typecache)
- for(var/obj/structure/stone_tile/S in found_safeties)
- if(S.fallen)
- LAZYREMOVE(found_safeties, S)
- return LAZYLEN(found_safeties)
-
-/datum/component/chasm/proc/drop_stuff(AM)
- . = 0
- if (is_safe())
- return FALSE
-
- var/atom/parent = src.parent
- var/to_check = AM ? list(AM) : parent.contents
- for (var/thing in to_check)
- if (droppable(thing))
- . = 1
- INVOKE_ASYNC(src, .proc/drop, thing)
-
-/datum/component/chasm/proc/droppable(atom/movable/AM)
- // avoid an infinite loop, but allow falling a large distance
- if(falling_atoms[AM] && falling_atoms[AM] > 30)
- return FALSE
- if(!isliving(AM) && !isobj(AM))
- return FALSE
- if(is_type_in_typecache(AM, forbidden_types) || AM.throwing || (AM.movement_type & MOVEMENT_FLOATING))
- return FALSE
- //Flies right over the chasm
- if(ismob(AM))
- var/mob/M = AM
- if(M.buckled) //middle statement to prevent infinite loops just in case!
- var/mob/buckled_to = M.buckled
- if((!ismob(M.buckled) || (buckled_to.buckled != M)) && !droppable(M.buckled))
- return FALSE
- if(M.is_flying())
- return FALSE
- if(ishuman(AM))
- var/mob/living/carbon/human/H = AM
- if(istype(H.belt, /obj/item/wormhole_jaunter))
- var/obj/item/wormhole_jaunter/J = H.belt
- //To freak out any bystanders
- H.visible_message("[H] falls into [parent]!")
- J.chasm_react(H)
- return FALSE
- return TRUE
-
-/datum/component/chasm/proc/drop(atom/movable/AM)
- //Make sure the item is still there after our sleep
- if(!AM || QDELETED(AM))
- return
- falling_atoms[AM] = (falling_atoms[AM] || 0) + 1
- var/turf/T = target_turf
-
- if(T)
- // send to the turf below
- AM.visible_message("[AM] falls into [parent]!", "[fall_message]")
- T.visible_message("[AM] falls from above!")
- AM.forceMove(T)
- if(isliving(AM))
- var/mob/living/L = AM
- L.Paralyze(100)
- L.adjustBruteLoss(30)
- falling_atoms -= AM
-
- else
- // send to oblivion
- AM.visible_message("[AM] falls into [parent]!", "[oblivion_message]")
- if (isliving(AM))
- var/mob/living/L = AM
- L.notransform = TRUE
- L.afflict_stun(20 * 200)
- L.resting = TRUE
-
- var/oldtransform = AM.transform
- var/oldcolor = AM.color
- var/oldalpha = AM.alpha
- animate(AM, transform = matrix() - matrix(), alpha = 0, color = rgb(0, 0, 0), time = 10)
- for(var/i in 1 to 5)
- //Make sure the item is still there after our sleep
- if(!AM || QDELETED(AM))
- return
- AM.pixel_y--
- sleep(2)
-
- //Make sure the item is still there after our sleep
- if(!AM || QDELETED(AM))
- return
-
- if(iscyborg(AM))
- var/mob/living/silicon/robot/S = AM
- qdel(S.mmi)
-
- falling_atoms -= AM
- qdel(AM)
- if(AM && !QDELETED(AM)) //It's indestructible
- var/atom/parent = src.parent
- parent.visible_message("[parent] spits out [AM]!")
- AM.alpha = oldalpha
- AM.color = oldcolor
- AM.transform = oldtransform
- AM.throw_at_old(get_edge_target_turf(parent,pick(GLOB.alldirs)),rand(1, 10),rand(1, 10))
diff --git a/code/datums/components/construction.dm b/code/datums/components/construction.dm
deleted file mode 100644
index 01df44752c9..00000000000
--- a/code/datums/components/construction.dm
+++ /dev/null
@@ -1,157 +0,0 @@
-#define FORWARD 1
-#define BACKWARD -1
-
-#define ITEM_DELETE "delete"
-#define ITEM_MOVE_INSIDE "move_inside"
-
-
-/datum/component/construction
- var/list/steps
- var/result
- var/index = 1
- var/desc
-
-/datum/component/construction/Initialize()
- if(!isatom(parent))
- return COMPONENT_INCOMPATIBLE
-
- RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
- RegisterSignal(parent, COMSIG_PARENT_ATTACKBY,.proc/action)
- update_parent(index)
-
-/datum/component/construction/proc/examine(datum/source, mob/user, list/examine_list)
- if(desc)
- examine_list += desc
-
-/datum/component/construction/proc/on_step()
- if(index > steps.len)
- spawn_result()
- else
- update_parent(index)
-
-/datum/component/construction/proc/action(datum/source, obj/item/I, mob/living/user)
- return check_step(I, user)
-
-/datum/component/construction/proc/update_index(diff)
- index += diff
- on_step()
-
-/datum/component/construction/proc/check_step(obj/item/I, mob/living/user)
- var/diff = is_right_key(I)
- if(diff && custom_action(I, user, diff))
- update_index(diff)
- return TRUE
- return FALSE
-
-/datum/component/construction/proc/is_right_key(obj/item/I) // returns index step
- var/list/L = steps[index]
- if(check_used_item(I, L["key"]))
- return FORWARD //to the first step -> forward
- else if(check_used_item(I, L["back_key"]))
- return BACKWARD //to the last step -> backwards
- return FALSE
-
-/datum/component/construction/proc/check_used_item(obj/item/I, key)
- if(!key)
- return FALSE
-
- if(ispath(key) && istype(I, key))
- return TRUE
-
- else if(I.tool_behaviour == key)
- return TRUE
-
- return FALSE
-
-/datum/component/construction/proc/custom_action(obj/item/I, mob/living/user, diff)
- var/target_index = index + diff
- var/list/current_step = steps[index]
- var/list/target_step
-
- if(target_index > 0 && target_index <= steps.len)
- target_step = steps[target_index]
-
- . = TRUE
-
- if(I.tool_behaviour)
- . = I.use_tool(parent, user, 0, volume=50)
-
- else if(diff == FORWARD)
- switch(current_step["action"])
- if(ITEM_DELETE)
- . = user.transferItemToLoc(I, parent)
- if(.)
- qdel(I)
-
- if(ITEM_MOVE_INSIDE)
- . = user.transferItemToLoc(I, parent)
-
- // Using stacks
- else if(istype(I, /obj/item/stack))
- . = I.use_tool(parent, user, 0, volume=50, amount=current_step["amount"])
-
-
- // Going backwards? Undo the last action. Drop/respawn the items used in last action, if any.
- if(. && diff == BACKWARD && target_step && !target_step["no_refund"])
- var/target_step_key = target_step["key"]
-
- switch(target_step["action"])
- if(ITEM_DELETE)
- new target_step_key(drop_location())
-
- if(ITEM_MOVE_INSIDE)
- var/obj/item/located_item = locate(target_step_key) in parent
- if(located_item)
- located_item.forceMove(drop_location())
-
- else if(ispath(target_step_key, /obj/item/stack))
- new target_step_key(drop_location(), target_step["amount"])
-
-/datum/component/construction/proc/spawn_result()
- // Some constructions result in new components being added.
- if(ispath(result, /datum/component))
- parent.AddComponent(result)
- qdel(src)
-
- else if(ispath(result, /atom))
- new result(drop_location())
- qdel(parent)
-
-/datum/component/construction/proc/update_parent(step_index)
- var/list/step = steps[step_index]
- var/atom/parent_atom = parent
-
- if(step["desc"])
- desc = step["desc"]
-
- if(step["icon_state"])
- parent_atom.icon_state = step["icon_state"]
-
-/datum/component/construction/proc/drop_location()
- var/atom/parent_atom = parent
- return parent_atom.drop_location()
-
-
-
-// Unordered construction.
-// Takes a list of part types, to be added in any order, as steps.
-// Calls spawn_result() when every type has been added.
-/datum/component/construction/unordered/check_step(obj/item/I, mob/living/user)
- for(var/typepath in steps)
- if(istype(I, typepath) && custom_action(I, user, typepath))
- steps -= typepath
- on_step()
- return TRUE
- return FALSE
-
-/datum/component/construction/unordered/on_step()
- if(!steps.len)
- spawn_result()
- else
- update_parent(steps.len)
-
-/datum/component/construction/unordered/update_parent(steps_left)
- return
-
-/datum/component/construction/unordered/custom_action(obj/item/I, mob/living/user, typepath)
- return TRUE
diff --git a/code/datums/components/decal.dm b/code/datums/components/decal.dm
deleted file mode 100644
index ec5465f31c6..00000000000
--- a/code/datums/components/decal.dm
+++ /dev/null
@@ -1,75 +0,0 @@
-/datum/component/decal
- dupe_mode = COMPONENT_DUPE_ALLOWED
- can_transfer = TRUE
- var/cleanable
- var/description
- var/mutable_appearance/pic
-
- var/first_dir // This only stores the dir arg from init
-
-/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description, _alpha=255)
- if(!isatom(parent) || !generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha))
- return COMPONENT_INCOMPATIBLE
- first_dir = _dir
- description = _description
- cleanable = _cleanable
-
- apply()
-
-/datum/component/decal/RegisterWithParent()
- if(first_dir)
- RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, .proc/rotate_react)
- if(cleanable)
- RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
- if(description)
- RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
-
-/datum/component/decal/UnregisterFromParent()
- UnregisterSignal(parent, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE))
-
-/datum/component/decal/Destroy()
- remove()
- return ..()
-
-/datum/component/decal/PreTransfer()
- remove()
-
-/datum/component/decal/PostTransfer()
- remove()
- apply()
-
-/datum/component/decal/proc/generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha)
- if(!_icon || !_icon_state)
- return FALSE
- // It has to be made from an image or dir breaks because of a byond bug
- var/temp_image = image(_icon, null, _icon_state, _layer, _dir)
- pic = new(temp_image)
- pic.color = _color
- pic.alpha = _alpha
- return TRUE
-
-/datum/component/decal/proc/apply(atom/thing)
- var/atom/master = thing || parent
- master.add_overlay(pic, TRUE)
- if(isitem(master))
- addtimer(CALLBACK(master, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
-
-/datum/component/decal/proc/remove(atom/thing)
- var/atom/master = thing || parent
- master.cut_overlay(pic, TRUE)
- if(isitem(master))
- addtimer(CALLBACK(master, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
-
-/datum/component/decal/proc/rotate_react(datum/source, old_dir, new_dir)
- if(old_dir == new_dir)
- return
- remove()
- pic.dir = turn(pic.dir, dir2angle(old_dir) - dir2angle(new_dir))
- apply()
-
-/datum/component/decal/proc/clean_react(datum/source, strength)
- if(strength >= cleanable)
- qdel(src)
-
-/datum/component/decal/proc/examine(datum/source, mob/user, list/examine_list)
- examine_list += description
diff --git a/code/datums/components/decals/blood.dm b/code/datums/components/decals/blood.dm
deleted file mode 100644
index 3114ddb24e9..00000000000
--- a/code/datums/components/decals/blood.dm
+++ /dev/null
@@ -1,39 +0,0 @@
-/datum/component/decal/blood
- dupe_mode = COMPONENT_DUPE_UNIQUE
-
-/datum/component/decal/blood/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_STRENGTH_BLOOD, _color, _layer=ABOVE_OBJ_LAYER)
- if(!isitem(parent))
- return COMPONENT_INCOMPATIBLE
- . = ..()
- RegisterSignal(parent, COMSIG_ATOM_GET_EXAMINE_NAME, .proc/get_examine_name)
-
-/datum/component/decal/blood/generate_appearance(_icon, _icon_state, _dir, _layer, _color)
- var/obj/item/I = parent
- if(!_icon)
- _icon = 'icons/effects/blood.dmi'
- if(!_icon_state)
- _icon_state = "itemblood"
- var/icon = initial(I.icon)
- var/icon_state = initial(I.icon_state)
- if(!icon || !icon_state)
- // It's something which takes on the look of other items, probably
- icon = I.icon
- icon_state = I.icon_state
- var/static/list/blood_splatter_appearances = list()
- //try to find a pre-processed blood-splatter. otherwise, make a new one
- var/index = "[REF(icon)]-[icon_state]"
- pic = blood_splatter_appearances[index]
-
- if(!pic)
- var/icon/blood_splatter_icon = icon(initial(I.icon), initial(I.icon_state), , 1) //we only want to apply blood-splatters to the initial icon_state for each object
- blood_splatter_icon.Blend("#fff", ICON_ADD) //fills the icon_state with white (except where it's transparent)
- blood_splatter_icon.Blend(icon(_icon, _icon_state), ICON_MULTIPLY) //adds blood and the remaining white areas become transparant
- pic = mutable_appearance(blood_splatter_icon, initial(I.icon_state))
- blood_splatter_appearances[index] = pic
- return TRUE
-
-/datum/component/decal/blood/proc/get_examine_name(datum/source, mob/user, list/override)
- var/atom/A = parent
- override[EXAMINE_POSITION_ARTICLE] = A.gender == PLURAL? "some" : "a"
- override[EXAMINE_POSITION_BEFORE] = " blood-stained "
- return COMPONENT_EXNAME_CHANGED
diff --git a/code/datums/components/earprotection.dm b/code/datums/components/earprotection.dm
deleted file mode 100644
index 9256c4310a7..00000000000
--- a/code/datums/components/earprotection.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-/datum/component/wearertargeting/earprotection
- signals = list(COMSIG_CARBON_SOUNDBANG)
- mobtype = /mob/living/carbon
- proctype = .proc/reducebang
-
-/datum/component/wearertargeting/earprotection/Initialize(_valid_slots)
- . = ..()
- valid_slots = _valid_slots
-
-/datum/component/wearertargeting/earprotection/proc/reducebang(datum/source, list/reflist)
- reflist[1]--
diff --git a/code/datums/components/edit_complainer.dm b/code/datums/components/edit_complainer.dm
deleted file mode 100644
index e2cca2eb50c..00000000000
--- a/code/datums/components/edit_complainer.dm
+++ /dev/null
@@ -1,23 +0,0 @@
-// This is just a bit of fun while making an example for global signal
-/datum/component/edit_complainer
- var/list/say_lines
-
-/datum/component/edit_complainer/Initialize(list/text)
- if(!ismovable(parent))
- return COMPONENT_INCOMPATIBLE
-
- var/static/list/default_lines = list(
- "CentCom's profligacy frays another thread.",
- "Another tug at the weave.",
- "Who knows when the stresses will finally shatter the form?",
- "Even now a light shines through the cracks.",
- "CentCom once more twists knowledge beyond its authority.",
- "There is an uncertain air in the mansus.",
- )
- say_lines = text || default_lines
-
- RegisterSignal(SSdcs, COMSIG_GLOB_VAR_EDIT, .proc/var_edit_react)
-
-/datum/component/edit_complainer/proc/var_edit_react(datum/source, list/arguments)
- var/atom/movable/master = parent
- master.say(pick(say_lines))
diff --git a/code/datums/components/empprotection.dm b/code/datums/components/empprotection.dm
deleted file mode 100644
index c85cdf31c72..00000000000
--- a/code/datums/components/empprotection.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-/datum/component/empprotection
- var/flags = NONE
-
-/datum/component/empprotection/Initialize(_flags)
- if(!istype(parent, /atom))
- return COMPONENT_INCOMPATIBLE
- flags = _flags
- RegisterSignal(parent, list(COMSIG_ATOM_EMP_ACT), .proc/getEmpFlags)
-
-/datum/component/empprotection/proc/getEmpFlags(datum/source, severity)
- return flags
diff --git a/code/datums/components/explodable.dm b/code/datums/components/explodable.dm
deleted file mode 100644
index f27fae30237..00000000000
--- a/code/datums/components/explodable.dm
+++ /dev/null
@@ -1,105 +0,0 @@
-///Component specifically for explosion sensetive things, currently only applies to heat based explosions but can later perhaps be used for things that are dangerous to handle carelessly like nitroglycerin.
-/datum/component/explodable
- var/devastation_range = 0
- var/heavy_impact_range = 0
- var/light_impact_range = 2
- var/flash_range = 3
- var/equipped_slot //For items, lets us determine where things should be hit.
-
-/datum/component/explodable/Initialize(devastation_range_override, heavy_impact_range_override, light_impact_range_override, flash_range_override)
- if(!isatom(parent))
- return COMPONENT_INCOMPATIBLE
-
- RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/explodable_attack)
- RegisterSignal(parent, COMSIG_TRY_STORAGE_INSERT, .proc/explodable_insert_item)
- RegisterSignal(parent, COMSIG_ATOM_EX_ACT, .proc/detonate)
- if(ismovable(parent))
- RegisterSignal(parent, COMSIG_MOVABLE_IMPACT, .proc/explodable_impact)
- RegisterSignal(parent, COMSIG_MOVABLE_BUMP, .proc/explodable_bump)
- if(isitem(parent))
- RegisterSignal(parent, list(COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_OBJ, COMSIG_ITEM_HIT_REACT), .proc/explodable_attack)
- RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
- RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
-
-
-
- if(devastation_range_override)
- devastation_range = devastation_range_override
- if(heavy_impact_range_override)
- heavy_impact_range = heavy_impact_range_override
- if(light_impact_range_override)
- light_impact_range = light_impact_range_override
- if(flash_range_override)
- flash_range = flash_range_override
-
-/datum/component/explodable/proc/explodable_insert_item(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE)
- check_if_detonate(I)
-
-/datum/component/explodable/proc/explodable_impact(datum/source, atom/hit_atom, datum/thrownthing/throwingdatum)
- check_if_detonate(hit_atom)
-
-/datum/component/explodable/proc/explodable_bump(datum/source, atom/A)
- check_if_detonate(A)
-
-///Called when you use this object to attack sopmething
-/datum/component/explodable/proc/explodable_attack(datum/source, atom/movable/target, mob/living/user)
- check_if_detonate(target)
-
-///Called when you attack a specific body part of the thing this is equipped on. Useful for exploding pants.
-/datum/component/explodable/proc/explodable_attack_zone(datum/source, damage, damagetype, def_zone)
- if(!def_zone)
- return
- if(damagetype != BURN) //Don't bother if it's not fire.
- return
- if(!is_hitting_zone(def_zone)) //You didn't hit us! ha!
- return
- detonate()
-
-/datum/component/explodable/proc/on_equip(datum/source, mob/equipper, slot)
- RegisterSignal(equipper, COMSIG_MOB_APPLY_DAMAGE, .proc/explodable_attack_zone)
-
-/datum/component/explodable/proc/on_drop(datum/source, mob/user)
- UnregisterSignal(user, COMSIG_MOB_APPLY_DAMAGE)
-
-/// Checks if we're hitting the zone this component is covering
-/datum/component/explodable/proc/is_hitting_zone(def_zone)
- var/obj/item/item = parent
- var/mob/living/L = item.loc //Get whoever is equipping the item currently
-
- if(!istype(L))
- return
-
- var/obj/item/bodypart/bodypart = L.get_bodypart(check_zone(def_zone))
-
- var/list/equipment_items = list()
- if(iscarbon(L))
- var/mob/living/carbon/C = L
- equipment_items += list(C.head, C.wear_mask, C.back, C.gloves, C.shoes, C.glasses, C.ears)
- if(ishuman(C))
- var/mob/living/carbon/human/H = C
- equipment_items += list(H.wear_suit, H.w_uniform, H.belt, H.s_store, H.wear_id)
-
- for(var/bp in equipment_items)
- if(!bp)
- continue
-
- var/obj/item/I = bp
- if(I.body_cover_flags & bodypart.body_part_flags)
- return TRUE
- return FALSE
-
-
-/datum/component/explodable/proc/check_if_detonate(target)
- if(!isitem(target))
- return
- var/obj/item/I = target
- if(!I.is_hot())
- return
- detonate() //If we're touching a hot item we go boom
-
-
-/// Expldoe and remove the object
-/datum/component/explodable/proc/detonate()
- var/atom/A = parent
- explosion(A, devastation_range, heavy_impact_range, light_impact_range, flash_range) //epic explosion time
- qdel(A)
diff --git a/code/datums/components/fantasy/affix.dm b/code/datums/components/fantasy/affix.dm
deleted file mode 100644
index ad1f44ce4d8..00000000000
--- a/code/datums/components/fantasy/affix.dm
+++ /dev/null
@@ -1,13 +0,0 @@
-/datum/fantasy_affix
- var/placement // A bitflag of "slots" this affix takes up, for example pre/suffix
- var/alignment
- var/weight = 10
-
-// For those occasional affixes which only make sense in certain circumstances
-/datum/fantasy_affix/proc/validate(datum/component/fantasy/comp)
- return TRUE
-
-/datum/fantasy_affix/proc/apply(datum/component/fantasy/comp, newName)
- return newName
-
-/datum/fantasy_affix/proc/remove(datum/component/fantasy/comp)
diff --git a/code/datums/components/fantasy/prefixes.dm b/code/datums/components/fantasy/prefixes.dm
deleted file mode 100644
index 7445ab582bf..00000000000
--- a/code/datums/components/fantasy/prefixes.dm
+++ /dev/null
@@ -1,68 +0,0 @@
-/datum/fantasy_affix/cosmetic_prefixes
- placement = AFFIX_PREFIX
- alignment = AFFIX_GOOD | AFFIX_EVIL
-
- var/list/goodPrefixes
- var/list/badPrefixes
-
-/datum/fantasy_affix/cosmetic_prefixes/New()
- goodPrefixes = list(
- "greater",
- "major",
- "blessed",
- "superior",
- "empowered",
- "honed",
- "true",
- "glorious",
- "robust",
- )
- badPrefixes = list(
- "lesser",
- "minor",
- "blighted",
- "inferior",
- "enfeebled",
- "rusted",
- "unsteady",
- "tragic",
- "gimped",
- "cursed",
- )
-
- weight = (length(goodPrefixes) + length(badPrefixes)) * 10
-
-/datum/fantasy_affix/cosmetic_prefixes/apply(datum/component/fantasy/comp, newName)
- if(comp.quality > 0 || (comp.quality == 0 && prob(50)))
- return "[pick(goodPrefixes)] [newName]"
- else
- return "[pick(badPrefixes)] [newName]"
-
-/datum/fantasy_affix/tactical
- placement = AFFIX_PREFIX
- alignment = AFFIX_GOOD
- weight = 1 // Very powerful, no one should have such power
-
-/datum/fantasy_affix/tactical/apply(datum/component/fantasy/comp, newName)
- var/obj/item/master = comp.parent
- comp.appliedComponents += master.AddComponent(/datum/component/tactical)
- return "tactical [newName]"
-
-/datum/fantasy_affix/pyromantic
- placement = AFFIX_PREFIX
- alignment = AFFIX_GOOD
-
-/datum/fantasy_affix/pyromantic/apply(datum/component/fantasy/comp, newName)
- var/obj/item/master = comp.parent
- comp.appliedComponents += master.AddComponent(/datum/component/igniter, clamp(comp.quality, 1, 10))
- return "pyromantic [newName]"
-
-/datum/fantasy_affix/vampiric
- placement = AFFIX_PREFIX
- alignment = AFFIX_GOOD
- weight = 5
-
-/datum/fantasy_affix/vampiric/apply(datum/component/fantasy/comp, newName)
- var/obj/item/master = comp.parent
- comp.appliedComponents += master.AddComponent(/datum/component/lifesteal, comp.quality)
- return "vampiric [newName]"
diff --git a/code/datums/components/fantasy/suffixes.dm b/code/datums/components/fantasy/suffixes.dm
deleted file mode 100644
index 0dd37edb6f4..00000000000
--- a/code/datums/components/fantasy/suffixes.dm
+++ /dev/null
@@ -1,169 +0,0 @@
-/datum/fantasy_affix/cosmetic_suffixes
- placement = AFFIX_SUFFIX
- alignment = AFFIX_GOOD | AFFIX_EVIL
-
- var/list/goodSuffixes
- var/list/badSuffixes
-
-/datum/fantasy_affix/cosmetic_suffixes/New()
- goodSuffixes = list(
- "dexterity",
- "constitution",
- "intelligence",
- "wisdom",
- "charisma",
- "the forest",
- "the hills",
- "the plains",
- "the sea",
- "the sun",
- "the moon",
- "the void",
- "the world",
- "many secrets",
- "many tales",
- "many colors",
- "rending",
- "sundering",
- "the night",
- "the day",
- )
- badSuffixes = list(
- "draining",
- "burden",
- "discomfort",
- "awkwardness",
- "poor hygiene",
- "timidity",
- )
-
- weight = (length(goodSuffixes) + length(badSuffixes)) * 10
-
-/datum/fantasy_affix/cosmetic_suffixes/apply(datum/component/fantasy/comp, newName)
- if(comp.quality > 0 || (comp.quality == 0 && prob(50)))
- return "[newName] of [pick(goodSuffixes)]"
- else
- return "[newName] of [pick(badSuffixes)]"
-
-//////////// Good suffixes
-/datum/fantasy_affix/bane
- placement = AFFIX_SUFFIX
- alignment = AFFIX_GOOD
-
-/datum/fantasy_affix/bane/apply(datum/component/fantasy/comp, newName)
- . = ..()
- // This is set up to be easy to add to these lists as I expect it will need modifications
- var/static/list/possible_mobtypes
- if(!possible_mobtypes)
- // The base list of allowed mob/species types
- possible_mobtypes = typecacheof(list(
- /mob/living/simple_animal,
- /mob/living/carbon,
- /datum/species,
- ))
- // Some particular types to disallow if they're too broad/abstract
- possible_mobtypes -= list(
- /mob/living/simple_animal/hostile,
- )
- // Some types to remove them and their subtypes
- possible_mobtypes -= typecacheof(list(
- /mob/living/carbon/human/species,
- ))
-
- var/mob/picked_mobtype = pick(possible_mobtypes)
- // This works even with the species picks since we're only accessing the name
-
- var/obj/item/master = comp.parent
- comp.appliedComponents += master.AddComponent(/datum/component/bane, picked_mobtype)
- return "[newName] of [initial(picked_mobtype.name)] slaying"
-
-/datum/fantasy_affix/summoning
- placement = AFFIX_SUFFIX
- alignment = AFFIX_GOOD
- weight = 5
-
-/datum/fantasy_affix/summoning/apply(datum/component/fantasy/comp, newName)
- . = ..()
- // This is set up to be easy to add to these lists as I expect it will need modifications
- var/static/list/possible_mobtypes
- if(!possible_mobtypes)
- // The base list of allowed mob/species types
- possible_mobtypes = typecacheof(list(
- /mob/living/simple_animal,
- /mob/living/carbon,
- /datum/species,
- ))
- // Some particular types to disallow if they're too broad/abstract
- possible_mobtypes -= list(
- /mob/living/simple_animal/hostile,
- )
- // Some types to remove them and their subtypes
- possible_mobtypes -= typecacheof(list(
- /mob/living/carbon/human/species,
- /mob/living/simple_animal/hostile/megafauna,
- ))
-
- var/mob/picked_mobtype = pick(possible_mobtypes)
- // This works even with the species picks since we're only accessing the name
-
- var/obj/item/master = comp.parent
- var/max_mobs = max(CEILING(comp.quality/2, 1), 1)
- var/spawn_delay = 300 - 30 * comp.quality
- comp.appliedComponents += master.AddComponent(/datum/component/summoning, list(picked_mobtype), 100, max_mobs, spawn_delay)
- return "[newName] of [initial(picked_mobtype.name)] summoning"
-
-/datum/fantasy_affix/shrapnel
- placement = AFFIX_SUFFIX
- alignment = AFFIX_GOOD
-
-/datum/fantasy_affix/shrapnel/validate(datum/component/fantasy/comp)
- if(isgun(comp.parent))
- return TRUE
- return FALSE
-
-/datum/fantasy_affix/shrapnel/apply(datum/component/fantasy/comp, newName)
- . = ..()
- // higher means more likely
- var/list/weighted_projectile_types = list(/obj/projectile/meteor = 1,
- /obj/projectile/energy/nuclear_particle = 1,
- /obj/projectile/beam/pulse = 1,
- /obj/projectile/bullet/honker = 15,
- /obj/projectile/temp = 15,
- /obj/projectile/ion = 15,
- /obj/projectile/magic/door = 15,
- /obj/projectile/magic/locker = 15,
- /obj/projectile/magic/fetch = 15,
- /obj/projectile/beam/emitter = 15,
- /obj/projectile/magic/flying = 15,
- /obj/projectile/energy/net = 15,
- /obj/projectile/bullet/incendiary/c9mm = 15,
- /obj/projectile/temp/hot = 15,
- /obj/projectile/beam/disabler = 15)
-
- var/obj/projectile/picked_projectiletype = pickweight(weighted_projectile_types)
-
- var/obj/item/master = comp.parent
- comp.appliedComponents += master.AddComponent(/datum/component/shrapnel, picked_projectiletype)
- return "[newName] of [initial(picked_projectiletype.name)] shrapnel"
-
-/datum/fantasy_affix/strength
- placement = AFFIX_SUFFIX
- alignment = AFFIX_GOOD
-
-/datum/fantasy_affix/strength/apply(datum/component/fantasy/comp, newName)
- . = ..()
- var/obj/item/master = comp.parent
- comp.appliedComponents += master.AddComponent(/datum/component/knockback, CEILING(comp.quality/2, 1), FLOOR(comp.quality/10, 1))
- return "[newName] of strength"
-
-//////////// Bad suffixes
-
-/datum/fantasy_affix/fool
- placement = AFFIX_SUFFIX
- alignment = AFFIX_EVIL
-
-/datum/fantasy_affix/fool/apply(datum/component/fantasy/comp, newName)
- . = ..()
- var/obj/item/master = comp.parent
- comp.appliedComponents += master.AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50)
- return "[newName] of the fool"
diff --git a/code/datums/components/forced_gravity.dm b/code/datums/components/forced_gravity.dm
deleted file mode 100644
index fe9cfc861b3..00000000000
--- a/code/datums/components/forced_gravity.dm
+++ /dev/null
@@ -1,20 +0,0 @@
-/datum/component/forced_gravity
- var/gravity
- var/ignore_space = FALSE //If forced gravity should also work on space turfs
-
-/datum/component/forced_gravity/Initialize(forced_value = 1)
- if(!isatom(parent))
- return COMPONENT_INCOMPATIBLE
- RegisterSignal(parent, COMSIG_ATOM_HAS_GRAVITY, .proc/gravity_check)
- if(isturf(parent))
- RegisterSignal(parent, COMSIG_TURF_HAS_GRAVITY, .proc/turf_gravity_check)
-
- gravity = forced_value
-
-/datum/component/forced_gravity/proc/gravity_check(datum/source, turf/location, list/gravs)
- if(!ignore_space && isspaceturf(location))
- return
- gravs += gravity
-
-/datum/component/forced_gravity/proc/turf_gravity_check(datum/source, atom/checker, list/gravs)
- return gravity_check(null, parent, gravs)
diff --git a/code/datums/components/forensics.dm b/code/datums/components/forensics.dm
deleted file mode 100644
index ff8d4e3ddfc..00000000000
--- a/code/datums/components/forensics.dm
+++ /dev/null
@@ -1,184 +0,0 @@
-/datum/component/forensics
- dupe_mode = COMPONENT_DUPE_UNIQUE
- can_transfer = TRUE
- var/list/fingerprints //assoc print = print
- var/list/hiddenprints //assoc ckey = realname/gloves/ckey
- var/list/blood_DNA //assoc dna = bloodtype
- var/list/fibers //assoc print = print
-
-/datum/component/forensics/InheritComponent(datum/component/forensics/F, original) //Use of | and |= being different here is INTENTIONAL.
- fingerprints = fingerprints | F.fingerprints
- hiddenprints = hiddenprints | F.hiddenprints
- blood_DNA = blood_DNA | F.blood_DNA
- fibers = fibers | F.fibers
- check_blood()
- return ..()
-
-/datum/component/forensics/Initialize(new_fingerprints, new_hiddenprints, new_blood_DNA, new_fibers)
- if(!isatom(parent))
- return COMPONENT_INCOMPATIBLE
- fingerprints = new_fingerprints
- hiddenprints = new_hiddenprints
- blood_DNA = new_blood_DNA
- fibers = new_fibers
- check_blood()
-
-/datum/component/forensics/RegisterWithParent()
- check_blood()
- RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_act)
-
-/datum/component/forensics/UnregisterFromParent()
- UnregisterSignal(parent, list(COMSIG_COMPONENT_CLEAN_ACT))
-
-/datum/component/forensics/PostTransfer()
- if(!isatom(parent))
- return COMPONENT_INCOMPATIBLE
-
-/datum/component/forensics/proc/wipe_fingerprints()
- fingerprints = null
- return TRUE
-
-/datum/component/forensics/proc/wipe_hiddenprints()
- return //no.
-
-/datum/component/forensics/proc/wipe_blood_DNA()
- blood_DNA = null
- if(isitem(parent))
- qdel(parent.GetComponent(/datum/component/decal/blood))
- return TRUE
-
-/datum/component/forensics/proc/wipe_fibers()
- fibers = null
- return TRUE
-
-/datum/component/forensics/proc/clean_act(datum/source, strength)
- if(strength >= CLEAN_STRENGTH_FINGERPRINTS)
- wipe_fingerprints()
- if(strength >= CLEAN_STRENGTH_BLOOD)
- wipe_blood_DNA()
- if(strength >= CLEAN_STRENGTH_FIBERS)
- wipe_fibers()
-
-/datum/component/forensics/proc/add_fingerprint_list(list/_fingerprints) //list(text)
- if(!length(_fingerprints))
- return
- LAZYINITLIST(fingerprints)
- for(var/i in _fingerprints) //We use an associative list, make sure we don't just merge a non-associative list into ours.
- fingerprints[i] = i
- return TRUE
-
-/datum/component/forensics/proc/add_fingerprint(mob/living/M, ignoregloves = FALSE)
- if(!isliving(M))
- if(!iscameramob(M))
- return
- if(isaicamera(M))
- var/mob/camera/aiEye/ai_camera = M
- if(!ai_camera.ai)
- return
- M = ai_camera.ai
- add_hiddenprint(M)
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- add_fibers(H)
- if(H.gloves) //Check if the gloves (if any) hide fingerprints
- var/obj/item/clothing/gloves/G = H.gloves
- if(G.transfer_prints)
- ignoregloves = TRUE
- if(!ignoregloves)
- H.gloves.add_fingerprint(H, TRUE) //ignoregloves = 1 to avoid infinite loop.
- return
- var/full_print = md5(H.dna.uni_identity)
- LAZYSET(fingerprints, full_print, full_print)
- return TRUE
-
-/datum/component/forensics/proc/add_fiber_list(list/_fibertext) //list(text)
- if(!length(_fibertext))
- return
- LAZYINITLIST(fibers)
- for(var/i in _fibertext) //We use an associative list, make sure we don't just merge a non-associative list into ours.
- fibers[i] = i
- return TRUE
-
-/datum/component/forensics/proc/add_fibers(mob/living/carbon/human/M)
- var/fibertext
- var/item_multiplier = isitem(src)?1.2:1
- if(M.wear_suit)
- fibertext = "Material from \a [M.wear_suit]."
- if(prob(10*item_multiplier) && !LAZYACCESS(fibers, fibertext))
- LAZYSET(fibers, fibertext, fibertext)
- if(!(M.wear_suit.body_cover_flags & CHEST))
- if(M.w_uniform)
- fibertext = "Fibers from \a [M.w_uniform]."
- if(prob(12*item_multiplier) && !LAZYACCESS(fibers, fibertext)) //Wearing a suit means less of the uniform exposed.
- LAZYSET(fibers, fibertext, fibertext)
- if(!(M.wear_suit.body_cover_flags & HANDS))
- if(M.gloves)
- fibertext = "Material from a pair of [M.gloves.name]."
- if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext))
- LAZYSET(fibers, fibertext, fibertext)
- else if(M.w_uniform)
- fibertext = "Fibers from \a [M.w_uniform]."
- if(prob(15*item_multiplier) && !LAZYACCESS(fibers, fibertext))
- // "Added fibertext: [fibertext]"
- LAZYSET(fibers, fibertext, fibertext)
- if(M.gloves)
- fibertext = "Material from a pair of [M.gloves.name]."
- if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext))
- LAZYSET(fibers, fibertext, fibertext)
- else if(M.gloves)
- fibertext = "Material from a pair of [M.gloves.name]."
- if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext))
- LAZYSET(fibers, fibertext, fibertext)
- return TRUE
-
-/datum/component/forensics/proc/add_hiddenprint_list(list/_hiddenprints) //list(ckey = text)
- if(!length(_hiddenprints))
- return
- LAZYINITLIST(hiddenprints)
- for(var/i in _hiddenprints) //We use an associative list, make sure we don't just merge a non-associative list into ours.
- hiddenprints[i] = _hiddenprints[i]
- return TRUE
-
-/datum/component/forensics/proc/add_hiddenprint(mob/M)
- if(!isliving(M))
- if(!iscameramob(M))
- return
- if(isaicamera(M))
- var/mob/camera/aiEye/ai_camera = M
- if(!ai_camera.ai)
- return
- M = ai_camera.ai
- if(!M.key)
- return
- var/hasgloves = ""
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(H.gloves)
- hasgloves = "(gloves)"
- var/current_time = time_stamp()
- if(!LAZYACCESS(hiddenprints, M.key))
- LAZYSET(hiddenprints, M.key, "First: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]")
- else
- var/laststamppos = findtext(LAZYACCESS(hiddenprints, M.key), " Last: ")
- if(laststamppos)
- LAZYSET(hiddenprints, M.key, copytext(hiddenprints[M.key], 1, laststamppos))
- hiddenprints[M.key] += " Last: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]" //made sure to be existing by if(!LAZYACCESS);else
- var/atom/A = parent
- A.fingerprintslast = M.ckey
- return TRUE
-
-/datum/component/forensics/proc/add_blood_DNA(list/dna) //list(dna_enzymes = type)
- if(!length(dna))
- return
- LAZYINITLIST(blood_DNA)
- for(var/i in dna)
- blood_DNA[i] = dna[i]
- check_blood()
- return TRUE
-
-/datum/component/forensics/proc/check_blood()
- if(!isitem(parent))
- return
- if(!length(blood_DNA))
- return
- parent.LoadComponent(/datum/component/decal/blood)
diff --git a/code/datums/components/heirloom.dm b/code/datums/components/heirloom.dm
deleted file mode 100644
index 72b28b125dd..00000000000
--- a/code/datums/components/heirloom.dm
+++ /dev/null
@@ -1,22 +0,0 @@
-/datum/component/heirloom
- var/datum/mind/owner
- var/family_name
-
-/datum/component/heirloom/Initialize(new_owner, new_family_name)
- if(!isitem(parent))
- return COMPONENT_INCOMPATIBLE
-
- owner = new_owner
- family_name = new_family_name
-
- RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
-
-/datum/component/heirloom/proc/examine(datum/source, mob/user, list/examine_list)
- if(user.mind == owner)
- examine_list += "It is your precious [family_name] family heirloom. Keep it safe!"
- else if(isobserver(user))
- examine_list += "It is the [family_name] family heirloom, belonging to [owner]."
- else
- var/datum/antagonist/obsessed/creeper = user.mind.has_antag_datum(/datum/antagonist/obsessed)
- if(creeper && creeper.trauma.obsession == owner)
- examine_list += "This must be [owner]'s family heirloom! It smells just like them..."
diff --git a/code/datums/components/igniter.dm b/code/datums/components/igniter.dm
deleted file mode 100644
index a254a7729bf..00000000000
--- a/code/datums/components/igniter.dm
+++ /dev/null
@@ -1,36 +0,0 @@
-/datum/component/igniter
- var/fire_stacks
-
-/datum/component/igniter/Initialize(fire_stacks=1)
- if(!isitem(parent) && !ishostile(parent) && !isgun(parent) && !ismachinery(parent) && !isstructure(parent))
- return COMPONENT_INCOMPATIBLE
-
- src.fire_stacks = fire_stacks
-
-/datum/component/igniter/RegisterWithParent()
- if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc
- RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit)
- else if(isitem(parent))
- RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/item_afterattack)
- else if(ishostile(parent))
- RegisterSignal(parent, COMSIG_HOSTILE_ATTACKINGTARGET, .proc/hostile_attackingtarget)
-
-/datum/component/igniter/UnregisterFromParent()
- UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT))
-
-/datum/component/igniter/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
- if(!(clickchain_flags & CLICKCHAIN_HAS_PROXIMITY))
- return
- do_igniter(target)
-
-/datum/component/igniter/proc/hostile_attackingtarget(mob/living/simple_animal/hostile/attacker, atom/target)
- do_igniter(target)
-
-/datum/component/igniter/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle)
- do_igniter(target)
-
-/datum/component/igniter/proc/do_igniter(atom/target)
- if(isliving(target))
- var/mob/living/L = target
- L.adjust_fire_stacks(fire_stacks)
- L.IgniteMob()
diff --git a/code/datums/components/infective.dm b/code/datums/components/infective.dm
deleted file mode 100644
index 314e381bfe6..00000000000
--- a/code/datums/components/infective.dm
+++ /dev/null
@@ -1,88 +0,0 @@
-/datum/component/infective
- dupe_mode = COMPONENT_DUPE_ALLOWED
- var/list/datum/disease/diseases //make sure these are the static, non-processing versions!
- var/expire_time
- var/min_clean_strength = CLEAN_WEAK
-
-/datum/component/infective/Initialize(list/datum/disease/_diseases, expire_in)
- if(islist(_diseases))
- diseases = _diseases
- else
- diseases = list(_diseases)
- if(expire_in)
- expire_time = world.time + expire_in
- QDEL_IN(src, expire_in)
-
- if(!ismovable(parent))
- return COMPONENT_INCOMPATIBLE
- RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean)
- RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, .proc/try_infect_buckle)
- RegisterSignal(parent, COMSIG_MOVABLE_BUMP, .proc/try_infect_collide)
- RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/try_infect_crossed)
- RegisterSignal(parent, COMSIG_MOVABLE_IMPACT_ZONE, .proc/try_infect_impact_zone)
- if(isitem(parent))
- RegisterSignal(parent, COMSIG_ITEM_ATTACK_ZONE, .proc/try_infect_attack_zone)
- RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/try_infect_attack)
- RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/try_infect_equipped)
- if(istype(parent, /obj/item/reagent_containers/food/snacks))
- RegisterSignal(parent, COMSIG_FOOD_EATEN, .proc/try_infect_eat)
- else if(istype(parent, /obj/effect/debris/cleanable/blood/gibs))
- RegisterSignal(parent, COMSIG_GIBS_STREAK, .proc/try_infect_streak)
-
-/datum/component/infective/proc/try_infect_eat(datum/source, mob/living/eater, mob/living/feeder)
- for(var/V in diseases)
- eater.ForceContractDisease(V)
- try_infect(feeder, BODY_ZONE_L_ARM)
-
-/datum/component/infective/proc/clean(datum/source, clean_strength)
- if(clean_strength >= min_clean_strength)
- qdel(src)
-
-/datum/component/infective/proc/try_infect_buckle(datum/source, mob/M, force)
- if(isliving(M))
- try_infect(M)
-
-/datum/component/infective/proc/try_infect_collide(datum/source, atom/A)
- var/atom/movable/P = parent
- if(P.throwing)
- //this will be handled by try_infect_impact_zone()
- return
- if(isliving(A))
- try_infect(A)
-
-/datum/component/infective/proc/try_infect_impact_zone(datum/source, mob/living/target, hit_zone)
- try_infect(target, hit_zone)
-
-/datum/component/infective/proc/try_infect_attack_zone(datum/source, mob/living/carbon/target, mob/living/user, hit_zone)
- try_infect(user, BODY_ZONE_L_ARM)
- try_infect(target, hit_zone)
-
-/datum/component/infective/proc/try_infect_attack(datum/source, mob/living/target, mob/living/user)
- if(!iscarbon(target)) //this case will be handled by try_infect_attack_zone
- try_infect(target)
- try_infect(user, BODY_ZONE_L_ARM)
-
-/datum/component/infective/proc/try_infect_equipped(datum/source, mob/living/L, slot)
- var/old_permeability
- if(isitem(parent))
- //if you are putting an infective item on, it obviously will not protect you, so set its permeability high enough that it will never block ContactContractDisease()
- var/obj/item/I = parent
- old_permeability = I.permeability_coefficient
- I.permeability_coefficient = 1.01
-
- try_infect(L, slot2body_zone(slot))
-
- if(isitem(parent))
- var/obj/item/I = parent
- I.permeability_coefficient = old_permeability
-
-/datum/component/infective/proc/try_infect_crossed(datum/source, atom/movable/M)
- if(isliving(M))
- try_infect(M, BODY_ZONE_PRECISE_L_FOOT)
-
-/datum/component/infective/proc/try_infect_streak(datum/source, list/directions, list/output_diseases)
- output_diseases |= diseases
-
-/datum/component/infective/proc/try_infect(mob/living/L, target_zone)
- for(var/V in diseases)
- L.ContactContractDisease(V, target_zone)
diff --git a/code/datums/components/knockback.dm b/code/datums/components/knockback.dm
deleted file mode 100644
index 7d5d5fe23ea..00000000000
--- a/code/datums/components/knockback.dm
+++ /dev/null
@@ -1,44 +0,0 @@
-/datum/component/knockback
- var/throw_distance
- var/throw_anchored
-
-/datum/component/knockback/Initialize(throw_distance=1, throw_anchored=FALSE)
- if(!isitem(parent) && !ishostile(parent) && !isgun(parent) && !ismachinery(parent) && !isstructure(parent))
- return COMPONENT_INCOMPATIBLE
-
- src.throw_distance = throw_distance
- src.throw_anchored = throw_anchored
-
-/datum/component/knockback/RegisterWithParent()
- if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc
- RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit)
- else if(isitem(parent))
- RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/item_afterattack)
- else if(ishostile(parent))
- RegisterSignal(parent, COMSIG_HOSTILE_ATTACKINGTARGET, .proc/hostile_attackingtarget)
-
-/datum/component/knockback/UnregisterFromParent()
- UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT))
-
-/datum/component/knockback/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
- if(!(clickchain_flags & CLICKCHAIN_HAS_PROXIMITY))
- return
- do_knockback(target, user, get_dir(source, target))
-
-/datum/component/knockback/proc/hostile_attackingtarget(mob/living/simple_animal/hostile/attacker, atom/target)
- do_knockback(target, attacker, get_dir(attacker, target))
-
-/datum/component/knockback/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle)
- do_knockback(target, null, angle2dir(Angle))
-
-/datum/component/knockback/proc/do_knockback(atom/target, mob/thrower, throw_dir)
- if(!ismovable(target) || throw_dir == null)
- return
- var/atom/movable/throwee = target
- if(throwee.anchored && !throw_anchored)
- return
- if(throw_distance < 0)
- throw_dir = turn(throw_dir, 180)
- throw_distance *= -1
- var/atom/throw_target = get_edge_target_turf(throwee, throw_dir)
- throwee.safe_throw_at(throw_target, throw_distance, 1, thrower)
diff --git a/code/datums/components/knockoff.dm b/code/datums/components/knockoff.dm
deleted file mode 100644
index 7d399c7d26d..00000000000
--- a/code/datums/components/knockoff.dm
+++ /dev/null
@@ -1,44 +0,0 @@
-//Items with these will have a chance to get knocked off when disarming
-/datum/component/knockoff
- var/knockoff_chance = 100 //Chance to knockoff
- var/list/target_zones //Aiming for these zones will cause the knockoff, null means all zones allowed
- var/list/slots_knockoffable //Can be only knocked off from these slots, null means all slots allowed
-
-/datum/component/knockoff/Initialize(knockoff_chance,zone_override,slots_knockoffable)
- if(!isitem(parent))
- return COMPONENT_INCOMPATIBLE
- RegisterSignal(parent, COMSIG_ITEM_EQUIPPED,.proc/OnEquipped)
- RegisterSignal(parent, COMSIG_ITEM_DROPPED,.proc/OnDropped)
-
- src.knockoff_chance = knockoff_chance
-
- if(zone_override)
- target_zones = zone_override
-
- if(slots_knockoffable)
- src.slots_knockoffable = slots_knockoffable
-
-/datum/component/knockoff/proc/Knockoff(mob/living/attacker,zone)
- var/obj/item/I = parent
- var/mob/living/carbon/human/wearer = I.loc
- if(!istype(wearer))
- return
- if(target_zones && !(zone in target_zones))
- return
- if(!prob(knockoff_chance))
- return
- if(!wearer.dropItemToGround(I))
- return
-
- wearer.visible_message("[attacker] knocks off [wearer]'s [I.name]!","[attacker] knocks off your [I.name]!")
-
-/datum/component/knockoff/proc/OnEquipped(datum/source, mob/living/carbon/human/H,slot)
- if(!istype(H))
- return
- if(slots_knockoffable && !(slot in slots_knockoffable))
- UnregisterSignal(H, COMSIG_HUMAN_DISARM_HIT)
- return
- RegisterSignal(H, COMSIG_HUMAN_DISARM_HIT, .proc/Knockoff, TRUE)
-
-/datum/component/knockoff/proc/OnDropped(datum/source, mob/living/M)
- UnregisterSignal(M, COMSIG_HUMAN_DISARM_HIT)
diff --git a/code/datums/components/lifesteal.dm b/code/datums/components/lifesteal.dm
deleted file mode 100644
index 40422d1e561..00000000000
--- a/code/datums/components/lifesteal.dm
+++ /dev/null
@@ -1,38 +0,0 @@
-/datum/component/lifesteal
- var/flat_heal // heals a constant amount every time a hit occurs
- var/static/list/damage_heal_order = list(BRUTE, BURN, OXY)
-
-/datum/component/lifesteal/Initialize(flat_heal=0)
- if(!isitem(parent) && !ishostile(parent) && !isgun(parent))
- return COMPONENT_INCOMPATIBLE
-
- src.flat_heal = flat_heal
-
-/datum/component/lifesteal/RegisterWithParent()
- if(isgun(parent))
- RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit)
- else if(isitem(parent))
- RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/item_afterattack)
- else if(ishostile(parent))
- RegisterSignal(parent, COMSIG_HOSTILE_ATTACKINGTARGET, .proc/hostile_attackingtarget)
-
-/datum/component/lifesteal/UnregisterFromParent()
- UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT))
-
-/datum/component/lifesteal/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
- if(!(clickchain_flags & CLICKCHAIN_HAS_PROXIMITY))
- return
- do_lifesteal(user, target)
-
-/datum/component/lifesteal/proc/hostile_attackingtarget(mob/living/simple_animal/hostile/attacker, atom/target)
- do_lifesteal(attacker, target)
-
-/datum/component/lifesteal/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle)
- do_lifesteal(firer, target)
-
-/datum/component/lifesteal/proc/do_lifesteal(atom/heal_target, atom/damage_target)
- if(isliving(heal_target) && isliving(damage_target))
- var/mob/living/healing = heal_target
- var/mob/living/damaging = damage_target
- if(damaging.stat != DEAD)
- healing.heal_ordered_damage(flat_heal, damage_heal_order)
diff --git a/code/datums/components/lockon_aiming.dm b/code/datums/components/lockon_aiming.dm
deleted file mode 100644
index 35dc8654bd6..00000000000
--- a/code/datums/components/lockon_aiming.dm
+++ /dev/null
@@ -1,214 +0,0 @@
-#define LOCKON_AIMING_MAX_CURSOR_RADIUS 7
-#define LOCKON_IGNORE_RESULT "ignore_my_result"
-#define LOCKON_RANGING_BREAK_CHECK if(current_ranging_id != this_id){return LOCKON_IGNORE_RESULT}
-
-/datum/component/lockon_aiming
- dupe_mode = COMPONENT_DUPE_ALLOWED
- var/lock_icon = 'icons/mob/cameramob.dmi'
- var/lock_icon_state = "marker"
- var/mutable_appearance/lock_appearance
- var/list/image/lock_images
- var/list/target_typecache
- var/list/immune_weakrefs //list(weakref = TRUE)
- var/mob_stat_check = TRUE //if a potential target is a mob make sure it's conscious!
- var/lock_amount = 1
- var/lock_cursor_range = 5
- var/list/locked_weakrefs
- var/update_disabled = FALSE
- var/current_ranging_id = 0
- var/list/last_location
- var/datum/callback/on_lock
- var/datum/callback/can_target_callback
-
-/datum/component/lockon_aiming/Initialize(range, list/typecache, amount, list/immune, datum/callback/when_locked, icon, icon_state, datum/callback/target_callback)
- if(!ismob(parent))
- return COMPONENT_INCOMPATIBLE
- if(target_callback)
- can_target_callback = target_callback
- else
- can_target_callback = CALLBACK(src, .proc/can_target)
- if(range)
- lock_cursor_range = range
- if(typecache)
- target_typecache = typecache
- if(amount)
- lock_amount = amount
- immune_weakrefs = list(WEAKREF(parent) = TRUE) //Manually take this out if you want..
- if(immune)
- for(var/i in immune)
- if(isweakref(i))
- immune_weakrefs[i] = TRUE
- else if(isatom(i))
- immune_weakrefs[WEAKREF(i)] = TRUE
- if(when_locked)
- on_lock = when_locked
- if(icon)
- lock_icon = icon
- if(icon_state)
- lock_icon_state = icon_state
- generate_lock_visuals()
- START_PROCESSING(SSfastprocess, src)
-
-/datum/component/lockon_aiming/Destroy()
- clear_visuals()
- STOP_PROCESSING(SSfastprocess, src)
- return ..()
-
-/datum/component/lockon_aiming/proc/show_visuals()
- LAZYINITLIST(lock_images)
- var/mob/M = parent
- if(!M.client)
- return
- for(var/i in locked_weakrefs)
- var/datum/weakref/R = i
- var/atom/A = R.resolve()
- if(!A)
- continue //It'll be cleared by processing.
- var/image/I = new
- I.appearance = lock_appearance
- I.loc = A
- M.client.images |= I
- lock_images |= I
-
-/datum/component/lockon_aiming/proc/clear_visuals()
- var/mob/M = parent
- if(!M.client)
- return
- if(!lock_images)
- return
- for(var/i in lock_images)
- M.client.images -= i
- qdel(i)
- lock_images.Cut()
-
-/datum/component/lockon_aiming/proc/refresh_visuals()
- clear_visuals()
- show_visuals()
-
-/datum/component/lockon_aiming/proc/generate_lock_visuals()
- lock_appearance = mutable_appearance(icon = lock_icon, icon_state = lock_icon_state, layer = FLOAT_LAYER)
-
-/datum/component/lockon_aiming/proc/unlock_all(refresh_vis = TRUE)
- LAZYCLEARLIST(locked_weakrefs)
- if(refresh_vis)
- refresh_visuals()
-
-/datum/component/lockon_aiming/proc/unlock(atom/A, refresh_vis = TRUE)
- if(!A.weak_reference)
- return
- LAZYREMOVE(locked_weakrefs, A.weak_reference)
- if(refresh_vis)
- refresh_visuals()
-
-/datum/component/lockon_aiming/proc/lock(atom/A, refresh_vis = TRUE)
- LAZYDISTINCTADD(locked_weakrefs, WEAKREF(A))
- if(refresh_vis)
- refresh_visuals()
-
-/datum/component/lockon_aiming/proc/add_immune_atom(atom/A)
- var/datum/weakref/R = WEAKREF(A)
- if(immune_weakrefs && (immune_weakrefs[R]))
- return
- LAZYSET(immune_weakrefs, R, TRUE)
-
-/datum/component/lockon_aiming/proc/remove_immune_atom(atom/A)
- if(!A.weak_reference || !immune_weakrefs) //if A doesn't have a weakref how did it get on the immunity list?
- return
- LAZYREMOVE(immune_weakrefs, A.weak_reference)
-
-/datum/component/lockon_aiming/process(delta_time)
- if(update_disabled)
- return
- if(!last_location)
- return
- var/changed = FALSE
- for(var/i in locked_weakrefs)
- var/datum/weakref/R = i
- if(istype(R))
- var/atom/thing = R.resolve()
- if(!istype(thing) || (get_dist(thing, locate(last_location[1], last_location[2], last_location[3])) > lock_cursor_range))
- unlock(R)
- changed = TRUE
- else
- unlock(R)
- changed = TRUE
- if(changed)
- autolock()
-
-/datum/component/lockon_aiming/proc/autolock()
- var/mob/M = parent
- if(!M.client)
- return FALSE
- var/datum/position/current = mouse_absolute_datum_map_position_from_client(M.client)
- var/turf/target = current.return_turf()
- var/list/atom/targets = get_nearest(target, target_typecache, lock_amount, lock_cursor_range)
- if(targets == LOCKON_IGNORE_RESULT)
- return
- unlock_all(FALSE)
- for(var/i in targets)
- if(immune_weakrefs[WEAKREF(i)])
- continue
- lock(i, FALSE)
- refresh_visuals()
- on_lock.Invoke(locked_weakrefs)
-
-/datum/component/lockon_aiming/proc/can_target(atom/A)
- var/mob/M = A
- return is_type_in_typecache(A, target_typecache) && !(ismob(A) && mob_stat_check && M.stat != CONSCIOUS) && !immune_weakrefs[WEAKREF(A)]
-
-/datum/component/lockon_aiming/proc/get_nearest(turf/T, list/typecache, amount, range)
- current_ranging_id++
- var/this_id = current_ranging_id
- var/list/L = list()
- var/turf/center = get_turf(T)
- if(amount < 1 || range < 0 || !istype(center) || !islist(typecache))
- return
- if(range == 0)
- return typecache_filter_list(T.contents + T, typecache)
- var/x = 0
- var/y = 0
- var/cd = 0
- while(cd <= range)
- x = center.x - cd + 1
- y = center.y + cd
- LOCKON_RANGING_BREAK_CHECK
- for(x in x to center.x + cd)
- T = locate(x, y, center.z)
- if(T)
- L |= special_list_filter(T.contents, can_target_callback)
- if(L.len >= amount)
- L.Cut(amount+1)
- return L
- LOCKON_RANGING_BREAK_CHECK
- y = center.y + cd - 1
- x = center.x + cd
- for(y in center.y - cd to y)
- T = locate(x, y, center.z)
- if(T)
- L |= special_list_filter(T.contents, can_target_callback)
- if(L.len >= amount)
- L.Cut(amount+1)
- return L
- LOCKON_RANGING_BREAK_CHECK
- y = center.y - cd
- x = center.x + cd - 1
- for(x in center.x - cd to x)
- T = locate(x, y, center.z)
- if(T)
- L |= special_list_filter(T.contents, can_target_callback)
- if(L.len >= amount)
- L.Cut(amount+1)
- return L
- LOCKON_RANGING_BREAK_CHECK
- y = center.y - cd + 1
- x = center.x - cd
- for(y in y to center.y + cd)
- T = locate(x, y, center.z)
- if(T)
- L |= special_list_filter(T.contents, can_target_callback)
- if(L.len >= amount)
- L.Cut(amount+1)
- return L
- LOCKON_RANGING_BREAK_CHECK
- cd++
- CHECK_TICK
diff --git a/code/datums/components/magnetic_catch.dm b/code/datums/components/magnetic_catch.dm
deleted file mode 100644
index 20cd8e1d78f..00000000000
--- a/code/datums/components/magnetic_catch.dm
+++ /dev/null
@@ -1,34 +0,0 @@
-/datum/component/magnetic_catch/Initialize()
- if(!isatom(parent))
- return COMPONENT_INCOMPATIBLE
- RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
- if(ismovable(parent))
- RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/crossed_react)
- RegisterSignal(parent, COMSIG_MOVABLE_UNCROSSED, .proc/uncrossed_react)
- for(var/i in get_turf(parent))
- if(i == parent)
- continue
- RegisterSignal(i, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react)
- else
- RegisterSignal(parent, COMSIG_ATOM_ENTERED, .proc/entered_react)
- RegisterSignal(parent, COMSIG_ATOM_EXITED, .proc/exited_react)
- for(var/i in parent)
- RegisterSignal(i, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react)
-
-/datum/component/magnetic_catch/proc/examine(datum/source, mob/user, list/examine_list)
- examine_list += "It has been installed with inertia dampening to prevent coffee spills."
-
-/datum/component/magnetic_catch/proc/crossed_react(datum/source, atom/movable/thing)
- RegisterSignal(thing, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react, TRUE)
-
-/datum/component/magnetic_catch/proc/uncrossed_react(datum/source, atom/movable/thing)
- UnregisterSignal(thing, COMSIG_MOVABLE_PRE_THROW)
-
-/datum/component/magnetic_catch/proc/entered_react(datum/source, atom/movable/thing, atom/oldloc)
- RegisterSignal(thing, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react, TRUE)
-
-/datum/component/magnetic_catch/proc/exited_react(datum/source, atom/movable/thing, atom/newloc)
- UnregisterSignal(thing, COMSIG_MOVABLE_PRE_THROW)
-
-/datum/component/magnetic_catch/proc/throw_react(datum/source, list/arguments)
- return COMPONENT_CANCEL_THROW
diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm
deleted file mode 100644
index 294c360ad37..00000000000
--- a/code/datums/components/material_container.dm
+++ /dev/null
@@ -1,352 +0,0 @@
-/**
- *! This datum should be used for handling mineral contents of machines and whatever else is supposed to hold minerals and make use of them.
- *
- ** Variables:
- ** - amount - Raw amount of the mineral this container is holding, calculated by the defined value MINERAL_MATERIAL_AMOUNT=2000.
- ** - max_amount - Max raw amount of mineral this container can hold.
- ** - sheet_type - Type of the mineral sheet the container handles, used for output.
- ** - parent - Object that this container is being used by, used for output.
- ** - MAX_STACK_SIZE - Size of a stack of mineral sheets. Constant.
- */
-
-/datum/component/material_container
- var/total_amount = 0
- var/max_amount
- var/sheet_type
- var/list/materials //Map of key = material ref | Value = amount
- 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
-
-/// Sets up the proper signals and fills the list of materials with the appropriate references.
-/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)
- 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
-
- RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
- RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/OnExamine)
-
- for(var/mat in mat_list) //Make the assoc list ref | amount
- var/datum/material/M = getmaterialref(mat) || mat
- materials[M] = 0
-
-/datum/component/material_container/proc/OnExamine(datum/source, mob/user)
- if(show_on_examine)
- for(var/I in materials)
- var/datum/material/M = I
- var/amt = materials[I]
- if(amt)
- to_chat(user, "It has [amt] units of [lowertext(M.name)] stored.")
-
-/// Proc that allows players to fill the parent with mats
-/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.item_flags & ITEM_ABSTRACT)
- return
- if((I.flags_1 & HOLOGRAM_1) || (I.item_flags & NO_MAT_REDEMPTION) || (tc && !is_type_in_typecache(I, tc)))
- to_chat(user, "[parent] won't accept [I]!")
- return
- . = COMPONENT_NO_AFTERATTACK
- var/datum/callback/pc = precondition
- if(pc && !pc.Invoke(user))
- return
- var/material_amount = get_item_material_amount(I)
- if(!material_amount)
- to_chat(user, "[I] does not contain sufficient amounts of metal or glass to be accepted by [parent].")
- return
- if(!has_space(material_amount))
- to_chat(user, "[parent] is full. Please remove metal or glass from [parent] in order to insert more.")
- return
- user_insert(I, user)
-
-/// Proc used for when player inserts materials
-/datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user)
- set waitfor = FALSE
- var/requested_amount
- var/active_held = user.get_active_held_item() // differs from I when using MUTATION_TELEKINESIS
- if(istype(I, /obj/item/stack) && precise_insertion)
- var/atom/current_parent = parent
- var/obj/item/stack/S = I
- requested_amount = input(user, "How much do you want to insert?", "Inserting [S.singular_name]s") as num|null
- if(isnull(requested_amount) || (requested_amount <= 0))
- return
- if(QDELETED(I) || QDELETED(user) || QDELETED(src) || parent != current_parent || user.physical_can_use_topic(current_parent) < UI_INTERACTIVE || user.get_active_held_item() != active_held)
- return
- if(!user.temporarilyRemoveItemFromInventory(I))
- to_chat(user, "[I] is stuck to you and cannot be placed into [parent].")
- return
- var/inserted = insert_item(I, stack_amt = requested_amount)
- if(inserted)
- 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) && I == active_held && !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)
- if(after_insert)
- after_insert.Invoke(I.type, last_inserted_id, inserted)
- else if(I == active_held)
- user.put_in_active_hand(I)
-
-/// Proc specifically for inserting items, returns the amount of materials entered.
-/datum/component/material_container/proc/insert_item(obj/item/I, var/multiplier = 1, stack_amt)
- if(!I)
- return FALSE
- if(istype(I, /obj/item/stack))
- return insert_stack(I, stack_amt, multiplier)
-
- multiplier = CEILING(multiplier, 0.01)
-
- var/material_amount = get_item_material_amount(I)
- if(!material_amount || !has_space(material_amount))
- return FALSE
-
- last_inserted_id = insert_item_materials(I, multiplier)
- return material_amount
-
-/datum/component/material_container/proc/insert_item_materials(obj/item/I, multiplier = 1)
- var/primary_mat
- var/max_mat_value = 0
- for(var/MAT in materials)
- materials[MAT] += I.materials[MAT] * multiplier
- total_amount += I.materials[MAT] * multiplier
- if(I.materials[MAT] > max_mat_value)
- primary_mat = MAT
- return primary_mat
-
-/// Proc for putting a stack inside of the container
-/datum/component/material_container/proc/insert_stack(obj/item/stack/S, amt, multiplier = 1)
- if(isnull(amt))
- amt = S.amount
-
- if(amt <= 0)
- return FALSE
-
- if(amt > S.amount)
- amt = S.amount
-
- var/material_amt = get_item_material_amount(S)
- if(!material_amt)
- return FALSE
-
- amt = min(amt, round(((max_amount - total_amount) / material_amt)))
- if(!amt)
- return FALSE
-
- last_inserted_id = insert_item_materials(S,amt * multiplier)
- S.use(amt)
- return amt
-
-/// For inserting an amount of material
-/datum/component/material_container/proc/insert_amount_mat(amt, var/datum/material/mat)
- if(!istype(mat))
- mat = getmaterialref(mat)
- if(amt > 0 && has_space(amt))
- var/total_amount_saved = total_amount
- if(mat)
- materials[mat] += amt
- else
- for(var/i in materials)
- materials[i] += amt
- total_amount += amt
- return (total_amount - total_amount_saved)
- return FALSE
-
-/// Uses an amount of a specific material, effectively removing it.
-/datum/component/material_container/proc/use_amount_mat(amt, var/datum/material/mat)
- if(!istype(mat))
- mat = getmaterialref(mat)
- var/amount = materials[mat]
- if(mat)
- if(amount >= amt)
- materials[mat] -= amt
- total_amount -= amt
- return amt
- return FALSE
-
-/// Proc for transfering materials to another container.
-/datum/component/material_container/proc/transer_amt_to(var/datum/component/material_container/T, amt, var/datum/material/mat)
- if(!istype(mat))
- mat = getmaterialref(mat)
- if((amt==0)||(!T)||(!mat))
- return FALSE
- if(amt<0)
- return T.transer_amt_to(src, -amt, mat)
- var/tr = min(amt, materials[mat],T.can_insert_amount_mat(amt, mat))
- if(tr)
- use_amount_mat(tr, mat)
- T.insert_amount_mat(tr, mat)
- return tr
- return FALSE
-
-/// Proc for checking if there is room in the component, returning the amount or else the amount lacking.
-/datum/component/material_container/proc/can_insert_amount_mat(amt, mat)
- if(amt && mat)
- var/datum/material/M = mat
- if(M)
- if((total_amount + amt) <= max_amount)
- return amt
- else
- return (max_amount-total_amount)
-
-
-/// For consuming a dictionary of materials. mats is the map of materials to use and the corresponding amounts, example: list(M/datum/material/glass =100, datum/material/iron=200)
-/datum/component/material_container/proc/use_materials(list/mats, multiplier=1)
- if(!mats || !length(mats))
- return FALSE
-
- var/list/mats_to_remove = list() //Assoc list MAT | AMOUNT
-
- for(var/x in mats) //Loop through all required materials
- var/datum/material/req_mat = x
- if(!istype(req_mat))
- req_mat = getmaterialref(req_mat) //Get the ref if necesary
- if(!materials[req_mat]) //Do we have the resource?
- return FALSE //Can't afford it
- var/amount_required = mats[x] * multiplier
- if(!(materials[req_mat] >= amount_required)) // do we have enough of the resource?
- return FALSE //Can't afford it
- mats_to_remove[req_mat] += amount_required //Add it to the assoc list of things to remove
- continue
-
- var/total_amount_save = total_amount
-
- for(var/i in mats_to_remove)
- total_amount_save -= use_amount_mat(mats_to_remove[i], i)
-
- return total_amount_save - total_amount
-
-/// For spawning mineral sheets at a specific location. Used by machines to output sheets.
-/datum/component/material_container/proc/retrieve_sheets(sheet_amt, var/datum/material/M, target = null)
- if(!M.sheet_type)
- return 0 //Add greyscale sheet handling here later
- if(sheet_amt <= 0)
- return 0
-
- if(!target)
- target = get_turf(parent)
- if(materials[M] < (sheet_amt * MINERAL_MATERIAL_AMOUNT))
- sheet_amt = round(materials[M] / 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_mat(sheet_amt * MINERAL_MATERIAL_AMOUNT, M)
- sheet_amt -= MAX_STACK_SIZE
- if(sheet_amt >= 1)
- new M.sheet_type(target, sheet_amt)
- count += sheet_amt
- use_amount_mat(sheet_amt * MINERAL_MATERIAL_AMOUNT, M)
- return count
-
-
-/// Proc to get all the materials and dump them as sheets
-/datum/component/material_container/proc/retrieve_all(target = null)
- var/result = 0
- for(var/MAT in materials)
- var/amount = materials[MAT]
- result += retrieve_sheets(amount2sheet(amount), MAT, target)
- return result
-
-/// Proc that returns TRUE if the container has space
-/datum/component/material_container/proc/has_space(amt = 0)
- return (total_amount + amt) <= max_amount
-
-/// Checks if its possible to afford a certain amount of materials. Takes a dictionary of materials.
-/datum/component/material_container/proc/has_materials(list/mats, multiplier=1)
- if(!mats || !mats.len)
- return FALSE
-
- for(var/x in mats) //Loop through all required materials
- var/datum/material/req_mat = x
- if(!istype(req_mat))
- if(ispath(req_mat)) //Is this an actual material, or is it a category?
- req_mat = getmaterialref(req_mat) //Get the ref
-
- else // Its a category. (For example MAT_CATEGORY_RIGID)
- if(!has_enough_of_category(req_mat, mats[x], multiplier)) //Do we have enough of this category?
- return FALSE
- else
- continue
-
- if(!has_enough_of_material(req_mat, mats[x], multiplier))//Not a category, so just check the normal way
- return FALSE
-
- return TRUE
-
-/// Returns all the categories in a recipe.
-/datum/component/material_container/proc/get_categories(list/mats)
- var/list/categories = list()
- for(var/x in mats) //Loop through all required materials
- if(!istext(x)) //This means its not a category
- continue
- categories += x
- return categories
-
-
-/// Returns TRUE if you have enough of the specified material.
-/datum/component/material_container/proc/has_enough_of_material(var/datum/material/req_mat, amount, multiplier=1)
- if(!materials[req_mat]) //Do we have the resource?
- return FALSE //Can't afford it
- var/amount_required = amount * multiplier
- if(materials[req_mat] >= amount_required) // do we have enough of the resource?
- return TRUE
- return FALSE //Can't afford it
-
-/// Returns TRUE if you have enough of a specified material category (Which could be multiple materials)
-/datum/component/material_container/proc/has_enough_of_category(category, amount, multiplier=1)
- for(var/i in SSmaterials.materials_by_category[category])
- var/datum/material/mat = i
- if(materials[mat] >= amount) //we have enough
- return TRUE
- return FALSE
-
-/// Turns a material amount into the amount of sheets it should output
-/datum/component/material_container/proc/amount2sheet(amt)
- if(amt >= MINERAL_MATERIAL_AMOUNT)
- return round(amt / MINERAL_MATERIAL_AMOUNT)
- return FALSE
-
-/// Turns an amount of sheets into the amount of material amount it should output
-/datum/component/material_container/proc/sheet2amount(sheet_amt)
- if(sheet_amt > 0)
- return sheet_amt * MINERAL_MATERIAL_AMOUNT
- return FALSE
-
-
-///returns the amount of material relevant to this container; if this container does not support glass, any glass in 'I' will not be taken into account
-/datum/component/material_container/proc/get_item_material_amount(obj/item/I)
- if(!istype(I))
- return FALSE
- var/material_amount = 0
- for(var/MAT in materials)
- material_amount += I.materials[MAT]
- return material_amount
-
-/// Returns the amount of a specific material in this container.
-/datum/component/material_container/proc/get_material_amount(var/datum/material/mat)
- if(!istype(mat))
- mat = getmaterialref(mat)
- return(materials[mat])
diff --git a/code/datums/components/mirage_border.dm b/code/datums/components/mirage_border.dm
deleted file mode 100644
index a366f4b822f..00000000000
--- a/code/datums/components/mirage_border.dm
+++ /dev/null
@@ -1,42 +0,0 @@
-/datum/component/mirage_border
- can_transfer = TRUE
- var/obj/effect/abstract/mirage_holder/holder
-
-/datum/component/mirage_border/Initialize(turf/target, direction, range=world.view)
- if(!isturf(parent))
- return COMPONENT_INCOMPATIBLE
- if(!target || !istype(target) || !direction)
- . = COMPONENT_INCOMPATIBLE
- CRASH("[type] improperly instanced with the following args: target=\[[target]\], direction=\[[direction]\], range=\[[range]\]")
-
- holder = new(parent)
-
- var/x = target.x
- var/y = target.y
- var/z = target.z
- var/turf/southwest = locate(clamp(x - (direction & WEST ? range : 0), 1, world.maxx), clamp(y - (direction & SOUTH ? range : 0), 1, world.maxy), clamp(z, 1, world.maxz))
- var/turf/northeast = locate(clamp(x + (direction & EAST ? range : 0), 1, world.maxx), clamp(y + (direction & NORTH ? range : 0), 1, world.maxy), clamp(z, 1, world.maxz))
- //holder.vis_contents += block(southwest, northeast) // This doesnt work because of beta bug memes
- for(var/i in block(southwest, northeast))
- holder.vis_contents += i
- if(direction & SOUTH)
- holder.pixel_y -= world.icon_size * range
- if(direction & WEST)
- holder.pixel_x -= world.icon_size * range
-
-/datum/component/mirage_border/Destroy()
- QDEL_NULL(holder)
- return ..()
-
-/datum/component/mirage_border/PreTransfer()
- holder.moveToNullspace()
-
-/datum/component/mirage_border/PostTransfer()
- if(!isturf(parent))
- return COMPONENT_INCOMPATIBLE
- holder.forceMove(parent)
-
-/obj/effect/abstract/mirage_holder
- name = "Mirage holder"
- anchored = TRUE
- mouse_opacity = MOUSE_OPACITY_TRANSPARENT
diff --git a/code/datums/components/nanites.dm b/code/datums/components/nanites.dm
deleted file mode 100644
index e63d0c9ad1b..00000000000
--- a/code/datums/components/nanites.dm
+++ /dev/null
@@ -1,316 +0,0 @@
-/datum/component/nanites
- dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
-
- var/mob/living/host_mob
- var/nanite_volume = 100 //amount of nanites in the system, used as fuel for nanite programs
- var/max_nanites = 500 //maximum amount of nanites in the system
- var/regen_rate = 0.5 //nanites generated per second
- var/safety_threshold = 50 //how low nanites will get before they stop processing/triggering
- var/cloud_id = 0 //0 if not connected to the cloud, 1-100 to set a determined cloud backup to draw from
- var/next_sync = 0
- var/list/datum/nanite_program/programs = list()
- var/max_programs = NANITE_PROGRAM_LIMIT
-
- var/stealth = FALSE //if TRUE, does not appear on HUDs and health scans, and does not display the program list on nanite scans
-
-/datum/component/nanites/Initialize(amount = 100, cloud = 0)
- if(!isliving(parent) && !istype(parent, /datum/nanite_cloud_backup))
- return COMPONENT_INCOMPATIBLE
-
- nanite_volume = amount
- cloud_id = cloud
-
- //Nanites without hosts are non-interactive through normal means
- if(isliving(parent))
- host_mob = parent
-
- if(!(host_mob.mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD))) //Shouldn't happen, but this avoids HUD runtimes in case a silicon gets them somehow.
- return COMPONENT_INCOMPATIBLE
-
- host_mob.hud_set_nanite_indicator()
- START_PROCESSING(SSnanites, src)
-
- if(cloud_id)
- cloud_sync()
-
-/datum/component/nanites/RegisterWithParent()
- RegisterSignal(parent, COMSIG_HAS_NANITES, .proc/confirm_nanites)
- RegisterSignal(parent, COMSIG_NANITE_UI_DATA, .proc/nanite_ui_data)
- RegisterSignal(parent, COMSIG_NANITE_GET_PROGRAMS, .proc/get_programs)
- RegisterSignal(parent, COMSIG_NANITE_SET_VOLUME, .proc/set_volume)
- RegisterSignal(parent, COMSIG_NANITE_ADJUST_VOLUME, .proc/adjust_nanites)
- RegisterSignal(parent, COMSIG_NANITE_SET_MAX_VOLUME, .proc/set_max_volume)
- RegisterSignal(parent, COMSIG_NANITE_SET_CLOUD, .proc/set_cloud)
- RegisterSignal(parent, COMSIG_NANITE_SET_SAFETY, .proc/set_safety)
- RegisterSignal(parent, COMSIG_NANITE_SET_REGEN, .proc/set_regen)
- RegisterSignal(parent, COMSIG_NANITE_ADD_PROGRAM, .proc/add_program)
- RegisterSignal(parent, COMSIG_NANITE_SCAN, .proc/nanite_scan)
- RegisterSignal(parent, COMSIG_NANITE_SYNC, .proc/sync)
-
- if(isliving(parent))
- RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/on_emp)
- RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/on_death)
- RegisterSignal(parent, COMSIG_MOB_ALLOWED, .proc/check_access)
- RegisterSignal(parent, COMSIG_LIVING_ELECTROCUTE_ACT, .proc/on_shock)
- RegisterSignal(parent, COMSIG_LIVING_MINOR_SHOCK, .proc/on_minor_shock)
- RegisterSignal(parent, COMSIG_SPECIES_GAIN, .proc/check_viable_biotype)
- RegisterSignal(parent, COMSIG_NANITE_SIGNAL, .proc/receive_signal)
- RegisterSignal(parent, COMSIG_NANITE_COMM_SIGNAL, .proc/receive_comm_signal)
-
-/datum/component/nanites/UnregisterFromParent()
- UnregisterSignal(parent, list(COMSIG_HAS_NANITES,
- COMSIG_NANITE_UI_DATA,
- COMSIG_NANITE_GET_PROGRAMS,
- COMSIG_NANITE_SET_VOLUME,
- COMSIG_NANITE_ADJUST_VOLUME,
- COMSIG_NANITE_SET_MAX_VOLUME,
- COMSIG_NANITE_SET_CLOUD,
- COMSIG_NANITE_SET_SAFETY,
- COMSIG_NANITE_SET_REGEN,
- COMSIG_NANITE_ADD_PROGRAM,
- COMSIG_NANITE_SCAN,
- COMSIG_NANITE_SYNC,
- COMSIG_ATOM_EMP_ACT,
- COMSIG_MOB_DEATH,
- COMSIG_MOB_ALLOWED,
- COMSIG_LIVING_ELECTROCUTE_ACT,
- COMSIG_LIVING_MINOR_SHOCK,
- COMSIG_MOVABLE_HEAR,
- COMSIG_SPECIES_GAIN,
- COMSIG_NANITE_SIGNAL,
- COMSIG_NANITE_COMM_SIGNAL))
-
-/datum/component/nanites/Destroy()
- STOP_PROCESSING(SSnanites, src)
- set_nanite_bar(TRUE)
- QDEL_LIST(programs)
- if(host_mob)
- host_mob.hud_set_nanite_indicator()
- host_mob = null
- return ..()
-
-/datum/component/nanites/InheritComponent(datum/component/nanites/new_nanites, i_am_original, list/arguments)
- if(new_nanites)
- adjust_nanites(null, new_nanites.nanite_volume)
- else
- adjust_nanites(null, arguments[1]) //just add to the nanite volume
-
-/datum/component/nanites/process(delta_time)
- adjust_nanites(null, regen_rate)
- for(var/X in programs)
- var/datum/nanite_program/NP = X
- NP.on_process()
- set_nanite_bar()
- if(cloud_id && world.time > next_sync)
- cloud_sync()
- next_sync = world.time + NANITE_SYNC_DELAY
-
-//Syncs the nanite component to another, making it so programs are the same with the same programming (except activation status)
-/datum/component/nanites/proc/sync(datum/signal_source, datum/component/nanites/source, full_overwrite = TRUE, copy_activation = FALSE)
- var/list/programs_to_remove = programs.Copy()
- var/list/programs_to_add = source.programs.Copy()
- for(var/X in programs)
- var/datum/nanite_program/NP = X
- for(var/Y in programs_to_add)
- var/datum/nanite_program/SNP = Y
- if(NP.type == SNP.type)
- programs_to_remove -= NP
- programs_to_add -= SNP
- SNP.copy_programming(NP, copy_activation)
- break
- if(full_overwrite)
- for(var/X in programs_to_remove)
- qdel(X)
- for(var/X in programs_to_add)
- var/datum/nanite_program/SNP = X
- add_program(null, SNP.copy())
-
-/datum/component/nanites/proc/cloud_sync()
- if(!cloud_id)
- return
- var/datum/nanite_cloud_backup/backup = SSnanites.get_cloud_backup(cloud_id)
- if(backup)
- var/datum/component/nanites/cloud_copy = backup.nanites
- if(cloud_copy)
- sync(null, cloud_copy)
-
-/datum/component/nanites/proc/add_program(datum/source, datum/nanite_program/new_program, datum/nanite_program/source_program)
- for(var/X in programs)
- var/datum/nanite_program/NP = X
- if(NP.unique && NP.type == new_program.type)
- qdel(NP)
- if(programs.len >= max_programs)
- return COMPONENT_PROGRAM_NOT_INSTALLED
- if(source_program)
- source_program.copy_programming(new_program)
- programs += new_program
- new_program.on_add(src)
- return COMPONENT_PROGRAM_INSTALLED
-
-/datum/component/nanites/proc/consume_nanites(amount, force = FALSE)
- if(!force && safety_threshold && (nanite_volume - amount < safety_threshold))
- return FALSE
- adjust_nanites(null, -amount)
- return (nanite_volume > 0)
-
-/datum/component/nanites/proc/adjust_nanites(datum/source, amount)
- nanite_volume = clamp(nanite_volume + amount, 0, max_nanites)
- if(nanite_volume <= 0) //oops we ran out
- qdel(src)
-
-/datum/component/nanites/proc/set_nanite_bar(remove = FALSE)
- var/image/holder = host_mob.hud_list[DIAG_NANITE_FULL_HUD]
- var/icon/I = icon(host_mob.icon, host_mob.icon_state, host_mob.dir)
- holder.pixel_y = I.Height() - world.icon_size
- holder.icon_state = null
- if(remove || stealth)
- return //bye icon
- var/nanite_percent = (nanite_volume / max_nanites) * 100
- nanite_percent = clamp(CEILING(nanite_percent, 10), 10, 100)
- holder.icon_state = "nanites[nanite_percent]"
-
-/datum/component/nanites/proc/on_emp(datum/source, severity)
- nanite_volume *= (rand(0.60, 0.90)) //Lose 10-40% of nanites
- adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume
- if(prob(40/severity))
- cloud_id = 0
- for(var/X in programs)
- var/datum/nanite_program/NP = X
- NP.on_emp(severity)
-
-/datum/component/nanites/proc/on_shock(datum/source, shock_damage)
- nanite_volume *= (rand(0.45, 0.80)) //Lose 20-55% of nanites
- adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume
- for(var/X in programs)
- var/datum/nanite_program/NP = X
- NP.on_shock(shock_damage)
-
-/datum/component/nanites/proc/on_minor_shock(datum/source)
- adjust_nanites(null, -(rand(5, 15))) //Lose 5-15 flat nanite volume
- for(var/X in programs)
- var/datum/nanite_program/NP = X
- NP.on_minor_shock()
-
-/datum/component/nanites/proc/on_death(datum/source, gibbed)
- for(var/X in programs)
- var/datum/nanite_program/NP = X
- NP.on_death(gibbed)
-
-/datum/component/nanites/proc/receive_signal(datum/source, code, source = "an unidentified source")
- for(var/X in programs)
- var/datum/nanite_program/NP = X
- NP.receive_signal(code, source)
-
-/datum/component/nanites/proc/receive_comm_signal(datum/source, comm_code, comm_message, comm_source = "an unidentified source")
- for(var/X in programs)
- if(istype(X, /datum/nanite_program/triggered/comm))
- var/datum/nanite_program/triggered/comm/NP = X
- NP.receive_comm_signal(comm_code, comm_message, comm_source)
-
-/datum/component/nanites/proc/check_viable_biotype()
- if(!(host_mob.mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD)))
- qdel(src) //bodytype no longer sustains nanites
-
-/datum/component/nanites/proc/check_access(datum/source, obj/O)
- for(var/datum/nanite_program/triggered/access/access_program in programs)
- if(access_program.activated)
- return O.check_access_list(access_program.access)
- else
- return FALSE
- return FALSE
-
-/datum/component/nanites/proc/set_volume(datum/source, amount)
- nanite_volume = clamp(amount, 0, max_nanites)
-
-/datum/component/nanites/proc/set_max_volume(datum/source, amount)
- max_nanites = max(1, max_nanites)
-
-/datum/component/nanites/proc/set_cloud(datum/source, amount)
- cloud_id = clamp(amount, 0, 100)
-
-/datum/component/nanites/proc/set_safety(datum/source, amount)
- safety_threshold = clamp(amount, 0, max_nanites)
-
-/datum/component/nanites/proc/set_regen(datum/source, amount)
- regen_rate = amount
-
-/datum/component/nanites/proc/confirm_nanites()
- return TRUE //yup i exist
-
-/datum/component/nanites/proc/get_data(list/nanite_data)
- nanite_data["nanite_volume"] = nanite_volume
- nanite_data["max_nanites"] = max_nanites
- nanite_data["cloud_id"] = cloud_id
- nanite_data["regen_rate"] = regen_rate
- nanite_data["safety_threshold"] = safety_threshold
- nanite_data["stealth"] = stealth
-
-/datum/component/nanites/proc/get_programs(datum/source, list/nanite_programs)
- nanite_programs |= programs
-
-/datum/component/nanites/proc/nanite_scan(datum/source, mob/user, full_scan)
- if(!full_scan)
- if(!stealth)
- to_chat(user, "Nanites Detected")
- to_chat(user, "Saturation: [nanite_volume]/[max_nanites]")
- return TRUE
- else
- to_chat(user, "NANITES DETECTED")
- to_chat(user, "================")
- to_chat(user, "Saturation: [nanite_volume]/[max_nanites]")
- to_chat(user, "Safety Threshold: [safety_threshold]")
- to_chat(user, "Cloud ID: [cloud_id ? cloud_id : "Disabled"]")
- to_chat(user, "================")
- to_chat(user, "Program List:")
- if(stealth)
- to_chat(user, "%#$ENCRYPTED&^@")
- else
- for(var/X in programs)
- var/datum/nanite_program/NP = X
- to_chat(user, "[NP.name] | [NP.activated ? "Active" : "Inactive"]")
- return TRUE
-
-/datum/component/nanites/proc/nanite_ui_data(datum/source, list/data, scan_level)
- data["has_nanites"] = TRUE
- data["nanite_volume"] = nanite_volume
- data["regen_rate"] = regen_rate
- data["safety_threshold"] = safety_threshold
- data["cloud_id"] = cloud_id
- var/list/mob_programs = list()
- var/id = 1
- for(var/X in programs)
- var/datum/nanite_program/P = X
- var/list/mob_program = list()
- mob_program["name"] = P.name
- mob_program["desc"] = P.desc
- mob_program["id"] = id
-
- if(scan_level >= 2)
- mob_program["activated"] = P.activated
- mob_program["use_rate"] = P.use_rate
- mob_program["can_trigger"] = P.can_trigger
- mob_program["trigger_cost"] = P.trigger_cost
- mob_program["trigger_cooldown"] = P.trigger_cooldown / 10
-
- if(scan_level >= 3)
- mob_program["activation_delay"] = P.activation_delay
- mob_program["timer"] = P.timer
- mob_program["timer_type"] = P.get_timer_type_text()
- var/list/extra_settings = list()
- for(var/Y in P.extra_settings)
- var/list/setting = list()
- setting["name"] = Y
- setting["value"] = P.get_extra_setting(Y)
- extra_settings += list(setting)
- mob_program["extra_settings"] = extra_settings
- if(LAZYLEN(extra_settings))
- mob_program["has_extra_settings"] = TRUE
-
- if(scan_level >= 4)
- mob_program["activation_code"] = P.activation_code
- mob_program["deactivation_code"] = P.deactivation_code
- mob_program["kill_code"] = P.kill_code
- mob_program["trigger_code"] = P.trigger_code
- id++
- mob_programs += list(mob_program)
- data["mob_programs"] = mob_programs
diff --git a/code/datums/components/ntnet_interface.dm b/code/datums/components/ntnet_interface.dm
deleted file mode 100644
index 3a8fb559bf4..00000000000
--- a/code/datums/components/ntnet_interface.dm
+++ /dev/null
@@ -1,66 +0,0 @@
-//Thing meant for allowing datums and objects to access a NTnet network datum.
-/datum/proc/ntnet_receive(datum/netdata/data)
- return
-
-/datum/proc/ntnet_receive_broadcast(datum/netdata/data)
- return
-
-/datum/proc/ntnet_send(datum/netdata/data, netid)
- var/datum/component/ntnet_interface/NIC = GetComponent(/datum/component/ntnet_interface)
- if(!NIC)
- return FALSE
- return NIC.__network_send(data, netid)
-
-/datum/component/ntnet_interface
- var/hardware_id //text. this is the true ID. do not change this. stuff like ID forgery can be done manually.
- var/network_name = "" //text
- var/list/networks_connected_by_id = list() //id = datum/ntnet
- var/differentiate_broadcast = TRUE //If false, broadcasts go to ntnet_receive. NOT RECOMMENDED.
-
-/datum/component/ntnet_interface/Initialize(force_name = "NTNet Device", autoconnect_station_network = TRUE) //Don't force ID unless you know what you're doing!
- hardware_id = "[SSnetworks.get_next_HID()]"
- network_name = force_name
- if(!SSnetworks.register_interface(src))
- . = COMPONENT_INCOMPATIBLE
- CRASH("Unable to register NTNet interface. Interface deleted.")
- if(autoconnect_station_network)
- register_connection(SSnetworks.station_network)
-
-/datum/component/ntnet_interface/Destroy()
- unregister_all_connections()
- SSnetworks.unregister_interface(src)
- return ..()
-
-/datum/component/ntnet_interface/proc/__network_receive(datum/netdata/data) //Do not directly proccall!
- SEND_SIGNAL(parent, COMSIG_COMPONENT_NTNET_RECEIVE, data)
- if(differentiate_broadcast && data.broadcast)
- parent.ntnet_receive_broadcast(data)
- else
- parent.ntnet_receive(data)
-
-/datum/component/ntnet_interface/proc/__network_send(datum/netdata/data, netid) //Do not directly proccall!
-
- if(netid)
- if(networks_connected_by_id[netid])
- var/datum/ntnet/net = networks_connected_by_id[netid]
- return net.process_data_transmit(src, data)
- return FALSE
- for(var/i in networks_connected_by_id)
- var/datum/ntnet/net = networks_connected_by_id[i]
- net.process_data_transmit(src, data)
- return TRUE
-
-/datum/component/ntnet_interface/proc/register_connection(datum/ntnet/net)
- if(net.interface_connect(src))
- networks_connected_by_id[net.network_id] = net
- return TRUE
-
-/datum/component/ntnet_interface/proc/unregister_all_connections()
- for(var/i in networks_connected_by_id)
- unregister_connection(networks_connected_by_id[i])
- return TRUE
-
-/datum/component/ntnet_interface/proc/unregister_connection(datum/ntnet/net)
- net.interface_disconnect(src)
- networks_connected_by_id -= net.network_id
- return TRUE
diff --git a/code/datums/components/paintable.dm b/code/datums/components/paintable.dm
deleted file mode 100644
index 511c51e0340..00000000000
--- a/code/datums/components/paintable.dm
+++ /dev/null
@@ -1,29 +0,0 @@
-/datum/component/spraycan_paintable
- var/current_paint
-
-/datum/component/spraycan_paintable/Initialize()
- RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/Repaint)
-
-/datum/component/spraycan_paintable/Destroy()
- RemoveCurrentCoat()
- return ..()
-
-/datum/component/spraycan_paintable/proc/RemoveCurrentCoat()
- var/atom/A = parent
- A.remove_atom_colour(FIXED_COLOUR_PRIORITY, current_paint)
-
-/datum/component/spraycan_paintable/proc/Repaint(datum/source, obj/item/toy/crayon/spraycan/spraycan, mob/living/user)
- if(!istype(spraycan) || user.a_intent == INTENT_HARM)
- return
- . = COMPONENT_NO_AFTERATTACK
- if(spraycan.is_capped)
- to_chat(user, "Take the cap off first!")
- return
- RemoveCurrentCoat()
- if(spraycan.use_charges(user, 2))
- var/colour = spraycan.paint_color
- current_paint = colour
- var/atom/A = parent
- A.add_atom_colour(colour, FIXED_COLOUR_PRIORITY)
- playsound(spraycan, 'sound/effects/spray.ogg', 5, TRUE, 5)
- to_chat(user, "You spray [spraycan] on [A], painting it.")
diff --git a/code/datums/components/plumbing/_plumbing.dm b/code/datums/components/plumbing/_plumbing.dm
deleted file mode 100644
index 16152d72b01..00000000000
--- a/code/datums/components/plumbing/_plumbing.dm
+++ /dev/null
@@ -1,197 +0,0 @@
-/datum/component/plumbing
- ///Index with "1" = /datum/ductnet/theductpointingnorth etc. "1" being the num2text from NORTH define
- var/list/datum/ductnet/ducts = list()
- ///shortcut to our parents' reagent holder
- var/datum/reagents/reagents
- ///TRUE if we wanna add proper pipe outless under our parent object. this is pretty good if i may so so myself
- var/use_overlays = TRUE
- ///We can't just cut all of the parents' overlays, so we'll track them here
- var/list/image/ducterlays
- ///directions in wich we act as a supplier
- var/supply_connects
- ///direction in wich we act as a demander
- var/demand_connects
- ///FALSE to pretty much just not exist in the plumbing world so we can be moved, TRUE to go plumbo mode
- var/active = FALSE
- ///if TRUE connects will spin with the parent object visually and codually, so you can have it work in any direction. FALSE if you want it to be static
- var/turn_connects = TRUE
-
-/datum/component/plumbing/Initialize(start=TRUE, _turn_connects=TRUE) //turn_connects for wheter or not we spin with the object to change our pipes
- if(parent && !ismovable(parent))
- return COMPONENT_INCOMPATIBLE
- var/atom/movable/AM = parent
- if(!AM.reagents)
- return COMPONENT_INCOMPATIBLE
- reagents = AM.reagents
- turn_connects = _turn_connects
-
- RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED,COMSIG_PARENT_PREQDELETED), .proc/disable)
- RegisterSignal(parent, list(COMSIG_OBJ_DEFAULT_UNFASTEN_WRENCH), .proc/toggle_active)
-
- if(start)
- enable()
-
- if(use_overlays)
- create_overlays()
-
-/datum/component/plumbing/process(delta_time)
- if(!demand_connects || !reagents)
- STOP_PROCESSING(SSfluids, src)
- return
- if(reagents.total_volume < reagents.maximum_volume)
- for(var/D in GLOB.cardinals)
- if(D & demand_connects)
- send_request(D)
-///Can we be added to the ductnet?
-/datum/component/plumbing/proc/can_add(datum/ductnet/D, dir)
- if(!active)
- return
- if(!dir || !D)
- return FALSE
- if(num2text(dir) in ducts)
- return FALSE
-
- return TRUE
-///called from in process(). only calls process_request(), but can be overwritten for children with special behaviour
-/datum/component/plumbing/proc/send_request(dir)
- process_request(amount = MACHINE_REAGENT_TRANSFER, reagent = null, dir = dir)
-///check who can give us what we want, and how many each of them will give us
-/datum/component/plumbing/proc/process_request(amount, reagent, dir)
- var/list/valid_suppliers = list()
- var/datum/ductnet/net
- if(!ducts.Find(num2text(dir)))
- return
- net = ducts[num2text(dir)]
- for(var/A in net.suppliers)
- var/datum/component/plumbing/supplier = A
- if(supplier.can_give(amount, reagent, net))
- valid_suppliers += supplier
- for(var/A in valid_suppliers)
- var/datum/component/plumbing/give = A
- give.transfer_to(src, amount / valid_suppliers.len, reagent, net)
-///returns TRUE when they can give the specified amount and reagent. called by process request
-/datum/component/plumbing/proc/can_give(amount, reagent, datum/ductnet/net)
- if(amount <= 0)
- return
-
- if(reagent) //only asked for one type of reagent
- for(var/A in reagents.reagent_list)
- var/datum/reagent/R = A
- if(R.type == reagent)
- return TRUE
- else if(reagents.total_volume > 0) //take whatever
- return TRUE
-///this is where the reagent is actually transferred and is thus the finish point of our process()
-/datum/component/plumbing/proc/transfer_to(datum/component/plumbing/target, amount, reagent, datum/ductnet/net)
- if(!reagents || !target || !target.reagents)
- return FALSE
- if(reagent)
- reagents.trans_id_to(target.parent, reagent, amount)
- else
- reagents.trans_to(target.parent, amount)
-///We create our luxurious piping overlays/underlays, to indicate where we do what. only called once if use_overlays = TRUE in Initialize()
-/datum/component/plumbing/proc/create_overlays()
- var/atom/movable/AM = parent
- for(var/image/I in ducterlays)
- AM.overlays.Remove(I)
- qdel(I)
- ducterlays = list()
- for(var/D in GLOB.cardinals)
- var/color
- var/direction
- if(D & demand_connects)
- color = "red" //red because red is mean and it takes
- else if(D & supply_connects)
- color = "blue" //blue is nice and gives
- else
- continue
- var/image/I
- if(turn_connects)
- switch(D)
- if(NORTH)
- direction = "north"
- if(SOUTH)
- direction = "south"
- if(EAST)
- direction = "east"
- if(WEST)
- direction = "west"
- I = image('icons/obj/plumbing/plumbers.dmi', "[direction]-[color]", layer = AM.layer - 1)
- else
- I = image('icons/obj/plumbing/plumbers.dmi', color, layer = AM.layer - 1) //color is not color as in the var, it's just the name
- I.dir = D
- AM.add_overlay(I)
- ducterlays += I
-///we stop acting like a plumbing thing and disconnect if we are, so we can safely be moved and stuff
-/datum/component/plumbing/proc/disable()
- if(!active)
- return
- STOP_PROCESSING(SSfluids, src)
- for(var/A in ducts)
- var/datum/ductnet/D = ducts[A]
- D.remove_plumber(src)
- active = FALSE
- for(var/D in GLOB.cardinals)
- if(D & (demand_connects | supply_connects))
- for(var/obj/machinery/duct/duct in get_step(parent, D))
- duct.attempt_connect()
-
-///settle wherever we are, and start behaving like a piece of plumbing
-/datum/component/plumbing/proc/enable()
- if(active)
- return
- update_dir()
- active = TRUE
-
- if(demand_connects)
- START_PROCESSING(SSfluids, src)
- for(var/D in GLOB.cardinals)
- if(D & (demand_connects | supply_connects))
- for(var/obj/machinery/duct/duct in get_step(parent, D))
- duct.attempt_connect()
-
- //TODO: Let plumbers directly plumb into one another without ducts if placed adjacent to each other
-
-/// Toggle our machinery on or off. This is called by a hook from default_unfasten_wrench with anchored as only param, so we dont have to copypaste this on every object that can move
-/datum/component/plumbing/proc/toggle_active(obj/O, new_state)
- if(new_state)
- enable()
- else
- disable()
-/** We update our connects only when we settle down by taking our current and original direction to find our new connects
-* If someone wants it to fucking spin while connected to something go actually knock yourself out
-*/
-/datum/component/plumbing/proc/update_dir()
- if(!turn_connects)
- return
- var/atom/movable/AM = parent
- var/new_demand_connects
- var/new_supply_connects
- var/new_dir = AM.dir
- var/angle = 180 - dir2angle(new_dir)
- if(new_dir == SOUTH)
- demand_connects = initial(demand_connects)
- supply_connects = initial(supply_connects)
- else
- for(var/D in GLOB.cardinals)
- if(D & initial(demand_connects))
- new_demand_connects += turn(D, angle)
- if(D & initial(supply_connects))
- new_supply_connects += turn(D, angle)
- demand_connects = new_demand_connects
- supply_connects = new_supply_connects
-///Give the direction of a pipe, and it'll return wich direction it originally was when it's object pointed SOUTH
-/datum/component/plumbing/proc/get_original_direction(dir)
- var/atom/movable/AM = parent
- return turn(dir, dir2angle(AM.dir) - 180)
-
-///has one pipe input that only takes, example is manual output pipe
-/datum/component/plumbing/simple_demand
- demand_connects = NORTH
-///has one pipe output that only supplies. example is liquid pump and manual input pipe
-/datum/component/plumbing/simple_supply
- supply_connects = NORTH
-///input and output, like a holding tank
-/datum/component/plumbing/tank
- demand_connects = WEST
- supply_connects = EAST
diff --git a/code/datums/components/plumbing/acclimator.dm b/code/datums/components/plumbing/acclimator.dm
deleted file mode 100644
index 239ae652238..00000000000
--- a/code/datums/components/plumbing/acclimator.dm
+++ /dev/null
@@ -1,18 +0,0 @@
-/datum/component/plumbing/acclimator
- demand_connects = WEST
- supply_connects = EAST
-
-/datum/component/plumbing/acclimator/Initialize(start=TRUE, _turn_connects=TRUE)
- . = ..()
- if(. && istype(parent, /obj/machinery/plumbing/acclimator))
- return TRUE
-
-/datum/component/plumbing/acclimator/can_give(amount, reagent)
- . = ..()
- if(.)
- var/obj/machinery/plumbing/acclimator/AC = parent
- if(AC.reagents.chem_temp >= AC.target_temperature && AC.target_temperature + AC.allowed_temperature_difference >= AC.reagents.chem_temp) //cooling here
- return TRUE
- if(AC.reagents.chem_temp <= AC.target_temperature && AC.target_temperature - AC.allowed_temperature_difference <= AC.reagents.chem_temp) //heating here
- return TRUE
- return FALSE
diff --git a/code/datums/components/plumbing/chemical_acclimator.dm b/code/datums/components/plumbing/chemical_acclimator.dm
deleted file mode 100644
index 239ae652238..00000000000
--- a/code/datums/components/plumbing/chemical_acclimator.dm
+++ /dev/null
@@ -1,18 +0,0 @@
-/datum/component/plumbing/acclimator
- demand_connects = WEST
- supply_connects = EAST
-
-/datum/component/plumbing/acclimator/Initialize(start=TRUE, _turn_connects=TRUE)
- . = ..()
- if(. && istype(parent, /obj/machinery/plumbing/acclimator))
- return TRUE
-
-/datum/component/plumbing/acclimator/can_give(amount, reagent)
- . = ..()
- if(.)
- var/obj/machinery/plumbing/acclimator/AC = parent
- if(AC.reagents.chem_temp >= AC.target_temperature && AC.target_temperature + AC.allowed_temperature_difference >= AC.reagents.chem_temp) //cooling here
- return TRUE
- if(AC.reagents.chem_temp <= AC.target_temperature && AC.target_temperature - AC.allowed_temperature_difference <= AC.reagents.chem_temp) //heating here
- return TRUE
- return FALSE
diff --git a/code/datums/components/plumbing/filter.dm b/code/datums/components/plumbing/filter.dm
deleted file mode 100644
index c1af5c5e0eb..00000000000
--- a/code/datums/components/plumbing/filter.dm
+++ /dev/null
@@ -1,59 +0,0 @@
-///The magical plumbing component used by the chemical filters. The different supply connects behave differently depending on the filters set on the chemical filter
-/datum/component/plumbing/filter
- demand_connects = NORTH
- supply_connects = SOUTH | EAST | WEST //SOUTH is straight, EAST is left and WEST is right. We look from the perspective of the insert
-
-/datum/component/plumbing/filter/Initialize()
- . = ..()
- if(!istype(parent, /obj/machinery/plumbing/filter))
- return COMPONENT_INCOMPATIBLE
-
-/datum/component/plumbing/filter/can_give(amount, reagent, datum/ductnet/net)
- . = ..()
- if(.)
- var/direction
- for(var/A in ducts)
- if(ducts[A] == net)
- direction = get_original_direction(text2num(A)) //we need it relative to the direction, so filters don't change when we turn the filter
- break
- if(!direction)
- return FALSE
- if(reagent)
- if(!can_give_in_direction(direction, reagent))
- return FALSE
-
-/datum/component/plumbing/filter/transfer_to(datum/component/plumbing/target, amount, reagent, datum/ductnet/net)
- if(!reagents || !target || !target.reagents)
- return FALSE
- var/direction
- for(var/A in ducts)
- if(ducts[A] == net)
- direction = get_original_direction(text2num(A))
- break
- if(reagent)
- reagents.trans_id_to(target.reagents, reagent, amount)
- else
- for(var/A in reagents.reagent_list)
- var/datum/reagent/R = A
- if(!can_give_in_direction(direction, R.type))
- continue
- var/new_amount
- if(R.volume < amount)
- new_amount = amount - R.volume
- reagents.trans_id_to(target.parent, R.type, amount)
- amount = new_amount
- if(amount <= 0)
- break
-///We check if the direction and reagent are valid to give. Needed for filters since different outputs have different behaviours
-/datum/component/plumbing/filter/proc/can_give_in_direction(dir, reagent)
- var/obj/machinery/plumbing/filter/F = parent
- switch(dir)
- if(SOUTH) //straight
- if(!F.left.Find(reagent) && !F.right.Find(reagent))
- return TRUE
- if(WEST) //right
- if(F.right.Find(reagent))
- return TRUE
- if(EAST) //left
- if(F.left.Find(reagent))
- return TRUE
diff --git a/code/datums/components/plumbing/reaction_chamber.dm b/code/datums/components/plumbing/reaction_chamber.dm
deleted file mode 100644
index 8caf8a6b091..00000000000
--- a/code/datums/components/plumbing/reaction_chamber.dm
+++ /dev/null
@@ -1,43 +0,0 @@
-/datum/component/plumbing/reaction_chamber
- demand_connects = WEST
- supply_connects = EAST
-
-/datum/component/plumbing/reaction_chamber/Initialize(start=TRUE, _turn_connects=TRUE)
- . = ..()
- if(!istype(parent, /obj/machinery/plumbing/reaction_chamber))
- return COMPONENT_INCOMPATIBLE
-
-/datum/component/plumbing/reaction_chamber/can_give(amount, reagent)
- . = ..()
- var/obj/machinery/plumbing/reaction_chamber/RC = parent
- if(!. || !RC.emptying)
- return FALSE
-
-/datum/component/plumbing/reaction_chamber/send_request(dir)
- var/obj/machinery/plumbing/reaction_chamber/RC = parent
- if(RC.emptying || !LAZYLEN(RC.required_reagents))
- return
- for(var/RT in RC.required_reagents)
- var/has_reagent = FALSE
- for(var/A in reagents.reagent_list)
- var/datum/reagent/RD = A
- if(RT == RD.type)
- has_reagent = TRUE
- if(RD.volume < RC.required_reagents[RT])
- process_request(min(RC.required_reagents[RT] - RD.volume, MACHINE_REAGENT_TRANSFER) , RT, dir)
- return
- if(!has_reagent)
- process_request(min(RC.required_reagents[RT], MACHINE_REAGENT_TRANSFER), RT, dir)
- return
- reagents.flags &= ~NO_REACT
- RC.emptying = TRUE
-
-/datum/component/plumbing/reaction_chamber/can_give(amount, reagent, datum/ductnet/net)
- . = ..()
- var/obj/machinery/plumbing/reaction_chamber/RC = parent
- if(!. || !RC.emptying)
- return FALSE
-
-
-
-
diff --git a/code/datums/components/plumbing/splitter.dm b/code/datums/components/plumbing/splitter.dm
deleted file mode 100644
index c4c322c2ab3..00000000000
--- a/code/datums/components/plumbing/splitter.dm
+++ /dev/null
@@ -1,47 +0,0 @@
-/datum/component/plumbing/splitter
- demand_connects = NORTH
- supply_connects = SOUTH | EAST
-
-/datum/component/plumbing/splitter/Initialize()
- . = ..()
- if(. && !istype(parent, /obj/machinery/plumbing/splitter))
- return FALSE
-
-/datum/component/plumbing/splitter/can_give(amount, reagent, datum/ductnet/net)
- . = ..()
- if(!.)
- return
- . = FALSE
- var/direction
- for(var/A in ducts)
- if(ducts[A] == net)
- direction = get_original_direction(text2num(A))
- break
- var/obj/machinery/plumbing/splitter/S = parent
- switch(direction)
- if(SOUTH)
- if(S.turn_straight && S.transfer_straight <= amount)
- S.turn_straight = FALSE
- return TRUE
- if(EAST)
- if(!S.turn_straight && S.transfer_side <= amount)
- S.turn_straight = FALSE
- return TRUE
-
-/datum/component/plumbing/splitter/transfer_to(datum/component/plumbing/target, amount, reagent, datum/ductnet/net)
- var/direction
- for(var/A in ducts)
- if(ducts[A] == net)
- direction = get_original_direction(text2num(A))
- break
- var/obj/machinery/plumbing/splitter/S = parent
- switch(direction)
- if(SOUTH)
- if(amount >= S.transfer_straight)
- amount = S.transfer_straight
- if(EAST)
- if(amount >= S.transfer_side)
- amount = S.transfer_side
- . = ..()
-
-
diff --git a/code/datums/components/punchcooldown.dm b/code/datums/components/punchcooldown.dm
deleted file mode 100644
index d42a8fd00dc..00000000000
--- a/code/datums/components/punchcooldown.dm
+++ /dev/null
@@ -1,29 +0,0 @@
-///Your favourite Jojoke. Used for the gloves of the north star.
-/datum/component/wearertargeting/punchcooldown
- signals = list(COMSIG_HUMAN_MELEE_UNARMED_ATTACK)
- mobtype = /mob/living/carbon
- proctype = .proc/reducecooldown
- valid_slots = list(SLOT_GLOVES)
- ///The warcry this generates
- var/warcry = "AT"
-
-/datum/component/wearertargeting/punchcooldown/Initialize()
- . = ..()
- if(. == COMPONENT_INCOMPATIBLE)
- return
- RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/changewarcry)
-
-///Called on COMSIG_HUMAN_MELEE_UNARMED_ATTACK. Yells the warcry and and reduces punch cooldown.
-/datum/component/wearertargeting/punchcooldown/proc/reducecooldown(mob/living/carbon/M, atom/target)
- if(M.a_intent == INTENT_HARM && isliving(target))
- M.changeNext_move(CLICK_CD_RAPID)
- if(warcry)
- M.say(warcry, ignore_spam = TRUE, forced = "north star warcry")
-
-///Called on COMSIG_ITEM_ATTACK_SELF. Allows you to change the warcry.
-/datum/component/wearertargeting/punchcooldown/proc/changewarcry(datum/source, mob/user)
- var/input = stripped_input(user,"What do you want your battlecry to be? Max length of 6 characters.", ,"", 7)
- if(!QDELETED(src) && !QDELETED(user) && !user.Adjacent(parent))
- return
- if(input)
- warcry = input
diff --git a/code/datums/components/remote_materials.dm b/code/datums/components/remote_materials.dm
deleted file mode 100644
index 7d6fdd85a8d..00000000000
--- a/code/datums/components/remote_materials.dm
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
-This component allows machines to connect remotely to a material container
-(namely an /obj/machinery/ore_silo) elsewhere. It offers optional graceful
-fallback to a local material storage in case remote storage is unavailable, and
-handles linking back and forth.
-*/
-
-/datum/component/remote_materials
- // Three possible states:
- // 1. silo exists, materials is parented to silo
- // 2. silo is null, materials is parented to parent
- // 3. silo is null, materials is null
- var/obj/machinery/ore_silo/silo
- var/datum/component/material_container/mat_container
- var/category
- var/allow_standalone
- var/local_size = INFINITY
-
-/datum/component/remote_materials/Initialize(category, mapload, allow_standalone = TRUE, force_connect = FALSE)
- if (!isatom(parent))
- return COMPONENT_INCOMPATIBLE
-
- src.category = category
- src.allow_standalone = allow_standalone
-
- RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
- RegisterSignal(parent, COMSIG_ATOM_MULTITOOL_ACT, .proc/OnMultitool)
-
- var/turf/T = get_turf(parent)
- if (force_connect || (mapload && is_station_level(T.z)))
- addtimer(CALLBACK(src, .proc/LateInitialize))
- else if (allow_standalone)
- _MakeLocal()
-
-/datum/component/remote_materials/proc/LateInitialize()
- silo = GLOB.ore_silo_default
- if (silo)
- silo.connected += src
- mat_container = silo.GetComponent(/datum/component/material_container)
- else
- _MakeLocal()
-
-/datum/component/remote_materials/Destroy()
- if (silo)
- silo.connected -= src
- silo.updateUsrDialog()
- silo = null
- mat_container = null
- else if (mat_container)
- // specify explicitly in case the other component is deleted first
- var/atom/P = parent
- mat_container.retrieve_all(P.drop_location())
- return ..()
-
-/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)
-
-/datum/component/remote_materials/proc/set_local_size(size)
- local_size = size
- if (!silo && mat_container)
- mat_container.max_amount = size
-
-// called if disconnected by ore silo UI or destruction
-/datum/component/remote_materials/proc/disconnect_from(obj/machinery/ore_silo/old_silo)
- if (!old_silo || silo != old_silo)
- return
- silo = null
- mat_container = null
- if (allow_standalone)
- _MakeLocal()
-
-/datum/component/remote_materials/proc/OnAttackBy(datum/source, obj/item/I, mob/user)
- if (silo && istype(I, /obj/item/stack))
- if (silo.remote_attackby(parent, user, I))
- return COMPONENT_NO_AFTERATTACK
-
-/datum/component/remote_materials/proc/OnMultitool(datum/source, mob/user, obj/item/I)
- if(!I.multitool_check_buffer(user, I))
- return COMPONENT_BLOCK_TOOL_ATTACK
- var/obj/item/multitool/M = I
- if (!QDELETED(M.buffer) && istype(M.buffer, /obj/machinery/ore_silo))
- if (silo == M.buffer)
- to_chat(user, "[parent] is already connected to [silo].")
- return COMPONENT_BLOCK_TOOL_ATTACK
- if (silo)
- silo.connected -= src
- silo.updateUsrDialog()
- else if (mat_container)
- mat_container.retrieve_all()
- qdel(mat_container)
- silo = M.buffer
- silo.connected += src
- silo.updateUsrDialog()
- mat_container = silo.GetComponent(/datum/component/material_container)
- to_chat(user, "You connect [parent] to [silo] from the multitool's buffer.")
- return COMPONENT_BLOCK_TOOL_ATTACK
-
-/datum/component/remote_materials/proc/on_hold()
- return silo && silo.holds["[get_area(parent)]/[category]"]
-
-/datum/component/remote_materials/proc/silo_log(obj/machinery/M, action, amount, noun, list/mats)
- if (silo)
- silo.silo_log(M || parent, action, amount, noun, mats)
-
-/datum/component/remote_materials/proc/format_amount()
- if (mat_container)
- return "[mat_container.total_amount] / [mat_container.max_amount == INFINITY ? "Unlimited" : mat_container.max_amount] ([silo ? "remote" : "local"])"
- else
- return "0 / 0"
diff --git a/code/datums/components/rot.dm b/code/datums/components/rot.dm
deleted file mode 100644
index 0f92ddf1e33..00000000000
--- a/code/datums/components/rot.dm
+++ /dev/null
@@ -1,60 +0,0 @@
-/datum/component/rot
- var/amount = 1
-
-/datum/component/rot/Initialize(new_amount)
- if(!isatom(parent))
- return COMPONENT_INCOMPATIBLE
-
- if(new_amount)
- amount = new_amount
-
- START_PROCESSING(SSprocessing, src)
-
-/datum/component/rot/process(delta_time)
- var/atom/A = parent
-
- var/turf/open/T = get_turf(A)
- if(!istype(T) || T.return_air().return_pressure() > (WARNING_HIGH_PRESSURE - 10))
- return
-
- var/datum/gas_mixture/stank = new
- ADD_GAS(/datum/gas/miasma, stank.gases)
- stank.gases[/datum/gas/miasma][MOLES] = amount
- stank.temperature = BODYTEMP_NORMAL // otherwise we have gas below 2.7K which will break our lag generator
- T.assume_air(stank)
- T.air_update_turf()
-
-/datum/component/rot/corpse
- amount = MIASMA_CORPSE_MOLES
-
-/datum/component/rot/corpse/Initialize()
- if(!iscarbon(parent))
- return COMPONENT_INCOMPATIBLE
- . = ..()
-
-/datum/component/rot/corpse/process(delta_time)
- var/mob/living/carbon/C = parent
- if(C.stat != DEAD)
- qdel(src)
- return
-
- // Wait a bit before decaying
- if(world.time - C.timeofdeath < 2 MINUTES)
- return
-
- // Properly stored corpses shouldn't create miasma
- if(istype(C.loc, /obj/structure/closet/crate/coffin)|| istype(C.loc, /obj/structure/closet/body_bag) || istype(C.loc, /obj/structure/bodycontainer))
- return
-
- // No decay if formaldehyde in corpse or when the corpse is charred
- if(C.reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 15) || HAS_TRAIT(C, TRAIT_HUSK))
- return
-
- // Also no decay if corpse chilled or not organic/undead
- if(C.bodytemperature <= T0C-10 || !(C.mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD)))
- return
-
- ..()
-
-/datum/component/rot/gibs
- amount = MIASMA_GIBS_MOLES
diff --git a/code/datums/components/rotation.dm b/code/datums/components/rotation.dm
deleted file mode 100644
index d8734226dfa..00000000000
--- a/code/datums/components/rotation.dm
+++ /dev/null
@@ -1,163 +0,0 @@
-#define ROTATION_ALTCLICK (1<<0)
-#define ROTATION_WRENCH (1<<1)
-#define ROTATION_VERBS (1<<2)
-#define ROTATION_COUNTERCLOCKWISE (1<<3)
-#define ROTATION_CLOCKWISE (1<<4)
-#define ROTATION_FLIP (1<<5)
-
-/datum/component/simple_rotation
- var/datum/callback/can_user_rotate //Checks if user can rotate
- var/datum/callback/can_be_rotated //Check if object can be rotated at all
- var/datum/callback/after_rotation //Additional stuff to do after rotation
-
- var/rotation_flags = NONE
- var/default_rotation_direction = ROTATION_CLOCKWISE
-
-/datum/component/simple_rotation/Initialize(rotation_flags = NONE ,can_user_rotate,can_be_rotated,after_rotation)
- if(!ismovable(parent))
- return COMPONENT_INCOMPATIBLE
-
- //throw if no rotation direction is specificed ?
-
- src.rotation_flags = rotation_flags
-
- if(can_user_rotate)
- src.can_user_rotate = can_user_rotate
- else
- src.can_user_rotate = CALLBACK(src,.proc/default_can_user_rotate)
-
- if(can_be_rotated)
- src.can_be_rotated = can_be_rotated
- else
- src.can_be_rotated = CALLBACK(src,.proc/default_can_be_rotated)
-
- if(after_rotation)
- src.after_rotation = after_rotation
- else
- src.after_rotation = CALLBACK(src,.proc/default_after_rotation)
-
- //Try Clockwise,counter,flip in order
- if(src.rotation_flags & ROTATION_FLIP)
- default_rotation_direction = ROTATION_FLIP
- if(src.rotation_flags & ROTATION_COUNTERCLOCKWISE)
- default_rotation_direction = ROTATION_COUNTERCLOCKWISE
- if(src.rotation_flags & ROTATION_CLOCKWISE)
- default_rotation_direction = ROTATION_CLOCKWISE
-
-/datum/component/simple_rotation/proc/add_signals()
- if(rotation_flags & ROTATION_ALTCLICK)
- RegisterSignal(parent, COMSIG_CLICK_ALT, .proc/HandRot)
- RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/ExamineMessage)
- if(rotation_flags & ROTATION_WRENCH)
- RegisterSignal(parent, COMSIG_ATOM_WRENCH_ACT, .proc/WrenchRot)
-
-/datum/component/simple_rotation/proc/add_verbs()
- if(rotation_flags & ROTATION_VERBS)
- var/atom/movable/AM = parent
- if(rotation_flags & ROTATION_FLIP)
- add_obj_verb(AM, /atom/movable/proc/simple_rotate_flip)
- if(src.rotation_flags & ROTATION_CLOCKWISE)
- add_obj_verb(AM, /atom/movable/proc/simple_rotate_clockwise)
- if(src.rotation_flags & ROTATION_COUNTERCLOCKWISE)
- add_obj_verb(AM, /atom/movable/proc/simple_rotate_counterclockwise)
-
-/datum/component/simple_rotation/proc/remove_verbs()
- if(parent)
- var/atom/movable/AM = parent
- remove_obj_verb(AM, /atom/movable/proc/simple_rotate_flip)
- remove_obj_verb(AM, /atom/movable/proc/simple_rotate_clockwise)
- remove_obj_verb(AM, /atom/movable/proc/simple_rotate_counterclockwise)
-
-/datum/component/simple_rotation/proc/remove_signals()
- UnregisterSignal(parent, list(COMSIG_CLICK_ALT, COMSIG_PARENT_EXAMINE, COMSIG_PARENT_ATTACKBY))
-
-/datum/component/simple_rotation/RegisterWithParent()
- add_verbs()
- add_signals()
- . = ..()
-
-/datum/component/simple_rotation/PostTransfer()
- //Because of the callbacks which we don't track cleanly we can't transfer this
- //item cleanly, better to let the new of the new item create a new rotation datum
- //instead (there's no real state worth transferring)
- return COMPONENT_NOTRANSFER
-
-/datum/component/simple_rotation/UnregisterFromParent()
- remove_verbs()
- remove_signals()
- . = ..()
-
-/datum/component/simple_rotation/Destroy()
- QDEL_NULL(can_user_rotate)
- QDEL_NULL(can_be_rotated)
- QDEL_NULL(after_rotation)
- //Signals + verbs removed via UnRegister
- . = ..()
-
-/datum/component/simple_rotation/RemoveComponent()
- remove_verbs()
- . = ..()
-
-/datum/component/simple_rotation/proc/ExamineMessage(datum/source, mob/user, list/examine_list)
- if(rotation_flags & ROTATION_ALTCLICK)
- examine_list += "Alt-click to rotate it clockwise."
-
-/datum/component/simple_rotation/proc/HandRot(datum/source, mob/user, rotation = default_rotation_direction)
- if(!can_be_rotated.Invoke(user, rotation) || !can_user_rotate.Invoke(user, rotation))
- return
- BaseRot(user, rotation)
-
-/datum/component/simple_rotation/proc/WrenchRot(datum/source, obj/item/I, mob/living/user)
- if(!can_be_rotated.Invoke(user,default_rotation_direction) || !can_user_rotate.Invoke(user,default_rotation_direction))
- return
- BaseRot(user,default_rotation_direction)
- return COMPONENT_BLOCK_TOOL_ATTACK
-
-/datum/component/simple_rotation/proc/BaseRot(mob/user,rotation_type)
- var/atom/movable/AM = parent
- var/rot_degree
- switch(rotation_type)
- if(ROTATION_CLOCKWISE)
- rot_degree = -90
- if(ROTATION_COUNTERCLOCKWISE)
- rot_degree = 90
- if(ROTATION_FLIP)
- rot_degree = 180
- AM.setDir(turn(AM.dir,rot_degree))
- after_rotation.Invoke(user,rotation_type)
-
-/datum/component/simple_rotation/proc/default_can_user_rotate(mob/living/user, rotation_type)
- if(!istype(user) || !user.canUseTopic(parent, BE_CLOSE, NO_DEXTERY))
- return FALSE
- return TRUE
-
-/datum/component/simple_rotation/proc/default_can_be_rotated(mob/user, rotation_type)
- var/atom/movable/AM = parent
- return !AM.anchored
-
-/datum/component/simple_rotation/proc/default_after_rotation(mob/user, rotation_type)
- to_chat(user,"You [rotation_type == ROTATION_FLIP ? "flip" : "rotate"] [parent].")
-
-/atom/movable/proc/simple_rotate_clockwise()
- set name = "Rotate Clockwise"
- set category = "Object"
- set src in oview(1)
- var/datum/component/simple_rotation/rotcomp = GetComponent(/datum/component/simple_rotation)
- if(rotcomp)
- rotcomp.HandRot(null,usr,ROTATION_CLOCKWISE)
-
-/atom/movable/proc/simple_rotate_counterclockwise()
- set name = "Rotate Counter-Clockwise"
- set category = "Object"
- set src in oview(1)
- var/datum/component/simple_rotation/rotcomp = GetComponent(/datum/component/simple_rotation)
- if(rotcomp)
- rotcomp.HandRot(null,usr,ROTATION_COUNTERCLOCKWISE)
-
-/atom/movable/proc/simple_rotate_flip()
- set name = "Flip"
- set category = "Object"
- set src in oview(1)
- var/datum/component/simple_rotation/rotcomp = GetComponent(/datum/component/simple_rotation)
- if(rotcomp)
- rotcomp.HandRot(null,usr,ROTATION_FLIP)
diff --git a/code/datums/components/shrapnel.dm b/code/datums/components/shrapnel.dm
deleted file mode 100644
index f549fbbb342..00000000000
--- a/code/datums/components/shrapnel.dm
+++ /dev/null
@@ -1,38 +0,0 @@
-/datum/component/shrapnel
- var/projectile_type
- var/radius // shoots a projectile for every turf on this radius from the hit target
- var/override_projectile_range
-
-/datum/component/shrapnel/Initialize(projectile_type, radius=1, override_projectile_range)
- if(!isgun(parent) && !ismachinery(parent) && !isstructure(parent))
- return COMPONENT_INCOMPATIBLE
-
- src.projectile_type = projectile_type
- src.radius = radius
- src.override_projectile_range = override_projectile_range
-
-/datum/component/shrapnel/RegisterWithParent()
- if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc
- RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit)
-
-/datum/component/shrapnel/UnregisterFromParent()
- UnregisterSignal(parent, list(COMSIG_PROJECTILE_ON_HIT))
-
-/datum/component/shrapnel/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle)
- do_shrapnel(firer, target)
-
-/datum/component/shrapnel/proc/do_shrapnel(mob/firer, atom/target)
- if(radius < 1)
- return
- var/turf/target_turf = get_turf(target)
- for(var/turf/shootat_turf in RANGE_TURFS(radius, target) - RANGE_TURFS(radius-1, target))
- var/obj/projectile/P = new projectile_type(target_turf)
-
- //Shooting Code:
- P.range = radius+1
- if(override_projectile_range)
- P.range = override_projectile_range
- P.preparePixelProjectile(shootat_turf, target)
- P.firer = firer // don't hit ourself that would be really annoying
- P.permutated += target // don't hit the target we hit already with the flak
- P.fire()
diff --git a/code/datums/components/shrink.dm b/code/datums/components/shrink.dm
deleted file mode 100644
index e9e5a1c659a..00000000000
--- a/code/datums/components/shrink.dm
+++ /dev/null
@@ -1,42 +0,0 @@
-/datum/component/shrink
- var/olddens
- var/oldopac
- dupe_mode = COMPONENT_DUPE_HIGHLANDER
-
-/datum/component/shrink/Initialize(shrink_time)
- if(!isatom(parent))
- return COMPONENT_INCOMPATIBLE
- var/atom/parent_atom = parent
- parent_atom.transform = parent_atom.transform.Scale(0.5,0.5)
- olddens = parent_atom.density
- oldopac = parent_atom.opacity
- parent_atom.density = 0
- parent_atom.opacity = 0
- if(isliving(parent_atom))
- var/mob/living/L = parent_atom
- L.add_movespeed_modifier(MOVESPEED_ID_SHRINK_RAY, update=TRUE, priority=100, multiplicative_slowdown=4, movement_type=MOVEMENT_GROUND)
- if(iscarbon(L))
- var/mob/living/carbon/C = L
- C.unequip_everything()
- C.visible_message("[C]'s belongings fall off of [C.p_them()] as they shrink down!",
- "Your belongings fall away as everything grows bigger!")
- if(ishuman(C))
- var/mob/living/carbon/human/H = C
- H.physiology.damage_resistance -= 100//carbons take double damage while shrunk
- parent_atom.visible_message("[parent_atom] shrinks down to a tiny size!",
- "Everything grows bigger!")
- QDEL_IN(src, shrink_time)
-
-
-/datum/component/shrink/Destroy()
- var/atom/parent_atom = parent
- parent_atom.transform = parent_atom.transform.Scale(2,2)
- parent_atom.density = olddens
- parent_atom.opacity = oldopac
- if(isliving(parent_atom))
- var/mob/living/L = parent_atom
- L.remove_movespeed_modifier(MOVESPEED_ID_SHRINK_RAY)
- if(ishuman(L))
- var/mob/living/carbon/human/H = L
- H.physiology.damage_resistance += 100
- ..()
diff --git a/code/datums/components/slippery.dm b/code/datums/components/slippery.dm
deleted file mode 100644
index 172f252d5af..00000000000
--- a/code/datums/components/slippery.dm
+++ /dev/null
@@ -1,19 +0,0 @@
-/datum/component/slippery
- var/force_drop_items = FALSE
- var/knockdown_time = 0
- var/paralyze_time = 0
- var/lube_flags
- var/datum/callback/callback
-
-/datum/component/slippery/Initialize(_knockdown, _lube_flags = NONE, datum/callback/_callback, _paralyze, _force_drop = FALSE)
- knockdown_time = max(_knockdown, 0)
- paralyze_time = max(_paralyze, 0)
- force_drop_items = _force_drop
- lube_flags = _lube_flags
- callback = _callback
- RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Slip)
-
-/datum/component/slippery/proc/Slip(datum/source, atom/movable/AM)
- var/mob/victim = AM
- if(istype(victim) && !victim.is_flying() && victim.slip(knockdown_time, parent, lube_flags, paralyze_time, force_drop_items) && callback)
- callback.Invoke(victim)
diff --git a/code/datums/components/spawner.dm b/code/datums/components/spawner.dm
deleted file mode 100644
index a89000626f0..00000000000
--- a/code/datums/components/spawner.dm
+++ /dev/null
@@ -1,51 +0,0 @@
-/datum/component/spawner
- var/mob_types = list(/mob/living/simple_animal/hostile/carp)
- var/spawn_time = 300 //30 seconds default
- var/list/spawned_mobs = list()
- var/spawn_delay = 0
- var/max_mobs = 5
- var/spawn_text = "emerges from"
- var/list/faction = list("mining")
-
-
-
-/datum/component/spawner/Initialize(_mob_types, _spawn_time, _faction, _spawn_text, _max_mobs)
- if(_spawn_time)
- spawn_time=_spawn_time
- if(_mob_types)
- mob_types=_mob_types
- if(_faction)
- faction=_faction
- if(_spawn_text)
- spawn_text=_spawn_text
- if(_max_mobs)
- max_mobs=_max_mobs
-
- RegisterSignal(parent, list(COMSIG_PARENT_QDELETING), .proc/stop_spawning)
- START_PROCESSING(SSprocessing, src)
-
-/datum/component/spawner/process(delta_time)
- try_spawn_mob()
-
-
-/datum/component/spawner/proc/stop_spawning(force)
- STOP_PROCESSING(SSprocessing, src)
- for(var/mob/living/simple_animal/L in spawned_mobs)
- if(L.nest == src)
- L.nest = null
- spawned_mobs = null
-
-/datum/component/spawner/proc/try_spawn_mob()
- var/atom/P = parent
- if(spawned_mobs.len >= max_mobs)
- return 0
- if(spawn_delay > world.time)
- return 0
- spawn_delay = world.time + spawn_time
- var/chosen_mob_type = pick(mob_types)
- var/mob/living/simple_animal/L = new chosen_mob_type(P.loc)
- L.flags_1 |= (P.flags_1 & ADMIN_SPAWNED_1)
- spawned_mobs += L
- L.nest = src
- L.faction = src.faction
- P.visible_message("[L] [spawn_text] [P].")
diff --git a/code/datums/components/spill.dm b/code/datums/components/spill.dm
deleted file mode 100644
index 1a9a526ec34..00000000000
--- a/code/datums/components/spill.dm
+++ /dev/null
@@ -1,57 +0,0 @@
-// This component is for forcing strange things into your pocket that fall out if you fall down
-// Yes this exists purely for the spaghetti meme
-
-/datum/component/spill
- can_transfer = TRUE
- var/preexisting_item_flags
-
- var/list/droptext
- var/list/dropsound
-
-// droptext is an arglist for visible_message
-// dropsound is a list of potential sounds that gets picked from
-/datum/component/spill/Initialize(list/_droptext, list/_dropsound)
- if(!isitem(parent))
- return COMPONENT_INCOMPATIBLE
-
- if(_droptext && !islist(_droptext))
- _droptext = list(_droptext)
- droptext = _droptext
-
- if(_dropsound && !islist(_dropsound))
- _dropsound = list(_dropsound)
- dropsound = _dropsound
-
-/datum/component/spill/PostTransfer()
- if(!isitem(parent))
- return COMPONENT_INCOMPATIBLE
-
-/datum/component/spill/RegisterWithParent()
- RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/equip_react)
- RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/drop_react)
- var/obj/item/master = parent
- preexisting_item_flags = master.item_flags
- master.item_flags |= ITEM_SLOT_POCKET
-
-/datum/component/spill/UnregisterFromParent()
- UnregisterSignal(parent, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED))
- var/obj/item/master = parent
- if(!(preexisting_item_flags & ITEM_SLOT_POCKET))
- master.item_flags &= ~ITEM_SLOT_POCKET
-
-/datum/component/spill/proc/equip_react(obj/item/source, mob/equipper, slot)
- if(slot == SLOT_L_STORE || slot == SLOT_R_STORE)
- RegisterSignal(equipper, COMSIG_LIVING_STATUS_KNOCKDOWN, .proc/knockdown_react, TRUE)
- else
- UnregisterSignal(equipper, COMSIG_LIVING_STATUS_KNOCKDOWN)
-
-/datum/component/spill/proc/drop_react(obj/item/source, mob/dropper)
- UnregisterSignal(dropper, COMSIG_LIVING_STATUS_KNOCKDOWN)
-
-/datum/component/spill/proc/knockdown_react(mob/living/fool)
- var/obj/item/master = parent
- fool.dropItemToGround(master)
- if(droptext)
- fool.visible_message(arglist(droptext))
- if(dropsound)
- playsound(master, pick(dropsound), 30)
diff --git a/code/datums/components/spooky.dm b/code/datums/components/spooky.dm
deleted file mode 100644
index 138fa930874..00000000000
--- a/code/datums/components/spooky.dm
+++ /dev/null
@@ -1,60 +0,0 @@
-/datum/component/spooky
- var/too_spooky = TRUE //will it spawn a new instrument?
-
-/datum/component/spooky/Initialize()
- RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/spectral_attack)
-
-/datum/component/spooky/proc/spectral_attack(datum/source, mob/living/carbon/C, mob/user)
- if(ishuman(user)) //this weapon wasn't meant for mortals.
- var/mob/living/carbon/human/U = user
- if(!istype(U.dna.species, /datum/species/skeleton))
- U.adjustStaminaLoss(35) //Extra Damage
- U.Jitter(35)
- U.stuttering = 20
- if(U.getStaminaLoss() > 95)
- to_chat(U, "Your ears weren't meant for this spectral sound.")
- spectral_change(U)
- return
-
- if(ishuman(C))
- var/mob/living/carbon/human/H = C
- if(istype(H.dna.species, /datum/species/skeleton))
- return //undeads are unaffected by the spook-pocalypse.
- if(istype(H.dna.species, /datum/species/zombie))
- H.adjustStaminaLoss(25)
- H.Paralyze(15) //zombies can't resist the doot
- C.Jitter(35)
- C.stuttering = 20
- if((!istype(H.dna.species, /datum/species/skeleton)) && (!istype(H.dna.species, /datum/species/golem)) && (!istype(H.dna.species, /datum/species/android)) && (!istype(H.dna.species, /datum/species/jelly)))
- C.adjustStaminaLoss(25) //boneless humanoids don't lose the will to live
- to_chat(C, "DOOT")
- spectral_change(H)
-
- else //the sound will spook monkeys.
- C.Jitter(15)
- C.stuttering = 20
-
-/datum/component/spooky/proc/spectral_change(mob/living/carbon/human/H, mob/user)
- if((H.getStaminaLoss() > 95) && (!istype(H.dna.species, /datum/species/skeleton)) && (!istype(H.dna.species, /datum/species/golem)) && (!istype(H.dna.species, /datum/species/android)) && (!istype(H.dna.species, /datum/species/jelly)))
- H.Paralyze(20)
- H.set_species(/datum/species/skeleton)
- H.visible_message("[H] has given up on life as a mortal.")
- var/T = get_turf(H)
- if(too_spooky)
- if(prob(30))
- new/obj/item/instrument/saxophone/spectral(T)
- else if(prob(30))
- new/obj/item/instrument/trumpet/spectral(T)
- else if(prob(30))
- new/obj/item/instrument/trombone/spectral(T)
- else
- to_chat(H, "The spooky gods forgot to ship your instrument. Better luck next unlife.")
- to_chat(H, "You are the spooky skeleton!")
- to_chat(H, "A new life and identity has begun. Help your fellow skeletons into bringing out the spooky-pocalypse. You haven't forgotten your past life, and are still beholden to past loyalties.")
- change_name(H) //time for a new name!
-
-/datum/component/spooky/proc/change_name(mob/living/carbon/human/H)
- var/t = sanitize_species_name(stripped_input(H, "Enter your new skeleton name", H.real_name, null, MAX_NAME_LEN))
- if(!t)
- t = "spooky skeleton"
- H.fully_replace_character_name(null, t)
diff --git a/code/datums/components/squeak.dm b/code/datums/components/squeak.dm
deleted file mode 100644
index f09b428eb05..00000000000
--- a/code/datums/components/squeak.dm
+++ /dev/null
@@ -1,90 +0,0 @@
-/datum/component/squeak
- var/static/list/default_squeak_sounds = list('sound/items/toysqueak1.ogg'=1, 'sound/items/toysqueak2.ogg'=1, 'sound/items/toysqueak3.ogg'=1)
- var/list/override_squeak_sounds
-
- var/squeak_chance = 100
- var/volume = 30
-
- // This is so shoes don't squeak every step
- var/steps = 0
- var/step_delay = 1
-
- // This is to stop squeak spam from inhand usage
- var/last_use = 0
- var/use_delay = 20
-
-/datum/component/squeak/Initialize(custom_sounds, volume_override, chance_override, step_delay_override, use_delay_override)
- if(!isatom(parent))
- return COMPONENT_INCOMPATIBLE
- RegisterSignal(parent, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_PARENT_ATTACKBY), .proc/play_squeak)
- if(ismovable(parent))
- RegisterSignal(parent, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_IMPACT), .proc/play_squeak)
- RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/play_squeak_crossed)
- RegisterSignal(parent, COMSIG_MOVABLE_DISPOSING, .proc/disposing_react)
- if(isitem(parent))
- RegisterSignal(parent, list(COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_OBJ, COMSIG_ITEM_HIT_REACT), .proc/play_squeak)
- RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/use_squeak)
- RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
- RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
- if(istype(parent, /obj/item/clothing/shoes))
- RegisterSignal(parent, COMSIG_SHOES_STEP_ACTION, .proc/step_squeak)
-
- override_squeak_sounds = custom_sounds
- if(chance_override)
- squeak_chance = chance_override
- if(volume_override)
- volume = volume_override
- if(isnum(step_delay_override))
- step_delay = step_delay_override
- if(isnum(use_delay_override))
- use_delay = use_delay_override
-
-/datum/component/squeak/proc/play_squeak()
- if(prob(squeak_chance))
- if(!override_squeak_sounds)
- playsound(parent, pickweight(default_squeak_sounds), volume, TRUE, -1)
- else
- playsound(parent, pickweight(override_squeak_sounds), volume, TRUE, -1)
-
-/datum/component/squeak/proc/step_squeak()
- if(steps > step_delay)
- play_squeak()
- steps = 0
- else
- steps++
-
-/datum/component/squeak/proc/play_squeak_crossed(datum/source, atom/movable/AM)
- if(isitem(AM))
- var/obj/item/I = AM
- if(I.item_flags & ITEM_ABSTRACT)
- return
- else if(istype(AM, /obj/projectile))
- var/obj/projectile/P = AM
- if(P.original != parent)
- return
- if(istype(AM, /obj/effect/dummy/phased_mob)) //don't squeek if they're in a phased/jaunting container.
- return
- var/atom/current_parent = parent
- if(isturf(current_parent.loc))
- play_squeak()
-
-/datum/component/squeak/proc/use_squeak()
- if(last_use + use_delay < world.time)
- last_use = world.time
- play_squeak()
-
-/datum/component/squeak/proc/on_equip(datum/source, mob/equipper, slot)
- RegisterSignal(equipper, COMSIG_MOVABLE_DISPOSING, .proc/disposing_react, TRUE)
-
-/datum/component/squeak/proc/on_drop(datum/source, mob/user)
- UnregisterSignal(user, COMSIG_MOVABLE_DISPOSING)
-
-// Disposal pipes related shit
-/datum/component/squeak/proc/disposing_react(datum/source, obj/structure/disposalholder/holder, obj/machinery/disposal/source)
- //We don't need to worry about unregistering this signal as it will happen for us automaticaly when the holder is qdeleted
- RegisterSignal(holder, COMSIG_ATOM_DIR_CHANGE, .proc/holder_dir_change)
-
-/datum/component/squeak/proc/holder_dir_change(datum/source, old_dir, new_dir)
- //If the dir changes it means we're going through a bend in the pipes, let's pretend we bumped the wall
- if(old_dir != new_dir)
- play_squeak()
diff --git a/code/datums/components/stationloving.dm b/code/datums/components/stationloving.dm
deleted file mode 100644
index 65a4d765b88..00000000000
--- a/code/datums/components/stationloving.dm
+++ /dev/null
@@ -1,90 +0,0 @@
-/datum/component/stationloving
- dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
- var/inform_admins = FALSE
- var/disallow_soul_imbue = TRUE
- var/allow_death = FALSE
-
-/datum/component/stationloving/Initialize(inform_admins = FALSE, allow_death = FALSE)
- if(!ismovable(parent))
- return COMPONENT_INCOMPATIBLE
- RegisterSignal(parent, list(COMSIG_MOVABLE_Z_CHANGED), .proc/check_in_bounds)
- RegisterSignal(parent, list(COMSIG_MOVABLE_SECLUDED_LOCATION), .proc/relocate)
- RegisterSignal(parent, list(COMSIG_PARENT_PREQDELETED), .proc/check_deletion)
- RegisterSignal(parent, list(COMSIG_ITEM_IMBUE_SOUL), .proc/check_soul_imbue)
- RegisterSignal(parent, list(COMSIG_ITEM_MARK_RETRIEVAL), .proc/check_mark_retrieval)
- src.inform_admins = inform_admins
- 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)
- if (original)
- if (istype(newc))
- inform_admins = newc.inform_admins
- allow_death = newc.allow_death
- else if (LAZYLEN(arguments))
- inform_admins = arguments[1]
-
-/datum/component/stationloving/proc/relocate()
- var/targetturf = find_safe_turf()
- if(!targetturf)
- if(GLOB.blobstart.len > 0)
- targetturf = get_turf(pick(GLOB.blobstart))
- else
- CRASH("Unable to find a blobstart landmark")
-
- var/atom/movable/AM = parent
- AM.forceMove(targetturf)
- to_chat(get(parent, /mob), "You can't help but feel that you just lost something back there...")
- // move the disc, so ghosts remain orbiting it even if it's "destroyed"
- return targetturf
-
-/datum/component/stationloving/proc/check_in_bounds()
- if(in_bounds())
- return
- else
- var/turf/currentturf = get_turf(src)
- var/turf/targetturf = relocate()
- log_game("[parent] has been moved out of bounds in [loc_name(currentturf)]. Moving it to [loc_name(targetturf)].")
- if(inform_admins)
- message_admins("[parent] has been moved out of bounds in [ADMIN_VERBOSEJMP(currentturf)]. Moving it to [ADMIN_VERBOSEJMP(targetturf)].")
-
-/datum/component/stationloving/proc/check_soul_imbue()
- return disallow_soul_imbue
-
-/datum/component/stationloving/proc/check_mark_retrieval()
- return COMPONENT_BLOCK_MARK_RETRIEVAL
-
-/datum/component/stationloving/proc/in_bounds()
- var/static/list/allowed_shuttles = typecacheof(list(/area/shuttle/syndicate, /area/shuttle/escape, /area/shuttle/pod_1, /area/shuttle/pod_2, /area/shuttle/pod_3, /area/shuttle/pod_4))
- var/static/list/disallowed_centcom_areas = typecacheof(list(/area/abductor_ship, /area/awaymission/errorroom))
- var/turf/T = get_turf(parent)
- if (!T)
- return FALSE
- var/area/A = T.loc
- if (is_station_level(T.z))
- return TRUE
- if (is_centcom_level(T.z))
- if (is_type_in_typecache(A, disallowed_centcom_areas))
- return FALSE
- return TRUE
- if (is_reserved_level(T.z))
- if (is_type_in_typecache(A, allowed_shuttles))
- return TRUE
-
- return FALSE
-
-/datum/component/stationloving/proc/check_deletion(datum/source, force) // TRUE = interrupt deletion, FALSE = proceed with deletion
-
- var/turf/T = get_turf(parent)
-
- if(inform_admins && force)
- message_admins("[parent] has been !!force deleted!! in [ADMIN_VERBOSEJMP(T)].")
- log_game("[parent] has been !!force deleted!! in [loc_name(T)].")
-
- if(!force && !allow_death)
- var/turf/targetturf = relocate()
- log_game("[parent] has been destroyed in [loc_name(T)]. Moving it to [loc_name(targetturf)].")
- if(inform_admins)
- message_admins("[parent] has been destroyed in [ADMIN_VERBOSEJMP(T)]. Moving it to [ADMIN_VERBOSEJMP(targetturf)].")
- return TRUE
- return FALSE
diff --git a/code/datums/components/storage/concrete/_concrete.dm b/code/datums/components/storage/concrete/_concrete.dm
deleted file mode 100644
index b7f3e774d91..00000000000
--- a/code/datums/components/storage/concrete/_concrete.dm
+++ /dev/null
@@ -1,201 +0,0 @@
-
-// External storage-related logic:
-// /mob/proc/ClickOn() in /_onclick/click.dm - clicking items in storages
-// /mob/living/Move() in /modules/mob/living/living.dm - hiding storage boxes on mob movement
-
-/datum/component/storage/concrete
- can_transfer = TRUE
- var/drop_all_on_deconstruct = TRUE
- var/drop_all_on_destroy = FALSE
- var/transfer_contents_on_component_transfer = FALSE
- var/list/datum/component/storage/slaves = list()
-
- var/list/_contents_limbo // Where objects go to live mid transfer
- var/list/_user_limbo // The last users before the component started moving
-
-/datum/component/storage/concrete/Initialize()
- . = ..()
- RegisterSignal(parent, COMSIG_ATOM_CONTENTS_DEL, .proc/on_contents_del)
- RegisterSignal(parent, COMSIG_OBJ_DECONSTRUCT, .proc/on_deconstruct)
-
-/datum/component/storage/concrete/Destroy()
- var/atom/real_location = real_location()
- for(var/atom/_A in real_location)
- _A.mouse_opacity = initial(_A.mouse_opacity)
- if(drop_all_on_destroy)
- do_quick_empty()
- for(var/i in slaves)
- var/datum/component/storage/slave = i
- slave.change_master(null)
- QDEL_LIST(_contents_limbo)
- _user_limbo = null
- return ..()
-
-/datum/component/storage/concrete/master()
- return src
-
-/datum/component/storage/concrete/real_location()
- return parent
-
-/datum/component/storage/concrete/PreTransfer()
- if(is_using)
- _user_limbo = is_using.Copy()
- close_all()
- if(transfer_contents_on_component_transfer)
- _contents_limbo = list()
- for(var/atom/movable/AM in parent)
- _contents_limbo += AM
- AM.moveToNullspace()
-
-/datum/component/storage/concrete/PostTransfer()
- if(!isatom(parent))
- return COMPONENT_INCOMPATIBLE
- if(transfer_contents_on_component_transfer)
- for(var/i in _contents_limbo)
- var/atom/movable/AM = i
- AM.forceMove(parent)
- _contents_limbo = null
- if(_user_limbo)
- for(var/i in _user_limbo)
- show_to(i)
- _user_limbo = null
-
-/datum/component/storage/concrete/_insert_physical_item(obj/item/I, override = FALSE)
- . = TRUE
- var/atom/real_location = real_location()
- if(I.loc != real_location)
- I.forceMove(real_location)
- refresh_mob_views()
-
-/datum/component/storage/concrete/refresh_mob_views()
- . = ..()
- for(var/i in slaves)
- var/datum/component/storage/slave = i
- slave.refresh_mob_views()
-
-/datum/component/storage/concrete/emp_act(datum/source, severity)
- if(emp_shielded)
- return
- var/atom/real_location = real_location()
- for(var/i in real_location)
- var/atom/A = i
- A.emp_act(severity)
-
-/datum/component/storage/concrete/proc/on_slave_link(datum/component/storage/S)
- if(S == src)
- return FALSE
- slaves += S
- return TRUE
-
-/datum/component/storage/concrete/proc/on_slave_unlink(datum/component/storage/S)
- slaves -= S
- return FALSE
-
-/datum/component/storage/concrete/proc/on_contents_del(datum/source, atom/A)
- var/atom/real_location = parent
- if(A in real_location)
- usr = null
- remove_from_storage(A, null)
-
-/datum/component/storage/concrete/proc/on_deconstruct(datum/source, disassembled)
- if(drop_all_on_deconstruct)
- do_quick_empty()
-
-/datum/component/storage/concrete/can_see_contents()
- . = ..()
- for(var/i in slaves)
- var/datum/component/storage/slave = i
- . |= slave.can_see_contents()
-
-//Resets screen loc and other vars of something being removed from storage.
-/datum/component/storage/concrete/_removal_reset(atom/movable/thing)
- thing.layer = initial(thing.layer)
- thing.plane = initial(thing.plane)
- thing.mouse_opacity = initial(thing.mouse_opacity)
- if(thing.maptext)
- thing.maptext = ""
-
-/datum/component/storage/concrete/remove_from_storage(atom/movable/AM, atom/new_location)
- //Cache this as it should be reusable down the bottom, will not apply if anyone adds a sleep to dropped
- //or moving objects, things that should never happen
- var/atom/parent = src.parent
- var/list/seeing_mobs = can_see_contents()
- for(var/mob/M in seeing_mobs)
- M.client.screen -= AM
- if(ismob(parent.loc) && isitem(AM))
- var/obj/item/I = AM
- var/mob/M = parent.loc
- I.dropped(M)
- I.item_flags &= ~ITEM_IN_STORAGE
- if(new_location)
- //Reset the items values
- _removal_reset(AM)
- AM.forceMove(new_location)
- //We don't want to call this if the item is being destroyed
- AM.on_exit_storage(src)
- else
- //Being destroyed, just move to nullspace now (so it's not in contents for the icon update)
- AM.moveToNullspace()
- refresh_mob_views()
- if(isobj(parent))
- var/obj/O = parent
- O.update_icon()
- return TRUE
-
-/datum/component/storage/concrete/proc/slave_can_insert_object(datum/component/storage/slave, obj/item/I, stop_messages = FALSE, mob/M)
- return TRUE
-
-/datum/component/storage/concrete/proc/handle_item_insertion_from_slave(datum/component/storage/slave, obj/item/I, prevent_warning = FALSE, M)
- . = handle_item_insertion(I, prevent_warning, M, slave)
- if(. && !prevent_warning)
- slave.mob_item_insertion_feedback(usr, M, I)
-
-/datum/component/storage/concrete/handle_item_insertion(obj/item/I, prevent_warning = FALSE, mob/M, datum/component/storage/remote) //Remote is null or the slave datum
- var/datum/component/storage/concrete/master = master()
- var/atom/parent = src.parent
- var/moved = FALSE
- if(!istype(I))
- return FALSE
- if(M)
- if(!M.temporarilyRemoveItemFromInventory(I))
- return FALSE
- else
- moved = TRUE //At this point if the proc fails we need to manually move the object back to the turf/mob/whatever.
- if(I.pulledby)
- I.pulledby.stop_pulling()
- if(silent)
- prevent_warning = TRUE
- if(!_insert_physical_item(I))
- if(moved)
- if(M)
- if(!M.put_in_active_hand(I))
- I.forceMove(parent.drop_location())
- else
- I.forceMove(parent.drop_location())
- return FALSE
- I.on_enter_storage(master)
- I.item_flags |= ITEM_IN_STORAGE
- refresh_mob_views()
- I.mouse_opacity = MOUSE_OPACITY_OPAQUE //So you can click on the area around the item to equip it, instead of having to pixel hunt
- if(M)
- if(M.client && M.active_storage != src)
- M.client.screen -= I
- if(M.observers && M.observers.len)
- for(var/i in M.observers)
- var/mob/dead/observe = i
- if(observe.client && observe.active_storage != src)
- observe.client.screen -= I
- if(!remote)
- parent.add_fingerprint(M)
- if(!prevent_warning)
- mob_item_insertion_feedback(usr, M, I)
- update_icon()
- return TRUE
-
-/datum/component/storage/concrete/update_icon()
- if(isobj(parent))
- var/obj/O = parent
- O.update_icon()
- for(var/i in slaves)
- var/datum/component/storage/slave = i
- slave.update_icon()
diff --git a/code/datums/components/storage/concrete/bag_of_holding.dm b/code/datums/components/storage/concrete/bag_of_holding.dm
deleted file mode 100644
index 942cf86bbe0..00000000000
--- a/code/datums/components/storage/concrete/bag_of_holding.dm
+++ /dev/null
@@ -1,27 +0,0 @@
-/datum/component/storage/concrete/bluespace/bag_of_holding/handle_item_insertion(obj/item/W, prevent_warning = FALSE, mob/living/user)
- var/atom/A = parent
- if(A == W) //don't put yourself into yourself.
- return
- var/list/obj/item/storage/backpack/holding/matching = typecache_filter_list(W.get_all_contents(), typecacheof(/obj/item/storage/backpack/holding))
- matching -= A
- if(istype(W, /obj/item/storage/backpack/holding) || matching.len)
- var/safety = alert(user, "Doing this will have extremely dire consequences for the station and its crew. Be sure you know what you're doing.", "Put in [A.name]?", "Abort", "Proceed")
- if(safety != "Proceed" || QDELETED(A) || QDELETED(W) || QDELETED(user) || !user.canUseTopic(A, BE_CLOSE, iscarbon(user)))
- return
- var/turf/loccheck = get_turf(A)
- if(is_reebe(loccheck.z))
- user.visible_message("An unseen force knocks [user] to the ground!", "\"I think not!\"")
- user.Paralyze(60)
- return
- to_chat(user, "The Bluespace interfaces of the two devices catastrophically malfunction!")
- qdel(W)
- playsound(loccheck,'sound/effects/supermatter.ogg', 200, TRUE)
-
- message_admins("[ADMIN_LOOKUPFLW(user)] detonated a bag of holding at [ADMIN_VERBOSEJMP(loccheck)].")
- log_game("[key_name(user)] detonated a bag of holding at [loc_name(loccheck)].")
-
- user.gib(TRUE, TRUE, TRUE)
- new/obj/singularity/boh_tear(loccheck)
- qdel(A)
- return
- . = ..()
diff --git a/code/datums/components/storage/concrete/bluespace.dm b/code/datums/components/storage/concrete/bluespace.dm
deleted file mode 100644
index 1b0934661e8..00000000000
--- a/code/datums/components/storage/concrete/bluespace.dm
+++ /dev/null
@@ -1,23 +0,0 @@
-/datum/component/storage/concrete/bluespace
- var/dumping_range = 8
- var/dumping_sound = 'sound/items/pshoom.ogg'
- var/alt_sound = 'sound/items/pshoom_2.ogg'
-
-/datum/component/storage/concrete/bluespace/dump_content_at(atom/dest, mob/M)
- var/atom/A = parent
- if(A.Adjacent(M))
- var/atom/dumping_location = dest.get_dumping_location()
- var/turf/bagT = get_turf(parent)
- var/turf/destT = get_turf(dumping_location)
- if(destT && bagT && bagT.z == destT.z && get_dist(M, dumping_location) < dumping_range)
- if(dumping_location.storage_contents_dump_act(src, M))
- if(alt_sound && prob(1))
- playsound(src, alt_sound, 40, TRUE)
- else
- playsound(src, dumping_sound, 40, TRUE)
- M.Beam(dumping_location, icon_state="rped_upgrade", time=5)
- return TRUE
- to_chat(M, "The [A.name] buzzes.")
- playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE)
- return FALSE
-
diff --git a/code/datums/components/storage/concrete/implant.dm b/code/datums/components/storage/concrete/implant.dm
deleted file mode 100644
index 405b3098fe5..00000000000
--- a/code/datums/components/storage/concrete/implant.dm
+++ /dev/null
@@ -1,18 +0,0 @@
-/datum/component/storage/concrete/implant
- max_w_class = WEIGHT_CLASS_NORMAL
- max_combined_w_class = 6
- max_items = 2
- drop_all_on_destroy = TRUE
- drop_all_on_deconstruct = TRUE
- silent = TRUE
- allow_big_nesting = TRUE
-
-/datum/component/storage/concrete/implant/Initialize()
- . = ..()
- set_holdable(null, list(/obj/item/disk/nuclear))
-
-/datum/component/storage/concrete/implant/InheritComponent(datum/component/storage/concrete/implant/I, original)
- if(!istype(I))
- return ..()
- max_combined_w_class += I.max_combined_w_class
- max_items += I.max_items
diff --git a/code/datums/components/storage/concrete/pockets.dm b/code/datums/components/storage/concrete/pockets.dm
deleted file mode 100644
index 5a82c95a82f..00000000000
--- a/code/datums/components/storage/concrete/pockets.dm
+++ /dev/null
@@ -1,96 +0,0 @@
-/datum/component/storage/concrete/pockets
- max_items = 2
- max_w_class = WEIGHT_CLASS_SMALL
- max_combined_w_class = 50
- rustle_sound = FALSE
-
-/datum/component/storage/concrete/pockets/handle_item_insertion(obj/item/I, prevent_warning, mob/user)
- . = ..()
- if(. && silent && !prevent_warning)
- if(quickdraw)
- to_chat(user, "You discreetly slip [I] into [parent]. Alt-click [parent] to remove it.")
- else
- to_chat(user, "You discreetly slip [I] into [parent].")
-
-/datum/component/storage/concrete/pockets
- max_w_class = WEIGHT_CLASS_NORMAL
-
-/datum/component/storage/concrete/pockets/small
- max_items = 1
- max_w_class = WEIGHT_CLASS_SMALL
- attack_hand_interact = FALSE
-
-/datum/component/storage/concrete/pockets/tiny
- max_items = 1
- max_w_class = WEIGHT_CLASS_TINY
- attack_hand_interact = FALSE
-
-/datum/component/storage/concrete/pockets/small/fedora/Initialize()
- . = ..()
- var/static/list/exception_cache = typecacheof(list(
- /obj/item/katana, /obj/item/toy/katana, /obj/item/nullrod/claymore/katana,
- /obj/item/energy_katana, /obj/item/gun/ballistic/automatic/tommygun
- ))
- exception_hold = exception_cache
-
-/datum/component/storage/concrete/pockets/small/fedora/detective
- attack_hand_interact = TRUE // so the detectives would discover pockets in their hats
-
-/datum/component/storage/concrete/pockets/shoes
- attack_hand_interact = FALSE
- quickdraw = TRUE
- silent = TRUE
-
-/datum/component/storage/concrete/pockets/shoes/Initialize()
- . = ..()
- set_holdable(list(
- /obj/item/kitchen/knife, /obj/item/switchblade, /obj/item/pen,
- /obj/item/scalpel, /obj/item/reagent_containers/syringe, /obj/item/dnainjector,
- /obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/dropper,
- /obj/item/implanter, /obj/item/tool/screwdriver, /obj/item/weldingtool/mini,
- /obj/item/firing_pin
- ),
- list(/obj/item/tool/screwdriver/power)
- )
-
-/datum/component/storage/concrete/pockets/shoes/clown/Initialize()
- . = ..()
- set_holdable(list(
- /obj/item/kitchen/knife, /obj/item/switchblade, /obj/item/pen,
- /obj/item/scalpel, /obj/item/reagent_containers/syringe, /obj/item/dnainjector,
- /obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/dropper,
- /obj/item/implanter, /obj/item/tool/screwdriver, /obj/item/weldingtool/mini,
- /obj/item/firing_pin, /obj/item/bikehorn),
- list(/obj/item/tool/screwdriver/power)
- )
-
-/datum/component/storage/concrete/pockets/pocketprotector
- max_items = 3
- max_w_class = WEIGHT_CLASS_TINY
- var/atom/original_parent
-
-/datum/component/storage/concrete/pockets/pocketprotector/Initialize()
- original_parent = parent
- . = ..()
- set_holdable(list( //Same items as a PDA
- /obj/item/pen,
- /obj/item/toy/crayon,
- /obj/item/lipstick,
- /obj/item/flashlight/pen,
- /obj/item/clothing/mask/cigarette)
- )
-
-/datum/component/storage/concrete/pockets/pocketprotector/real_location()
- // if the component is reparented to a jumpsuit, the items still go in the protector
- return original_parent
-
-/datum/component/storage/concrete/pockets/helmet
- quickdraw = TRUE
- max_combined_w_class = 6
-
-/datum/component/storage/concrete/pockets/helmet/Initialize()
- . = ..()
- set_holdable(list(/obj/item/reagent_containers/food/drinks/bottle/vodka,
- /obj/item/reagent_containers/food/drinks/bottle/molotov,
- /obj/item/reagent_containers/food/drinks/drinkingglass,
- /obj/item/ammo_box/a762))
diff --git a/code/datums/components/storage/concrete/rped.dm b/code/datums/components/storage/concrete/rped.dm
deleted file mode 100644
index 455eb985f09..00000000000
--- a/code/datums/components/storage/concrete/rped.dm
+++ /dev/null
@@ -1,33 +0,0 @@
-/datum/component/storage/concrete/rped
- collection_mode = COLLECT_EVERYTHING
- allow_quick_gather = TRUE
- allow_quick_empty = TRUE
- click_gather = TRUE
- max_w_class = WEIGHT_CLASS_NORMAL
- max_combined_w_class = 100
- max_items = 50
- display_numerical_stacking = TRUE
-
-/datum/component/storage/concrete/rped/can_be_inserted(obj/item/I, stop_messages, mob/M)
- . = ..()
- if(!I.get_part_rating())
- if (!stop_messages)
- to_chat(M, "[parent] only accepts machine parts!")
- return FALSE
-
-/datum/component/storage/concrete/bluespace/rped
- collection_mode = COLLECT_EVERYTHING
- allow_quick_gather = TRUE
- allow_quick_empty = TRUE
- click_gather = TRUE
- max_w_class = WEIGHT_CLASS_BULKY // can fit vending refills
- max_combined_w_class = 800
- max_items = 400
- display_numerical_stacking = TRUE
-
-/datum/component/storage/concrete/bluespace/rped/can_be_inserted(obj/item/I, stop_messages, mob/M)
- . = ..()
- if(!I.get_part_rating())
- if (!stop_messages)
- to_chat(M, "[parent] only accepts machine parts!")
- return FALSE
diff --git a/code/datums/components/storage/concrete/stack.dm b/code/datums/components/storage/concrete/stack.dm
deleted file mode 100644
index 1f0c44c6502..00000000000
--- a/code/datums/components/storage/concrete/stack.dm
+++ /dev/null
@@ -1,67 +0,0 @@
-//Stack-only storage.
-/datum/component/storage/concrete/stack
- display_numerical_stacking = TRUE
- var/max_combined_stack_amount = 300
- max_w_class = WEIGHT_CLASS_NORMAL
- max_combined_w_class = WEIGHT_CLASS_NORMAL * 14
-
-/datum/component/storage/concrete/stack/proc/total_stack_amount()
- . = 0
- var/atom/real_location = real_location()
- for(var/i in real_location)
- var/obj/item/stack/S = i
- if(!istype(S))
- continue
- . += S.amount
-
-/datum/component/storage/concrete/stack/proc/remaining_space()
- return max(0, max_combined_stack_amount - total_stack_amount())
-
-//emptying procs do not need modification as stacks automatically merge.
-
-/datum/component/storage/concrete/stack/_insert_physical_item(obj/item/I, override = FALSE)
- if(!istype(I, /obj/item/stack))
- if(override)
- return ..()
- return FALSE
- var/atom/real_location = real_location()
- var/obj/item/stack/S = I
- var/can_insert = min(S.amount, remaining_space())
- if(!can_insert)
- return FALSE
- for(var/i in real_location) //combine.
- if(QDELETED(I))
- return
- var/obj/item/stack/_S = i
- if(!istype(_S))
- continue
- if(_S.merge_type == S.merge_type)
- _S.add(can_insert)
- S.use(can_insert, TRUE)
- return TRUE
- return ..(S.change_stack(null, can_insert), override)
-
-/datum/component/storage/concrete/stack/remove_from_storage(obj/item/I, atom/new_location)
- var/atom/real_location = real_location()
- var/obj/item/stack/S = I
- if(!istype(S))
- return ..()
- if(S.amount > S.max_amount)
- var/overrun = S.amount - S.max_amount
- S.amount = S.max_amount
- var/obj/item/stack/temp = new S.type(real_location, overrun)
- handle_item_insertion(temp)
- return ..(S, new_location)
-
-/datum/component/storage/concrete/stack/_process_numerical_display()
- var/atom/real_location = real_location()
- . = list()
- for(var/i in real_location)
- var/obj/item/stack/I = i
- if(!istype(I) || QDELETED(I)) //We're specialized stack storage, just ignore non stacks.
- continue
- if(!.[I.merge_type])
- .[I.merge_type] = new /datum/numbered_display(I, I.amount)
- else
- var/datum/numbered_display/ND = .[I.merge_type]
- ND.number += I.amount
diff --git a/code/datums/components/storage/concrete/wallet.dm b/code/datums/components/storage/concrete/wallet.dm
deleted file mode 100644
index 7122474afe3..00000000000
--- a/code/datums/components/storage/concrete/wallet.dm
+++ /dev/null
@@ -1,18 +0,0 @@
-/datum/component/storage/concrete/wallet/on_alt_click(datum/source, mob/user)
- if(!isliving(user) || !user.CanReach(parent))
- return
- if(locked)
- to_chat(user, "[parent] seems to be locked!")
- return
-
- var/obj/item/storage/wallet/A = parent
- if(istype(A) && A.front_id && !issilicon(user) && !(A.item_flags & ITEM_IN_STORAGE)) //if it's a wallet in storage seeing the full inventory is more useful
- var/obj/item/I = A.front_id
- A.add_fingerprint(user)
- remove_from_storage(I, get_turf(user))
- if(!user.put_in_hands(I))
- to_chat(user, "You fumble for [I] and it falls on the floor.")
- return
- user.visible_message("[user] draws [I] from [parent]!", "You draw [I] from [parent].")
- return
- ..()
diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm
deleted file mode 100644
index 300ac6170c7..00000000000
--- a/code/datums/components/storage/storage.dm
+++ /dev/null
@@ -1,810 +0,0 @@
-#define COLLECT_ONE 0
-#define COLLECT_EVERYTHING 1
-#define COLLECT_SAME 2
-
-#define DROP_NOTHING 0
-#define DROP_AT_PARENT 1
-#define DROP_AT_LOCATION 2
-
-// External storage-related logic:
-// /mob/proc/ClickOn() in /_onclick/click.dm - clicking items in storages
-// /mob/living/Move() in /modules/mob/living/living.dm - hiding storage boxes on mob movement
-
-/datum/component/storage
- dupe_mode = COMPONENT_DUPE_UNIQUE
- var/datum/component/storage/concrete/master //If not null, all actions act on master and this is just an access point.
-
- var/list/can_hold //if this is set, only items, and their children, will fit
- var/list/cant_hold //if this is set, items, and their children, won't fit
- var/list/exception_hold //if set, these items will be the exception to the max size of object that can fit.
-
- var/can_hold_description
-
- var/list/mob/is_using //lazy list of mobs looking at the contents of this storage.
-
- var/locked = FALSE //when locked nothing can see inside or use it.
-
- var/max_w_class = WEIGHT_CLASS_SMALL //max size of objects that will fit.
- var/max_combined_w_class = 14 //max combined sizes of objects that will fit.
- var/max_items = 7 //max number of objects that will fit.
-
- var/emp_shielded = FALSE
-
- var/silent = FALSE //whether this makes a message when things are put in.
- var/click_gather = FALSE //whether this can be clicked on items to pick it up rather than the other way around.
- var/rustle_sound = TRUE //play rustle sound on interact.
- var/allow_quick_empty = FALSE //allow empty verb which allows dumping on the floor of everything inside quickly.
- var/allow_quick_gather = FALSE //allow toggle mob verb which toggles collecting all items from a tile.
-
- var/collection_mode = COLLECT_EVERYTHING
-
- var/insert_preposition = "in" //you put things "in" a bag, but "on" a tray.
-
- var/display_numerical_stacking = FALSE //stack things of the same type and show as a single object with a number.
-
- var/atom/movable/screen/storage/boxes //storage display object
- var/atom/movable/screen/close/closer //close button object
-
- var/allow_big_nesting = FALSE //allow storage objects of the same or greater size.
-
- var/attack_hand_interact = TRUE //interact on attack hand.
- var/quickdraw = FALSE //altclick interact
-
- var/datum/action/item_action/storage_gather_mode/modeswitch_action
-
- //Screen variables: Do not mess with these vars unless you know what you're doing. They're not defines so storage that isn't in the same location can be supported in the future.
- var/screen_max_columns = 7 //These two determine maximum screen sizes.
- var/screen_max_rows = INFINITY
- var/screen_pixel_x = 16 //These two are pixel values for screen loc of boxes and closer
- var/screen_pixel_y = 16
- var/screen_start_x = 3 //These two are where the storage starts being rendered, screen_loc wise.
- var/screen_start_y = 1
- //End
-
-/datum/component/storage/Initialize(datum/component/storage/concrete/master)
- if(!isatom(parent))
- return COMPONENT_INCOMPATIBLE
- if(master)
- change_master(master)
- boxes = new(null, src)
- closer = new(null, src)
- orient2hud()
-
- RegisterSignal(parent, COMSIG_CONTAINS_STORAGE, .proc/on_check)
- RegisterSignal(parent, COMSIG_IS_STORAGE_LOCKED, .proc/check_locked)
- RegisterSignal(parent, COMSIG_TRY_STORAGE_SHOW, .proc/signal_show_attempt)
- RegisterSignal(parent, COMSIG_TRY_STORAGE_INSERT, .proc/signal_insertion_attempt)
- RegisterSignal(parent, COMSIG_TRY_STORAGE_CAN_INSERT, .proc/signal_can_insert)
- RegisterSignal(parent, COMSIG_TRY_STORAGE_TAKE_TYPE, .proc/signal_take_type)
- RegisterSignal(parent, COMSIG_TRY_STORAGE_FILL_TYPE, .proc/signal_fill_type)
- RegisterSignal(parent, COMSIG_TRY_STORAGE_SET_LOCKSTATE, .proc/set_locked)
- RegisterSignal(parent, COMSIG_TRY_STORAGE_TAKE, .proc/signal_take_obj)
- RegisterSignal(parent, COMSIG_TRY_STORAGE_QUICK_EMPTY, .proc/signal_quick_empty)
- RegisterSignal(parent, COMSIG_TRY_STORAGE_HIDE_FROM, .proc/signal_hide_attempt)
- RegisterSignal(parent, COMSIG_TRY_STORAGE_HIDE_ALL, .proc/close_all)
- RegisterSignal(parent, COMSIG_TRY_STORAGE_RETURN_INVENTORY, .proc/signal_return_inv)
-
- RegisterSignal(parent, COMSIG_TOPIC, .proc/topic_handle)
-
- RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/attackby)
-
- RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand)
- RegisterSignal(parent, COMSIG_ATOM_ATTACK_PAW, .proc/on_attack_hand)
- RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/emp_act)
- RegisterSignal(parent, COMSIG_ATOM_ATTACK_GHOST, .proc/show_to_ghost)
- RegisterSignal(parent, COMSIG_ATOM_ENTERED, .proc/refresh_mob_views)
- RegisterSignal(parent, COMSIG_ATOM_EXITED, .proc/_remove_and_refresh)
- RegisterSignal(parent, COMSIG_ATOM_CANREACH, .proc/canreach_react)
-
- RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, .proc/preattack_intercept)
- RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/attack_self)
- RegisterSignal(parent, COMSIG_ITEM_PICKUP, .proc/signal_on_pickup)
-
- RegisterSignal(parent, COMSIG_MOVABLE_POST_THROW, .proc/close_all)
- RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/on_move)
-
- RegisterSignal(parent, COMSIG_CLICK_ALT, .proc/on_alt_click)
- RegisterSignal(parent, COMSIG_MOUSEDROP_ONTO, .proc/mousedrop_onto)
- RegisterSignal(parent, COMSIG_MOUSEDROPPED_ONTO, .proc/mousedrop_receive)
-
- update_actions()
-
-/datum/component/storage/Destroy()
- close_all()
- QDEL_NULL(boxes)
- QDEL_NULL(closer)
- LAZYCLEARLIST(is_using)
- return ..()
-
-/datum/component/storage/PreTransfer()
- update_actions()
-
-/datum/component/storage/proc/set_holdable(can_hold_list, cant_hold_list)
- can_hold_description = generate_hold_desc(can_hold_list)
-
- if (can_hold_list != null)
- can_hold = typecacheof(can_hold_list)
-
- if (cant_hold_list != null)
- cant_hold = typecacheof(cant_hold_list)
-
-/datum/component/storage/proc/generate_hold_desc(can_hold_list)
- var/list/desc = list()
-
- for(var/valid_type in can_hold_list)
- var/obj/item/valid_item = valid_type
- desc += "\a [initial(valid_item.name)]"
-
- return "\n\t[desc.Join("\n\t")]"
-
-/datum/component/storage/proc/update_actions()
- QDEL_NULL(modeswitch_action)
- if(!isitem(parent) || !allow_quick_gather)
- return
- var/obj/item/I = parent
- modeswitch_action = new(I)
- RegisterSignal(modeswitch_action, COMSIG_ACTION_TRIGGER, .proc/action_trigger)
- if(I.obj_flags & ITEM_IN_INVENTORY)
- var/mob/M = I.loc
- if(!istype(M))
- return
- modeswitch_action.Grant(M)
-
-/datum/component/storage/proc/change_master(datum/component/storage/concrete/new_master)
- if(new_master == src || (!isnull(new_master) && !istype(new_master)))
- return FALSE
- if(master)
- master.on_slave_unlink(src)
- master = new_master
- if(master)
- master.on_slave_link(src)
- return TRUE
-
-/datum/component/storage/proc/master()
- if(master == src)
- return //infinite loops yo.
- return master
-
-/datum/component/storage/proc/real_location()
- var/datum/component/storage/concrete/master = master()
- return master? master.real_location() : null
-
-/datum/component/storage/proc/canreach_react(datum/source, list/next)
- var/datum/component/storage/concrete/master = master()
- if(!master)
- return
- . = COMPONENT_BLOCK_REACH
- next += master.parent
- for(var/i in master.slaves)
- var/datum/component/storage/slave = i
- next += slave.parent
-
-/datum/component/storage/proc/on_move()
- var/atom/A = parent
- for(var/mob/living/L in can_see_contents())
- if(!L.CanReach(A))
- hide_from(L)
-
-/datum/component/storage/proc/attack_self(datum/source, mob/M)
- if(locked)
- to_chat(M, "[parent] seems to be locked!")
- return FALSE
- if((M.get_active_held_item() == parent) && allow_quick_empty)
- quick_empty(M)
-
-/datum/component/storage/proc/preattack_intercept(datum/source, obj/O, mob/M, params)
- if(!isitem(O) || !click_gather || SEND_SIGNAL(O, COMSIG_CONTAINS_STORAGE))
- return FALSE
- . = COMPONENT_NO_ATTACK
- if(locked)
- to_chat(M, "[parent] seems to be locked!")
- return FALSE
- var/obj/item/I = O
- if(collection_mode == COLLECT_ONE)
- if(can_be_inserted(I, null, M))
- handle_item_insertion(I, null, M)
- return
- if(!isturf(I.loc))
- return
- var/list/things = I.loc.contents.Copy()
- if(collection_mode == COLLECT_SAME)
- things = typecache_filter_list(things, typecacheof(I.type))
- var/len = length(things)
- if(!len)
- to_chat(M, "You failed to pick up anything with [parent]!")
- return
- var/datum/progressbar/progress = new(M, len, I.loc)
- var/list/rejections = list()
- while(do_after(M, 10, parent, DO_AFTER_NO_PROGRESS, additional_checks = CALLBACK(src, .proc/handle_mass_pickup, things, I.loc, rejections, progress)))
- stoplag(1)
- qdel(progress)
- to_chat(M, "You put everything you could [insert_preposition] [parent].")
-
-/datum/component/storage/proc/handle_mass_item_insertion(list/things, datum/component/storage/src_object, mob/user, datum/progressbar/progress)
- var/atom/source_real_location = src_object.real_location()
- for(var/obj/item/I in things)
- things -= I
- if(I.loc != source_real_location)
- continue
- if(user.active_storage != src_object)
- if(I.on_found(user))
- break
- if(can_be_inserted(I,FALSE,user))
- handle_item_insertion(I, TRUE, user)
- if (TICK_CHECK)
- progress.update(progress.goal - things.len)
- return TRUE
-
- progress.update(progress.goal - things.len)
- return FALSE
-
-/datum/component/storage/proc/handle_mass_pickup(list/things, atom/thing_loc, list/rejections, datum/progressbar/progress)
- var/atom/real_location = real_location()
- for(var/obj/item/I in things)
- things -= I
- if(I.loc != thing_loc)
- continue
- if(I.type in rejections) // To limit bag spamming: any given type only complains once
- continue
- if(!can_be_inserted(I, stop_messages = TRUE)) // Note can_be_inserted still makes noise when the answer is no
- if(real_location.contents.len >= max_items)
- break
- rejections += I.type // therefore full bags are still a little spammy
- continue
-
- handle_item_insertion(I, TRUE) //The TRUE stops the "You put the [parent] into [S]" insertion message from being displayed.
-
- if (TICK_CHECK)
- progress.update(progress.goal - things.len)
- return TRUE
-
- progress.update(progress.goal - things.len)
- return FALSE
-
-/datum/component/storage/proc/quick_empty(mob/M)
- var/atom/A = parent
- if(!M.canUseStorage() || !A.Adjacent(M) || M.incapacitated())
- return
- if(locked)
- to_chat(M, "[parent] seems to be locked!")
- return FALSE
- A.add_fingerprint(M)
- to_chat(M, "You start dumping out [parent].")
- var/turf/T = get_turf(A)
- var/list/things = contents()
- var/datum/progressbar/progress = new(M, length(things), T)
- while(do_after(M, 10, T, DO_AFTER_NO_PROGRESS, additional_checks = CALLBACK(src, .proc/mass_remove_from_storage, T, things, progress)))
- stoplag(1)
- qdel(progress)
-
-/datum/component/storage/proc/mass_remove_from_storage(atom/target, list/things, datum/progressbar/progress, trigger_on_found = TRUE)
- var/atom/real_location = real_location()
- for(var/obj/item/I in things)
- things -= I
- if(I.loc != real_location)
- continue
- remove_from_storage(I, target)
- I.pixel_x = rand(-10,10)
- I.pixel_y = rand(-10,10)
- if(trigger_on_found && I.on_found())
- return FALSE
- if(TICK_CHECK)
- progress.update(progress.goal - length(things))
- return TRUE
- progress.update(progress.goal - length(things))
- return FALSE
-
-/datum/component/storage/proc/do_quick_empty(atom/_target)
- if(!_target)
- _target = get_turf(parent)
- if(usr)
- hide_from(usr)
- var/list/contents = contents()
- var/atom/real_location = real_location()
- for(var/obj/item/I in contents)
- if(I.loc != real_location)
- continue
- remove_from_storage(I, _target)
- return TRUE
-
-/datum/component/storage/proc/set_locked(datum/source, new_state)
- locked = new_state
- if(locked)
- close_all()
-
-/datum/component/storage/proc/_process_numerical_display()
- . = list()
- var/atom/real_location = real_location()
- for(var/obj/item/I in real_location.contents)
- if(QDELETED(I))
- continue
- if(!.["[I.type]-[I.name]"])
- .["[I.type]-[I.name]"] = new /datum/numbered_display(I, 1)
- else
- var/datum/numbered_display/ND = .["[I.type]-[I.name]"]
- ND.number++
-
-//This proc determines the size of the inventory to be displayed. Please touch it only if you know what you're doing.
-/datum/component/storage/proc/orient2hud()
- var/atom/real_location = real_location()
- var/adjusted_contents = real_location.contents.len
-
- //Numbered contents display
- var/list/datum/numbered_display/numbered_contents
- if(display_numerical_stacking)
- numbered_contents = _process_numerical_display()
- adjusted_contents = numbered_contents.len
-
- var/columns = clamp(max_items, 1, screen_max_columns)
- var/rows = clamp(CEILING(adjusted_contents / columns, 1), 1, screen_max_rows)
- standard_orient_objs(rows, columns, numbered_contents)
-
-//This proc draws out the inventory and places the items on it. It uses the standard position.
-/datum/component/storage/proc/standard_orient_objs(rows, cols, list/obj/item/numerical_display_contents)
- boxes.screen_loc = "LEFT+[screen_start_x]:[screen_pixel_x],BOTTOM+[screen_start_y]:[screen_pixel_y] to LEFT+[screen_start_x+cols-1]:[screen_pixel_x],BOTTOM+[screen_start_y+rows-1]:[screen_pixel_y]"
- var/cx = screen_start_x
- var/cy = screen_start_y
- if(islist(numerical_display_contents))
- for(var/type in numerical_display_contents)
- var/datum/numbered_display/ND = numerical_display_contents[type]
- ND.sample_object.mouse_opacity = MOUSE_OPACITY_OPAQUE
- ND.sample_object.screen_loc = "LEFT+[cx]:[screen_pixel_x],BOTTOM+[cy]:[screen_pixel_y]"
- ND.sample_object.maptext = "[(ND.number > 1)? "[ND.number]" : ""]"
- ND.sample_object.layer = ABOVE_HUD_LAYER
- ND.sample_object.plane = ABOVE_HUD_PLANE
- cx++
- if(cx - screen_start_x >= cols)
- cx = screen_start_x
- cy++
- if(cy - screen_start_y >= rows)
- break
- else
- var/atom/real_location = real_location()
- for(var/obj/O in real_location)
- if(QDELETED(O))
- continue
- O.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip"
- O.screen_loc = "LEFT+[cx]:[screen_pixel_x],BOTTOM+[cy]:[screen_pixel_y]"
- O.maptext = ""
- O.layer = ABOVE_HUD_LAYER
- O.plane = ABOVE_HUD_PLANE
- cx++
- if(cx - screen_start_x >= cols)
- cx = screen_start_x
- cy++
- if(cy - screen_start_y >= rows)
- break
- closer.screen_loc = "LEFT+[screen_start_x + cols]:[screen_pixel_x],BOTTOM+[screen_start_y]:[screen_pixel_y]"
-
-/datum/component/storage/proc/show_to(mob/M)
- if(!M.client)
- return FALSE
- var/atom/real_location = real_location()
- if(M.active_storage != src && (M.stat == CONSCIOUS))
- for(var/obj/item/I in real_location)
- if(I.on_found(M))
- return FALSE
- if(M.active_storage)
- M.active_storage.hide_from(M)
- orient2hud()
- M.client.screen |= boxes
- M.client.screen |= closer
- M.client.screen |= real_location.contents
- M.active_storage = src
- LAZYDISTINCTADD(is_using, M)
- return TRUE
-
-/datum/component/storage/proc/hide_from(mob/M)
- if(!M.client)
- return TRUE
- var/atom/real_location = real_location()
- M.client.screen -= boxes
- M.client.screen -= closer
- M.client.screen -= real_location.contents
- if(M.active_storage == src)
- M.active_storage = null
- LAZYREMOVE(is_using, M)
- return TRUE
-
-/datum/component/storage/proc/close(mob/M)
- hide_from(M)
-
-/datum/component/storage/proc/close_all()
- . = FALSE
- for(var/mob/M in can_see_contents())
- close(M)
- . = TRUE //returns TRUE if any mobs actually got a close(M) call
-
-/datum/component/storage/proc/emp_act(datum/source, severity)
- if(emp_shielded)
- return
- var/datum/component/storage/concrete/master = master()
- master.emp_act(source, severity)
-
-//This proc draws out the inventory and places the items on it. tx and ty are the upper left tile and mx, my are the bottm right.
-//The numbers are calculated from the bottom-left The bottom-left slot being 1,1.
-/datum/component/storage/proc/orient_objs(tx, ty, mx, my)
- var/atom/real_location = real_location()
- var/cx = tx
- var/cy = ty
- boxes.screen_loc = "LEFT+[tx]:,BOTTOM+[ty] to LEFT+[mx],BOTTOM+[my]"
- for(var/obj/O in real_location)
- if(QDELETED(O))
- continue
- O.screen_loc = "LEFT+[cx],BOTTOM+[cy]"
- O.layer = ABOVE_HUD_LAYER
- O.plane = ABOVE_HUD_PLANE
- cx++
- if(cx > mx)
- cx = tx
- cy--
- closer.screen_loc = "LEFT+[mx+1],BOTTOM+[my]"
-
-//Resets something that is being removed from storage.
-/datum/component/storage/proc/_removal_reset(atom/movable/thing)
- if(!istype(thing))
- return FALSE
- var/datum/component/storage/concrete/master = master()
- if(!istype(master))
- return FALSE
- return master._removal_reset(thing)
-
-/datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/thing)
- _removal_reset(thing)
- refresh_mob_views()
-
-//Call this proc to handle the removal of an item from the storage item. The item will be moved to the new_location target, if that is null it's being deleted
-/datum/component/storage/proc/remove_from_storage(atom/movable/AM, atom/new_location)
- if(!istype(AM))
- return FALSE
- var/datum/component/storage/concrete/master = master()
- if(!istype(master))
- return FALSE
- return master.remove_from_storage(AM, new_location)
-
-/datum/component/storage/proc/refresh_mob_views()
- var/list/seeing = can_see_contents()
- for(var/i in seeing)
- show_to(i)
- return TRUE
-
-/datum/component/storage/proc/can_see_contents()
- var/list/cansee = list()
- for(var/mob/M in is_using)
- if(M.active_storage == src && M.client)
- cansee |= M
- else
- LAZYREMOVE(is_using, M)
- return cansee
-
-//Tries to dump content
-/datum/component/storage/proc/dump_content_at(atom/dest_object, mob/M)
- var/atom/A = parent
- var/atom/dump_destination = dest_object.get_dumping_location()
- if(A.Adjacent(M) && dump_destination && M.Adjacent(dump_destination))
- if(locked)
- to_chat(M, "[parent] seems to be locked!")
- return FALSE
- if(dump_destination.storage_contents_dump_act(src, M))
- playsound(A, "rustle", 50, TRUE, -5)
- return TRUE
- return FALSE
-
-//This proc is called when you want to place an item into the storage item.
-/datum/component/storage/proc/attackby(datum/source, obj/item/I, mob/M, params)
- if(istype(I, /obj/item/hand_labeler))
- var/obj/item/hand_labeler/labeler = I
- if(labeler.mode)
- return FALSE
- . = TRUE //no afterattack
- if(iscyborg(M))
- return
- if(!can_be_inserted(I, FALSE, M))
- var/atom/real_location = real_location()
- if(real_location.contents.len >= max_items) //don't use items on the backpack if they don't fit
- return TRUE
- return FALSE
- handle_item_insertion(I, FALSE, M)
-
-/datum/component/storage/proc/return_inv(recursive)
- var/list/ret = list()
- ret |= contents()
- if(recursive)
- for(var/i in ret.Copy())
- var/atom/A = i
- SEND_SIGNAL(A, COMSIG_TRY_STORAGE_RETURN_INVENTORY, ret, TRUE)
- return ret
-
-/datum/component/storage/proc/contents() //ONLY USE IF YOU NEED TO COPY CONTENTS OF REAL LOCATION, COPYING IS NOT AS FAST AS DIRECT ACCESS!
- var/atom/real_location = real_location()
- return real_location.contents.Copy()
-
-//Abuses the fact that lists are just references, or something like that.
-/datum/component/storage/proc/signal_return_inv(datum/source, list/interface, recursive = TRUE)
- if(!islist(interface))
- return FALSE
- interface |= return_inv(recursive)
- return TRUE
-
-/datum/component/storage/proc/topic_handle(datum/source, user, href_list)
- if(href_list["show_valid_pocket_items"])
- handle_show_valid_items(source, user)
-
-/datum/component/storage/proc/handle_show_valid_items(datum/source, user)
- to_chat(user, "[source] can hold: [can_hold_description]")
-
-/datum/component/storage/proc/mousedrop_onto(datum/source, atom/over_object, mob/M)
- set waitfor = FALSE
- . = COMPONENT_NO_MOUSEDROP
- if(!ismob(M))
- return
- if(!over_object)
- return
- if(ismecha(M.loc)) // stops inventory actions in a mech
- return
- if(M.incapacitated() || !M.canUseStorage())
- return
- var/atom/A = parent
- A.add_fingerprint(M)
- // this must come before the screen objects only block, dunno why it wasn't before
- if(over_object == M)
- user_show_to_mob(M)
- if(!istype(over_object, /atom/movable/screen))
- dump_content_at(over_object, M)
- return
- if(A.loc != M)
- return
- playsound(A, "rustle", 50, TRUE, -5)
- if(istype(over_object, /atom/movable/screen/inventory/hand))
- var/atom/movable/screen/inventory/hand/H = over_object
- M.putItemFromInventoryInHandIfPossible(A, H.held_index)
- return
- A.add_fingerprint(M)
-
-/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE)
- var/atom/A = parent
- if(!istype(M))
- return FALSE
- A.add_fingerprint(M)
- if(locked && !force)
- to_chat(M, "[parent] seems to be locked!")
- return FALSE
- if(force || M.CanReach(parent, view_only = TRUE))
- show_to(M)
-
-/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M)
- if(isitem(O))
- var/obj/item/I = O
- if(iscarbon(M) || isdrone(M))
- var/mob/living/L = M
- if(!L.incapacitated() && I == L.get_active_held_item())
- if(!SEND_SIGNAL(I, COMSIG_CONTAINS_STORAGE) && can_be_inserted(I, FALSE)) //If it has storage it should be trying to dump, not insert.
- handle_item_insertion(I, FALSE, L)
-
-//This proc return 1 if the item can be picked up and 0 if it can't.
-//Set the stop_messages to stop it from printing messages
-/datum/component/storage/proc/can_be_inserted(obj/item/I, stop_messages = FALSE, mob/M)
- if(!istype(I) || (I.item_flags & ITEM_ABSTRACT))
- return FALSE //Not an item
- if(I == parent)
- return FALSE //no paradoxes for you
- var/atom/real_location = real_location()
- var/atom/host = parent
- if(real_location == I.loc)
- return FALSE //Means the item is already in the storage item
- if(locked)
- if(M && !stop_messages)
- host.add_fingerprint(M)
- to_chat(M, "[host] seems to be locked!")
- return FALSE
- if(real_location.contents.len >= max_items)
- if(!stop_messages)
- to_chat(M, "[host] is full, make some space!")
- return FALSE //Storage item is full
- if(length(can_hold))
- if(!is_type_in_typecache(I, can_hold))
- if(!stop_messages)
- to_chat(M, "[host] cannot hold [I]!")
- return FALSE
- if(is_type_in_typecache(I, cant_hold)) //Check for specific items which this container can't hold.
- if(!stop_messages)
- to_chat(M, "[host] cannot hold [I]!")
- return FALSE
- if(I.w_class > max_w_class && !is_type_in_typecache(I, exception_hold))
- if(!stop_messages)
- to_chat(M, "[I] is too big for [host]!")
- return FALSE
- var/sum_w_class = I.w_class
- for(var/obj/item/_I in real_location)
- sum_w_class += _I.w_class //Adds up the combined w_classes which will be in the storage item if the item is added to it.
- if(sum_w_class > max_combined_w_class)
- if(!stop_messages)
- to_chat(M, "[I] won't fit in [host], make some space!")
- return FALSE
- if(isitem(host))
- var/obj/item/IP = host
- var/datum/component/storage/STR_I = I.GetComponent(/datum/component/storage)
- if((I.w_class >= IP.w_class) && STR_I && !allow_big_nesting)
- if(!stop_messages)
- to_chat(M, "[IP] cannot hold [I] as it's a storage item of the same size!")
- return FALSE //To prevent the stacking of same sized storage items.
- var/datum/component/storage/concrete/master = master()
- if(!istype(master))
- return FALSE
- return master.slave_can_insert_object(src, I, stop_messages, M)
-
-/datum/component/storage/proc/_insert_physical_item(obj/item/I, override = FALSE)
- return FALSE
-
-//This proc handles items being inserted. It does not perform any checks of whether an item can or can't be inserted. That's done by can_be_inserted()
-//The prevent_warning parameter will stop the insertion message from being displayed. It is intended for cases where you are inserting multiple items at once,
-//such as when picking up all the items on a tile with one click.
-/datum/component/storage/proc/handle_item_insertion(obj/item/I, prevent_warning = FALSE, mob/M, datum/component/storage/remote)
- var/atom/parent = src.parent
- var/datum/component/storage/concrete/master = master()
- if(!istype(master))
- return FALSE
- if(silent)
- prevent_warning = TRUE
- if(M)
- parent.add_fingerprint(M)
- . = master.handle_item_insertion_from_slave(src, I, prevent_warning, M)
-
-/datum/component/storage/proc/mob_item_insertion_feedback(mob/user, mob/M, obj/item/I, override = FALSE)
- if(silent && !override)
- return
- if(rustle_sound)
- playsound(parent, "rustle", 50, TRUE, -5)
- for(var/mob/viewing in viewers(user, null))
- if(M == viewing)
- to_chat(usr, "You put [I] [insert_preposition]to [parent].")
- else if(in_range(M, viewing)) //If someone is standing close enough, they can tell what it is...
- viewing.show_message("[M] puts [I] [insert_preposition]to [parent].", 1)
- else if(I && I.w_class >= 3) //Otherwise they can only see large or normal items from a distance...
- viewing.show_message("[M] puts [I] [insert_preposition]to [parent].", 1)
-
-/datum/component/storage/proc/update_icon()
- if(isobj(parent))
- var/obj/O = parent
- O.update_icon()
-
-/datum/component/storage/proc/signal_insertion_attempt(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE)
- if((!force && !can_be_inserted(I, TRUE, M)) || (I == parent))
- return FALSE
- return handle_item_insertion(I, silent, M)
-
-/datum/component/storage/proc/signal_can_insert(datum/source, obj/item/I, mob/M, silent = FALSE)
- return can_be_inserted(I, silent, M)
-
-/datum/component/storage/proc/show_to_ghost(datum/source, mob/observer/dead/M)
- return user_show_to_mob(M, TRUE)
-
-/datum/component/storage/proc/signal_show_attempt(datum/source, mob/showto, force = FALSE)
- return user_show_to_mob(showto, force)
-
-/datum/component/storage/proc/on_check()
- return TRUE
-
-/datum/component/storage/proc/check_locked()
- return locked
-
-/datum/component/storage/proc/signal_take_type(datum/source, type, atom/destination, amount = INFINITY, check_adjacent = FALSE, force = FALSE, mob/user, list/inserted)
- if(!force)
- if(check_adjacent)
- if(!user || !user.CanReach(destination) || !user.CanReach(parent))
- return FALSE
- var/list/taking = typecache_filter_list(contents(), typecacheof(type))
- if(taking.len > amount)
- taking.len = amount
- if(inserted) //duplicated code for performance, don't bother checking retval/checking for list every item.
- for(var/i in taking)
- if(remove_from_storage(i, destination))
- inserted |= i
- else
- for(var/i in taking)
- remove_from_storage(i, destination)
- return TRUE
-
-/datum/component/storage/proc/remaining_space_items()
- var/atom/real_location = real_location()
- return max(0, max_items - real_location.contents.len)
-
-/datum/component/storage/proc/signal_fill_type(datum/source, type, amount = 20, force = FALSE)
- var/atom/real_location = real_location()
- if(!force)
- amount = min(remaining_space_items(), amount)
- for(var/i in 1 to amount)
- handle_item_insertion(new type(real_location), TRUE)
- CHECK_TICK
- return TRUE
-
-/datum/component/storage/proc/on_attack_hand(datum/source, mob/user)
- var/atom/A = parent
- if(!attack_hand_interact)
- return
- if(user.active_storage == src && A.loc == user) //if you're already looking inside the storage item
- user.active_storage.close(user)
- close(user)
- . = COMPONENT_NO_ATTACK_HAND
- return
-
- if(rustle_sound)
- playsound(A, "rustle", 50, TRUE, -5)
-
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- if(H.l_store == A && !H.get_active_held_item()) //Prevents opening if it's in a pocket.
- . = COMPONENT_NO_ATTACK_HAND
- H.put_in_hands(A)
- H.l_store = null
- return
- if(H.r_store == A && !H.get_active_held_item())
- . = COMPONENT_NO_ATTACK_HAND
- H.put_in_hands(A)
- H.r_store = null
- return
-
- if(A.loc == user)
- . = COMPONENT_NO_ATTACK_HAND
- if(locked)
- to_chat(user, "[parent] seems to be locked!")
- else
- show_to(user)
-
-/datum/component/storage/proc/signal_on_pickup(datum/source, mob/user)
- var/atom/A = parent
- update_actions()
- for(var/mob/M in range(1, A))
- if(M.active_storage == src)
- close(M)
-
-/datum/component/storage/proc/signal_take_obj(datum/source, atom/movable/AM, new_loc, force = FALSE)
- if(!(AM in real_location()))
- return FALSE
- return remove_from_storage(AM, new_loc)
-
-/datum/component/storage/proc/signal_quick_empty(datum/source, atom/loctarget)
- return do_quick_empty(loctarget)
-
-/datum/component/storage/proc/signal_hide_attempt(datum/source, mob/target)
- return hide_from(target)
-
-/datum/component/storage/proc/on_alt_click(datum/source, mob/user)
- if(!isliving(user) || !user.CanReach(parent))
- return
- if(locked)
- to_chat(user, "[parent] seems to be locked!")
- return
-
- var/atom/A = parent
- if(!quickdraw)
- A.add_fingerprint(user)
- user_show_to_mob(user)
- playsound(A, "rustle", 50, TRUE, -5)
- return
-
- if(!user.incapacitated())
- var/obj/item/I = locate() in real_location()
- if(!I)
- return
- A.add_fingerprint(user)
- remove_from_storage(I, get_turf(user))
- if(!user.put_in_hands(I))
- to_chat(user, "You fumble for [I] and it falls on the floor.")
- return
- user.visible_message("[user] draws [I] from [parent]!", "You draw [I] from [parent].")
- return
-
-/datum/component/storage/proc/action_trigger(datum/signal_source, datum/action/source)
- gather_mode_switch(source.owner)
- return COMPONENT_ACTION_BLOCK_TRIGGER
-
-/datum/component/storage/proc/gather_mode_switch(mob/user)
- collection_mode = (collection_mode+1)%3
- switch(collection_mode)
- if(COLLECT_SAME)
- to_chat(user, "[parent] now picks up all items of a single type at once.")
- if(COLLECT_EVERYTHING)
- to_chat(user, "[parent] now picks up all items in a tile at once.")
- if(COLLECT_ONE)
- to_chat(user, "[parent] now picks up one item at a time.")
diff --git a/code/datums/components/summoning.dm b/code/datums/components/summoning.dm
deleted file mode 100644
index adb42e153c8..00000000000
--- a/code/datums/components/summoning.dm
+++ /dev/null
@@ -1,68 +0,0 @@
-/datum/component/summoning
- var/list/mob_types = list()
- var/spawn_chance // chance for the mob to spawn on hit in percent
- var/max_mobs
- var/spawn_delay // delay in spawning between mobs (deciseconds)
- var/spawn_text
- var/spawn_sound
- var/list/faction
-
- var/last_spawned_time = 0
- var/list/spawned_mobs = list()
-
-/datum/component/summoning/Initialize(mob_types, spawn_chance=100, max_mobs=3, spawn_delay=100, spawn_text="appears out of nowhere", spawn_sound='sound/magic/summon_magic.ogg', faction)
- if(!isitem(parent) && !ishostile(parent) && !isgun(parent) && !ismachinery(parent) && !isstructure(parent))
- return COMPONENT_INCOMPATIBLE
-
- src.mob_types = mob_types
- src.spawn_chance = spawn_chance
- src.max_mobs = max_mobs
- src.spawn_delay = spawn_delay
- src.spawn_text = spawn_text
- src.spawn_sound = spawn_sound
- src.faction = faction
-
-/datum/component/summoning/RegisterWithParent()
- if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc
- RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit)
- else if(isitem(parent))
- RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/item_afterattack)
- else if(ishostile(parent))
- RegisterSignal(parent, COMSIG_HOSTILE_ATTACKINGTARGET, .proc/hostile_attackingtarget)
-
-/datum/component/summoning/UnregisterFromParent()
- UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT))
-
-/datum/component/summoning/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
- if(!(clickchain_flags & CLICKCHAIN_HAS_PROXIMITY))
- return
- do_spawn_mob(get_turf(target), user)
-
-/datum/component/summoning/proc/hostile_attackingtarget(mob/living/simple_animal/hostile/attacker, atom/target)
- do_spawn_mob(get_turf(target), attacker)
-
-/datum/component/summoning/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle)
- do_spawn_mob(get_turf(target), firer)
-
-/datum/component/summoning/proc/do_spawn_mob(atom/spawn_location, summoner)
- if(spawned_mobs.len >= max_mobs)
- return 0
- if(last_spawned_time > world.time)
- return 0
- if(!prob(spawn_chance))
- return 0
- last_spawned_time = world.time + spawn_delay
- var/chosen_mob_type = pick(mob_types)
- var/mob/living/simple_animal/L = new chosen_mob_type(spawn_location)
- if(ishostile(L))
- var/mob/living/simple_animal/hostile/H = L
- H.friends += summoner // do not attack our summon boy
- spawned_mobs += L
- if(faction != null)
- L.faction = faction
- RegisterSignal(L, COMSIG_MOB_DEATH, .proc/on_spawned_death) // so we can remove them from the list, etc (for mobs with corpses)
- playsound(spawn_location,spawn_sound, 50, TRUE)
- spawn_location.visible_message("[L] [spawn_text].")
-
-/datum/component/summoning/proc/on_spawned_death(mob/killed, gibbed)
- spawned_mobs -= killed
diff --git a/code/datums/components/swarming.dm b/code/datums/components/swarming.dm
deleted file mode 100644
index 16ddc66280e..00000000000
--- a/code/datums/components/swarming.dm
+++ /dev/null
@@ -1,55 +0,0 @@
-/datum/component/swarming
- var/offset_x = 0
- var/offset_y = 0
- var/is_swarming = FALSE
- var/list/swarm_members = list()
-
-/datum/component/swarming/Initialize(max_x = 24, max_y = 24)
- if(!ismovable(parent))
- return COMPONENT_INCOMPATIBLE
- offset_x = rand(-max_x, max_x)
- offset_y = rand(-max_y, max_y)
-
- RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/join_swarm)
- RegisterSignal(parent, COMSIG_MOVABLE_UNCROSSED, .proc/leave_swarm)
-
-/datum/component/swarming/Destroy()
- for(var/other in swarm_members)
- var/datum/component/swarming/other_swarm = other
- other_swarm.swarm_members -= src
- if(!other_swarm.swarm_members.len)
- other_swarm.unswarm()
- swarm_members = null
- return ..()
-
-/datum/component/swarming/proc/join_swarm(datum/source, atom/movable/AM)
- var/datum/component/swarming/other_swarm = AM.GetComponent(/datum/component/swarming)
- if(!other_swarm)
- return
- swarm()
- swarm_members |= other_swarm
- other_swarm.swarm()
- other_swarm.swarm_members |= src
-
-/datum/component/swarming/proc/leave_swarm(datum/source, atom/movable/AM)
- var/datum/component/swarming/other_swarm = AM.GetComponent(/datum/component/swarming)
- if(!other_swarm || !(other_swarm in swarm_members))
- return
- swarm_members -= other_swarm
- if(!swarm_members.len)
- unswarm()
- other_swarm.swarm_members -= src
- if(!other_swarm.swarm_members.len)
- other_swarm.unswarm()
-
-/datum/component/swarming/proc/swarm()
- var/atom/movable/owner = parent
- if(!is_swarming)
- is_swarming = TRUE
- animate(owner, pixel_x = owner.pixel_x + offset_x, pixel_y = owner.pixel_y + offset_y, time = 2)
-
-/datum/component/swarming/proc/unswarm()
- var/atom/movable/owner = parent
- if(is_swarming)
- animate(owner, pixel_x = owner.pixel_x - offset_x, pixel_y = owner.pixel_y - offset_y, time = 2)
- is_swarming = FALSE
diff --git a/code/datums/components/tactical.dm b/code/datums/components/tactical.dm
deleted file mode 100644
index 7c742a769b4..00000000000
--- a/code/datums/components/tactical.dm
+++ /dev/null
@@ -1,41 +0,0 @@
-/datum/component/tactical
- var/allowed_slot
-
-/datum/component/tactical/Initialize(allowed_slot)
- if(!isitem(parent))
- return COMPONENT_INCOMPATIBLE
-
- src.allowed_slot = allowed_slot
-
-/datum/component/tactical/RegisterWithParent()
- RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/modify)
- RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/unmodify)
-
-/datum/component/tactical/UnregisterFromParent()
- UnregisterSignal(parent, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED))
- unmodify()
-
-/datum/component/fantasy/Destroy()
- unmodify()
- return ..()
-
-/datum/component/tactical/proc/modify(obj/item/source, mob/user, slot)
- if(allowed_slot && slot != allowed_slot)
- unmodify()
- return
-
- var/obj/item/master = parent
- var/image/I = image(icon = master.icon, icon_state = master.icon_state, loc = user)
- I.copy_overlays(master)
- I.override = TRUE
- source.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/everyone, "sneaking_mission", I)
- I.layer = ABOVE_MOB_LAYER
-
-/datum/component/tactical/proc/unmodify(obj/item/source, mob/user)
- var/obj/item/master = source || parent
- if(!user)
- if(!ismob(master.loc))
- return
- user = master.loc
-
- user.remove_alt_appearance("sneaking_mission")
diff --git a/code/datums/components/tether.dm b/code/datums/components/tether.dm
deleted file mode 100644
index faa6182208a..00000000000
--- a/code/datums/components/tether.dm
+++ /dev/null
@@ -1,37 +0,0 @@
-/datum/component/tether
- dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
- var/atom/tether_target
- var/max_dist
- var/tether_name
-
-/datum/component/tether/Initialize(atom/tether_target, max_dist = 4, tether_name)
- if(!isliving(parent) || !istype(tether_target) || !tether_target.loc)
- return COMPONENT_INCOMPATIBLE
- src.tether_target = tether_target
- src.max_dist = max_dist
- if (ispath(tether_name, /atom))
- var/atom/tmp = tether_name
- src.tether_name = initial(tmp.name)
- else
- src.tether_name = tether_name
- RegisterSignal(parent, list(COMSIG_MOVABLE_PRE_MOVE), .proc/checkTether)
-
-/datum/component/tether/proc/checkTether(mob/mover, newloc)
- if (get_dist(mover,newloc) > max_dist)
- to_chat(mover, "The [tether_name] runs out of slack and prevents you from moving!")
- return COMPONENT_MOVABLE_BLOCK_PRE_MOVE
-
- var/atom/blocker
- out:
- for(var/turf/T in getline(tether_target,newloc))
- if (T.density)
- blocker = T
- break out
- for(var/a in T)
- var/atom/A = a
- if(A.density && A != mover && A != tether_target)
- blocker = A
- break out
- if (blocker)
- to_chat(mover, "The [tether_name] catches on [blocker] and prevents you from moving!")
- return COMPONENT_MOVABLE_BLOCK_PRE_MOVE
diff --git a/code/datums/components/thermite.dm b/code/datums/components/thermite.dm
deleted file mode 100644
index 5a6dfcd0183..00000000000
--- a/code/datums/components/thermite.dm
+++ /dev/null
@@ -1,92 +0,0 @@
-/datum/component/thermite
- dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
- var/amount
- var/burn_require
- var/overlay
-
- var/static/list/blacklist = typecacheof(list(
- /turf/open/lava,
- /turf/space,
- /turf/open/water,
- /turf/open/chasm)
- )
-
- var/static/list/immunelist = typecacheof(list(
- /turf/closed/wall/mineral/diamond,
- /turf/closed/indestructible,
- /turf/open/indestructible)
- )
-
- var/static/list/resistlist = typecacheof(
- /turf/closed/wall/r_wall
- )
-
-/datum/component/thermite/Initialize(_amount)
- if(!istype(parent, /turf) || blacklist[parent.type])
- return COMPONENT_INCOMPATIBLE
-
- if(immunelist[parent.type])
- amount = 0 //Yeah the overlay can still go on it and be cleaned but you arent burning down a diamond wall
- else
- amount = _amount
- if(resistlist[parent.type])
- burn_require = 50
- else
- burn_require = 30
-
- var/turf/master = parent
- overlay = mutable_appearance('icons/effects/effects.dmi', "thermite")
- master.add_overlay(overlay)
-
- RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
- RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/attackby_react)
- RegisterSignal(parent, COMSIG_ATOM_FIRE_ACT, .proc/flame_react)
-
-/datum/component/thermite/UnregisterFromParent()
- UnregisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT)
- UnregisterSignal(parent, COMSIG_PARENT_ATTACKBY)
- UnregisterSignal(parent, COMSIG_ATOM_FIRE_ACT)
-
-/datum/component/thermite/Destroy()
- var/turf/master = parent
- master.cut_overlay(overlay)
- return ..()
-
-/datum/component/thermite/InheritComponent(datum/component/thermite/newC, i_am_original, list/arguments)
- if(!i_am_original)
- return
- if(newC)
- amount += newC.amount
- else
- amount += arguments[1]
-
-/datum/component/thermite/proc/thermite_melt(mob/user)
- var/turf/master = parent
- master.cut_overlay(overlay)
- playsound(master, 'sound/items/welder.ogg', 100, TRUE)
- var/obj/effect/overlay/thermite/fakefire = new(master)
- addtimer(CALLBACK(src, .proc/burn_parent, fakefire, user), min(amount * 0.35 SECONDS, 20 SECONDS))
- UnregisterFromParent()
-
-/datum/component/thermite/proc/burn_parent(var/datum/fakefire, mob/user)
- var/turf/master = parent
- if(!QDELETED(fakefire))
- qdel(fakefire)
- if(user)
- master.add_hiddenprint(user)
- if(amount >= burn_require)
- master = master.Melt()
- master.burn_tile()
- qdel(src)
-
-/datum/component/thermite/proc/clean_react(datum/source, strength)
- //Thermite is just some loose powder, you could probably clean it with your hands. << todo?
- qdel(src)
-
-/datum/component/thermite/proc/flame_react(datum/source, exposed_temperature, exposed_volume)
- if(exposed_temperature > 1922) // This is roughly the real life requirement to ignite thermite
- thermite_melt()
-
-/datum/component/thermite/proc/attackby_react(datum/source, obj/item/thing, mob/user, params)
- if(thing.is_hot())
- thermite_melt(user)
diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm
deleted file mode 100644
index fb514bb432f..00000000000
--- a/code/datums/components/uplink.dm
+++ /dev/null
@@ -1,318 +0,0 @@
-GLOBAL_LIST_EMPTY(uplinks)
-
-#define PEN_ROTATIONS 2
-
-/**
- * Uplinks
- *
- * All /obj/item(s) have a hidden_uplink var. By default it's null. Give the item one with 'new(src') (it must be in it's contents). Then add 'uses.'
- * Use whatever conditionals you want to check that the user has an uplink, and then call interact() on their uplink.
- * You might also want the uplink menu to open if active. Check if the uplink is 'active' and then interact() with it.
-**/
-/datum/component/uplink
- dupe_mode = COMPONENT_DUPE_UNIQUE
- var/name = "syndicate uplink"
- var/active = FALSE
- var/lockable = TRUE
- var/locked = TRUE
- var/allow_restricted = TRUE
- var/telecrystals
- var/selected_cat
- var/owner = null
- var/datum/game_mode/gamemode
- var/datum/uplink_purchase_log/purchase_log
- var/list/uplink_items
- var/hidden_crystals = 0
- var/unlock_note
- var/unlock_code
- var/failsafe_code
-
- var/list/previous_attempts
-
-/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20)
- if(!isitem(parent))
- return COMPONENT_INCOMPATIBLE
-
-
- RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
- RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/interact)
- if(istype(parent, /obj/item/implant))
- RegisterSignal(parent, COMSIG_IMPLANT_ACTIVATED, .proc/implant_activation)
- RegisterSignal(parent, COMSIG_IMPLANT_IMPLANTING, .proc/implanting)
- RegisterSignal(parent, COMSIG_IMPLANT_OTHER, .proc/old_implant)
- RegisterSignal(parent, COMSIG_IMPLANT_EXISTING_UPLINK, .proc/new_implant)
- else if(istype(parent, /obj/item/pda))
- RegisterSignal(parent, COMSIG_PDA_CHANGE_RINGTONE, .proc/new_ringtone)
- RegisterSignal(parent, COMSIG_PDA_CHECK_DETONATE, .proc/check_detonate)
- else if(istype(parent, /obj/item/radio))
- RegisterSignal(parent, COMSIG_RADIO_NEW_FREQUENCY, .proc/new_frequency)
- else if(istype(parent, /obj/item/pen))
- RegisterSignal(parent, COMSIG_PEN_ROTATED, .proc/pen_rotation)
-
- GLOB.uplinks += src
- uplink_items = get_uplink_items(_gamemode, TRUE, allow_restricted)
-
- if(_owner)
- owner = _owner
- LAZYINITLIST(GLOB.uplink_purchase_logs_by_key)
- if(GLOB.uplink_purchase_logs_by_key[owner])
- purchase_log = GLOB.uplink_purchase_logs_by_key[owner]
- else
- purchase_log = new(owner, src)
- lockable = _lockable
- active = _enabled
- gamemode = _gamemode
- telecrystals = starting_tc
- if(!lockable)
- active = TRUE
- locked = FALSE
-
- previous_attempts = list()
-
-/datum/component/uplink/InheritComponent(datum/component/uplink/U)
- lockable |= U.lockable
- active |= U.active
- if(!gamemode)
- gamemode = U.gamemode
- telecrystals += U.telecrystals
- if(purchase_log && U.purchase_log)
- purchase_log.MergeWithAndDel(U.purchase_log)
-
-/datum/component/uplink/Destroy()
- GLOB.uplinks -= src
- gamemode = null
- purchase_log = null
- return ..()
-
-/datum/component/uplink/proc/LoadTC(mob/user, obj/item/stack/telecrystal/TC, silent = FALSE)
- if(!silent)
- to_chat(user, "You slot [TC] into [parent] and charge its internal uplink.")
- var/amt = TC.amount
- telecrystals += amt
- TC.use(amt)
-
-/datum/component/uplink/proc/set_gamemode(_gamemode)
- gamemode = _gamemode
- uplink_items = get_uplink_items(gamemode, TRUE, allow_restricted)
-
-/datum/component/uplink/proc/OnAttackBy(datum/source, obj/item/I, mob/user)
- if(!active)
- return //no hitting everyone/everything just to try to slot tcs in!
- if(istype(I, /obj/item/stack/telecrystal))
- LoadTC(user, I)
- for(var/category in uplink_items)
- for(var/item in uplink_items[category])
- var/datum/uplink_item/UI = uplink_items[category][item]
- var/path = UI.refund_path || UI.item
- var/cost = UI.refund_amount || UI.cost
- if(I.type == path && UI.refundable && I.check_uplink_validity())
- telecrystals += cost
- if(purchase_log)
- purchase_log.total_spent -= cost
- to_chat(user, "[I] refunded.")
- qdel(I)
- return
-
-/datum/component/uplink/proc/interact(datum/source, mob/user)
- if(locked)
- return
- active = TRUE
- if(user)
- nano_ui_interact(user)
- // an unlocked uplink blocks also opening the PDA or headset menu
- return COMPONENT_NO_INTERACT
-
-/datum/component/uplink/nano_ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
- datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state)
- active = TRUE
- ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
- if(!ui)
- ui = new(user, src, ui_key, "uplink", name, 450, 750, master_ui, state)
- ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input.
- ui.set_style("syndicate")
- ui.open()
-
-/datum/component/uplink/ui_data(mob/user)
- if(!user.mind)
- return
- var/list/data = list()
- data["telecrystals"] = telecrystals
- data["lockable"] = lockable
-
- data["categories"] = list()
- for(var/category in uplink_items)
- var/list/cat = list(
- "name" = category,
- "items" = (category == selected_cat ? list() : null))
- if(category == selected_cat)
- for(var/item in uplink_items[category])
- var/datum/uplink_item/I = uplink_items[category][item]
- if(I.limited_stock == 0)
- continue
- if(I.restricted_roles.len)
- var/is_inaccessible = 1
- for(var/R in I.restricted_roles)
- if(R == user.mind.assigned_role)
- is_inaccessible = 0
- if(is_inaccessible)
- continue
- if(I.restricted_species)
- if(ishuman(user))
- var/is_inaccessible = TRUE
- var/mob/living/carbon/human/H = user
- for(var/F in I.restricted_species)
- if(F == H.dna.species.id)
- is_inaccessible = FALSE
- break
- if(is_inaccessible)
- continue
- cat["items"] += list(list(
- "name" = I.name,
- "cost" = I.cost,
- "desc" = I.desc,
- ))
- data["categories"] += list(cat)
- return data
-
-/datum/component/uplink/ui_act(action, params)
- if(!active)
- return
-
- switch(action)
- if("buy")
- var/item = params["item"]
-
- var/list/buyable_items = list()
- for(var/category in uplink_items)
- buyable_items += uplink_items[category]
-
- if(item in buyable_items)
- var/datum/uplink_item/I = buyable_items[item]
- MakePurchase(usr, I)
- . = TRUE
- if("lock")
- active = FALSE
- locked = TRUE
- telecrystals += hidden_crystals
- hidden_crystals = 0
- SStgui.close_uis(src)
- if("select")
- selected_cat = params["category"]
- return TRUE
-
-/datum/component/uplink/proc/MakePurchase(mob/user, datum/uplink_item/U)
- if(!istype(U))
- return
- if (!user || user.incapacitated())
- return
-
- if(telecrystals < U.cost || U.limited_stock == 0)
- return
- telecrystals -= U.cost
-
- U.purchase(user, src)
-
- if(U.limited_stock > 0)
- U.limited_stock -= 1
-
- SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(U.name)]", "[U.cost]"))
- return TRUE
-
-// Implant signal responses
-
-/datum/component/uplink/proc/implant_activation()
- var/obj/item/implant/implant = parent
- locked = FALSE
- interact(null, implant.imp_in)
-
-/datum/component/uplink/proc/implanting(datum/source, list/arguments)
- var/mob/user = arguments[2]
- owner = "[user.key]"
-
-/datum/component/uplink/proc/old_implant(datum/source, list/arguments, obj/item/implant/new_implant)
- // It kinda has to be weird like this until implants are components
- return SEND_SIGNAL(new_implant, COMSIG_IMPLANT_EXISTING_UPLINK, src)
-
-/datum/component/uplink/proc/new_implant(datum/source, datum/component/uplink/uplink)
- uplink.telecrystals += telecrystals
- return COMPONENT_DELETE_NEW_IMPLANT
-
-// PDA signal responses
-
-/datum/component/uplink/proc/new_ringtone(datum/source, mob/living/user, new_ring_text)
- var/obj/item/pda/master = parent
- if(trim(lowertext(new_ring_text)) != trim(lowertext(unlock_code)))
- if(trim(lowertext(new_ring_text)) == trim(lowertext(failsafe_code)))
- failsafe()
- return COMPONENT_STOP_RINGTONE_CHANGE
- return
- locked = FALSE
- interact(null, user)
- to_chat(user, "The PDA softly beeps.")
- user << browse(null, "window=pda")
- master.mode = 0
- return COMPONENT_STOP_RINGTONE_CHANGE
-
-/datum/component/uplink/proc/check_detonate()
- return COMPONENT_PDA_NO_DETONATE
-
-// Radio signal responses
-
-/datum/component/uplink/proc/new_frequency(datum/source, list/arguments)
- var/obj/item/radio/master = parent
- var/frequency = arguments[1]
- if(frequency != unlock_code)
- if(frequency == failsafe_code)
- failsafe()
- return
- locked = FALSE
- if(ismob(master.loc))
- interact(null, master.loc)
-
-// Pen signal responses
-
-/datum/component/uplink/proc/pen_rotation(datum/source, degrees, mob/living/carbon/user)
- var/obj/item/pen/master = parent
- previous_attempts += degrees
- if(length(previous_attempts) > PEN_ROTATIONS)
- popleft(previous_attempts)
-
- if(compare_list(previous_attempts, unlock_code))
- locked = FALSE
- previous_attempts.Cut()
- master.degrees = 0
- interact(null, user)
- to_chat(user, "Your pen makes a clicking noise, before quickly rotating back to 0 degrees!")
-
- else if(compare_list(previous_attempts, failsafe_code))
- failsafe()
-
-/datum/component/uplink/proc/setup_unlock_code()
- unlock_code = generate_code()
- var/obj/item/P = parent
- if(istype(parent,/obj/item/pda))
- unlock_note = "Uplink Passcode: [unlock_code] ([P.name])."
- else if(istype(parent,/obj/item/radio))
- unlock_note = "Radio Frequency: [format_frequency(unlock_code)] ([P.name])."
- else if(istype(parent,/obj/item/pen))
- unlock_note = "Uplink Degrees: [english_list(unlock_code)] ([P.name])."
-
-/datum/component/uplink/proc/generate_code()
- if(istype(parent,/obj/item/pda))
- return "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]"
- else if(istype(parent,/obj/item/radio))
- return sanitize_frequency(rand(MIN_FREQ, MAX_FREQ))
- else if(istype(parent,/obj/item/pen))
- var/list/L = list()
- for(var/i in 1 to PEN_ROTATIONS)
- L += rand(1, 360)
- return L
-
-/datum/component/uplink/proc/failsafe()
- if(!parent)
- return
- var/turf/T = get_turf(parent)
- if(!T)
- return
- explosion(T,1,2,3)
- qdel(parent) //Alternatively could brick the uplink.
diff --git a/code/datums/components/waddling.dm b/code/datums/components/waddling.dm
deleted file mode 100644
index 13a36c9473d..00000000000
--- a/code/datums/components/waddling.dm
+++ /dev/null
@@ -1,22 +0,0 @@
-/datum/component/waddling
- dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
-
-/datum/component/waddling/Initialize()
- . = ..()
- if(!ismovable(parent))
- return COMPONENT_INCOMPATIBLE
- if(isliving(parent))
- RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/LivingWaddle)
- else
- RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/Waddle)
-
-/datum/component/waddling/proc/LivingWaddle()
- var/mob/living/L = parent
- if(L.incapacitated() || !(L.mobility_flags & MOBILITY_IS_STANDING))
- return
- Waddle()
-
-/datum/component/waddling/proc/Waddle()
- animate(parent, pixel_z = 4, time = 0)
- animate(pixel_z = 0, transform = turn(matrix(), pick(-12, 0, 12)), time=2)
- animate(pixel_z = 0, transform = matrix(), time = 0)
diff --git a/code/datums/components/wearertargeting.dm b/code/datums/components/wearertargeting.dm
deleted file mode 100644
index 4760757701f..00000000000
--- a/code/datums/components/wearertargeting.dm
+++ /dev/null
@@ -1,22 +0,0 @@
-// A dummy parent type used for easily making components that target an item's wearer rather than the item itself.
-
-/datum/component/wearertargeting
- var/list/valid_slots = list()
- var/list/signals = list()
- var/proctype = .proc/pass
- var/mobtype = /mob/living
-
-/datum/component/wearertargeting/Initialize()
- if(!isitem(parent))
- return COMPONENT_INCOMPATIBLE
- RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
- RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
-
-/datum/component/wearertargeting/proc/on_equip(datum/source, mob/equipper, slot)
- if((slot in valid_slots) && istype(equipper, mobtype))
- RegisterSignal(equipper, signals, proctype, TRUE)
- else
- UnregisterSignal(equipper, signals)
-
-/datum/component/wearertargeting/proc/on_drop(datum/source, mob/user)
- UnregisterSignal(user, signals)
diff --git a/code/datums/components/wet_floor.dm b/code/datums/components/wet_floor.dm
deleted file mode 100644
index b5845ffa306..00000000000
--- a/code/datums/components/wet_floor.dm
+++ /dev/null
@@ -1,207 +0,0 @@
-/datum/component/wet_floor
- dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
- can_transfer = TRUE
- var/highest_strength = TURF_DRY
- var/lube_flags = NONE //why do we have this?
- var/list/time_left_list //In deciseconds.
- var/static/mutable_appearance/permafrost_overlay = mutable_appearance('icons/effects/water.dmi', "ice_floor")
- var/static/mutable_appearance/ice_overlay = mutable_appearance('icons/turf/overlays.dmi', "snowfloor")
- var/static/mutable_appearance/water_overlay = mutable_appearance('icons/effects/water.dmi', "wet_floor_static")
- var/static/mutable_appearance/generic_turf_overlay = mutable_appearance('icons/effects/water.dmi', "wet_static")
- var/current_overlay
- var/permanent = FALSE
- var/last_process = 0
-
-/datum/component/wet_floor/InheritComponent(datum/newcomp, orig, argslist)
- if(!newcomp) //We are getting passed the arguments of a would-be new component, but not a new component
- add_wet(arglist(argslist))
- 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.
- CRASH("Wet floor component tried to inherit another, but the other was able to garbage collect while being inherited! What a waste of time!")
- return
- for(var/i in WF.time_left_list)
- add_wet(text2num(i), WF.time_left_list[i])
-
-/datum/component/wet_floor/Initialize(strength, duration_minimum, duration_add, duration_maximum, _permanent = FALSE)
- if(!isopenturf(parent))
- return COMPONENT_INCOMPATIBLE
- add_wet(strength, duration_minimum, duration_add, duration_maximum)
- permanent = _permanent
- if(!permanent)
- START_PROCESSING(SSwet_floors, src)
- addtimer(CALLBACK(src, .proc/gc, TRUE), 1) //GC after initialization.
- last_process = world.time
-
-/datum/component/wet_floor/RegisterWithParent()
- RegisterSignal(parent, COMSIG_TURF_IS_WET, .proc/is_wet)
- RegisterSignal(parent, COMSIG_TURF_MAKE_DRY, .proc/dry)
-
-/datum/component/wet_floor/UnregisterFromParent()
- UnregisterSignal(parent, list(COMSIG_TURF_IS_WET, COMSIG_TURF_MAKE_DRY))
-
-/datum/component/wet_floor/Destroy()
- STOP_PROCESSING(SSwet_floors, src)
- var/turf/T = parent
- qdel(T.GetComponent(/datum/component/slippery))
- if(istype(T)) //If this is false there is so many things wrong with it.
- T.cut_overlay(current_overlay)
- else
- stack_trace("Warning: Wet floor component wasn't on a turf when being destroyed! This is really bad!")
- return ..()
-
-/datum/component/wet_floor/proc/update_overlay()
- var/intended
- if(!istype(parent, /turf/open/floor))
- intended = generic_turf_overlay
- else
- switch(highest_strength)
- if(TURF_WET_PERMAFROST)
- intended = permafrost_overlay
- if(TURF_WET_ICE)
- intended = ice_overlay
- else
- intended = water_overlay
- if(current_overlay != intended)
- var/turf/T = parent
- T.cut_overlay(current_overlay)
- T.add_overlay(intended)
- current_overlay = intended
-
-/datum/component/wet_floor/proc/AfterSlip(mob/living/L)
- if(highest_strength == TURF_WET_LUBE)
- L.confused = max(L.confused, 8)
-
-/datum/component/wet_floor/proc/update_flags()
- var/intensity
- lube_flags = NONE
- switch(highest_strength)
- if(TURF_WET_WATER)
- intensity = 60
- lube_flags = NO_SLIP_WHEN_WALKING
- if(TURF_WET_LUBE)
- intensity = 80
- lube_flags = SLIDE | GALOSHES_DONT_HELP
- if(TURF_WET_ICE)
- intensity = 120
- lube_flags = SLIDE | GALOSHES_DONT_HELP
- if(TURF_WET_PERMAFROST)
- intensity = 120
- lube_flags = SLIDE_ICE | GALOSHES_DONT_HELP
- if(TURF_WET_SUPERLUBE)
- intensity = 120
- lube_flags = SLIDE | GALOSHES_DONT_HELP | SLIP_WHEN_CRAWLING
- else
- qdel(parent.GetComponent(/datum/component/slippery))
- return
-
- parent.LoadComponent(/datum/component/slippery, intensity, lube_flags, CALLBACK(src, .proc/AfterSlip))
-
-/datum/component/wet_floor/proc/dry(datum/source, strength = TURF_WET_WATER, immediate = FALSE, duration_decrease = INFINITY)
- for(var/i in time_left_list)
- if(text2num(i) <= strength)
- time_left_list[i] = max(0, time_left_list[i] - duration_decrease)
- if(immediate)
- check()
-
-/datum/component/wet_floor/proc/max_time_left()
- . = 0
- for(var/i in time_left_list)
- . = max(., time_left_list[i])
-
-/datum/component/wet_floor/process(delta_time)
- var/turf/open/T = parent
- var/diff = world.time - last_process
- var/decrease = 0
- var/t = T.GetTemperature()
- switch(t)
- if(-INFINITY to T0C)
- add_wet(TURF_WET_ICE, max_time_left()) //Water freezes into ice!
- if(T0C to T0C + 100)
- decrease = ((T.air.temperature - T0C) / SSwet_floors.temperature_coeff) * (diff / SSwet_floors.time_ratio)
- if(T0C + 100 to INFINITY)
- decrease = INFINITY
- decrease = max(0, decrease)
- if((is_wet() & TURF_WET_ICE) && t > T0C) //Ice melts into water!
- for(var/obj/O in T.contents)
- if(O.obj_flags & FROZEN)
- O.make_unfrozen()
- add_wet(TURF_WET_WATER, max_time_left())
- dry(null, TURF_WET_ICE)
- dry(null, ALL, FALSE, decrease)
- check()
- last_process = world.time
-
-/datum/component/wet_floor/proc/update_strength()
- highest_strength = 0 //Not bitflag.
- for(var/i in time_left_list)
- highest_strength = max(highest_strength, text2num(i))
-
-/datum/component/wet_floor/proc/is_wet()
- . = 0
- for(var/i in time_left_list)
- . |= text2num(i)
-
-/datum/component/wet_floor/PreTransfer()
- var/turf/O = parent
- O.cut_overlay(current_overlay)
- //That turf is no longer slippery, we're out of here
- //Slippery components don't transfer due to callbacks
- qdel(O.GetComponent(/datum/component/slippery))
-
-/datum/component/wet_floor/PostTransfer()
- if(!isopenturf(parent))
- return COMPONENT_INCOMPATIBLE
- var/turf/T = parent
- T.add_overlay(current_overlay)
- //Make sure to add/update any slippery component on the new turf (update_flags calls LoadComponent)
- update_flags()
-
- //NB it's possible we get deleted after this, due to inherit
-
-/datum/component/wet_floor/proc/add_wet(type, duration_minimum = 0, duration_add = 0, duration_maximum = MAXIMUM_WET_TIME, _permanent = FALSE)
- var/static/list/allowed_types = list(TURF_WET_WATER, TURF_WET_LUBE, TURF_WET_ICE, TURF_WET_PERMAFROST, TURF_WET_SUPERLUBE)
- if(duration_minimum <= 0 || !type)
- return FALSE
- if(type in allowed_types)
- return _do_add_wet(type, duration_minimum, duration_add, duration_maximum)
- else
- . = NONE
- for(var/i in allowed_types)
- if(!(type & i))
- continue
- . |= _do_add_wet(i, duration_minimum, duration_add, duration_maximum)
- if(_permanent)
- permanent = TRUE
- STOP_PROCESSING(SSwet_floors, src)
-
-/datum/component/wet_floor/proc/_do_add_wet(type, duration_minimum, duration_add, duration_maximum)
- var/time = 0
- if(LAZYACCESS(time_left_list, "[type]"))
- time = clamp(LAZYACCESS(time_left_list, "[type]") + duration_add, duration_minimum, duration_maximum)
- else
- time = min(duration_minimum, duration_maximum)
- LAZYSET(time_left_list, "[type]", time)
- check(TRUE)
- return TRUE
-
-/datum/component/wet_floor/proc/gc(on_init = FALSE)
- if(!LAZYLEN(time_left_list))
- if(on_init)
- var/turf/T = parent
- stack_trace("Warning: Wet floor component gc'd right after initialization! What a waste of time and CPU! Type = [T? T.type : "ERROR - NO PARENT"], Location = [istype(T)? AREACOORD(T) : "ERROR - INVALID PARENT"].")
- qdel(src)
- return TRUE
- return FALSE
-
-/datum/component/wet_floor/proc/check(force_update = FALSE)
- var/changed = FALSE
- for(var/i in time_left_list)
- if(time_left_list[i] <= 0)
- time_left_list -= i
- changed = TRUE
- if(changed || force_update)
- update_strength()
- update_overlay()
- update_flags()
- gc()
diff --git a/code/datums/elements/cleaning.dm b/code/datums/elements/cleaning.dm
deleted file mode 100644
index 96ade07744b..00000000000
--- a/code/datums/elements/cleaning.dm
+++ /dev/null
@@ -1,41 +0,0 @@
-/datum/element/cleaning/Attach(datum/target)
- . = ..()
- if(!ismovable(target))
- return ELEMENT_INCOMPATIBLE
- RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/Clean)
-
-/datum/element/cleaning/Detach(datum/target)
- . = ..()
- UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
-
-/datum/element/cleaning/proc/Clean(datum/source)
- var/atom/movable/AM = source
- var/turf/tile = AM.loc
- if(!isturf(tile))
- return
-
- SEND_SIGNAL(tile, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- for(var/A in tile)
- if(is_cleanable(A))
- qdel(A)
- else if(istype(A, /obj/item))
- var/obj/item/I = A
- SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- if(ismob(I.loc))
- var/mob/M = I.loc
- M.regenerate_icons()
- else if(ishuman(A))
- var/mob/living/carbon/human/cleaned_human = A
- if(!(cleaned_human.mobility_flags & MOBILITY_IS_STANDING))
- if(cleaned_human.head)
- SEND_SIGNAL(cleaned_human.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- if(cleaned_human.wear_suit)
- SEND_SIGNAL(cleaned_human.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- else if(cleaned_human.w_uniform)
- SEND_SIGNAL(cleaned_human.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- if(cleaned_human.shoes)
- SEND_SIGNAL(cleaned_human.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- SEND_SIGNAL(cleaned_human, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- cleaned_human.wash_cream()
- cleaned_human.regenerate_icons()
- to_chat(cleaned_human, "[AM] cleans your face!")
diff --git a/code/datums/elements/digitalcamo.dm b/code/datums/elements/digitalcamo.dm
deleted file mode 100644
index b264da40a99..00000000000
--- a/code/datums/elements/digitalcamo.dm
+++ /dev/null
@@ -1,35 +0,0 @@
-/datum/element/digitalcamo
- element_flags = ELEMENT_DETACH
- var/list/attached_mobs = list()
-
-/datum/element/digitalcamo/New()
- . = ..()
- START_PROCESSING(SSdcs, src)
-
-/datum/element/digitalcamo/Attach(datum/target)
- . = ..()
- if(!isliving(target) || target in attached_mobs)
- return ELEMENT_INCOMPATIBLE
- RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_examine)
- RegisterSignal(target, COMSIG_LIVING_CAN_TRACK, .proc/can_track)
- var/image/img = image(loc = target)
- img.override = TRUE
- attached_mobs[target] = img
-
-/datum/element/digitalcamo/Detach(datum/target)
- . = ..()
- UnregisterSignal(target, list(COMSIG_PARENT_EXAMINE, COMSIG_LIVING_CAN_TRACK))
- for(var/mob/living/silicon/ai/AI in GLOB.GLOB.player_list)
- AI.client.images -= attached_mobs[target]
- attached_mobs -= target
-
-/datum/element/digitalcamo/proc/on_examine(datum/source, mob/M)
- to_chat(M, "[source.p_their()] skin seems to be shifting and morphing like is moving around below it.")
-
-/datum/element/digitalcamo/proc/can_track(datum/source)
- return COMPONENT_CANT_TRACK
-
-/datum/element/digitalcamo/process(delta_time)
- for(var/mob/living/silicon/ai/AI in GLOB.GLOB.player_list)
- for(var/mob in attached_mobs)
- AI.client.images |= attached_mobs[mob]
diff --git a/code/datums/elements/earhealing.dm b/code/datums/elements/earhealing.dm
deleted file mode 100644
index bfe7a1cc3c7..00000000000
--- a/code/datums/elements/earhealing.dm
+++ /dev/null
@@ -1,36 +0,0 @@
-/datum/element/earhealing
- element_flags = ELEMENT_DETACH
- var/list/user_by_item = list()
-
-/datum/element/earhealing/New()
- START_PROCESSING(SSdcs, src)
-
-/datum/element/earhealing/Attach(datum/target)
- . = ..()
- if(!isitem(target))
- return ELEMENT_INCOMPATIBLE
-
- RegisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), .proc/equippedChanged)
-
-/datum/element/earhealing/Detach(datum/target)
- . = ..()
- UnregisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED))
- user_by_item -= target
-
-/datum/element/earhealing/proc/equippedChanged(datum/source, mob/living/carbon/user, slot)
- if(slot == SLOT_EARS && istype(user))
- user_by_item[source] = user
- else
- user_by_item -= source
-
-/datum/element/earhealing/process(delta_time)
- for(var/i in user_by_item)
- var/mob/living/carbon/user = user_by_item[i]
- if(HAS_TRAIT(user, TRAIT_DEAF))
- continue
- var/obj/item/organ/ears/ears = user.getorganslot(ORGAN_SLOT_EARS)
- if(!ears)
- continue
- ears.deaf = max(ears.deaf - 0.25, (ears.damage < ears.maxHealth ? 0 : 1)) // Do not clear deafness if our ears are too damaged
- ears.damage = max(ears.damage - 0.025, 0)
- CHECK_TICK
diff --git a/code/datums/elements/firestacker.dm b/code/datums/elements/firestacker.dm
deleted file mode 100644
index fa24e3c2d6f..00000000000
--- a/code/datums/elements/firestacker.dm
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Can be applied to /atom/movable subtypes to make them apply fire stacks to things they hit
- */
-/datum/element/firestacker
- element_flags = ELEMENT_DETACH
- /// A list in format {atom/movable/owner, number}
- /// Used to keep track of movables which want to apply a different number of fire stacks than default
- var/list/amount_by_owner = list()
-
-/datum/element/firestacker/Attach(datum/target, amount)
- . = ..()
- if(!ismovable(target))
- return ELEMENT_INCOMPATIBLE
- RegisterSignal(target, COMSIG_MOVABLE_IMPACT, .proc/impact)
- if(isitem(target))
- RegisterSignal(target, COMSIG_ITEM_ATTACK, .proc/item_attack)
- RegisterSignal(target, COMSIG_ITEM_ATTACK_SELF, .proc/item_attack_self)
-
- if(amount) // If amount is not given we default to 1 and don't need to save it here
- amount_by_owner[target] = amount
-
-/datum/element/firestacker/Detach(datum/source, force)
- . = ..()
- UnregisterSignal(source, list(COMSIG_MOVABLE_IMPACT, COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_SELF))
- amount_by_owner -= source
-
-/datum/element/firestacker/proc/stack_on(datum/owner, mob/living/target)
- target.adjust_fire_stacks(amount_by_owner[owner] || 1)
-
-/datum/element/firestacker/proc/impact(datum/source, atom/hit_atom, datum/thrownthing/throwingdatum)
- if(isliving(hit_atom))
- stack_on(source, hit_atom)
-
-/datum/element/firestacker/proc/item_attack(datum/source, atom/movable/target, mob/living/user)
- if(isliving(target))
- stack_on(source, target)
-
-/datum/element/firestacker/proc/item_attack_self(datum/source, mob/user)
- if(isliving(user))
- stack_on(source, user)
diff --git a/code/datums/elements/light_blocking.dm b/code/datums/elements/light_blocking.dm
deleted file mode 100644
index 8b4863256ac..00000000000
--- a/code/datums/elements/light_blocking.dm
+++ /dev/null
@@ -1,44 +0,0 @@
-//! Prerequisites: Opacity Refactor @Zandario
-
-/**
- * Attached to movable atoms with opacity. Listens to them move and updates their old and new turf loc's opacity accordingly.
- */
-/datum/element/light_blocking
- element_flags = ELEMENT_DETACH
-
-
-/datum/element/light_blocking/Attach(datum/target)
- . = ..()
- if(!ismovable(target))
- return ELEMENT_INCOMPATIBLE
- // RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_target_move))
- RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/on_target_move)
- var/atom/movable/movable_target = target
- if(!isturf(movable_target.loc))
- return
- for(var/turf/turf_loc as anything in movable_target.locs)
- turf_loc.add_opacity_source(target)
-
-
-/datum/element/light_blocking/Detach(datum/target)
- . = ..()
- UnregisterSignal(target, list(COMSIG_MOVABLE_MOVED))
- var/atom/movable/movable_target = target
- if(!isturf(movable_target.loc))
- return
- for(var/turf/turf_loc as anything in movable_target.locs)
- turf_loc.remove_opacity_source(target)
-
-///Updates old and new turf loc opacities.
-/datum/element/light_blocking/proc/on_target_move(atom/movable/source, atom/old_loc, dir, forced, list/old_locs)
- SIGNAL_HANDLER
- if(isturf(old_loc))
- if(old_locs)
- for(var/turf/old_turf as anything in old_locs)
- old_turf.remove_opacity_source(source)
- else
- var/turf/old_turf = old_loc
- old_turf.remove_opacity_source(source)
- if(isturf(source.loc))
- for(var/turf/new_turf as anything in source.locs)
- new_turf.add_opacity_source(source)
diff --git a/code/datums/elements/snail_crawl.dm b/code/datums/elements/snail_crawl.dm
deleted file mode 100644
index 7447b7e59c8..00000000000
--- a/code/datums/elements/snail_crawl.dm
+++ /dev/null
@@ -1,31 +0,0 @@
-/datum/element/snailcrawl
- element_flags = ELEMENT_DETACH
-
-/datum/element/snailcrawl/Attach(datum/target)
- . = ..()
- if(!ismovable(target))
- return ELEMENT_INCOMPATIBLE
- var/P
- if(iscarbon(target))
- P = .proc/snail_crawl
- else
- P = .proc/lubricate
- RegisterSignal(target, COMSIG_MOVABLE_MOVED, P)
-
-/datum/element/snailcrawl/Detach(mob/living/carbon/target)
- . = ..()
- UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
- if(istype(target))
- target.remove_movespeed_modifier(MOVESPEED_ID_SNAIL_CRAWL)
-
-/datum/element/snailcrawl/proc/snail_crawl(mob/living/carbon/snail)
- if(snail.resting && !snail.buckled && lubricate(snail))
- snail.add_movespeed_modifier(MOVESPEED_ID_SNAIL_CRAWL, update=TRUE, priority=100, multiplicative_slowdown=-7, movement_type=MOVEMENT_GROUND)
- else
- snail.remove_movespeed_modifier(MOVESPEED_ID_SNAIL_CRAWL)
-
-/datum/element/snailcrawl/proc/lubricate(atom/movable/snail)
- var/turf/open/OT = get_turf(snail)
- if(istype(OT))
- OT.MakeSlippery(TURF_WET_LUBE, 20)
- return TRUE
diff --git a/code/datums/elements/update_icon_blocker.dm b/code/datums/elements/update_icon_blocker.dm
deleted file mode 100644
index 45206772564..00000000000
--- a/code/datums/elements/update_icon_blocker.dm
+++ /dev/null
@@ -1,18 +0,0 @@
-/// Prevents calling anything in update_icon() like update_icon_state() or update_overlays()
-/datum/element/update_icon_blocker
-
-/datum/element/update_icon_blocker/Attach(datum/target)
- . = ..()
- if(!isatom(target))
- return ELEMENT_INCOMPATIBLE
-
- RegisterSignal(target, COMSIG_ATOM_UPDATE_ICON, .proc/block_update_icon)
-
-/datum/element/update_icon_blocker/Detach(datum/source, ...)
- UnregisterSignal(source, COMSIG_ATOM_UPDATE_ICON)
- return ..()
-
-/datum/element/update_icon_blocker/proc/block_update_icon()
- SIGNAL_HANDLER
-
- return COMSIG_ATOM_NO_UPDATE_ICON_STATE | COMSIG_ATOM_NO_UPDATE_OVERLAYS