mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-17 18:13:34 +01:00
@@ -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()
|
||||
..()
|
||||
Reference in New Issue
Block a user