diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm
index a194a6ac9f..035fc845c4 100644
--- a/code/game/objects/effects/anomalies.dm
+++ b/code/game/objects/effects/anomalies.dm
@@ -26,6 +26,7 @@
aSignal = new(src)
aSignal.name = "[name] core"
aSignal.code = rand(1,100)
+ aSignal.anomaly_type = type
var/frequency = rand(MIN_FREE_FREQ, MAX_FREE_FREQ)
if(ISMULTIPLE(frequency, 2))//signaller frequencies are always uneven!
diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm
index c0af20ead6..c293439431 100644
--- a/code/modules/assembly/signaler.dm
+++ b/code/modules/assembly/signaler.dm
@@ -186,6 +186,7 @@ Code:
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
+ var/anomaly_type = /obj/effect/anomaly
/obj/item/assembly/signaler/anomaly/receive_signal(datum/signal/signal)
if(!signal)
diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm
index 37d48b484e..af6d2b6c5e 100644
--- a/code/modules/clothing/suits/armor.dm
+++ b/code/modules/clothing/suits/armor.dm
@@ -165,186 +165,6 @@
. = ..()
allowed = GLOB.detective_vest_allowed
-//Reactive armor
-/obj/item/clothing/suit/armor/reactive
- name = "reactive armor"
- desc = "Doesn't seem to do much for some reason."
- var/active = 0
- var/reactivearmor_cooldown_duration = 0 //cooldown specific to reactive armor
- var/reactivearmor_cooldown = 0
- icon_state = "reactiveoff"
- item_state = "reactiveoff"
- blood_overlay_type = "armor"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
- actions_types = list(/datum/action/item_action/toggle)
- resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
- hit_reaction_chance = 50
-
-
-/obj/item/clothing/suit/armor/reactive/attack_self(mob/user)
- src.active = !( src.active )
- if (src.active)
- to_chat(user, "[src] is now active.")
- src.icon_state = "reactive"
- src.item_state = "reactive"
- else
- to_chat(user, "[src] is now inactive.")
- src.icon_state = "reactiveoff"
- src.item_state = "reactiveoff"
- src.add_fingerprint(user)
- return
-
-/obj/item/clothing/suit/armor/reactive/emp_act(severity)
- active = 0
- src.icon_state = "reactiveoff"
- src.item_state = "reactiveoff"
- reactivearmor_cooldown = world.time + 200
- ..()
-
-//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!)
-/obj/item/clothing/suit/armor/reactive/teleport
- name = "reactive teleport armor"
- desc = "Someone separated our Research Director from his own head!"
- var/tele_range = 6
- var/rad_amount= 15
- reactivearmor_cooldown_duration = 100
-
-/obj/item/clothing/suit/armor/reactive/teleport/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- if(!active)
- return 0
- if(prob(hit_reaction_chance))
- var/mob/living/carbon/human/H = owner
- if(world.time < reactivearmor_cooldown)
- owner.visible_message("The reactive teleport system is still recharging! It fails to teleport [H]!")
- return
- owner.visible_message("The reactive teleport system flings [H] clear of [attack_text], shutting itself off in the process!")
- var/list/turfs = new/list()
- for(var/turf/T in orange(tele_range, H))
- if(T.density)
- continue
- if(T.x>world.maxx-tele_range || T.xworld.maxy-tele_range || T.yThe reactive incendiary armor on [owner] activates, but fails to send out flames as it is still recharging its flame jets!")
- return
- owner.visible_message("[src] blocks [attack_text], sending out jets of flame!")
- for(var/mob/living/carbon/C in range(6, owner))
- if(C != owner)
- C.fire_stacks += 8
- C.IgniteMob()
- owner.fire_stacks = -20
- reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
- return 1
- return 0
-
-
-/obj/item/clothing/suit/armor/reactive/stealth
- name = "reactive stealth armor"
- desc = "An experimental suit of armor that renders the wearer invisible on detection of imminent harm, and creates a decoy that runs away from the owner. You can't fight what you can't see."
-
-/obj/item/clothing/suit/armor/reactive/stealth/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- if(!active)
- return 0
- if(prob(hit_reaction_chance))
- if(world.time < reactivearmor_cooldown)
- owner.visible_message("The reactive stealth system on [owner] activates, but is still recharging its holographic emitters!")
- return
- var/mob/living/simple_animal/hostile/illusion/escape/E = new(owner.loc)
- E.Copy_Parent(owner, 50)
- E.GiveTarget(owner) //so it starts running right away
- E.Goto(owner, E.move_to_delay, E.minimum_distance)
- owner.alpha = 0
- owner.visible_message("[owner] is hit by [attack_text] in the chest!") //We pretend to be hit, since blocking it would stop the message otherwise
- spawn(40)
- owner.alpha = initial(owner.alpha)
- reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
- return 1
-
-/obj/item/clothing/suit/armor/reactive/tesla
- name = "reactive tesla armor"
- desc = "An experimental suit of armor with sensitive detectors hooked up to a huge capacitor grid, with emitters strutting out of it. Zap."
- siemens_coefficient = -1
- var/tesla_power = 25000
- var/tesla_range = 20
- var/tesla_boom = FALSE
- var/tesla_stun = FALSE
-
-/obj/item/clothing/suit/armor/reactive/tesla/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- if(!active)
- return 0
- if(prob(hit_reaction_chance))
- if(world.time < reactivearmor_cooldown)
- var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread
- sparks.set_up(1, 1, src)
- sparks.start()
- owner.visible_message("The tesla capacitors on [owner]'s reactive tesla armor are still recharging! The armor merely emits some sparks.")
- return
- owner.visible_message("[src] blocks [attack_text], sending out arcs of lightning!")
- tesla_zap(owner,tesla_range,tesla_power,tesla_boom, tesla_stun)
- reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
- return 1
-
-/obj/item/clothing/suit/armor/reactive/table
- name = "reactive table armor"
- desc = "If you can't beat the memes, embrace them."
- var/tele_range = 10
-
-/obj/item/clothing/suit/armor/reactive/table/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- if(!active)
- return 0
- if(prob(hit_reaction_chance))
- var/mob/living/carbon/human/H = owner
- if(world.time < reactivearmor_cooldown)
- owner.visible_message("The reactive table armor's fabricators are still on cooldown!")
- return
- owner.visible_message("The reactive teleport system flings [H] clear of [attack_text] and slams them into a fabricated table!")
- owner.visible_message("[H] GOES ON THE TABLE!!!")
- owner.Knockdown(40)
- var/list/turfs = new/list()
- for(var/turf/T in orange(tele_range, H))
- if(T.density)
- continue
- if(T.x>world.maxx-tele_range || T.xworld.maxy-tele_range || T.y[src] is now active.")
+ icon_state = "reactive"
+ item_state = "reactive"
+ else
+ to_chat(user, "[src] is now inactive.")
+ icon_state = "reactiveoff"
+ item_state = "reactiveoff"
+ add_fingerprint(user)
+ return
+
+/obj/item/clothing/suit/armor/reactive/emp_act(severity)
+ active = 0
+ icon_state = "reactiveoff"
+ item_state = "reactiveoff"
+ reactivearmor_cooldown = world.time + 200
+ ..()
+
+//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!)
+/obj/item/clothing/suit/armor/reactive/teleport
+ name = "reactive teleport armor"
+ desc = "Someone separated our Research Director from his own head!"
+ var/tele_range = 6
+ var/rad_amount= 15
+ reactivearmor_cooldown_duration = 100
+
+/obj/item/clothing/suit/armor/reactive/teleport/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ if(!active)
+ return 0
+ if(prob(hit_reaction_chance))
+ var/mob/living/carbon/human/H = owner
+ if(world.time < reactivearmor_cooldown)
+ owner.visible_message("The reactive teleport system is still recharging! It fails to teleport [H]!")
+ return
+ owner.visible_message("The reactive teleport system flings [H] clear of [attack_text], shutting itself off in the process!")
+ var/list/turfs = new/list()
+ for(var/turf/T in orange(tele_range, H))
+ if(T.density)
+ continue
+ if(T.x>world.maxx-tele_range || T.xworld.maxy-tele_range || T.yThe reactive incendiary armor on [owner] activates, but fails to send out flames as it is still recharging its flame jets!")
+ return
+ owner.visible_message("[src] blocks [attack_text], sending out jets of flame!")
+ for(var/mob/living/carbon/C in range(6, owner))
+ if(C != owner)
+ C.fire_stacks += 8
+ C.IgniteMob()
+ owner.fire_stacks = -20
+ reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
+ return 1
+ return 0
+
+//Stealth
+
+/obj/item/clothing/suit/armor/reactive/stealth
+ name = "reactive stealth armor"
+ desc = "An experimental suit of armor that renders the wearer invisible on detection of imminent harm, and creates a decoy that runs away from the owner. You can't fight what you can't see."
+
+/obj/item/clothing/suit/armor/reactive/stealth/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ if(!active)
+ return 0
+ if(prob(hit_reaction_chance))
+ if(world.time < reactivearmor_cooldown)
+ owner.visible_message("The reactive stealth system on [owner] activates, but is still recharging its holographic emitters!")
+ return
+ var/mob/living/simple_animal/hostile/illusion/escape/E = new(owner.loc)
+ E.Copy_Parent(owner, 50)
+ E.GiveTarget(owner) //so it starts running right away
+ E.Goto(owner, E.move_to_delay, E.minimum_distance)
+ owner.alpha = 0
+ owner.visible_message("[owner] is hit by [attack_text] in the chest!") //We pretend to be hit, since blocking it would stop the message otherwise
+ spawn(40)
+ owner.alpha = initial(owner.alpha)
+ reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
+ return 1
+
+//Tesla
+
+/obj/item/clothing/suit/armor/reactive/tesla
+ name = "reactive tesla armor"
+ desc = "An experimental suit of armor with sensitive detectors hooked up to a huge capacitor grid, with emitters strutting out of it. Zap."
+ siemens_coefficient = -1
+ var/tesla_power = 25000
+ var/tesla_range = 20
+ var/tesla_boom = FALSE
+ var/tesla_stun = FALSE
+
+/obj/item/clothing/suit/armor/reactive/tesla/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ if(!active)
+ return 0
+ if(prob(hit_reaction_chance))
+ if(world.time < reactivearmor_cooldown)
+ var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread
+ sparks.set_up(1, 1, src)
+ sparks.start()
+ owner.visible_message("The tesla capacitors on [owner]'s reactive tesla armor are still recharging! The armor merely emits some sparks.")
+ return
+ owner.visible_message("[src] blocks [attack_text], sending out arcs of lightning!")
+ tesla_zap(owner,tesla_range,tesla_power,tesla_boom, tesla_stun)
+ reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
+ return 1
+
+
+//Repulse
+
+/obj/item/clothing/suit/armor/reactive/repulse
+ name = "reactive repulse armor"
+ desc = "An experimental suit of armor that violently throws back attackers."
+
+/obj/item/clothing/suit/armor/reactive/repulse/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ if(!active)
+ return 0
+ if(prob(hit_reaction_chance))
+ if(world.time < reactivearmor_cooldown)
+ owner.visible_message("The repulse generator is still recharging!")
+ return 0
+ owner.visible_message("[src] blocks [attack_text], converting the attack into a wave of force!")
+ var/turf/T = get_turf(owner)
+ var/list/thrown_items = list()
+ for(var/atom/movable/A in range(T, 7))
+ if(A == owner || A.anchored || thrown_items[A])
+ continue
+ var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(A, src)))
+ A.throw_at(throwtarget,10,1)
+ thrown_items[A] = A
+
+ reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
+ return 1
+
+/obj/item/clothing/suit/armor/reactive/table
+ name = "reactive table armor"
+ desc = "If you can't beat the memes, embrace them."
+ var/tele_range = 10
+
+/obj/item/clothing/suit/armor/reactive/table/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ if(!active)
+ return 0
+ if(prob(hit_reaction_chance))
+ var/mob/living/carbon/human/H = owner
+ if(world.time < reactivearmor_cooldown)
+ owner.visible_message("The reactive table armor's fabricators are still on cooldown!")
+ return
+ owner.visible_message("The reactive teleport system flings [H] clear of [attack_text] and slams them into a fabricated table!")
+ owner.visible_message("[H] GOES ON THE TABLE!!!")
+ owner.Knockdown(40)
+ var/list/turfs = new/list()
+ for(var/turf/T in orange(tele_range, H))
+ if(T.density)
+ continue
+ if(T.x>world.maxx-tele_range || T.xworld.maxy-tele_range || T.y