diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index 4136771eef5..fffcbd09f30 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -56,7 +56,7 @@ var/global/list/special_roles = list(
// ROLE_MONKEY = /datum/game_mode/monkey, Sooner or later these are going to get ported
// ROLE_GANG = /datum/game_mode/gang,
ROLE_SHADOWLING = /datum/game_mode/shadowling,
-// ROLE_ABDUCTOR = /datum/game_mode/abduction,
+ ROLE_ABDUCTOR = /datum/game_mode/abduction,
// ROLE_HOG_GOD = /datum/game_mode/hand_of_god,
// ROLE_HOG_CULTIST = /datum/game_mode/hand_of_god,
ROLE_RAIDER = /datum/game_mode/heist,
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 46f2f039f73..a7fb80b87fb 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -346,6 +346,26 @@
sections["shadowling"] = text
+ /** Abductors **/
+
+ text = "Abductor"
+ if(ticker.mode.config_tag == "abductor")
+ text = uppertext(text)
+ text = "[text]: "
+ if(src in ticker.mode.abductors)
+ text += "Abductor|human"
+ text += "|undress|equip"
+ else
+ text += "Abductor|human"
+
+ if(current && current.client && (ROLE_ABDUCTOR in current.client.prefs.be_special))
+ text += "|Enabled in Prefs"
+ else
+ text += "|Disabled in Prefs"
+
+
+ sections["Abductor"] = text
+
/** SILICON ***/
if (istype(current, /mob/living/silicon))
@@ -1069,6 +1089,28 @@
message_admins("[key_name_admin(usr)] has thralled [current].")
log_admin("[key_name(usr)] has thralled [current].")
+ else if(href_list["abductor"])
+ switch(href_list["abductor"])
+ if("clear")
+ to_chat(usr, "Not implemented yet. Sorry!")
+ //ticker.mode.update_abductor_icons_removed(src)
+ if("abductor")
+ if(!ishuman(current))
+ to_chat(usr, "This only works on humans!")
+ return
+ make_Abductor()
+ log_admin("[key_name(usr)] turned [current] into abductor.")
+ ticker.mode.update_abductor_icons_added(src)
+ if("equip")
+ var/gear = alert("Agent or Scientist Gear","Gear","Agent","Scientist")
+ if(gear)
+ var/datum/game_mode/abduction/temp = new
+ temp.equip_common(current)
+ if(gear=="Agent")
+ temp.equip_agent(current)
+ else
+ temp.equip_scientist(current)
+
else if (href_list["silicon"])
switch(href_list["silicon"])
if("unmalf")
@@ -1373,6 +1415,57 @@
// fail |= !ticker.mode.equip_traitor(current, 1)
fail |= !ticker.mode.equip_revolutionary(current)
+/datum/mind/proc/make_Abductor()
+ var/role = alert("Abductor Role ?","Role","Agent","Scientist")
+ var/team = input("Abductor Team ?","Team ?") in list(1,2,3,4)
+ var/teleport = alert("Teleport to ship ?","Teleport","Yes","No")
+
+ if(!role || !team || !teleport)
+ return
+
+ if(!ishuman(current))
+ return
+
+ ticker.mode.abductors |= src
+
+ var/datum/objective/experiment/O = new
+ O.owner = src
+ objectives += O
+
+ var/mob/living/carbon/human/H = current
+
+ H.set_species("Abductor")
+
+ switch(role)
+ if("Agent")
+ H.mind.abductor.agent = 1
+ if("Scientist")
+ H.mind.abductor.scientist = 1
+ H.mind.abductor.team = team
+
+ var/list/obj/effect/landmark/abductor/agent_landmarks = new
+ var/list/obj/effect/landmark/abductor/scientist_landmarks = new
+ agent_landmarks.len = 4
+ scientist_landmarks.len = 4
+ 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/obj/effect/landmark/L
+ if(teleport=="Yes")
+ switch(role)
+ if("Agent")
+ H.mind.abductor.agent = 1
+ L = agent_landmarks[team]
+ H.loc = L.loc
+ if("Scientist")
+ H.mind.abductor.scientist = 1
+ L = agent_landmarks[team]
+ H.loc = L.loc
+
+
// check whether this mind's mob has been brigged for the given duration
// have to call this periodically for the duration to work properly
/datum/mind/proc/is_brigged(duration)
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
index a829d53e567..01f4435a1d1 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
@@ -308,6 +308,14 @@
item_state = "alienpistol"
origin_tech = "combat=5;materials=4;powerstorage=3;abductor=3"
+/obj/item/weapon/gun/energy/decloner/alien/special_check(user)
+ if(istype(user, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = user
+ if(H.get_species() != "Abductor")
+ to_chat(user, "UNAUTHORIZED -- UNAUTHORIZED")
+ return 0
+ return 1
+
/obj/item/weapon/paper/abductor
name = "Dissection Guide"
icon_state = "alienpaper_words"
@@ -318,15 +326,16 @@
2.Put the specimen on operating table
3.Apply scalpel to the chest, preparing for dissection
4.Apply scalpel to specimen torso
- 5.Clamp bleeders on the specimen's torso
+ 5.Clamp bleeders on the specimen's torso
6.Retract skin from specimen's torso
7.Saw through the specimen's torso
8.Retract skin from specimen's torso again
- 9.Search through the specimen's torso with your hands to remove any organs
+ 9.Search through the specimen's torso with your hands to remove their heart
10.Insert replacement gland (Retrieve one from gland storage)
- 11.Consider dressing the specimen back to not disturb the habitat
- 12.Put the specimen in the experiment machinery
- 13.Choose one of the machine options and follow displayed instructions
+ 11.Cauterize the patient's torso
+ 12.Consider dressing the specimen back to not disturb the habitat
+ 13.Put the specimen in the experiment machinery
+ 14.Choose one of the machine options and follow displayed instructions
Congratulations! You are now trained for xenobiology research!"}
@@ -418,6 +427,10 @@ Congratulations! You are now trained for xenobiology research!"}
/obj/item/weapon/abductor_baton/attack_self(mob/living/user)
toggle(user)
+ if(istype(user,/mob/living/carbon/human))
+ var/mob/living/carbon/human/H = user
+ H.update_inv_l_hand()
+ H.update_inv_r_hand()
/obj/item/weapon/abductor_baton/proc/StunAttack(mob/living/L,mob/living/user)
user.lastattacked = L
@@ -435,7 +448,7 @@ Congratulations! You are now trained for xenobiology research!"}
var/mob/living/carbon/human/H = L
H.forcesay(hit_appends)
- add_logs(user, L, "stunned")
+ add_logs(L, user, "stunned")
return
/obj/item/weapon/abductor_baton/proc/SleepAttack(mob/living/L,mob/living/user)
@@ -444,7 +457,7 @@ Congratulations! You are now trained for xenobiology research!"}
"You suddenly feel very drowsy!")
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
L.Sleeping(60)
- add_logs(user, L, "put to sleep")
+ add_logs(L, user, "put to sleep")
else
L.drowsyness += 1
to_chat(user, "Sleep inducement works fully only on stunned specimens! ")
@@ -465,7 +478,7 @@ Congratulations! You are now trained for xenobiology research!"}
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/energy/used(C)
C.update_inv_handcuffed()
to_chat(user, "You handcuff [C].")
- add_logs(user, C, "handcuffed")
+ add_logs(C, user, "handcuffed")
else
to_chat(user, "You fail to handcuff [C].")
return
@@ -488,7 +501,7 @@ Congratulations! You are now trained for xenobiology research!"}
else
helptext = "Subject suitable for experiments."
- to_chat(user,"Probing result:[species]")
+ to_chat(user,"Probing result: [species]")
to_chat(user, "[helptext]")
/obj/item/weapon/restraints/handcuffs/energy
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm
index a9df076eea3..5666a2a1fa8 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm
@@ -1,6 +1,6 @@
/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)
+ 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, /datum/surgery_step/generic/cauterize)
possible_locs = list("chest")
/datum/surgery/organ_extraction/can_start(mob/user, mob/living/carbon/target)
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 932fcef0807..6e4f58c5ab2 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -749,6 +749,10 @@ var/global/nologevent = 0
if (ticker.mode.config_tag == "changeling")
return 2
return 1
+ if(M.mind in ticker.mode.abductors)
+ if (ticker.mode.config_tag == "abduction")
+ return 2
+ return 1
if(isrobot(M))
var/mob/living/silicon/robot/R = M
if(R.emagged)
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 30277f3a4ab..2a4a3e9cdeb 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -515,6 +515,12 @@
if(ticker.mode.shadowling_thralls.len)
dat += check_role_table("Shadowling Thralls", ticker.mode.shadowling_thralls, src)
+ if(ticker.mode.abductors.len)
+ dat += check_role_table("Abductors", ticker.mode.abductors, src)
+
+ if(ticker.mode.abductees.len)
+ dat += check_role_table("Abductees", ticker.mode.abductees, src)
+
if(ticker.mode.vampires.len)
dat += check_role_table("Vampires", ticker.mode.vampires, src)
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 60e196c7982..f93e8c416bf 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -63,6 +63,10 @@
log_admin("[key_name(usr)] has spawned vox raiders.")
if(!src.makeVoxRaiders())
to_chat(usr, "\red Unfortunately there weren't enough candidates available.")
+ if("9")
+ log_admin("[key_name(usr)] has spawned an abductor team.")
+ if(!src.makeAbductorTeam())
+ to_chat(usr, "\red Unfortunately there weren't enough candidates available.")
else if(href_list["dbsearchckey"] || href_list["dbsearchadmin"] || href_list["dbsearchip"] || href_list["dbsearchcid"] || href_list["dbsearchbantype"])
var/adminckey = href_list["dbsearchadmin"]
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index 022cd29105a..5e8e1d46162 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -21,6 +21,7 @@ client/proc/one_click_antag()
Make Wizard (Requires Ghosts)
Make Vampires
Make Vox Raiders (Requires Ghosts)
+ Make Abductor Team (Requires Ghosts)
"}
usr << browse(dat, "window=oneclickantag;size=400x400")
return
@@ -308,8 +309,10 @@ client/proc/one_click_antag()
return 1
-
-
+//Abductors
+/datum/admins/proc/makeAbductorTeam()
+ new /datum/event/abductor
+ return 1
/datum/admins/proc/makeAliens()
alien_infestation(3)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index ccd7eda05e5..e458ebb7a14 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -25,6 +25,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
ROLE_NINJA = 21,
ROLE_MUTINEER = 21,
ROLE_MALF = 30,
+ ROLE_ABDUCTOR = 30,
)
/proc/player_old_enough_antag(client/C, role)
diff --git a/code/modules/events/abductor.dm b/code/modules/events/abductor.dm
new file mode 100644
index 00000000000..988da3f86b6
--- /dev/null
+++ b/code/modules/events/abductor.dm
@@ -0,0 +1,49 @@
+/datum/event/abductor
+
+/datum/event/abductor/start()
+ if(!makeAbductorTeam())
+ message_admins("Abductor event failed to find players. Retrying in 30s.")
+ spawn(300)
+ makeAbductorTeam()
+
+/datum/event/abductor/proc/makeAbductorTeam()
+ var/list/mob/dead/observer/candidates = pollCandidates("Do you wish to be considered for an Abductor Team?", ROLE_ABDUCTOR, 1)
+
+ if(candidates.len >= 2)
+ //Oh god why we can't have static functions
+ var/number = ticker.mode.abductor_teams + 1
+
+ var/datum/game_mode/abduction/temp
+ if(ticker.mode.config_tag == "abduction")
+ temp = ticker.mode
+ else
+ temp = new
+
+ var/agent_mind = pick(candidates)
+ candidates -= agent_mind
+ var/scientist_mind = pick(candidates)
+
+ var/mob/living/carbon/human/agent=makeBody(agent_mind)
+ var/mob/living/carbon/human/scientist=makeBody(scientist_mind)
+
+ agent_mind = agent.mind
+ scientist_mind = scientist.mind
+
+ temp.scientists.len = number
+ temp.agents.len = number
+ temp.abductors.len = 2*number
+ temp.team_objectives.len = number
+ temp.team_names.len = number
+ temp.scientists[number] = scientist_mind
+ temp.agents[number] = agent_mind
+ temp.abductors |= list(agent_mind,scientist_mind)
+ temp.make_abductor_team(number,preset_scientist=scientist_mind,preset_agent=agent_mind)
+ temp.post_setup_team(number)
+
+ ticker.mode.abductor_teams++
+
+ if(ticker.mode.config_tag != "abduction")
+ ticker.mode.abductors |= temp.abductors
+ return 1
+ else
+ return 0
\ No newline at end of file
diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm
index 8d16fd5a4cb..304abd3cd13 100644
--- a/code/modules/events/event_container.dm
+++ b/code/modules/events/event_container.dm
@@ -178,10 +178,11 @@ var/list/event_last_fired = list()
severity = EVENT_LEVEL_MAJOR
available_events = list(
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 1320),
- new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1),
- //new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station, 0, list(ASSIGNMENT_ANY = 5)),
- new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 30), 1),
- new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
+ new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1),
+ //new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station, 0, list(ASSIGNMENT_ANY = 5)),
+ new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 30), 1),
+ new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
+ new /datum/event_meta(EVENT_LEVEL_MAJOR, "Abductor Visit", /datum/event/abductor, 80, is_one_shot = 1),
new /datum/event_meta/alien(EVENT_LEVEL_MAJOR, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 30), 1),
)
diff --git a/code/modules/mob/living/carbon/human/species/abdcutor.dm b/code/modules/mob/living/carbon/human/species/abdcutor.dm
index ad4fbc0a3a3..1c641b27af0 100644
--- a/code/modules/mob/living/carbon/human/species/abdcutor.dm
+++ b/code/modules/mob/living/carbon/human/species/abdcutor.dm
@@ -1,14 +1,14 @@
/datum/species/abductor
name = "Abductor"
name_plural = "Abductors"
- icobase = 'icons/mob/human_races/r_grey.dmi'
- deform = 'icons/mob/human_races/r_def_grey.dmi'
+ icobase = 'icons/mob/human_races/r_abductor.dmi'
+ deform = 'icons/mob/human_races/r_abductor.dmi'
path = /mob/living/carbon/human/abductor
language = "Abductor Mindlink"
default_language = "Abductor Mindlink"
unarmed_type = /datum/unarmed_attack/punch
darksight = 3
- eyes = "grey_eyes_s"
+ eyes = "blank_eyes"
flags = HAS_LIPS | NO_BLOOD | NO_BREATHE
virus_immune = 1
diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi
index 4f7829c3aac..eeb5ecbbee3 100644
Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ
diff --git a/icons/mob/human_races/r_abductor.dmi b/icons/mob/human_races/r_abductor.dmi
new file mode 100644
index 00000000000..e9dad4c13b3
Binary files /dev/null and b/icons/mob/human_races/r_abductor.dmi differ
diff --git a/paradise.dme b/paradise.dme
index fb331e2b1c9..3e4ef904e70 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -1226,6 +1226,7 @@
#include "code\modules\economy\Job_Departments.dm"
#include "code\modules\economy\POS.dm"
#include "code\modules\economy\utils.dm"
+#include "code\modules\events\abductor.dm"
#include "code\modules\events\alien_infestation.dm"
#include "code\modules\events\anomaly.dm"
#include "code\modules\events\anomaly_bluespace.dm"