diff --git a/code/datums/components/shrink.dm b/code/datums/components/shrink.dm
new file mode 100644
index 0000000000..f070d9b22f
--- /dev/null
+++ b/code/datums/components/shrink.dm
@@ -0,0 +1,42 @@
+/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)
+ 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
+ ..()
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/glands/access.dm b/code/modules/antagonists/abductor/equipment/glands/access.dm
new file mode 100644
index 0000000000..548650d4e3
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/glands/access.dm
@@ -0,0 +1,19 @@
+/obj/item/organ/heart/gland/access
+ true_name = "anagraphic electro-scrambler"
+ cooldown_low = 600
+ cooldown_high = 1200
+ uses = 1
+ icon_state = "mindshock"
+ mind_control_uses = 3
+ mind_control_duration = 900
+
+/obj/item/organ/heart/gland/access/activate()
+ to_chat(owner, "You feel like a VIP for some reason.")
+ RegisterSignal(owner, COMSIG_MOB_ALLOWED, .proc/free_access)
+
+/obj/item/organ/heart/gland/access/proc/free_access(datum/source, obj/O)
+ return TRUE
+
+/obj/item/organ/heart/gland/access/Remove(mob/living/carbon/M, special = 0)
+ UnregisterSignal(owner, COMSIG_MOB_ALLOWED)
+ ..()
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/glands/blood.dm b/code/modules/antagonists/abductor/equipment/glands/blood.dm
new file mode 100644
index 0000000000..06b8249484
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/glands/blood.dm
@@ -0,0 +1,18 @@
+/obj/item/organ/heart/gland/blood
+ true_name = "pseudonuclear hemo-destabilizer"
+ cooldown_low = 1200
+ cooldown_high = 1800
+ uses = -1
+ icon_state = "egg"
+ lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi'
+ mind_control_uses = 3
+ mind_control_duration = 1500
+
+/obj/item/organ/heart/gland/blood/activate()
+ if(!ishuman(owner) || !owner.dna.species)
+ return
+ var/mob/living/carbon/human/H = owner
+ var/datum/species/species = H.dna.species
+ to_chat(H, "You feel your blood heat up for a moment.")
+ species.exotic_blood = get_random_reagent_id()
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/glands/chem.dm b/code/modules/antagonists/abductor/equipment/glands/chem.dm
new file mode 100644
index 0000000000..e7b6fda85f
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/glands/chem.dm
@@ -0,0 +1,20 @@
+/obj/item/organ/heart/gland/chem
+ true_name = "intrinsic pharma-provider"
+ cooldown_low = 50
+ cooldown_high = 50
+ uses = -1
+ icon_state = "viral"
+ mind_control_uses = 3
+ mind_control_duration = 1200
+ var/list/possible_reagents = list()
+
+/obj/item/organ/heart/gland/chem/Initialize()
+ . = ..()
+ for(var/R in subtypesof(/datum/reagent/drug) + subtypesof(/datum/reagent/medicine) + typesof(/datum/reagent/toxin))
+ possible_reagents += R
+
+/obj/item/organ/heart/gland/chem/activate()
+ var/chem_to_add = pick(possible_reagents)
+ owner.reagents.add_reagent(chem_to_add, 2)
+ owner.adjustToxLoss(-5, TRUE, TRUE)
+ ..()
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/glands/egg.dm b/code/modules/antagonists/abductor/equipment/glands/egg.dm
new file mode 100644
index 0000000000..429a24b19c
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/glands/egg.dm
@@ -0,0 +1,15 @@
+/obj/item/organ/heart/gland/egg
+ true_name = "roe/enzymatic synthesizer"
+ cooldown_low = 300
+ cooldown_high = 400
+ uses = -1
+ icon_state = "egg"
+ lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi'
+ mind_control_uses = 2
+ mind_control_duration = 1800
+
+/obj/item/organ/heart/gland/egg/activate()
+ owner.visible_message("[owner] [pick(EGG_LAYING_MESSAGES)]")
+ var/turf/T = owner.drop_location()
+ new /obj/item/reagent_containers/food/snacks/egg/gland(T)
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/glands/electric.dm b/code/modules/antagonists/abductor/equipment/glands/electric.dm
new file mode 100644
index 0000000000..c5c14bb179
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/glands/electric.dm
@@ -0,0 +1,26 @@
+/obj/item/organ/heart/gland/electric
+ true_name = "electron accumulator/discharger"
+ cooldown_low = 800
+ cooldown_high = 1200
+ icon_state = "species"
+ uses = -1
+ mind_control_uses = 2
+ mind_control_duration = 900
+
+/obj/item/organ/heart/gland/electric/Insert(mob/living/carbon/M, special = 0)
+ ..()
+ ADD_TRAIT(owner, TRAIT_SHOCKIMMUNE, "abductor_gland")
+
+/obj/item/organ/heart/gland/electric/Remove(mob/living/carbon/M, special = 0)
+ REMOVE_TRAIT(owner, TRAIT_SHOCKIMMUNE, "abductor_gland")
+ ..()
+
+/obj/item/organ/heart/gland/electric/activate()
+ owner.visible_message("[owner]'s skin starts emitting electric arcs!",\
+ "You feel electric energy building up inside you!")
+ playsound(get_turf(owner), "sparks", 100, TRUE, -1)
+ addtimer(CALLBACK(src, .proc/zap), rand(30, 100))
+
+/obj/item/organ/heart/gland/electric/proc/zap()
+ tesla_zap(owner, 4, 8000, TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN)
+ playsound(get_turf(owner), 'sound/magic/lightningshock.ogg', 50, TRUE)
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/glands/heal.dm b/code/modules/antagonists/abductor/equipment/glands/heal.dm
new file mode 100644
index 0000000000..bf9a00e13c
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/glands/heal.dm
@@ -0,0 +1,178 @@
+/obj/item/organ/heart/gland/heal
+ true_name = "organic replicator"
+ cooldown_low = 200
+ cooldown_high = 400
+ uses = -1
+ human_only = TRUE
+ icon_state = "health"
+ mind_control_uses = 3
+ mind_control_duration = 3000
+
+/obj/item/organ/heart/gland/heal/activate()
+ if(!(owner.mob_biotypes & MOB_ORGANIC))
+ return
+
+ for(var/organ in owner.internal_organs)
+ if(istype(organ, /obj/item/organ/cyberimp))
+ reject_implant(organ)
+ return
+
+ var/obj/item/organ/liver/liver = owner.getorganslot(ORGAN_SLOT_LIVER)
+ if((!liver/* && !HAS_TRAIT(owner, TRAIT_NOMETABOLISM)*/) || (liver && ((liver.damage > (liver.maxHealth / 2)) || (istype(liver, /obj/item/organ/liver/cybernetic)))))
+ replace_liver(liver)
+ return
+
+ var/obj/item/organ/lungs/lungs = owner.getorganslot(ORGAN_SLOT_LUNGS)
+ if((!lungs && !HAS_TRAIT(owner, TRAIT_NOBREATH)) || (lungs && (istype(lungs, /obj/item/organ/lungs/cybernetic))))
+ replace_lungs(lungs)
+ return
+
+ var/obj/item/organ/eyes/eyes = owner.getorganslot(ORGAN_SLOT_EYES)
+ if(!eyes || (eyes && ((HAS_TRAIT_FROM(owner, TRAIT_NEARSIGHT, EYE_DAMAGE)) || (HAS_TRAIT_FROM(owner, TRAIT_BLIND, EYE_DAMAGE)) || (istype(eyes, /obj/item/organ/eyes/robotic)))))
+ replace_eyes(eyes)
+ return
+
+ var/obj/item/bodypart/limb
+ var/list/limb_list = list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
+ for(var/zone in limb_list)
+ limb = owner.get_bodypart(zone)
+ if(!limb)
+ replace_limb(zone)
+ return
+ if((limb.get_damage() >= (limb.max_damage / 2)) || (limb.status == BODYPART_ROBOTIC))
+ replace_limb(zone, limb)
+ return
+
+ if(owner.getToxLoss() > 40)
+ replace_blood()
+ return
+ var/tox_amount = 0
+ for(var/datum/reagent/toxin/T in owner.reagents.reagent_list)
+ tox_amount += owner.reagents.get_reagent_amount(T.type)
+ if(tox_amount > 10)
+ replace_blood()
+ return
+ if(owner.blood_volume < BLOOD_VOLUME_OKAY)
+ owner.blood_volume = BLOOD_VOLUME_NORMAL
+ to_chat(owner, "You feel your blood pulsing within you.")
+ return
+
+ var/obj/item/bodypart/chest/chest = owner.get_bodypart(BODY_ZONE_CHEST)
+ if((chest.get_damage() >= (chest.max_damage / 4)) || (chest.status == BODYPART_ROBOTIC))
+ replace_chest(chest)
+ return
+
+/obj/item/organ/heart/gland/heal/proc/reject_implant(obj/item/organ/cyberimp/implant)
+ owner.visible_message("[owner] vomits up his [implant.name]!", "You suddenly vomit up your [implant.name]!")
+ owner.vomit(0, TRUE, TRUE, 1, FALSE, FALSE, FALSE, TRUE)
+ implant.Remove(owner)
+ implant.forceMove(owner.drop_location())
+
+/obj/item/organ/heart/gland/heal/proc/replace_liver(obj/item/organ/liver/liver)
+ if(liver)
+ owner.visible_message("[owner] vomits up his [liver.name]!", "You suddenly vomit up your [liver.name]!")
+ owner.vomit(0, TRUE, TRUE, 1, FALSE, FALSE, FALSE, TRUE)
+ liver.Remove(owner)
+ liver.forceMove(owner.drop_location())
+ else
+ to_chat(owner, "You feel a weird rumble in your bowels...")
+
+ var/liver_type = /obj/item/organ/liver
+ if(owner?.dna?.species?.mutantliver)
+ liver_type = owner.dna.species.mutantliver
+ var/obj/item/organ/liver/new_liver = new liver_type()
+ new_liver.Insert(owner)
+
+/obj/item/organ/heart/gland/heal/proc/replace_lungs(obj/item/organ/lungs/lungs)
+ if(lungs)
+ owner.visible_message("[owner] vomits up his [lungs.name]!", "You suddenly vomit up your [lungs.name]!")
+ owner.vomit(0, TRUE, TRUE, 1, FALSE, FALSE, FALSE, TRUE)
+ lungs.Remove(owner)
+ lungs.forceMove(owner.drop_location())
+ else
+ to_chat(owner, "You feel a weird rumble inside your chest...")
+
+ var/lung_type = /obj/item/organ/lungs
+ if(owner.dna.species && owner.dna.species.mutantlungs)
+ lung_type = owner.dna.species.mutantlungs
+ var/obj/item/organ/lungs/new_lungs = new lung_type()
+ new_lungs.Insert(owner)
+
+/obj/item/organ/heart/gland/heal/proc/replace_eyes(obj/item/organ/eyes/eyes)
+ if(eyes)
+ owner.visible_message("[owner]'s [eyes.name] fall out of their sockets!", "Your [eyes.name] fall out of their sockets!")
+ playsound(owner, 'sound/effects/splat.ogg', 50, TRUE)
+ eyes.Remove(owner)
+ eyes.forceMove(owner.drop_location())
+ else
+ to_chat(owner, "You feel a weird rumble behind your eye sockets...")
+
+ addtimer(CALLBACK(src, .proc/finish_replace_eyes), rand(100, 200))
+
+/obj/item/organ/heart/gland/heal/proc/finish_replace_eyes()
+ var/eye_type = /obj/item/organ/eyes
+ if(owner.dna.species && owner.dna.species.mutanteyes)
+ eye_type = owner.dna.species.mutanteyes
+ var/obj/item/organ/eyes/new_eyes = new eye_type()
+ new_eyes.Insert(owner)
+ owner.visible_message("A pair of new eyes suddenly inflates into [owner]'s eye sockets!", "A pair of new eyes suddenly inflates into your eye sockets!")
+
+/obj/item/organ/heart/gland/heal/proc/replace_limb(body_zone, obj/item/bodypart/limb)
+ if(limb)
+ owner.visible_message("[owner]'s [limb.name] suddenly detaches from [owner.p_their()] body!", "Your [limb.name] suddenly detaches from your body!")
+ playsound(owner, "desceration", 50, TRUE, -1)
+ limb.drop_limb()
+ else
+ to_chat(owner, "You feel a weird tingle in your [parse_zone(body_zone)]... even if you don't have one.")
+
+ addtimer(CALLBACK(src, .proc/finish_replace_limb, body_zone), rand(150, 300))
+
+/obj/item/organ/heart/gland/heal/proc/finish_replace_limb(body_zone)
+ owner.visible_message("With a loud snap, [owner]'s [parse_zone(body_zone)] rapidly grows back from [owner.p_their()] body!",
+ "With a loud snap, your [parse_zone(body_zone)] rapidly grows back from your body!",
+ "Your hear a loud snap.")
+ playsound(owner, 'sound/magic/demon_consume.ogg', 50, TRUE)
+ owner.regenerate_limb(body_zone)
+
+/obj/item/organ/heart/gland/heal/proc/replace_blood()
+ owner.visible_message("[owner] starts vomiting huge amounts of blood!", "You suddenly start vomiting huge amounts of blood!")
+ keep_replacing_blood()
+
+/obj/item/organ/heart/gland/heal/proc/keep_replacing_blood()
+ var/keep_going = FALSE
+ owner.vomit(0, TRUE, FALSE, 3, FALSE, FALSE, FALSE, TRUE)
+ owner.Stun(15)
+ owner.adjustToxLoss(-15, TRUE, TRUE)
+
+ owner.blood_volume = min(BLOOD_VOLUME_NORMAL, owner.blood_volume + 20)
+ if(owner.blood_volume < BLOOD_VOLUME_NORMAL)
+ keep_going = TRUE
+
+ if(owner.getToxLoss())
+ keep_going = TRUE
+ for(var/datum/reagent/toxin/R in owner.reagents.reagent_list)
+ owner.reagents.remove_reagent(R.type, 4)
+ if(owner.reagents.has_reagent(R.type))
+ keep_going = TRUE
+ if(keep_going)
+ addtimer(CALLBACK(src, .proc/keep_replacing_blood), 30)
+
+/obj/item/organ/heart/gland/heal/proc/replace_chest(obj/item/bodypart/chest/chest)
+ if(chest.status == BODYPART_ROBOTIC)
+ owner.visible_message("[owner]'s [chest.name] rapidly expels its mechanical components, replacing them with flesh!", "Your [chest.name] rapidly expels its mechanical components, replacing them with flesh!")
+ playsound(owner, 'sound/magic/clockwork/anima_fragment_attack.ogg', 50, TRUE)
+ var/list/dirs = GLOB.alldirs.Copy()
+ for(var/i in 1 to 3)
+ var/obj/effect/decal/cleanable/robot_debris/debris = new(get_turf(owner))
+ debris.streak(dirs)
+ else
+ owner.visible_message("[owner]'s [chest.name] sheds off its damaged flesh, rapidly replacing it!", "Your [chest.name] sheds off its damaged flesh, rapidly replacing it!")
+ playsound(owner, 'sound/effects/splat.ogg', 50, TRUE)
+ var/list/dirs = GLOB.alldirs.Copy()
+ for(var/i in 1 to 3)
+ var/obj/effect/decal/cleanable/blood/gibs/gibs = new(get_turf(owner))
+ gibs.streak(dirs)
+
+ var/obj/item/bodypart/chest/new_chest = new(null)
+ new_chest.replace_limb(owner, TRUE)
+ qdel(chest)
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/glands/mindshock.dm b/code/modules/antagonists/abductor/equipment/glands/mindshock.dm
new file mode 100644
index 0000000000..f8b91343f2
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/glands/mindshock.dm
@@ -0,0 +1,64 @@
+/obj/item/organ/heart/gland/mindshock
+ true_name = "neural crosstalk uninhibitor"
+ cooldown_low = 400
+ cooldown_high = 700
+ uses = -1
+ icon_state = "mindshock"
+ mind_control_uses = 1
+ mind_control_duration = 6000
+ var/list/mob/living/carbon/human/broadcasted_mobs = list()
+
+/obj/item/organ/heart/gland/mindshock/activate()
+ to_chat(owner, "You get a headache.")
+
+ var/turf/T = get_turf(owner)
+ for(var/mob/living/carbon/H in orange(4,T))
+ if(H == owner)
+ continue
+ switch(pick(1,3))
+ if(1)
+ to_chat(H, "You hear a loud buzz in your head, silencing your thoughts!")
+ H.Stun(50)
+ if(2)
+ to_chat(H, "You hear an annoying buzz in your head.")
+ H.confused += 15
+ H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10, 160)
+ if(3)
+ H.hallucination += 60
+
+/obj/item/organ/heart/gland/mindshock/mind_control(command, mob/living/user)
+ if(!ownerCheck() || !mind_control_uses || active_mind_control)
+ return FALSE
+ mind_control_uses--
+ for(var/mob/M in oview(7, owner))
+ if(!ishuman(M))
+ continue
+ var/mob/living/carbon/human/H = M
+ if(H.stat)
+ continue
+
+ broadcasted_mobs += H
+ to_chat(H, "You suddenly feel an irresistible compulsion to follow an order...")
+ to_chat(H, "[command]")
+
+ message_admins("[key_name(user)] broadcasted an abductor mind control message from [key_name(owner)] to [key_name(H)]: [command]")
+
+ var/obj/screen/alert/mind_control/mind_alert = H.throw_alert("mind_control", /obj/screen/alert/mind_control)
+ mind_alert.command = command
+
+ if(LAZYLEN(broadcasted_mobs))
+ active_mind_control = TRUE
+ addtimer(CALLBACK(src, .proc/clear_mind_control), mind_control_duration)
+
+ update_gland_hud()
+ return TRUE
+
+/obj/item/organ/heart/gland/mindshock/clear_mind_control()
+ if(!active_mind_control || !LAZYLEN(broadcasted_mobs))
+ return FALSE
+ for(var/M in broadcasted_mobs)
+ var/mob/living/carbon/human/H = M
+ to_chat(H, "You feel the compulsion fade, and you completely forget about your previous orders.")
+ H.clear_alert("mind_control")
+ active_mind_control = FALSE
+ return TRUE
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/glands/plasma.dm b/code/modules/antagonists/abductor/equipment/glands/plasma.dm
new file mode 100644
index 0000000000..4a30d99d44
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/glands/plasma.dm
@@ -0,0 +1,22 @@
+/obj/item/organ/heart/gland/plasma
+ true_name = "effluvium sanguine-synonym emitter"
+ cooldown_low = 1200
+ cooldown_high = 1800
+ icon_state = "slime"
+ uses = -1
+ mind_control_uses = 1
+ mind_control_duration = 800
+
+/obj/item/organ/heart/gland/plasma/activate()
+ to_chat(owner, "You feel bloated.")
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, owner, "A massive stomachache overcomes you."), 150)
+ addtimer(CALLBACK(src, .proc/vomit_plasma), 200)
+
+/obj/item/organ/heart/gland/plasma/proc/vomit_plasma()
+ if(!owner)
+ return
+ owner.visible_message("[owner] vomits a cloud of plasma!")
+ var/turf/open/T = get_turf(owner)
+ if(istype(T))
+ T.atmos_spawn_air("plasma=50;TEMP=[T20C]")
+ owner.vomit()
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/glands/quantum.dm b/code/modules/antagonists/abductor/equipment/glands/quantum.dm
new file mode 100644
index 0000000000..a5b8815437
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/glands/quantum.dm
@@ -0,0 +1,47 @@
+/obj/item/organ/heart/gland/quantum
+ true_name = "quantic de-observation matrix"
+ cooldown_low = 150
+ cooldown_high = 150
+ uses = -1
+ icon_state = "emp"
+ mind_control_uses = 2
+ mind_control_duration = 1200
+ var/mob/living/carbon/entangled_mob
+
+/obj/item/organ/heart/gland/quantum/activate()
+ if(entangled_mob)
+ return
+ for(var/mob/M in oview(owner, 7))
+ if(!iscarbon(M))
+ continue
+ entangled_mob = M
+ addtimer(CALLBACK(src, .proc/quantum_swap), rand(600, 2400))
+ return
+
+/obj/item/organ/heart/gland/quantum/proc/quantum_swap()
+ if(QDELETED(entangled_mob))
+ entangled_mob = null
+ return
+ var/turf/T = get_turf(owner)
+ do_teleport(owner, get_turf(entangled_mob),null,TRUE,channel = TELEPORT_CHANNEL_QUANTUM)
+ do_teleport(entangled_mob, T,null,TRUE,channel = TELEPORT_CHANNEL_QUANTUM)
+ to_chat(owner, "You suddenly find yourself somewhere else!")
+ to_chat(entangled_mob, "You suddenly find yourself somewhere else!")
+ if(!active_mind_control) //Do not reset entangled mob while mind control is active
+ entangled_mob = null
+
+/obj/item/organ/heart/gland/quantum/mind_control(command, mob/living/user)
+ if(..())
+ if(entangled_mob && ishuman(entangled_mob) && (entangled_mob.stat < DEAD))
+ to_chat(entangled_mob, "You suddenly feel an irresistible compulsion to follow an order...")
+ to_chat(entangled_mob, "[command]")
+ var/obj/screen/alert/mind_control/mind_alert = entangled_mob.throw_alert("mind_control", /obj/screen/alert/mind_control)
+ mind_alert.command = command
+ message_admins("[key_name(owner)] mirrored an abductor mind control message to [key_name(entangled_mob)]: [command]")
+ update_gland_hud()
+
+/obj/item/organ/heart/gland/quantum/clear_mind_control()
+ if(active_mind_control)
+ to_chat(entangled_mob, "You feel the compulsion fade, and you completely forget about your previous orders.")
+ entangled_mob.clear_alert("mind_control")
+ ..()
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/glands/slime.dm b/code/modules/antagonists/abductor/equipment/glands/slime.dm
new file mode 100644
index 0000000000..ff3f5aa0a4
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/glands/slime.dm
@@ -0,0 +1,21 @@
+/obj/item/organ/heart/gland/slime
+ true_name = "gastric animation galvanizer"
+ cooldown_low = 600
+ cooldown_high = 1200
+ uses = -1
+ icon_state = "slime"
+ mind_control_uses = 1
+ mind_control_duration = 2400
+
+/obj/item/organ/heart/gland/slime/Insert(mob/living/carbon/M, special = 0)
+ ..()
+ owner.faction |= "slime"
+ owner.grant_language(/datum/language/slime)
+
+/obj/item/organ/heart/gland/slime/activate()
+ to_chat(owner, "You feel nauseated!")
+ owner.vomit(20)
+
+ var/mob/living/simple_animal/slime/Slime = new(get_turf(owner), "grey")
+ Slime.Friends = list(owner)
+ Slime.Leader = owner
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/glands/spider.dm b/code/modules/antagonists/abductor/equipment/glands/spider.dm
new file mode 100644
index 0000000000..f0421b23b2
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/glands/spider.dm
@@ -0,0 +1,14 @@
+/obj/item/organ/heart/gland/spiderman
+ true_name = "araneae cloister accelerator"
+ cooldown_low = 450
+ cooldown_high = 900
+ uses = -1
+ icon_state = "spider"
+ mind_control_uses = 2
+ mind_control_duration = 2400
+
+/obj/item/organ/heart/gland/spiderman/activate()
+ to_chat(owner, "You feel something crawling in your skin.")
+ owner.faction |= "spiders"
+ var/obj/structure/spider/spiderling/S = new(owner.drop_location())
+ S.directive = "Protect your nest inside [owner.real_name]."
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/glands/transform.dm b/code/modules/antagonists/abductor/equipment/glands/transform.dm
new file mode 100644
index 0000000000..05c4760d37
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/glands/transform.dm
@@ -0,0 +1,15 @@
+/obj/item/organ/heart/gland/transform
+ true_name = "anthropmorphic transmorphosizer"
+ cooldown_low = 900
+ cooldown_high = 1800
+ uses = -1
+ human_only = TRUE
+ icon_state = "species"
+ mind_control_uses = 7
+ mind_control_duration = 300
+
+/obj/item/organ/heart/gland/transform/activate()
+ to_chat(owner, "You feel unlike yourself.")
+ randomize_human(owner)
+ var/species = pick(list(/datum/species/human, /datum/species/lizard, /datum/species/insect, /datum/species/fly))
+ owner.set_species(species)
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/glands/trauma.dm b/code/modules/antagonists/abductor/equipment/glands/trauma.dm
new file mode 100644
index 0000000000..b6280ec017
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/glands/trauma.dm
@@ -0,0 +1,18 @@
+/obj/item/organ/heart/gland/trauma
+ true_name = "white matter randomiser"
+ cooldown_low = 800
+ cooldown_high = 1200
+ uses = 5
+ icon_state = "emp"
+ mind_control_uses = 3
+ mind_control_duration = 1800
+
+/obj/item/organ/heart/gland/trauma/activate()
+ to_chat(owner, "You feel a spike of pain in your head.")
+ if(prob(33))
+ owner.gain_trauma_type(BRAIN_TRAUMA_SPECIAL, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_LOBOTOMY))
+ else
+ if(prob(20))
+ owner.gain_trauma_type(BRAIN_TRAUMA_SEVERE, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_LOBOTOMY))
+ else
+ owner.gain_trauma_type(BRAIN_TRAUMA_MILD, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_LOBOTOMY))
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/glands/ventcrawl.dm b/code/modules/antagonists/abductor/equipment/glands/ventcrawl.dm
new file mode 100644
index 0000000000..d1ea135497
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/glands/ventcrawl.dm
@@ -0,0 +1,12 @@
+/obj/item/organ/heart/gland/ventcrawling
+ true_name = "pliant cartilage enabler"
+ cooldown_low = 1800
+ cooldown_high = 2400
+ uses = 1
+ icon_state = "vent"
+ mind_control_uses = 4
+ mind_control_duration = 1800
+
+/obj/item/organ/heart/gland/ventcrawling/activate()
+ to_chat(owner, "You feel very stretchy.")
+ owner.ventcrawler = VENTCRAWLER_ALWAYS
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/glands/viral.dm b/code/modules/antagonists/abductor/equipment/glands/viral.dm
new file mode 100644
index 0000000000..4d4f865a7c
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/glands/viral.dm
@@ -0,0 +1,34 @@
+/obj/item/organ/heart/gland/viral
+ true_name = "contamination incubator"
+ cooldown_low = 1800
+ cooldown_high = 2400
+ uses = 1
+ icon_state = "viral"
+ mind_control_uses = 1
+ mind_control_duration = 1800
+
+/obj/item/organ/heart/gland/viral/activate()
+ to_chat(owner, "You feel sick.")
+ var/datum/disease/advance/A = random_virus(pick(2,6),6)
+ A.carrier = TRUE
+ owner.ForceContractDisease(A, FALSE, TRUE)
+
+/obj/item/organ/heart/gland/viral/proc/random_virus(max_symptoms, max_level)
+ if(max_symptoms > VIRUS_SYMPTOM_LIMIT)
+ max_symptoms = VIRUS_SYMPTOM_LIMIT
+ var/datum/disease/advance/A = new /datum/disease/advance()
+ var/list/datum/symptom/possible_symptoms = list()
+ for(var/symptom in subtypesof(/datum/symptom))
+ var/datum/symptom/S = symptom
+ if(initial(S.level) > max_level)
+ continue
+ if(initial(S.level) <= 0) //unobtainable symptoms
+ continue
+ possible_symptoms += S
+ for(var/i in 1 to max_symptoms)
+ var/datum/symptom/chosen_symptom = pick_n_take(possible_symptoms)
+ if(chosen_symptom)
+ var/datum/symptom/S = new chosen_symptom
+ A.symptoms += S
+ A.Refresh() //just in case someone already made and named the same disease
+ return A
\ No newline at end of file
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index 3f96796a00..6eebd7b63e 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -238,25 +238,64 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = -5,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = -5, "fire" = 0, "acid" = 0)
equip_delay_other = 140
var/datum/brain_trauma/mild/phobia/paranoia
+ var/warped = FALSE
+
+/obj/item/clothing/head/foilhat/Initialize(mapload)
+ . = ..()
+ if(!warped)
+ AddComponent(/datum/component/anti_magic, FALSE, FALSE, TRUE, ITEM_SLOT_HEAD, 6, TRUE, null, CALLBACK(src, .proc/warp_up))
+ else
+ warp_up()
/obj/item/clothing/head/foilhat/equipped(mob/living/carbon/human/user, slot)
- ..()
- if(slot == SLOT_HEAD)
- if(paranoia)
- QDEL_NULL(paranoia)
- paranoia = new()
- user.gain_trauma(paranoia, TRAUMA_RESILIENCE_MAGIC, "conspiracies")
- to_chat(user, "As you don the foiled hat, an entire world of conspiracy theories and seemingly insane ideas suddenly rush into your mind. What you once thought unbelievable suddenly seems.. undeniable. Everything is connected and nothing happens just by accident. You know too much and now they're out to get you. ")
+ . = ..()
+ if(slot != SLOT_HEAD || warped)
+ return
+ if(paranoia)
+ QDEL_NULL(paranoia)
+ paranoia = new()
+ paranoia.clonable = FALSE
+
+ user.gain_trauma(paranoia, TRAUMA_RESILIENCE_MAGIC)
+ to_chat(user, "As you don the foiled hat, an entire world of conspiracy theories and seemingly insane ideas suddenly rush into your mind. What you once thought unbelievable suddenly seems.. undeniable. Everything is connected and nothing happens just by accident. You know too much and now they're out to get you. ")
+
+
+/obj/item/clothing/head/foilhat/MouseDrop(atom/over_object)
+ //God Im sorry
+ if(!warped && iscarbon(usr))
+ var/mob/living/carbon/C = usr
+ if(src == C.head)
+ to_chat(C, "Why would you want to take this off? Do you want them to get into your mind?!")
+ return
+ return ..()
/obj/item/clothing/head/foilhat/dropped(mob/user)
- ..()
+ . = ..()
if(paranoia)
QDEL_NULL(paranoia)
+/obj/item/clothing/head/foilhat/proc/warp_up()
+ name = "scorched tinfoil hat"
+ desc = "A badly warped up hat. Quite unprobable this will still work against any of fictional and contemporary dangers it used to."
+ warped = TRUE
+ if(!isliving(loc) || !paranoia)
+ return
+ var/mob/living/target = loc
+ if(target.get_item_by_slot(SLOT_HEAD) != src)
+ return
+ QDEL_NULL(paranoia)
+ if(!target.IsUnconscious())
+ to_chat(target, "Your zealous conspirationism rapidly dissipates as the donned hat warps up into a ruined mess. All those theories starting to sound like nothing but a ridicolous fanfare.")
+
/obj/item/clothing/head/foilhat/attack_hand(mob/user)
- if(iscarbon(user))
+ if(!warped && iscarbon(user))
var/mob/living/carbon/C = user
if(src == C.head)
to_chat(user, "Why would you want to take this off? Do you want them to get into your mind?!")
return
- ..()
+ return ..()
+
+/obj/item/clothing/head/foilhat/microwave_act(obj/machinery/microwave/M)
+ . = ..()
+ if(!warped)
+ warp_up()
diff --git a/sound/weapons/shrink_hit.ogg b/sound/weapons/shrink_hit.ogg
new file mode 100644
index 0000000000..c39c2d5269
Binary files /dev/null and b/sound/weapons/shrink_hit.ogg differ