Merge pull request #4233 from Fox-McCloud/abduction

Abduction
This commit is contained in:
TheDZD
2016-04-20 11:01:55 -04:00
77 changed files with 2806 additions and 173 deletions
+26
View File
@@ -448,3 +448,29 @@ proc/get_nt_opposed()
else
message_admins("[M] ([M.key] has been converted into [role_type] with an active antagonist jobban for said role since no ghost has volunteered to take their place.")
to_chat(M, "<span class='biggerdanger'>You have been converted into [role_type] with an active jobban. Any further violations of the rules on your part are likely to result in a permanent ban.</span>")
/datum/game_mode/proc/printplayer(datum/mind/ply, fleecheck)
var/text = "<br><b>[ply.key]</b> was <b>[ply.name]</b> the <b>[ply.assigned_role]</b> and"
if(ply.current)
if(ply.current.stat == DEAD)
text += " <span class='boldannounce'>died</span>"
else
text += " <span class='greenannounce'>survived</span>"
if(fleecheck && ply.current.z > ZLEVEL_STATION)
text += " while <span class='boldannounce'>fleeing the station</span>"
if(ply.current.real_name != ply.name)
text += " as <b>[ply.current.real_name]</b>"
else
text += " <span class='boldannounce'>had their body destroyed</span>"
return text
/datum/game_mode/proc/printobjectives(datum/mind/ply)
var/text = ""
var/count = 1
for(var/datum/objective/objective in ply.objectives)
if(objective.check_completion())
text += "<br><b>Objective #[count]</b>: [objective.explanation_text] <span class='greenannounce'>Success!</span>"
else
text += "<br><b>Objective #[count]</b>: [objective.explanation_text] <span class='boldannounce'>Fail.</span>"
count++
return text
@@ -0,0 +1,456 @@
/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, "<B>The current game mode is - Abduction!</B>")
to_chat(world, "There are alien <b>abductors</b> sent to [world.name] to perform nefarious experiments!")
to_chat(world, "<b>Abductors</b> - kidnap the crew and replace their organs with experimental ones.")
to_chat(world, "<b>Crew</b> - 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 = "MODE"
scientist.special_role = "abductor scientist"
log_game("[scientist.key] (ckey) has been selected as an abductor team [team_number] scientist.")
agent.assigned_role = "MODE"
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
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.forceMove(get_turf(L))
H.set_species("Abductor")
H.mind.abductor.agent = 1
H.mind.abductor.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.forceMove(get_turf(L))
H.set_species("Abductor")
H.mind.abductor.scientist = 1
H.mind.abductor.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
team_name = team_names[team_number]
agent = agents[team_number]
H = agent.current
L = agent_landmarks[team_number]
H.forceMove(get_turf(L))
H.set_species("Abductor")
H.mind.abductor.agent = 1
H.mind.abductor.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.forceMove(get_turf(L))
H.set_species("Abductor")
H.mind.abductor.scientist = 1
H.mind.abductor.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/abductor //stores abductor's team and whether they're a scientist or agent; since species datums are global, we have to use this, instead.
var/scientist = 0
var/agent = 0
var/team = 1
/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, "<span class='notice'>You are an agent of [team_name]!</span>")
to_chat(abductor.current, "<span class='notice'>With the help of your teammate, kidnap and experiment on station crew members!</span>")
to_chat(abductor.current, "<span class='notice'>Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve.</span>")
var/obj_count = 1
for(var/datum/objective/objective in abductor.objectives)
to_chat(abductor.current, "<B>Objective #[obj_count]</B>: [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, "<span class='notice'>You are a scientist of [team_name]!</span>")
to_chat(abductor.current, "<span class='notice'>With the help of your teammate, kidnap and experiment on station crew members!</span>")
to_chat(abductor.current, "<span class='notice'>Use your tool and ship consoles to support the agent and retrieve human specimens.</span>")
var/obj_count = 1
for(var/datum/objective/objective in abductor.objectives)
to_chat(abductor.current, "<B>Objective #[obj_count]</B>: [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 abductor_equipment)
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)
team_number = agent.mind.abductor.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)
agent.update_icons()
/datum/game_mode/abduction/proc/equip_scientist(var/mob/living/carbon/human/scientist,var/team_number)
if(!team_number)
team_number = scientist.mind.abductor.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)
scientist.update_icons()
/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, "<span class='greenannounce'>[team_name] team fullfilled its mission!</span>")
else
to_chat(world, "<span class='boldannounce'>[team_name] team failed its mission.</span>")
..()
return 1
/datum/game_mode/proc/auto_declare_completion_abduction()
var/text = ""
if(abductors.len)
text += "<br><span class='big'><b>The abductors were:</b></span>"
for(var/datum/mind/abductor_mind in abductors)
text += printplayer(abductor_mind)
text += printobjectives(abductor_mind)
text += "<br>"
if(abductees.len)
text += "<br><span class='big'><b>The abductees were:</b></span>"
for(var/datum/mind/abductee_mind in abductees)
text += printplayer(abductee_mind)
text += printobjectives(abductee_mind)
text += "<br>"
to_chat(world, text)
//Landmarks
// TODO: Split into seperate landmarks for prettier ships
/obj/effect/landmark/abductor
var/team = 1
/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
ab_team = H.mind.abductor.team
for(var/obj/machinery/abductor/experiment/E in abductor_equipment)
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."
@@ -0,0 +1,634 @@
#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_name = "Activate"
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(ishuman(loc))
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(ishuman(loc))
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(ishuman(loc))
if(combat_cooldown != initial(combat_cooldown))
to_chat(src.loc, "<span class='warning'>Combat injection is still recharging.</span>")
return
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, "<span class='warning'>You can't figure how this works!</span>")
return 0
/obj/item/device/abductor/proc/ScientistCheck(user)
var/mob/living/carbon/human/H = user
if(H.mind && H.mind.abductor)
return H.mind.abductor.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 = "gizmo"
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, "<span class='warning'>You're not trained to use this!</span>")
return
if(mode == GIZMO_SCAN)
mode = GIZMO_MARK
icon_state = "gizmo_mark"
else
mode = GIZMO_SCAN
icon_state = "gizmo_scan"
to_chat(user, "<span class='notice'>You switch the device to [mode==GIZMO_SCAN? "SCAN": "MARK"] MODE</span>")
/obj/item/device/abductor/gizmo/attack(mob/living/M, mob/user)
if(!AbductorCheck(user))
return
if(!ScientistCheck(user))
to_chat(user, "<span class='notice'>You're not trained to use this</span>")
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, "<span class='notice'>You're not trained to use this</span>")
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, "<span class='notice'>You scan [target] and add them to the database.</span>")
/obj/item/device/abductor/gizmo/proc/mark(atom/target, mob/living/user)
if(marked == target)
to_chat(user, "<span class='warning'>This specimen is already marked!</span>")
return
if(istype(target,/mob/living/carbon/human))
if(IsAbductor(target))
marked = target
to_chat(user, "<span class='notice'>You mark [target] for future retrieval.</span>")
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, "<span class='warning'>You need to be next to the specimen to prepare it for transport!</span>")
return
to_chat(user, "<span class='notice'>You begin preparing [target] for transport...</span>")
if(do_after(user, 100, target = target))
marked = target
to_chat(user, "<span class='notice'>You finish preparing [target] for transport.</span>")
/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 = "silencer"
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, "<span class='notice'>You silence [M]'s radio devices.</span>")
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, "<span class='warning'>You must wait [30 - cooldown] seconds to use [src] again!</span>")
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")
console = get_team_console(H.mind.abductor.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 abductor_equipment)
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/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, "<span class='userdanger'>UNAUTHORIZED -- UNAUTHORIZED</span>")
return 0
return 1
/obj/item/weapon/paper/abductor
name = "Dissection Guide"
icon_state = "alienpaper_words"
info = {"<b>Dissection for Dummies</b><br>
<br>
1.Acquire fresh specimen.<br>
2.Put the specimen on operating table<br>
3.Apply scalpel to the chest, preparing for dissection<br>
4.Apply scalpel to specimen torso<br>
5.Clamp bleeders on the specimen's torso<br>
6.Retract skin from specimen's torso<br>
7.Saw through the specimen's torso<br>
8.Retract skin from specimen's torso again<br>
9.Search through the specimen's torso with your hands to remove their heart<br>
10.Insert replacement gland (Retrieve one from gland storage)<br>
11.Cauterize the patient's torso<br>
12.Consider dressing the specimen back to not disturb the habitat <br>
13.Put the specimen in the experiment machinery<br>
14.Choose one of the machine options and follow displayed instructions<br>
<br>
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, "<span class='notice'>You switch the baton to [txt] mode.</span>")
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)
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
L.lastattacker = user
L.Stun(7)
L.Weaken(7)
L.apply_effect(STUTTER, 7)
L.visible_message("<span class='danger'>[user] has stunned [L] with [src]!</span>", \
"<span class='userdanger'>[user] has stunned you with [src]!</span>")
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(L, user, "stunned")
return
/obj/item/weapon/abductor_baton/proc/SleepAttack(mob/living/L,mob/living/user)
if(L.stunned)
L.visible_message("<span class='danger'>[user] has induced sleep in [L] with [src]!</span>", \
"<span class='userdanger'>You suddenly feel very drowsy!</span>")
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
L.Sleeping(60)
add_logs(L, user, "put to sleep")
else
L.drowsyness += 1
to_chat(user, "<span class='warning'>Sleep inducement works fully only on stunned specimens! </span>")
L.visible_message("<span class='danger'>[user] tried to induce sleep in [L] with [src]!</span>", \
"<span class='userdanger'>You suddenly feel drowsy!</span>")
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("<span class='danger'>[user] begins restraining [C] with [src]!</span>", \
"<span class='userdanger'>[user] begins shaping an energy field around your hands!</span>")
if(do_mob(user, C, 30))
if(!C.handcuffed)
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/energy/used(C)
C.update_inv_handcuffed()
to_chat(user, "<span class='notice'>You handcuff [C].</span>")
add_logs(C, user, "handcuffed")
else
to_chat(user, "<span class='warning'>You fail to handcuff [C].</span>")
return
/obj/item/weapon/abductor_baton/proc/ProbeAttack(mob/living/L,mob/living/user)
L.visible_message("<span class='danger'>[user] probes [L] with [src]!</span>", \
"<span class='userdanger'>[user] probes you!</span>")
var/species = "<span class='warning'>Unknown species</span>"
var/helptext = "<span class='warning'>Species unsuitable for experiments.</span>"
if(ishuman(L))
var/mob/living/carbon/human/H = L
species = "<span clas=='notice'>[H.species.name]</span>"
if(L.mind && L.mind.changeling)
species = "<span class='warning'>Changeling lifeform</span>"
var/obj/item/organ/internal/gland/temp = locate() in H.internal_organs
if(temp)
helptext = "<span class='warning'>Experimental gland detected!</span>"
else
helptext = "<span class='notice'>Subject suitable for experiments.</span>"
to_chat(user,"<span class='notice'>Probing result: </span>[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("<span class='danger'>[user]'s [src] break in a discharge of energy!</span>", \
"<span class='userdanger'>[user]'s [src] break in a discharge of energy!</span>")
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, "<span class='warning'>The baton is in stun mode.</span>")
if(BATON_SLEEP)
to_chat(user, "<span class='warning'>The baton is in sleep inducement mode.</span>")
if(BATON_CUFF)
to_chat(user, "<span class='warning'>The baton is in restraining mode.</span>")
if(BATON_PROBE)
to_chat(user, "<span class='warning'>The baton is in probing mode.</span>")
/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"
no_icon_updates = 1 //no icon updates for this; it's static.
/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, "<span class='notice'>You start disassembling [src]...</span>")
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, "<span class='warning'>You need one alien alloy sheet to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [P] to [src]...</span>")
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"
icon_closed = "abductor"
icon_opened = "abductoropen"
material_drop = /obj/item/stack/sheet/mineral/abductor
@@ -0,0 +1,62 @@
/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, /datum/surgery_step/generic/cauterize)
possible_locs = list("chest")
/datum/surgery/organ_extraction/can_start(mob/user, mob/living/carbon/target)
if(!ishuman(user))
return 0
if(target.get_species() == "Machine") //Maybe add in a machine version, later?
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.", "<span class='notice'>You start to remove [target]'s organs...</span>")
..()
/datum/surgery_step/internal/extract_organ/end_step(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/mob/living/carbon/human/AB = target
if(AB.species.flags & NO_INTORGANS)
user.visible_message("[user] prepares [target]'s [target_zone] for further dissection!", "<span class='notice'>You prepare [target]'s [target_zone] for further dissection.</span>")
return 1
if(IC)
user.visible_message("[user] pulls [IC] out of [target]'s [target_zone]!", "<span class='notice'>You pull [IC] out of [target]'s [target_zone].</span>")
user.put_in_hands(IC)
IC.remove(target, special = 1)
return 1
else
to_chat(user, "<span class='warning'>You don't find anything in [target]'s [target_zone]!</span>")
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].", "<span class ='notice'>You start to insert [tool] into [target]...</span>")
..()
/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].", "<span class ='notice'>You insert [tool] into [target].</span>")
user.drop_item()
var/obj/item/organ/internal/gland/gland = tool
gland.insert(target, 2)
return 1
@@ -0,0 +1,280 @@
/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, "<span class='notice'>You feel curiously revitalized.</span>")
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, "<span class='warning'>You feel nauseous!</span>")
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, "<span class='notice'>You get a headache.</span>")
var/turf/T = get_turf(owner)
for(var/mob/living/carbon/H in orange(4,T))
if(H == owner)
continue
to_chat(H, "<span class='alien'>You hear a buzz in your head.</span>")
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, "<span class='notice'>You feel unlike yourself.</span>")
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, "<span class='notice'>You feel very stretchy.</span>")
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, "<span class='warning'>You feel sick.</span>")
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, "<span class='warning'>You feel a spike of pain in your head.</span>")
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, "<span class='warning'>You feel something crawling in your skin.</span>")
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, "<span class='boldannounce'>You lay an egg!</span>")
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("<span class='danger'>[owner]'s skin erupts with blood!</span>",\
"<span class='userdanger'>Blood pours from your skin!</span>")
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, "<span class='warning'>You feel something moving around inside you...</span>")
//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.rename_character(clone.name, owner_dna.real_name)
clone.body_accessory = H.body_accessory
clone.dna = owner_dna.Clone()
clone.set_species(H.species.name)
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("<span class='warning'>[src] hatches!</span>")
M.forceMove(get_turf(src))
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, "<span class='warning'>You feel bloated.</span>")
sleep(150)
if(!owner) return
to_chat(owner, "<span class='userdanger'>A massive stomachache overcomes you.</span>")
sleep(50)
if(!owner) return
owner.visible_message("<span class='danger'>[owner] explodes in a cloud of plasma!</span>")
var/turf/simulated/T = get_turf(owner)
if(istype(T))
T.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C,300)
owner.gib()
return
@@ -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)
if(H.mind && H.mind.abductor)
return H.mind.abductor.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)
@@ -0,0 +1,223 @@
//Common
/obj/machinery/abductor
var/team = 0
/obj/machinery/abductor/New()
abductor_equipment.Add(src)
..()
/obj/machinery/abductor/Destroy()
abductor_equipment.Remove(src)
return ..()
/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")
if(H.mind && H.mind.abductor)
return H.mind.abductor.agent
return 0
/obj/machinery/abductor/proc/IsScientist(mob/living/carbon/human/H)
if(H.get_species() == "Abductor")
if(H.mind && H.mind.abductor)
return H.mind.abductor.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/initialize()
..()
Link_Abduction_Equipment()
/obj/machinery/abductor/console/attack_hand(mob/user)
if(..())
return
if(!IsAbductor(user))
to_chat(user, "<span class='warning'>You start mashing alien buttons at random!</span>")
if(do_after(user,100, target = src))
TeleporterSend()
return
user.set_machine(src)
var/dat = ""
dat += "<H3> Abductsoft 3000 </H3>"
if(experiment != null)
var/points = experiment.points
dat += "Collected Samples : [points] <br>"
dat += "<b>Transfer data in exchange for supplies:</b><br>"
dat += "<a href='?src=\ref[src];dispense=baton'>Advanced Baton</A><br>"
dat += "<a href='?src=\ref[src];dispense=helmet'>Agent Helmet</A><br>"
dat += "<a href='?src=\ref[src];dispense=silencer'>Radio Silencer</A><br>"
dat += "<a href='?src=\ref[src];dispense=tool'>Science Tool</A><br>"
else
dat += "<span class='bad'>NO EXPERIMENT MACHINE DETECTED</span> <br>"
if(pad!=null)
dat += "<span class='bad'>Emergency Teleporter System.</span>"
dat += "<span class='bad'>Consider using primary observation console first.</span>"
dat += "<a href='?src=\ref[src];teleporter_send=1'>Activate Teleporter</A><br>"
if(gizmo!=null && gizmo.marked!=null)
dat += "<a href='?src=\ref[src];teleporter_retrieve=1'>Retrieve Mark</A><br>"
else
dat += "<span class='linkOff'>Retrieve Mark</span><br>"
else
dat += "<span class='bad'>NO TELEPAD DETECTED</span></br>"
if(vest!=null)
dat += "<h4> Agent Vest Mode </h4><br>"
var/mode = vest.mode
if(mode == VEST_STEALTH)
dat += "<a href='?src=\ref[src];flip_vest=1'>Combat</A>"
dat += "<span class='linkOff'>Stealth</span>"
else
dat += "<span class='linkOff'>Combat</span>"
dat += "<a href='?src=\ref[src];flip_vest=1'>Stealth</A>"
dat+="<br>"
dat += "<a href='?src=\ref[src];select_disguise=1'>Select Agent Vest Disguise</a><br>"
else
dat += "<span class='bad'>NO AGENT VEST DETECTED</span>"
var/datum/browser/popup = new(user, "computer", "Abductor Console", 400, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return
/obj/machinery/abductor/console/Topic(href, href_list)
if(..())
return
usr.set_machine(src)
if(href_list["teleporter_send"])
TeleporterSend()
else if(href_list["teleporter_retrieve"])
TeleporterRetrieve()
else if(href_list["flip_vest"])
FlipVest()
else if(href_list["select_disguise"])
SelectDisguise()
else if(href_list["dispense"])
switch(href_list["dispense"])
if("baton")
Dispense(/obj/item/weapon/abductor_baton,cost=2)
if("helmet")
Dispense(/obj/item/clothing/head/helmet/abductor)
if("silencer")
Dispense(/obj/item/device/abductor/silencer)
if("tool")
Dispense(/obj/item/device/abductor/gizmo)
src.updateUsrDialog()
/obj/machinery/abductor/console/proc/TeleporterRetrieve()
if(gizmo!=null && pad!=null && gizmo.marked)
pad.Retrieve(gizmo.marked)
return
/obj/machinery/abductor/console/proc/TeleporterSend()
if(pad!=null)
pad.Send()
return
/obj/machinery/abductor/console/proc/FlipVest()
if(vest!=null)
vest.flip_mode()
return
/obj/machinery/abductor/console/proc/SelectDisguise(remote=0)
var/list/entries = list()
var/tempname
var/datum/icon_snapshot/temp
for(var/i = 1; i <= disguises.len; i++)
temp = disguises[i]
tempname = temp.name
entries["[tempname]"] = disguises[i]
var/entry_name = input( "Choose Disguise", "Disguise") in entries
var/datum/icon_snapshot/chosen = entries[entry_name]
if(chosen && (remote || in_range(usr,src)))
vest.SetDisguise(chosen)
return
/obj/machinery/abductor/console/proc/SetDroppoint(turf/location,user)
if(!istype(location))
to_chat(user, "<span class='warning'>That place is not safe for the specimen.</span>")
return
if(pad)
pad.teleport_target = location
to_chat(user, "<span class='notice'>Location marked as test subject release point.</span>")
/obj/machinery/abductor/console/proc/Link_Abduction_Equipment() // these must all be explicitly `in machines` or they will not properly link.
for(var/obj/machinery/abductor/pad/p in machines)
if(p.team == team)
pad = p
break
for(var/obj/machinery/abductor/experiment/e in machines)
if(e.team == team)
experiment = e
e.console = src
for(var/obj/machinery/computer/camera_advanced/abductor/c in machines)
if(c.team == team)
camera = c
c.console = src
/obj/machinery/abductor/console/proc/AddSnapshot(mob/living/carbon/human/target)
var/datum/icon_snapshot/entry = new
entry.name = target.name
entry.icon = target.icon
entry.icon_state = target.icon_state
entry.overlays = target.get_overlays_copy(list(L_HAND_LAYER,R_HAND_LAYER))
for(var/i=1,i<=disguises.len,i++)
var/datum/icon_snapshot/temp = disguises[i]
if(temp.name == entry.name)
disguises[i] = entry
return
disguises.Add(entry)
return
/obj/machinery/abductor/console/attackby(obj/O, mob/user, params)
if(istype(O, /obj/item/device/abductor/gizmo))
var/obj/item/device/abductor/gizmo/G = O
to_chat(user, "<span class='notice'>You link the tool to the console.</span>")
gizmo = G
G.console = src
else if(istype(O, /obj/item/clothing/suit/armor/abductor/vest))
var/obj/item/clothing/suit/armor/abductor/vest/V = O
to_chat(user, "<span class='notice'>You link the vest to the console.</span>")
vest = V
else
..()
/obj/machinery/abductor/console/proc/Dispense(item,cost=1)
if(experiment && experiment.points >= cost)
experiment.points-=cost
atom_say("Incoming supply!")
if(pad)
flick("alien-pad", pad)
new item(pad.loc)
else
new item(src.loc)
else
atom_say("Insufficent data!")
return
@@ -0,0 +1,83 @@
/obj/machinery/abductor/gland_dispenser
name = "Replacement Organ Storage"
desc = "A tank filled with replacement organs"
icon = 'icons/obj/abductor.dmi'
icon_state = "dispenser"
density = 1
anchored = 1
var/list/gland_types
var/list/gland_colors
var/list/amounts
/obj/machinery/abductor/gland_dispenser/proc/random_color()
//TODO : replace with presets or spectrum
return rgb(rand(0,255),rand(0,255),rand(0,255))
/obj/machinery/abductor/gland_dispenser/New()
gland_types = subtypesof(/obj/item/organ/internal/gland)
gland_types = shuffle(gland_types)
gland_colors = new/list(gland_types.len)
amounts = new/list(gland_types.len)
for(var/i=1,i<=gland_types.len,i++)
gland_colors[i] = random_color()
amounts[i] = rand(1,5)
/obj/machinery/abductor/gland_dispenser/attack_hand(mob/user)
if(..())
return
if(!IsAbductor(user))
return
user.set_machine(src)
var/box_css = {"
<style>
a.box.gland {
float: left;
width: 20px;
height: 20px;
margin: 5px;
border-width: 1px;
border-style: solid;
border-color: rgba(0,0,0,.2);
text-align: center;
}
</style>"}
var/dat = ""
var/item_count = 0
for(var/i=1,i<=gland_colors.len,i++)
item_count++
var/g_color = gland_colors[i]
var/amount = amounts[i]
dat += "<a class='box gland' style='background-color:[g_color]' href='?src=\ref[src];dispense=[i]'>[amount]</a>"
if(item_count == 3) // Three boxes per line
dat +="</br></br>"
item_count = 0
var/datum/browser/popup = new(user, "glands", "Gland Dispenser", 200, 200)
popup.add_head_content(box_css)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return
/obj/machinery/abductor/gland_dispenser/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/organ/internal/gland))
if(!user.drop_item())
return
W.forceMove(src)
for(var/i=1,i<=gland_colors.len,i++)
if(gland_types[i] == W.type)
amounts[i]++
/obj/machinery/abductor/gland_dispenser/Topic(href, href_list)
if(..())
return
usr.set_machine(src)
if(href_list["dispense"])
Dispense(text2num(href_list["dispense"]))
src.updateUsrDialog()
/obj/machinery/abductor/gland_dispenser/proc/Dispense(count)
if(amounts[count]>0)
amounts[count]--
var/T = gland_types[count]
new T(get_turf(src))
@@ -0,0 +1,195 @@
/obj/machinery/abductor/experiment
name = "experimentation machine"
desc = "A large man-sized tube sporting a complex array of surgical apparatus."
icon = 'icons/obj/abductor.dmi'
icon_state = "experiment-open"
anchored = 1
density = 1
var/points = 0
var/list/history = list()
var/list/abductee_minds = list()
var/flash = " - || - "
var/obj/machinery/abductor/console/console
var/mob/living/carbon/human/occupant
/obj/machinery/abductor/experiment/Destroy()
eject_abductee()
return ..()
/obj/machinery/abductor/experiment/MouseDrop_T(mob/living/carbon/human/target, mob/user)
if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user) || !ishuman(target))
return
if(IsAbductor(target))
return
if(occupant)
to_chat(user, "<span class='notice'>\The [src] is already occupied.</span>")
return //occupied
if(target.buckled)
return
for(var/mob/living/carbon/slime/M in range(1, target))
if(M.Victim == target)
to_chat(user, "<span class='danger'>[target] has a slime attached to them, deal with that first.</span>")
return
visible_message("[user] puts [target] into the [src].")
target.forceMove(src)
occupant = target
icon_state = "experiment"
add_fingerprint(user)
/obj/machinery/abductor/experiment/attack_hand(mob/user)
if(..())
return
experimentUI(user)
/obj/machinery/abductor/experiment/proc/experimentUI(mob/user)
var/dat
dat += "<h3> Experiment </h3>"
if(occupant)
dat += "<table><tr><td>"
dat += "</td><td>"
dat += "<a href='?src=\ref[src];experiment=1'>Probe</a><br>"
dat += "<a href='?src=\ref[src];experiment=2'>Dissect</a><br>"
dat += "<a href='?src=\ref[src];experiment=3'>Analyze</a><br>"
dat += "</td></tr></table>"
else
dat += "<span class='linkOff'>Experiment </span>"
if(!occupant)
dat += "<h3>Machine Unoccupied</h3>"
else
dat += "<h3>Subject Status : </h3>"
dat += "[occupant.name] => "
switch(occupant.stat)
if(0)
dat += "<span class='good'>Conscious</span>"
if(1)
dat += "<span class='average'>Unconscious</span>"
else
dat += "<span class='bad'>Deceased</span>"
dat += "<br>"
dat += "[flash]"
dat += "<br>"
dat += "<a href='?src=\ref[src];refresh=1'>Scan</a>"
dat += "<a href='?src=\ref[src];[occupant ? "eject=1'>Eject Occupant</a>" : "unoccupied=1'>Unoccupied</a>"]"
var/datum/browser/popup = new(user, "experiment", "Probing Console", 300, 300)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.set_content(dat)
popup.open()
/obj/machinery/abductor/experiment/Topic(href, href_list)
if(..() || usr == occupant)
return
usr.set_machine(src)
if(href_list["refresh"])
updateUsrDialog()
return
if(href_list["eject"])
eject_abductee()
return
if(occupant && occupant.stat != DEAD)
if(href_list["experiment"])
flash = Experiment(occupant,href_list["experiment"])
updateUsrDialog()
add_fingerprint(usr)
/obj/machinery/abductor/experiment/proc/Experiment(mob/occupant,type)
var/mob/living/carbon/human/H = occupant
var/point_reward = 0
if(H in history)
return "<span class='bad'>Specimen already in database.</span>"
if(H.stat == DEAD)
atom_say("Specimen deceased - please provide fresh sample.")
return "<span class='bad'>Specimen deceased.</span>"
var/obj/item/organ/internal/gland/GlandTest = locate() in H.internal_organs
if(!GlandTest)
atom_say("Experimental dissection not detected!")
return "<span class='bad'>No glands detected!</span>"
if(H.mind != null && H.ckey != null)
history += H
abductee_minds += H.mind
atom_say("Processing specimen...")
sleep(5)
switch(text2num(type))
if(1)
to_chat(H, "<span class='warning'>You feel violated.</span>")
if(2)
to_chat(H, "<span class='warning'>You feel yourself being sliced apart and put back together.</span>")
if(3)
to_chat(H, "<span class='warning'>You feel intensely watched.</span>")
sleep(5)
to_chat(H, "<span class='warning'><b>Your mind snaps!</b></span>")
var/objtype = pick(subtypesof(/datum/objective/abductee/))
var/datum/objective/abductee/O = new objtype()
ticker.mode.abductees += H.mind
H.mind.objectives += O
var/obj_count = 1
to_chat(H, "<span class='notice'>Your current objectives:</span>")
for(var/datum/objective/objective in H.mind.objectives)
to_chat(H, "<B>Objective #[obj_count]</B>: [objective.explanation_text]")
obj_count++
ticker.mode.update_abductor_icons_added(H.mind)
for(var/obj/item/organ/internal/gland/G in H.internal_organs)
G.Start()
point_reward++
if(point_reward > 0)
eject_abductee()
SendBack(H)
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
points += point_reward
return "<span class='good'>Experiment successful! [point_reward] new data-points collected.</span>"
else
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 1)
return "<span class='bad'>Experiment failed! No replacement organ detected.</span>"
else
atom_say("Brain activity nonexistant - disposing sample...")
eject_abductee()
SendBack(H)
return "<span class='bad'>Specimen braindead - disposed.</span>"
return "<span class='bad'>ERROR</span>"
/obj/machinery/abductor/experiment/proc/SendBack(mob/living/carbon/human/H)
H.Sleeping(8)
if(console && console.pad && console.pad.teleport_target)
H.forceMove(console.pad.teleport_target)
H.uncuff()
return
//Area not chosen / It's not safe area - teleport to arrivals
H.forceMove(pick(latejoin))
H.uncuff()
return
/obj/machinery/abductor/experiment/attackby(obj/item/weapon/G, mob/user)
if(istype(G, /obj/item/weapon/grab))
var/obj/item/weapon/grab/grabbed = G
if(!ishuman(grabbed.affecting))
return
if(IsAbductor(grabbed.affecting))
return
if(occupant)
to_chat(user, "<span class='notice'>The [src] is already occupied!</span>")
return
for(var/mob/living/carbon/slime/S in range(1, grabbed.affecting))
if(S.Victim == grabbed.affecting)
to_chat(user, "<span class='danger'>[grabbed.affecting] has a slime attached to them, deal with that first.</span>")
return
visible_message("[user] puts [grabbed.affecting] into the [src].")
var/mob/living/carbon/human/H = grabbed.affecting
H.forceMove(src)
occupant = H
icon_state = "experiment"
add_fingerprint(user)
qdel(G)
/obj/machinery/abductor/experiment/proc/eject_abductee()
if(!occupant)
return
if(occupant.client)
occupant.client.eye = occupant.client.mob
occupant.client.perspective = MOB_PERSPECTIVE
occupant.forceMove(get_turf(src))
occupant = null
icon_state = "experiment-open"
@@ -0,0 +1,54 @@
/obj/machinery/abductor/pad
name = "Alien Telepad"
desc = "Use this to transport to and from human habitat"
icon = 'icons/obj/abductor.dmi'
icon_state = "alien-pad-idle"
anchored = 1
var/turf/teleport_target
/obj/machinery/abductor/pad/proc/Warp(mob/living/target)
target.Move(src.loc)
/obj/machinery/abductor/pad/proc/Send()
if(teleport_target == null)
teleport_target = teleportlocs[pick(teleportlocs)]
flick("alien-pad", src)
for(var/mob/living/target in loc)
target.forceMove(teleport_target)
spawn(0)
anim(target.loc,target,'icons/mob/mob.dmi',,"uncloak",,target.dir)
/obj/machinery/abductor/pad/proc/Retrieve(mob/living/target)
flick("alien-pad", src)
spawn(0)
anim(target.loc,target,'icons/mob/mob.dmi',,"uncloak",,target.dir)
Warp(target)
/obj/machinery/abductor/pad/proc/MobToLoc(place,mob/living/target)
new/obj/effect/overlay/temp/teleport_abductor(place)
sleep(80)
flick("alien-pad", src)
target.forceMove(place)
anim(target.loc,target,'icons/mob/mob.dmi',,"uncloak",,target.dir)
/obj/machinery/abductor/pad/proc/PadToLoc(place)
new/obj/effect/overlay/temp/teleport_abductor(place)
sleep(80)
flick("alien-pad", src)
for(var/mob/living/target in src.loc)
target.forceMove(place)
spawn(0)
anim(target.loc,target,'icons/mob/mob.dmi',,"uncloak",,target.dir)
/obj/effect/overlay/temp/teleport_abductor
name = "Huh"
icon = 'icons/obj/abductor.dmi'
icon_state = "teleport"
duration = 80
/obj/effect/overlay/temp/teleport_abductor/New()
var/datum/effect/system/spark_spread/S = new
S.set_up(10,0,loc)
S.start()
..()