diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index c6a78c418e6..b6fcfc104c8 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -188,3 +188,36 @@
// teehee no one will find these here
#define MFOAM_ALUMINUM 1
#define MFOAM_IRON 2
+
+//Human Overlays Indexes/////////
+#define MUTANTRACE_LAYER 1
+#define TAIL_UNDERLIMBS_LAYER 2
+#define LIMBS_LAYER 3
+#define MARKINGS_LAYER 4
+#define UNDERWEAR_LAYER 5
+#define MUTATIONS_LAYER 6
+#define DAMAGE_LAYER 7
+#define UNIFORM_LAYER 8
+#define ID_LAYER 9
+#define SHOES_LAYER 10
+#define GLOVES_LAYER 11
+#define EARS_LAYER 12
+#define SUIT_LAYER 13
+#define GLASSES_LAYER 14
+#define BELT_LAYER 15 //Possible make this an overlay of somethign required to wear a belt?
+#define SUIT_STORE_LAYER 16
+#define BACK_LAYER 17
+#define TAIL_LAYER 18 //bs12 specific. this hack is probably gonna come back to haunt me
+#define HAIR_LAYER 19 //TODO: make part of head layer?
+#define HEAD_ACCESSORY_LAYER 20
+#define FHAIR_LAYER 21
+#define FACEMASK_LAYER 22
+#define HEAD_LAYER 23
+#define COLLAR_LAYER 24
+#define HANDCUFF_LAYER 25
+#define LEGCUFF_LAYER 26
+#define L_HAND_LAYER 27
+#define R_HAND_LAYER 28
+#define TARGETED_LAYER 29 //BS12: Layer for the target overlay from weapon targeting system
+#define FIRE_LAYER 30 //If you're on fire
+#define TOTAL_LAYERS 30
\ No newline at end of file
diff --git a/code/datums/helper_datums/icon_snapshot.dm b/code/datums/helper_datums/icon_snapshot.dm
new file mode 100644
index 00000000000..22b402be446
--- /dev/null
+++ b/code/datums/helper_datums/icon_snapshot.dm
@@ -0,0 +1,15 @@
+/datum/icon_snapshot
+ var/name
+ var/icon
+ var/icon_state
+ var/list/overlays
+
+/datum/icon_snapshot/proc/makeImg()
+ if(!icon || !icon_state)
+ return
+ var/obj/temp = new
+ temp.icon = icon
+ temp.icon_state = icon_state
+ temp.overlays = overlays.Copy()
+ var/icon/tempicon = getFlatIcon(temp) // TODO Actually write something less heavy-handed for this
+ return tempicon
diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm
new file mode 100644
index 00000000000..6345fb4e830
--- /dev/null
+++ b/code/game/gamemodes/miniantags/abduction/abduction.dm
@@ -0,0 +1,459 @@
+/datum/game_mode
+ var/abductor_teams = 0
+ var/list/datum/mind/abductors = list()
+ var/list/datum/mind/abductees = list()
+
+/datum/game_mode/abduction
+ name = "abduction"
+ config_tag = "abduction"
+ recommended_enemies = 2
+ required_players = 15
+ required_players_secret = 15
+ var/max_teams = 4
+ abductor_teams = 1
+ var/list/datum/mind/scientists = list()
+ var/list/datum/mind/agents = list()
+ var/list/datum/objective/team_objectives = list()
+ var/list/team_names = list()
+ var/finished = 0
+ var/list/datum/mind/possible_abductors = list()
+
+/datum/game_mode/abduction/announce()
+ to_chat(world, "The current game mode is - Abduction!")
+ to_chat(world, "There are alien abductors sent to [world.name] to perform nefarious experiments!")
+ to_chat(world, "Abductors - kidnap the crew and replace their organs with experimental ones.")
+ to_chat(world, "Crew - don't get abducted and stop the abductors.")
+
+/datum/game_mode/abduction/pre_setup()
+ possible_abductors = get_players_for_role(ROLE_ABDUCTOR)
+
+ if(!possible_abductors.len)
+ return 0
+
+ abductor_teams = max(1, min(max_teams,round(num_players()/15)))
+ var/possible_teams = max(1,round(possible_abductors.len / 2))
+ abductor_teams = min(abductor_teams,possible_teams)
+
+ abductors.len = 2*abductor_teams
+ scientists.len = abductor_teams
+ agents.len = abductor_teams
+ team_objectives.len = abductor_teams
+ team_names.len = abductor_teams
+
+ for(var/i=1,i<=abductor_teams,i++)
+ if(!make_abductor_team(i))
+ return 0
+
+ return 1
+
+/datum/game_mode/abduction/proc/make_abductor_team(team_number,preset_agent=null,preset_scientist=null)
+ //Team Name
+ team_names[team_number] = "Mothership [pick(possible_changeling_IDs)]" //TODO Ensure unique and actual alieny names
+ //Team Objective
+ var/datum/objective/experiment/team_objective = new
+ team_objective.team = team_number
+ team_objectives[team_number] = team_objective
+ //Team Members
+
+ if(!preset_agent || !preset_scientist)
+ if(possible_abductors.len <=2)
+ return 0
+
+ var/datum/mind/scientist
+ var/datum/mind/agent
+
+ if(!preset_scientist)
+ scientist = pick(possible_abductors)
+ possible_abductors -= scientist
+ else
+ scientist = preset_scientist
+
+ if(!preset_agent)
+ agent = pick(possible_abductors)
+ possible_abductors -= agent
+ else
+ agent = preset_agent
+
+
+ scientist.assigned_role = "abductor scientist"
+ scientist.special_role = "abductor scientist"
+ log_game("[scientist.key] (ckey) has been selected as an abductor team [team_number] scientist.")
+
+ agent.assigned_role = "abductor agent"
+ agent.special_role = "abductor agent"
+ log_game("[agent.key] (ckey) has been selected as an abductor team [team_number] agent.")
+
+ abductors |= agent
+ abductors |= scientist
+ scientists[team_number] = scientist
+ agents[team_number] = agent
+ return 1
+
+/datum/game_mode/abduction/post_setup()
+ //Spawn Team
+ var/list/obj/effect/landmark/abductor/agent_landmarks = new
+ var/list/obj/effect/landmark/abductor/scientist_landmarks = new
+ agent_landmarks.len = max_teams
+ scientist_landmarks.len = max_teams
+ for(var/obj/effect/landmark/abductor/A in landmarks_list)
+ if(istype(A,/obj/effect/landmark/abductor/agent))
+ agent_landmarks[text2num(A.team)] = A
+ else if(istype(A,/obj/effect/landmark/abductor/scientist))
+ scientist_landmarks[text2num(A.team)] = A
+
+ var/datum/mind/agent
+ var/obj/effect/landmark/L
+ var/datum/mind/scientist
+ var/team_name
+ var/mob/living/carbon/human/H
+ var/datum/species/abductor/S
+ for(var/team_number=1,team_number<=abductor_teams,team_number++)
+ team_name = team_names[team_number]
+ agent = agents[team_number]
+ H = agent.current
+ L = agent_landmarks[team_number]
+ H.loc = L.loc
+ H.set_species("Abductor")
+ S = H.dna.species
+ S.agent = 1
+ S.team = team_number
+ H.real_name = team_name + " Agent"
+ equip_common(H,team_number)
+ equip_agent(H,team_number)
+ greet_agent(agent,team_number)
+
+ scientist = scientists[team_number]
+ H = scientist.current
+ L = scientist_landmarks[team_number]
+ H.loc = L.loc
+ H.set_species("Abductor")
+ S = H.dna.species
+ S.scientist = 1
+ S.team = team_number
+ H.real_name = team_name + " Scientist"
+ equip_common(H,team_number)
+ equip_scientist(H,team_number)
+ greet_scientist(scientist,team_number)
+ return ..()
+
+//Used for create antag buttons
+/datum/game_mode/abduction/proc/post_setup_team(team_number)
+ var/list/obj/effect/landmark/abductor/agent_landmarks = new
+ var/list/obj/effect/landmark/abductor/scientist_landmarks = new
+ agent_landmarks.len = max_teams
+ scientist_landmarks.len = max_teams
+ for(var/obj/effect/landmark/abductor/A in landmarks_list)
+ if(istype(A,/obj/effect/landmark/abductor/agent))
+ agent_landmarks[text2num(A.team)] = A
+ else if(istype(A,/obj/effect/landmark/abductor/scientist))
+ scientist_landmarks[text2num(A.team)] = A
+
+ var/datum/mind/agent
+ var/obj/effect/landmark/L
+ var/datum/mind/scientist
+ var/team_name
+ var/mob/living/carbon/human/H
+ var/datum/species/abductor/S
+
+ team_name = team_names[team_number]
+ agent = agents[team_number]
+ H = agent.current
+ L = agent_landmarks[team_number]
+ H.loc = L.loc
+ H.set_species("Abductor")
+ S = H.dna.species
+ S.agent = 1
+ S.team = team_number
+ H.real_name = team_name + " Agent"
+ equip_common(H,team_number)
+ equip_agent(H,team_number)
+ greet_agent(agent,team_number)
+
+
+ scientist = scientists[team_number]
+ H = scientist.current
+ L = scientist_landmarks[team_number]
+ H.loc = L.loc
+ H.set_species("Abductor")
+ S = H.dna.species
+ S.scientist = 1
+ S.team = team_number
+ H.real_name = team_name + " Scientist"
+ equip_common(H,team_number)
+ equip_scientist(H,team_number)
+ greet_scientist(scientist,team_number)
+
+
+
+/datum/game_mode/abduction/proc/greet_agent(datum/mind/abductor,team_number)
+ abductor.objectives += team_objectives[team_number]
+ var/team_name = team_names[team_number]
+
+ to_chat(abductor.current, "You are an agent of [team_name]!")
+ to_chat(abductor.current, "With the help of your teammate, kidnap and experiment on station crew members!")
+ to_chat(abductor.current, "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve.")
+
+ var/obj_count = 1
+ for(var/datum/objective/objective in abductor.objectives)
+ to_chat(abductor.current, "Objective #[obj_count]: [objective.explanation_text]")
+ obj_count++
+ return
+
+/datum/game_mode/abduction/proc/greet_scientist(datum/mind/abductor,team_number)
+ abductor.objectives += team_objectives[team_number]
+ var/team_name = team_names[team_number]
+
+ to_chat(abductor.current, "You are a scientist of [team_name]!")
+ to_chat(abductor.current, "With the help of your teammate, kidnap and experiment on station crew members!")
+ to_chat(abductor.current, "Use your tool and ship consoles to support the agent and retrieve human specimens.")
+
+ var/obj_count = 1
+ for(var/datum/objective/objective in abductor.objectives)
+ to_chat(abductor.current, "Objective #[obj_count]: [objective.explanation_text]")
+ obj_count++
+ return
+
+/datum/game_mode/abduction/proc/equip_common(mob/living/carbon/human/agent,team_number)
+ var/radio_freq = SYND_FREQ
+
+ var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate/alt(agent)
+ R.set_frequency(radio_freq)
+ agent.equip_to_slot_or_del(R, slot_l_ear)
+ agent.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(agent), slot_shoes)
+ agent.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey(agent), slot_w_uniform) //they're greys gettit
+ agent.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(agent), slot_back)
+
+/datum/game_mode/abduction/proc/get_team_console(team)
+ var/obj/machinery/abductor/console/console
+ for(var/obj/machinery/abductor/console/c in machines)
+ if(c.team == team)
+ console = c
+ break
+ return console
+
+/datum/game_mode/abduction/proc/equip_agent(mob/living/carbon/human/agent,team_number)
+ if(!team_number)
+ var/datum/species/abductor/S = agent.dna.species
+ team_number = S.team
+
+ var/obj/machinery/abductor/console/console = get_team_console(team_number)
+ var/obj/item/clothing/suit/armor/abductor/vest/V = new /obj/item/clothing/suit/armor/abductor/vest(agent)
+ if(console!=null)
+ console.vest = V
+ V.flags |= NODROP
+ agent.equip_to_slot_or_del(V, slot_wear_suit)
+ agent.equip_to_slot_or_del(new /obj/item/weapon/abductor_baton(agent), slot_in_backpack)
+ agent.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/decloner/alien(agent), slot_belt)
+ agent.equip_to_slot_or_del(new /obj/item/device/abductor/silencer(agent), slot_in_backpack)
+ agent.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/abductor(agent), slot_head)
+
+
+/datum/game_mode/abduction/proc/equip_scientist(var/mob/living/carbon/human/scientist,var/team_number)
+ if(!team_number)
+ var/datum/species/abductor/S = scientist.dna.species
+ team_number = S.team
+
+ var/obj/machinery/abductor/console/console = get_team_console(team_number)
+ var/obj/item/device/abductor/gizmo/G = new /obj/item/device/abductor/gizmo(scientist)
+ if(console!=null)
+ console.gizmo = G
+ G.console = console
+ scientist.equip_to_slot_or_del(G, slot_in_backpack)
+
+ var/obj/item/weapon/implant/abductor/beamplant = new /obj/item/weapon/implant/abductor(scientist)
+ beamplant.implant(scientist)
+
+
+/datum/game_mode/abduction/check_finished()
+ if(!finished)
+ for(var/team_number=1,team_number<=abductor_teams,team_number++)
+ var/obj/machinery/abductor/console/con = get_team_console(team_number)
+ var/datum/objective/objective = team_objectives[team_number]
+ if (con.experiment.points >= objective.target_amount)
+ shuttle_master.emergency.request(null, 0.5)
+ finished = 1
+ return ..()
+ return ..()
+
+/datum/game_mode/abduction/declare_completion()
+ for(var/team_number=1,team_number<=abductor_teams,team_number++)
+ var/obj/machinery/abductor/console/console = get_team_console(team_number)
+ var/datum/objective/objective = team_objectives[team_number]
+ var/team_name = team_names[team_number]
+ if(console.experiment.points >= objective.target_amount)
+ to_chat(world, "[team_name] team fullfilled its mission!")
+ else
+ to_chat(world, "[team_name] team failed its mission.")
+ ..()
+ return 1
+
+/datum/game_mode/proc/auto_declare_completion_abduction()
+ if(abductors.len)
+ to_chat(world, "Abductors:")
+ for(var/datum/mind/M in abductors)
+ to_chat(world, "Abductor [M.current ? M.current.name : "Abductor"]([M.key])")
+ return
+
+//Landmarks
+// TODO: Split into seperate landmarks for prettier ships
+/obj/effect/landmark/abductor
+ var/team = 1
+
+/obj/effect/landmark/abductor/console/New()
+ var/obj/machinery/abductor/console/c = new /obj/machinery/abductor/console(src.loc)
+ c.team = team
+
+ spawn(5) // I'd do this properly when i got some time, temporary hack for mappers
+ c.Initialize()
+ qdel(src)
+
+
+/obj/effect/landmark/abductor/agent
+/obj/effect/landmark/abductor/scientist
+
+
+// OBJECTIVES
+/datum/objective/experiment
+ target_amount = 6
+ var/team
+
+/datum/objective/experiment/New()
+ explanation_text = "Experiment on [target_amount] humans."
+
+/datum/objective/experiment/check_completion()
+ var/ab_team = team
+ if(owner)
+ if(!owner.current || !ishuman(owner.current))
+ return 0
+ var/mob/living/carbon/human/H = owner.current
+ if(H.get_species() != "Abductor")
+ return 0
+ var/datum/species/abductor/S = H.dna.species
+ ab_team = S.team
+ for(var/obj/machinery/abductor/experiment/E in machines)
+ if(E.team == ab_team)
+ if(E.points >= target_amount)
+ return 1
+ else
+ return 0
+ return 0
+
+/datum/game_mode/proc/update_abductor_icons_added(datum/mind/alien_mind)
+ var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_ABDUCTOR]
+ hud.join_hud(alien_mind.current)
+ set_antag_hud(alien_mind.current, ((alien_mind in abductors) ? "abductor" : "abductee"))
+
+/datum/game_mode/proc/update_abductor_icons_removed(datum/mind/alien_mind)
+ var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_ABDUCTOR]
+ hud.leave_hud(alien_mind.current)
+ set_antag_hud(alien_mind.current, null)
+
+/datum/objective/abductee
+ completed = 1
+
+/datum/objective/abductee/steal
+ explanation_text = "Steal all"
+
+/datum/objective/abductee/steal/New()
+ var/target = pick(list("pets","lights","monkeys","fruits","shoes","bars of soap"))
+ explanation_text+=" [target]."
+
+/datum/objective/abductee/capture
+ explanation_text = "Capture"
+
+/datum/objective/abductee/capture/New()
+ var/list/jobs = job_master.occupations.Copy()
+ for(var/datum/job/J in jobs)
+ if(J.current_positions < 1)
+ jobs -= J
+ if(jobs.len > 0)
+ var/datum/job/target = pick(jobs)
+ explanation_text += " a [target.title]."
+ else
+ explanation_text += " someone."
+
+/datum/objective/abductee/shuttle
+ explanation_text = "You must escape the station! Get the shuttle called!"
+
+/datum/objective/abductee/noclone
+ explanation_text = "Don't allow anyone to be cloned."
+
+/datum/objective/abductee/oxygen
+ explanation_text = "The oxygen is killing them all and they don't even know it. Make sure no oxygen is on the station."
+
+/datum/objective/abductee/blazeit
+ explanation_text = "Your body must be improved. Ingest as many drugs as you can."
+
+/datum/objective/abductee/yumyum
+ explanation_text = "You are hungry. Eat as much food as you can find."
+
+/datum/objective/abductee/insane
+ explanation_text = "You see you see what they cannot you see the open door you seeE you SEeEe you SEe yOU seEee SHOW THEM ALL"
+
+/datum/objective/abductee/cannotmove
+ explanation_text = "Convince the crew that you are a paraplegic."
+
+/datum/objective/abductee/deadbodies
+ explanation_text = "Start a collection of corpses. Don't kill people to get these corpses."
+
+/datum/objective/abductee/floors
+ explanation_text = "Replace all the floor tiles with carpeting, wooden boards, or grass."
+
+/datum/objective/abductee/POWERUNLIMITED
+ explanation_text = "Flood the station's powernet with as much electricity as you can."
+
+/datum/objective/abductee/pristine
+ explanation_text = "Ensure the station is in absolutely pristine condition."
+
+/datum/objective/abductee/window
+ explanation_text = "Replace all normal windows with reinforced windows."
+
+/datum/objective/abductee/nations
+ explanation_text = "Ensure your department prospers over all else."
+
+/datum/objective/abductee/abductception
+ explanation_text = "You have been changed forever. Find the ones that did this to you and give them a taste of their own medicine."
+
+/datum/objective/abductee/ghosts
+ explanation_text = "Conduct a seance with the spirits of the afterlife."
+
+/datum/objective/abductee/summon
+ explanation_text = "Conduct a ritual to summon an elder god."
+
+/datum/objective/abductee/machine
+ explanation_text = "You are secretly an android. Interface with as many machines as you can to boost your own power."
+
+/datum/objective/abductee/prevent
+ explanation_text = "You have been enlightened. This knowledge must not escape. Ensure nobody else can become enlightened."
+
+/datum/objective/abductee/calling
+ explanation_text = "Call forth a spirit from the other side."
+
+/datum/objective/abductee/calling/New()
+ var/mob/dead/D = pick(dead_mob_list)
+ if(D)
+ explanation_text = "You know that [D] has perished. Call them from the spirit realm."
+
+/datum/objective/abductee/social_experiment
+ explanation_text = "This is a secret social experiment conducted by Nanotrasen. Convince the crew that this is the truth."
+
+/datum/objective/abductee/vr
+ explanation_text = "It's all an entirely virtual simulation within an underground vault. Convince the crew to escape the shackles of VR."
+
+/datum/objective/abductee/pets
+ explanation_text = "Nanotrasen is abusing the animals! Save as many as you can!"
+
+/datum/objective/abductee/defect
+ explanation_text = "Defect from your employer."
+
+/datum/objective/abductee/promote
+ explanation_text = "Climb the corporate ladder all the way to the top!"
+
+/datum/objective/abductee/science
+ explanation_text = "So much lies undiscovered. Look deeper into the machinations of the universe."
+
+/datum/objective/abductee/build
+ explanation_text = "Expand the station."
+
+/datum/objective/abductee/pragnant
+ explanation_text = "You are pregnant and soon due. Find a safe place to deliver your baby."
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
new file mode 100644
index 00000000000..689398af78d
--- /dev/null
+++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
@@ -0,0 +1,644 @@
+#define VEST_STEALTH 1
+#define VEST_COMBAT 2
+#define GIZMO_SCAN 1
+#define GIZMO_MARK 2
+
+//AGENT VEST
+/obj/item/clothing/suit/armor/abductor/vest
+ name = "agent vest"
+ desc = "A vest outfitted with advanced stealth technology. It has two modes - combat and stealth."
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "vest_stealth"
+ item_state = "armor"
+ blood_overlay_type = "armor"
+ origin_tech = "materials=5;biotech=4;powerstorage=5;abductor=3"
+ armor = list(melee = 15, bullet = 15, laser = 15, energy = 15, bomb = 15, bio = 15, rad = 15)
+ action_button_is_hands_free = 1
+ var/mode = VEST_STEALTH
+ var/stealth_active = 0
+ var/combat_cooldown = 10
+ var/datum/icon_snapshot/disguise
+ var/stealth_armor = list(melee = 15, bullet = 15, laser = 15, energy = 15, bomb = 15, bio = 15, rad = 15)
+ var/combat_armor = list(melee = 50, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 50, rad = 50)
+
+/obj/item/clothing/suit/armor/abductor/vest/proc/flip_mode()
+ switch(mode)
+ if(VEST_STEALTH)
+ mode = VEST_COMBAT
+ DeactivateStealth()
+ armor = combat_armor
+ icon_state = "vest_combat"
+ if(istype(loc, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = loc
+ H.update_inv_wear_suit()
+ return
+ if(VEST_COMBAT)// TO STEALTH
+ mode = VEST_STEALTH
+ armor = stealth_armor
+ icon_state = "vest_stealth"
+ if(istype(loc, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = loc
+ H.update_inv_wear_suit()
+ return
+
+/obj/item/clothing/suit/armor/abductor/vest/proc/SetDisguise(datum/icon_snapshot/entry)
+ disguise = entry
+
+/obj/item/clothing/suit/armor/abductor/vest/proc/ActivateStealth()
+ if(disguise == null)
+ return
+ stealth_active = 1
+ if(istype(src.loc, /mob/living/carbon/human))
+ var/mob/living/carbon/human/M = src.loc
+ spawn(0)
+ anim(M.loc,M,'icons/mob/mob.dmi',,"cloak",,M.dir)
+
+ M.name_override = disguise.name
+ M.icon = disguise.icon
+ M.icon_state = disguise.icon_state
+ M.overlays = disguise.overlays
+ M.update_inv_r_hand()
+ M.update_inv_l_hand()
+ return
+
+/obj/item/clothing/suit/armor/abductor/vest/proc/DeactivateStealth()
+ if(!stealth_active)
+ return
+ stealth_active = 0
+ if(istype(src.loc, /mob/living/carbon/human))
+ var/mob/living/carbon/human/M = src.loc
+ spawn(0)
+ anim(M.loc,M,'icons/mob/mob.dmi',,"uncloak",,M.dir)
+ M.name_override = null
+ M.overlays.Cut()
+ M.regenerate_icons()
+ return
+
+/obj/item/clothing/suit/armor/abductor/vest/IsShield()
+ DeactivateStealth()
+ return 0
+
+/obj/item/clothing/suit/armor/abductor/vest/IsReflect()
+ DeactivateStealth()
+ return 0
+
+/obj/item/clothing/suit/armor/abductor/vest/ui_action_click()
+ switch(mode)
+ if(VEST_COMBAT)
+ Adrenaline()
+ if(VEST_STEALTH)
+ if(stealth_active)
+ DeactivateStealth()
+ else
+ ActivateStealth()
+
+/obj/item/clothing/suit/armor/abductor/vest/proc/Adrenaline()
+ if(istype(src.loc, /mob/living/carbon/human))
+ if(combat_cooldown != initial(combat_cooldown))
+ to_chat(src.loc, "Combat injection is still recharging.")
+ var/mob/living/carbon/human/M = src.loc
+ M.adjustStaminaLoss(-75)
+ M.SetParalysis(0)
+ M.SetStunned(0)
+ M.SetWeakened(0)
+ combat_cooldown = 0
+ processing_objects.Add(src)
+
+/obj/item/clothing/suit/armor/abductor/vest/process()
+ combat_cooldown++
+ if(combat_cooldown==initial(combat_cooldown))
+ processing_objects.Remove(src)
+
+/obj/item/device/abductor/proc/IsAbductor(user)
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ if(H.get_species() != "Abductor")
+ return 0
+ return 1
+ return 0
+
+/obj/item/device/abductor/proc/AbductorCheck(user)
+ if(IsAbductor(user))
+ return 1
+ to_chat(user, "You can't figure how this works!")
+ return 0
+
+/obj/item/device/abductor/proc/ScientistCheck(user)
+ var/mob/living/carbon/human/H = user
+ var/datum/species/abductor/S = H.dna.species
+ return S.scientist
+
+/obj/item/device/abductor/gizmo
+ name = "science tool"
+ desc = "A dual-mode tool for retrieving specimens and scanning appearances. Scanning can be done through cameras."
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "gizmo_scan"
+ item_state = "silencer"
+ origin_tech = "materials=5;magnets=5;bluespace=6;abductor=4"
+ var/mode = GIZMO_SCAN
+ var/mob/living/marked = null
+ var/obj/machinery/abductor/console/console
+
+/obj/item/device/abductor/gizmo/attack_self(mob/user)
+ if(!AbductorCheck(user))
+ return
+ if(!ScientistCheck(user))
+ to_chat(user, "You're not trained to use this!")
+ return
+ if(mode == GIZMO_SCAN)
+ mode = GIZMO_MARK
+ icon_state = "gizmo_mark"
+ else
+ mode = GIZMO_SCAN
+ icon_state = "gizmo_scan"
+ to_chat(user, "You switch the device to [mode==GIZMO_SCAN? "SCAN": "MARK"] MODE")
+
+/obj/item/device/abductor/gizmo/attack(mob/living/M, mob/user)
+ if(!AbductorCheck(user))
+ return
+ if(!ScientistCheck(user))
+ to_chat(user, "You're not trained to use this")
+ return
+ switch(mode)
+ if(GIZMO_SCAN)
+ scan(M, user)
+ if(GIZMO_MARK)
+ mark(M, user)
+
+
+/obj/item/device/abductor/gizmo/afterattack(atom/target, mob/living/user, flag, params)
+ if(flag)
+ return
+ if(!AbductorCheck(user))
+ return
+ if(!ScientistCheck(user))
+ to_chat(user, "You're not trained to use this")
+ return
+ switch(mode)
+ if(GIZMO_SCAN)
+ scan(target, user)
+ if(GIZMO_MARK)
+ mark(target, user)
+
+/obj/item/device/abductor/gizmo/proc/scan(atom/target, mob/living/user)
+ if(istype(target,/mob/living/carbon/human))
+ if(console!=null)
+ console.AddSnapshot(target)
+ to_chat(user, "You scan [target] and add them to the database.")
+
+/obj/item/device/abductor/gizmo/proc/mark(atom/target, mob/living/user)
+ if(marked == target)
+ to_chat(user, "This specimen is already marked!")
+ return
+ if(istype(target,/mob/living/carbon/human))
+ if(IsAbductor(target))
+ marked = target
+ to_chat(user, "You mark [target] for future retrieval.")
+ else
+ prepare(target,user)
+ else
+ prepare(target,user)
+
+/obj/item/device/abductor/gizmo/proc/prepare(atom/target, mob/living/user)
+ if(get_dist(target,user)>1)
+ to_chat(user, "You need to be next to the specimen to prepare it for transport!")
+ return
+ to_chat(user, "You begin preparing [target] for transport...")
+ if(do_after(user, 100, target = target))
+ marked = target
+ to_chat(user, "You finish preparing [target] for transport.")
+
+
+/obj/item/device/abductor/silencer
+ name = "abductor silencer"
+ desc = "A compact device used to shut down communications equipment."
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "silencer"
+ item_state = "gizmo"
+ origin_tech = "materials=5;magnets=5;abductor=3"
+
+/obj/item/device/abductor/silencer/attack(mob/living/M, mob/user)
+ if(!AbductorCheck(user))
+ return
+ radio_off(M, user)
+
+/obj/item/device/abductor/silencer/afterattack(atom/target, mob/living/user, flag, params)
+ if(flag)
+ return
+ if(!AbductorCheck(user))
+ return
+ radio_off(target, user)
+
+/obj/item/device/abductor/silencer/proc/radio_off(atom/target, mob/living/user)
+ if( !(user in (viewers(7,target))) )
+ return
+
+ var/turf/targloc = get_turf(target)
+
+ var/mob/living/carbon/human/M
+ for(M in view(2,targloc))
+ if(M == user)
+ continue
+ to_chat(user, "You silence [M]'s radio devices.")
+ radio_off_mob(M)
+
+/obj/item/device/abductor/silencer/proc/radio_off_mob(mob/living/carbon/human/M)
+ var/list/all_items = M.GetAllContents()
+
+ for(var/obj/I in all_items)
+ if(istype(I,/obj/item/device/radio/))
+ var/obj/item/device/radio/r = I
+ r.listening = 0
+ if(!istype(I,/obj/item/device/radio/headset))
+ r.broadcasting = 0 //goddamned headset hacks
+
+
+/obj/item/weapon/implant/abductor
+ name = "recall implant"
+ desc = "Returns you to the mothership."
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "implant"
+ activated = 1
+ origin_tech = "materials=2;biotech=3;magnets=4;bluespace=5;abductor=5"
+ var/obj/machinery/abductor/pad/home
+ var/cooldown = 30
+
+/obj/item/weapon/implant/abductor/activate()
+ if(cooldown == initial(cooldown))
+ home.Retrieve(imp_in,1)
+ cooldown = 0
+ processing_objects.Add(src)
+ else
+ to_chat(imp_in, "You must wait [30 - cooldown] seconds to use [src] again!")
+ return
+
+/obj/item/weapon/implant/abductor/process()
+ if(cooldown < initial(cooldown))
+ cooldown++
+ if(cooldown == initial(cooldown))
+ processing_objects.Remove(src)
+
+/obj/item/weapon/implant/abductor/implant(var/mob/source, var/mob/user)
+ if(..())
+ var/obj/machinery/abductor/console/console
+ if(ishuman(source))
+ var/mob/living/carbon/human/H = source
+ if(H.get_species() == "Abductor")
+ var/datum/species/abductor/S = H.dna.species
+ console = get_team_console(S.team)
+ home = console.pad
+
+ if(!home)
+ console = get_team_console(pick(1, 2, 3, 4))
+ home = console.pad
+ return 1
+
+/obj/item/weapon/implant/abductor/proc/get_team_console(var/team)
+ var/obj/machinery/abductor/console/console
+ for(var/obj/machinery/abductor/console/c in machines)
+ if(c.team == team)
+ console = c
+ break
+ return console
+
+/obj/item/weapon/gun/energy/decloner/alien
+ name = "alien pistol"
+ desc = "A complicated gun that fires bursts of high-intensity radiation."
+ icon_state = "alienpistol"
+ item_state = "alienpistol"
+ origin_tech = "combat=5;materials=4;powerstorage=3;abductor=3"
+
+/obj/item/weapon/paper/abductor
+ name = "Dissection Guide"
+ icon_state = "alienpaper_words"
+ info = {"Dissection for Dummies
+
+
+ 1.Acquire fresh specimen.
+ 2.Put the specimen on operating table
+ 3.Apply surgical drapes preparing for dissection
+ 4.Apply scalpel to specimen torso
+ 5.Retract skin from specimen's torso
+ 6.Apply scalpel to specimen's torso
+ 7.Search through the specimen's torso with your hands to remove any organs
+ 8.Insert replacement gland (Retrieve one from gland storage)
+ 9.Consider dressing the specimen back to not disturb the habitat
+ 10.Put the specimen in the experiment machinery
+ 11.Choose one of the machine options and follow displayed instructions
+
+Congratulations! You are now trained for xenobiology research!"}
+
+/obj/item/weapon/paper/abductor/update_icon()
+ return
+
+#define BATON_STUN 0
+#define BATON_SLEEP 1
+#define BATON_CUFF 2
+#define BATON_PROBE 3
+#define BATON_MODES 4
+
+/obj/item/weapon/abductor_baton
+ name = "advanced baton"
+ desc = "A quad-mode baton used for incapacitation and restraining of specimens."
+ var/mode = BATON_STUN
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "wonderprodStun"
+ item_state = "wonderprod"
+ slot_flags = SLOT_BELT
+ origin_tech = "materials=6;combat=5;biotech=7;abductor=4"
+ force = 7
+ w_class = 3
+ action_button_name = "Toggle Mode"
+
+/obj/item/weapon/abductor_baton/proc/toggle(mob/living/user=usr)
+ mode = (mode+1)%BATON_MODES
+ var/txt
+ switch(mode)
+ if(BATON_STUN)
+ txt = "stunning"
+ if(BATON_SLEEP)
+ txt = "sleep inducement"
+ if(BATON_CUFF)
+ txt = "restraining"
+ if(BATON_PROBE)
+ txt = "probing"
+
+ to_chat(usr, "You switch the baton to [txt] mode.")
+ update_icon()
+
+/obj/item/weapon/abductor_baton/update_icon()
+ switch(mode)
+ if(BATON_STUN)
+ icon_state = "wonderprodStun"
+ item_state = "wonderprodStun"
+ if(BATON_SLEEP)
+ icon_state = "wonderprodSleep"
+ item_state = "wonderprodSleep"
+ if(BATON_CUFF)
+ icon_state = "wonderprodCuff"
+ item_state = "wonderprodCuff"
+ if(BATON_PROBE)
+ icon_state = "wonderprodProbe"
+ item_state = "wonderprodProbe"
+
+/obj/item/weapon/abductor_baton/proc/IsAbductor(mob/living/user)
+ if(!ishuman(user))
+ return 0
+ var/mob/living/carbon/human/H = user
+ if(H.get_species() != "Abductor")
+ return 0
+ return 1
+
+/obj/item/weapon/abductor_baton/attack(mob/target, mob/living/user)
+ if(!IsAbductor(user))
+ return
+
+ if(isrobot(target))
+ ..()
+ return
+
+ if(!isliving(target))
+ return
+
+ var/mob/living/L = target
+
+ user.do_attack_animation(L)
+
+ switch (mode)
+ if(BATON_STUN)
+ StunAttack(L,user)
+ if(BATON_SLEEP)
+ SleepAttack(L,user)
+ if(BATON_CUFF)
+ CuffAttack(L,user)
+ if(BATON_PROBE)
+ ProbeAttack(L,user)
+
+/obj/item/weapon/abductor_baton/attack_self(mob/living/user)
+ toggle(user)
+
+/obj/item/weapon/abductor_baton/proc/StunAttack(mob/living/L,mob/living/user)
+ user.lastattacked = L
+ L.lastattacker = user
+
+ L.Stun(7)
+ L.Weaken(7)
+ L.apply_effect(STUTTER, 7)
+
+ L.visible_message("[user] has stunned [L] with [src]!", \
+ "[user] has stunned you with [src]!")
+ playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
+
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ H.forcesay(hit_appends)
+
+ add_logs(user, L, "stunned")
+ return
+
+/obj/item/weapon/abductor_baton/proc/SleepAttack(mob/living/L,mob/living/user)
+ if(L.stunned)
+ L.visible_message("[user] has induced sleep in [L] with [src]!", \
+ "You suddenly feel very drowsy!")
+ playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
+ L.Sleeping(60)
+ add_logs(user, L, "put to sleep")
+ else
+ L.drowsyness += 1
+ to_chat(user, "Sleep inducement works fully only on stunned specimens! ")
+ L.visible_message("[user] tried to induce sleep in [L] with [src]!", \
+ "You suddenly feel drowsy!")
+ return
+
+/obj/item/weapon/abductor_baton/proc/CuffAttack(mob/living/L,mob/living/user)
+ if(!iscarbon(L))
+ return
+ var/mob/living/carbon/C = L
+ if(!C.handcuffed)
+ playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
+ C.visible_message("[user] begins restraining [C] with [src]!", \
+ "[user] begins shaping an energy field around your hands!")
+ if(do_mob(user, C, 30))
+ if(!C.handcuffed)
+ C.handcuffed = new /obj/item/weapon/restraints/handcuffs/energy/used(C)
+ C.update_inv_handcuffed(0)
+ to_chat(user, "You handcuff [C].")
+ add_logs(user, C, "handcuffed")
+ else
+ to_chat(user, "You fail to handcuff [C].")
+ return
+
+/obj/item/weapon/abductor_baton/proc/ProbeAttack(mob/living/L,mob/living/user)
+ L.visible_message("[user] probes [L] with [src]!", \
+ "[user] probes you!")
+
+ var/species = "Unknown species"
+ var/helptext = "Species unsuitable for experiments."
+
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ species = "[H.species.name]"
+ if(L.mind && L.mind.changeling)
+ species = "Changeling lifeform"
+ var/obj/item/organ/internal/gland/temp = locate() in H.internal_organs
+ if(temp)
+ helptext = "Experimental gland detected!"
+ else
+ helptext = "Subject suitable for experiments."
+
+ to_chat(user,"Probing result:[species]")
+ to_chat(user, "[helptext]")
+
+/obj/item/weapon/restraints/handcuffs/energy
+ name = "hard-light energy field"
+ desc = "A hard-light field restraining the hands."
+ icon_state = "cuff_white" // Needs sprite
+ breakouttime = 450
+ trashtype = /obj/item/weapon/restraints/handcuffs/energy/used
+ origin_tech = "materials=2;magnets=5;abductor=2"
+
+/obj/item/weapon/restraints/handcuffs/energy/used
+ desc = "energy discharge"
+
+/obj/item/weapon/restraints/handcuffs/energy/used/dropped(mob/user)
+ user.visible_message("[user]'s [src] break in a discharge of energy!", \
+ "[user]'s [src] break in a discharge of energy!")
+ var/datum/effect/system/spark_spread/S = new
+ S.set_up(4,0,user.loc)
+ S.start()
+ qdel(src)
+
+/obj/item/weapon/abductor_baton/examine(mob/user)
+ ..()
+ switch(mode)
+ if(BATON_STUN)
+ to_chat(user, "The baton is in stun mode.")
+ if(BATON_SLEEP)
+ to_chat(user, "The baton is in sleep inducement mode.")
+ if(BATON_CUFF)
+ to_chat(user, "The baton is in restraining mode.")
+ if(BATON_PROBE)
+ to_chat(user, "The baton is in probing mode.")
+
+
+/obj/item/weapon/scalpel/alien
+ name = "alien scalpel"
+ icon = 'icons/obj/abductor.dmi'
+ origin_tech = "materials=2;biotech=2;abductor=2"
+
+/obj/item/weapon/hemostat/alien
+ name = "alien hemostat"
+ icon = 'icons/obj/abductor.dmi'
+ origin_tech = "materials=2;biotech=2;abductor=2"
+
+/obj/item/weapon/retractor/alien
+ name = "alien retractor"
+ icon = 'icons/obj/abductor.dmi'
+ origin_tech = "materials=2;biotech=2;abductor=2"
+
+/obj/item/weapon/circular_saw/alien
+ name = "alien saw"
+ icon = 'icons/obj/abductor.dmi'
+ origin_tech = "materials=2;biotech=2;abductor=2"
+
+/obj/item/weapon/surgicaldrill/alien
+ name = "alien drill"
+ icon = 'icons/obj/abductor.dmi'
+ origin_tech = "materials=2;biotech=2;abductor=2"
+
+/obj/item/weapon/cautery/alien
+ name = "alien cautery"
+ icon = 'icons/obj/abductor.dmi'
+ origin_tech = "materials=2;biotech=2;abductor=2"
+
+/obj/item/clothing/head/helmet/abductor
+ name = "agent headgear"
+ desc = "Abduct with style - spiky style. Prevents digital tracking."
+ icon_state = "alienhelmet"
+ item_state = "alienhelmet"
+ blockTracking = 1
+ origin_tech = "materials=6;magnets=5;abductor=3"
+ flags = BLOCKHAIR
+ flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
+
+// Operating Table / Beds / Lockers
+
+/obj/machinery/optable/abductor
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "bed"
+
+/obj/structure/stool/bed/abductor
+ name = "resting contraption"
+ desc = "This looks similar to contraptions from earth. Could aliens be stealing our technology?"
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "bed"
+
+/obj/structure/abductor_tableframe
+ name = "alien table frame"
+ desc = "A sturdy table frame made from alien alloy."
+ icon_state = "alien_frame"
+ density = 1
+
+/obj/structure/abductor_tableframe/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/weapon/wrench))
+ to_chat(user, "You start disassembling [src]...")
+ playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ if(do_after(user, 30, target = src))
+ playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ new /obj/item/stack/sheet/mineral/abductor(get_turf(src))
+ qdel(src)
+ return
+ if(istype(I, /obj/item/stack/sheet/mineral/abductor))
+ var/obj/item/stack/sheet/P = I
+ if(P.get_amount() < 1)
+ to_chat(user, "You need one alien alloy sheet to do this!")
+ return
+ to_chat(user, "You start adding [P] to [src]...")
+ if(do_after(user, 50, target = src))
+ P.use(1)
+ new /obj/structure/table/abductor(src.loc)
+ qdel(src)
+ return
+
+/obj/structure/table/abductor
+ name = "alien table"
+ desc = "Advanced flat surface technology at work!"
+ icon = 'icons/obj/smooth_structures/alien_table.dmi'
+ icon_state = "alien_table"
+ canSmoothWith = null
+ parts = /obj/item/stack/sheet/mineral/abductor
+
+/obj/structure/closet/abductor
+ name = "alien locker"
+ desc = "Contains secrets of the universe."
+ icon_state = "abductor"
+ material_drop = /obj/item/stack/sheet/mineral/abductor
+
+/obj/structure/door_assembly/door_assembly_abductor
+ name = "alien airlock assembly"
+ icon = 'icons/obj/doors/abductor/abductor_airlock.dmi'
+ base_name = "abductor"
+ base_icon_state = "abductor"
+ airlock_type = "/abductor"
+ anchored = 1
+ state = 1
+
+/obj/structure/door_assembly/door_assembly_abductor/attackby(obj/item/W, mob/user, params)
+ if(istype(W, /obj/item/weapon/weldingtool) && !anchored )
+ var/obj/item/weapon/weldingtool/WT = W
+ if(WT.remove_fuel(0,user))
+ user.visible_message("[user] disassembles the airlock assembly.", \
+ "You start to disassemble the airlock assembly...")
+ playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
+ if(do_after(user, 40, target = src))
+ if( !WT.isOn() )
+ return
+ to_chat(user, "You disassemble the airlock assembly.")
+ new /obj/item/stack/sheet/mineral/abductor(get_turf(src), 4)
+ qdel(src)
+ else
+ return
+ else if(istype(W, /obj/item/stack/sheet))
+ return // no material modding
+ else
+ ..()
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm
new file mode 100644
index 00000000000..a9df076eea3
--- /dev/null
+++ b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm
@@ -0,0 +1,56 @@
+/datum/surgery/organ_extraction
+ name = "experimental dissection"
+ steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/open_encased/saw, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/internal/extract_organ, /datum/surgery_step/internal/gland_insert)
+ possible_locs = list("chest")
+
+/datum/surgery/organ_extraction/can_start(mob/user, mob/living/carbon/target)
+ if(!ishuman(user))
+ return 0
+ var/mob/living/carbon/human/H = user
+ if(H.get_species() == "Abductor")
+ return 1
+ if((locate(/obj/item/weapon/implant/abductor) in H))
+ return 1
+ return 0
+
+
+/datum/surgery_step/internal/extract_organ
+ name = "remove heart"
+ accept_hand = 1
+ time = 32
+ var/obj/item/organ/internal/IC = null
+ var/list/organ_types = list(/obj/item/organ/internal/heart)
+
+/datum/surgery_step/internal/extract_organ/begin_step(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ for(var/obj/item/I in target.internal_organs)
+ if(I.type in organ_types)
+ IC = I
+ break
+ user.visible_message("[user] starts to remove [target]'s organs.", "You start to remove [target]'s organs...")
+ ..()
+
+/datum/surgery_step/internal/extract_organ/end_step(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ if(IC)
+ user.visible_message("[user] pulls [IC] out of [target]'s [target_zone]!", "You pull [IC] out of [target]'s [target_zone].")
+ user.put_in_hands(IC)
+ IC.remove(target, special = 1)
+ return 1
+ else
+ to_chat(user, "You don't find anything in [target]'s [target_zone]!")
+ return 0
+
+/datum/surgery_step/internal/gland_insert
+ name = "insert gland"
+ allowed_tools = list(/obj/item/organ/internal/gland = 100)
+ time = 32
+
+/datum/surgery_step/internal/gland_insert/begin_step(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] starts to insert [tool] into [target].", "You start to insert [tool] into [target]...")
+ ..()
+
+/datum/surgery_step/internal/gland_insert/end_step(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] inserts [tool] into [target].", "You insert [tool] into [target].")
+ user.drop_item()
+ var/obj/item/organ/internal/gland/gland = tool
+ gland.insert(target, 2)
+ return 1
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm
new file mode 100644
index 00000000000..51396f1d7ce
--- /dev/null
+++ b/code/game/gamemodes/miniantags/abduction/gland.dm
@@ -0,0 +1,281 @@
+/obj/item/organ/internal/gland
+ name = "fleshy mass"
+ desc = "A nausea-inducing hunk of twisting flesh and metal."
+ icon = 'icons/obj/abductor.dmi'
+ parent_organ = "chest"
+ slot = "gland"
+ icon_state = "gland"
+ status = ORGAN_ROBOT
+ origin_tech = "materials=4;biotech=5;abductor=3"
+ var/cooldown_low = 300
+ var/cooldown_high = 300
+ var/next_activation = 0
+ var/uses // -1 For inifinite
+ var/human_only = 0
+ var/active = 0
+ tough = 1 //not easily broken by combat damage
+ sterile = 1 //not very germy
+
+/obj/item/organ/internal/gland/proc/ownerCheck()
+ if(ishuman(owner))
+ return 1
+ if(!human_only && iscarbon(owner))
+ return 1
+ return 0
+
+/obj/item/organ/internal/gland/proc/Start()
+ active = 1
+ next_activation = world.time + rand(cooldown_low,cooldown_high)
+
+
+/obj/item/organ/internal/gland/remove(var/mob/living/carbon/M, special = 0)
+ active = 0
+ if(initial(uses) == 1)
+ uses = initial(uses)
+ ..()
+
+/obj/item/organ/internal/gland/insert(var/mob/living/carbon/M, special = 0)
+ ..()
+ if(special != 2 && uses) // Special 2 means abductor surgery
+ Start()
+
+/obj/item/organ/internal/gland/on_life()
+ if(!active)
+ return
+ if(!ownerCheck())
+ active = 0
+ return
+ if(next_activation <= world.time)
+ activate()
+ uses--
+ next_activation = world.time + rand(cooldown_low,cooldown_high)
+ if(!uses)
+ active = 0
+
+/obj/item/organ/internal/gland/proc/activate()
+ return
+
+/obj/item/organ/internal/gland/heals
+ origin_tech = "materials=4;biotech=6;abductor=3"
+ cooldown_low = 200
+ cooldown_high = 400
+ uses = -1
+ icon_state = "health"
+
+/obj/item/organ/internal/gland/heals/activate()
+ to_chat(owner, "You feel curiously revitalized.")
+ owner.adjustBruteLoss(-20)
+ owner.adjustOxyLoss(-20)
+ owner.adjustFireLoss(-20)
+
+/obj/item/organ/internal/gland/slime
+ origin_tech = "materials=4;biotech=6;abductor=3"
+ cooldown_low = 600
+ cooldown_high = 1200
+ uses = -1
+ icon_state = "slime"
+
+/obj/item/organ/internal/gland/slime/activate()
+ to_chat(owner, "You feel nauseous!")
+ owner.vomit(20)
+
+ var/mob/living/carbon/slime/Slime = new/mob/living/carbon/slime(get_turf(owner))
+ Slime.Friends = list(owner)
+ Slime.Leader = owner
+
+/obj/item/organ/internal/gland/mindshock
+ origin_tech = "materials=4;biotech=5;magnets=3;abductor=3"
+ cooldown_low = 300
+ cooldown_high = 300
+ uses = -1
+ icon_state = "mindshock"
+
+/obj/item/organ/internal/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
+ to_chat(H, "You hear a buzz in your head.")
+ H.confused += 20
+
+/obj/item/organ/internal/gland/pop
+ origin_tech = "materials=4;biotech=6;abductor=3"
+ cooldown_low = 900
+ cooldown_high = 1800
+ uses = 6
+ human_only = 1
+ icon_state = "species"
+
+/obj/item/organ/internal/gland/pop/activate()
+ to_chat(owner, "You feel unlike yourself.")
+ var/species = pick("Unathi","Skrell","Diona","Tajaran","Vulpkanin","Kidan","Grey","Diona")
+ owner.set_species(species)
+
+/obj/item/organ/internal/gland/ventcrawling
+ origin_tech = "materials=4;biotech=5;bluespace=3;abductor=3"
+ cooldown_low = 1800
+ cooldown_high = 2400
+ uses = 1
+ icon_state = "vent"
+
+/obj/item/organ/internal/gland/ventcrawling/activate()
+ to_chat(owner, "You feel very stretchy.")
+ owner.ventcrawler = 2
+ return
+
+
+/obj/item/organ/internal/gland/viral
+ origin_tech = "materials=4;biotech=6;abductor=3"
+ cooldown_low = 1800
+ cooldown_high = 2400
+ uses = 1
+ icon_state = "viral"
+
+/obj/item/organ/internal/gland/viral/activate()
+ to_chat(owner, "You feel sick.")
+ var/virus_type = pick(/datum/disease/beesease, /datum/disease/brainrot, /datum/disease/magnitis)
+ var/datum/disease/D = new virus_type()
+ D.carrier = 1
+ owner.viruses += D
+ D.affected_mob = owner
+ D.holder = owner
+ owner.med_hud_set_status()
+
+
+/obj/item/organ/internal/gland/emp //TODO : Replace with something more interesting
+ origin_tech = "materials=4;biotech=5;magnets=3;abductor=3"
+ cooldown_low = 900
+ cooldown_high = 1600
+ uses = 10
+ icon_state = "emp"
+
+/obj/item/organ/internal/gland/emp/activate()
+ to_chat(owner, "You feel a spike of pain in your head.")
+ empulse(get_turf(owner), 2, 5, 1)
+
+/obj/item/organ/internal/gland/spiderman
+ origin_tech = "materials=4;biotech=6;abductor=3"
+ cooldown_low = 450
+ cooldown_high = 900
+ uses = 10
+ icon_state = "spider"
+
+/obj/item/organ/internal/gland/spiderman/activate()
+ to_chat(owner, "You feel something crawling in your skin.")
+ owner.faction |= "spiders"
+ new /obj/effect/spider/spiderling(owner.loc)
+
+/obj/item/organ/internal/gland/egg
+ origin_tech = "materials=4;biotech=6;abductor=3"
+ cooldown_low = 300
+ cooldown_high = 400
+ uses = -1
+ icon_state = "egg"
+
+/obj/item/organ/internal/gland/egg/activate()
+ to_chat(owner, "You lay an egg!")
+ var/obj/item/weapon/reagent_containers/food/snacks/egg/egg = new(owner.loc)
+ egg.reagents.add_reagent("sacid",20)
+ egg.desc += " It smells bad."
+
+/obj/item/organ/internal/gland/bloody
+ origin_tech = "materials=4;biotech=6;abductor=3"
+ cooldown_low = 200
+ cooldown_high = 400
+ uses = -1
+
+/obj/item/organ/internal/gland/bloody/activate()
+ owner.adjustBruteLoss(15)
+
+ owner.visible_message("[owner]'s skin erupts with blood!",\
+ "Blood pours from your skin!")
+
+ for(var/turf/T in oview(3,owner)) //Make this respect walls and such
+ T.add_blood_floor(owner)
+ for(var/mob/living/carbon/human/H in oview(3,owner)) //Blood decals for simple animals would be neat. aka Carp with blood on it.
+ if(H.wear_suit)
+ H.wear_suit.add_blood(owner)
+ H.update_inv_wear_suit(0)
+ else if(H.w_uniform)
+ H.w_uniform.add_blood(owner)
+ H.update_inv_w_uniform(0)
+
+/obj/item/organ/internal/gland/bodysnatch
+ origin_tech = "materials=4;biotech=7;abductor=3"
+ cooldown_low = 600
+ cooldown_high = 600
+ human_only = 1
+ uses = 1
+
+/obj/item/organ/internal/gland/bodysnatch/activate()
+ to_chat(owner, "You feel something moving around inside you...")
+ //spawn cocoon with clone greytide snpc inside
+ if(ishuman(owner))
+ var/obj/effect/cocoon/abductor/C = new (get_turf(owner))
+ C.Copy(owner)
+ C.Start()
+ owner.gib()
+ return
+
+/obj/effect/cocoon/abductor
+ name = "slimy cocoon"
+ desc = "Something is moving inside."
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "cocoon_large3"
+ color = rgb(10,120,10)
+ density = 1
+ var/hatch_time = 0
+
+/obj/effect/cocoon/abductor/proc/Copy(mob/living/carbon/human/H)
+ var/mob/living/carbon/human/interactive/greytide/clone = new(src)
+ var/datum/dna/owner_dna = H.dna
+ clone.real_name = owner_dna.real_name
+ clone.set_species(H.species.name)
+ clone.body_accessory = H.body_accessory
+ clone.dna = owner_dna.Clone()
+ clone.UpdateAppearance()
+ domutcheck(clone)
+
+ //There's no define for this / get all items ?
+ var/list/slots = list(slot_back,slot_w_uniform,slot_wear_suit,\
+ slot_wear_mask,slot_head,slot_shoes,slot_gloves,slot_l_ear,slot_r_ear,\
+ slot_glasses,slot_belt,slot_s_store,slot_l_store,slot_r_store,slot_wear_id,slot_wear_pda)
+
+ for(var/slot in slots)
+ var/obj/item/I = H.get_item_by_slot(slot)
+ if(I)
+ clone.equip_to_slot_if_possible(I,slot)
+
+/obj/effect/cocoon/abductor/proc/Start()
+ hatch_time = world.time + 600
+ processing_objects.Add(src)
+
+/obj/effect/cocoon/abductor/process()
+ if(world.time > hatch_time)
+ processing_objects.Remove(src)
+ for(var/mob/M in contents)
+ src.visible_message("[src] hatches!")
+ M.loc = src.loc
+ qdel(src)
+
+/obj/item/organ/internal/gland/plasma
+ cooldown_low = 2400
+ cooldown_high = 3000
+ origin_tech = "materials=4;biotech=5;plasmatech=3;abductor=3"
+ uses = 1
+
+/obj/item/organ/internal/gland/plasma/activate()
+ to_chat(owner, "You feel bloated.")
+ sleep(150)
+ if(!owner) return
+ to_chat(owner, "A massive stomachache overcomes you.")
+ sleep(50)
+ if(!owner) return
+ owner.visible_message("[owner] explodes in a cloud of plasma!")
+ var/turf/simulated/T = get_turf(owner)
+ if(istype(T))
+ T.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C,300)
+ owner.gib()
+ return
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/camera.dm b/code/game/gamemodes/miniantags/abduction/machinery/camera.dm
new file mode 100644
index 00000000000..8368b8c06e4
--- /dev/null
+++ b/code/game/gamemodes/miniantags/abduction/machinery/camera.dm
@@ -0,0 +1,165 @@
+/obj/machinery/computer/camera_advanced/abductor
+ name = "Human Observation Console"
+ var/team = 0
+ networks = list("SS13","Abductor")
+ off_action = new/datum/action/camera_off/abductor //specific datum
+ var/datum/action/teleport_in/tele_in_action = new
+ var/datum/action/teleport_out/tele_out_action = new
+ var/datum/action/teleport_self/tele_self_action = new
+ var/datum/action/vest_mode_swap/vest_mode_action = new
+ var/datum/action/vest_disguise_swap/vest_disguise_action = new
+ var/datum/action/set_droppoint/set_droppoint_action = new
+ var/obj/machinery/abductor/console/console
+
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "camera"
+
+/obj/machinery/computer/camera_advanced/abductor/CreateEye()
+ ..()
+ eyeobj.visible_icon = 1
+ eyeobj.icon = 'icons/obj/abductor.dmi'
+ eyeobj.icon_state = "camera_target"
+
+/obj/machinery/computer/camera_advanced/abductor/GrantActions(mob/living/carbon/user)
+ off_action.target = user
+ off_action.Grant(user)
+
+ jump_action.target = user
+ jump_action.Grant(user)
+ //TODO : add null checks
+ tele_in_action.target = console.pad
+ tele_in_action.Grant(user)
+
+ tele_out_action.target = console
+ tele_out_action.Grant(user)
+
+ tele_self_action.target = console.pad
+ tele_self_action.Grant(user)
+
+ vest_mode_action.target = console
+ vest_mode_action.Grant(user)
+
+ vest_disguise_action.target = console
+ vest_disguise_action.Grant(user)
+
+ set_droppoint_action.target = console
+ set_droppoint_action.Grant(user)
+
+/obj/machinery/computer/camera_advanced/abductor/proc/IsAbductor(mob/living/carbon/human/H)
+ return H.get_species() == "Abductor"
+
+/obj/machinery/computer/camera_advanced/abductor/proc/IsScientist(mob/living/carbon/human/H)
+ var/datum/species/abductor/S = H.dna.species
+ return S.scientist
+
+/obj/machinery/computer/camera_advanced/abductor/attack_hand(mob/user)
+ if(!iscarbon(user) || !IsAbductor(user))
+ return
+ return ..()
+
+/datum/action/camera_off/abductor/Activate()
+ if(!target || !iscarbon(target))
+ return
+ var/mob/living/carbon/C = target
+ var/mob/camera/aiEye/remote/remote_eye = C.remote_control
+ var/obj/machinery/computer/camera_advanced/abductor/origin = remote_eye.origin
+ C.remote_view = 0
+ origin.current_user = null
+ origin.jump_action.Remove(C)
+ origin.tele_in_action.Remove(C)
+ origin.tele_out_action.Remove(C)
+ origin.tele_self_action.Remove(C)
+ origin.vest_mode_action.Remove(C)
+ origin.vest_disguise_action.Remove(C)
+ origin.set_droppoint_action.Remove(C)
+ remote_eye.user = null
+ if(C.client)
+ C.client.perspective = MOB_PERSPECTIVE
+ C.client.eye = src
+ C.client.images -= remote_eye.user_image
+ for(var/datum/camerachunk/chunk in remote_eye.visibleCameraChunks)
+ C.client.images -= chunk.obscured
+ C.remote_control = null
+ C.unset_machine()
+ src.Remove(C)
+
+
+/datum/action/teleport_in
+ name = "Send To"
+ button_icon_state = "beam_down"
+ action_type = AB_INNATE
+
+/datum/action/teleport_in/Activate()
+ if(!target || !iscarbon(owner))
+ return
+ var/mob/living/carbon/human/C = owner
+ var/mob/camera/aiEye/remote/remote_eye = C.remote_control
+ var/obj/machinery/abductor/pad/P = target
+
+ if(cameranet.checkTurfVis(remote_eye.loc))
+ P.PadToLoc(remote_eye.loc)
+
+/datum/action/teleport_out
+ name = "Retrieve"
+ button_icon_state = "beam_up"
+ action_type = AB_INNATE
+
+/datum/action/teleport_out/Activate()
+ if(!target || !iscarbon(owner))
+ return
+ var/obj/machinery/abductor/console/console = target
+
+ console.TeleporterRetrieve()
+
+/datum/action/teleport_self
+ name = "Send Self"
+ button_icon_state = "beam_down"
+ action_type = AB_INNATE
+
+/datum/action/teleport_self/Activate()
+ if(!target || !iscarbon(owner))
+ return
+ var/mob/living/carbon/human/C = owner
+ var/mob/camera/aiEye/remote/remote_eye = C.remote_control
+ var/obj/machinery/abductor/pad/P = target
+
+ if(cameranet.checkTurfVis(remote_eye.loc))
+ P.MobToLoc(remote_eye.loc,C)
+
+/datum/action/vest_mode_swap
+ name = "Switch Vest Mode"
+ button_icon_state = "vest_mode"
+ action_type = AB_INNATE
+
+/datum/action/vest_mode_swap/Activate()
+ if(!target || !iscarbon(owner))
+ return
+ var/obj/machinery/abductor/console/console = target
+ console.FlipVest()
+
+
+/datum/action/vest_disguise_swap
+ name = "Switch Vest Disguise"
+ button_icon_state = "vest_disguise"
+ action_type = AB_INNATE
+
+/datum/action/vest_disguise_swap/Activate()
+ if(!target || !iscarbon(owner))
+ return
+ var/obj/machinery/abductor/console/console = target
+ console.SelectDisguise(remote=1)
+
+/datum/action/set_droppoint
+ name = "Set Experiment Release Point"
+ button_icon_state = "set_drop"
+ action_type = AB_INNATE
+
+/datum/action/set_droppoint/Activate()
+ if(!target || !iscarbon(owner))
+ return
+
+ var/mob/living/carbon/human/C = owner
+ var/mob/camera/aiEye/remote/remote_eye = C.remote_control
+
+ var/obj/machinery/abductor/console/console = target
+ console.SetDroppoint(remote_eye.loc,owner)
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/console.dm b/code/game/gamemodes/miniantags/abduction/machinery/console.dm
new file mode 100644
index 00000000000..b9f6a983b9c
--- /dev/null
+++ b/code/game/gamemodes/miniantags/abduction/machinery/console.dm
@@ -0,0 +1,211 @@
+//Common
+
+/obj/machinery/abductor
+ var/team = 0
+
+/obj/machinery/abductor/proc/IsAbductor(mob/living/carbon/human/H)
+ return H.get_species() == "Abductor"
+
+/obj/machinery/abductor/proc/IsAgent(mob/living/carbon/human/H)
+ if(H.get_species() == "Abductor")
+ var/datum/species/abductor/S = H.dna.species
+ return S.agent
+ return 0
+
+/obj/machinery/abductor/proc/IsScientist(mob/living/carbon/human/H)
+ if(H.get_species() == "Abductor")
+ var/datum/species/abductor/S = H.dna.species
+ return S.scientist
+ return 0
+
+//Console
+
+/obj/machinery/abductor/console
+ name = "Abductor console"
+ desc = "Ship command center."
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "console"
+ density = 1
+ anchored = 1
+ var/obj/item/device/abductor/gizmo/gizmo
+ var/obj/item/clothing/suit/armor/abductor/vest/vest
+ var/obj/machinery/abductor/experiment/experiment
+ var/obj/machinery/abductor/pad/pad
+ var/obj/machinery/computer/camera_advanced/abductor/camera
+ var/list/datum/icon_snapshot/disguises = list()
+
+/obj/machinery/abductor/console/attack_hand(mob/user)
+ if(..())
+ return
+ if(!IsAbductor(user))
+ to_chat(user, "You start mashing alien buttons at random!")
+ if(do_after(user,100, target = src))
+ TeleporterSend()
+ return
+ user.set_machine(src)
+ var/dat = ""
+ dat += "
| " + dat += " | "
+ dat += "Probe " + dat += "Dissect " + dat += "Analyze " + dat += " |