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
+33
View File
@@ -188,3 +188,36 @@
// teehee no one will find these here
#define MFOAM_ALUMINUM 1
#define MFOAM_IRON 2
//Human Overlays Indexes/////////
#define MUTANTRACE_LAYER 1
#define TAIL_UNDERLIMBS_LAYER 2
#define LIMBS_LAYER 3
#define MARKINGS_LAYER 4
#define UNDERWEAR_LAYER 5
#define MUTATIONS_LAYER 6
#define DAMAGE_LAYER 7
#define UNIFORM_LAYER 8
#define ID_LAYER 9
#define SHOES_LAYER 10
#define GLOVES_LAYER 11
#define EARS_LAYER 12
#define SUIT_LAYER 13
#define GLASSES_LAYER 14
#define BELT_LAYER 15 //Possible make this an overlay of somethign required to wear a belt?
#define SUIT_STORE_LAYER 16
#define BACK_LAYER 17
#define TAIL_LAYER 18 //bs12 specific. this hack is probably gonna come back to haunt me
#define HAIR_LAYER 19 //TODO: make part of head layer?
#define HEAD_ACCESSORY_LAYER 20
#define FHAIR_LAYER 21
#define FACEMASK_LAYER 22
#define HEAD_LAYER 23
#define COLLAR_LAYER 24
#define HANDCUFF_LAYER 25
#define LEGCUFF_LAYER 26
#define L_HAND_LAYER 27
#define R_HAND_LAYER 28
#define TARGETED_LAYER 29 //BS12: Layer for the target overlay from weapon targeting system
#define FIRE_LAYER 30 //If you're on fire
#define TOTAL_LAYERS 30
+1 -1
View File
@@ -56,7 +56,7 @@ var/global/list/special_roles = list(
// ROLE_MONKEY = /datum/game_mode/monkey, Sooner or later these are going to get ported
// ROLE_GANG = /datum/game_mode/gang,
ROLE_SHADOWLING = /datum/game_mode/shadowling,
// ROLE_ABDUCTOR = /datum/game_mode/abduction,
ROLE_ABDUCTOR = /datum/game_mode/abduction,
// ROLE_HOG_GOD = /datum/game_mode/hand_of_god,
// ROLE_HOG_CULTIST = /datum/game_mode/hand_of_god,
ROLE_RAIDER = /datum/game_mode/heist,
+1
View File
@@ -29,3 +29,4 @@ var/global/list/deliverybeacontags = list() //list of all tags associated with
var/global/list/beacons = list()
var/global/list/shuttle_caller_list = list() //list of all communication consoles and AIs, for automatic shuttle calls when there are none.
var/global/list/tracked_implants = list() //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented...
var/global/list/abductor_equipment = list() //list of all abductor equipment
+1 -1
View File
@@ -266,7 +266,7 @@
blacklist = null
whitelist = list(/obj/item/device,/obj/item/weapon/card,/obj/item/weapon/cartridge,/obj/item/weapon/cautery,/obj/item/weapon/stock_parts/cell,/obj/item/weapon/circuitboard,
/obj/item/weapon/aiModule,/obj/item/weapon/airalarm_electronics,/obj/item/weapon/airlock_electronics,/obj/item/weapon/circular_saw,
/obj/item/weapon/cloaking_device,/obj/item/weapon/crowbar,/obj/item/weapon/disk,/obj/item/weapon/firealarm_electronics,/obj/item/weapon/hand_tele,
/obj/item/weapon/crowbar,/obj/item/weapon/disk,/obj/item/weapon/firealarm_electronics,/obj/item/weapon/hand_tele,
/obj/item/weapon/hand_labeler,/obj/item/weapon/hemostat,/obj/item/weapon/mop,/obj/item/weapon/locator,/obj/item/weapon/minihoe,
/obj/item/stack/packageWrap,/obj/item/weapon/pen,/obj/item/weapon/pickaxe,/obj/item/weapon/pinpointer,
/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/retractor,/obj/item/weapon/rsf,/obj/item/weapon/rsp,/obj/item/weapon/scalpel,
@@ -0,0 +1,15 @@
/datum/icon_snapshot
var/name
var/icon
var/icon_state
var/list/overlays
/datum/icon_snapshot/proc/makeImg()
if(!icon || !icon_state)
return
var/obj/temp = new
temp.icon = icon
temp.icon_state = icon_state
temp.overlays = overlays.Copy()
var/icon/tempicon = getFlatIcon(temp) // TODO Actually write something less heavy-handed for this
return tempicon
+94
View File
@@ -58,6 +58,7 @@
var/datum/changeling/changeling //changeling holder
var/datum/vampire/vampire //vampire holder
var/datum/nations/nation //nation holder
var/datum/abductor/abductor //abductor holder
var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state
var/datum/atom_hud/antag/antag_hud = null //this mind's antag HUD
@@ -345,6 +346,26 @@
sections["shadowling"] = text
/** Abductors **/
text = "Abductor"
if(ticker.mode.config_tag == "abductor")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if(src in ticker.mode.abductors)
text += "<b>Abductor</b>|<a href='?src=\ref[src];abductor=clear'>human</a>"
text += "|<a href='?src=\ref[src];common=undress'>undress</a>|<a href='?src=\ref[src];abductor=equip'>equip</a>"
else
text += "<a href='?src=\ref[src];abductor=abductor'>Abductor</a>|<b>human</b>"
if(current && current.client && (ROLE_ABDUCTOR in current.client.prefs.be_special))
text += "|Enabled in Prefs"
else
text += "|Disabled in Prefs"
sections["Abductor"] = text
/** SILICON ***/
if (istype(current, /mob/living/silicon))
@@ -1068,6 +1089,28 @@
message_admins("[key_name_admin(usr)] has thralled [current].")
log_admin("[key_name(usr)] has thralled [current].")
else if(href_list["abductor"])
switch(href_list["abductor"])
if("clear")
to_chat(usr, "Not implemented yet. Sorry!")
//ticker.mode.update_abductor_icons_removed(src)
if("abductor")
if(!ishuman(current))
to_chat(usr, "<span class='warning'>This only works on humans!</span>")
return
make_Abductor()
log_admin("[key_name(usr)] turned [current] into abductor.")
ticker.mode.update_abductor_icons_added(src)
if("equip")
var/gear = alert("Agent or Scientist Gear","Gear","Agent","Scientist")
if(gear)
var/datum/game_mode/abduction/temp = new
temp.equip_common(current)
if(gear=="Agent")
temp.equip_agent(current)
else
temp.equip_scientist(current)
else if (href_list["silicon"])
switch(href_list["silicon"])
if("unmalf")
@@ -1372,6 +1415,57 @@
// fail |= !ticker.mode.equip_traitor(current, 1)
fail |= !ticker.mode.equip_revolutionary(current)
/datum/mind/proc/make_Abductor()
var/role = alert("Abductor Role ?","Role","Agent","Scientist")
var/team = input("Abductor Team ?","Team ?") in list(1,2,3,4)
var/teleport = alert("Teleport to ship ?","Teleport","Yes","No")
if(!role || !team || !teleport)
return
if(!ishuman(current))
return
ticker.mode.abductors |= src
var/datum/objective/experiment/O = new
O.owner = src
objectives += O
var/mob/living/carbon/human/H = current
H.set_species("Abductor")
switch(role)
if("Agent")
H.mind.abductor.agent = 1
if("Scientist")
H.mind.abductor.scientist = 1
H.mind.abductor.team = team
var/list/obj/effect/landmark/abductor/agent_landmarks = new
var/list/obj/effect/landmark/abductor/scientist_landmarks = new
agent_landmarks.len = 4
scientist_landmarks.len = 4
for(var/obj/effect/landmark/abductor/A in landmarks_list)
if(istype(A,/obj/effect/landmark/abductor/agent))
agent_landmarks[text2num(A.team)] = A
else if(istype(A,/obj/effect/landmark/abductor/scientist))
scientist_landmarks[text2num(A.team)] = A
var/obj/effect/landmark/L
if(teleport=="Yes")
switch(role)
if("Agent")
H.mind.abductor.agent = 1
L = agent_landmarks[team]
H.loc = L.loc
if("Scientist")
H.mind.abductor.scientist = 1
L = agent_landmarks[team]
H.loc = L.loc
// check whether this mind's mob has been brigged for the given duration
// have to call this periodically for the duration to work properly
/datum/mind/proc/is_brigged(duration)
+8
View File
@@ -618,6 +618,14 @@ var/list/ghostteleportlocs = list()
name = "\improper Hyperspace"
icon_state = "shuttle"
//Abductors
/area/abductor_ship
name = "\improper Abductor Ship"
icon_state = "yellow"
requires_power = 0
has_gravity = 1
lighting_use_dynamic = 0
/area/wizard_station
name = "\improper Wizard's Den"
icon_state = "yellow"
+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()
..()
+9 -4
View File
@@ -13,6 +13,7 @@
var/obj/machinery/computer/operating/computer = null
buckle_lying = 90
var/no_icon_updates = 0 //set this to 1 if you don't want the icons ever changing
/obj/machinery/optable/New()
..()
@@ -79,10 +80,12 @@
var/mob/living/carbon/human/M = locate(/mob/living/carbon/human, src.loc)
if(M.lying)
src.victim = M
icon_state = M.pulse ? "table2-active" : "table2-idle"
if(!no_icon_updates)
icon_state = M.pulse ? "table2-active" : "table2-idle"
return 1
src.victim = null
icon_state = "table2-idle"
if(!no_icon_updates)
icon_state = "table2-idle"
return 0
/obj/machinery/optable/process()
@@ -106,9 +109,11 @@
if(ishuman(C))
var/mob/living/carbon/human/H = C
src.victim = H
icon_state = H.pulse ? "table2-active" : "table2-idle"
if(!no_icon_updates)
icon_state = H.pulse ? "table2-active" : "table2-idle"
else
icon_state = "table2-idle"
if(!no_icon_updates)
icon_state = "table2-idle"
/obj/machinery/optable/verb/climb_on()
set name = "Climb On Table"
@@ -20,12 +20,22 @@
jump_action.Grant(user)
/obj/machinery/computer/camera_advanced/check_eye(mob/user)
if (get_dist(user, src) > 1 || user.eye_blind)
if(user == current_user)
off_action.Activate()
if((stat & (NOPOWER|BROKEN)) || !Adjacent(user) || user.eye_blind || user.incapacitated())
user.unset_machine()
return 0
return 1
/obj/machinery/computer/camera_advanced/Destroy()
if(current_user)
current_user.unset_machine()
if(eyeobj)
qdel(eyeobj)
return ..()
/obj/machinery/computer/camera_advanced/on_unset_machine(mob/M)
if(M == current_user)
off_action.Activate()
/obj/machinery/computer/camera_advanced/attack_hand(mob/user)
if(..())
return
@@ -34,6 +44,7 @@
var/mob/living/carbon/L = user
if(!current_user)
user.set_machine(src)
if(!eyeobj)
CreateEye()
GrantActions(user)
@@ -193,3 +193,31 @@ var/global/list/datum/stack_recipe/mime_recipes = list ( \
icon_state = "sheet-enruranium"
origin_tech = "materials=6"
materials = list(MAT_URANIUM=3000)
/*
* Alien Alloy
*/
/obj/item/stack/sheet/mineral/abductor
name = "alien alloy"
icon = 'icons/obj/abductor.dmi'
icon_state = "sheet-abductor"
singular_name = "alien alloy sheet"
force = 5
throwforce = 5
w_class = 3
throw_speed = 1
throw_range = 3
origin_tech = "materials=6;abductor=1"
sheettype = "abductor"
var/global/list/datum/stack_recipe/abductor_recipes = list ( \
new/datum/stack_recipe("alien bed", /obj/structure/stool/bed/abductor, 2, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("alien locker", /obj/structure/closet/abductor, 1, time = 15, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("alien table frame", /obj/structure/abductor_tableframe, 1, time = 15, one_per_turf = 1, on_floor = 1), \
null, \
new/datum/stack_recipe("alien floor tile", /obj/item/stack/tile/mineral/abductor, 1, 4, 20), \
)
/obj/item/stack/sheet/mineral/abductor/New(var/loc, var/amount=null)
recipes = abductor_recipes
..()
@@ -0,0 +1,9 @@
/obj/item/stack/tile/mineral/abductor
name = "alien floor tile"
singular_name = "alien floor tile"
desc = "A tile made out of alien alloy."
icon = 'icons/obj/abductor.dmi'
icon_state = "tile_abductor"
origin_tech = "materials=6;abductor=1"
turf_type = /turf/simulated/floor/mineral/abductor
mineralType = "abductor"
@@ -85,6 +85,9 @@
/obj/item/weapon/restraints/handcuffs/cable/white
color = COLOR_WHITE
/obj/item/weapon/restraints/handcuffs/alien
icon_state = "handcuffAlien"
/obj/item/weapon/restraints/handcuffs/pinkcuffs
name = "fluffy pink handcuffs"
desc = "Use this to keep prisoners in line. Or you know, your significant other."
@@ -137,37 +137,3 @@
H.update_inv_r_hand()
add_fingerprint(user)
return
/obj/item/weapon/cloaking_device
name = "cloaking device"
desc = "Use this to become invisible to the human eyesocket."
icon = 'icons/obj/device.dmi'
icon_state = "shield0"
var/active = 0.0
flags = CONDUCT
item_state = "electronic"
throwforce = 10.0
throw_speed = 2
throw_range = 10
w_class = 2.0
origin_tech = "magnets=3;syndicate=4"
/obj/item/weapon/cloaking_device/attack_self(mob/user as mob)
src.active = !( src.active )
if (src.active)
to_chat(user, "\blue The cloaking device is now active.")
src.icon_state = "shield1"
else
to_chat(user, "\blue The cloaking device is now inactive.")
src.icon_state = "shield0"
src.add_fingerprint(user)
return
/obj/item/weapon/cloaking_device/emp_act(severity)
active = 0
icon_state = "shield0"
if(ismob(loc))
loc:update_icons()
..()
@@ -512,6 +512,16 @@
new /obj/item/weapon/restraints/handcuffs/cable/zipties(src)
new /obj/item/weapon/restraints/handcuffs/cable/zipties(src)
/obj/item/weapon/storage/box/alienhandcuffs
name = "box of spare handcuffs"
desc = "A box full of handcuffs."
icon_state = "alienboxCuffs"
New()
..()
for(var/i in 1 to 7)
new /obj/item/weapon/restraints/handcuffs/alien(src)
/obj/item/weapon/storage/box/fakesyndiesuit
name = "boxed space suit and helmet"
desc = "A sleek, sturdy box used to hold replica spacesuits."
+7 -1
View File
@@ -129,7 +129,13 @@
return
/mob/proc/unset_machine()
src.machine = null
if(machine)
machine.on_unset_machine(src)
machine = null
//called when the user unsets the machine.
/atom/movable/proc/on_unset_machine(mob/user)
return
/mob/proc/set_machine(var/obj/O)
if(src.machine)
@@ -11,9 +11,11 @@
var/wall_mounted = 0 //never solid (You can always pass over it)
var/health = 100
var/lastbang
var/cutting_tool = /obj/item/weapon/weldingtool
var/sound = 'sound/machines/click.ogg'
var/storage_capacity = 30 //This is so that someone can't pack hundreds of items in a locker/crate
//then open it in a populated area to crash clients.
var/cutting_sound = 'sound/items/Welder.ogg'
var/storage_capacity = 30 //This is so that someone can't pack hundreds of items in a locker/crate then open it in a populated area to crash clients.
var/material_drop = /obj/item/stack/sheet/metal
/obj/structure/closet/New()
..()
@@ -257,16 +259,24 @@
src.MouseDrop_T(W:affecting, user) //act like they were dragged onto the closet
if(istype(W,/obj/item/tk_grab))
return 0
if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(!WT.remove_fuel(0,user))
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
return
new /obj/item/stack/sheet/metal(src.loc)
for(var/mob/M in viewers(src))
M.show_message("<span class='notice'>\The [src] has been cut apart by [user] with \the [WT].</span>", 3, "You hear welding.", 2)
qdel(src)
return
if(istype(W, cutting_tool))
if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(!WT.remove_fuel(0, user))
return
to_chat(user, "<span class='notice'>You begin cutting \the [src] apart...</span>")
playsound(loc, cutting_sound, 40, 1)
if(do_after(user, 40, 1, target = src))
if(!opened || !WT.isOn())
return
playsound(loc, cutting_sound, 50, 1)
visible_message("<span class='notice'>[user] slices apart \the [src].</span>",
"<span class='notice'>You cut \the [src] apart with \the [WT].</span>",
"<span class='italics'>You hear welding.</span>")
var/turf/T = get_turf(src)
new material_drop(T)
qdel(src)
return
if(isrobot(user))
return
if(!usr.drop_item())
@@ -6,6 +6,8 @@
icon_closed = "cardboard"
health = 10
sound = 'sound/effects/rustle2.ogg'
material_drop = /obj/item/stack/sheet/cardboard
cutting_sound = 'sound/items/poster_ripped.ogg'
var/move_delay = 0
var/egged = 0
@@ -3,4 +3,5 @@
desc = "A crate which can sustain life for a while."
icon_state = "critter"
icon_opened = "critteropen"
icon_closed = "critter"
icon_closed = "critter"
material_drop = /obj/item/stack/sheet/wood
@@ -274,3 +274,12 @@
mineral = "metal"
walltype = "iron"
canSmoothWith = list(/obj/structure/falsewall/iron, /turf/simulated/wall/mineral/iron)
/obj/structure/falsewall/abductor
name = "alien wall"
desc = "A wall with alien alloy plating."
icon = 'icons/turf/walls/abductor_wall.dmi'
icon_state = "abductor"
mineral = "abductor"
walltype = "abductor"
canSmoothWith = list(/obj/structure/falsewall/abductor, /turf/simulated/wall/mineral/abductor)
@@ -0,0 +1,48 @@
/turf/simulated/floor/mineral
name = "mineral floor"
icon_state = ""
var/list/icons = list()
/turf/simulated/floor/mineral/New()
..()
broken_states = list("[initial(icon_state)]_dam")
/turf/simulated/floor/mineral/update_icon()
if(!..())
return 0
if(!broken && !burnt)
if( !(icon_state in icons) )
icon_state = initial(icon_state)
// ALIEN ALLOY
/turf/simulated/floor/mineral/abductor
name = "alien floor"
icon_state = "alienpod1"
floor_tile = /obj/item/stack/tile/mineral/abductor
icons = list("alienpod1", "alienpod2", "alienpod3", "alienpod4", "alienpod5", "alienpod6", "alienpod7", "alienpod8", "alienpod9")
/turf/simulated/floor/mineral/New()
..()
icon_state = "alienpod[rand(1,9)]"
/turf/simulated/floor/mineral/break_tile()
return //unbreakable
/turf/simulated/floor/mineral/abductor/burn_tile()
return //unburnable
/turf/simulated/floor/mineral/abductor/make_plating()
return ChangeTurf(/turf/simulated/floor/plating/abductor2)
/turf/simulated/floor/plating/abductor2
name = "alien plating"
icon_state = "alienplating"
/turf/simulated/floor/plating/abductor2/break_tile()
return //unbreakable
/turf/simulated/floor/plating/abductor2/burn_tile()
return //unburnable
+9 -1
View File
@@ -292,4 +292,12 @@
/turf/simulated/floor/plasteel/airless/New()
..()
name = "floor"
name = "floor"
/turf/simulated/floor/plating/abductor
name = "alien floor"
icon_state = "alienpod1"
/turf/simulated/floor/plating/abductor/New()
..()
icon_state = "alienpod[rand(1,9)]"
+11 -1
View File
@@ -175,4 +175,14 @@
icon_state = "iron"
walltype = "iron"
mineral = "rods"
canSmoothWith = list(/turf/simulated/wall/mineral/iron, /obj/structure/falsewall/iron)
canSmoothWith = list(/turf/simulated/wall/mineral/iron, /obj/structure/falsewall/iron)
/turf/simulated/wall/mineral/abductor
name = "alien wall"
desc = "A wall with alien alloy plating."
icon = 'icons/turf/walls/abductor_wall.dmi'
icon_state = "abductor"
walltype = "abductor"
mineral = "abductor"
explosion_block = 3
canSmoothWith = list(/turf/simulated/wall/mineral/abductor, /obj/structure/falsewall/abductor)
+9 -1
View File
@@ -27,4 +27,12 @@
/turf/unsimulated/floor/chasm/New()
spawn(1)
smooth_icon(src)
smooth_icon_neighbors(src)
smooth_icon_neighbors(src)
/turf/unsimulated/floor/abductor
name = "alien floor"
icon_state = "alienpod1"
/turf/unsimulated/floor/abductor/New()
..()
icon_state = "alienpod[rand(1,9)]"
+5 -1
View File
@@ -23,4 +23,8 @@ turf/unsimulated/wall/splashscreen
layer = FLY_LAYER
/turf/unsimulated/wall/other
icon_state = "r_wall"
icon_state = "r_wall"
/turf/unsimulated/wall/abductor
icon_state = "alien1"
explosion_block = 50
+4
View File
@@ -749,6 +749,10 @@ var/global/nologevent = 0
if (ticker.mode.config_tag == "changeling")
return 2
return 1
if(M.mind in ticker.mode.abductors)
if (ticker.mode.config_tag == "abduction")
return 2
return 1
if(isrobot(M))
var/mob/living/silicon/robot/R = M
if(R.emagged)
+6
View File
@@ -515,6 +515,12 @@
if(ticker.mode.shadowling_thralls.len)
dat += check_role_table("Shadowling Thralls", ticker.mode.shadowling_thralls, src)
if(ticker.mode.abductors.len)
dat += check_role_table("Abductors", ticker.mode.abductors, src)
if(ticker.mode.abductees.len)
dat += check_role_table("Abductees", ticker.mode.abductees, src)
if(ticker.mode.vampires.len)
dat += check_role_table("Vampires", ticker.mode.vampires, src)
+4
View File
@@ -63,6 +63,10 @@
log_admin("[key_name(usr)] has spawned vox raiders.")
if(!src.makeVoxRaiders())
to_chat(usr, "\red Unfortunately there weren't enough candidates available.")
if("9")
log_admin("[key_name(usr)] has spawned an abductor team.")
if(!src.makeAbductorTeam())
to_chat(usr, "\red Unfortunately there weren't enough candidates available.")
else if(href_list["dbsearchckey"] || href_list["dbsearchadmin"] || href_list["dbsearchip"] || href_list["dbsearchcid"] || href_list["dbsearchbantype"])
var/adminckey = href_list["dbsearchadmin"]
-2
View File
@@ -682,7 +682,6 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/clothing/head/det_hat(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/weapon/cloaking_device(M), slot_r_store)
M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/automatic/proto(M), slot_r_hand)
M.equip_to_slot_or_del(new /obj/item/ammo_box/a357(M), slot_l_store)
@@ -814,7 +813,6 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/wcoat(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword/saber(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/weapon/cloaking_device(M), slot_r_store)
var/obj/item/weapon/storage/secure/briefcase/sec_briefcase = new(M)
for(var/obj/item/briefcase_item in sec_briefcase)
+6 -3
View File
@@ -21,6 +21,7 @@ client/proc/one_click_antag()
<a href='?src=\ref[src];makeAntag=6'>Make Wizard (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=7'>Make Vampires</a><br>
<a href='?src=\ref[src];makeAntag=8'>Make Vox Raiders (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=9'>Make Abductor Team (Requires Ghosts)</a><br>
"}
usr << browse(dat, "window=oneclickantag;size=400x400")
return
@@ -308,8 +309,10 @@ client/proc/one_click_antag()
return 1
//Abductors
/datum/admins/proc/makeAbductorTeam()
new /datum/event/abductor
return 1
/datum/admins/proc/makeAliens()
alien_infestation(3)
@@ -396,7 +399,7 @@ client/proc/one_click_antag()
//First we spawn a dude.
var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned.
var/datum/preferences/A = new()
var/datum/preferences/A = new(G_found.client)
A.copy_to(new_character)
new_character.dna.ready_dna(new_character)
+1
View File
@@ -25,6 +25,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
ROLE_NINJA = 21,
ROLE_MUTINEER = 21,
ROLE_MALF = 30,
ROLE_ABDUCTOR = 30,
)
/proc/player_old_enough_antag(client/C, role)
+52
View File
@@ -0,0 +1,52 @@
/datum/event/abductor
/datum/event/abductor/start()
//spawn abductor team
processing = 0 //so it won't fire again in next tick
if(!makeAbductorTeam())
message_admins("Abductor event failed to find players. Retrying in 30s.")
spawn(300)
makeAbductorTeam()
/datum/event/abductor/proc/makeAbductorTeam()
var/list/mob/dead/observer/candidates = pollCandidates("Do you wish to be considered for an Abductor Team?", ROLE_ABDUCTOR, 1)
if(candidates.len >= 2)
//Oh god why we can't have static functions
var/number = ticker.mode.abductor_teams + 1
var/datum/game_mode/abduction/temp
if(ticker.mode.config_tag == "abduction")
temp = ticker.mode
else
temp = new
var/agent_mind = pick(candidates)
candidates -= agent_mind
var/scientist_mind = pick(candidates)
var/mob/living/carbon/human/agent=makeBody(agent_mind)
var/mob/living/carbon/human/scientist=makeBody(scientist_mind)
agent_mind = agent.mind
scientist_mind = scientist.mind
temp.scientists.len = number
temp.agents.len = number
temp.abductors.len = 2*number
temp.team_objectives.len = number
temp.team_names.len = number
temp.scientists[number] = scientist_mind
temp.agents[number] = agent_mind
temp.abductors |= list(agent_mind,scientist_mind)
temp.make_abductor_team(number,preset_scientist=scientist_mind,preset_agent=agent_mind)
temp.post_setup_team(number)
ticker.mode.abductor_teams++
if(ticker.mode.config_tag != "abduction")
ticker.mode.abductors |= temp.abductors
processing = 1 //So it will get gc'd
return 1
else
return 0
+4
View File
@@ -48,6 +48,7 @@
return 0*/
/datum/event //NOTE: Times are measured in master controller ticks!
var/processing = 1
var/startWhen = 0 //When in the lifetime to call start().
var/announceWhen = 0 //When in the lifetime to call announce().
var/endWhen = 0 //When in the lifetime the event should end.
@@ -105,6 +106,9 @@
//Do not override this proc, instead use the appropiate procs.
//This proc will handle the calls to the appropiate procs.
/datum/event/proc/process()
if(!processing)
return
if(activeFor > startWhen && activeFor < endWhen || noAutoEnd)
tick()
+5 -4
View File
@@ -178,10 +178,11 @@ var/list/event_last_fired = list()
severity = EVENT_LEVEL_MAJOR
available_events = list(
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 1320),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1),
//new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station, 0, list(ASSIGNMENT_ANY = 5)),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1),
//new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station, 0, list(ASSIGNMENT_ANY = 5)),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Abductor Visit", /datum/event/abductor, 80, is_one_shot = 1),
new /datum/event_meta/alien(EVENT_LEVEL_MAJOR, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 30), 1),
)
+22 -2
View File
@@ -107,10 +107,10 @@
to_chat(player, msg_dead)
continue
else if(istype(player,/mob/dead) || ((src in player.languages) && check_special_condition(player)))
else if(istype(player,/mob/dead) || ((src in player.languages) && check_special_condition(player, speaker)))
to_chat(player, msg)
/datum/language/proc/check_special_condition(var/mob/other)
/datum/language/proc/check_special_condition(var/mob/other, var/mob/living/speaker)
return 1
/datum/language/proc/get_spoken_verb(var/msg_end)
@@ -409,6 +409,7 @@
key = "8"
flags = RESTRICTED | HIVEMIND
/datum/language/shadowling/broadcast(var/mob/living/speaker, var/message, var/speaker_mask)
if(speaker.mind && speaker.mind.special_role)
..(speaker, message, "([speaker.mind.special_role]) [speaker]")
@@ -422,6 +423,25 @@
else
..(speaker,message)
/datum/language/abductor
name = "Abductor Mindlink"
desc = "Abductors are incapable of speech, but have a psychic link attuned to their own team."
speech_verb = "gibbers"
ask_verb = "gibbers"
exclaim_verb = "gibbers"
colour = "abductor"
key = "zw" //doesn't matter, this is their default and only language
flags = RESTRICTED | HIVEMIND
/datum/language/abductor/broadcast(var/mob/living/speaker,var/message,var/speaker_mask)
..(speaker,message,speaker.real_name)
/datum/language/abductor/check_special_condition(var/mob/living/carbon/human/other, var/mob/living/carbon/human/speaker)
if(other.mind && other.mind.abductor)
if(other.mind.abductor.team == speaker.mind.abductor.team)
return 1
return 0
/datum/language/corticalborer
name = "Cortical Link"
desc = "Cortical borers possess a strange link between their tiny minds."
@@ -112,6 +112,9 @@
/mob/living/carbon/human/grey/New(var/new_loc)
..(new_loc, "Grey")
/mob/living/carbon/human/abductor/New(var/new_loc)
..(new_loc, "Abductor")
/mob/living/carbon/human/human/New(var/new_loc)
..(new_loc, "Human")
@@ -688,6 +691,8 @@
//repurposed proc. Now it combines get_id_name() and get_face_name() to determine a mob's name variable. Made into a seperate proc as it'll be useful elsewhere
/mob/living/carbon/human/get_visible_name()
if(name_override)
return name_override
if(wear_mask && (wear_mask.flags_inv & HIDEFACE)) //Wearing a mask which hides our face, use id-name if possible
return get_id_name("Unknown")
if(head && (head.flags_inv & HIDEFACE))
@@ -80,6 +80,8 @@
var/hand_blood_color
var/name_override //For temporary visible name changes
var/xylophone = 0 //For the spoooooooky xylophone cooldown
var/mob/remoteview_target = null
@@ -0,0 +1,27 @@
/datum/species/abductor
name = "Abductor"
name_plural = "Abductors"
icobase = 'icons/mob/human_races/r_abductor.dmi'
deform = 'icons/mob/human_races/r_abductor.dmi'
path = /mob/living/carbon/human/abductor
language = "Abductor Mindlink"
default_language = "Abductor Mindlink"
unarmed_type = /datum/unarmed_attack/punch
darksight = 3
eyes = "blank_eyes"
flags = HAS_LIPS | NO_BLOOD | NO_BREATHE
virus_immune = 1
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
dietflags = DIET_OMNI
reagent_tag = PROCESS_ORG
blood_color = "#FF5AFF"
/datum/species/abductor/can_understand(var/mob/other) //Abductors can understand everyone, but they can only speak over their mindlink to another team-member
return 1
/datum/species/abductor/handle_post_spawn(var/mob/living/carbon/human/H)
H.gender = NEUTER
if(H.mind)
H.mind.abductor = new /datum/abductor
return ..()
@@ -104,41 +104,6 @@ If you have any questions/constructive-comments/bugs-to-report/or have a massivl
Please contact me on #coderbus IRC. ~Carn x
*/
//Human Overlays Indexes/////////
#define MUTANTRACE_LAYER 1
#define TAIL_UNDERLIMBS_LAYER 2
#define LIMBS_LAYER 3
#define MARKINGS_LAYER 4
#define UNDERWEAR_LAYER 5
#define MUTATIONS_LAYER 6
#define DAMAGE_LAYER 7
#define UNIFORM_LAYER 8
#define ID_LAYER 9
#define SHOES_LAYER 10
#define GLOVES_LAYER 11
#define EARS_LAYER 12
#define SUIT_LAYER 13
#define GLASSES_LAYER 14
#define BELT_LAYER 15 //Possible make this an overlay of somethign required to wear a belt?
#define SUIT_STORE_LAYER 16
#define BACK_LAYER 17
#define TAIL_LAYER 18 //bs12 specific. this hack is probably gonna come back to haunt me
#define HAIR_LAYER 19 //TODO: make part of head layer?
#define HEAD_ACCESSORY_LAYER 20
#define FHAIR_LAYER 21
#define FACEMASK_LAYER 22
#define HEAD_LAYER 23
#define COLLAR_LAYER 24
#define HANDCUFF_LAYER 25
#define LEGCUFF_LAYER 26
#define L_HAND_LAYER 27
#define R_HAND_LAYER 28
#define TARGETED_LAYER 29 //BS12: Layer for the target overlay from weapon targeting system
#define FIRE_LAYER 30 //If you're on fire
#define TOTAL_LAYERS 30
/mob/living/carbon/human
var/list/overlays_standing[TOTAL_LAYERS]
var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed
@@ -163,18 +128,26 @@ Please contact me on #coderbus IRC. ~Carn x
update_hud() //TODO: remove the need for this
var/stealth = 0
for(var/obj/item/weapon/cloaking_device/S in list(l_hand,r_hand,belt,l_store,r_store))
if(S.active)
var/obj/item/clothing/suit/armor/abductor/vest/V // Begin the most snowflakey bullshit code I've ever written. I'm so sorry, but there was no other way.
for(V in list(wear_suit))
if(V.stealth_active)
stealth = 1
break
if(stealth)
icon = 'icons/mob/human.dmi'
icon_state = "body_cloaked"
var/image/I = overlays_standing[L_HAND_LAYER]
if(istype(I)) overlays += I
I = overlays_standing[R_HAND_LAYER]
if(istype(I)) overlays += I
icon = V.disguise.icon //if the suit is active, reference the suit's current loaded icon and overlays; this does not include hand overlays
overlays.Cut()
for(var/thing in V.disguise.overlays)
if(thing)
overlays += thing
var/image/I = overlays_standing[L_HAND_LAYER] //manually add both left and right hand, so its independently updated
if(istype(I))
overlays += I
I = overlays_standing[R_HAND_LAYER]
if(istype(I))
overlays += I
else
icon = stand_icon
overlays.Cut()
@@ -1240,34 +1213,11 @@ var/global/list/damage_icon_parts = list()
O.sync_colour_to_human(src)
update_body(0)
//Human Overlays Indexes/////////
#undef MUTANTRACE_LAYER
#undef TAIL_UNDERLIMBS_LAYER
#undef LIMBS_LAYER
#undef MARKINGS_LAYER
#undef MUTATIONS_LAYER
#undef DAMAGE_LAYER
#undef UNIFORM_LAYER
#undef ID_LAYER
#undef SHOES_LAYER
#undef GLOVES_LAYER
#undef EARS_LAYER
#undef SUIT_LAYER
#undef GLASSES_LAYER
#undef FACEMASK_LAYER
#undef BELT_LAYER
#undef SUIT_STORE_LAYER
#undef BACK_LAYER
#undef TAIL_LAYER
#undef HAIR_LAYER
#undef HEAD_LAYER
#undef HEAD_ACCESSORY_LAYER
#undef FHAIR_LAYER
#undef COLLAR_LAYER
#undef HANDCUFF_LAYER
#undef LEGCUFF_LAYER
#undef L_HAND_LAYER
#undef R_HAND_LAYER
#undef TARGETED_LAYER
#undef FIRE_LAYER
#undef TOTAL_LAYERS
/mob/living/carbon/human/proc/get_overlays_copy(list/unwantedLayers)
var/list/out = new
for(var/i=1;i<=TOTAL_LAYERS;i++)
if(overlays_standing[i])
if(i in unwantedLayers)
continue
out += overlays_standing[i]
return out
@@ -39,14 +39,6 @@
/mob/living/bullet_act(var/obj/item/projectile/P, var/def_zone)
//Being hit while using a cloaking device
var/obj/item/weapon/cloaking_device/C = locate((/obj/item/weapon/cloaking_device) in src)
if(C && C.active)
C.attack_self(src)//Should shut it off
update_icons()
to_chat(src, "\blue Your [C.name] was disrupted!")
Stun(2)
//Armor
var/armor = run_armor_check(def_zone, P.flag, armour_penetration = P.armour_penetration)
var/proj_sharp = is_sharp(P)
@@ -230,4 +230,14 @@
build_type = PROTOLATHE
materials = list(MAT_METAL = 15000, MAT_GLASS = 5000, MAT_SILVER = 2500) //hardcore
build_path = /obj/item/weapon/storage/part_replacer/bluespace
category = list("Stock Parts")
/datum/design/alienalloy
name = "Alien Alloy"
desc = "A sheet of reverse-engineered alien alloy."
id = "alienalloy"
req_tech = list("abductor" = 1, "materials" = 7, "plasmatech" = 2)
build_type = PROTOLATHE
materials = list(MAT_METAL = 4000, MAT_PLASMA = 4000)
build_path = /obj/item/stack/sheet/mineral/abductor
category = list("Stock Parts")
+7 -2
View File
@@ -438,8 +438,9 @@ proc/CallMaterialName(ID)
if( new_item.type == /obj/item/weapon/storage/backpack/holding )
new_item.investigate_log("built by [key]","singulo")
new_item.reliability = 100
new_item.materials[MAT_METAL] /= coeff
new_item.materials[MAT_GLASS] /= coeff
if(!istype(new_item, /obj/item/stack/sheet)) // To avoid materials dupe glitches
new_item.materials[MAT_METAL] /= coeff
new_item.materials[MAT_GLASS] /= coeff
if(O)
var/obj/item/weapon/storage/lockbox/L = new/obj/item/weapon/storage/lockbox(linked_lathe.loc)
new_item.loc = L
@@ -706,6 +707,8 @@ proc/CallMaterialName(ID)
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A>"
dat += "<h3>Current Research Levels:</h3><BR><div class='statusDisplay'>"
for(var/datum/tech/T in files.known_tech)
if(T.level <= 0)
continue
dat += "[T.name]<BR>"
dat += "* Level: [T.level]<BR>"
dat += "* Summary: [T.desc]<HR>"
@@ -733,6 +736,8 @@ proc/CallMaterialName(ID)
dat += "<A href='?src=\ref[src];menu=1.2'>Return to Disk Operations</A><div class='statusDisplay'>"
dat += "<h3>Load Technology to Disk:</h3><BR>"
for(var/datum/tech/T in files.known_tech)
if(T.level <= 0)
continue
dat += "[T.name] "
dat += "<A href='?src=\ref[src];copy_tech=1;copy_tech_ID=[T.id]'>Copy to Disk</A><BR>"
dat += "</div>"
+9 -3
View File
@@ -117,7 +117,7 @@ research holder datum.
if(DesignHasReqs(PD))
AddDesign2Known(PD)
for(var/datum/tech/T in known_tech)
T = Clamp(T.level, 1, 20)
T = Clamp(T.level, 0, 20)
for(var/datum/design/D in known_designs)
D.CalcReliability(known_tech)
return
@@ -242,6 +242,13 @@ datum/tech/syndicate
max_level = 0 // Don't count towards maxed research, since it's illegal.
rare = 4
/datum/tech/abductor
name = "Alien Technologies Research"
desc = "The study of technologies used by the advanced alien race known as Abductors."
id = "abductor"
rare = 5
level = 0
/*
datum/tech/arcane
name = "Arcane Research"
@@ -278,8 +285,7 @@ datum/tech/robotics
return 0
var/cost = 0
var/i
for(i=current_level+1, i<=level, i++)
for(var/i=current_level+1, i<=level, i++)
if(i == initial(level))
continue
cost += i*5*rare
+2
View File
@@ -315,6 +315,8 @@
dat += "[temp_server.name] Data ManagementP<BR><BR>"
dat += "Known Technologies<BR>"
for(var/datum/tech/T in temp_server.files.known_tech)
if(T.level <= 0)
continue
dat += "* [T.name] "
dat += "<A href='?src=\ref[src];reset_tech=[T.id]'>(Reset)</A><BR>" //FYI, these are all strings.
dat += "Known Designs<BR>"