@@ -0,0 +1,79 @@
|
||||
GLOBAL_LIST_INIT(abductor_gear, subtypesof(/datum/abductor_gear))
|
||||
|
||||
/datum/abductor_gear
|
||||
/// Name of the gear
|
||||
var/name = "Generic Abductor Gear"
|
||||
/// Description of the gear
|
||||
var/description = "Generic description."
|
||||
/// Unique ID of the gear
|
||||
var/id = "abductor_generic"
|
||||
/// Credit cost of the gear
|
||||
var/cost = 1
|
||||
/// Build path of the gear itself
|
||||
var/build_path = null
|
||||
/// Category of the gear
|
||||
var/category = "Basic Gear"
|
||||
|
||||
/datum/abductor_gear/agent_helmet
|
||||
name = "Agent Helmet"
|
||||
description = "Abduct with style - spiky style. Prevents digital tracking."
|
||||
id = "agent_helmet"
|
||||
build_path = /obj/item/clothing/head/helmet/abductor
|
||||
|
||||
/datum/abductor_gear/agent_vest
|
||||
name = "Agent Vest"
|
||||
description = "A vest outfitted with advanced stealth technology. It has two modes - combat and stealth."
|
||||
id = "agent_vest"
|
||||
build_path = /obj/item/clothing/suit/armor/abductor/vest
|
||||
|
||||
/datum/abductor_gear/radio_silencer
|
||||
name = "Radio Silencer"
|
||||
description = "A compact device used to shut down communications equipment."
|
||||
id = "radio_silencer"
|
||||
build_path = /obj/item/abductor/silencer
|
||||
|
||||
/datum/abductor_gear/science_tool
|
||||
name = "Science Tool"
|
||||
description = "A dual-mode tool for retrieving specimens and scanning appearances. Scanning can be done through cameras."
|
||||
id = "science_tool"
|
||||
build_path = /obj/item/abductor/gizmo
|
||||
/*
|
||||
/datum/abductor_gear/advanced_baton
|
||||
name = "Advanced Baton"
|
||||
description = "A quad-mode baton used for incapacitation and restraining of specimens."
|
||||
id = "advanced_baton"
|
||||
cost = 2
|
||||
build_path = /obj/item/melee/baton/abductor //does not exist?
|
||||
*/
|
||||
/datum/abductor_gear/superlingual_matrix
|
||||
name = "Superlingual Matrix"
|
||||
description = "A mysterious structure that allows for instant communication between users. Pretty impressive until you need to eat something."
|
||||
id = "superlingual_matrix"
|
||||
build_path = /obj/item/organ/tongue/abductor
|
||||
category = "Advanced Gear"
|
||||
|
||||
/datum/abductor_gear/mental_interface
|
||||
name = "Mental Interface Device"
|
||||
description = "A dual-mode tool for directly communicating with sentient brains. It can be used to send a direct message to a target, \
|
||||
or to send a command to a test subject with a charged gland."
|
||||
id = "mental_interface"
|
||||
cost = 2
|
||||
build_path = /obj/item/abductor/mind_device
|
||||
category = "Advanced Gear"
|
||||
|
||||
/datum/abductor_gear/reagent_synthesizer
|
||||
name = "Reagent Synthesizer"
|
||||
description = "Synthesizes a variety of reagents using proto-matter."
|
||||
id = "reagent_synthesizer"
|
||||
cost = 2
|
||||
build_path = /obj/item/abductor_machine_beacon/chem_dispenser
|
||||
category = "Advanced Gear"
|
||||
|
||||
/datum/abductor_gear/shrink_ray
|
||||
name = "Shrink Ray Blaster"
|
||||
description = "This is a piece of frightening alien tech that enhances the magnetic pull of atoms in a localized space to temporarily make an object shrink. \
|
||||
That or it's just space magic. Either way, it shrinks stuff."
|
||||
id = "shrink_ray"
|
||||
cost = 2
|
||||
build_path = /obj/item/gun/energy/shrink_ray
|
||||
category = "Advanced Gear"
|
||||
@@ -23,99 +23,105 @@
|
||||
var/obj/machinery/abductor/pad/pad
|
||||
var/obj/machinery/computer/camera_advanced/abductor/camera
|
||||
var/list/datum/icon_snapshot/disguises = list()
|
||||
/// Currently selected gear category
|
||||
var/selected_cat
|
||||
/// Dictates if the compact mode of the interface is on or off
|
||||
var/compact_mode = FALSE
|
||||
/// Possible gear to be dispensed
|
||||
var/list/possible_gear
|
||||
|
||||
/obj/machinery/abductor/console/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(!HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING) && !HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_TRAINING))
|
||||
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>"
|
||||
|
||||
/obj/machinery/abductor/console/ui_status(mob/user)
|
||||
if(!isabductor(user) && !isobserver(user))
|
||||
return UI_CLOSE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/abductor/console/ui_state(mob/user)
|
||||
return GLOB.physical_state
|
||||
|
||||
/obj/machinery/abductor/console/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "AbductorConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/abductor/console/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["categories"] = list()
|
||||
for(var/category in possible_gear)
|
||||
var/list/cat = list(
|
||||
"name" = category,
|
||||
"items" = (category == selected_cat ? list() : null))
|
||||
for(var/gear in possible_gear[category])
|
||||
var/datum/abductor_gear/AG = possible_gear[category][gear]
|
||||
cat["items"] += list(list(
|
||||
"name" = AG.name,
|
||||
"cost" = AG.cost,
|
||||
"desc" = AG.description,
|
||||
))
|
||||
data["categories"] += list(cat)
|
||||
return data
|
||||
|
||||
/obj/machinery/abductor/console/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["compactMode"] = compact_mode
|
||||
data["experiment"] = experiment ? TRUE : FALSE
|
||||
if(experiment)
|
||||
var/points = experiment.points
|
||||
var/credits = experiment.credits
|
||||
dat += "Collected Samples : [points] <br>"
|
||||
dat += "Gear Credits: [credits] <br>"
|
||||
dat += "<b>Transfer data in exchange for supplies:</b><br>"
|
||||
dat += "<a href='?src=[REF(src)];dispense=baton'>Advanced Baton (2 Credits)</A><br>"
|
||||
dat += "<a href='?src=[REF(src)];dispense=mind_device'>Mental Interface Device (2 Credits)</A><br>"
|
||||
dat += "<a href='?src=[REF(src)];dispense=chem_dispenser'>Reagent Synthesizer (2 Credits)</A><br>"
|
||||
dat += "<a href='?src=[REF(src)];dispense=helmet'>Agent Helmet (1 Credit)</A><br>"
|
||||
dat += "<a href='?src=[REF(src)];dispense=vest'>Agent Vest (1 Credit)</A><br>"
|
||||
dat += "<a href='?src=[REF(src)];dispense=silencer'>Radio Silencer (1 Credit)</A><br>"
|
||||
dat += "<a href='?src=[REF(src)];dispense=tool'>Science Tool (1 Credit)</A><br>"
|
||||
dat += "<a href='?src=[REF(src)];dispense=tongue'>Superlingual Matrix (1 Credit)</a><br>"
|
||||
else
|
||||
dat += "<span class='bad'>NO EXPERIMENT MACHINE DETECTED</span> <br>"
|
||||
|
||||
data["points"] = experiment.points
|
||||
data["credits"] = experiment.credits
|
||||
data["pad"] = pad ? TRUE : FALSE
|
||||
if(pad)
|
||||
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 && gizmo.marked)
|
||||
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>"
|
||||
|
||||
data["gizmo"] = gizmo && gizmo.marked ? TRUE : FALSE
|
||||
data["vest"] = vest ? TRUE : FALSE
|
||||
if(vest)
|
||||
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>"
|
||||
data["vest_mode"] = vest.mode
|
||||
data["vest_lock"] = HAS_TRAIT_FROM(vest, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT)
|
||||
return data
|
||||
|
||||
dat+="<br>"
|
||||
dat += "<a href='?src=[REF(src)];select_disguise=1'>Select Agent Vest Disguise</a><br>"
|
||||
dat += "<a href='?src=[REF(src)];toggle_vest=1'>[HAS_TRAIT_FROM(vest, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) ? "Unlock" : "Lock"] Vest</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.open()
|
||||
|
||||
/obj/machinery/abductor/console/Topic(href, href_list)
|
||||
if(..())
|
||||
/obj/machinery/abductor/console/ui_act(action, list/params)
|
||||
. = ..()
|
||||
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["toggle_vest"])
|
||||
if(vest)
|
||||
switch(action)
|
||||
if("buy")
|
||||
var/item_name = params["name"]
|
||||
var/list/buyable_items = list()
|
||||
for(var/category in possible_gear)
|
||||
buyable_items += possible_gear[category]
|
||||
for(var/key in buyable_items)
|
||||
var/datum/abductor_gear/AG = buyable_items[key]
|
||||
if(AG.name == item_name)
|
||||
Dispense(AG.build_path, AG.cost)
|
||||
return TRUE
|
||||
if("teleporter_send")
|
||||
TeleporterSend()
|
||||
return TRUE
|
||||
if("teleporter_retrieve")
|
||||
TeleporterRetrieve()
|
||||
return TRUE
|
||||
if("flip_vest")
|
||||
FlipVest()
|
||||
return TRUE
|
||||
if("toggle_vest")
|
||||
if(!vest)
|
||||
return
|
||||
vest.toggle_nodrop()
|
||||
else if(href_list["select_disguise"])
|
||||
SelectDisguise()
|
||||
else if(href_list["dispense"])
|
||||
switch(href_list["dispense"])
|
||||
if("baton")
|
||||
Dispense(/obj/item/abductor/baton,cost=2)
|
||||
if("helmet")
|
||||
Dispense(/obj/item/clothing/head/helmet/abductor)
|
||||
if("silencer")
|
||||
Dispense(/obj/item/abductor/silencer)
|
||||
if("tool")
|
||||
Dispense(/obj/item/abductor/gizmo)
|
||||
if("vest")
|
||||
Dispense(/obj/item/clothing/suit/armor/abductor/vest)
|
||||
if("mind_device")
|
||||
Dispense(/obj/item/abductor/mind_device,cost=2)
|
||||
if("chem_dispenser")
|
||||
Dispense(/obj/item/abductor_machine_beacon/chem_dispenser,cost=2)
|
||||
if("tongue")
|
||||
Dispense(/obj/item/organ/tongue/abductor)
|
||||
updateUsrDialog()
|
||||
return TRUE
|
||||
if("select_disguise")
|
||||
SelectDisguise()
|
||||
return TRUE
|
||||
if("select")
|
||||
selected_cat = params["category"]
|
||||
return TRUE
|
||||
if("compact_toggle")
|
||||
compact_mode = !compact_mode
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/abductor/console/proc/TeleporterRetrieve()
|
||||
if(pad && gizmo && gizmo.marked)
|
||||
@@ -156,7 +162,6 @@
|
||||
pad.teleport_target = location
|
||||
to_chat(user, "<span class='notice'>Location marked as test subject release point.</span>")
|
||||
|
||||
|
||||
/obj/machinery/abductor/console/Initialize(mapload)
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
@@ -22,38 +22,44 @@
|
||||
gland_colors[i] = random_color()
|
||||
amounts[i] = rand(1,5)
|
||||
|
||||
/obj/machinery/abductor/gland_dispenser/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(!isabductor(user))
|
||||
/obj/machinery/abductor/gland_dispenser/ui_status(mob/user)
|
||||
if(!isabductor(user) && !isobserver(user))
|
||||
return UI_CLOSE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/abductor/gland_dispenser/ui_state(mob/user)
|
||||
return GLOB.physical_state
|
||||
|
||||
/obj/machinery/abductor/gland_dispenser/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "GlandDispenser", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/abductor/gland_dispenser/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["glands"] = list()
|
||||
for(var/gland_number=1,gland_number<=gland_colors.len,gland_number++)
|
||||
var/list/gland_information = list(
|
||||
"color" = gland_colors[gland_number],
|
||||
"amount" = amounts[gland_number],
|
||||
"id" = gland_number,
|
||||
)
|
||||
data["glands"] += list(gland_information)
|
||||
return data
|
||||
|
||||
/obj/machinery/abductor/gland_dispenser/ui_act(action, list/params)
|
||||
. = ..()
|
||||
if(.)
|
||||
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 == 4) // Four 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.open()
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("dispense")
|
||||
var/gland_id = text2num(params["gland_id"])
|
||||
if(!gland_id)
|
||||
return
|
||||
Dispense(gland_id)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/abductor/gland_dispenser/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/organ/heart/gland))
|
||||
@@ -65,15 +71,6 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/abductor/gland_dispenser/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
usr.set_machine(src)
|
||||
|
||||
if(href_list["dispense"])
|
||||
Dispense(text2num(href_list["dispense"]))
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/abductor/gland_dispenser/proc/Dispense(count)
|
||||
if(amounts[count]>0)
|
||||
amounts[count]--
|
||||
|
||||
@@ -15,16 +15,13 @@
|
||||
var/breakout_time = 450
|
||||
|
||||
/obj/machinery/abductor/experiment/MouseDrop_T(mob/target, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user) || !ishuman(target))
|
||||
var/mob/living/L = user
|
||||
if(user.stat || (isliving(user) && (!(L.mobility_flags & MOBILITY_STAND) || !(L.mobility_flags & MOBILITY_UI))) || !Adjacent(user) || !target.Adjacent(user) || !ishuman(target))
|
||||
return
|
||||
if(isabductor(target))
|
||||
return
|
||||
close_machine(target)
|
||||
|
||||
/obj/machinery/abductor/experiment/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
|
||||
experimentUI(user)
|
||||
|
||||
/obj/machinery/abductor/experiment/open_machine()
|
||||
if(!state_open && !panel_open)
|
||||
..()
|
||||
@@ -46,7 +43,7 @@
|
||||
/obj/machinery/abductor/experiment/container_resist(mob/living/user)
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
|
||||
"<span class='italics'>You hear a metallic creaking from [src].</span>")
|
||||
"<span class='hear'>You hear a metallic creaking from [src].</span>")
|
||||
if(do_after(user,(breakout_time), target = src))
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open)
|
||||
return
|
||||
@@ -54,122 +51,84 @@
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/abductor/experiment/proc/dissection_icon(mob/living/carbon/human/H)
|
||||
var/icon/photo = null
|
||||
var/g = (H.dna.features["body_model"] == FEMALE) ? "f" : "m"
|
||||
if(H.dna.species.use_skintones)
|
||||
photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.skin_tone]_[g]")
|
||||
else
|
||||
photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.dna.species.id]_[g]")
|
||||
photo.Blend("#[H.dna.features["mcolor"]]", ICON_MULTIPLY)
|
||||
/obj/machinery/abductor/experiment/ui_status(mob/user)
|
||||
if(user == occupant)
|
||||
return UI_CLOSE
|
||||
return ..()
|
||||
|
||||
var/icon/eyes
|
||||
if(EYECOLOR in H.dna.species.species_traits)
|
||||
eyes = icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = "eyes")
|
||||
eyes.Blend("#[H.eye_color]", ICON_MULTIPLY)
|
||||
/obj/machinery/abductor/experiment/ui_state(mob/user)
|
||||
return GLOB.physical_state
|
||||
|
||||
var/datum/sprite_accessory/S
|
||||
S = GLOB.hair_styles_list[H.hair_style]
|
||||
if(S && (HAIR in H.dna.species.species_traits))
|
||||
var/icon/hair = icon("icon" = S.icon, "icon_state" = "[S.icon_state]")
|
||||
hair.Blend("#[H.hair_color]", ICON_MULTIPLY)
|
||||
eyes.Blend(hair, ICON_OVERLAY)
|
||||
/obj/machinery/abductor/experiment/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "ProbingConsole", name)
|
||||
ui.open()
|
||||
|
||||
S = GLOB.facial_hair_styles_list[H.facial_hair_style]
|
||||
if(S && (FACEHAIR in H.dna.species.species_traits))
|
||||
var/icon/facial = icon("icon" = S.icon, "icon_state" = "[S.icon_state]")
|
||||
facial.Blend("#[H.facial_hair_color]", ICON_MULTIPLY)
|
||||
eyes.Blend(facial, ICON_OVERLAY)
|
||||
|
||||
if(eyes)
|
||||
photo.Blend(eyes, ICON_OVERLAY)
|
||||
|
||||
var/icon/splat = icon("icon" = 'icons/mob/dam_mob.dmi',"icon_state" = "chest30")
|
||||
photo.Blend(splat,ICON_OVERLAY)
|
||||
|
||||
return photo
|
||||
|
||||
/obj/machinery/abductor/experiment/proc/experimentUI(mob/user)
|
||||
var/dat
|
||||
dat += "<h3> Experiment </h3>"
|
||||
if(occupant)
|
||||
var/obj/item/photo/P = new
|
||||
P.picture = new
|
||||
P.picture.picture_image = icon(dissection_icon(occupant), dir = SOUTH)
|
||||
user << browse_rsc(P.picture.picture_image, "dissection_img")
|
||||
dat += "<table><tr><td>"
|
||||
dat += "<img src=dissection_img height=80 width=80>" //Avert your eyes
|
||||
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] => "
|
||||
var/mob/living/mob_occupant = occupant
|
||||
switch(mob_occupant.stat)
|
||||
if(CONSCIOUS)
|
||||
dat += "<span class='good'>Conscious</span>"
|
||||
if(UNCONSCIOUS)
|
||||
dat += "<span class='average'>Unconscious</span>"
|
||||
else // DEAD
|
||||
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)];[state_open ? "close=1'>Close</a>" : "open=1'>Open</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["open"])
|
||||
open_machine()
|
||||
return
|
||||
if(href_list["close"])
|
||||
close_machine()
|
||||
return
|
||||
/obj/machinery/abductor/experiment/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["open"] = state_open
|
||||
data["feedback"] = flash
|
||||
data["occupant"] = occupant ? TRUE : FALSE
|
||||
data["occupant_name"] = null
|
||||
data["occupant_status"] = null
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(mob_occupant.stat != DEAD)
|
||||
if(href_list["experiment"])
|
||||
flash = Experiment(occupant,href_list["experiment"],usr)
|
||||
updateUsrDialog()
|
||||
add_fingerprint(usr)
|
||||
data["occupant_name"] = mob_occupant.name
|
||||
data["occupant_status"] = mob_occupant.stat
|
||||
return data
|
||||
|
||||
/obj/machinery/abductor/experiment/proc/Experiment(mob/occupant,type,mob/user)
|
||||
/obj/machinery/abductor/experiment/ui_act(action, list/params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("door")
|
||||
if(state_open)
|
||||
close_machine()
|
||||
return TRUE
|
||||
else
|
||||
open_machine()
|
||||
return TRUE
|
||||
if("experiment")
|
||||
if(!occupant)
|
||||
return
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(mob_occupant.stat == DEAD)
|
||||
return
|
||||
flash = experiment(occupant, params["experiment_type"], usr)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* experiment: Performs selected experiment on occupant mob, resulting in a point reward on success
|
||||
*
|
||||
* Arguments:
|
||||
* * occupant The mob inside the machine
|
||||
* * type The type of experiment to be performed
|
||||
* * user The mob starting the experiment
|
||||
*/
|
||||
/obj/machinery/abductor/experiment/proc/experiment(mob/occupant, type, mob/user)
|
||||
LAZYINITLIST(history)
|
||||
var/mob/living/carbon/human/H = occupant
|
||||
|
||||
var/datum/antagonist/abductor/user_abductor = user.mind.has_antag_datum(/datum/antagonist/abductor)
|
||||
if(!user_abductor)
|
||||
return "<span class='bad'>Authorization failure. Contact mothership immidiately.</span>"
|
||||
return "Authorization failure. Contact mothership immediately."
|
||||
|
||||
var/point_reward = 0
|
||||
if(!H)
|
||||
return "Invalid or missing specimen."
|
||||
if(H in history)
|
||||
return "<span class='bad'>Specimen already in database.</span>"
|
||||
return "Specimen already in database."
|
||||
if(H.stat == DEAD)
|
||||
say("Specimen deceased - please provide fresh sample.")
|
||||
return "<span class='bad'>Specimen deceased.</span>"
|
||||
return "Specimen deceased."
|
||||
var/obj/item/organ/heart/gland/GlandTest = locate() in H.internal_organs
|
||||
if(!GlandTest)
|
||||
say("Experimental dissection not detected!")
|
||||
return "<span class='bad'>No glands detected!</span>"
|
||||
if(H.mind != null && (H.voluntary_ghosted || (H.ckey != null)))
|
||||
return "No glands detected!"
|
||||
if(H.mind != null && H.ckey != null)
|
||||
LAZYINITLIST(abductee_minds)
|
||||
LAZYADD(history, H)
|
||||
LAZYADD(abductee_minds, H.mind)
|
||||
@@ -191,22 +150,27 @@
|
||||
point_reward++
|
||||
if(point_reward > 0)
|
||||
open_machine()
|
||||
SendBack(H)
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
send_back(H)
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, TRUE)
|
||||
points += point_reward
|
||||
credits += point_reward
|
||||
return "<span class='good'>Experiment successful! [point_reward] new data-points collected.</span>"
|
||||
return "Experiment successful! [point_reward] new data-points collected."
|
||||
else
|
||||
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 1)
|
||||
return "<span class='bad'>Experiment failed! No replacement organ detected.</span>"
|
||||
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, TRUE)
|
||||
return "Experiment failed! No replacement organ detected."
|
||||
else
|
||||
say("Brain activity nonexistent - disposing sample...")
|
||||
open_machine()
|
||||
SendBack(H)
|
||||
return "<span class='bad'>Specimen braindead - disposed.</span>"
|
||||
send_back(H)
|
||||
return "Specimen braindead - disposed."
|
||||
|
||||
|
||||
/obj/machinery/abductor/experiment/proc/SendBack(mob/living/carbon/human/H)
|
||||
/**
|
||||
* send_back: Sends a mob back to a selected teleport location if safe
|
||||
*
|
||||
* Arguments:
|
||||
* * H The human mob to be sent back
|
||||
*/
|
||||
/obj/machinery/abductor/experiment/proc/send_back(mob/living/carbon/human/H)
|
||||
H.Sleeping(160)
|
||||
H.uncuff()
|
||||
if(console && console.pad && console.pad.teleport_target)
|
||||
@@ -216,7 +180,6 @@
|
||||
SSjob.SendToLateJoin(H, FALSE)
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/abductor/experiment/update_icon_state()
|
||||
if(state_open)
|
||||
icon_state = "experiment-open"
|
||||
|
||||
@@ -13,10 +13,13 @@
|
||||
changeling = null
|
||||
. = ..()
|
||||
|
||||
/datum/cellular_emporium/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.always_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/datum/cellular_emporium/ui_state(mob/user)
|
||||
return GLOB.always_state
|
||||
|
||||
/datum/cellular_emporium/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "CellularEmporium", name, 900, 480, master_ui, state)
|
||||
ui = new(user, src, "CellularEmporium", name)
|
||||
ui.open()
|
||||
|
||||
/datum/cellular_emporium/ui_data(mob/user)
|
||||
|
||||
@@ -25,9 +25,6 @@
|
||||
/datum/clockwork_scripture/ranged_ability/kindle, /datum/clockwork_scripture/ranged_ability/hateful_manacles) //quickbound scripture, accessed by index
|
||||
var/maximum_quickbound = 5 //how many quickbound scriptures we can have
|
||||
|
||||
var/ui_x = 800
|
||||
var/ui_z = 420
|
||||
|
||||
var/obj/structure/destructible/clockwork/trap/linking //If we're linking traps together, which ones we're doing
|
||||
|
||||
/obj/item/clockwork/slab/internal //an internal motor for mobs running scripture
|
||||
@@ -39,6 +36,11 @@
|
||||
speed_multiplier = 0
|
||||
no_cost = TRUE
|
||||
|
||||
/obj/item/clockwork/slab/debug/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
add_servant_of_ratvar(user)
|
||||
return ..()
|
||||
|
||||
/obj/item/clockwork/slab/traitor
|
||||
var/spent = FALSE
|
||||
|
||||
@@ -57,11 +59,6 @@
|
||||
to_chat(user, "<span class='userdanger'>[src] falls dark. It appears you weren't worthy.</span>")
|
||||
return ..()
|
||||
|
||||
/obj/item/clockwork/slab/debug/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
add_servant_of_ratvar(user)
|
||||
return ..()
|
||||
|
||||
/obj/item/clockwork/slab/cyborg //three scriptures, plus a spear and fabricator
|
||||
clockwork_desc = "A divine link to the Celestial Derelict, allowing for limited recital of scripture."
|
||||
quickbound = list(/datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/ranged_ability/linked_vanguard, \
|
||||
@@ -145,14 +142,15 @@
|
||||
|
||||
/obj/item/clockwork/slab/examine(mob/user)
|
||||
. = ..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
if(LAZYLEN(quickbound))
|
||||
for(var/i in 1 to quickbound.len)
|
||||
if(!quickbound[i])
|
||||
continue
|
||||
var/datum/clockwork_scripture/quickbind_slot = quickbound[i]
|
||||
. += "Quickbind button: <span class='[get_component_span(initial(quickbind_slot.primary_component))]'>[initial(quickbind_slot.name)]</span>."
|
||||
. += "Available power: <span class='bold brass'>[DisplayPower(get_clockwork_power())].</span>"
|
||||
if(!is_servant_of_ratvar(user) || !isobserver(user))
|
||||
return
|
||||
if(LAZYLEN(quickbound))
|
||||
for(var/i in 1 to quickbound.len)
|
||||
if(!quickbound[i])
|
||||
continue
|
||||
var/datum/clockwork_scripture/quickbind_slot = quickbound[i]
|
||||
. += "Quickbind button: <span class='[get_component_span(initial(quickbind_slot.primary_component))]'>[initial(quickbind_slot.name)]</span>."
|
||||
. += "Available power: <span class='bold brass'>[DisplayPower(get_clockwork_power())].</span>"
|
||||
|
||||
//Slab actions; Hierophant, Quickbind
|
||||
/obj/item/clockwork/slab/ui_action_click(mob/user, action)
|
||||
@@ -198,12 +196,6 @@
|
||||
ui_interact(user)
|
||||
return TRUE
|
||||
|
||||
/obj/item/clockwork/slab/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "ClockworkSlab", name, ui_x, ui_z, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/item/clockwork/slab/proc/recite_scripture(datum/clockwork_scripture/scripture, mob/living/user)
|
||||
if(!scripture || !user || !user.canUseTopic(src) || (!no_cost && !can_recite_scripture(user)))
|
||||
return FALSE
|
||||
@@ -223,27 +215,62 @@
|
||||
scripture_to_recite.run_scripture()
|
||||
return TRUE
|
||||
|
||||
/*
|
||||
* Gets text for a certain section. "Default" is used for when you first open Recollection.
|
||||
* Current sections (make sure to update this if you add one:
|
||||
* Basics
|
||||
* Terminology
|
||||
* Components
|
||||
* Scripture
|
||||
* Power
|
||||
* Conversion
|
||||
* * what - What section?
|
||||
*/
|
||||
/obj/item/clockwork/slab/proc/get_recollection(what) //Now DMDOC compliant!*
|
||||
. = list()
|
||||
switch(what) //need someone to rewrite info for this.
|
||||
if("Default")
|
||||
.["title"] = "Default"
|
||||
.["info"] = "Hello servant! Currently these categories dosen't work!"
|
||||
/*
|
||||
if("Basics")
|
||||
.["title"] = "Basics"
|
||||
.["info"] = "# MARKDOWN WITH HTML?"
|
||||
if("Terminology")
|
||||
.["title"] = "Terminology"
|
||||
.["info"] = "# MARKDOWN WITH HTML?"
|
||||
if("Components")
|
||||
.["title"] = "Default"
|
||||
.["info"] = "# MARKDOWN WITH HTML?"
|
||||
if("Scripture")
|
||||
.["title"] = "Default"
|
||||
.["info"] = "# MARKDOWN WITH HTML?"
|
||||
if("Power")
|
||||
.["title"] = "Power"
|
||||
.["info"] = "# MARKDOWN WITH HTML?"
|
||||
if("Conversion")
|
||||
.["title"] = "Conversion"
|
||||
.["info"] = "# MARKDOWN WITH HTML?"
|
||||
*/
|
||||
else
|
||||
return null //error text handled tgui side. should not cause BSOD
|
||||
|
||||
//Gets text for a certain section. "Default" is used for when you first open Recollection.
|
||||
//Current sections (make sure to update this if you add one:
|
||||
//- Basics
|
||||
//- Terminology
|
||||
//- Components
|
||||
//- Scripture
|
||||
//- Power
|
||||
//- Conversion
|
||||
/obj/item/clockwork/slab/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "ClockworkSlab", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/clockwork/slab/ui_data(mob/user) //we display a lot of data via TGUI
|
||||
. = list()
|
||||
.["recollection"] = recollecting
|
||||
.["power"] = DisplayPower(get_clockwork_power())
|
||||
.["power_unformatted"] = get_clockwork_power()
|
||||
// .["rec_text"] = recollection() handled TGUI side
|
||||
.["HONOR_RATVAR"] = GLOB.ratvar_awakens
|
||||
.["scripture"] = list()
|
||||
for(var/s in GLOB.all_scripture)
|
||||
for(var/s in GLOB.all_scripture) //don't block this, even when ratvar spawns for roundend griff.
|
||||
var/datum/clockwork_scripture/S = GLOB.all_scripture[s]
|
||||
if(S.tier == SCRIPTURE_PERIPHERAL) //yes, tiers are the tabs.
|
||||
if(S.tier == SCRIPTURE_PERIPHERAL) // This tier is skiped because this contains basetype stuff
|
||||
continue
|
||||
|
||||
var/list/data = list()
|
||||
@@ -253,7 +280,7 @@
|
||||
data["required"] = "([DisplayPower(S.power_cost)][S.special_power_text ? "+ [replacetext(S.special_power_text, "POWERCOST", "[DisplayPower(S.special_power_cost)]")]" : ""])"
|
||||
data["required_unformatted"] = S.power_cost
|
||||
data["type"] = "[S.type]"
|
||||
data["quickbind"] = S.quickbind //this is if it cant quickbind
|
||||
data["quickbind"] = S.quickbind //this is if it cant quickbind (bool)
|
||||
data["fontcolor"] = get_component_color_bright(S.primary_component)
|
||||
data["important"] = S.important //italic!
|
||||
|
||||
@@ -265,10 +292,8 @@
|
||||
|
||||
.["rec_binds"] = list()
|
||||
for(var/i in 1 to maximum_quickbound)
|
||||
if(GLOB.ratvar_awakens)
|
||||
return
|
||||
if(LAZYLEN(quickbound) < i || !quickbound[i])
|
||||
.["rec_binds"] += list(list())
|
||||
.["rec_binds"] += list(list()) //a blank json.
|
||||
else
|
||||
var/datum/clockwork_scripture/quickbind_slot = quickbound[i]
|
||||
.["rec_binds"] += list(list(
|
||||
@@ -280,7 +305,11 @@
|
||||
|
||||
/obj/item/clockwork/slab/ui_static_data(mob/user)
|
||||
. = list()
|
||||
.["tier_infos"] = list()
|
||||
.["tier_infos"] = list() //HEY!! WHEN ADDING NEW TIER, ADD IT HERE
|
||||
.["tier_infos"][SCRIPTURE_PERIPHERAL] = list(
|
||||
"requirement" = "Breaking the code DM side. Report to coggerbus if this appears!!",
|
||||
"ready" = FALSE //just in case. Should NOT exist at all
|
||||
)
|
||||
.["tier_infos"][SCRIPTURE_DRIVER] = list(
|
||||
"requirement" = "None, this is already unlocked",
|
||||
"ready" = TRUE //to bold it on JS side, and to say "These scriptures are permanently unlocked."
|
||||
@@ -297,10 +326,10 @@
|
||||
"requirement" = "Unlock powerful equipment and structures by converting five servants or if [DisplayPower(JUDGEMENT_UNLOCK_THRESHOLD)] of power is reached..",
|
||||
"ready" = SSticker.scripture_states[SCRIPTURE_JUDGEMENT]
|
||||
)
|
||||
|
||||
// .["selected"] = selected_scripture
|
||||
generate_all_scripture()
|
||||
.["recollection_categories"] = GLOB.ratvar_awakens ? list() : list(
|
||||
.["recollection_categories"] = list()
|
||||
if(GLOB.ratvar_awakens)
|
||||
return
|
||||
.["recollection_categories"] = list(
|
||||
list("name" = "Getting Started", "desc" = "First-time servant? Read this first."),
|
||||
list("name" = "Basics", "desc" = "A primer on how to play as a servant."),
|
||||
list("name" = "Terminology", "desc" = "Common acronyms, words, and terms."),
|
||||
@@ -309,8 +338,9 @@
|
||||
list("name" = "Power", "desc" = "The power system that certain objects use to function."),
|
||||
list("name" = "Conversion", "desc" = "Converting the crew, cyborgs, and very walls to your cause.")
|
||||
)
|
||||
// .["rec_section"]["title"] //this is here if ever we decided to return these back.
|
||||
// .["rec_section"]["info"]// wall of info for the thing
|
||||
.["rec_section"] = get_recollection(recollection_category)
|
||||
generate_all_scripture()
|
||||
//needs a new place to live, preferably when clockcult unlocks/downgrades a tier. Smart enough to earlyreturn.
|
||||
|
||||
/obj/item/clockwork/slab/ui_act(action, params)
|
||||
switch(action)
|
||||
@@ -369,4 +399,4 @@
|
||||
Q.button_icon_state = quickbind_slot.name
|
||||
Q.UpdateButtonIcon()
|
||||
if(isliving(loc))
|
||||
Q.Grant(loc)
|
||||
Q.Grant(loc)
|
||||
|
||||
@@ -7,17 +7,13 @@
|
||||
density = TRUE
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
ui_x = 350
|
||||
ui_y = 442
|
||||
|
||||
var/timer_set = 90
|
||||
var/default_timer_set = 90
|
||||
var/minimum_timer_set = 90
|
||||
var/maximum_timer_set = 3600
|
||||
ui_style = "nanotrasen"
|
||||
|
||||
var/numeric_input = ""
|
||||
var/ui_mode = NUKEUI_AWAIT_DISK
|
||||
|
||||
var/timing = FALSE
|
||||
var/exploding = FALSE
|
||||
var/exploded = FALSE
|
||||
@@ -34,7 +30,6 @@
|
||||
var/interior = ""
|
||||
var/proper_bomb = TRUE //Please
|
||||
var/obj/effect/countdown/nuclearbomb/countdown
|
||||
var/nuclear_cooldown //used to stop global spam.
|
||||
|
||||
/obj/machinery/nuclearbomb/Initialize()
|
||||
. = ..()
|
||||
@@ -77,15 +72,16 @@
|
||||
/obj/machinery/nuclearbomb/syndicate/get_cinematic_type(off_station)
|
||||
var/datum/game_mode/nuclear/NM = SSticker.mode
|
||||
switch(off_station)
|
||||
if(FALSE)
|
||||
if(0)
|
||||
if(istype(NM) && !NM.nuke_team.syndies_escaped())
|
||||
return CINEMATIC_ANNIHILATION
|
||||
else
|
||||
return CINEMATIC_NUKE_WIN
|
||||
if(NUKE_MISS_STATION)
|
||||
if(1)
|
||||
return CINEMATIC_NUKE_MISS
|
||||
else
|
||||
if(2)
|
||||
return CINEMATIC_NUKE_FAR
|
||||
return CINEMATIC_NUKE_FAR
|
||||
|
||||
/obj/machinery/nuclearbomb/proc/disk_check(obj/item/disk/nuclear/D)
|
||||
if(D.fake)
|
||||
@@ -194,7 +190,7 @@
|
||||
icon_state = "nuclearbomb_exploding"
|
||||
|
||||
/obj/machinery/nuclearbomb/update_overlays()
|
||||
. = ..()
|
||||
. += ..()
|
||||
update_icon_interior()
|
||||
update_icon_lights()
|
||||
|
||||
@@ -236,7 +232,7 @@
|
||||
explode()
|
||||
else
|
||||
var/volume = (get_time_left() <= 20 ? 30 : 5)
|
||||
playsound(loc, 'sound/items/timer.ogg', volume, 0)
|
||||
playsound(loc, 'sound/items/timer.ogg', volume, FALSE)
|
||||
|
||||
/obj/machinery/nuclearbomb/proc/update_ui_mode()
|
||||
if(exploded)
|
||||
@@ -261,17 +257,18 @@
|
||||
|
||||
ui_mode = NUKEUI_AWAIT_TIMER
|
||||
|
||||
|
||||
/obj/machinery/nuclearbomb/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state=GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/nuclearbomb/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "NuclearBomb", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "NuclearBomb", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/nuclearbomb/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["disk_present"] = auth
|
||||
|
||||
var/hidden_code = (ui_mode == NUKEUI_AWAIT_CODE && numeric_input != "ERROR")
|
||||
|
||||
var/current_code = ""
|
||||
if(hidden_code)
|
||||
while(length(current_code) < length(numeric_input))
|
||||
@@ -388,14 +385,13 @@
|
||||
if("anchor")
|
||||
if(auth && yes_code)
|
||||
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
|
||||
set_anchor(usr)
|
||||
set_anchor()
|
||||
else
|
||||
playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE)
|
||||
|
||||
|
||||
/obj/machinery/nuclearbomb/proc/set_anchor(mob/user)
|
||||
if((istype(get_area(src), /area/space) || isinspace()) && !anchored)
|
||||
to_chat(user, "<span class='warning'>This is not a suitable platform for anchoring [src]!</span>")
|
||||
/obj/machinery/nuclearbomb/proc/set_anchor()
|
||||
if(isinspace() && !anchored)
|
||||
to_chat(usr, "<span class='warning'>There is nothing to anchor to!</span>")
|
||||
else
|
||||
anchored = !anchored
|
||||
|
||||
@@ -416,9 +412,6 @@
|
||||
if(safety)
|
||||
to_chat(usr, "<span class='danger'>The safety is still on.</span>")
|
||||
return
|
||||
if(!timing && nuclear_cooldown > world.time)
|
||||
to_chat(usr, "<span class='danger'>[src]'s timer protocols are currently on cooldown, please stand by.</span>")
|
||||
return
|
||||
timing = !timing
|
||||
if(timing)
|
||||
previous_level = NUM2SECLEVEL(GLOB.security_level)
|
||||
@@ -427,12 +420,6 @@
|
||||
S.switch_mode_to(TRACK_INFILTRATOR)
|
||||
countdown.start()
|
||||
set_security_level("delta")
|
||||
nuclear_cooldown = world.time + 15 SECONDS
|
||||
|
||||
if(GLOB.war_declared)
|
||||
var/area/A = get_area(src)
|
||||
priority_announce("Alert: Unexpected increase in radiation levels near [A.name] ([src.x],[src.y],[src.z]). Please send an authorized radiation specialist to investigate.", "Sensory Nuclear Indexer Telemetry Calculation Helper")
|
||||
|
||||
else
|
||||
detonation_timer = null
|
||||
set_security_level(previous_level)
|
||||
@@ -483,12 +470,19 @@
|
||||
|
||||
var/off_station = FALSE
|
||||
var/turf/bomb_location = get_turf(src)
|
||||
if(!bomb_location || !is_station_level(bomb_location.z))
|
||||
off_station = NUKE_MISS_STATION
|
||||
var/area/A = get_area(bomb_location)
|
||||
|
||||
if(bomb_location && is_station_level(bomb_location.z))
|
||||
if(istype(A, /area/space))
|
||||
off_station = NUKE_NEAR_MISS
|
||||
if((bomb_location.x < (128-NUKERANGE)) || (bomb_location.x > (128+NUKERANGE)) || (bomb_location.y < (128-NUKERANGE)) || (bomb_location.y > (128+NUKERANGE)))
|
||||
off_station = NUKE_NEAR_MISS
|
||||
else if(bomb_location.onSyndieBase())
|
||||
off_station = NUKE_SYNDICATE_BASE
|
||||
else
|
||||
off_station = NUKE_MISS_STATION
|
||||
|
||||
if(!off_station)
|
||||
if(off_station < 2) //can only launch when nuke is on syndie base or space
|
||||
SSshuttle.registerHostileEnvironment(src)
|
||||
SSshuttle.lockdown = TRUE
|
||||
|
||||
@@ -502,13 +496,13 @@
|
||||
INVOKE_ASYNC(GLOBAL_PROC,.proc/KillEveryoneOnZLevel, z)
|
||||
|
||||
/obj/machinery/nuclearbomb/proc/get_cinematic_type(off_station)
|
||||
if(!off_station)
|
||||
if(off_station < 2)
|
||||
return CINEMATIC_SELFDESTRUCT
|
||||
else
|
||||
return CINEMATIC_SELFDESTRUCT_MISS
|
||||
|
||||
/obj/machinery/nuclearbomb/beer
|
||||
name = "Nanotrasen-brand nuclear fission explosive"
|
||||
name = "\improper Nanotrasen-brand nuclear fission explosive"
|
||||
desc = "One of the more successful achievements of the Nanotrasen Corporate Warfare Division, their nuclear fission explosives are renowned for being cheap to produce and devastatingly effective. Signs explain that though this particular device has been decommissioned, every Nanotrasen station is equipped with an equivalent one, just in case. All Captains carefully guard the disk needed to detonate them - at least, the sign says they do. There seems to be a tap on the back."
|
||||
proper_bomb = FALSE
|
||||
var/obj/structure/reagent_dispensers/beerkeg/keg
|
||||
@@ -521,9 +515,9 @@
|
||||
/obj/machinery/nuclearbomb/beer/examine(mob/user)
|
||||
. = ..()
|
||||
if(keg.reagents.total_volume)
|
||||
. += "<span class='notice'>It has [keg.reagents.total_volume] unit\s left.</span>"
|
||||
to_chat(user, "<span class='notice'>It has [keg.reagents.total_volume] unit\s left.</span>")
|
||||
else
|
||||
. += "<span class='danger'>It's empty.</span>"
|
||||
to_chat(user, "<span class='danger'>It's empty.</span>")
|
||||
|
||||
/obj/machinery/nuclearbomb/beer/attackby(obj/item/W, mob/user, params)
|
||||
if(W.is_refillable())
|
||||
@@ -535,6 +529,8 @@
|
||||
return ..()
|
||||
|
||||
/obj/machinery/nuclearbomb/beer/actually_explode()
|
||||
//Unblock roundend, we're not actually exploding.
|
||||
SSticker.roundend_check_paused = FALSE
|
||||
var/turf/bomb_location = get_turf(src)
|
||||
if(!bomb_location)
|
||||
disarm()
|
||||
@@ -583,7 +579,7 @@
|
||||
This is here to make the tiles around the station mininuke change when it's armed.
|
||||
*/
|
||||
|
||||
/obj/machinery/nuclearbomb/selfdestruct/set_anchor(mob/user)
|
||||
/obj/machinery/nuclearbomb/selfdestruct/set_anchor()
|
||||
return
|
||||
|
||||
/obj/machinery/nuclearbomb/selfdestruct/set_active()
|
||||
@@ -641,18 +637,19 @@ This is here to make the tiles around the station mininuke change when it's arme
|
||||
if(newturf && lastlocation == newturf)
|
||||
if(last_disk_move < world.time - 5000 && prob((world.time - 5000 - last_disk_move)*0.0001))
|
||||
var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control
|
||||
if(istype(loneop))
|
||||
if(istype(loneop) && loneop.occurrences < loneop.max_occurrences)
|
||||
loneop.weight += 1
|
||||
if(loneop.weight % 5 == 0)
|
||||
if(loneop.weight % 5 == 0 && SSticker.totalPlayers > 1) //players count now
|
||||
message_admins("[src] is stationary in [ADMIN_VERBOSEJMP(newturf)]. The weight of Lone Operative is now [loneop.weight].")
|
||||
log_game("[src] is stationary for too long in [loc_name(newturf)], and has increased the weight of the Lone Operative event to [loneop.weight].")
|
||||
|
||||
else
|
||||
lastlocation = newturf
|
||||
last_disk_move = world.time
|
||||
var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control
|
||||
if(istype(loneop) && prob(loneop.weight))
|
||||
if(istype(loneop) && loneop.occurrences < loneop.max_occurrences && prob(loneop.weight))
|
||||
loneop.weight = max(loneop.weight - 1, 0)
|
||||
if(loneop.weight % 5 == 0)
|
||||
if(loneop.weight % 5 == 0 && SSticker.totalPlayers > 1)
|
||||
message_admins("[src] is on the move (currently in [ADMIN_VERBOSEJMP(newturf)]). The weight of Lone Operative is now [loneop.weight].")
|
||||
log_game("[src] being on the move has reduced the weight of the Lone Operative event to [loneop.weight].")
|
||||
|
||||
@@ -661,9 +658,19 @@ This is here to make the tiles around the station mininuke change when it's arme
|
||||
if(!fake)
|
||||
return
|
||||
|
||||
if(isobserver(user) || HAS_TRAIT(user, TRAIT_DISK_VERIFIER) || (user.mind && HAS_TRAIT(user.mind, TRAIT_DISK_VERIFIER)))
|
||||
if(isobserver(user) || HAS_TRAIT(user.mind, TRAIT_DISK_VERIFIER))
|
||||
. += "<span class='warning'>The serial numbers on [src] are incorrect.</span>"
|
||||
|
||||
/*
|
||||
* You can't accidentally eat the nuke disk, bro
|
||||
*/
|
||||
/*
|
||||
/obj/item/disk/nuclear/on_accidental_consumption(mob/living/carbon/M, mob/living/carbon/user, obj/item/source_item, discover_after = TRUE)
|
||||
M.visible_message("<span class='warning'>[M] looks like [M.p_theyve()] just bitten into something important.</span>", \
|
||||
"<span class='warning'>Wait, is this the nuke disk?</span>")
|
||||
|
||||
return discover_after
|
||||
*/
|
||||
/obj/item/disk/nuclear/attackby(obj/item/I, mob/living/user, params)
|
||||
if(istype(I, /obj/item/claymore/highlander) && !fake)
|
||||
var/obj/item/claymore/highlander/H = I
|
||||
@@ -686,7 +693,7 @@ This is here to make the tiles around the station mininuke change when it's arme
|
||||
|
||||
/obj/item/disk/nuclear/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is going delta! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
playsound(src, 'sound/machines/alarm.ogg', 50, -1, 1)
|
||||
playsound(src, 'sound/machines/alarm.ogg', 50, -1, TRUE)
|
||||
for(var/i in 1 to 100)
|
||||
addtimer(CALLBACK(user, /atom/proc/add_atom_colour, (i % 2)? "#00FF00" : "#FF0000", ADMIN_COLOUR_PRIORITY), i)
|
||||
addtimer(CALLBACK(src, .proc/manual_suicide, user), 101)
|
||||
@@ -694,7 +701,7 @@ This is here to make the tiles around the station mininuke change when it's arme
|
||||
|
||||
/obj/item/disk/nuclear/proc/manual_suicide(mob/living/user)
|
||||
user.remove_atom_colour(ADMIN_COLOUR_PRIORITY)
|
||||
user.visible_message("<span class='suicide'>[user] was destroyed by the nuclear blast!</span>")
|
||||
user.visible_message("<span class='suicide'>[user] is destroyed by the nuclear blast!</span>")
|
||||
user.adjustOxyLoss(200)
|
||||
user.death(0)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user