@@ -9,8 +9,6 @@
|
||||
icon_state = "bus"
|
||||
density = TRUE
|
||||
circuit = /obj/item/circuitboard/machine/ntnet_relay
|
||||
ui_x = 400
|
||||
ui_y = 300
|
||||
|
||||
var/datum/ntnet/NTNet = null // This is mostly for backwards reference and to allow varedit modifications from ingame.
|
||||
var/enabled = 1 // Set to 0 if the relay was turned off
|
||||
@@ -64,15 +62,12 @@
|
||||
SSnetworks.station_network.add_log("Quantum relay switched from overload recovery mode to normal operation mode.")
|
||||
..()
|
||||
|
||||
/obj/machinery/ntnet_relay/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, 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/ntnet_relay/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "NtnetRelay", "NTNet Quantum Relay", ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "NtnetRelay")
|
||||
ui.open()
|
||||
|
||||
|
||||
/obj/machinery/ntnet_relay/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["enabled"] = enabled
|
||||
@@ -81,7 +76,6 @@
|
||||
data["dos_crashed"] = dos_failure
|
||||
return data
|
||||
|
||||
|
||||
/obj/machinery/ntnet_relay/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
@@ -78,10 +78,15 @@
|
||||
close_machine(target)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/vr_sleeper/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_contained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/vr_sleeper/ui_state(mob/user)
|
||||
if(user == occupant)
|
||||
return GLOB.contained_state
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/vr_sleeper/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "VrSleeper", "VR Sleeper", 475, 340, master_ui, state)
|
||||
ui = new(user, src, "VrSleeper", "VR Sleeper")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/vr_sleeper/ui_act(action, params)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
icon_state = "infrared"
|
||||
custom_materials = list(/datum/material/iron=1000, /datum/material/glass=500)
|
||||
is_position_sensitive = TRUE
|
||||
var/ui_x = 225
|
||||
var/ui_y = 110
|
||||
var/on = FALSE
|
||||
var/visible = FALSE
|
||||
var/maxlength = 8
|
||||
@@ -134,7 +132,7 @@
|
||||
. = ..()
|
||||
setDir(t)
|
||||
|
||||
/obj/item/assembly/infra/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, gentle = FALSE)
|
||||
/obj/item/assembly/infra/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, gentle = FALSE, quickstart = TRUE)
|
||||
. = ..()
|
||||
olddir = dir
|
||||
|
||||
@@ -186,11 +184,10 @@
|
||||
return ..()
|
||||
return UI_CLOSE
|
||||
|
||||
/obj/item/assembly/infra/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/assembly/infra/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "InfraredEmitter", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "InfraredEmitter", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/assembly/infra/ui_data(mob/user)
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
icon_state = "prox"
|
||||
custom_materials = list(/datum/material/iron=800, /datum/material/glass=200)
|
||||
attachable = TRUE
|
||||
var/ui_x = 250
|
||||
var/ui_y = 185
|
||||
var/scanning = FALSE
|
||||
var/timing = FALSE
|
||||
var/time = 10
|
||||
@@ -113,11 +111,10 @@
|
||||
return ..()
|
||||
return UI_CLOSE
|
||||
|
||||
/obj/item/assembly/prox_sensor/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/assembly/prox_sensor/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "ProximitySensor", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "ProximitySensor", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/assembly/prox_sensor/ui_data(mob/user)
|
||||
|
||||
@@ -8,33 +8,46 @@
|
||||
custom_materials = list(/datum/material/iron=400, /datum/material/glass=120)
|
||||
wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE
|
||||
attachable = TRUE
|
||||
var/ui_x = 280
|
||||
var/ui_y = 132
|
||||
|
||||
var/code = DEFAULT_SIGNALER_CODE
|
||||
var/frequency = FREQ_SIGNALER
|
||||
var/datum/radio_frequency/radio_connection
|
||||
var/suicider = null
|
||||
///Holds the mind that commited suicide.
|
||||
var/datum/mind/suicider
|
||||
///Holds a reference string to the mob, decides how much of a gamer you are.
|
||||
var/suicide_mob
|
||||
var/hearing_range = 1
|
||||
|
||||
/obj/item/assembly/signaler/suicide_act(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user] eats \the [src]! If it is signaled, [user.p_they()] will die!</span>")
|
||||
playsound(src, 'sound/items/eatfood.ogg', 50, TRUE)
|
||||
user.transferItemToLoc(src, user, TRUE)
|
||||
suicider = user
|
||||
moveToNullspace()
|
||||
suicider = user.mind
|
||||
suicide_mob = REF(user)
|
||||
return MANUAL_SUICIDE
|
||||
|
||||
/obj/item/assembly/signaler/proc/manual_suicide(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user]'s \the [src] receives a signal, killing [user.p_them()] instantly!</span>")
|
||||
/obj/item/assembly/signaler/proc/manual_suicide(datum/mind/suicidee)
|
||||
var/mob/living/user = suicidee.current
|
||||
if(!istype(user))
|
||||
return
|
||||
if(suicide_mob == REF(user))
|
||||
user.visible_message("<span class='suicide'>[user]'s [src] receives a signal, killing [user.p_them()] instantly!</span>")
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user]'s [src] receives a signal and [user.p_they()] die[user.p_s()] like a gamer!</span>")
|
||||
user.adjustOxyLoss(200)//it sends an electrical pulse to their heart, killing them. or something.
|
||||
user.death(0)
|
||||
//user.set_suicide(TRUE)
|
||||
user.suicide_log()
|
||||
playsound(user, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/assembly/signaler/Initialize()
|
||||
. = ..()
|
||||
set_frequency(frequency)
|
||||
|
||||
|
||||
/obj/item/assembly/signaler/Destroy()
|
||||
SSradio.remove_object(src,frequency)
|
||||
suicider = null
|
||||
. = ..()
|
||||
|
||||
/obj/item/assembly/signaler/activate()
|
||||
@@ -53,11 +66,10 @@
|
||||
return ..()
|
||||
return UI_CLOSE
|
||||
|
||||
/obj/item/assembly/signaler/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/assembly/signaler/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Signaler", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "Signaler", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/assembly/signaler/ui_data(mob/user)
|
||||
@@ -66,12 +78,12 @@
|
||||
data["code"] = code
|
||||
data["minFrequency"] = MIN_FREE_FREQ
|
||||
data["maxFrequency"] = MAX_FREE_FREQ
|
||||
|
||||
return data
|
||||
|
||||
/obj/item/assembly/signaler/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("signal")
|
||||
INVOKE_ASYNC(src, .proc/signal)
|
||||
@@ -115,9 +127,6 @@
|
||||
if(usr)
|
||||
GLOB.lastsignalers.Add("[time] <B>:</B> [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) <B>:</B> [format_frequency(frequency)]/[code]")
|
||||
|
||||
|
||||
return
|
||||
|
||||
/obj/item/assembly/signaler/receive_signal(datum/signal/signal)
|
||||
. = FALSE
|
||||
if(!signal)
|
||||
@@ -128,6 +137,7 @@
|
||||
return
|
||||
if(suicider)
|
||||
manual_suicide(suicider)
|
||||
return
|
||||
pulse(TRUE)
|
||||
audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*", null, hearing_range)
|
||||
for(var/CHM in get_hearers_in_view(hearing_range, src))
|
||||
@@ -136,7 +146,6 @@
|
||||
LM.playsound_local(get_turf(src), 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/assembly/signaler/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
@@ -165,69 +174,8 @@
|
||||
return
|
||||
return ..(signal)
|
||||
|
||||
// Embedded signaller used in anomalies.
|
||||
/obj/item/assembly/signaler/anomaly
|
||||
name = "anomaly core"
|
||||
desc = "The neutralized core of an anomaly. It'd probably be valuable for research."
|
||||
icon_state = "anomaly core"
|
||||
item_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
resistance_flags = FIRE_PROOF
|
||||
var/anomaly_type = /obj/effect/anomaly
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/receive_signal(datum/signal/signal)
|
||||
if(!signal)
|
||||
return FALSE
|
||||
if(signal.data["code"] != code)
|
||||
return FALSE
|
||||
if(suicider)
|
||||
manual_suicide(suicider)
|
||||
for(var/obj/effect/anomaly/A in get_turf(src))
|
||||
A.anomalyNeutralize()
|
||||
return TRUE
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/manual_suicide(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user]'s [src] is reacting to the radio signal, warping [user.p_their()] body!</span>")
|
||||
user.suiciding = TRUE
|
||||
user.suicide_log()
|
||||
user.gib()
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/attackby(obj/item/I, mob/user, params)
|
||||
if(I.tool_behaviour == TOOL_ANALYZER)
|
||||
to_chat(user, "<span class='notice'>Analyzing... [src]'s stabilized field is fluctuating along frequency [format_frequency(frequency)], code [code].</span>")
|
||||
..()
|
||||
|
||||
//Anomaly cores
|
||||
/obj/item/assembly/signaler/anomaly/pyro
|
||||
name = "\improper pyroclastic anomaly core"
|
||||
desc = "The neutralized core of a pyroclastic anomaly. It feels warm to the touch. It'd probably be valuable for research."
|
||||
icon_state = "pyro core"
|
||||
anomaly_type = /obj/effect/anomaly/pyro
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/grav
|
||||
name = "\improper gravitational anomaly core"
|
||||
desc = "The neutralized core of a gravitational anomaly. It feels much heavier than it looks. It'd probably be valuable for research."
|
||||
icon_state = "grav core"
|
||||
anomaly_type = /obj/effect/anomaly/grav
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/flux
|
||||
name = "\improper flux anomaly core"
|
||||
desc = "The neutralized core of a flux anomaly. Touching it makes your skin tingle. It'd probably be valuable for research."
|
||||
icon_state = "flux core"
|
||||
anomaly_type = /obj/effect/anomaly/flux
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/bluespace
|
||||
name = "\improper bluespace anomaly core"
|
||||
desc = "The neutralized core of a bluespace anomaly. It keeps phasing in and out of view. It'd probably be valuable for research."
|
||||
icon_state = "anomaly core"
|
||||
anomaly_type = /obj/effect/anomaly/bluespace
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/vortex
|
||||
name = "\improper vortex anomaly core"
|
||||
desc = "The neutralized core of a vortex anomaly. It won't sit still, as if some invisible force is acting on it. It'd probably be valuable for research."
|
||||
icon_state = "vortex core"
|
||||
anomaly_type = /obj/effect/anomaly/bhole
|
||||
/obj/item/assembly/signaler/anomaly/attack_self()
|
||||
return
|
||||
|
||||
/obj/item/assembly/signaler/cyborg
|
||||
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
icon_state = "timer"
|
||||
custom_materials = list(/datum/material/iron=500, /datum/material/glass=50)
|
||||
attachable = TRUE
|
||||
var/ui_x = 275
|
||||
var/ui_y = 115
|
||||
|
||||
var/timing = FALSE
|
||||
var/time = 5
|
||||
var/saved_time = 5
|
||||
@@ -88,11 +87,10 @@
|
||||
return ..()
|
||||
return UI_CLOSE
|
||||
|
||||
/obj/item/assembly/timer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/assembly/timer/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Timer", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "Timer", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/assembly/timer/ui_data(mob/user)
|
||||
|
||||
@@ -94,6 +94,13 @@ Note: If your code uses output() with assets you will need to call asset_flush o
|
||||
var/list/stacktrace = gib_stack_trace()
|
||||
log_asset("WARNING: dupe asset added to the asset cache: [asset_name] existing asset md5: [OACI.md5] new asset md5:[ACI.md5]\n[stacktrace.Join("\n")]")
|
||||
SSassets.cache[asset_name] = ACI
|
||||
return ACI
|
||||
|
||||
/// Returns the url of the asset, currently this is just its name, here to allow further work cdn'ing assets.
|
||||
/// Can be given an asset as well, this is just a work around for buggy edge cases where two assets may have the same name, doesn't matter now, but it will when the cdn comes.
|
||||
/proc/get_asset_url(asset_name, asset = null)
|
||||
var/datum/asset_cache_item/ACI = SSassets.cache[asset_name]
|
||||
return ACI?.url
|
||||
|
||||
//Generated names do not include file extention.
|
||||
//Used mainly for code that deals with assets in a generic way
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
**/
|
||||
/datum/asset_cache_item
|
||||
var/name
|
||||
var/url
|
||||
var/md5
|
||||
var/resource
|
||||
|
||||
@@ -18,4 +19,5 @@
|
||||
CRASH("invalid asset sent to asset cache")
|
||||
debug_world_log("asset cache unexpected success of second fcopy_rsc")
|
||||
src.name = name
|
||||
url = name
|
||||
resource = file
|
||||
|
||||
@@ -16,6 +16,9 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
GLOB.asset_datums[type] = src
|
||||
register()
|
||||
|
||||
/datum/asset/proc/get_url_mappings()
|
||||
return list()
|
||||
|
||||
/datum/asset/proc/register()
|
||||
return
|
||||
|
||||
@@ -30,11 +33,19 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
|
||||
/datum/asset/simple/register()
|
||||
for(var/asset_name in assets)
|
||||
register_asset(asset_name, assets[asset_name])
|
||||
assets[asset_name] = register_asset(asset_name, assets[asset_name])
|
||||
|
||||
/datum/asset/simple/send(client)
|
||||
. = send_asset_list(client, assets)
|
||||
|
||||
/datum/asset/simple/get_url_mappings()
|
||||
. = list()
|
||||
for (var/asset_name in assets)
|
||||
var/datum/asset_cache_item/ACI = assets[asset_name]
|
||||
if (!ACI)
|
||||
continue
|
||||
.[asset_name] = ACI.url
|
||||
|
||||
|
||||
// For registering or sending multiple others at once
|
||||
/datum/asset/group
|
||||
@@ -50,6 +61,11 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
var/datum/asset/A = get_asset_datum(type)
|
||||
. = A.send(C) || .
|
||||
|
||||
/datum/asset/group/get_url_mappings()
|
||||
. = list()
|
||||
for(var/type in children)
|
||||
var/datum/asset/A = get_asset_datum(type)
|
||||
. += A.get_url_mappings()
|
||||
|
||||
// spritesheet implementation - coalesces various icons into a single .png file
|
||||
// and uses CSS to select icons out of that file - saves on transferring some
|
||||
@@ -70,7 +86,9 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
if (!name)
|
||||
CRASH("spritesheet [type] cannot register without a name")
|
||||
ensure_stripped()
|
||||
|
||||
for(var/size_id in sizes)
|
||||
var/size = sizes[size_id]
|
||||
register_asset("[name]_[size_id].png", size[SPRSZ_STRIPPED])
|
||||
var/res_name = "spritesheet_[name].css"
|
||||
var/fname = "data/spritesheets/[res_name]"
|
||||
fdel(fname)
|
||||
@@ -78,10 +96,6 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
register_asset(res_name, fcopy_rsc(fname))
|
||||
fdel(fname)
|
||||
|
||||
for(var/size_id in sizes)
|
||||
var/size = sizes[size_id]
|
||||
register_asset("[name]_[size_id].png", size[SPRSZ_STRIPPED])
|
||||
|
||||
/datum/asset/spritesheet/send(client/C)
|
||||
if (!name)
|
||||
return
|
||||
@@ -90,6 +104,15 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
all += "[name]_[size_id].png"
|
||||
. = send_asset_list(C, all)
|
||||
|
||||
/datum/asset/spritesheet/get_url_mappings()
|
||||
if (!name)
|
||||
return
|
||||
. = list("spritesheet_[name].css" = get_asset_url("spritesheet_[name].css"))
|
||||
for(var/size_id in sizes)
|
||||
.["[name]_[size_id].png"] = get_asset_url("[name]_[size_id].png")
|
||||
|
||||
|
||||
|
||||
/datum/asset/spritesheet/proc/ensure_stripped(sizes_to_strip = sizes)
|
||||
for(var/size_id in sizes_to_strip)
|
||||
var/size = sizes[size_id]
|
||||
@@ -111,7 +134,7 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
for (var/size_id in sizes)
|
||||
var/size = sizes[size_id]
|
||||
var/icon/tiny = size[SPRSZ_ICON]
|
||||
out += ".[name][size_id]{display:inline-block;width:[tiny.Width()]px;height:[tiny.Height()]px;background:url('[name]_[size_id].png') no-repeat;}"
|
||||
out += ".[name][size_id]{display:inline-block;width:[tiny.Width()]px;height:[tiny.Height()]px;background:url('[get_asset_url("[name]_[size_id].png")]') no-repeat;}"
|
||||
|
||||
for (var/sprite_id in sprites)
|
||||
var/sprite = sprites[sprite_id]
|
||||
@@ -162,7 +185,10 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
Insert("[prefix][prefix2][icon_state_name]", I, icon_state=icon_state_name, dir=direction)
|
||||
|
||||
/datum/asset/spritesheet/proc/css_tag()
|
||||
return {"<link rel="stylesheet" href="spritesheet_[name].css" />"}
|
||||
return {"<link rel="stylesheet" href="[css_filename()]" />"}
|
||||
|
||||
/datum/asset/spritesheet/proc/css_filename()
|
||||
return get_asset_url("spritesheet_[name].css")
|
||||
|
||||
/datum/asset/spritesheet/proc/icon_tag(sprite_name)
|
||||
var/sprite = sprites[sprite_name]
|
||||
|
||||
@@ -6,12 +6,6 @@
|
||||
"tgui.bundle.css" = 'tgui/packages/tgui/public/tgui.bundle.css',
|
||||
)
|
||||
|
||||
/datum/asset/group/tgui
|
||||
children = list(
|
||||
/datum/asset/simple/tgui,
|
||||
/datum/asset/simple/fontawesome
|
||||
)
|
||||
|
||||
/datum/asset/simple/headers
|
||||
assets = list(
|
||||
"alarm_green.gif" = 'icons/program_icons/alarm_green.gif',
|
||||
@@ -78,6 +72,7 @@
|
||||
"refresh" = 'icons/pda_icons/pda_refresh.png',
|
||||
"scanner" = 'icons/pda_icons/pda_scanner.png',
|
||||
"signaler" = 'icons/pda_icons/pda_signaler.png',
|
||||
// "skills" = 'icons/pda_icons/pda_skills.png',
|
||||
"status" = 'icons/pda_icons/pda_status.png',
|
||||
"dronephone" = 'icons/pda_icons/pda_dronephone.png',
|
||||
"emoji" = 'icons/pda_icons/pda_emoji.png'
|
||||
@@ -97,6 +92,10 @@
|
||||
"stamp-cap" = 'icons/stamp_icons/large_stamp-cap.png',
|
||||
"stamp-qm" = 'icons/stamp_icons/large_stamp-qm.png',
|
||||
"stamp-law" = 'icons/stamp_icons/large_stamp-law.png'
|
||||
// "stamp-chap" = 'icons/stamp_icons/large_stamp-chap.png'
|
||||
// "stamp-mime" = 'icons/stamp_icons/large_stamp-mime.png',
|
||||
// "stamp-centcom" = 'icons/stamp_icons/large_stamp-centcom.png',
|
||||
// "stamp-syndicate" = 'icons/stamp_icons/large_stamp-syndicate.png'
|
||||
)
|
||||
|
||||
|
||||
@@ -147,7 +146,6 @@
|
||||
"jquery.min.js" = 'code/modules/goonchat/browserassets/js/jquery.min.js',
|
||||
)
|
||||
|
||||
|
||||
/datum/asset/simple/goonchat
|
||||
assets = list(
|
||||
"json2.min.js" = 'code/modules/goonchat/browserassets/js/json2.min.js',
|
||||
@@ -375,7 +373,18 @@
|
||||
"ghost.png" = 'html/ghost.png'
|
||||
)
|
||||
|
||||
/datum/asset/simple/vv
|
||||
assets = list(
|
||||
"ghost.png" = 'html/ghost.png'
|
||||
"view_variables.css" = 'html/admin/view_variables.css'
|
||||
)
|
||||
|
||||
/datum/asset/spritesheet/sheetmaterials
|
||||
name = "sheetmaterials"
|
||||
|
||||
/datum/asset/spritesheet/sheetmaterials/register()
|
||||
InsertAll("", 'icons/obj/stack_objects.dmi')
|
||||
|
||||
// Special case to handle Bluespace Crystals
|
||||
Insert("polycrystal", 'icons/obj/telescience.dmi', "polycrystal")
|
||||
..()
|
||||
|
||||
|
||||
@@ -237,11 +237,10 @@
|
||||
return ..()
|
||||
return UI_CLOSE
|
||||
|
||||
/obj/machinery/airalarm/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/airalarm/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "AirAlarm", name, 440, 650, master_ui, state)
|
||||
ui = new(user, src, "AirAlarm", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/airalarm/ui_data(mob/user)
|
||||
|
||||
@@ -26,9 +26,6 @@ Passive gate is similar to the regular pump except:
|
||||
construction_type = /obj/item/pipe/directional
|
||||
pipe_state = "passivegate"
|
||||
|
||||
ui_x = 335
|
||||
ui_y = 115
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/CtrlClick(mob/user)
|
||||
if(can_interact(user))
|
||||
on = !on
|
||||
@@ -102,11 +99,10 @@ Passive gate is similar to the regular pump except:
|
||||
))
|
||||
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/atmospherics/components/binary/passive_gate/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "AtmosPump", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "AtmosPump", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/ui_data()
|
||||
|
||||
@@ -107,11 +107,10 @@
|
||||
))
|
||||
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/atmospherics/components/binary/pump/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "AtmosPump", name, 335, 115, master_ui, state)
|
||||
ui = new(user, src, "AtmosPump", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/ui_data()
|
||||
|
||||
@@ -60,15 +60,14 @@
|
||||
else if(!opened && our_pressure >= open_pressure)
|
||||
open()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/relief_valve/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/atmospherics/components/binary/relief_valve/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_relief", name, 335, 115, master_ui, state)
|
||||
ui = new(user, src, "AtmosRelief", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/relief_valve/ui_data()
|
||||
var/data = list()
|
||||
var/list/data = list()
|
||||
data["open_pressure"] = round(open_pressure)
|
||||
data["close_pressure"] = round(close_pressure)
|
||||
data["max_pressure"] = round(50*ONE_ATMOSPHERE)
|
||||
@@ -79,11 +78,11 @@
|
||||
return
|
||||
switch(action)
|
||||
if("open_pressure")
|
||||
var/pressure = params["open_pressure"]
|
||||
var/pressure = params["pressure"]
|
||||
if(pressure == "max")
|
||||
pressure = 50*ONE_ATMOSPHERE
|
||||
. = TRUE
|
||||
else if(pressure == "input")
|
||||
else if(pressure == "input") // The manual expirience.
|
||||
pressure = input("New output pressure ([close_pressure]-[50*ONE_ATMOSPHERE] kPa):", name, open_pressure) as num|null
|
||||
if(!isnull(pressure) && !..())
|
||||
. = TRUE
|
||||
@@ -94,7 +93,7 @@
|
||||
open_pressure = clamp(pressure, close_pressure, 50*ONE_ATMOSPHERE)
|
||||
investigate_log("open pressure was set to [open_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS)
|
||||
if("close_pressure")
|
||||
var/pressure = params["close_pressure"]
|
||||
var/pressure = params["pressure"]
|
||||
if(pressure == "max")
|
||||
pressure = open_pressure
|
||||
. = TRUE
|
||||
|
||||
@@ -92,11 +92,10 @@
|
||||
))
|
||||
radio_connection.post_signal(src, signal)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/atmospherics/components/binary/volume_pump/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "AtmosPump", name, 310, 115, master_ui, state)
|
||||
ui = new(user, src, "AtmosPump", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/ui_data()
|
||||
|
||||
@@ -133,11 +133,10 @@
|
||||
set_frequency(frequency)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/atmospherics/components/trinary/filter/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "AtmosFilter", name, 475, 185, master_ui, state)
|
||||
ui = new(user, src, "AtmosFilter", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/ui_data()
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
construction_type = /obj/item/pipe/trinary/flippable
|
||||
pipe_state = "mixer"
|
||||
|
||||
ui_x = 370
|
||||
ui_y = 165
|
||||
|
||||
//node 3 is the outlet, nodes 1 & 2 are intakes
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/CtrlClick(mob/user)
|
||||
@@ -127,11 +124,10 @@
|
||||
var/datum/pipeline/parent3 = parents[3]
|
||||
parent3.update = TRUE
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/atmospherics/components/trinary/mixer/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "AtmosMixer", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "AtmosMixer", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/ui_data()
|
||||
|
||||
@@ -332,11 +332,13 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_state(mob/user)
|
||||
return GLOB.notcontained_state
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Cryo", name, 400, 550, master_ui, state)
|
||||
ui = new(user, src, "Cryo", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_data()
|
||||
|
||||
@@ -20,9 +20,6 @@
|
||||
|
||||
pipe_state = "injector"
|
||||
|
||||
ui_x = 310
|
||||
ui_y = 115
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/outlet_injector/CtrlClick(mob/user)
|
||||
if(can_interact(user))
|
||||
on = !on
|
||||
@@ -132,7 +129,7 @@
|
||||
on = !on
|
||||
|
||||
if("inject" in signal.data)
|
||||
spawn inject()
|
||||
INVOKE_ASYNC(src, .proc/inject)
|
||||
return
|
||||
|
||||
if("set_volume_rate" in signal.data)
|
||||
@@ -140,22 +137,16 @@
|
||||
var/datum/gas_mixture/air_contents = airs[1]
|
||||
volume_rate = clamp(number, 0, air_contents.return_volume())
|
||||
|
||||
if("status" in signal.data)
|
||||
spawn(2)
|
||||
broadcast_status()
|
||||
return //do not update_icon
|
||||
addtimer(CALLBACK(src, .proc/broadcast_status), 2)
|
||||
|
||||
spawn(2)
|
||||
broadcast_status()
|
||||
|
||||
update_icon()
|
||||
if(!("status" in signal.data)) //do not update_icon
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/outlet_injector/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/atmospherics/components/unary/outlet_injector/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "AtmosPump", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "AtmosPump", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/outlet_injector/ui_data()
|
||||
|
||||
@@ -61,15 +61,14 @@
|
||||
|
||||
update_parents()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/relief_valve/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/atmospherics/components/unary/relief_valve/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_relief", name, 335, 115, master_ui, state)
|
||||
ui = new(user, src, "AtmosRelief", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/relief_valve/ui_data()
|
||||
var/data = list()
|
||||
var/list/data = list()
|
||||
data["open_pressure"] = round(open_pressure)
|
||||
data["close_pressure"] = round(close_pressure)
|
||||
data["max_pressure"] = round(50*ONE_ATMOSPHERE)
|
||||
@@ -80,7 +79,7 @@
|
||||
return
|
||||
switch(action)
|
||||
if("open_pressure")
|
||||
var/pressure = params["open_pressure"]
|
||||
var/pressure = params["pressure"]
|
||||
if(pressure == "max")
|
||||
pressure = 50*ONE_ATMOSPHERE
|
||||
. = TRUE
|
||||
@@ -95,7 +94,7 @@
|
||||
open_pressure = clamp(pressure, close_pressure, 50*ONE_ATMOSPHERE)
|
||||
investigate_log("open pressure was set to [open_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS)
|
||||
if("close_pressure")
|
||||
var/pressure = params["close_pressure"]
|
||||
var/pressure = params["pressure"]
|
||||
if(pressure == "max")
|
||||
pressure = open_pressure
|
||||
. = TRUE
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
layer = OBJ_LAYER
|
||||
plane = GAME_PLANE
|
||||
circuit = /obj/item/circuitboard/machine/thermomachine
|
||||
ui_x = 300
|
||||
ui_y = 230
|
||||
|
||||
pipe_flags = PIPING_ONE_PER_TURF
|
||||
|
||||
@@ -125,11 +123,10 @@
|
||||
return ..()
|
||||
return UI_CLOSE
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/atmospherics/components/unary/thermomachine/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "ThermoMachine", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "ThermoMachine", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/ui_data(mob/user)
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
desc = "A canister for the storage of gas."
|
||||
icon_state = "yellow"
|
||||
density = TRUE
|
||||
ui_x = 300
|
||||
ui_y = 232
|
||||
|
||||
var/valve_open = FALSE
|
||||
var/obj/machinery/atmospherics/components/binary/passive_gate/pump
|
||||
@@ -319,11 +317,13 @@ obj/machinery/portable_atmospherics/canister/welder_act(mob/living/user, obj/ite
|
||||
air_update_turf() // Update the environment if needed.
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/portable_atmospherics/canister/ui_state(mob/user)
|
||||
return GLOB.physical_state
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Canister", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "Canister", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/ui_data()
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
name = "portable air pump"
|
||||
icon_state = "psiphon:0"
|
||||
density = TRUE
|
||||
ui_x = 300
|
||||
ui_y = 315
|
||||
|
||||
var/on = FALSE
|
||||
var/direction = PUMP_OUT
|
||||
@@ -83,11 +81,10 @@
|
||||
investigate_log("[key_name(user)] started a transfer into [holding].", INVESTIGATE_ATMOS)
|
||||
|
||||
|
||||
/obj/machinery/portable_atmospherics/pump/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/portable_atmospherics/pump/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "PortablePump", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "PortablePump", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/portable_atmospherics/pump/ui_data()
|
||||
|
||||
@@ -62,11 +62,10 @@
|
||||
on = !on
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/portable_atmospherics/scrubber/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "PortableScrubber", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "PortableScrubber", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/ui_data()
|
||||
|
||||
@@ -277,11 +277,10 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
|
||||
. = ..()
|
||||
try_to_linkup()
|
||||
|
||||
/obj/machinery/computer/gateway_control/ui_interact(mob/user, ui_key = "main", datum/tgui/ui, force_open, datum/tgui/master_ui, datum/ui_state/state = GLOB.default_state)
|
||||
. = ..()
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/gateway_control/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Gateway", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "Gateway", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/gateway_control/ui_data(mob/user)
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
#define PRINTER_TIMEOUT 10
|
||||
|
||||
|
||||
|
||||
/obj/machinery/computer/bounty
|
||||
name = "Nanotrasen bounty console"
|
||||
name = "\improper Nanotrasen bounty console"
|
||||
desc = "Used to check and claim bounties offered by Nanotrasen"
|
||||
icon_screen = "bounty"
|
||||
circuit = /obj/item/circuitboard/computer/bounty
|
||||
light_color = "#E2853D"//orange
|
||||
var/printer_ready = 0 //cooldown var
|
||||
var/static/datum/bank_account/cargocash
|
||||
|
||||
/obj/machinery/computer/bounty/Initialize()
|
||||
. = ..()
|
||||
printer_ready = world.time + PRINTER_TIMEOUT
|
||||
cargocash = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
|
||||
/obj/machinery/computer/bounty/proc/print_paper()
|
||||
new /obj/item/paper/bounty_printout(loc)
|
||||
@@ -23,70 +23,43 @@
|
||||
/obj/item/paper/bounty_printout/Initialize()
|
||||
. = ..()
|
||||
info = "<h2>Nanotrasen Cargo Bounties</h2></br>"
|
||||
update_icon()
|
||||
|
||||
for(var/datum/bounty/B in GLOB.bounties_list)
|
||||
if(B.claimed)
|
||||
continue
|
||||
info += {"<h3>[B.name]</h3>
|
||||
<ul><li>Reward: [B.reward_string()]</li>
|
||||
<li>Completed: [B.completion_string()]</li></ul>"}
|
||||
|
||||
/obj/machinery/computer/bounty/ui_interact(mob/user)
|
||||
. = ..()
|
||||
<ul><li>Reward: [B.reward_string()]</li>
|
||||
<li>Completed: [B.completion_string()]</li></ul>"}
|
||||
|
||||
/obj/machinery/computer/bounty/ui_interact(mob/user, datum/tgui/ui)
|
||||
if(!GLOB.bounties_list.len)
|
||||
setup_bounties()
|
||||
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
var/list/dat = list({"<a href='?src=[REF(src)];refresh=1'>Refresh</a>
|
||||
<a href='?src=[REF(src)];refresh=1;choice=Print'>Print Paper</a>
|
||||
<p>Credits: <b>[D.account_balance]</b></p>
|
||||
<table style="text-align:center;" border="1" cellspacing="0" width="100%">
|
||||
<tr><th>Name</th><th>Description</th><th>Reward</th><th>Completion</th><th>Status</th></tr>"})
|
||||
for(var/datum/bounty/B in GLOB.bounties_list)
|
||||
if(B.claimed)
|
||||
dat += "<tr style='background-color:#294675;'>"
|
||||
else if(B.can_claim())
|
||||
dat += "<tr style='background-color:#4F7529;'>"
|
||||
else
|
||||
dat += "<tr style='background-color:#990000;'>"
|
||||
if(B.high_priority)
|
||||
dat += {"<td><b>[B.name]</b></td>
|
||||
<td><b>High Priority:</b> [B.description]</td>
|
||||
<td><b>[B.reward_string()]</b></td>"}
|
||||
else
|
||||
dat += {"<td>[B.name]</td>
|
||||
<td>[B.description]</td>
|
||||
<td>[B.reward_string()]</td>"}
|
||||
dat += "<td>[B.completion_string()]</td>"
|
||||
if(B.claimed)
|
||||
dat += "<td>Claimed</td>"
|
||||
else if(B.can_claim())
|
||||
dat += "<td><A href='?src=[REF(src)];refresh=1;choice=Claim;d_rec=[REF(B)]'>Claim</a></td>"
|
||||
else
|
||||
dat += "<td>Unclaimed</td>"
|
||||
dat += "</tr>"
|
||||
dat += "</table>"
|
||||
dat = dat.Join()
|
||||
var/datum/browser/popup = new(user, "bounties", "Nanotrasen Bounties", 700, 600)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "CargoBountyConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/bounty/Topic(href, href_list)
|
||||
/obj/machinery/computer/bounty/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/list/bountyinfo = list()
|
||||
for(var/datum/bounty/B in GLOB.bounties_list)
|
||||
bountyinfo += list(list("name" = B.name, "description" = B.description, "reward_string" = B.reward_string(), "completion_string" = B.completion_string() , "claimed" = B.claimed, "can_claim" = B.can_claim(), "priority" = B.high_priority, "bounty_ref" = REF(B)))
|
||||
data["stored_cash"] = cargocash.account_balance
|
||||
data["bountydata"] = bountyinfo
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/bounty/ui_act(action,params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(href_list["choice"])
|
||||
switch(action)
|
||||
if("ClaimBounty")
|
||||
var/datum/bounty/cashmoney = locate(params["bounty"]) in GLOB.bounties_list
|
||||
if(cashmoney)
|
||||
cashmoney.claim()
|
||||
return TRUE
|
||||
if("Print")
|
||||
if(printer_ready < world.time)
|
||||
printer_ready = world.time + PRINTER_TIMEOUT
|
||||
print_paper()
|
||||
|
||||
if("Claim")
|
||||
var/datum/bounty/B = locate(href_list["d_rec"])
|
||||
if(B in GLOB.bounties_list)
|
||||
B.claim()
|
||||
|
||||
if(href_list["refresh"])
|
||||
playsound(src, "terminal_type", 25, 0)
|
||||
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/client/proc/centcom_podlauncher() //Creates a verb for admins to open up the ui
|
||||
set name = "Config/Launch Supplypod"
|
||||
set desc = "Configure and launch a Centcom supplypod full of whatever your heart desires!"
|
||||
set desc = "Configure and launch a CentCom supplypod full of whatever your heart desires!"
|
||||
set category = "Admin"
|
||||
var/datum/centcom_podlauncher/plaunch = new(usr)//create the datum
|
||||
plaunch.ui_interact(usr)//datum has a tgui component, here we open the window
|
||||
@@ -23,7 +23,10 @@
|
||||
var/turf/oldTurf //Keeps track of where the user was at if they use the "teleport to centcom" button, so they can go back
|
||||
var/client/holder //client of whoever is using this datum
|
||||
var/area/bay //What bay we're using to launch shit from.
|
||||
var/turf/dropoff_turf //If we're reversing, where the reverse pods go
|
||||
var/picking_dropoff_turf
|
||||
var/launchClone = FALSE //If true, then we don't actually launch the thing in the bay. Instead we call duplicateObject() and send the result
|
||||
var/launchRandomItem = FALSE //If true, lauches a single random item instead of everything on a turf.
|
||||
var/launchChoice = 1 //Determines if we launch all at once (0) , in order (1), or at random(2)
|
||||
var/explosionChoice = 0 //Determines if there is no explosion (0), custom explosion (1), or just do a maxcap (2)
|
||||
var/damageChoice = 0 //Determines if we do no damage (0), custom amnt of damage (1), or gib + 5000dmg (2)
|
||||
@@ -50,20 +53,25 @@
|
||||
temp_pod = new(locate(/area/centcom/supplypod/podStorage) in GLOB.sortedAreas) //Create a new temp_pod in the podStorage area on centcom (so users are free to look at it and change other variables if needed)
|
||||
orderedArea = createOrderedArea(bay) //Order all the turfs in the selected bay (top left to bottom right) to a single list. Used for the "ordered" mode (launchChoice = 1)
|
||||
|
||||
/datum/centcom_podlauncher/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, \
|
||||
force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.admin_state)//ui_interact is called when the client verb is called.
|
||||
/datum/centcom_podlauncher/ui_state(mob/user)
|
||||
return GLOB.admin_state
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/datum/centcom_podlauncher/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "CentcomPodLauncher", "Config/Launch Supplypod", 700, 700, master_ui, state)
|
||||
ui = new(user, src, "CentcomPodLauncher")
|
||||
ui.open()
|
||||
|
||||
/datum/centcom_podlauncher/ui_data(mob/user) //Sends info about the pod to the UI.
|
||||
var/list/data = list() //*****NOTE*****: Many of these comments are similarly described in supplypod.dm. If you change them here, please consider doing so in the supplypod code as well!
|
||||
var/B = (istype(bay, /area/centcom/supplypod/loading/one)) ? 1 : (istype(bay, /area/centcom/supplypod/loading/two)) ? 2 : (istype(bay, /area/centcom/supplypod/loading/three)) ? 3 : (istype(bay, /area/centcom/supplypod/loading/four)) ? 4 : 0 //top ten THICCEST FUCKING TERNARY CONDITIONALS OF 2036
|
||||
data["bay"] = B //Holds the current bay the user is launching objects from. Bays are specific rooms on the centcom map.
|
||||
var/B = (istype(bay, /area/centcom/supplypod/loading/one)) ? 1 : (istype(bay, /area/centcom/supplypod/loading/two)) ? 2 : (istype(bay, /area/centcom/supplypod/loading/three)) ? 3 : (istype(bay, /area/centcom/supplypod/loading/four)) ? 4 : 0 //(istype(bay, /area/centcom/supplypod/loading/ert)) ? 5 : 0 //top ten THICCEST FUCKING TERNARY CONDITIONALS OF 2036
|
||||
data["bay"] = bay //Holds the current bay the user is launching objects from. Bays are specific rooms on the centcom map.
|
||||
data["bayNumber"] = B //Holds the bay as a number. Useful for comparisons in centcom_podlauncher.ract
|
||||
data["oldArea"] = (oldTurf ? get_area(oldTurf) : null) //Holds the name of the area that the user was in before using the teleportCentcom action
|
||||
data["picking_dropoff_turf"] = picking_dropoff_turf //If we're picking or have picked a dropoff turf. Only works when pod is in reverse mode
|
||||
data["dropoff_turf"] = dropoff_turf //The turf that reverse pods will drop their newly acquired cargo off at
|
||||
data["launchClone"] = launchClone //Do we launch the actual items in the bay or just launch clones of them?
|
||||
data["launchRandomItem"] = launchRandomItem //Do we launch a single random item instead of everything on the turf?
|
||||
data["launchChoice"] = launchChoice //Launch turfs all at once (0), ordered (1), or randomly(1)
|
||||
data["explosionChoice"] = explosionChoice //An explosion that occurs when landing. Can be no explosion (0), custom explosion (1), or maxcap (2)
|
||||
data["damageChoice"] = damageChoice //Damage that occurs to any mob under the pod when it lands. Can be no damage (0), custom damage (1), or gib+5000dmg (2)
|
||||
@@ -72,11 +80,12 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
data["openingDelay"] = temp_pod.openingDelay //How long the pod takes to open after landing
|
||||
data["departureDelay"] = temp_pod.departureDelay //How long the pod takes to leave after opening (if bluespace=true, it deletes. if reversing=true, it flies back to centcom)
|
||||
data["styleChoice"] = temp_pod.style //Style is a variable that keeps track of what the pod is supposed to look like. It acts as an index to the POD_STYLES list in cargo.dm defines to get the proper icon/name/desc for the pod.
|
||||
data["effectShrapnel"] = FALSE //temp_pod.effectShrapnel //If true, creates a cloud of shrapnel of a decided type and magnitude on landing
|
||||
data["effectStun"] = temp_pod.effectStun //If true, stuns anyone under the pod when it launches until it lands, forcing them to get hit by the pod. Devilish!
|
||||
data["effectLimb"] = temp_pod.effectLimb //If true, pops off a limb (if applicable) from anyone caught under the pod when it lands
|
||||
data["effectOrgans"] = temp_pod.effectOrgans //If true, yeets the organs out of any bodies caught under the pod when it lands
|
||||
data["effectBluespace"] = temp_pod.bluespace //If true, the pod deletes (in a shower of sparks) after landing
|
||||
data["effectStealth"] = temp_pod.effectStealth //If true, a target icon isnt displayed on the turf where the pod will land
|
||||
data["effectStealth"] = temp_pod.effectStealth //If true, a target icon isn't displayed on the turf where the pod will land
|
||||
data["effectQuiet"] = temp_pod.effectQuiet //The female sniper. If true, the pod makes no noise (including related explosions, opening sounds, etc)
|
||||
data["effectMissile"] = temp_pod.effectMissile //If true, the pod deletes the second it lands. If you give it an explosion, it will act like a missile exploding as it hits the ground
|
||||
data["effectCircle"] = temp_pod.effectCircle //If true, allows the pod to come in at any angle. Bit of a weird feature but whatever its here
|
||||
@@ -115,20 +124,41 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
bay = locate(/area/centcom/supplypod/loading/four) in GLOB.sortedAreas
|
||||
refreshBay()
|
||||
. = TRUE
|
||||
if("bay5")
|
||||
to_chat(usr, "LetterN is lazy and didin't bother porting this new cc area!")
|
||||
return
|
||||
// bay = locate(/area/centcom/supplypod/loading/ert) in GLOB.sortedAreas
|
||||
// refreshBay()
|
||||
// . = TRUE
|
||||
if("pickDropoffTurf") //Enters a mode that lets you pick the dropoff location for reverse pods
|
||||
if (picking_dropoff_turf)
|
||||
picking_dropoff_turf = FALSE
|
||||
updateCursor(FALSE, FALSE) //Update the cursor of the user to a cool looking target icon
|
||||
return
|
||||
if (launcherActivated)
|
||||
launcherActivated = FALSE //We don't want to have launch mode enabled while we're picking a turf
|
||||
picking_dropoff_turf = TRUE
|
||||
updateCursor(FALSE, TRUE) //Update the cursor of the user to a cool looking target icon
|
||||
. = TRUE
|
||||
if("clearDropoffTurf")
|
||||
picking_dropoff_turf = FALSE
|
||||
dropoff_turf = null
|
||||
updateCursor(FALSE, FALSE)
|
||||
. = TRUE
|
||||
if("teleportCentcom") //Teleports the user to the centcom supply loading facility.
|
||||
var/mob/M = holder.mob //We teleport whatever mob the client is attached to at the point of clicking
|
||||
oldTurf = get_turf(M) //Used for the "teleportBack" action
|
||||
var/area/A = locate(/area/centcom/supplypod/loading) in GLOB.sortedAreas
|
||||
var/area/A = locate(bay) in GLOB.sortedAreas
|
||||
var/list/turfs = list()
|
||||
for(var/turf/T in A)
|
||||
turfs.Add(T) //Fill a list with turfs in the area
|
||||
var/turf/T = safepick(turfs) //Only teleport if the list isn't empty
|
||||
if(!T) //If the list is empty, error and cancel
|
||||
if (!length(turfs)) //If the list is empty, error and cancel
|
||||
to_chat(M, "Nowhere to jump to!")
|
||||
return
|
||||
return //Only teleport if the list isn't empty
|
||||
var/turf/T = pick(turfs)
|
||||
M.forceMove(T) //Perform the actual teleport
|
||||
log_admin("[key_name(usr)] jumped to [AREACOORD(A)]")
|
||||
message_admins("[key_name_admin(usr)] jumped to [AREACOORD(A)]")
|
||||
log_admin("[key_name(usr)] jumped to [AREACOORD(T)]")
|
||||
message_admins("[key_name_admin(usr)] jumped to [AREACOORD(T)]")
|
||||
. = TRUE
|
||||
if("teleportBack") //After teleporting to centcom, this button allows the user to teleport to the last spot they were at.
|
||||
var/mob/M = holder.mob
|
||||
@@ -144,6 +174,9 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if("launchClone") //Toggles the launchClone var. See variable declarations above for what this specifically means
|
||||
launchClone = !launchClone
|
||||
. = TRUE
|
||||
if("launchRandomItem") //Pick random turfs from the supplypod bay at centcom to launch
|
||||
launchRandomItem = !launchRandomItem
|
||||
. = TRUE
|
||||
if("launchOrdered") //Launch turfs (from the orderedArea list) one at a time in order, from the supplypod bay at centcom
|
||||
if (launchChoice == 1) //launchChoice 1 represents ordered. If we push "ordered" and it already is, then we go to default value
|
||||
launchChoice = 0
|
||||
@@ -152,7 +185,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
launchChoice = 1
|
||||
updateSelector()
|
||||
. = TRUE
|
||||
if("launchRandom") //Pick random turfs from the supplypod bay at centcom to launch
|
||||
if("launchRandomTurf") //Pick random turfs from the supplypod bay at centcom to launch
|
||||
if (launchChoice == 2)
|
||||
launchChoice = 0
|
||||
updateSelector()
|
||||
@@ -170,11 +203,11 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
var/list/expNames = list("Devastation", "Heavy Damage", "Light Damage", "Flame") //Explosions have a range of different types of damage
|
||||
var/list/boomInput = list()
|
||||
for (var/i=1 to expNames.len) //Gather input from the user for the value of each type of damage
|
||||
boomInput.Add(input("[expNames[i]] Range", "Enter the [expNames[i]] range of the explosion. WARNING: This ignores the bomb cap!", 0) as null|num)
|
||||
boomInput.Add(input("Enter the [expNames[i]] range of the explosion. WARNING: This ignores the bomb cap!", "[expNames[i]] Range", 0) as null|num)
|
||||
if (isnull(boomInput[i]))
|
||||
return
|
||||
if (!isnum(boomInput[i])) //If the user doesn't input a number, set that specific explosion value to zero
|
||||
alert(usr, "That wasnt a number! Value set to default (zero) instead.")
|
||||
alert(usr, "That wasn't a number! Value set to default (zero) instead.")
|
||||
boomInput = 0
|
||||
explosionChoice = 1
|
||||
temp_pod.explosionSize = boomInput
|
||||
@@ -192,11 +225,11 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
damageChoice = 0
|
||||
temp_pod.damage = 0
|
||||
return
|
||||
var/damageInput = input("How much damage to deal", "Enter the amount of brute damage dealt by getting hit", 0) as null|num
|
||||
var/damageInput = input("Enter the amount of brute damage dealt by getting hit","How much damage to deal", 0) as null|num
|
||||
if (isnull(damageInput))
|
||||
return
|
||||
if (!isnum(damageInput)) //Sanitize the input for damage to deal.s
|
||||
alert(usr, "That wasnt a number! Value set to default (zero) instead.")
|
||||
alert(usr, "That wasn't a number! Value set to default (zero) instead.")
|
||||
damageInput = 0
|
||||
damageChoice = 1
|
||||
temp_pod.damage = damageInput
|
||||
@@ -226,13 +259,32 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
temp_pod.desc = descInput
|
||||
temp_pod.adminNamed = TRUE //This variable is checked in the supplypod/setStyle() proc
|
||||
. = TRUE
|
||||
/*
|
||||
if("effectShrapnel") //Creates a cloud of shrapnel on landing
|
||||
if (temp_pod.effectShrapnel == TRUE) //If already doing custom damage, set back to default (no shrapnel)
|
||||
temp_pod.effectShrapnel = FALSE
|
||||
return
|
||||
var/shrapnelInput = input("Please enter the type of pellet cloud you'd like to create on landing (Can be any projectile!)", "Projectile Typepath", 0) in sortList(subtypesof(/obj/item/projectile), /proc/cmp_typepaths_asc)
|
||||
if (isnull(shrapnelInput))
|
||||
return
|
||||
var/shrapnelMagnitude = input("Enter the magnitude of the pellet cloud. This is usually a value around 1-5. Please note that Ryll-Ryll has asked me to tell you that if you go too crazy with the projectiles you might crash the server. So uh, be gentle!", "Shrapnel Magnitude", 0) as null|num
|
||||
if (isnull(shrapnelMagnitude))
|
||||
return
|
||||
if (!isnum(shrapnelMagnitude))
|
||||
alert(usr, "That wasn't a number! Value set to 3 instead.")
|
||||
shrapnelMagnitude = 3
|
||||
temp_pod.shrapnel_type = shrapnelInput
|
||||
temp_pod.shrapnel_magnitude = shrapnelMagnitude
|
||||
temp_pod.effectShrapnel = TRUE
|
||||
. = TRUE
|
||||
*/
|
||||
if("effectStun") //Toggle: Any mob under the pod is stunned (cant move) until the pod lands, hitting them!
|
||||
temp_pod.effectStun = !temp_pod.effectStun
|
||||
. = TRUE
|
||||
if("effectLimb") //Toggle: Anyone carbon mob under the pod loses a limb when it lands
|
||||
temp_pod.effectLimb = !temp_pod.effectLimb
|
||||
. = TRUE
|
||||
if("effectOrgans") //Toggle: Any carbon mob under the pod loses every limb and organ
|
||||
if("effectOrgans") //Toggle: Anyone carbon mob under the pod loses a limb when it lands
|
||||
temp_pod.effectOrgans = !temp_pod.effectOrgans
|
||||
. = TRUE
|
||||
if("effectBluespace") //Toggle: Deletes the pod after landing
|
||||
@@ -253,7 +305,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if("effectBurst") //Toggle: Launch 5 pods (with a very slight delay between) in a 3x3 area centered around the target
|
||||
effectBurst = !effectBurst
|
||||
. = TRUE
|
||||
if("effectAnnounce") //Toggle: Sends a ghost announcement.
|
||||
if("effectAnnounce") //Toggle: Launch 5 pods (with a very slight delay between) in a 3x3 area centered around the target
|
||||
effectAnnounce = !effectAnnounce
|
||||
. = TRUE
|
||||
if("effectReverse") //Toggle: Don't send any items. Instead, after landing, close (taking any objects inside) and go back to the centcom bay it came from
|
||||
@@ -272,15 +324,15 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
. = TRUE
|
||||
|
||||
////////////////////////////TIMER DELAYS//////////////////
|
||||
if("fallDuration") //Change the falling animation duration
|
||||
if (temp_pod.fallDuration != initial(temp_pod.fallDuration)) //If the fall duration has already been changed when we push the "change value" button, then set it to default
|
||||
if("fallDuration") //Change the time it takes the pod to land, after firing
|
||||
if (temp_pod.fallDuration != initial(temp_pod.fallDuration)) //If the landing delay has already been changed when we push the "change value" button, then set it to default
|
||||
temp_pod.fallDuration = initial(temp_pod.fallDuration)
|
||||
return
|
||||
var/timeInput = input("Enter the duration of the pod's falling animation, in seconds", "Delay Time", initial(temp_pod.fallDuration) * 0.1) as null|num
|
||||
var/timeInput = input("Enter the duration of the pod's falling animation, in seconds", "Delay Time", initial(temp_pod.fallDuration) * 0.1) as null|num
|
||||
if (isnull(timeInput))
|
||||
return
|
||||
if (!isnum(timeInput)) //Sanitize input, if it doesnt check out, error and set to default
|
||||
alert(usr, "That wasnt a number! Value set to default ([initial(temp_pod.fallDuration)*0.1]) instead.")
|
||||
alert(usr, "That wasn't a number! Value set to default ([initial(temp_pod.fallDuration)*0.1]) instead.")
|
||||
timeInput = initial(temp_pod.fallDuration)
|
||||
temp_pod.fallDuration = 10 * timeInput
|
||||
. = TRUE
|
||||
@@ -292,7 +344,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if (isnull(timeInput))
|
||||
return
|
||||
if (!isnum(timeInput)) //Sanitize input, if it doesnt check out, error and set to default
|
||||
alert(usr, "That wasnt a number! Value set to default ([initial(temp_pod.landingDelay)*0.1]) instead.")
|
||||
alert(usr, "That wasn't a number! Value set to default ([initial(temp_pod.landingDelay)*0.1]) instead.")
|
||||
timeInput = initial(temp_pod.landingDelay)
|
||||
temp_pod.landingDelay = 10 * timeInput
|
||||
. = TRUE
|
||||
@@ -304,7 +356,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if (isnull(timeInput))
|
||||
return
|
||||
if (!isnum(timeInput)) //Sanitize input
|
||||
alert(usr, "That wasnt a number! Value set to default ([initial(temp_pod.openingDelay)*0.1]) instead.")
|
||||
alert(usr, "That wasn't a number! Value set to default ([initial(temp_pod.openingDelay)*0.1]) instead.")
|
||||
timeInput = initial(temp_pod.openingDelay)
|
||||
temp_pod.openingDelay = 10 * timeInput
|
||||
. = TRUE
|
||||
@@ -316,13 +368,13 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if (isnull(timeInput))
|
||||
return
|
||||
if (!isnum(timeInput))
|
||||
alert(usr, "That wasnt a number! Value set to default ([initial(temp_pod.departureDelay)*0.1]) instead.")
|
||||
alert(usr, "That wasn't a number! Value set to default ([initial(temp_pod.departureDelay)*0.1]) instead.")
|
||||
timeInput = initial(temp_pod.departureDelay)
|
||||
temp_pod.departureDelay = 10 * timeInput
|
||||
. = TRUE
|
||||
|
||||
////////////////////////////ADMIN SOUNDS//////////////////
|
||||
if("fallingSound") //Admin sound from a local file that plays when the pod falls
|
||||
if("fallSound") //Admin sound from a local file that plays when the pod lands
|
||||
if ((temp_pod.fallingSound) != initial(temp_pod.fallingSound))
|
||||
temp_pod.fallingSound = initial(temp_pod.fallingSound)
|
||||
temp_pod.fallingSoundLength = initial(temp_pod.fallingSoundLength)
|
||||
@@ -334,7 +386,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if (isnull(timeInput))
|
||||
return
|
||||
if (!isnum(timeInput))
|
||||
alert(usr, "That wasnt a number! Value set to default ([initial(temp_pod.fallingSoundLength)*0.1]) instead.")
|
||||
alert(usr, "That wasn't a number! Value set to default ([initial(temp_pod.fallingSoundLength)*0.1]) instead.")
|
||||
temp_pod.fallingSound = soundInput
|
||||
temp_pod.fallingSoundLength = 10 * timeInput
|
||||
. = TRUE
|
||||
@@ -369,7 +421,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if (temp_pod.soundVolume != initial(temp_pod.soundVolume))
|
||||
temp_pod.soundVolume = initial(temp_pod.soundVolume)
|
||||
return
|
||||
var/soundInput = input(holder, "Please pick a volume. Default is between 1 and 100 with 80 being average, but pick whatever. I'm a notification, not a cop. If you still cant hear your sound, consider turning on the Quiet effect. It will silence all pod sounds except for the custom admin ones set by the previous three buttons.", "Pick Admin Sound Volume") as null|num
|
||||
var/soundInput = input(holder, "Please pick a volume. Default is between 1 and 100 with 50 being average, but pick whatever. I'm a notification, not a cop. If you still cant hear your sound, consider turning on the Quiet effect. It will silence all pod sounds except for the custom admin ones set by the previous three buttons.", "Pick Admin Sound Volume") as null|num
|
||||
if (isnull(soundInput))
|
||||
return
|
||||
temp_pod.soundVolume = soundInput
|
||||
@@ -421,26 +473,36 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
. = TRUE
|
||||
if("giveLauncher") //Enters the "Launch Mode". When the launcher is activated, temp_pod is cloned, and the result it filled and launched anywhere the user clicks (unless specificTarget is true)
|
||||
launcherActivated = !launcherActivated
|
||||
updateCursor(launcherActivated) //Update the cursor of the user to a cool looking target icon
|
||||
updateCursor(launcherActivated, FALSE) //Update the cursor of the user to a cool looking target icon
|
||||
. = TRUE
|
||||
if("clearBay") //Delete all mobs and objs in the selected bay
|
||||
if(alert(usr, "This will delete all objs and mobs in [bay]. Are you sure?", "Confirmation", "Delete that shit", "No") == "Delete that shit")
|
||||
clearBay()
|
||||
refreshBay()
|
||||
. = TRUE
|
||||
|
||||
/datum/centcom_podlauncher/ui_close() //Uses the destroy() proc. When the user closes the UI, we clean up the temp_pod and supplypod_selector variables.
|
||||
qdel(src)
|
||||
|
||||
/datum/centcom_podlauncher/proc/updateCursor(var/launching) //Update the moues of the user
|
||||
if (holder) //Check to see if we have a client
|
||||
if (launching) //If the launching param is true, we give the user new mouse icons.
|
||||
holder.mouse_up_icon = 'icons/effects/supplypod_target.dmi' //Icon for when mouse is released
|
||||
holder.mouse_down_icon = 'icons/effects/supplypod_down_target.dmi' //Icon for when mouse is pressed
|
||||
holder.mouse_pointer_icon = holder.mouse_up_icon //Icon for idle mouse (same as icon for when released)
|
||||
holder.click_intercept = src //Create a click_intercept so we know where the user is clicking
|
||||
else
|
||||
var/mob/M = holder.mob
|
||||
holder.mouse_up_icon = null
|
||||
holder.mouse_down_icon = null
|
||||
holder.click_intercept = null
|
||||
if (M)
|
||||
M.update_mouse_pointer() //set the moues icons to null, then call update_moues_pointer() which resets them to the correct values based on what the mob is doing (in a mech, holding a spell, etc)()
|
||||
/datum/centcom_podlauncher/proc/updateCursor(var/launching, var/turf_picking) //Update the mouse of the user
|
||||
if (!holder) //Can't update the mouse icon if the client doesnt exist!
|
||||
return
|
||||
if (launching || turf_picking) //If the launching param is true, we give the user new mouse icons.
|
||||
if(launching)
|
||||
holder.mouse_up_icon = 'icons/effects/mouse_pointers/supplypod_target.dmi' //Icon for when mouse is released
|
||||
holder.mouse_down_icon = 'icons/effects/mouse_pointers/supplypod_down_target.dmi' //Icon for when mouse is pressed
|
||||
if(turf_picking)
|
||||
holder.mouse_up_icon = 'icons/effects/mouse_pointers/supplypod_pickturf.dmi' //Icon for when mouse is released
|
||||
holder.mouse_down_icon = 'icons/effects/mouse_pointers/supplypod_pickturf_down.dmi' //Icon for when mouse is pressed
|
||||
holder.mouse_pointer_icon = holder.mouse_up_icon //Icon for idle mouse (same as icon for when released)
|
||||
holder.click_intercept = src //Create a click_intercept so we know where the user is clicking
|
||||
else
|
||||
var/mob/M = holder.mob
|
||||
holder.mouse_up_icon = null
|
||||
holder.mouse_down_icon = null
|
||||
holder.click_intercept = null
|
||||
if (M)
|
||||
M.update_mouse_pointer() //set the moues icons to null, then call update_moues_pointer() which resets them to the correct values based on what the mob is doing (in a mech, holding a spell, etc)()
|
||||
|
||||
/datum/centcom_podlauncher/proc/InterceptClickOn(user,params,atom/target) //Click Intercept so we know where to send pods where the user clicks
|
||||
var/list/pa = params2list(params)
|
||||
@@ -461,7 +523,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
else
|
||||
return //if target is null and we don't have a specific target, cancel
|
||||
if (effectAnnounce)
|
||||
deadchat_broadcast("<span class='deadsay'>A special package is being launched at the station!</span>", turf_target = target)
|
||||
deadchat_broadcast("A special package is being launched at the station!", turf_target = target) //, message_type=DEADCHAT_ANNOUNCEMENT)
|
||||
var/list/bouttaDie = list()
|
||||
for (var/mob/living/M in target)
|
||||
bouttaDie.Add(M)
|
||||
@@ -479,6 +541,15 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
else
|
||||
launch(target) //If we couldn't locate an adjacent turf, just launch at the normal target
|
||||
sleep(rand()*2) //looks cooler than them all appearing at once. Gives the impression of burst fire.
|
||||
else if (picking_dropoff_turf)
|
||||
//Clicking on UI elements shouldn't pick a dropoff turf
|
||||
if(istype(target,/obj/screen))
|
||||
return FALSE
|
||||
|
||||
. = TRUE
|
||||
if(left_click) //When we left click:
|
||||
dropoff_turf = get_turf(target)
|
||||
to_chat(user, "<span class = 'notice'> You've selected [dropoff_turf] at [COORD(dropoff_turf)] as your dropoff location.</span>")
|
||||
|
||||
/datum/centcom_podlauncher/proc/refreshBay() //Called whenever the bay is switched, as well as wheneber a pod is launched
|
||||
orderedArea = createOrderedArea(bay) //Create an ordered list full of turfs form the bay
|
||||
@@ -489,7 +560,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
to_chat(holder.mob, "No /area/centcom/supplypod/loading/one (or /two or /three or /four) in the world! You can make one yourself (then refresh) for now, but yell at a mapper to fix this, today!")
|
||||
CRASH("No /area/centcom/supplypod/loading/one (or /two or /three or /four) has been mapped into the centcom z-level!")
|
||||
orderedArea = list()
|
||||
if (!isemptylist(A.contents)) //Go through the area passed into the proc, and figure out the top left and bottom right corners by calculating max and min values
|
||||
if (length(A.contents)) //Go through the area passed into the proc, and figure out the top left and bottom right corners by calculating max and min values
|
||||
var/startX = A.contents[1].x //Create the four values (we do it off a.contents[1] so they have some sort of arbitrary initial value. They should be overwritten in a few moments)
|
||||
var/endX = A.contents[1].x
|
||||
var/startY = A.contents[1].y
|
||||
@@ -512,12 +583,12 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
numTurfs = 0 //Counts the number of turfs that can be launched (remember, supplypods either launch all at once or one turf-worth of items at a time)
|
||||
acceptableTurfs = list()
|
||||
for (var/turf/T in orderedArea) //Go through the orderedArea list
|
||||
if (typecache_filter_list_reverse(T.contents, ignored_atoms).len != 0) //if there is something in this turf that isnt in the blacklist, we consider this turf "acceptable" and add it to the acceptableTurfs list
|
||||
if (typecache_filter_list_reverse(T.contents, ignored_atoms).len != 0) //if there is something in this turf that isn't in the blacklist, we consider this turf "acceptable" and add it to the acceptableTurfs list
|
||||
acceptableTurfs.Add(T) //Because orderedArea was an ordered linear list, acceptableTurfs will be as well.
|
||||
numTurfs ++
|
||||
|
||||
launchList = list() //Anything in launchList will go into the supplypod when it is launched
|
||||
if (!isemptylist(acceptableTurfs) && !temp_pod.reversing && !temp_pod.effectMissile) //We dont fill the supplypod if acceptableTurfs is empty, if the pod is going in reverse (effectReverse=true), or if the pod is acitng like a missile (effectMissile=true)
|
||||
if (length(acceptableTurfs) && !temp_pod.reversing && !temp_pod.effectMissile) //We dont fill the supplypod if acceptableTurfs is empty, if the pod is going in reverse (effectReverse=true), or if the pod is acitng like a missile (effectMissile=true)
|
||||
switch(launchChoice)
|
||||
if(0) //If we are launching all the turfs at once
|
||||
for (var/turf/T in acceptableTurfs)
|
||||
@@ -536,22 +607,36 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if (isnull(A))
|
||||
return
|
||||
var/obj/structure/closet/supplypod/centcompod/toLaunch = DuplicateObject(temp_pod) //Duplicate the temp_pod (which we have been varediting or configuring with the UI) and store the result
|
||||
toLaunch.bay = bay //Bay is currently a nonstatic expression, so it cant go into toLaunch using DuplicateObject
|
||||
toLaunch.update_icon()//we update_icon() here so that the door doesnt "flicker on" right after it lands
|
||||
if (launchClone) //We arent launching the actual items from the bay, rather we are creating clones and launching those
|
||||
for (var/atom/movable/O in launchList)
|
||||
DuplicateObject(O).forceMove(toLaunch) //Duplicate each atom/movable in launchList and forceMove them into the supplypod
|
||||
new /obj/effect/abstract/DPtarget(A, toLaunch) //Create the DPTarget, which will eventually forceMove the temp_pod to it's location
|
||||
/*
|
||||
if(dropoff_turf)
|
||||
toLaunch.reverse_dropoff_turf = dropoff_turf
|
||||
else
|
||||
for (var/atom/movable/O in launchList) //If we aren't cloning the objects, just go through the launchList
|
||||
toLaunch.reverse_dropoff_turf = bay //Bay is currently a nonstatic expression, so it cant go into toLaunch using DuplicateObject
|
||||
*/
|
||||
toLaunch.update_icon()//we update_icon() here so that the door doesnt "flicker on" right after it lands
|
||||
// var/shippingLane = GLOB.areas_by_type[/area/centcom/supplypod/fly_me_to_the_moon]
|
||||
// toLaunch.forceMove(shippingLane) The shipping lane is temporarily closed due to ratvarian blockades
|
||||
if (launchClone) //We arent launching the actual items from the bay, rather we are creating clones and launching those
|
||||
if(launchRandomItem)
|
||||
var/atom/movable/O = pick_n_take(launchList)
|
||||
DuplicateObject(O).forceMove(toLaunch) //Duplicate a single atom/movable from launchList and forceMove it into the supplypod
|
||||
else
|
||||
for (var/atom/movable/O in launchList)
|
||||
DuplicateObject(O).forceMove(toLaunch) //Duplicate each atom/movable in launchList and forceMove them into the supplypod
|
||||
else
|
||||
if(launchRandomItem)
|
||||
var/atom/movable/O = pick_n_take(launchList)
|
||||
O.forceMove(toLaunch) //and forceMove any atom/moveable into the supplypod
|
||||
new /obj/effect/abstract/DPtarget(A, toLaunch) //Then, create the DPTarget effect, which will eventually forceMove the temp_pod to it's location
|
||||
else
|
||||
for (var/atom/movable/O in launchList) //If we aren't cloning the objects, just go through the launchList
|
||||
O.forceMove(toLaunch) //and forceMove any atom/moveable into the supplypod
|
||||
new /obj/effect/abstract/DPtarget(A, toLaunch) //Then, create the DPTarget effect, which will eventually forceMove the temp_pod to it's location
|
||||
if (launchClone)
|
||||
launchCounter++ //We only need to increment launchCounter if we are cloning objects.
|
||||
//If we aren't cloning objects, taking and removing the first item each time from the acceptableTurfs list will inherently iterate through the list in order
|
||||
|
||||
/datum/centcom_podlauncher/proc/updateSelector() //Ensures that the selector effect will showcase the next item if needed
|
||||
if (launchChoice == 1 && !isemptylist(acceptableTurfs) && !temp_pod.reversing && !temp_pod.effectMissile) //We only show the selector if we are taking items from the bay
|
||||
if (launchChoice == 1 && length(acceptableTurfs) && !temp_pod.reversing && !temp_pod.effectMissile) //We only show the selector if we are taking items from the bay
|
||||
var/index = launchCounter + 1 //launchCounter acts as an index to the ordered acceptableTurfs list, so adding one will show the next item in the list
|
||||
if (index > acceptableTurfs.len) //out of bounds check
|
||||
index = 1
|
||||
@@ -559,8 +644,14 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
else
|
||||
selector.moveToNullspace() //Otherwise, we move the selector to nullspace until it is needed again
|
||||
|
||||
/datum/centcom_podlauncher/proc/clearBay() //Clear all objs and mobs from the selected bay
|
||||
for (var/obj/O in bay.GetAllContents())
|
||||
qdel(O)
|
||||
for (var/mob/M in bay.GetAllContents())
|
||||
qdel(M)
|
||||
|
||||
/datum/centcom_podlauncher/Destroy() //The Destroy() proc. This is called by ui_close proc, or whenever the user leaves the game
|
||||
updateCursor(FALSE) //Make sure our moues cursor resets to default. False means we are not in launch mode
|
||||
updateCursor(FALSE, FALSE) //Make sure our moues cursor resets to default. False means we are not in launch mode
|
||||
qdel(temp_pod) //Delete the temp_pod
|
||||
qdel(selector) //Delete the selector effect
|
||||
. = ..()
|
||||
@@ -581,8 +672,8 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
for (var/X in temp_pod.explosionSize)
|
||||
explosionString += "[X]|"
|
||||
|
||||
var/msg = "launched [podString][whomString].[delayString][damageString][explosionString]]"
|
||||
message_admins("[key_name_admin(usr)] [msg] in [AREACOORD(specificTarget)].")
|
||||
if (!isemptylist(whoDyin))
|
||||
var/msg = "launched [podString] towards [whomString] [delayString][damageString][explosionString]"
|
||||
message_admins("[key_name_admin(usr)] [msg] in [ADMIN_VERBOSEJMP(specificTarget)].")
|
||||
if (length(whoDyin))
|
||||
for (var/mob/living/M in whoDyin)
|
||||
admin_ticket_log(M, "[key_name_admin(usr)] [msg]")
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
desc = "Used to order supplies, approve requests, and control the shuttle."
|
||||
icon_screen = "supply"
|
||||
circuit = /obj/item/circuitboard/computer/cargo
|
||||
req_access = list(ACCESS_CARGO)
|
||||
ui_x = 780
|
||||
ui_y = 750
|
||||
|
||||
var/requestonly = FALSE
|
||||
var/contraband = FALSE
|
||||
@@ -27,7 +24,6 @@
|
||||
desc = "Used to request supplies from cargo."
|
||||
icon_screen = "request"
|
||||
circuit = /obj/item/circuitboard/computer/cargo/request
|
||||
req_access = list()
|
||||
requestonly = TRUE
|
||||
|
||||
/obj/machinery/computer/cargo/Initialize()
|
||||
@@ -66,15 +62,12 @@
|
||||
var/obj/item/circuitboard/computer/cargo/board = circuit
|
||||
board.contraband = TRUE
|
||||
board.obj_flags |= EMAGGED
|
||||
req_access = list()
|
||||
update_static_data(user)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/cargo/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/computer/cargo/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Cargo", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "Cargo", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/cargo/ui_data()
|
||||
@@ -120,7 +113,6 @@
|
||||
var/list/data = list()
|
||||
data["requestonly"] = requestonly
|
||||
data["supplies"] = list()
|
||||
data["emagged"] = obj_flags & EMAGGED
|
||||
for(var/pack in SSshuttle.supply_packs)
|
||||
var/datum/supply_pack/P = SSshuttle.supply_packs[pack]
|
||||
if(!data["supplies"][P.group])
|
||||
@@ -135,8 +127,8 @@
|
||||
"cost" = P.cost,
|
||||
"id" = pack,
|
||||
"desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name.
|
||||
"goody" = P.goody,
|
||||
"private_goody" = P.goody == PACK_GOODY_PRIVATE,
|
||||
"goody" = P.goody == PACK_GOODY_PUBLIC,
|
||||
"access" = P.access,
|
||||
"can_private_buy" = P.can_private_buy
|
||||
))
|
||||
@@ -145,9 +137,6 @@
|
||||
/obj/machinery/computer/cargo/ui_act(action, params, datum/tgui/ui)
|
||||
if(..())
|
||||
return
|
||||
if(!allowed(usr))
|
||||
to_chat(usr, "<span class='notice'>Access denied.</span>")
|
||||
return
|
||||
switch(action)
|
||||
if("send")
|
||||
if(!SSshuttle.supply.canMove())
|
||||
@@ -179,6 +168,8 @@
|
||||
else
|
||||
SSshuttle.shuttle_loan.loan_shuttle()
|
||||
say("The supply shuttle has been loaned to CentCom.")
|
||||
investigate_log("[key_name(usr)] accepted a shuttle loan event.", INVESTIGATE_CARGO)
|
||||
log_game("[key_name(usr)] accepted a shuttle loan event.")
|
||||
. = TRUE
|
||||
if("add")
|
||||
var/id = text2path(params["id"])
|
||||
@@ -200,13 +191,15 @@
|
||||
rank = "Silicon"
|
||||
|
||||
var/datum/bank_account/account
|
||||
if(self_paid)
|
||||
if(!pack.can_private_buy && !(obj_flags & EMAGGED))
|
||||
return
|
||||
var/obj/item/card/id/id_card = usr.get_idcard(TRUE)
|
||||
if(self_paid && ishuman(usr))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
var/obj/item/card/id/id_card = H.get_idcard(TRUE)
|
||||
if(!istype(id_card))
|
||||
say("No ID card detected.")
|
||||
return
|
||||
if(istype(id_card, /obj/item/card/id/departmental_budget))
|
||||
say("The [src] rejects [id_card].")
|
||||
return
|
||||
account = id_card.registered_account
|
||||
if(!istype(account))
|
||||
say("Invalid bank account.")
|
||||
@@ -241,6 +234,9 @@
|
||||
SSshuttle.shoppinglist += SO
|
||||
if(self_paid)
|
||||
say("Order processed. The price will be charged to [account.account_holder]'s bank account on delivery.")
|
||||
if(requestonly && message_cooldown < world.time)
|
||||
radio.talk_into(src, "A new order has been requested.", RADIO_CHANNEL_SUPPLY)
|
||||
message_cooldown = world.time + 30 SECONDS
|
||||
. = TRUE
|
||||
if("remove")
|
||||
var/id = text2num(params["id"])
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#define MAX_EMAG_ROCKETS 8
|
||||
#define BEACON_COST 5000
|
||||
#define BEACON_COST 500
|
||||
#define SP_LINKED 1
|
||||
#define SP_READY 2
|
||||
#define SP_LAUNCH 3
|
||||
@@ -13,10 +13,9 @@
|
||||
All sales are near instantaneous - please choose carefully"
|
||||
icon_screen = "supply_express"
|
||||
circuit = /obj/item/circuitboard/computer/cargo/express
|
||||
ui_x = 600
|
||||
ui_y = 700
|
||||
blockade_warning = "Bluespace instability detected. Delivery impossible."
|
||||
req_access = list(ACCESS_QM)
|
||||
|
||||
var/message
|
||||
var/printed_beacons = 0 //number of beacons printed. Used to determine beacon names.
|
||||
var/list/meme_pack_data
|
||||
@@ -42,7 +41,7 @@
|
||||
to_chat(user, "<span class='notice'>You [locked ? "lock" : "unlock"] the interface.</span>")
|
||||
return
|
||||
else if(istype(W, /obj/item/disk/cargo/bluespace_pod))
|
||||
podType = /obj/structure/closet/supplypod/bluespacepod
|
||||
podType = /obj/structure/closet/supplypod/bluespacepod //doesnt effect circuit board, making reversal possible
|
||||
to_chat(user, "<span class='notice'>You insert the disk into [src], allowing for advanced supply delivery vehicles.</span>")
|
||||
qdel(W)
|
||||
return TRUE
|
||||
@@ -52,22 +51,20 @@
|
||||
sb.link_console(src, user)
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] is already linked to [sb].</span>")
|
||||
to_chat(user, "<span class='alert'>[src] is already linked to [sb].</span>")
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/cargo/express/emag_act(mob/living/user)
|
||||
. = SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT)
|
||||
if(obj_flags & EMAGGED)
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] swipes a suspicious card through [src]!</span>",
|
||||
"<span class='notice'>You change the routing protocols, allowing the Supply Pod to land anywhere on the station.</span>")
|
||||
if(user)
|
||||
user.visible_message("<span class='warning'>[user] swipes a suspicious card through [src]!</span>",
|
||||
"<span class='notice'>You change the routing protocols, allowing the Supply Pod to land anywhere on the station.</span>")
|
||||
obj_flags |= EMAGGED
|
||||
// This also sets this on the circuit board
|
||||
var/obj/item/circuitboard/computer/cargo/board = circuit
|
||||
board.obj_flags |= EMAGGED
|
||||
packin_up()
|
||||
req_access = list()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/cargo/express/proc/packin_up() // oh shit, I'm sorry
|
||||
meme_pack_data = list() // sorry for what?
|
||||
@@ -89,10 +86,10 @@
|
||||
"desc" = P.desc || P.name // If there is a description, use it. Otherwise use the pack's name.
|
||||
))
|
||||
|
||||
/obj/machinery/computer/cargo/express/ui_interact(mob/living/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) // Remember to use the appropriate state.
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/cargo/express/ui_interact(mob/living/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "CargoExpress", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "CargoExpress", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/cargo/express/ui_data(mob/user)
|
||||
@@ -131,9 +128,6 @@
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/cargo/express/ui_act(action, params, datum/tgui/ui)
|
||||
if(!allowed(usr))
|
||||
to_chat(usr, "<span class='notice'>Access denied.</span>")
|
||||
return
|
||||
switch(action)
|
||||
if("LZCargo")
|
||||
usingBeacon = FALSE
|
||||
@@ -153,6 +147,7 @@
|
||||
printed_beacons++//printed_beacons starts at 0, so the first one out will be called beacon # 1
|
||||
beacon.name = "Supply Pod Beacon #[printed_beacons]"
|
||||
|
||||
|
||||
if("add")//Generate Supply Order first
|
||||
var/id = text2path(params["id"])
|
||||
var/datum/supply_pack/pack = SSshuttle.supply_packs[id]
|
||||
@@ -195,7 +190,6 @@
|
||||
LZ = pick(empty_turfs)
|
||||
if (SO.pack.cost <= points_to_check && LZ)//we need to call the cost check again because of the CHECK_TICK call
|
||||
D.adjust_money(-SO.pack.cost)
|
||||
SSblackbox.record_feedback("nested tally", "cargo_imports", 1, list("[SO.pack.cost]", "[SO.pack.name]"))
|
||||
new /obj/effect/abstract/DPtarget(LZ, podType, SO)
|
||||
. = TRUE
|
||||
update_icon()
|
||||
@@ -209,7 +203,7 @@
|
||||
CHECK_TICK
|
||||
if(empty_turfs && empty_turfs.len)
|
||||
D.adjust_money(-(SO.pack.cost * (0.72*MAX_EMAG_ROCKETS)))
|
||||
SSblackbox.record_feedback("nested tally", "cargo_imports", MAX_EMAG_ROCKETS, list("[SO.pack.cost * 0.72]", "[SO.pack.name]"))
|
||||
|
||||
SO.generateRequisition(get_turf(src))
|
||||
for(var/i in 1 to MAX_EMAG_ROCKETS)
|
||||
var/LZ = pick(empty_turfs)
|
||||
|
||||
@@ -41,6 +41,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
if(!asset_cache_job)
|
||||
return
|
||||
|
||||
// Rate limiting
|
||||
var/mtl = CONFIG_GET(number/minute_topic_limit)
|
||||
if (!holder && mtl)
|
||||
var/minute = round(world.time, 600)
|
||||
@@ -98,6 +99,10 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
keyUp(keycode)
|
||||
return
|
||||
|
||||
// Tgui Topic middleware
|
||||
if(!tgui_Topic(href_list))
|
||||
return
|
||||
|
||||
// Admin PM
|
||||
if(href_list["priv_msg"])
|
||||
cmd_admin_pm(href_list["priv_msg"],null)
|
||||
|
||||
@@ -95,14 +95,11 @@
|
||||
icon_state = "dominator"
|
||||
density = TRUE
|
||||
var/active = FALSE
|
||||
var/obj/item/gps/gps
|
||||
var/credits_stored = 0
|
||||
var/siphon_per_tick = 5
|
||||
|
||||
/obj/machinery/shuttle_scrambler/Initialize(mapload)
|
||||
. = ..()
|
||||
gps = new/obj/item/gps/internal/pirate(src)
|
||||
gps.tracking = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/shuttle_scrambler/process()
|
||||
@@ -112,6 +109,7 @@
|
||||
if(D)
|
||||
var/siphoned = min(D.account_balance,siphon_per_tick)
|
||||
D.adjust_money(-siphoned)
|
||||
credits_stored += siphoned
|
||||
interrupt_research()
|
||||
else
|
||||
return
|
||||
@@ -120,7 +118,7 @@
|
||||
|
||||
/obj/machinery/shuttle_scrambler/proc/toggle_on(mob/user)
|
||||
SSshuttle.registerTradeBlockade(src)
|
||||
gps.tracking = TRUE
|
||||
AddComponent(/datum/component/gps, "Nautical Signal")
|
||||
active = TRUE
|
||||
to_chat(user,"<span class='notice'>You toggle [src] [active ? "on":"off"].</span>")
|
||||
to_chat(user,"<span class='warning'>The scrambling signal can be now tracked by GPS.</span>")
|
||||
@@ -130,7 +128,7 @@
|
||||
if(!active)
|
||||
if(alert(user, "Turning the scrambler on will make the shuttle trackable by GPS. Are you sure you want to do it?", "Scrambler", "Yes", "Cancel") == "Cancel")
|
||||
return
|
||||
if(active || !user.canUseTopic(src))
|
||||
if(active || !user.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
toggle_on(user)
|
||||
update_icon()
|
||||
@@ -147,35 +145,31 @@
|
||||
new /obj/effect/temp_visual/emp(get_turf(S))
|
||||
|
||||
/obj/machinery/shuttle_scrambler/proc/dump_loot(mob/user)
|
||||
new /obj/item/holochip(drop_location(), credits_stored)
|
||||
to_chat(user,"<span class='notice'>You retrieve the siphoned credits!</span>")
|
||||
credits_stored = 0
|
||||
if(credits_stored) // Prevents spamming empty holochips
|
||||
new /obj/item/holochip(drop_location(), credits_stored)
|
||||
to_chat(user,"<span class='notice'>You retrieve the siphoned credits!</span>")
|
||||
credits_stored = 0
|
||||
else
|
||||
to_chat(user,"<span class='notice'>There's nothing to withdraw.</span>")
|
||||
|
||||
/obj/machinery/shuttle_scrambler/proc/send_notification()
|
||||
priority_announce("Data theft signal detected, source registered on local gps units.")
|
||||
|
||||
/obj/machinery/shuttle_scrambler/proc/toggle_off(mob/user)
|
||||
SSshuttle.clearTradeBlockade(src)
|
||||
gps.tracking = FALSE
|
||||
active = FALSE
|
||||
STOP_PROCESSING(SSobj,src)
|
||||
|
||||
/obj/machinery/shuttle_scrambler/update_overlays()
|
||||
. = ..()
|
||||
/obj/machinery/shuttle_scrambler/update_icon_state()
|
||||
if(active)
|
||||
var/mutable_appearance/M = mutable_appearance(icon, "dominator-overlay")
|
||||
M.color = "#00FFFF"
|
||||
. += M
|
||||
icon_state = "dominator-blue"
|
||||
else
|
||||
icon_state = "dominator"
|
||||
|
||||
/obj/machinery/shuttle_scrambler/Destroy()
|
||||
toggle_off()
|
||||
QDEL_NULL(gps)
|
||||
return ..()
|
||||
|
||||
/obj/item/gps/internal/pirate
|
||||
gpstag = "Nautical Signal"
|
||||
desc = "You can hear shanties over the static."
|
||||
|
||||
/obj/machinery/computer/shuttle/pirate
|
||||
name = "pirate shuttle console"
|
||||
shuttleId = "pirateship"
|
||||
@@ -312,11 +306,10 @@
|
||||
else
|
||||
pad = locate() in range(4,src)
|
||||
|
||||
/obj/machinery/computer/piratepad_control/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/computer/piratepad_control/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "CargoHoldTerminal", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "CargoHoldTerminal", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/piratepad_control/ui_data(mob/user)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 100
|
||||
circuit = /obj/item/circuitboard/machine/smartfridge
|
||||
|
||||
var/max_n_of_items = 1500
|
||||
var/allow_ai_retrieve = FALSE
|
||||
var/list/initial_contents
|
||||
@@ -38,12 +39,10 @@
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
. += "<span class='notice'>The status display reads: This unit can hold a maximum of <b>[max_n_of_items]</b> items.</span>"
|
||||
|
||||
/obj/machinery/smartfridge/power_change()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/smartfridge/update_icon_state()
|
||||
SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays)
|
||||
if(!stat)
|
||||
SSvis_overlays.add_vis_overlay(src, icon, "smartfridge-light-mask", EMISSIVE_LAYER, EMISSIVE_PLANE, dir, alpha)
|
||||
if(visible_contents)
|
||||
switch(contents.len)
|
||||
if(0)
|
||||
@@ -66,9 +65,6 @@
|
||||
********************/
|
||||
|
||||
/obj/machinery/smartfridge/attackby(obj/item/O, mob/user, params)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
|
||||
if(default_deconstruction_screwdriver(user, icon_state, icon_state, O))
|
||||
cut_overlays()
|
||||
if(panel_open)
|
||||
@@ -87,46 +83,53 @@
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
if(stat)
|
||||
updateUsrDialog()
|
||||
return FALSE
|
||||
if(!stat)
|
||||
|
||||
if(contents.len >= max_n_of_items)
|
||||
to_chat(user, "<span class='warning'>\The [src] is full!</span>")
|
||||
return FALSE
|
||||
|
||||
if(accept_check(O))
|
||||
load(O)
|
||||
user.visible_message("[user] has added \the [O] to \the [src].", "<span class='notice'>You add \the [O] to \the [src].</span>")
|
||||
updateUsrDialog()
|
||||
if (visible_contents)
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
if(istype(O, /obj/item/storage/bag))
|
||||
var/obj/item/storage/P = O
|
||||
var/loaded = 0
|
||||
for(var/obj/G in P.contents)
|
||||
if(contents.len >= max_n_of_items)
|
||||
break
|
||||
if(accept_check(G))
|
||||
load(G)
|
||||
loaded++
|
||||
updateUsrDialog()
|
||||
|
||||
if(loaded)
|
||||
user.visible_message("[user] loads \the [src] with \the [O].", \
|
||||
"<span class='notice'>You [contents.len >= max_n_of_items ? "fill" : "load"] \the [src] with \the [O].</span>")
|
||||
if(O.contents.len > 0)
|
||||
to_chat(user, "<span class='warning'>Some items are refused.</span>")
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There is nothing in [O] to put in [src]!</span>")
|
||||
if(contents.len >= max_n_of_items)
|
||||
to_chat(user, "<span class='warning'>\The [src] is full!</span>")
|
||||
return FALSE
|
||||
|
||||
to_chat(user, "<span class='warning'>\The [src] smartly refuses [O].</span>")
|
||||
updateUsrDialog()
|
||||
return FALSE
|
||||
if(accept_check(O))
|
||||
load(O)
|
||||
user.visible_message("<span class='notice'>[user] adds \the [O] to \the [src].</span>", "<span class='notice'>You add \the [O] to \the [src].</span>")
|
||||
updateUsrDialog()
|
||||
if (visible_contents)
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
if(istype(O, /obj/item/storage/bag))
|
||||
var/obj/item/storage/P = O
|
||||
var/loaded = 0
|
||||
for(var/obj/G in P.contents)
|
||||
if(contents.len >= max_n_of_items)
|
||||
break
|
||||
if(accept_check(G))
|
||||
load(G)
|
||||
loaded++
|
||||
updateUsrDialog()
|
||||
|
||||
if(loaded)
|
||||
if(contents.len >= max_n_of_items)
|
||||
user.visible_message("<span class='notice'>[user] loads \the [src] with \the [O].</span>", \
|
||||
"<span class='notice'>You fill \the [src] with \the [O].</span>")
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] loads \the [src] with \the [O].</span>", \
|
||||
"<span class='notice'>You load \the [src] with \the [O].</span>")
|
||||
if(O.contents.len > 0)
|
||||
to_chat(user, "<span class='warning'>Some items are refused.</span>")
|
||||
if (visible_contents)
|
||||
update_icon()
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There is nothing in [O] to put in [src]!</span>")
|
||||
return FALSE
|
||||
|
||||
if(user.a_intent != INTENT_HARM)
|
||||
to_chat(user, "<span class='warning'>\The [src] smartly refuses [O].</span>")
|
||||
updateUsrDialog()
|
||||
return FALSE
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
@@ -151,16 +154,16 @@
|
||||
return TRUE
|
||||
|
||||
///Really simple proc, just moves the object "O" into the hands of mob "M" if able, done so I could modify the proc a little for the organ fridge
|
||||
/obj/machinery/smartfridge/proc/dispense(obj/item/O, var/mob/M)
|
||||
/obj/machinery/smartfridge/proc/dispense(obj/item/O, mob/M)
|
||||
if(!M.put_in_hands(O))
|
||||
O.forceMove(drop_location())
|
||||
adjust_item_drop_location(O)
|
||||
|
||||
|
||||
/obj/machinery/smartfridge/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, 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/smartfridge/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "SmartVend", name, 440, 550, master_ui, state)
|
||||
ui = new(user, src, "SmartVend", name)
|
||||
ui.set_autoupdate(FALSE)
|
||||
ui.open()
|
||||
|
||||
@@ -232,7 +235,7 @@
|
||||
// ----------------------------
|
||||
/obj/machinery/smartfridge/drying_rack
|
||||
name = "drying rack"
|
||||
desc = "A wooden contraption, used to dry plant products, food and leather."
|
||||
desc = "A wooden contraption, used to dry plant products, food and hide."
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
icon_state = "drying_rack"
|
||||
use_power = IDLE_POWER_USE
|
||||
@@ -277,6 +280,11 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
// /obj/machinery/smartfridge/drying_rack/powered() do we have this? no.
|
||||
// if(!anchored)
|
||||
// return FALSE
|
||||
// return ..()
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/power_change()
|
||||
if(powered() && anchored)
|
||||
stat &= ~NOPOWER
|
||||
@@ -285,6 +293,10 @@
|
||||
toggle_drying(TRUE)
|
||||
update_icon()
|
||||
|
||||
// . = ..()
|
||||
// if(!powered())
|
||||
// toggle_drying(TRUE)
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/load() //For updating the filled overlay
|
||||
..()
|
||||
update_icon()
|
||||
@@ -308,7 +320,7 @@
|
||||
var/obj/item/reagent_containers/food/snacks/S = O
|
||||
if(S.dried_type)
|
||||
return TRUE
|
||||
if(istype(O, /obj/item/stack/sheet/wetleather/))
|
||||
if(istype(O, /obj/item/stack/sheet/wetleather/)) //no wethide
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -386,19 +398,19 @@
|
||||
/obj/machinery/smartfridge/extract/preloaded
|
||||
initial_contents = list(/obj/item/slime_scanner = 2)
|
||||
|
||||
// ------------------------- You think you're better than Chem, huh?
|
||||
// -------------------------
|
||||
// Organ Surgery Smartfridge
|
||||
// ------------------------- Just wait till Tamiorgans
|
||||
// -------------------------
|
||||
/obj/machinery/smartfridge/organ
|
||||
name = "smart organ storage"
|
||||
desc = "A refrigerated storage unit for organ storage."
|
||||
max_n_of_items = 25 //vastly lower to prevent processing too long
|
||||
max_n_of_items = 20 //vastly lower to prevent processing too long
|
||||
var/repair_rate = 0
|
||||
|
||||
/obj/machinery/smartfridge/organ/accept_check(obj/item/O)
|
||||
if(istype(O, /obj/item/organ))
|
||||
if(isorgan(O) || isbodypart(O))
|
||||
return TRUE
|
||||
if(istype(O, /obj/item/reagent_containers/syringe))
|
||||
if(istype(O, /obj/item/reagent_containers/syringe)) //other medical things.
|
||||
return TRUE
|
||||
if(istype(O, /obj/item/reagent_containers/glass/bottle))
|
||||
return TRUE
|
||||
@@ -410,7 +422,7 @@
|
||||
. = ..()
|
||||
if(!.) //if the item loads, clear can_decompose
|
||||
return
|
||||
if(istype(O, /obj/item/organ))
|
||||
if(isorgan(O))
|
||||
var/obj/item/organ/organ = O
|
||||
organ.organ_flags |= ORGAN_FROZEN
|
||||
|
||||
@@ -426,12 +438,13 @@
|
||||
return
|
||||
O.applyOrganDamage(-repair_rate)
|
||||
|
||||
/obj/machinery/smartfridge/organ/Exited(obj/item/organ/AM, atom/newLoc)
|
||||
/obj/machinery/smartfridge/organ/Exited(atom/movable/AM, atom/newLoc)
|
||||
. = ..()
|
||||
if(istype(AM))
|
||||
AM.organ_flags &= ~ORGAN_FROZEN
|
||||
if(isorgan(AM))
|
||||
var/obj/item/organ/O = AM
|
||||
O.organ_flags &= ~ORGAN_FROZEN
|
||||
|
||||
/obj/machinery/smartfridge/organ/preloaded
|
||||
/obj/machinery/smartfridge/organ/preloaded //cit specific??????
|
||||
initial_contents = list(
|
||||
/obj/item/reagent_containers/medspray/synthtissue = 1,
|
||||
/obj/item/reagent_containers/medspray/sterilizine = 1)
|
||||
@@ -450,6 +463,15 @@
|
||||
desc = "A refrigerated storage unit for medicine storage."
|
||||
|
||||
/obj/machinery/smartfridge/chemistry/accept_check(obj/item/O)
|
||||
var/static/list/chemfridge_typecache = typecacheof(list(
|
||||
/obj/item/reagent_containers/syringe,
|
||||
/obj/item/reagent_containers/glass/bottle,
|
||||
/obj/item/reagent_containers/glass/beaker,
|
||||
/obj/item/reagent_containers/spray,
|
||||
// /obj/item/reagent_containers/medigel,
|
||||
/obj/item/reagent_containers/chem_pack
|
||||
))
|
||||
|
||||
if(istype(O, /obj/item/storage/pill_bottle))
|
||||
if(O.contents.len)
|
||||
for(var/obj/item/I in O)
|
||||
@@ -463,7 +485,7 @@
|
||||
return TRUE
|
||||
if(!O.reagents || !O.reagents.reagent_list.len) // other empty containers not accepted
|
||||
return FALSE
|
||||
if(istype(O, /obj/item/reagent_containers/syringe) || istype(O, /obj/item/reagent_containers/glass/bottle) || istype(O, /obj/item/reagent_containers/glass/beaker) || istype(O, /obj/item/reagent_containers/spray) || istype(O, /obj/item/reagent_containers/medspray) || istype(O, /obj/item/reagent_containers/chem_pack))
|
||||
if(is_type_in_typecache(O, chemfridge_typecache))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -487,6 +509,7 @@
|
||||
/obj/item/reagent_containers/glass/bottle/cold = 1,
|
||||
/obj/item/reagent_containers/glass/bottle/flu_virion = 1,
|
||||
/obj/item/reagent_containers/glass/bottle/mutagen = 1,
|
||||
/obj/item/reagent_containers/glass/bottle/sugar = 1,
|
||||
/obj/item/reagent_containers/glass/bottle/plasma = 1,
|
||||
/obj/item/reagent_containers/glass/bottle/synaptizine = 1,
|
||||
/obj/item/reagent_containers/glass/bottle/formaldehyde = 1)
|
||||
@@ -498,8 +521,8 @@
|
||||
name = "disk compartmentalizer"
|
||||
desc = "A machine capable of storing a variety of disks. Denoted by most as the DSU (disk storage unit)."
|
||||
icon_state = "disktoaster"
|
||||
visible_contents = FALSE
|
||||
pass_flags = PASSTABLE
|
||||
visible_contents = FALSE
|
||||
|
||||
/obj/machinery/smartfridge/disks/accept_check(obj/item/O)
|
||||
if(istype(O, /obj/item/disk/))
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
Holodeck Update
|
||||
|
||||
The on-station holodeck area is of type [holodeck_type].
|
||||
All types found in GLOB.holodeck_areas_per_comp_type[src.type], generated on make_datum_references_lists(),
|
||||
are loaded into the program cache or emag programs list.
|
||||
Paths with their abstract_type variable equal to themselves will be skipped.
|
||||
|
||||
All subtypes of [program_type] are loaded into the program cache or emag programs list.
|
||||
If init_program is null, a random program will be loaded on startup.
|
||||
If you don't wish this, set it to the offline program or another of your choosing.
|
||||
|
||||
@@ -15,6 +12,7 @@
|
||||
3) Create a new control console that uses those areas
|
||||
|
||||
Non-mapped areas should be skipped but you should probably comment them out anyway.
|
||||
The base of program_type will always be ignored; only subtypes will be loaded.
|
||||
*/
|
||||
|
||||
#define HOLODECK_CD 25
|
||||
@@ -26,18 +24,20 @@
|
||||
icon_screen = "holocontrol"
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 50
|
||||
|
||||
var/area/holodeck/linked
|
||||
var/area/holodeck/program
|
||||
var/area/holodeck/last_program
|
||||
var/area/offline_program = /area/holodeck/rec_center/offline
|
||||
|
||||
// Splitting this up allows two holodecks of the same size
|
||||
// to use the same source patterns. Y'know, if you want to.
|
||||
var/holodeck_type = /area/holodeck/rec_center
|
||||
|
||||
var/list/program_cache
|
||||
var/list/emag_programs
|
||||
|
||||
// Splitting this up allows two holodecks of the same size
|
||||
// to use the same source patterns. Y'know, if you want to.
|
||||
var/holodeck_type = /area/holodeck/rec_center // locate(this) to get the target holodeck
|
||||
var/program_type = /area/holodeck/rec_center // subtypes of this (but not this itself) are loadable programs
|
||||
|
||||
var/active = FALSE
|
||||
var/damaged = FALSE
|
||||
var/list/spawned = list()
|
||||
@@ -49,41 +49,47 @@
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/machinery/computer/holodeck/LateInitialize()
|
||||
linked = SSholodeck.target_holodeck_area[type]
|
||||
offline_program = SSholodeck.offline_programs[type]
|
||||
if(ispath(holodeck_type, /area))
|
||||
linked = pop(get_areas(holodeck_type, FALSE))
|
||||
if(ispath(offline_program, /area))
|
||||
offline_program = pop(get_areas(offline_program), FALSE)
|
||||
// the following is necessary for power reasons
|
||||
if(!linked || !offline_program)
|
||||
log_world("No matching holodeck area found")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
program_cache = SSholodeck.program_cache[type]
|
||||
emag_programs = SSholodeck.emag_program_cache[type]
|
||||
|
||||
// the following is necessary for power reasons
|
||||
var/area/AS = get_base_area(src)
|
||||
var/area/AS = get_area(src)
|
||||
if(istype(AS, /area/holodeck))
|
||||
log_mapping("Holodeck computer cannot be in a holodeck, This would cause circular power dependency.")
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
linked.linked = src
|
||||
|
||||
/*
|
||||
var/area/my_area = get_area(src)
|
||||
if(my_area)
|
||||
linked.power_usage = my_area.power_usage
|
||||
else
|
||||
linked.power_usage = new /list(AREA_USAGE_LEN)
|
||||
*/
|
||||
generate_program_list()
|
||||
load_program(offline_program, FALSE, FALSE)
|
||||
|
||||
/obj/machinery/computer/holodeck/Destroy()
|
||||
emergency_shutdown()
|
||||
if(linked)
|
||||
linked.linked = null
|
||||
//linked.power_usage = new /list(AREA_USAGE_LEN)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/holodeck/power_change()
|
||||
. = ..()
|
||||
toggle_power(!stat)
|
||||
|
||||
/obj/machinery/computer/holodeck/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, 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/computer/holodeck/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Holodeck", name, 400, 500, master_ui, state)
|
||||
ui = new(user, src, "Holodeck", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/holodeck/ui_data(mob/user)
|
||||
@@ -107,19 +113,27 @@
|
||||
var/program_to_load = text2path(params["type"])
|
||||
if(!ispath(program_to_load))
|
||||
return FALSE
|
||||
var/valid = FALSE
|
||||
var/list/checked = program_cache.Copy()
|
||||
if(obj_flags & EMAGGED)
|
||||
checked |= emag_programs
|
||||
for(var/prog in checked)
|
||||
var/list/P = prog
|
||||
if(P["type"] == program_to_load)
|
||||
valid = TRUE
|
||||
break
|
||||
if(!valid)
|
||||
return FALSE
|
||||
|
||||
var/area/A = locate(program_to_load) in GLOB.sortedAreas
|
||||
if(A)
|
||||
load_program(A)
|
||||
if("safety")
|
||||
if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr))
|
||||
var/msg = "[key_name(usr)] attempted to emag the holodeck using a href they shouldn't have!"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
return
|
||||
obj_flags ^= EMAGGED
|
||||
if((obj_flags & EMAGGED) && program && emag_programs[program.name])
|
||||
if((obj_flags & EMAGGED) && program)
|
||||
emergency_shutdown()
|
||||
nerf(obj_flags & EMAGGED)
|
||||
obj_flags ^= EMAGGED
|
||||
say("Safeties restored. Restarting...")
|
||||
|
||||
/obj/machinery/computer/holodeck/process()
|
||||
if(damaged && prob(10))
|
||||
@@ -160,13 +174,12 @@
|
||||
if(!LAZYLEN(emag_programs))
|
||||
to_chat(user, "[src] does not seem to have a card swipe port. It must be an inferior model.")
|
||||
return
|
||||
playsound(src, "sparks", 75, 1)
|
||||
playsound(src, "sparks", 75, TRUE)
|
||||
obj_flags |= EMAGGED
|
||||
to_chat(user, "<span class='warning'>You vastly increase projector power and override the safety and security protocols.</span>")
|
||||
to_chat(user, "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator.")
|
||||
say("Warning. Automatic shutoff and derezzing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator.")
|
||||
log_game("[key_name(user)] emagged the Holodeck Control Console")
|
||||
nerf(!(obj_flags & EMAGGED))
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/holodeck/emp_act(severity)
|
||||
. = ..()
|
||||
@@ -182,6 +195,19 @@
|
||||
emergency_shutdown()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/generate_program_list()
|
||||
for(var/typekey in subtypesof(program_type))
|
||||
var/area/holodeck/A = GLOB.areas_by_type[typekey]
|
||||
if(!A || !A.contents.len)
|
||||
continue
|
||||
var/list/info_this = list()
|
||||
info_this["name"] = A.name
|
||||
info_this["type"] = A.type
|
||||
if(A.restricted)
|
||||
LAZYADD(emag_programs, list(info_this))
|
||||
else
|
||||
LAZYADD(program_cache, list(info_this))
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/toggle_power(toggleOn = FALSE)
|
||||
if(active == toggleOn)
|
||||
return
|
||||
@@ -281,7 +307,7 @@
|
||||
silent = FALSE // otherwise make sure they are dropped
|
||||
|
||||
if(!silent)
|
||||
visible_message("[O] fades away!")
|
||||
visible_message("<span class='notice'>[O] fades away!</span>")
|
||||
qdel(O)
|
||||
|
||||
#undef HOLODECK_CD
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
var/processing = FALSE
|
||||
var/obj/item/reagent_containers/glass/beaker = null
|
||||
var/points = 0
|
||||
var/menustat = "menu"
|
||||
var/efficiency = 0
|
||||
var/productivity = 0
|
||||
var/max_items = 40
|
||||
var/datum/techweb/stored_research
|
||||
var/list/show_categories = list("Food", "Botany Chemicals", "Organic Materials")
|
||||
var/list/timesFiveCategories = list("Food", "Botany Chemicals")
|
||||
/// Currently selected category in the UI
|
||||
var/selected_cat
|
||||
|
||||
/obj/machinery/biogenerator/Initialize()
|
||||
. = ..()
|
||||
@@ -37,22 +37,20 @@
|
||||
if(A == beaker)
|
||||
beaker = null
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/biogenerator/RefreshParts()
|
||||
var/E = 0.5
|
||||
var/P = 0.5
|
||||
var/max_storage = 20
|
||||
var/E = 0
|
||||
var/P = 0
|
||||
var/max_storage = 40
|
||||
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
|
||||
P += B.rating * 0.5
|
||||
max_storage = max(20 * B.rating, max_storage)
|
||||
P += B.rating
|
||||
max_storage = 40 * B.rating
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
E += M.rating * 0.5
|
||||
E += M.rating
|
||||
efficiency = E
|
||||
productivity = P
|
||||
max_items = max_storage
|
||||
|
||||
|
||||
/obj/machinery/biogenerator/examine(mob/user)
|
||||
. = ..()
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
@@ -70,7 +68,6 @@
|
||||
icon_state = "biogen-stand"
|
||||
else
|
||||
icon_state = "biogen-work"
|
||||
return
|
||||
|
||||
/obj/machinery/biogenerator/attackby(obj/item/O, mob/user, params)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
@@ -102,7 +99,6 @@
|
||||
beaker = O
|
||||
to_chat(user, "<span class='notice'>You add the container to the machine.</span>")
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Close the maintenance panel first.</span>")
|
||||
return
|
||||
@@ -139,9 +135,9 @@
|
||||
to_chat(user, "<span class='info'>You put [O.name] in [src.name]</span>")
|
||||
return TRUE //no afterattack
|
||||
else if (istype(O, /obj/item/disk/design_disk))
|
||||
user.visible_message("[user] begins to load \the [O] in \the [src]...",
|
||||
"You begin to load a design from \the [O]...",
|
||||
"You hear the chatter of a floppy drive.")
|
||||
user.visible_message("<span class='notice'>[user] begins to load \the [O] in \the [src]...</span>",
|
||||
"<span class='notice'>You begin to load a design from \the [O]...</span>",
|
||||
"<span class='hear'>You hear the chatter of a floppy drive.</span>")
|
||||
processing = TRUE
|
||||
var/obj/item/disk/design_disk/D = O
|
||||
if(do_after(user, 10, target = src))
|
||||
@@ -153,106 +149,53 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You cannot put this in [src.name]!</span>")
|
||||
|
||||
/obj/machinery/biogenerator/ui_interact(mob/user)
|
||||
if(stat & BROKEN || panel_open)
|
||||
return
|
||||
. = ..()
|
||||
var/dat
|
||||
if(processing)
|
||||
dat += "<div class='statusDisplay'>Biogenerator is processing! Please wait...</div><BR>"
|
||||
else
|
||||
switch(menustat)
|
||||
if("nopoints")
|
||||
dat += "<div class='statusDisplay'>You do not have enough biomass to create products.<BR>Please, put growns into reactor and activate it.</div>"
|
||||
menustat = "menu"
|
||||
if("complete")
|
||||
dat += "<div class='statusDisplay'>Operation complete.</div>"
|
||||
menustat = "menu"
|
||||
if("void")
|
||||
dat += "<div class='statusDisplay'>Error: No growns inside.<BR>Please, put growns into reactor.</div>"
|
||||
menustat = "menu"
|
||||
if("nobeakerspace")
|
||||
dat += "<div class='statusDisplay'>Not enough space left in container. Unable to create product.</div>"
|
||||
menustat = "menu"
|
||||
if(beaker)
|
||||
var/categories = show_categories.Copy()
|
||||
for(var/V in categories)
|
||||
categories[V] = list()
|
||||
for(var/V in stored_research.researched_designs)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(V)
|
||||
for(var/C in categories)
|
||||
if(C in D.category)
|
||||
categories[C] += D
|
||||
|
||||
dat += "<div class='statusDisplay'>Biomass: [points] units.</div><BR>"
|
||||
dat += "<A href='?src=[REF(src)];activate=1'>Activate</A><A href='?src=[REF(src)];detach=1'>Detach Container</A>"
|
||||
for(var/cat in categories)
|
||||
dat += "<h3>[cat]:</h3>"
|
||||
dat += "<div class='statusDisplay'>"
|
||||
for(var/V in categories[cat])
|
||||
var/datum/design/D = V
|
||||
dat += "[D.name]: <A href='?src=[REF(src)];create=[D.id];amount=1'>Make</A>"
|
||||
if(cat in timesFiveCategories)
|
||||
dat += "<A href='?src=[REF(src)];create=[D.id];amount=5'>x5</A>"
|
||||
if(ispath(D.build_path, /obj/item/stack))
|
||||
dat += "<A href='?src=[REF(src)];create=[D.id];amount=10'>x10</A>"
|
||||
dat += "([CEILING(D.materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]/efficiency, 1)])<br>"
|
||||
dat += "</div>"
|
||||
else
|
||||
dat += "<div class='statusDisplay'>No container inside, please insert container.</div>"
|
||||
|
||||
var/datum/browser/popup = new(user, "biogen", name, 350, 520)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/biogenerator/AltClick(mob/living/user)
|
||||
. = ..()
|
||||
if(istype(user) && user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) && can_interact(user))
|
||||
detach(user)
|
||||
|
||||
/obj/machinery/biogenerator/proc/activate()
|
||||
if (usr.stat != CONSCIOUS)
|
||||
/**
|
||||
* activate: Activates biomass processing and converts all inserted grown products into biomass
|
||||
*
|
||||
* Arguments:
|
||||
* * user The mob starting the biomass processing
|
||||
*/
|
||||
/obj/machinery/biogenerator/proc/activate(mob/user)
|
||||
if(user.stat != CONSCIOUS)
|
||||
return
|
||||
if (src.stat != NONE) //NOPOWER etc
|
||||
if(stat != NONE)
|
||||
return
|
||||
if(processing)
|
||||
to_chat(usr, "<span class='warning'>The biogenerator is in the process of working.</span>")
|
||||
to_chat(user, "<span class='warning'>The biogenerator is in the process of working.</span>")
|
||||
return
|
||||
var/S = 0
|
||||
var/total = 0
|
||||
for(var/obj/item/reagent_containers/food/snacks/grown/I in contents)
|
||||
S += 5
|
||||
var/nutri_amount = I.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment)
|
||||
if(nutri_amount < 0.1)
|
||||
total += 1*productivity
|
||||
if(I.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment) < 0.1)
|
||||
points += 1 * productivity
|
||||
else
|
||||
total += nutri_amount*10*productivity
|
||||
points += I.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment) * 10 * productivity
|
||||
qdel(I)
|
||||
points += round(total)
|
||||
if(S)
|
||||
processing = TRUE
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
playsound(src.loc, 'sound/machines/blender.ogg', 50, 1)
|
||||
use_power(S*30)
|
||||
sleep(S+15/productivity)
|
||||
playsound(loc, 'sound/machines/blender.ogg', 50, TRUE)
|
||||
use_power(S * 30)
|
||||
sleep(S + 15 / productivity)
|
||||
if(QDELETED(src)) //let's not.
|
||||
return
|
||||
processing = FALSE
|
||||
update_icon()
|
||||
else
|
||||
menustat = "void"
|
||||
|
||||
/obj/machinery/biogenerator/proc/check_cost(list/materials, multiplier = 1, remove_points = TRUE)
|
||||
if(materials.len != 1 || materials[1] != SSmaterials.GetMaterialRef(/datum/material/biomass))
|
||||
return FALSE
|
||||
var/cost = CEILING(materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]*multiplier/efficiency, 1)
|
||||
if (cost > points)
|
||||
menustat = "nopoints"
|
||||
if (materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]*multiplier/efficiency > points)
|
||||
return FALSE
|
||||
else
|
||||
if(remove_points)
|
||||
points -= cost
|
||||
points -= materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]*multiplier/efficiency
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/biogenerator/proc/check_container_volume(list/reagents, multiplier = 1)
|
||||
@@ -262,7 +205,6 @@
|
||||
sum_reagents *= multiplier
|
||||
|
||||
if(beaker.reagents.total_volume + sum_reagents > beaker.reagents.maximum_volume)
|
||||
menustat = "nobeakerspace"
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
@@ -284,6 +226,7 @@
|
||||
var/i = amount
|
||||
while(i > 0)
|
||||
if(!check_container_volume(D.make_reagents))
|
||||
say("Warning: Attached container does not have enough free capacity!")
|
||||
return .
|
||||
if(!check_cost(D.materials))
|
||||
return .
|
||||
@@ -293,51 +236,100 @@
|
||||
beaker.reagents.add_reagent(R, D.make_reagents[R])
|
||||
. = 1
|
||||
--i
|
||||
|
||||
menustat = "complete"
|
||||
update_icon()
|
||||
return .
|
||||
|
||||
/obj/machinery/biogenerator/proc/detach(mob/living/user)
|
||||
if(beaker)
|
||||
user.put_in_hands(beaker)
|
||||
if(can_interact(user))
|
||||
user.put_in_hands(beaker)
|
||||
else
|
||||
beaker.drop_location(get_turf(src))
|
||||
beaker = null
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/biogenerator/Topic(href, href_list)
|
||||
if(..() || panel_open)
|
||||
/obj/machinery/biogenerator/ui_status(mob/user)
|
||||
if(stat & BROKEN || panel_open)
|
||||
return UI_CLOSE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/biogenerator/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/spritesheet/research_designs),
|
||||
)
|
||||
|
||||
/obj/machinery/biogenerator/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Biogenerator", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/biogenerator/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["beaker"] = beaker ? TRUE : FALSE
|
||||
data["biomass"] = points
|
||||
data["processing"] = processing
|
||||
if(locate(/obj/item/reagent_containers/food/snacks/grown) in contents)
|
||||
data["can_process"] = TRUE
|
||||
else
|
||||
data["can_process"] = FALSE
|
||||
return data
|
||||
|
||||
/obj/machinery/biogenerator/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["categories"] = list()
|
||||
|
||||
var/categories = show_categories.Copy()
|
||||
for(var/V in categories)
|
||||
categories[V] = list()
|
||||
for(var/V in stored_research.researched_designs)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(V)
|
||||
for(var/C in categories)
|
||||
if(C in D.category)
|
||||
categories[C] += D
|
||||
|
||||
for(var/category in categories)
|
||||
var/list/cat = list(
|
||||
"name" = category,
|
||||
"items" = (category == selected_cat ? list() : null))
|
||||
for(var/item in categories[category])
|
||||
var/datum/design/D = item
|
||||
cat["items"] += list(list(
|
||||
"id" = D.id,
|
||||
"name" = D.name,
|
||||
"cost" = D.materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]/efficiency,
|
||||
))
|
||||
data["categories"] += list(cat)
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/biogenerator/ui_act(action, list/params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
usr.set_machine(src)
|
||||
|
||||
if(href_list["activate"])
|
||||
activate()
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["detach"])
|
||||
detach(usr)
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["create"])
|
||||
var/amount = (text2num(href_list["amount"]))
|
||||
//Can't be outside these (if you change this keep a sane limit)
|
||||
amount = clamp(amount, 1, 50)
|
||||
var/id = href_list["create"]
|
||||
if(!stored_research.researched_designs.Find(id))
|
||||
//naughty naughty
|
||||
stack_trace("ID did not map to a researched datum [id]")
|
||||
return
|
||||
|
||||
//Get design by id (or may return error design)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(id)
|
||||
//Valid design datum, amount and the datum is not the error design, lets proceed
|
||||
if(D && amount && !istype(D, /datum/design/error_design))
|
||||
create_product(D, amount)
|
||||
//This shouldnt happen normally but href forgery is real
|
||||
else
|
||||
stack_trace("ID could not be turned into a valid techweb design datum [id]")
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["menu"])
|
||||
menustat = "menu"
|
||||
updateUsrDialog()
|
||||
switch(action)
|
||||
if("activate")
|
||||
activate(usr)
|
||||
return TRUE
|
||||
if("detach")
|
||||
detach(usr)
|
||||
return TRUE
|
||||
if("create")
|
||||
var/amount = text2num(params["amount"])
|
||||
amount = clamp(amount, 1, 10)
|
||||
if(!amount)
|
||||
return
|
||||
var/id = params["id"]
|
||||
if(!stored_research.researched_designs.Find(id))
|
||||
stack_trace("ID did not map to a researched datum [id]")
|
||||
return
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(id)
|
||||
if(D && !istype(D, /datum/design/error_design))
|
||||
create_product(D, amount)
|
||||
else
|
||||
stack_trace("ID could not be turned into a valid techweb design datum [id]")
|
||||
return
|
||||
return TRUE
|
||||
if("select")
|
||||
selected_cat = params["category"]
|
||||
return TRUE
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/**
|
||||
* Finds and extracts seeds from an object
|
||||
*
|
||||
* Checks if the object is such that creates a seed when extracted. Used by seed
|
||||
* extractors or posably anything that would create seeds in some way. The seeds
|
||||
* are dropped either at the extractor, if it exists, or where the original object
|
||||
* was and it qdel's the object
|
||||
*
|
||||
* Arguments:
|
||||
* * O - Object containing the seed, can be the loc of the dumping of seeds
|
||||
* * t_max - Amount of seed copies to dump, -1 is ranomized
|
||||
* * extractor - Seed Extractor, used as the dumping loc for the seeds and seed multiplier
|
||||
* * user - checks if we can remove the object from the inventory
|
||||
* *
|
||||
*/
|
||||
/proc/seedify(obj/item/O, t_max, obj/machinery/seed_extractor/extractor, mob/living/user)
|
||||
var/t_amount = 0
|
||||
var/list/seeds = list()
|
||||
@@ -46,20 +61,22 @@
|
||||
icon_state = "sextractor"
|
||||
density = TRUE
|
||||
circuit = /obj/item/circuitboard/machine/seed_extractor
|
||||
var/piles = list()
|
||||
/// Associated list of seeds, they are all weak refs. We check the len to see how many refs we have for each
|
||||
// seed
|
||||
var/list/piles = list()
|
||||
var/max_seeds = 1000
|
||||
var/seed_multiplier = 1
|
||||
|
||||
/obj/machinery/seed_extractor/RefreshParts()
|
||||
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
|
||||
max_seeds = 1000 * B.rating
|
||||
max_seeds = initial(max_seeds) * B.rating
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
seed_multiplier = M.rating
|
||||
seed_multiplier = initial(seed_multiplier) * M.rating
|
||||
|
||||
/obj/machinery/seed_extractor/examine(mob/user)
|
||||
. = ..()
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
. += "<span class='notice'>The status display reads: Extracting <b>[seed_multiplier]</b> seed(s) per piece of produce.<br>Machine can store up to <b>[max_seeds]</b> seeds.</span>"
|
||||
. += "<span class='notice'>The status display reads: Extracting <b>[seed_multiplier]</b> seed(s) per piece of produce.<br>Machine can store up to <b>[max_seeds]%</b> seeds.</span>"
|
||||
|
||||
/obj/machinery/seed_extractor/attackby(obj/item/O, mob/user, params)
|
||||
|
||||
@@ -102,78 +119,26 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/datum/seed_pile
|
||||
var/name = ""
|
||||
var/lifespan = 0 //Saved stats
|
||||
var/endurance = 0
|
||||
var/maturation = 0
|
||||
var/production = 0
|
||||
var/yield = 0
|
||||
var/potency = 0
|
||||
var/amount = 0
|
||||
/**
|
||||
* Generate seed string
|
||||
*
|
||||
* Creates a string based of the traits of a seed. We use this string as a bucket for all
|
||||
* seeds that match as well as the key the ui uses to get the seed. We also use the key
|
||||
* for the data shown in the ui. Javascript parses this string to display
|
||||
*
|
||||
* Arguments:
|
||||
* * O - seed to generate the string from
|
||||
*/
|
||||
/obj/machinery/seed_extractor/proc/generate_seed_string(obj/item/seeds/O)
|
||||
return "name=[O.name];lifespan=[O.lifespan];endurance=[O.endurance];maturation=[O.maturation];production=[O.production];yield=[O.yield];potency=[O.potency];instability=0"
|
||||
|
||||
/datum/seed_pile/New(var/name, var/life, var/endur, var/matur, var/prod, var/yie, var/poten, var/am = 1)
|
||||
src.name = name
|
||||
src.lifespan = life
|
||||
src.endurance = endur
|
||||
src.maturation = matur
|
||||
src.production = prod
|
||||
src.yield = yie
|
||||
src.potency = poten
|
||||
src.amount = am
|
||||
|
||||
/obj/machinery/seed_extractor/ui_interact(mob/user)
|
||||
. = ..()
|
||||
if (stat)
|
||||
return FALSE
|
||||
|
||||
var/dat = "<b>Stored seeds:</b><br>"
|
||||
|
||||
if (contents.len == 0)
|
||||
dat += "<font color='red'>No seeds</font>"
|
||||
else
|
||||
dat += "<table cellpadding='3' style='text-align:center;'><tr><td>Name</td><td>Lifespan</td><td>Endurance</td><td>Maturation</td><td>Production</td><td>Yield</td><td>Potency</td><td>Stock</td></tr>"
|
||||
for (var/datum/seed_pile/O in piles)
|
||||
dat += "<tr><td>[O.name]</td><td>[O.lifespan]</td><td>[O.endurance]</td><td>[O.maturation]</td>"
|
||||
dat += "<td>[O.production]</td><td>[O.yield]</td><td>[O.potency]</td><td>"
|
||||
dat += "<a href='byond://?src=[REF(src)];name=[O.name];li=[O.lifespan];en=[O.endurance];ma=[O.maturation];pr=[O.production];yi=[O.yield];pot=[O.potency]'>Vend</a> ([O.amount] left)</td></tr>"
|
||||
dat += "</table>"
|
||||
var/datum/browser/popup = new(user, "seed_ext", name, 700, 400)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
return
|
||||
|
||||
/obj/machinery/seed_extractor/Topic(var/href, var/list/href_list)
|
||||
if(..())
|
||||
return
|
||||
usr.set_machine(src)
|
||||
|
||||
href_list["li"] = text2num(href_list["li"])
|
||||
href_list["en"] = text2num(href_list["en"])
|
||||
href_list["ma"] = text2num(href_list["ma"])
|
||||
href_list["pr"] = text2num(href_list["pr"])
|
||||
href_list["yi"] = text2num(href_list["yi"])
|
||||
href_list["pot"] = text2num(href_list["pot"])
|
||||
|
||||
for (var/datum/seed_pile/N in piles)//Find the pile we need to reduce...
|
||||
if (href_list["name"] == N.name && href_list["li"] == N.lifespan && href_list["en"] == N.endurance && href_list["ma"] == N.maturation && href_list["pr"] == N.production && href_list["yi"] == N.yield && href_list["pot"] == N.potency)
|
||||
if(N.amount <= 0)
|
||||
return
|
||||
N.amount = max(N.amount - 1, 0)
|
||||
if (N.amount <= 0)
|
||||
piles -= N
|
||||
qdel(N)
|
||||
break
|
||||
|
||||
for (var/obj/T in contents)//Now we find the seed we need to vend
|
||||
var/obj/item/seeds/O = T
|
||||
if (O.plantname == href_list["name"] && O.lifespan == href_list["li"] && O.endurance == href_list["en"] && O.maturation == href_list["ma"] && O.production == href_list["pr"] && O.yield == href_list["yi"] && O.potency == href_list["pot"])
|
||||
O.forceMove(drop_location())
|
||||
break
|
||||
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
/** Add Seeds Proc.
|
||||
*
|
||||
* Adds the seeds to the contents and to an associated list that pregenerates the data
|
||||
* needed to go to the ui handler
|
||||
*
|
||||
**/
|
||||
/obj/machinery/seed_extractor/proc/add_seed(obj/item/seeds/O)
|
||||
if(contents.len >= 999)
|
||||
to_chat(usr, "<span class='notice'>\The [src] is full.</span>")
|
||||
@@ -188,10 +153,47 @@
|
||||
if(!M.transferItemToLoc(O, src))
|
||||
return FALSE
|
||||
|
||||
. = TRUE
|
||||
for (var/datum/seed_pile/N in piles)
|
||||
if (O.plantname == N.name && O.lifespan == N.lifespan && O.endurance == N.endurance && O.maturation == N.maturation && O.production == N.production && O.yield == N.yield && O.potency == N.potency)
|
||||
++N.amount
|
||||
return
|
||||
var/seed_string = generate_seed_string(O)
|
||||
if(piles[seed_string])
|
||||
piles[seed_string] += WEAKREF(O)
|
||||
else
|
||||
piles[seed_string] = list(WEAKREF(O))
|
||||
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/seed_extractor/ui_state(mob/user)
|
||||
return GLOB.notcontained_state
|
||||
|
||||
/obj/machinery/seed_extractor/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "SeedExtractor", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/seed_extractor/ui_data()
|
||||
var/list/V = list()
|
||||
for(var/key in piles)
|
||||
if(piles[key])
|
||||
var/len = length(piles[key])
|
||||
if(len)
|
||||
V[key] = len
|
||||
|
||||
. = list()
|
||||
.["seeds"] = V
|
||||
|
||||
/obj/machinery/seed_extractor/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("select")
|
||||
var/item = params["item"]
|
||||
if(piles[item] && length(piles[item]) > 0)
|
||||
var/datum/weakref/WO = piles[item][1]
|
||||
var/obj/item/seeds/O = WO.resolve()
|
||||
if(O)
|
||||
piles[item] -= WO
|
||||
O.forceMove(drop_location())
|
||||
. = TRUE
|
||||
//to_chat(usr, "<span class='notice'>[src] clanks to life briefly before vending [prize.equipment_name]!</span>")
|
||||
|
||||
piles += new /datum/seed_pile(O.plantname, O.lifespan, O.endurance, O.maturation, O.production, O.yield, O.potency)
|
||||
|
||||
@@ -8,10 +8,13 @@
|
||||
language_holder = null
|
||||
. = ..()
|
||||
|
||||
/datum/language_menu/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.language_menu_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/datum/language_menu/ui_state(mob/user)
|
||||
return GLOB.language_menu_state
|
||||
|
||||
/datum/language_menu/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "LanguageMenu", "Language Menu", 700, 600, master_ui, state)
|
||||
ui = new(user, src, "LanguageMenu")
|
||||
ui.open()
|
||||
|
||||
/datum/language_menu/ui_data(mob/user)
|
||||
|
||||
@@ -34,13 +34,13 @@
|
||||
if(U.check_acedia())
|
||||
to_chat(user, "<span class='notice'>None of this matters, why are you reading this? You put [title] down.</span>")
|
||||
return
|
||||
user.visible_message("[user] opens [title] and begins reading intently.")
|
||||
user.visible_message("<span class='notice'>[user] opens [title] and begins reading intently.</span>")
|
||||
ask_name(user)
|
||||
|
||||
|
||||
/obj/item/book/codex_gigas/proc/perform_research(mob/user, devilName)
|
||||
if(!devilName)
|
||||
user.visible_message("[user] closes [title] without looking anything up.")
|
||||
user.visible_message("<span class='notice'>[user] closes [title] without looking anything up.</span>")
|
||||
return
|
||||
inUse = TRUE
|
||||
var/speed = 300
|
||||
@@ -50,7 +50,7 @@
|
||||
if(U.job in list("Curator")) // the curator is both faster, and more accurate than normal crew members at research
|
||||
speed = 100
|
||||
correctness = 100
|
||||
correctness -= U.getOrganLoss(ORGAN_SLOT_BRAIN) *0.5 //Brain damage makes researching hard.
|
||||
correctness -= U.getOrganLoss(ORGAN_SLOT_BRAIN) * 0.5 //Brain damage makes researching hard.
|
||||
speed += U.getOrganLoss(ORGAN_SLOT_BRAIN) * 3
|
||||
if(do_after(user, speed, 0, user))
|
||||
var/usedName = devilName
|
||||
@@ -95,11 +95,10 @@
|
||||
currentSection = SUFFIX
|
||||
return currentSection != oldSection
|
||||
|
||||
/obj/item/book/codex_gigas/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/item/book/codex_gigas/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "CodexGigas", name, 450, 450, master_ui, state)
|
||||
ui = new(user, src, "CodexGigas", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/book/codex_gigas/ui_data(mob/user)
|
||||
|
||||
@@ -35,13 +35,13 @@
|
||||
return
|
||||
|
||||
if(existing_message)
|
||||
user.visible_message("<span class='notice'>[user] starts erasing [existing_message].</span>", "<span class='notice'>You start erasing [existing_message].</span>", "<span class='italics'>You hear a chipping sound.</span>")
|
||||
playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1)
|
||||
user.visible_message("<span class='notice'>[user] starts erasing [existing_message].</span>", "<span class='notice'>You start erasing [existing_message].</span>", "<span class='hear'>You hear a chipping sound.</span>")
|
||||
playsound(loc, 'sound/items/gavel.ogg', 50, TRUE, -1)
|
||||
if(do_after(user, tool_speed, target = existing_message))
|
||||
user.visible_message("<span class='notice'>[user] erases [existing_message].</span>", "<span class='notice'>You erase [existing_message][existing_message.creator_key == user.ckey ? ", refunding a use" : ""].</span>")
|
||||
existing_message.persists = FALSE
|
||||
qdel(existing_message)
|
||||
playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1)
|
||||
playsound(loc, 'sound/items/gavel.ogg', 50, TRUE, -1)
|
||||
if(existing_message.creator_key == user.ckey)
|
||||
refund_use()
|
||||
return
|
||||
@@ -54,12 +54,12 @@
|
||||
if(!target.Adjacent(user) && locate(/obj/structure/chisel_message) in T)
|
||||
to_chat(user, "<span class='warning'>Someone wrote here before you chose! Find another spot.</span>")
|
||||
return
|
||||
playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1)
|
||||
user.visible_message("<span class='notice'>[user] starts engraving a message into [T]...</span>", "<span class='notice'>You start engraving a message into [T]...</span>", "<span class='italics'>You hear a chipping sound.</span>")
|
||||
playsound(loc, 'sound/items/gavel.ogg', 50, TRUE, -1)
|
||||
user.visible_message("<span class='notice'>[user] starts engraving a message into [T]...</span>", "<span class='notice'>You start engraving a message into [T]...</span>", "<span class='hear'>You hear a chipping sound.</span>")
|
||||
if(can_use() && do_after(user, tool_speed, target = T) && can_use()) //This looks messy but it's actually really clever!
|
||||
if(!locate(/obj/structure/chisel_message) in T)
|
||||
user.visible_message("<span class='notice'>[user] leaves a message for future spacemen!</span>", "<span class='notice'>You engrave a message into [T]!</span>", "<span class='italics'>You hear a chipping sound.</span>")
|
||||
playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1)
|
||||
user.visible_message("<span class='notice'>[user] leaves a message for future spacemen!</span>", "<span class='notice'>You engrave a message into [T]!</span>", "<span class='hear'>You hear a chipping sound.</span>")
|
||||
playsound(loc, 'sound/items/gavel.ogg', 50, TRUE, -1)
|
||||
var/obj/structure/chisel_message/M = new(T)
|
||||
M.register(user, message)
|
||||
remove_use()
|
||||
@@ -112,12 +112,10 @@
|
||||
desc = "A message from a past traveler."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "soapstone_message"
|
||||
layer = HIGH_OBJ_LAYER
|
||||
layer = LATTICE_LAYER
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
max_integrity = 30
|
||||
layer = LATTICE_LAYER
|
||||
light_power = 0.3
|
||||
|
||||
var/hidden_message
|
||||
var/creator_key
|
||||
@@ -206,10 +204,13 @@
|
||||
/obj/structure/chisel_message/interact()
|
||||
return
|
||||
|
||||
/obj/structure/chisel_message/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)
|
||||
/obj/structure/chisel_message/ui_state(mob/user)
|
||||
return GLOB.always_state
|
||||
|
||||
/obj/structure/chisel_message/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "EngravedMessage", name, 600, 300, master_ui, state)
|
||||
ui = new(user, src, "EngravedMessage", name)
|
||||
ui.open()
|
||||
|
||||
/obj/structure/chisel_message/ui_data(mob/user)
|
||||
|
||||
@@ -8,8 +8,6 @@ GLOBAL_LIST(labor_sheet_values)
|
||||
icon = 'icons/obj/machines/mining_machines.dmi'
|
||||
icon_state = "console"
|
||||
density = FALSE
|
||||
ui_x = 315
|
||||
ui_y = 430
|
||||
|
||||
var/obj/machinery/mineral/stacking_machine/laborstacker/stacking_machine = null
|
||||
var/machinedir = SOUTH
|
||||
@@ -35,11 +33,10 @@ GLOBAL_LIST(labor_sheet_values)
|
||||
/proc/cmp_sheet_list(list/a, list/b)
|
||||
return a["value"] - b["value"]
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/mineral/labor_claim_console/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "LaborClaimConsole", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "LaborClaimConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/ui_data(mob/user)
|
||||
@@ -121,7 +118,7 @@ GLOBAL_LIST(labor_sheet_values)
|
||||
/obj/machinery/mineral/stacking_machine/laborstacker
|
||||
force_connect = TRUE
|
||||
var/points = 0 //The unclaimed value of ore stacked.
|
||||
|
||||
//damage_deflection = 21
|
||||
/obj/machinery/mineral/stacking_machine/laborstacker/process_sheet(obj/item/stack/sheet/inp)
|
||||
points += inp.point_value * inp.amount
|
||||
..()
|
||||
|
||||
@@ -195,10 +195,10 @@
|
||||
to_chat(user, "<span class='notice'>You change [src]'s I/O settings, setting the input to [dir2text(input_dir)] and the output to [dir2text(output_dir)].</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/mineral/ore_redemption/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, 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/mineral/ore_redemption/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "OreRedemptionMachine", "Ore Redemption Machine", 440, 550, master_ui, state)
|
||||
ui = new(user, src, "OreRedemptionMachine")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/mineral/ore_redemption/ui_data(mob/user)
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
icon_state = "mining"
|
||||
density = TRUE
|
||||
circuit = /obj/item/circuitboard/machine/mining_equipment_vendor
|
||||
ui_x = 425
|
||||
ui_y = 600
|
||||
var/icon_deny = "mining-deny"
|
||||
var/obj/item/card/id/inserted_id
|
||||
var/list/prize_list = list( //if you add something to this, please, for the love of god, sort it by price/type. use tabs and not spaces.
|
||||
@@ -102,17 +100,15 @@
|
||||
else
|
||||
icon_state = "[initial(icon_state)]-off"
|
||||
|
||||
/obj/machinery/mineral/equipment_vendor/ui_base_html(html)
|
||||
var/datum/asset/spritesheet/assets = get_asset_datum(/datum/asset/spritesheet/vending)
|
||||
. = replacetext(html, "<!--customheadhtml-->", assets.css_tag())
|
||||
/obj/machinery/mineral/equipment_vendor/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/spritesheet/vending),
|
||||
)
|
||||
|
||||
/obj/machinery/mineral/equipment_vendor/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/mineral/equipment_vendor/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/vending)
|
||||
assets.send(user)
|
||||
ui = new(user, src, ui_key, "MiningVendor", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "MiningVendor", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/mineral/equipment_vendor/ui_static_data(mob/user)
|
||||
@@ -137,10 +133,12 @@
|
||||
if(C)
|
||||
.["user"] = list()
|
||||
.["user"]["points"] = C.mining_points
|
||||
if(C.assignment)
|
||||
.["user"]["job"] = C.assignment
|
||||
else
|
||||
.["user"]["job"] = "No Job"
|
||||
if(C.registered_account)
|
||||
.["user"]["name"] = C.registered_account.account_holder
|
||||
if(C.registered_account.account_job)
|
||||
.["user"]["job"] = C.registered_account.account_job.title
|
||||
else
|
||||
.["user"]["job"] = "No Job"
|
||||
|
||||
/obj/machinery/mineral/equipment_vendor/ui_act(action, params)
|
||||
if(..())
|
||||
|
||||
@@ -9,9 +9,6 @@
|
||||
density = TRUE
|
||||
pressure_resistance = 5*ONE_ATMOSPHERE
|
||||
|
||||
var/ui_x = 335
|
||||
var/ui_y = 415
|
||||
|
||||
/obj/structure/ore_box/attackby(obj/item/W, mob/user, params)
|
||||
if (istype(W, /obj/item/stack/ore))
|
||||
user.transferItemToLoc(W, src)
|
||||
@@ -58,11 +55,10 @@
|
||||
stoplag()
|
||||
drop = drop_location()
|
||||
|
||||
/obj/structure/ore_box/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
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/structure/ore_box/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "OreBox", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "OreBox", name)
|
||||
ui.open()
|
||||
|
||||
/obj/structure/ore_box/ui_data()
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
set name = "Notification preferences"
|
||||
set desc = "Notification preferences"
|
||||
|
||||
var/datum/notificationpanel/panel = new(usr)
|
||||
var/datum/notificationpanel/panel = new(usr)
|
||||
|
||||
panel.ui_interact(usr)
|
||||
|
||||
|
||||
|
||||
/datum/notificationpanel
|
||||
var/client/user
|
||||
|
||||
@@ -21,10 +19,13 @@
|
||||
else
|
||||
src.user = user
|
||||
|
||||
/datum/notificationpanel/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.observer_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/datum/notificationpanel/ui_state(mob/user)
|
||||
return GLOB.observer_state
|
||||
|
||||
/datum/notificationpanel/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "NotificationPreferences", "Notification Preferences", 270, 360, master_ui, state)
|
||||
ui = new(user, src, "NotificationPreferences")
|
||||
ui.open()
|
||||
|
||||
/datum/notificationpanel/ui_data(mob/user)
|
||||
@@ -35,8 +36,7 @@
|
||||
"key" = key,
|
||||
"enabled" = (user.ckey in GLOB.poll_ignore[key]),
|
||||
"desc" = GLOB.poll_ignore_desc[key]
|
||||
))
|
||||
|
||||
))
|
||||
|
||||
/datum/notificationpanel/ui_act(action, params)
|
||||
if(..())
|
||||
|
||||
@@ -6,9 +6,12 @@
|
||||
qdel(src)
|
||||
owner = new_owner
|
||||
|
||||
/datum/orbit_menu/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.observer_state)
|
||||
/datum/orbit_menu/ui_state(mob/user)
|
||||
return GLOB.observer_state
|
||||
|
||||
/datum/orbit_menu/ui_interact(mob/user, datum/tgui/ui)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "Orbit", "Orbit", 350, 700, master_ui, state)
|
||||
ui = new(user, src, "Orbit")
|
||||
ui.open()
|
||||
|
||||
/datum/orbit_menu/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
@@ -16,11 +19,10 @@
|
||||
return
|
||||
|
||||
if (action == "orbit")
|
||||
var/list/pois = getpois(skip_mindless = 1)
|
||||
var/atom/movable/poi = pois[params["name"]]
|
||||
var/ref = params["ref"]
|
||||
var/atom/movable/poi = (locate(ref) in GLOB.mob_list) || (locate(ref) in GLOB.poi_list)
|
||||
if (poi != null)
|
||||
owner.ManualFollow(poi)
|
||||
ui.close()
|
||||
|
||||
/datum/orbit_menu/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
@@ -39,6 +41,8 @@
|
||||
|
||||
var/poi = pois[name]
|
||||
|
||||
serialized["ref"] = REF(poi)
|
||||
|
||||
var/mob/M = poi
|
||||
if (istype(M))
|
||||
if (isobserver(M))
|
||||
|
||||
@@ -287,11 +287,16 @@
|
||||
else
|
||||
ui_interact(owner)
|
||||
|
||||
/datum/action/innate/swap_body/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)
|
||||
/datum/action/innate/swap_body/ui_host(mob/user)
|
||||
return owner
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/datum/action/innate/swap_body/ui_state(mob/user)
|
||||
return GLOB.not_incapacitated_state
|
||||
|
||||
/datum/action/innate/swap_body/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "SlimeBodySwapper", name, 400, 400, master_ui, state)
|
||||
ui = new(user, src, "SlimeBodySwapper", name)
|
||||
ui.open()
|
||||
|
||||
/datum/action/innate/swap_body/ui_data(mob/user)
|
||||
@@ -361,7 +366,8 @@
|
||||
return
|
||||
switch(action)
|
||||
if("swap")
|
||||
var/mob/living/carbon/human/selected = locate(params["ref"])
|
||||
var/datum/species/jelly/slime/SS = H.dna.species
|
||||
var/mob/living/carbon/human/selected = locate(params["ref"]) in SS.bodies
|
||||
if(!can_swap(selected))
|
||||
return
|
||||
SStgui.close_uis(src)
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
to_chat(src, "Receiving control information from APC.")
|
||||
sleep(2)
|
||||
apc_override = 1
|
||||
theAPC.ui_interact(src, state = GLOB.conscious_state)
|
||||
theAPC.ui_interact(src)
|
||||
apc_override = 0
|
||||
aiRestorePowerRoutine = POWER_RESTORATION_APC_FOUND
|
||||
sleep(50)
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
return ..()
|
||||
return UI_CLOSE
|
||||
|
||||
/datum/robot_control/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/robot_control/ui_state(mob/user)
|
||||
return GLOB.always_state
|
||||
|
||||
/datum/robot_control/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "RemoteRobotControl", "Remote Robot Control", 500, 500, master_ui, state)
|
||||
ui = new(user, src, "RemoteRobotControl")
|
||||
ui.open()
|
||||
|
||||
/datum/robot_control/ui_data(mob/user)
|
||||
|
||||
@@ -29,9 +29,6 @@
|
||||
model = "MULE"
|
||||
bot_core_type = /obj/machinery/bot_core/mulebot
|
||||
|
||||
var/ui_x = 350
|
||||
var/ui_y = 425
|
||||
|
||||
var/id
|
||||
|
||||
path_image_color = "#7F5200"
|
||||
@@ -170,11 +167,10 @@
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/mob/living/simple_animal/bot/mulebot/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Mule", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "Mule", name)
|
||||
ui.open()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/ui_data(mob/user)
|
||||
@@ -191,8 +187,7 @@
|
||||
data["modeStatus"] = "average"
|
||||
if(BOT_NO_ROUTE)
|
||||
data["modeStatus"] = "bad"
|
||||
else
|
||||
data["load"] = load ? load.name : null
|
||||
data["load"] = load ? load.name : null //IF YOU CHANGE THE NAME OF THIS, UPDATE MULEBOT/PARANORMAL/UI_DATA.
|
||||
data["destination"] = destination ? destination : null
|
||||
data["home"] = home_destination
|
||||
data["destinations"] = GLOB.deliverybeacontags
|
||||
@@ -206,18 +201,20 @@
|
||||
return data
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/ui_act(action, params)
|
||||
var/silicon_access = hasSiliconAccessInArea(usr)
|
||||
if(..() || (locked && silicon_access))
|
||||
if(..() || (locked && hasSiliconAccessInArea(usr)))
|
||||
return
|
||||
switch(action)
|
||||
if("lock")
|
||||
if(silicon_access)
|
||||
if(hasSiliconAccessInArea(usr))
|
||||
locked = !locked
|
||||
. = TRUE
|
||||
if("power")
|
||||
if(on)
|
||||
turn_off()
|
||||
else if(cell && !open)
|
||||
else if(open)
|
||||
to_chat(usr, "<span class='warning'>[name]'s maintenance panel is open!</span>")
|
||||
return
|
||||
else if(cell)
|
||||
if(!turn_on())
|
||||
to_chat(usr, "<span class='warning'>You can't switch on [src]!</span>")
|
||||
return
|
||||
|
||||
@@ -73,4 +73,4 @@
|
||||
add_status_message("[client.username] has changed channel title from [title] to [newtitle]")
|
||||
title = newtitle
|
||||
|
||||
#undef MAX_CHANNELS
|
||||
#undef MAX_CHANNELS
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
/obj/proc/is_modular_computer()
|
||||
return
|
||||
|
||||
/obj/proc/get_modular_computer_part(part_type)
|
||||
return null
|
||||
|
||||
/obj/item/modular_computer/is_modular_computer()
|
||||
return TRUE
|
||||
|
||||
/obj/item/modular_computer/get_modular_computer_part(part_type)
|
||||
if(!part_type)
|
||||
stack_trace("get_modular_computer_part() called without a valid part_type")
|
||||
return null
|
||||
return all_components[part_type]
|
||||
|
||||
|
||||
/obj/machinery/modular_computer/is_modular_computer()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/modular_computer/get_modular_computer_part(part_type)
|
||||
if(!part_type)
|
||||
stack_trace("get_modular_computer_part() called without a valid part_type")
|
||||
return null
|
||||
return cpu?.all_components[part_type]
|
||||
|
||||
|
||||
/obj/proc/get_modular_computer_parts_examine(mob/user)
|
||||
. = list()
|
||||
if(!is_modular_computer())
|
||||
return
|
||||
|
||||
var/user_is_adjacent = Adjacent(user) //don't reveal full details unless they're close enough to see it on the screen anyway.
|
||||
|
||||
var/obj/item/computer_hardware/ai_slot/ai_slot = get_modular_computer_part(MC_AI)
|
||||
if(ai_slot)
|
||||
if(ai_slot.stored_card)
|
||||
if(user_is_adjacent)
|
||||
. += "It has a slot installed for an intelliCard which contains: [ai_slot.stored_card.name]"
|
||||
else
|
||||
. += "It has a slot installed for an intelliCard, which appears to be occupied."
|
||||
. += "<span class='info'>Alt-click to eject the intelliCard.</span>"
|
||||
else
|
||||
. += "It has a slot installed for an intelliCard."
|
||||
|
||||
var/obj/item/computer_hardware/card_slot/card_slot = get_modular_computer_part(MC_CARD)
|
||||
if(card_slot)
|
||||
if(card_slot.stored_card || card_slot.stored_card2)
|
||||
var/obj/item/card/id/first_ID = card_slot.stored_card
|
||||
var/obj/item/card/id/second_ID = card_slot.stored_card2
|
||||
var/multiple_cards = istype(first_ID) && istype(second_ID)
|
||||
if(user_is_adjacent)
|
||||
. += "It has two slots for identification cards installed[multiple_cards ? " which contain [first_ID] and [second_ID]" : ", one of which contains [first_ID ? first_ID : second_ID]"]."
|
||||
else
|
||||
. += "It has two slots for identification cards installed, [multiple_cards ? "both of which appear" : "and one of them appears"] to be occupied."
|
||||
. += "<span class='info'>Alt-click [src] to eject the identification card[multiple_cards ? "s":""].</span>"
|
||||
else
|
||||
. += "It has two slots installed for identification cards."
|
||||
|
||||
var/obj/item/computer_hardware/printer/printer_slot = get_modular_computer_part(MC_PRINT)
|
||||
if(printer_slot)
|
||||
. += "It has a printer installed."
|
||||
if(user_is_adjacent)
|
||||
. += "The printer's paper levels are at: [printer_slot.stored_paper]/[printer_slot.max_paper].</span>]"
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
var/enabled = 0 // Whether the computer is turned on.
|
||||
var/screen_on = 1 // Whether the computer is active/opened/it's screen is on.
|
||||
var/device_theme = "ntos" // Sets the theme for the main menu, hardware config, and file browser apps. Overridden by certain non-NT devices.
|
||||
var/datum/computer_file/program/active_program = null // A currently active program running on the computer.
|
||||
var/hardware_flag = 0 // A flag that describes this device type
|
||||
var/last_power_usage = 0
|
||||
@@ -98,7 +99,7 @@
|
||||
if(issilicon(usr))
|
||||
return
|
||||
var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
|
||||
if(usr.canUseTopic(src))
|
||||
if(usr.canUseTopic(src, BE_CLOSE))
|
||||
card_slot.try_eject(null, usr)
|
||||
|
||||
// Eject ID card from computer, if it has ID slot with card inside.
|
||||
@@ -109,7 +110,7 @@
|
||||
if(issilicon(usr))
|
||||
return
|
||||
var/obj/item/computer_hardware/ai_slot/ai_slot = all_components[MC_AI]
|
||||
if(usr.canUseTopic(src))
|
||||
if(usr.canUseTopic(src, BE_CLOSE))
|
||||
ai_slot.try_eject(null, usr,1)
|
||||
|
||||
|
||||
@@ -121,17 +122,17 @@
|
||||
if(issilicon(usr))
|
||||
return
|
||||
|
||||
if(usr.canUseTopic(src))
|
||||
if(usr.canUseTopic(src, BE_CLOSE))
|
||||
var/obj/item/computer_hardware/hard_drive/portable/portable_drive = all_components[MC_SDD]
|
||||
if(uninstall_component(portable_drive, usr))
|
||||
portable_drive.verb_pickup()
|
||||
|
||||
/obj/item/modular_computer/AltClick(mob/user)
|
||||
. = ..()
|
||||
..()
|
||||
if(issilicon(user))
|
||||
return
|
||||
|
||||
if(user.canUseTopic(src))
|
||||
if(user.canUseTopic(src, BE_CLOSE))
|
||||
var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
|
||||
var/obj/item/computer_hardware/ai_slot/ai_slot = all_components[MC_AI]
|
||||
var/obj/item/computer_hardware/hard_drive/portable/portable_drive = all_components[MC_SDD]
|
||||
@@ -143,7 +144,7 @@
|
||||
return
|
||||
if(ai_slot)
|
||||
ai_slot.try_eject(null, user)
|
||||
return TRUE
|
||||
|
||||
|
||||
// Gets IDs/access levels from card slot. Would be useful when/if PDAs would become modular PCs.
|
||||
/obj/item/modular_computer/GetAccess()
|
||||
@@ -175,7 +176,7 @@
|
||||
|
||||
/obj/item/modular_computer/MouseDrop(obj/over_object, src_location, over_location)
|
||||
var/mob/M = usr
|
||||
if((!istype(over_object, /obj/screen)) && usr.canUseTopic(src))
|
||||
if((!istype(over_object, /obj/screen)) && usr.canUseTopic(src, BE_CLOSE))
|
||||
return attack_self(M)
|
||||
return ..()
|
||||
|
||||
@@ -195,12 +196,22 @@
|
||||
|
||||
/obj/item/modular_computer/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(obj_flags & EMAGGED)
|
||||
to_chat(user, "<span class='warning'>\The [src] was already emagged.</span>")
|
||||
return
|
||||
obj_flags |= EMAGGED
|
||||
to_chat(user, "<span class='notice'>You emag \the [src]. It's screen briefly shows a \"OVERRIDE ACCEPTED: New software downloads available.\" message.</span>")
|
||||
return TRUE
|
||||
if(!enabled)
|
||||
to_chat(user, "<span class='warning'>You'd need to turn the [src] on first.</span>")
|
||||
return FALSE
|
||||
obj_flags |= EMAGGED //Mostly for consistancy purposes; the programs will do their own emag handling
|
||||
var/newemag = FALSE
|
||||
var/obj/item/computer_hardware/hard_drive/drive = all_components[MC_HDD]
|
||||
for(var/datum/computer_file/program/app in drive.stored_files)
|
||||
if(!istype(app))
|
||||
continue
|
||||
if(app.run_emag())
|
||||
newemag = TRUE
|
||||
if(newemag)
|
||||
to_chat(user, "<span class='notice'>You swipe \the [src]. A console window momentarily fills the screen, with white text rapidly scrolling past.</span>")
|
||||
return TRUE
|
||||
to_chat(user, "<span class='notice'>You swipe \the [src]. A console window fills the screen, but it quickly closes itself after only a few lines are written to it.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/item/modular_computer/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -209,13 +220,14 @@
|
||||
else if(obj_integrity < max_integrity)
|
||||
. += "<span class='warning'>It is damaged.</span>"
|
||||
|
||||
. += get_modular_computer_parts_examine(user)
|
||||
|
||||
/obj/item/modular_computer/update_icon_state()
|
||||
if(!enabled)
|
||||
icon_state = icon_state_unpowered
|
||||
else
|
||||
icon_state = icon_state_powered
|
||||
|
||||
|
||||
/obj/item/modular_computer/update_overlays()
|
||||
. = ..()
|
||||
if(!display_overlays)
|
||||
@@ -306,6 +318,8 @@
|
||||
/obj/item/modular_computer/proc/get_header_data()
|
||||
var/list/data = list()
|
||||
|
||||
data["PC_device_theme"] = device_theme
|
||||
|
||||
var/obj/item/computer_hardware/battery/battery_module = all_components[MC_CELL]
|
||||
var/obj/item/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
|
||||
|
||||
@@ -407,17 +421,17 @@
|
||||
if(install_component(W, user))
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/wrench))
|
||||
if(W.tool_behaviour == TOOL_WRENCH)
|
||||
if(all_components.len)
|
||||
to_chat(user, "<span class='warning'>Remove all components from \the [src] before disassembling it.</span>")
|
||||
return
|
||||
new /obj/item/stack/sheet/metal( get_turf(src.loc), steel_sheet_cost )
|
||||
physical.visible_message("\The [src] has been disassembled by [user].")
|
||||
physical.visible_message("<span class='notice'>\The [src] is disassembled by [user].</span>")
|
||||
relay_qdel()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/weldingtool))
|
||||
if(W.tool_behaviour == TOOL_WELDER)
|
||||
if(obj_integrity == max_integrity)
|
||||
to_chat(user, "<span class='warning'>\The [src] does not require repairs.</span>")
|
||||
return
|
||||
@@ -431,7 +445,7 @@
|
||||
to_chat(user, "<span class='notice'>You repair \the [src].</span>")
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/screwdriver))
|
||||
if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
if(!all_components.len)
|
||||
to_chat(user, "<span class='warning'>This device doesn't have any components installed.</span>")
|
||||
return
|
||||
@@ -440,7 +454,7 @@
|
||||
var/obj/item/computer_hardware/H = all_components[h]
|
||||
component_names.Add(H.name)
|
||||
|
||||
var/choice = input(user, "Which component do you want to uninstall?", "Computer maintenance", null) as null|anything in component_names
|
||||
var/choice = input(user, "Which component do you want to uninstall?", "Computer maintenance", null) as null|anything in sortList(component_names)
|
||||
|
||||
if(!choice)
|
||||
return
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
|
||||
/obj/item/modular_computer/proc/break_apart()
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
physical.visible_message("\The [src] breaks apart!")
|
||||
physical.visible_message("<span class='notice'>\The [src] breaks apart!</span>")
|
||||
var/turf/newloc = get_turf(src)
|
||||
new /obj/item/stack/sheet/metal(newloc, round(steel_sheet_cost/2))
|
||||
for(var/C in all_components)
|
||||
var/obj/item/computer_hardware/H = all_components[C]
|
||||
if(QDELETED(H))
|
||||
return
|
||||
continue
|
||||
uninstall_component(H)
|
||||
H.forceMove(newloc)
|
||||
if(prob(25))
|
||||
|
||||
@@ -28,8 +28,7 @@
|
||||
|
||||
/obj/item/modular_computer/get_cell()
|
||||
var/obj/item/computer_hardware/battery/battery_module = all_components[MC_CELL]
|
||||
if(battery_module && battery_module.battery)
|
||||
return battery_module.battery
|
||||
return battery_module?.get_cell()
|
||||
|
||||
// Used in following function to reduce copypaste
|
||||
/obj/item/modular_computer/proc/power_failure()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
ui_interact(user)
|
||||
|
||||
// Operates TGUI
|
||||
/obj/item/modular_computer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
/obj/item/modular_computer/ui_interact(mob/user, datum/tgui/ui)
|
||||
if(!enabled)
|
||||
if(ui)
|
||||
ui.close()
|
||||
@@ -14,7 +14,7 @@
|
||||
return 0
|
||||
|
||||
// Robots don't really need to see the screen, their wireless connection works as long as computer is on.
|
||||
if(!screen_on && !hasSiliconAccessInArea(user))
|
||||
if(!screen_on && !issilicon(user))
|
||||
if(ui)
|
||||
ui.close()
|
||||
return 0
|
||||
@@ -33,19 +33,17 @@
|
||||
to_chat(user, "<span class='danger'>\The [src] beeps three times, it's screen displaying a \"DISK ERROR\" warning.</span>")
|
||||
return // No HDD, No HDD files list or no stored files. Something is very broken.
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if (!ui)
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers)
|
||||
assets.send(user)
|
||||
assets = get_asset_datum(/datum/asset/simple/arcade)
|
||||
assets.send(user)
|
||||
ui = new(user, src, ui_key, "NtosMain", "NtOS Main menu", 400, 500, master_ui, state)
|
||||
ui = new(user, src, "NtosMain")
|
||||
ui.set_autoupdate(TRUE)
|
||||
ui.open()
|
||||
ui.set_autoupdate(state = 1)
|
||||
ui.send_asset(get_asset_datum(/datum/asset/simple/headers))
|
||||
|
||||
|
||||
/obj/item/modular_computer/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
data["device_theme"] = device_theme
|
||||
data["programs"] = list()
|
||||
var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
|
||||
for(var/datum/computer_file/program/P in hard_drive.stored_files)
|
||||
@@ -143,6 +141,7 @@
|
||||
set_light(comp_light_luminosity, 1, comp_light_color)
|
||||
else
|
||||
set_light(0)
|
||||
return TRUE
|
||||
|
||||
if("PC_light_color")
|
||||
var/mob/user = usr
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
icon_state_powered = "laptop"
|
||||
icon_state_unpowered = "laptop-off"
|
||||
icon_state_menu = "menu"
|
||||
display_overlays = FALSE
|
||||
|
||||
hardware_flag = PROGRAM_LAPTOP
|
||||
max_hardware_size = 2
|
||||
@@ -18,8 +19,8 @@
|
||||
screen_on = 0 // Starts closed
|
||||
var/start_open = TRUE // unless this var is set to 1
|
||||
var/icon_state_closed = "laptop-closed"
|
||||
display_overlays = FALSE
|
||||
var/w_class_open = WEIGHT_CLASS_BULKY
|
||||
var/slowdown_open = TRUE
|
||||
|
||||
/obj/item/modular_computer/laptop/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -38,6 +39,13 @@
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/obj/item/modular_computer/laptop/update_overlays()
|
||||
if(screen_on)
|
||||
return ..()
|
||||
else
|
||||
cut_overlays()
|
||||
icon_state = icon_state_closed
|
||||
|
||||
/obj/item/modular_computer/laptop/attack_self(mob/user)
|
||||
if(!screen_on)
|
||||
try_toggle_open(user)
|
||||
@@ -74,7 +82,7 @@
|
||||
return
|
||||
if(!isturf(loc) && !ismob(loc)) // No opening it in backpack.
|
||||
return
|
||||
if(!user.canUseTopic(src))
|
||||
if(!user.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
|
||||
toggle_open(user)
|
||||
@@ -83,15 +91,17 @@
|
||||
/obj/item/modular_computer/laptop/AltClick(mob/user)
|
||||
if(screen_on) // Close it.
|
||||
try_toggle_open(user)
|
||||
return TRUE
|
||||
return ..()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/modular_computer/laptop/proc/toggle_open(mob/living/user=null)
|
||||
if(screen_on)
|
||||
to_chat(user, "<span class='notice'>You close \the [src].</span>")
|
||||
slowdown = initial(slowdown)
|
||||
w_class = initial(w_class)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You open \the [src].</span>")
|
||||
slowdown = slowdown_open
|
||||
w_class = w_class_open
|
||||
|
||||
screen_on = !screen_on
|
||||
|
||||
@@ -20,4 +20,3 @@
|
||||
/obj/item/modular_computer/laptop/preset/civilian/install_programs()
|
||||
var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
|
||||
hard_drive.store_file(new/datum/computer_file/program/chatclient())
|
||||
hard_drive.store_file(new/datum/computer_file/program/nttransfer())
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Held by /obj/machinery/modular_computer to reduce amount of copy-pasted code.
|
||||
//TODO: REFACTOR THIS SPAGHETTI CODE, MAKE IT A COMPUTER_HARDWARE COMPONENT OR REMOVE IT
|
||||
/obj/item/modular_computer/processor
|
||||
name = "processing unit"
|
||||
desc = "You shouldn't see this. If you do, report it."
|
||||
@@ -11,19 +12,22 @@
|
||||
var/obj/machinery/modular_computer/machinery_computer = null
|
||||
|
||||
/obj/item/modular_computer/processor/Destroy()
|
||||
. = ..()
|
||||
if(machinery_computer && (machinery_computer.cpu == src))
|
||||
machinery_computer.cpu = null
|
||||
machinery_computer.UnregisterSignal(src, COMSIG_ATOM_UPDATED_ICON)
|
||||
machinery_computer = null
|
||||
|
||||
/obj/item/modular_computer/processor/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!loc || !istype(loc, /obj/machinery/modular_computer))
|
||||
|
||||
/obj/item/modular_computer/processor/New(comp) //intentional new probably
|
||||
..()
|
||||
STOP_PROCESSING(SSobj, src) // Processed by its machine
|
||||
|
||||
if(!comp || !istype(comp, /obj/machinery/modular_computer))
|
||||
CRASH("Inapropriate type passed to obj/item/modular_computer/processor/New()! Aborting.")
|
||||
// Obtain reference to machinery computer
|
||||
all_components = list()
|
||||
idle_threads = list()
|
||||
machinery_computer = loc
|
||||
machinery_computer = comp
|
||||
machinery_computer.cpu = src
|
||||
hardware_flag = machinery_computer.hardware_flag
|
||||
max_hardware_size = machinery_computer.max_hardware_size
|
||||
@@ -39,7 +43,7 @@
|
||||
qdel(machinery_computer)
|
||||
|
||||
// This thing is not meant to be used on it's own, get topic data from our machinery owner.
|
||||
//obj/item/modular_computer/processor/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
|
||||
//obj/item/modular_computer/processor/canUseTopic(atom/movable/M, be_close=FALSE, no_dexterity=FALSE, no_tk=FALSE)
|
||||
// if(!machinery_computer)
|
||||
// return 0
|
||||
|
||||
@@ -69,3 +73,6 @@
|
||||
machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_disk
|
||||
if(MC_AI)
|
||||
machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_card
|
||||
|
||||
/obj/item/modular_computer/processor/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
icon_state_unpowered = "tablet"
|
||||
icon_state_powered = "tablet"
|
||||
icon_state_menu = "menu"
|
||||
//worn_icon_state = "tablet"
|
||||
hardware_flag = PROGRAM_TABLET
|
||||
max_hardware_size = 1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
@@ -32,3 +33,17 @@
|
||||
slot_flags = ITEM_SLOT_ID | ITEM_SLOT_BELT
|
||||
comp_light_luminosity = 6.3
|
||||
has_variants = FALSE
|
||||
|
||||
/// Given to Nuke Ops members.
|
||||
/obj/item/modular_computer/tablet/nukeops
|
||||
icon_state = "tablet-syndicate"
|
||||
comp_light_luminosity = 6.3
|
||||
has_variants = FALSE
|
||||
device_theme = "syndicate"
|
||||
|
||||
/obj/item/modular_computer/tablet/nukeops/emag_act(mob/user)
|
||||
if(!enabled)
|
||||
to_chat(user, "<span class='warning'>You'd need to turn the [src] on first.</span>")
|
||||
return FALSE
|
||||
to_chat(user, "<span class='notice'>You swipe \the [src]. It's screen briefly shows a message reading \"MEMORY CODE INJECTION DETECTED AND SUCCESSFULLY QUARANTINED\".</span>")
|
||||
return FALSE
|
||||
|
||||
@@ -22,23 +22,38 @@
|
||||
|
||||
/obj/item/modular_computer/tablet/preset/cargo/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/computer_hardware/hard_drive/small/hard_drive = new
|
||||
install_component(new /obj/item/computer_hardware/processor_unit/small)
|
||||
install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer))
|
||||
install_component(new /obj/item/computer_hardware/hard_drive/small)
|
||||
install_component(hard_drive)
|
||||
install_component(new /obj/item/computer_hardware/network_card)
|
||||
install_component(new /obj/item/computer_hardware/printer/mini)
|
||||
hard_drive.store_file(new /datum/computer_file/program/bounty)
|
||||
//hard_drive.store_file(new /datum/computer_file/program/shipping)
|
||||
|
||||
/obj/item/modular_computer/tablet/syndicate_contract_uplink/preset/uplink/Initialize() // Given by the syndicate as part of the contract uplink bundle - loads in the Contractor Uplink.
|
||||
/// Given by the syndicate as part of the contract uplink bundle - loads in the Contractor Uplink.
|
||||
/obj/item/modular_computer/tablet/syndicate_contract_uplink/preset/uplink/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/computer_hardware/hard_drive/small/syndicate/hard_drive = new
|
||||
var/datum/computer_file/program/contract_uplink/uplink = new
|
||||
|
||||
active_program = uplink
|
||||
uplink.program_state = PROGRAM_STATE_ACTIVE
|
||||
uplink.computer = src
|
||||
|
||||
hard_drive.store_file(uplink)
|
||||
|
||||
install_component(new /obj/item/computer_hardware/processor_unit/small)
|
||||
install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer))
|
||||
install_component(hard_drive)
|
||||
install_component(new /obj/item/computer_hardware/network_card)
|
||||
install_component(new /obj/item/computer_hardware/card_slot)
|
||||
install_component(new /obj/item/computer_hardware/printer/mini)
|
||||
install_component(new /obj/item/computer_hardware/printer/mini)
|
||||
|
||||
/// Given to Nuke Ops members.
|
||||
/obj/item/modular_computer/tablet/nukeops/Initialize()
|
||||
. = ..()
|
||||
install_component(new /obj/item/computer_hardware/processor_unit/small)
|
||||
install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer))
|
||||
install_component(new /obj/item/computer_hardware/hard_drive/small/nukeops)
|
||||
install_component(new /obj/item/computer_hardware/network_card)
|
||||
|
||||
@@ -46,16 +46,12 @@
|
||||
desc = "A stationary computer. This one comes preloaded with research programs."
|
||||
_has_ai = TRUE
|
||||
|
||||
/obj/machinery/modular_computer/console/preset/research/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Alt-click to eject the intelliCard.</span>"
|
||||
|
||||
/obj/machinery/modular_computer/console/preset/research/install_programs()
|
||||
var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
|
||||
hard_drive.store_file(new/datum/computer_file/program/ntnetmonitor())
|
||||
hard_drive.store_file(new/datum/computer_file/program/nttransfer())
|
||||
hard_drive.store_file(new/datum/computer_file/program/chatclient())
|
||||
hard_drive.store_file(new/datum/computer_file/program/aidiag())
|
||||
hard_drive.store_file(new/datum/computer_file/program/robocontrol())
|
||||
|
||||
|
||||
// ===== COMMAND CONSOLE =====
|
||||
@@ -66,15 +62,27 @@
|
||||
_has_id_slot = TRUE
|
||||
_has_printer = TRUE
|
||||
|
||||
/obj/machinery/modular_computer/console/preset/command/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Alt-click [src] to eject the identification card.</span>"
|
||||
|
||||
/obj/machinery/modular_computer/console/preset/command/install_programs()
|
||||
var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
|
||||
hard_drive.store_file(new/datum/computer_file/program/chatclient())
|
||||
hard_drive.store_file(new/datum/computer_file/program/card_mod())
|
||||
|
||||
|
||||
// ===== IDENTIFICATION CONSOLE =====
|
||||
/obj/machinery/modular_computer/console/preset/id
|
||||
console_department = "Identification"
|
||||
name = "identification console"
|
||||
desc = "A stationary computer. This one comes preloaded with identification modification programs."
|
||||
_has_id_slot = TRUE
|
||||
_has_printer = TRUE
|
||||
|
||||
/obj/machinery/modular_computer/console/preset/id/install_programs()
|
||||
var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
|
||||
hard_drive.store_file(new/datum/computer_file/program/chatclient())
|
||||
hard_drive.store_file(new/datum/computer_file/program/card_mod())
|
||||
hard_drive.store_file(new/datum/computer_file/program/job_management())
|
||||
hard_drive.store_file(new/datum/computer_file/program/crew_manifest())
|
||||
|
||||
// ===== CIVILIAN CONSOLE =====
|
||||
/obj/machinery/modular_computer/console/preset/civilian
|
||||
console_department = "Civilian"
|
||||
@@ -84,5 +92,4 @@
|
||||
/obj/machinery/modular_computer/console/preset/civilian/install_programs()
|
||||
var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
|
||||
hard_drive.store_file(new/datum/computer_file/program/chatclient())
|
||||
hard_drive.store_file(new/datum/computer_file/program/nttransfer())
|
||||
hard_drive.store_file(new/datum/computer_file/program/arcade())
|
||||
|
||||
@@ -36,6 +36,10 @@
|
||||
QDEL_NULL(cpu)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/modular_computer/examine(mob/user)
|
||||
. = ..()
|
||||
. += get_modular_computer_parts_examine(user)
|
||||
|
||||
/obj/machinery/modular_computer/attack_ghost(mob/dead/observer/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -45,31 +49,31 @@
|
||||
|
||||
/obj/machinery/modular_computer/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(cpu)
|
||||
. |= cpu.emag_act(user)
|
||||
if(!cpu)
|
||||
to_chat(user, "<span class='warning'>You'd need to turn the [src] on first.</span>")
|
||||
return FALSE
|
||||
return (cpu.emag_act(user))
|
||||
|
||||
/obj/machinery/modular_computer/update_icon_state()
|
||||
if(cpu?.enabled)
|
||||
icon_state = icon_state_powered
|
||||
else if(stat & NOPOWER || !(cpu?.use_power()))
|
||||
icon_state = icon_state_unpowered
|
||||
/obj/machinery/modular_computer/update_icon()
|
||||
cut_overlays()
|
||||
icon_state = icon_state_powered
|
||||
|
||||
/obj/machinery/modular_computer/update_overlays()
|
||||
. = ..()
|
||||
if(!cpu || !cpu.enabled)
|
||||
if (!(stat & NOPOWER) && (cpu && cpu.use_power()))
|
||||
. += screen_icon_screensaver
|
||||
add_overlay(screen_icon_screensaver)
|
||||
else
|
||||
icon_state = icon_state_unpowered
|
||||
set_light(0)
|
||||
else
|
||||
set_light(light_strength)
|
||||
if(cpu.active_program)
|
||||
. += cpu.active_program.program_icon_state ? cpu.active_program.program_icon_state : screen_icon_state_menu
|
||||
add_overlay(cpu.active_program.program_icon_state ? cpu.active_program.program_icon_state : screen_icon_state_menu)
|
||||
else
|
||||
. += screen_icon_state_menu
|
||||
add_overlay(screen_icon_state_menu)
|
||||
|
||||
if(cpu && cpu.obj_integrity <= cpu.integrity_failure * cpu.max_integrity)
|
||||
. += "bsod"
|
||||
. += "broken"
|
||||
add_overlay("bsod")
|
||||
add_overlay("broken")
|
||||
|
||||
// Eject ID card from computer, if it has ID slot with card inside.
|
||||
/obj/machinery/modular_computer/proc/eject_id()
|
||||
@@ -96,10 +100,10 @@
|
||||
cpu.eject_card()
|
||||
|
||||
/obj/machinery/modular_computer/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(cpu)
|
||||
return cpu.AltClick(user)
|
||||
cpu.AltClick(user)
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
// On-click handling. Turns on the computer if it's off and opens the GUI.
|
||||
/obj/machinery/modular_computer/interact(mob/user)
|
||||
if(cpu)
|
||||
@@ -130,8 +134,7 @@
|
||||
stat &= ~NOPOWER
|
||||
update_icon()
|
||||
return
|
||||
..()
|
||||
update_icon()
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/modular_computer/attackby(var/obj/item/W as obj, mob/user)
|
||||
if(cpu && !(flags_1 & NODECONSTRUCT_1))
|
||||
@@ -144,6 +147,13 @@
|
||||
/obj/machinery/modular_computer/ex_act(severity)
|
||||
if(cpu)
|
||||
cpu.ex_act(severity)
|
||||
// switch(severity)
|
||||
// if(EXPLODE_DEVASTATE)
|
||||
// SSexplosions.highobj += cpu
|
||||
// if(EXPLODE_HEAVY)
|
||||
// SSexplosions.medobj += cpu
|
||||
// if(EXPLODE_LIGHT)
|
||||
// SSexplosions.lowobj += cpu
|
||||
..()
|
||||
|
||||
// EMPs are similar to explosions, but don't cause physical damage to the casing. Instead they screw up the components
|
||||
|
||||
@@ -52,4 +52,4 @@
|
||||
network_card.identification_string = "Unknown Console"
|
||||
if(cpu)
|
||||
cpu.screen_on = 1
|
||||
update_icon()
|
||||
update_icon()
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Modular computer programs
|
||||
|
||||
How module computer programs work
|
||||
|
||||
Ok. so a quick rundown on how to make a program. This is kind of a shitty documentation, but oh well I was asked to.
|
||||
|
||||
## Base setup
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
var/filetype = "XXX" // File full names are [filename].[filetype] so like NewFile.XXX in this case
|
||||
var/size = 1 // File size in GQ. Integers only!
|
||||
var/obj/item/computer_hardware/hard_drive/holder // Holder that contains this file.
|
||||
var/unsendable = 0 // Whether the file may be sent to someone via NTNet transfer or other means.
|
||||
var/undeletable = 0 // Whether the file may be deleted. Setting to 1 prevents deletion/renaming/etc.
|
||||
var/unsendable = FALSE // Whether the file may be sent to someone via NTNet transfer or other means.
|
||||
var/undeletable = FALSE // Whether the file may be deleted. Setting to TRUE prevents deletion/renaming/etc.
|
||||
var/uid // UID of this file
|
||||
var/static/file_uid = 0
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
return ..()
|
||||
|
||||
// Returns independent copy of this file.
|
||||
/datum/computer_file/proc/clone(rename = 0)
|
||||
/datum/computer_file/proc/clone(rename = FALSE)
|
||||
var/datum/computer_file/temp = new type
|
||||
temp.unsendable = unsendable
|
||||
temp.undeletable = undeletable
|
||||
@@ -34,4 +34,4 @@
|
||||
else
|
||||
temp.filename = filename
|
||||
temp.filetype = filetype
|
||||
return temp
|
||||
return temp
|
||||
|
||||
@@ -31,15 +31,10 @@
|
||||
var/available_on_ntnet = 1
|
||||
/// Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to 1 to enable.
|
||||
var/available_on_syndinet = 0
|
||||
/// ID of TGUI interface
|
||||
/// Name of the tgui interface
|
||||
var/tgui_id
|
||||
/// Default size of TGUI window, in pixels
|
||||
var/ui_x = 575
|
||||
var/ui_y = 700
|
||||
/// Example: "something.gif" - a header image that will be rendered in computer's UI when this program is running at background. Images are taken from /icons/program_icons. Be careful not to use too large images!
|
||||
var/ui_header = null
|
||||
///Assets specific to programs
|
||||
var/list/special_assets = list()
|
||||
|
||||
/datum/computer_file/program/New(obj/item/modular_computer/comp = null)
|
||||
..()
|
||||
@@ -69,23 +64,23 @@
|
||||
/datum/computer_file/program/proc/generate_network_log(text)
|
||||
if(computer)
|
||||
return computer.add_log(text)
|
||||
return FALSE
|
||||
return 0
|
||||
|
||||
/datum/computer_file/program/proc/is_supported_by_hardware(hardware_flag = 0, loud = 0, mob/user = null)
|
||||
if(!(hardware_flag & usage_flags))
|
||||
if(loud && computer && user)
|
||||
to_chat(user, "<span class='danger'>\The [computer] flashes an \"Hardware Error - Incompatible software\" warning.</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
to_chat(user, "<span class='danger'>\The [computer] flashes a \"Hardware Error - Incompatible software\" warning.</span>")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/datum/computer_file/program/proc/get_signal(specific_action = 0)
|
||||
if(computer)
|
||||
return computer.get_ntnet_status(specific_action)
|
||||
return FALSE
|
||||
return 0
|
||||
|
||||
// Called by Process() on device that runs us, once every tick.
|
||||
/datum/computer_file/program/proc/process_tick()
|
||||
return TRUE
|
||||
return 1
|
||||
|
||||
// Check if the user can run program. Only humans can operate computer. Automatically called in run_program()
|
||||
// User has to wear their ID for ID Scan to work.
|
||||
@@ -131,7 +126,7 @@
|
||||
return TRUE
|
||||
if(loud)
|
||||
to_chat(user, "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>")
|
||||
return FALSE
|
||||
return 0
|
||||
|
||||
// This attempts to retrieve header data for UIs. If implementing completely new device of different type than existing ones
|
||||
// always include the device here in this proc. This proc basically relays the request to whatever is running the program.
|
||||
@@ -143,11 +138,25 @@
|
||||
// This is performed on program startup. May be overridden to add extra logic. Remember to include ..() call. Return 1 on success, 0 on failure.
|
||||
// When implementing new program based device, use this to run the program.
|
||||
/datum/computer_file/program/proc/run_program(mob/living/user)
|
||||
if(can_run(user, TRUE))
|
||||
if(can_run(user, 1))
|
||||
if(requires_ntnet && network_destination)
|
||||
generate_network_log("Connection opened to [network_destination].")
|
||||
program_state = PROGRAM_STATE_ACTIVE
|
||||
return TRUE
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/**
|
||||
*
|
||||
*Called by the device when it is emagged.
|
||||
*
|
||||
*Emagging the device allows certain programs to unlock new functions. However, the program will
|
||||
*need to be downloaded first, and then handle the unlock on their own in their run_emag() proc.
|
||||
*The device will allow an emag to be run multiple times, so the user can re-emag to run the
|
||||
*override again, should they download something new. The run_emag() proc should return TRUE if
|
||||
*the emagging affected anything, and FALSE if no change was made (already emagged, or has no
|
||||
*emag functions).
|
||||
**/
|
||||
/datum/computer_file/program/proc/run_emag()
|
||||
return FALSE
|
||||
|
||||
// Use this proc to kill the program. Designed to be implemented by each program if it requires on-quit logic, such as the NTNRC client.
|
||||
@@ -155,20 +164,14 @@
|
||||
program_state = PROGRAM_STATE_KILLED
|
||||
if(network_destination)
|
||||
generate_network_log("Connection to [network_destination] closed.")
|
||||
return TRUE
|
||||
return 1
|
||||
|
||||
|
||||
/datum/computer_file/program/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/datum/computer_file/program/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui && tgui_id)
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers)
|
||||
assets.send(user)
|
||||
for(var/i in special_assets)
|
||||
assets = get_asset_datum(i)
|
||||
assets.send(user)
|
||||
|
||||
ui = new(user, src, ui_key, tgui_id, filedesc, ui_x, ui_y, state = state)
|
||||
ui = new(user, src, tgui_id, filedesc)
|
||||
ui.open()
|
||||
ui.send_asset(get_asset_datum(/datum/asset/simple/headers))
|
||||
|
||||
// CONVENTIONS, READ THIS WHEN CREATING NEW PROGRAM AND OVERRIDING THIS PROC:
|
||||
// Topic calls are automagically forwarded from NanoModule this program contains.
|
||||
@@ -177,17 +180,17 @@
|
||||
// ALWAYS INCLUDE PARENT CALL ..() OR DIE IN FIRE.
|
||||
/datum/computer_file/program/ui_act(action,list/params,datum/tgui/ui)
|
||||
if(..())
|
||||
return TRUE
|
||||
return 1
|
||||
if(computer)
|
||||
switch(action)
|
||||
if("PC_exit")
|
||||
computer.kill_program()
|
||||
ui.close()
|
||||
return TRUE
|
||||
return 1
|
||||
if("PC_shutdown")
|
||||
computer.shutdown_computer()
|
||||
ui.close()
|
||||
return TRUE
|
||||
return 1
|
||||
if("PC_minimize")
|
||||
var/mob/user = usr
|
||||
if(!computer.active_program || !computer.all_components[MC_CPU])
|
||||
|
||||
@@ -13,6 +13,6 @@
|
||||
/datum/computer_file/program/proc/event_networkfailure(background)
|
||||
kill_program(forced = TRUE)
|
||||
if(background)
|
||||
computer.visible_message("<span class='danger'>\The [computer]'s screen displays an \"Process [filename].[filetype] (PID [rand(100,999)]) terminated - Network Error\" error</span>")
|
||||
computer.visible_message("<span class='danger'>\The [computer]'s screen displays a \"Process [filename].[filetype] (PID [rand(100,999)]) terminated - Network Error\" error</span>")
|
||||
else
|
||||
computer.visible_message("<span class='danger'>\The [computer]'s screen briefly freezes and then shows \"NETWORK ERROR - NTNet connection lost. Please retry. If problem persists contact your system administrator.\" error.</span>")
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
transfer_access = ACCESS_HEADS
|
||||
available_on_ntnet = TRUE
|
||||
tgui_id = "NtosAiRestorer"
|
||||
ui_x = 370
|
||||
ui_y = 400
|
||||
/// Variable dictating if we are in the process of restoring the AI in the inserted intellicard
|
||||
var/restoring = FALSE
|
||||
|
||||
@@ -74,8 +72,8 @@
|
||||
restoring = FALSE
|
||||
return
|
||||
ai_slot.locked =TRUE
|
||||
A.adjustOxyLoss(-5, 0)
|
||||
A.adjustFireLoss(-5, 0)
|
||||
A.adjustOxyLoss(-5, 0)//, FALSE)
|
||||
A.adjustFireLoss(-5, 0)//, FALSE)
|
||||
A.adjustToxLoss(-5, 0)
|
||||
A.adjustBruteLoss(-5, 0)
|
||||
A.updatehealth()
|
||||
@@ -113,7 +111,7 @@
|
||||
data["restoring"] = restoring
|
||||
data["health"] = (AI.health + 100) / 2
|
||||
data["isDead"] = AI.stat == DEAD
|
||||
data["laws"] = AI.laws.get_law_list(include_zeroth = 1)
|
||||
data["laws"] = AI.laws.get_law_list(include_zeroth = TRUE, render_html = FALSE)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
network_destination = "alarm monitoring network"
|
||||
size = 5
|
||||
tgui_id = "NtosStationAlertConsole"
|
||||
ui_x = 315
|
||||
ui_y = 500
|
||||
|
||||
var/has_alert = 0
|
||||
var/alarms = list("Fire" = list(), "Atmosphere" = list(), "Power" = list())
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/computer_file/program/contract_uplink
|
||||
filename = "contractor uplink"
|
||||
filedesc = "Syndicate Contract Uplink"
|
||||
filedesc = "Syndicate Contractor Uplink"
|
||||
program_icon_state = "assign"
|
||||
extended_desc = "A standard, Syndicate issued system for handling important contracts while on the field."
|
||||
size = 10
|
||||
@@ -9,8 +9,6 @@
|
||||
unsendable = 1
|
||||
undeletable = 1
|
||||
tgui_id = "SyndContractor"
|
||||
ui_x = 500
|
||||
ui_y = 600
|
||||
var/error = ""
|
||||
var/info_screen = TRUE
|
||||
var/assigned = FALSE
|
||||
@@ -22,14 +20,18 @@
|
||||
/datum/computer_file/program/contract_uplink/ui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
var/mob/living/user = usr
|
||||
var/obj/item/computer_hardware/hard_drive/small/syndicate/hard_drive = computer.all_components[MC_HDD]
|
||||
|
||||
switch(action)
|
||||
if("PRG_contract-accept")
|
||||
var/contract_id = text2num(params["contract_id"])
|
||||
|
||||
// Set as the active contract
|
||||
hard_drive.traitor_data.contractor_hub.assigned_contracts[contract_id].status = CONTRACT_STATUS_ACTIVE
|
||||
hard_drive.traitor_data.contractor_hub.current_contract = hard_drive.traitor_data.contractor_hub.assigned_contracts[contract_id]
|
||||
|
||||
program_icon_state = "single_contract"
|
||||
return TRUE
|
||||
if("PRG_login")
|
||||
@@ -38,26 +40,30 @@
|
||||
// Bake their data right into the hard drive, or we don't allow non-antags gaining access to an unused
|
||||
// contract system.
|
||||
// We also create their contracts at this point.
|
||||
if(traitor_data)
|
||||
if (traitor_data)
|
||||
// Only play greet sound, and handle contractor hub when assigning for the first time.
|
||||
if(!traitor_data.contractor_hub)
|
||||
if (!traitor_data.contractor_hub)
|
||||
user.playsound_local(user, 'sound/effects/contractstartup.ogg', 100, FALSE)
|
||||
traitor_data.contractor_hub = new
|
||||
traitor_data.contractor_hub.create_hub_items()
|
||||
|
||||
// Stops any topic exploits such as logging in multiple times on a single system.
|
||||
if(!assigned)
|
||||
if (!assigned)
|
||||
traitor_data.contractor_hub.create_contracts(traitor_data.owner)
|
||||
|
||||
hard_drive.traitor_data = traitor_data
|
||||
|
||||
program_icon_state = "contracts"
|
||||
assigned = TRUE
|
||||
else
|
||||
error = "UNAUTHORIZED USER"
|
||||
return TRUE
|
||||
if("PRG_call_extraction")
|
||||
if(hard_drive.traitor_data.contractor_hub.current_contract.status != CONTRACT_STATUS_EXTRACTING)
|
||||
if(hard_drive.traitor_data.contractor_hub.current_contract.handle_extraction(user))
|
||||
if (hard_drive.traitor_data.contractor_hub.current_contract.status != CONTRACT_STATUS_EXTRACTING)
|
||||
if (hard_drive.traitor_data.contractor_hub.current_contract.handle_extraction(user))
|
||||
user.playsound_local(user, 'sound/effects/confirmdropoff.ogg', 100, TRUE)
|
||||
hard_drive.traitor_data.contractor_hub.current_contract.status = CONTRACT_STATUS_EXTRACTING
|
||||
|
||||
program_icon_state = "extracted"
|
||||
else
|
||||
user.playsound_local(user, 'sound/machines/uplinkerror.ogg', 50)
|
||||
@@ -65,15 +71,19 @@
|
||||
else
|
||||
user.playsound_local(user, 'sound/machines/uplinkerror.ogg', 50)
|
||||
error = "Already extracting... Place the target into the pod. If the pod was destroyed, this contract is no longer possible."
|
||||
|
||||
return TRUE
|
||||
if("PRG_contract_abort")
|
||||
var/contract_id = hard_drive.traitor_data.contractor_hub.current_contract.id
|
||||
|
||||
hard_drive.traitor_data.contractor_hub.current_contract = null
|
||||
hard_drive.traitor_data.contractor_hub.assigned_contracts[contract_id].status = CONTRACT_STATUS_ABORTED
|
||||
|
||||
program_icon_state = "contracts"
|
||||
|
||||
return TRUE
|
||||
if("PRG_redeem_TC")
|
||||
if(hard_drive.traitor_data.contractor_hub.contract_TC_to_redeem)
|
||||
if (hard_drive.traitor_data.contractor_hub.contract_TC_to_redeem)
|
||||
var/obj/item/stack/telecrystal/crystals = new /obj/item/stack/telecrystal(get_turf(user),
|
||||
hard_drive.traitor_data.contractor_hub.contract_TC_to_redeem)
|
||||
if(ishuman(user))
|
||||
@@ -82,13 +92,14 @@
|
||||
to_chat(H, "<span class='notice'>Your payment materializes into your hands!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>Your payment materializes onto the floor.</span>")
|
||||
|
||||
hard_drive.traitor_data.contractor_hub.contract_TC_payed_out += hard_drive.traitor_data.contractor_hub.contract_TC_to_redeem
|
||||
hard_drive.traitor_data.contractor_hub.contract_TC_to_redeem = 0
|
||||
return TRUE
|
||||
else
|
||||
user.playsound_local(user, 'sound/machines/uplinkerror.ogg', 50)
|
||||
return TRUE
|
||||
if("PRG_clear_error")
|
||||
if ("PRG_clear_error")
|
||||
error = ""
|
||||
return TRUE
|
||||
if("PRG_set_first_load_finished")
|
||||
@@ -97,10 +108,11 @@
|
||||
if("PRG_toggle_info")
|
||||
info_screen = !info_screen
|
||||
return TRUE
|
||||
if("buy_hub")
|
||||
if(hard_drive.traitor_data.owner.current == user)
|
||||
if ("buy_hub")
|
||||
if (hard_drive.traitor_data.owner.current == user)
|
||||
var/item = params["item"]
|
||||
for(var/datum/contractor_item/hub_item in hard_drive.traitor_data.contractor_hub.hub_items)
|
||||
|
||||
for (var/datum/contractor_item/hub_item in hard_drive.traitor_data.contractor_hub.hub_items)
|
||||
if (hub_item.name == item)
|
||||
hub_item.handle_purchase(hard_drive.traitor_data.contractor_hub, user)
|
||||
else
|
||||
@@ -112,13 +124,15 @@
|
||||
var/screen_to_be = null
|
||||
|
||||
data["first_load"] = first_load
|
||||
if(hard_drive && hard_drive.traitor_data != null)
|
||||
|
||||
if (hard_drive && hard_drive.traitor_data != null)
|
||||
var/datum/antagonist/traitor/traitor_data = hard_drive.traitor_data
|
||||
data += get_header_data()
|
||||
if(traitor_data.contractor_hub.current_contract)
|
||||
|
||||
if (traitor_data.contractor_hub.current_contract)
|
||||
data["ongoing_contract"] = TRUE
|
||||
screen_to_be = "single_contract"
|
||||
if(traitor_data.contractor_hub.current_contract.status == CONTRACT_STATUS_EXTRACTING)
|
||||
if (traitor_data.contractor_hub.current_contract.status == CONTRACT_STATUS_EXTRACTING)
|
||||
data["extraction_enroute"] = TRUE
|
||||
screen_to_be = "extracted"
|
||||
else
|
||||
@@ -126,15 +140,19 @@
|
||||
else
|
||||
data["ongoing_contract"] = FALSE
|
||||
data["extraction_enroute"] = FALSE
|
||||
|
||||
data["logged_in"] = TRUE
|
||||
data["station_name"] = GLOB.station_name
|
||||
data["redeemable_tc"] = traitor_data.contractor_hub.contract_TC_to_redeem
|
||||
data["earned_tc"] = traitor_data.contractor_hub.contract_TC_payed_out
|
||||
data["contracts_completed"] = traitor_data.contractor_hub.contracts_completed
|
||||
data["contract_rep"] = traitor_data.contractor_hub.contract_rep
|
||||
|
||||
data["info_screen"] = info_screen
|
||||
|
||||
data["error"] = error
|
||||
for(var/datum/contractor_item/hub_item in traitor_data.contractor_hub.hub_items)
|
||||
|
||||
for (var/datum/contractor_item/hub_item in traitor_data.contractor_hub.hub_items)
|
||||
data["contractor_hub_items"] += list(list(
|
||||
"name" = hub_item.name,
|
||||
"desc" = hub_item.desc,
|
||||
@@ -142,7 +160,8 @@
|
||||
"limited" = hub_item.limited,
|
||||
"item_icon" = hub_item.item_icon
|
||||
))
|
||||
for(var/datum/syndicate_contract/contract in traitor_data.contractor_hub.assigned_contracts)
|
||||
|
||||
for (var/datum/syndicate_contract/contract in traitor_data.contractor_hub.assigned_contracts)
|
||||
data["contracts"] += list(list(
|
||||
"target" = contract.contract.target,
|
||||
"target_rank" = contract.target_rank,
|
||||
@@ -155,23 +174,28 @@
|
||||
))
|
||||
|
||||
var/direction
|
||||
if(traitor_data.contractor_hub.current_contract)
|
||||
if (traitor_data.contractor_hub.current_contract)
|
||||
var/turf/curr = get_turf(user)
|
||||
var/turf/dropoff_turf
|
||||
data["current_location"] = "[get_area_name(curr, TRUE)]"
|
||||
for(var/turf/content in traitor_data.contractor_hub.current_contract.contract.dropoff.contents)
|
||||
if(isturf(content))
|
||||
|
||||
for (var/turf/content in traitor_data.contractor_hub.current_contract.contract.dropoff.contents)
|
||||
if (isturf(content))
|
||||
dropoff_turf = content
|
||||
break
|
||||
|
||||
if(curr.z == dropoff_turf.z) //Direction calculations for same z-level only
|
||||
direction = uppertext(dir2text(get_dir(curr, dropoff_turf))) //Direction text (East, etc). Not as precise, but still helpful.
|
||||
if(get_area(user) == traitor_data.contractor_hub.current_contract.contract.dropoff)
|
||||
direction = "LOCATION CONFIRMED"
|
||||
else
|
||||
direction = "???"
|
||||
|
||||
data["dropoff_direction"] = direction
|
||||
|
||||
else
|
||||
data["logged_in"] = FALSE
|
||||
|
||||
program_icon_state = screen_to_be
|
||||
update_computer_icon()
|
||||
return data
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
available_on_ntnet = FALSE
|
||||
available_on_syndinet = TRUE
|
||||
tgui_id = "NtosNetDos"
|
||||
ui_x = 400
|
||||
ui_y = 250
|
||||
|
||||
var/obj/machinery/ntnet_relay/target = null
|
||||
var/dos_speed = 0
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
available_on_ntnet = FALSE
|
||||
available_on_syndinet = TRUE
|
||||
tgui_id = "NtosRevelation"
|
||||
ui_x = 400
|
||||
ui_y = 250
|
||||
|
||||
var/armed = 0
|
||||
|
||||
/datum/computer_file/program/revelation/run_program(var/mob/living/user)
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
network_destination = "arcade network"
|
||||
size = 6
|
||||
tgui_id = "NtosArcade"
|
||||
ui_x = 450
|
||||
ui_y = 350
|
||||
|
||||
///Returns TRUE if the game is being played.
|
||||
var/game_active = TRUE
|
||||
@@ -27,6 +25,7 @@
|
||||
|
||||
/datum/computer_file/program/arcade/proc/game_check(mob/user)
|
||||
sleep(5)
|
||||
//user?.mind?.adjust_experience(/datum/skill/gaming, 1) No gaming(TM) Yet
|
||||
if(boss_hp <= 0)
|
||||
heads_up = "You have crushed [boss_name]! Rejoice!"
|
||||
playsound(computer.loc, 'sound/arcade/win.ogg', 50, TRUE, extrarange = -3, falloff = 10)
|
||||
@@ -35,6 +34,7 @@
|
||||
if(istype(computer))
|
||||
computer.update_icon()
|
||||
ticket_count += 1
|
||||
//user?.mind?.adjust_experience(/datum/skill/gaming, 50)
|
||||
sleep(10)
|
||||
else if(player_hp <= 0 || player_mp <= 0)
|
||||
heads_up = "You have been defeated... how will the station survive?"
|
||||
@@ -43,6 +43,7 @@
|
||||
program_icon_state = "arcade_off"
|
||||
if(istype(computer))
|
||||
computer.update_icon()
|
||||
//user?.mind?.adjust_experience(/datum/skill/gaming, 10)
|
||||
sleep(10)
|
||||
|
||||
/datum/computer_file/program/arcade/proc/enemy_check(mob/user)
|
||||
@@ -73,14 +74,13 @@
|
||||
pause_state = FALSE
|
||||
game_check()
|
||||
|
||||
/datum/computer_file/program/arcade/ui_interact(mob/user, ui_key, datum/tgui/ui, force_open, datum/tgui/master_ui, datum/ui_state/state)
|
||||
. = ..()
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/arcade)
|
||||
assets.send(user)
|
||||
/datum/computer_file/program/arcade/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/simple/arcade),
|
||||
)
|
||||
|
||||
/datum/computer_file/program/arcade/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
|
||||
data["Hitpoints"] = boss_hp
|
||||
data["PlayerHitpoints"] = player_hp
|
||||
data["PlayerMP"] = player_mp
|
||||
@@ -98,11 +98,13 @@
|
||||
if(computer)
|
||||
printer = computer.all_components[MC_PRINT]
|
||||
|
||||
//var/gamerSkillLevel = usr.mind?.get_skill_level(/datum/skill/gaming)
|
||||
//var/gamerSkill = usr.mind?.get_skill_modifier(/datum/skill/gaming, SKILL_RANDS_MODIFIER)
|
||||
switch(action)
|
||||
if("Attack")
|
||||
var/attackamt = 0 //Spam prevention.
|
||||
if(pause_state == FALSE)
|
||||
attackamt = rand(2,6)
|
||||
attackamt = rand(2,6)// + rand(0, gamerSkill)
|
||||
pause_state = TRUE
|
||||
heads_up = "You attack for [attackamt] damage."
|
||||
playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3, falloff = 10)
|
||||
@@ -115,8 +117,10 @@
|
||||
var/healamt = 0 //More Spam Prevention.
|
||||
var/healcost = 0
|
||||
if(pause_state == FALSE)
|
||||
healamt = rand(6,8)
|
||||
healamt = rand(6,8)// + rand(0, gamerSkill)
|
||||
var/maxPointCost = 3
|
||||
//if(gamerSkillLevel >= SKILL_LEVEL_JOURNEYMAN)
|
||||
// maxPointCost = 2
|
||||
healcost = rand(1, maxPointCost)
|
||||
pause_state = TRUE
|
||||
heads_up = "You heal for [healamt] damage."
|
||||
@@ -130,7 +134,7 @@
|
||||
if("Recharge_Power")
|
||||
var/rechargeamt = 0 //As above.
|
||||
if(pause_state == FALSE)
|
||||
rechargeamt = rand(4, 7)
|
||||
rechargeamt = rand(4,7)// + rand(0, gamerSkill)
|
||||
pause_state = TRUE
|
||||
heads_up = "You regain [rechargeamt] magic power."
|
||||
playsound(computer.loc, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3, falloff = 10)
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
network_destination = "atmos scan"
|
||||
size = 4
|
||||
tgui_id = "NtosAtmos"
|
||||
ui_x = 300
|
||||
ui_y = 350
|
||||
|
||||
/datum/computer_file/program/atmosscan/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
@@ -15,16 +13,16 @@
|
||||
var/turf/T = get_turf(ui_host())
|
||||
if(T)
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
var/list/env_gases = environment.gases
|
||||
var/list/env_gases = environment.get_gases()
|
||||
var/pressure = environment.return_pressure()
|
||||
var/total_moles = environment.total_moles()
|
||||
data["AirPressure"] = round(pressure,0.1)
|
||||
data["AirTemp"] = round(environment.temperature-T0C)
|
||||
data["AirTemp"] = round(environment.return_temperature()-T0C)
|
||||
if (total_moles)
|
||||
for(var/id in env_gases)
|
||||
var/gas_level = env_gases[id][MOLES]/total_moles
|
||||
var/gas_level = environment.get_moles(id)/total_moles
|
||||
if(gas_level > 0)
|
||||
airlist += list(list("name" = "[env_gases[id][GAS_META][META_GAS_NAME]]", "percentage" = round(gas_level*100, 0.01)))
|
||||
airlist += list(list("name" = "[GLOB.meta_gas_names[id]]", "percentage" = round(gas_level*100, 0.01)))
|
||||
data["AirData"] = airlist
|
||||
return data
|
||||
|
||||
|
||||
@@ -9,21 +9,17 @@
|
||||
network_destination = "cyborg remote monitoring"
|
||||
size = 5
|
||||
tgui_id = "NtosCyborgRemoteMonitor"
|
||||
ui_x = 600
|
||||
ui_y = 800
|
||||
|
||||
/datum/computer_file/program/borg_monitor/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
|
||||
data["card"] = FALSE
|
||||
if(computer.GetID())
|
||||
if(checkID())
|
||||
data["card"] = TRUE
|
||||
|
||||
data["cyborgs"] = list()
|
||||
for(var/mob/living/silicon/robot/R in GLOB.silicon_mobs)
|
||||
if((get_turf(computer)).z != (get_turf(R)).z)
|
||||
continue
|
||||
if(R.scrambledcodes)
|
||||
if(!evaluate_borg(R))
|
||||
continue
|
||||
|
||||
var/list/upgrade
|
||||
@@ -36,7 +32,7 @@
|
||||
|
||||
var/list/cyborg_data = list(
|
||||
name = R.name,
|
||||
locked_down = R.locked_down,
|
||||
locked_down = R.lockcharge,
|
||||
status = R.stat,
|
||||
shell_discon = shell,
|
||||
charge = R.cell ? round(R.cell.percent()) : null,
|
||||
@@ -56,14 +52,53 @@
|
||||
var/mob/living/silicon/robot/R = locate(params["ref"]) in GLOB.silicon_mobs
|
||||
if(!istype(R))
|
||||
return
|
||||
var/obj/item/card/id/ID = computer.GetID()
|
||||
var/ID = checkID()
|
||||
if(!ID)
|
||||
return
|
||||
var/message = stripped_input(usr, message = "Enter message to be sent to remote cyborg.", title = "Send Message")
|
||||
if(!message)
|
||||
return
|
||||
to_chat(R, "<br><br><span class='notice'>Message from [ID.registered_name] -- \"[message]\"</span><br>")
|
||||
to_chat(R, "<br><br><span class='notice'>Message from [ID] -- \"[message]\"</span><br>")
|
||||
SEND_SOUND(R, 'sound/machines/twobeep_high.ogg')
|
||||
if(R.connected_ai)
|
||||
to_chat(R.connected_ai, "<br><br><span class='notice'>Message from [ID.registered_name] to [R] -- \"[message]\"</span><br>")
|
||||
to_chat(R.connected_ai, "<br><br><span class='notice'>Message from [ID] to [R] -- \"[message]\"</span><br>")
|
||||
SEND_SOUND(R.connected_ai, 'sound/machines/twobeep_high.ogg')
|
||||
usr.log_talk(message, LOG_PDA, tag="Cyborg Monitor Program: ID name \"[ID]\" to [R]")
|
||||
|
||||
///This proc is used to determin if a borg should be shown in the list (based on the borg's scrambledcodes var). Syndicate version overrides this to show only syndicate borgs.
|
||||
/datum/computer_file/program/borg_monitor/proc/evaluate_borg(mob/living/silicon/robot/R)
|
||||
if((get_turf(computer)).z != (get_turf(R)).z)
|
||||
return FALSE
|
||||
if(R.scrambledcodes)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
///Gets the ID's name, if one is inserted into the device. This is a seperate proc solely to be overridden by the syndicate version of the app.
|
||||
/datum/computer_file/program/borg_monitor/proc/checkID()
|
||||
var/obj/item/card/id/ID = computer.GetID()
|
||||
if(!ID)
|
||||
return FALSE
|
||||
return ID.registered_name
|
||||
|
||||
/datum/computer_file/program/borg_monitor/syndicate
|
||||
filename = "scyborgmonitor"
|
||||
filedesc = "Mission-Specific Cyborg Remote Monitoring"
|
||||
ui_header = "borg_mon.gif"
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "This program allows for remote monitoring of mission-assigned cyborgs."
|
||||
requires_ntnet = FALSE
|
||||
available_on_ntnet = FALSE
|
||||
available_on_syndinet = TRUE
|
||||
transfer_access = null
|
||||
network_destination = "cyborg remote monitoring"
|
||||
tgui_id = "NtosCyborgRemoteMonitorSyndicate"
|
||||
|
||||
/datum/computer_file/program/borg_monitor/syndicate/evaluate_borg(mob/living/silicon/robot/R)
|
||||
if((get_turf(computer)).z != (get_turf(R)).z)
|
||||
return FALSE
|
||||
if(!R.scrambledcodes)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/borg_monitor/syndicate/checkID()
|
||||
return "\[CLASSIFIED\]" //no ID is needed for the syndicate version's message function, and the borg will see "[CLASSIFIED]" as the message sender.
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/datum/computer_file/program/bounty_board
|
||||
filename = "bountyboard"
|
||||
filedesc = "Bounty Board Request Network"
|
||||
program_icon_state = "bountyboard"
|
||||
extended_desc = "A multi-platform network for placing requests across the station, with payment across the network being possible.."
|
||||
requires_ntnet = TRUE
|
||||
network_destination = "bounty board interface"
|
||||
size = 10
|
||||
tgui_id = "NtosRequestKiosk"
|
||||
///Reference to the currently logged in user.
|
||||
var/datum/bank_account/current_user
|
||||
///The station request datum being affected by UI actions.
|
||||
var/datum/station_request/active_request
|
||||
///Value of the currently bounty input
|
||||
var/bounty_value = 1
|
||||
///Text of the currently written bounty
|
||||
var/bounty_text = ""
|
||||
///Has the app been added to the network yet?
|
||||
var/networked = FALSE
|
||||
|
||||
/datum/computer_file/program/bounty_board/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
var/list/formatted_requests = list()
|
||||
var/list/formatted_applicants = list()
|
||||
var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD]
|
||||
if(!networked)
|
||||
GLOB.allbountyboards += computer
|
||||
networked = TRUE
|
||||
if(card_slot && card_slot.stored_card && card_slot.stored_card.registered_account)
|
||||
current_user = card_slot.stored_card.registered_account
|
||||
for(var/i in GLOB.request_list)
|
||||
if(!i)
|
||||
continue
|
||||
var/datum/station_request/request = i
|
||||
formatted_requests += list(list("owner" = request.owner, "value" = request.value, "description" = request.description, "acc_number" = request.req_number))
|
||||
if(request.applicants)
|
||||
for(var/datum/bank_account/j in request.applicants)
|
||||
formatted_applicants += list(list("name" = j.account_holder, "request_id" = request.owner_account.account_id, "requestee_id" = j.account_id))
|
||||
if(current_user)
|
||||
data["accountName"] = current_user.account_holder
|
||||
data["requests"] = formatted_requests
|
||||
data["applicants"] = formatted_applicants
|
||||
data["bountyValue"] = bounty_value
|
||||
data["bountyText"] = bounty_text
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/bounty_board/ui_act(action, list/params)
|
||||
if(..())
|
||||
return
|
||||
var/current_ref_num = params["request"]
|
||||
var/current_app_num = params["applicant"]
|
||||
var/datum/bank_account/request_target
|
||||
if(current_ref_num)
|
||||
for(var/datum/station_request/i in GLOB.request_list)
|
||||
if("[i.req_number]" == "[current_ref_num]")
|
||||
active_request = i
|
||||
break
|
||||
if(active_request)
|
||||
for(var/datum/bank_account/j in active_request.applicants)
|
||||
if("[j.account_id]" == "[current_app_num]")
|
||||
request_target = j
|
||||
break
|
||||
switch(action)
|
||||
if("createBounty")
|
||||
if(!current_user || !bounty_text)
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 20, TRUE)
|
||||
return TRUE
|
||||
for(var/datum/station_request/i in GLOB.request_list)
|
||||
if("[i.req_number]" == "[current_user.account_id]")
|
||||
computer.say("Account already has active bounty.")
|
||||
return
|
||||
var/datum/station_request/curr_request = new /datum/station_request(current_user.account_holder, bounty_value,bounty_text,current_user.account_id, current_user)
|
||||
GLOB.request_list += list(curr_request)
|
||||
for(var/obj/i in GLOB.allbountyboards)
|
||||
i.say("New bounty has been added!")
|
||||
playsound(i.loc, 'sound/effects/cashregister.ogg', 30, TRUE)
|
||||
return TRUE
|
||||
if("apply")
|
||||
if(!current_user)
|
||||
computer.say("Please swipe a valid ID first.")
|
||||
return TRUE
|
||||
if(current_user.account_holder == active_request.owner)
|
||||
playsound(computer, 'sound/machines/buzz-sigh.ogg', 20, TRUE)
|
||||
return TRUE
|
||||
active_request.applicants += list(current_user)
|
||||
if("payApplicant")
|
||||
if(!current_user)
|
||||
return
|
||||
if(!current_user.has_money(active_request.value) || (current_user.account_holder != active_request.owner))
|
||||
playsound(computer, 'sound/machines/buzz-sigh.ogg', 30, TRUE)
|
||||
return
|
||||
request_target.transfer_money(current_user, active_request.value)
|
||||
computer.say("Paid out [active_request.value] credits.")
|
||||
return TRUE
|
||||
if("clear")
|
||||
if(current_user)
|
||||
current_user = null
|
||||
computer.say("Account Reset.")
|
||||
return TRUE
|
||||
if("deleteRequest")
|
||||
if(!current_user)
|
||||
playsound(computer, 'sound/machines/buzz-sigh.ogg', 20, TRUE)
|
||||
return TRUE
|
||||
if(active_request.owner != current_user.account_holder)
|
||||
playsound(computer, 'sound/machines/buzz-sigh.ogg', 20, TRUE)
|
||||
return TRUE
|
||||
computer.say("Deleted current request.")
|
||||
GLOB.request_list.Remove(active_request)
|
||||
return TRUE
|
||||
if("bountyVal")
|
||||
bounty_value = text2num(params["bountyval"])
|
||||
if(!bounty_value)
|
||||
bounty_value = 1
|
||||
if("bountyText")
|
||||
bounty_text = (params["bountytext"])
|
||||
. = TRUE
|
||||
|
||||
/datum/computer_file/program/bounty_board/Destroy()
|
||||
GLOB.allbountyboards -= computer
|
||||
. = ..()
|
||||
@@ -15,8 +15,6 @@
|
||||
requires_ntnet = 0
|
||||
size = 8
|
||||
tgui_id = "NtosCard"
|
||||
ui_x = 450
|
||||
ui_y = 520
|
||||
|
||||
var/is_centcom = FALSE
|
||||
var/minor = FALSE
|
||||
@@ -275,7 +273,7 @@
|
||||
departments = list("CentCom" = get_all_centcom_jobs())
|
||||
else if(isnull(departments))
|
||||
departments = list(
|
||||
CARDCON_DEPARTMENT_COMMAND = list("Captain"),
|
||||
CARDCON_DEPARTMENT_COMMAND = list("Captain"),//lol
|
||||
CARDCON_DEPARTMENT_ENGINEERING = GLOB.engineering_positions,
|
||||
CARDCON_DEPARTMENT_MEDICAL = GLOB.medical_positions,
|
||||
CARDCON_DEPARTMENT_SCIENCE = GLOB.science_positions,
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/datum/computer_file/program/bounty
|
||||
filename = "bounty"
|
||||
filedesc = "Nanotrasen Bounty Hunter"
|
||||
program_icon_state = "bounty"
|
||||
extended_desc = "A basic interface for supply personnel to check and claim bounties."
|
||||
requires_ntnet = TRUE
|
||||
transfer_access = ACCESS_CARGO
|
||||
network_destination = "cargo claims interface"
|
||||
size = 10
|
||||
tgui_id = "NtosBountyConsole"
|
||||
///cooldown var for printing paper sheets.
|
||||
var/printer_ready = 0
|
||||
///The cargo account for grabbing the cargo account's credits.
|
||||
var/static/datum/bank_account/cargocash
|
||||
|
||||
/datum/computer_file/program/bounty/proc/print_paper()
|
||||
new /obj/item/paper/bounty_printout(get_turf(computer))
|
||||
|
||||
/datum/computer_file/program/bounty/ui_interact(mob/user, datum/tgui/ui)
|
||||
if(!GLOB.bounties_list.len)
|
||||
setup_bounties()
|
||||
printer_ready = world.time + PRINTER_TIMEOUT
|
||||
cargocash = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
. = ..()
|
||||
|
||||
/datum/computer_file/program/bounty/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
var/list/bountyinfo = list()
|
||||
for(var/datum/bounty/B in GLOB.bounties_list)
|
||||
bountyinfo += list(list("name" = B.name, "description" = B.description, "reward_string" = B.reward_string(), "completion_string" = B.completion_string() , "claimed" = B.claimed, "can_claim" = B.can_claim(), "priority" = B.high_priority, "bounty_ref" = REF(B)))
|
||||
data["stored_cash"] = cargocash.account_balance
|
||||
data["bountydata"] = bountyinfo
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/bounty/ui_act(action,params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("ClaimBounty")
|
||||
var/datum/bounty/cashmoney = locate(params["bounty"]) in GLOB.bounties_list
|
||||
if(cashmoney)
|
||||
cashmoney.claim()
|
||||
return TRUE
|
||||
if("Print")
|
||||
if(printer_ready < world.time)
|
||||
printer_ready = world.time + PRINTER_TIMEOUT
|
||||
print_paper()
|
||||
return
|
||||
@@ -6,11 +6,9 @@
|
||||
network_destination = "ship scanner"
|
||||
size = 6
|
||||
tgui_id = "NtosShipping"
|
||||
ui_x = 450
|
||||
ui_y = 350
|
||||
///Account used for creating barcodes.
|
||||
var/datum/bank_account/payments_acc
|
||||
///The amount which the tagger will recieve for the sale.
|
||||
///The amount which the tagger will receive for the sale.
|
||||
var/percent_cut = 20
|
||||
|
||||
/datum/computer_file/program/shipping/ui_data(mob/user)
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
unsendable = 1
|
||||
undeletable = 1
|
||||
size = 4
|
||||
ui_x = 420
|
||||
ui_y = 630
|
||||
available_on_ntnet = 0
|
||||
requires_ntnet = 0
|
||||
tgui_id = "NtosConfiguration"
|
||||
|
||||
@@ -7,12 +7,10 @@
|
||||
requires_ntnet = FALSE
|
||||
size = 4
|
||||
tgui_id = "NtosCrewManifest"
|
||||
ui_x = 400
|
||||
ui_y = 480
|
||||
|
||||
/datum/computer_file/program/crew_manifest/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["manifest"] = GLOB.data_core.get_manifest()
|
||||
data["manifest"] = GLOB.data_core.get_manifest_tg()
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/crew_manifest/ui_data(mob/user)
|
||||
@@ -41,9 +39,9 @@
|
||||
if(computer && printer) //This option should never be called if there is no printer
|
||||
var/contents = {"<h4>Crew Manifest</h4>
|
||||
<br>
|
||||
[GLOB.data_core ? GLOB.data_core.get_manifest_html(0) : ""]
|
||||
[GLOB.data_core ? GLOB.data_core.get_manifest() : ""]
|
||||
"}
|
||||
if(!printer.print_text(contents,text("crew manifest ([])", station_time_timestamp())))
|
||||
if(!printer.print_text(contents,text("crew manifest ([])", STATION_TIME_TIMESTAMP("hh:mm:ss", world.time))))
|
||||
to_chat(usr, "<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>")
|
||||
return
|
||||
else
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
requires_ntnet = 0
|
||||
size = 4
|
||||
tgui_id = "NtosJobManager"
|
||||
ui_x = 400
|
||||
ui_y = 620
|
||||
|
||||
var/change_position_cooldown = 30
|
||||
//Jobs you cannot open new positions for
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
available_on_ntnet = 0
|
||||
ui_header = "downloader_finished.gif"
|
||||
tgui_id = "NtosNetDownloader"
|
||||
ui_x = 480
|
||||
ui_y = 735
|
||||
|
||||
var/datum/computer_file/program/downloaded_file = null
|
||||
var/hacked_download = 0
|
||||
@@ -20,6 +18,21 @@
|
||||
var/download_netspeed = 0
|
||||
var/downloaderror = ""
|
||||
var/obj/item/modular_computer/my_computer = null
|
||||
var/emagged = FALSE
|
||||
var/list/main_repo
|
||||
var/list/antag_repo
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/run_program()
|
||||
. = ..()
|
||||
main_repo = SSnetworks.station_network.available_station_software
|
||||
antag_repo = SSnetworks.station_network.available_antag_software
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/run_emag()
|
||||
if(emagged)
|
||||
return FALSE
|
||||
emagged = TRUE
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/proc/begin_file_download(filename)
|
||||
if(downloaded_file)
|
||||
@@ -30,8 +43,8 @@
|
||||
if(!PRG || !istype(PRG))
|
||||
return 0
|
||||
|
||||
// Attempting to download antag only program, but without having emagged computer. No.
|
||||
if(PRG.available_on_syndinet && !(computer.obj_flags & EMAGGED))
|
||||
// Attempting to download antag only program, but without having emagged/syndicate computer. No.
|
||||
if(PRG.available_on_syndinet && !emagged)
|
||||
return 0
|
||||
|
||||
var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
|
||||
@@ -41,10 +54,10 @@
|
||||
|
||||
ui_header = "downloader_running.gif"
|
||||
|
||||
if(PRG in SSnetworks.station_network.available_station_software)
|
||||
if(PRG in main_repo)
|
||||
generate_network_log("Began downloading file [PRG.filename].[PRG.filetype] from NTNet Software Repository.")
|
||||
hacked_download = 0
|
||||
else if(PRG in SSnetworks.station_network.available_antag_software)
|
||||
else if(PRG in antag_repo)
|
||||
generate_network_log("Began downloading file **ENCRYPTED**.[PRG.filetype] from unspecified server.")
|
||||
hacked_download = 1
|
||||
else
|
||||
@@ -130,7 +143,7 @@
|
||||
data["disk_size"] = hard_drive.max_capacity
|
||||
data["disk_used"] = hard_drive.used_capacity
|
||||
var/list/all_entries[0]
|
||||
for(var/A in SSnetworks.station_network.available_station_software)
|
||||
for(var/A in main_repo)
|
||||
var/datum/computer_file/program/P = A
|
||||
// Only those programs our user can run will show in the list
|
||||
if(!P.can_run(user,transfer = 1) || hard_drive.find_file_by_name(P.filename))
|
||||
@@ -143,9 +156,9 @@
|
||||
"size" = P.size,
|
||||
)))
|
||||
data["hackedavailable"] = FALSE
|
||||
if(computer.obj_flags & EMAGGED) // If we are running on emagged computer we have access to some "bonus" software
|
||||
if(emagged) // If we are running on emagged computer we have access to some "bonus" software
|
||||
var/list/hacked_programs[0]
|
||||
for(var/S in SSnetworks.station_network.available_antag_software)
|
||||
for(var/S in antag_repo)
|
||||
var/datum/computer_file/program/P = S
|
||||
if(hard_drive.find_file_by_name(P.filename))
|
||||
continue
|
||||
@@ -172,3 +185,24 @@
|
||||
/datum/computer_file/program/ntnetdownload/kill_program(forced)
|
||||
abort_file_download()
|
||||
return ..(forced)
|
||||
|
||||
////////////////////////
|
||||
//Syndicate Downloader//
|
||||
////////////////////////
|
||||
|
||||
/// This app only lists programs normally found in the emagged section of the normal downloader app
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/syndicate
|
||||
filename = "syndownloader"
|
||||
filedesc = "Software Download Tool"
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "This program allows downloads of software from shared Syndicate repositories"
|
||||
requires_ntnet = 0
|
||||
ui_header = "downloader_finished.gif"
|
||||
tgui_id = "NtosNetDownloader"
|
||||
emagged = TRUE
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/syndicate/run_program()
|
||||
. = ..()
|
||||
main_repo = SSnetworks.station_network.available_antag_software
|
||||
antag_repo = null
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
ui_header = "ntnrc_idle.gif"
|
||||
available_on_ntnet = 1
|
||||
tgui_id = "NtosNetChat"
|
||||
ui_x = 900
|
||||
ui_y = 675
|
||||
|
||||
var/last_message // Used to generate the toolbar icon
|
||||
var/username
|
||||
var/active_channel
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
/datum/computer_file/program/nttransfer
|
||||
filename = "nttransfer"
|
||||
filedesc = "P2P Transfer Client"
|
||||
extended_desc = "This program allows for simple file transfer via direct peer to peer connection."
|
||||
program_icon_state = "comm_logs"
|
||||
size = 7
|
||||
requires_ntnet = 1
|
||||
requires_ntnet_feature = NTNET_PEERTOPEER
|
||||
network_destination = "other device via P2P tunnel"
|
||||
available_on_ntnet = 1
|
||||
tgui_id = "ntos_net_transfer"
|
||||
|
||||
var/error = "" // Error screen
|
||||
var/server_password = "" // Optional password to download the file.
|
||||
var/datum/computer_file/provided_file = null // File which is provided to clients.
|
||||
var/datum/computer_file/downloaded_file = null // File which is being downloaded
|
||||
var/list/connected_clients = list() // List of connected clients.
|
||||
var/datum/computer_file/program/nttransfer/remote // Client var, specifies who are we downloading from.
|
||||
var/download_completion = 0 // Download progress in GQ
|
||||
var/download_netspeed = 0 // Our connectivity speed in GQ/s
|
||||
var/actual_netspeed = 0 // Displayed in the UI, this is the actual transfer speed.
|
||||
var/unique_token // UID of this program
|
||||
var/upload_menu = 0 // Whether we show the program list and upload menu
|
||||
var/static/nttransfer_uid = 0
|
||||
|
||||
/datum/computer_file/program/nttransfer/New()
|
||||
unique_token = nttransfer_uid++
|
||||
..()
|
||||
|
||||
/datum/computer_file/program/nttransfer/process_tick()
|
||||
// Server mode
|
||||
update_netspeed()
|
||||
if(provided_file)
|
||||
for(var/datum/computer_file/program/nttransfer/C in connected_clients)
|
||||
// Transfer speed is limited by device which uses slower connectivity.
|
||||
// We can have multiple clients downloading at same time, but let's assume we use some sort of multicast transfer
|
||||
// so they can all run on same speed.
|
||||
C.actual_netspeed = min(C.download_netspeed, download_netspeed)
|
||||
C.download_completion += C.actual_netspeed
|
||||
if(C.download_completion >= provided_file.size)
|
||||
C.finish_download()
|
||||
else if(downloaded_file) // Client mode
|
||||
if(!remote)
|
||||
crash_download("Connection to remote server lost")
|
||||
|
||||
/datum/computer_file/program/nttransfer/kill_program(forced = FALSE)
|
||||
if(downloaded_file) // Client mode, clean up variables for next use
|
||||
finalize_download()
|
||||
|
||||
if(provided_file) // Server mode, disconnect all clients
|
||||
for(var/datum/computer_file/program/nttransfer/P in connected_clients)
|
||||
P.crash_download("Connection terminated by remote server")
|
||||
downloaded_file = null
|
||||
..(forced)
|
||||
|
||||
/datum/computer_file/program/nttransfer/proc/update_netspeed()
|
||||
download_netspeed = 0
|
||||
switch(ntnet_status)
|
||||
if(1)
|
||||
download_netspeed = NTNETSPEED_LOWSIGNAL
|
||||
if(2)
|
||||
download_netspeed = NTNETSPEED_HIGHSIGNAL
|
||||
if(3)
|
||||
download_netspeed = NTNETSPEED_ETHERNET
|
||||
|
||||
// Finishes download and attempts to store the file on HDD
|
||||
/datum/computer_file/program/nttransfer/proc/finish_download()
|
||||
var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
|
||||
if(!computer || !hard_drive || !hard_drive.store_file(downloaded_file))
|
||||
error = "I/O Error: Unable to save file. Check your hard drive and try again."
|
||||
finalize_download()
|
||||
|
||||
// Crashes the download and displays specific error message
|
||||
/datum/computer_file/program/nttransfer/proc/crash_download(var/message)
|
||||
error = message ? message : "An unknown error has occurred during download"
|
||||
finalize_download()
|
||||
|
||||
// Cleans up variables for next use
|
||||
/datum/computer_file/program/nttransfer/proc/finalize_download()
|
||||
if(remote)
|
||||
remote.connected_clients.Remove(src)
|
||||
downloaded_file = null
|
||||
remote = null
|
||||
download_completion = 0
|
||||
|
||||
/datum/computer_file/program/nttransfer/ui_act(action, params)
|
||||
if(..())
|
||||
return 1
|
||||
switch(action)
|
||||
if("PRG_downloadfile")
|
||||
for(var/datum/computer_file/program/nttransfer/P in SSnetworks.station_network.fileservers)
|
||||
if("[P.unique_token]" == params["id"])
|
||||
remote = P
|
||||
break
|
||||
if(!remote || !remote.provided_file)
|
||||
return
|
||||
if(remote.server_password)
|
||||
var/pass = reject_bad_text(input(usr, "Code 401 Unauthorized. Please enter password:", "Password required"))
|
||||
if(pass != remote.server_password)
|
||||
error = "Incorrect Password"
|
||||
return
|
||||
downloaded_file = remote.provided_file.clone()
|
||||
remote.connected_clients.Add(src)
|
||||
return 1
|
||||
if("PRG_reset")
|
||||
error = ""
|
||||
upload_menu = 0
|
||||
finalize_download()
|
||||
if(src in SSnetworks.station_network.fileservers)
|
||||
SSnetworks.station_network.fileservers.Remove(src)
|
||||
for(var/datum/computer_file/program/nttransfer/T in connected_clients)
|
||||
T.crash_download("Remote server has forcibly closed the connection")
|
||||
provided_file = null
|
||||
return 1
|
||||
if("PRG_setpassword")
|
||||
var/pass = reject_bad_text(input(usr, "Enter new server password. Leave blank to cancel, input 'none' to disable password.", "Server security", "none"))
|
||||
if(!pass)
|
||||
return
|
||||
if(pass == "none")
|
||||
server_password = ""
|
||||
return
|
||||
server_password = pass
|
||||
return 1
|
||||
if("PRG_uploadfile")
|
||||
var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
|
||||
for(var/datum/computer_file/F in hard_drive.stored_files)
|
||||
if("[F.uid]" == params["id"])
|
||||
if(F.unsendable)
|
||||
error = "I/O Error: File locked."
|
||||
return
|
||||
if(istype(F, /datum/computer_file/program))
|
||||
var/datum/computer_file/program/P = F
|
||||
if(!P.can_run(usr,transfer = 1))
|
||||
error = "Access Error: Insufficient rights to upload file."
|
||||
provided_file = F
|
||||
SSnetworks.station_network.fileservers.Add(src)
|
||||
return
|
||||
error = "I/O Error: Unable to locate file on hard drive."
|
||||
return 1
|
||||
if("PRG_uploadmenu")
|
||||
upload_menu = 1
|
||||
|
||||
|
||||
/datum/computer_file/program/nttransfer/ui_data(mob/user)
|
||||
|
||||
var/list/data = get_header_data()
|
||||
|
||||
if(error)
|
||||
data["error"] = error
|
||||
else if(downloaded_file)
|
||||
data["downloading"] = 1
|
||||
data["download_size"] = downloaded_file.size
|
||||
data["download_progress"] = download_completion
|
||||
data["download_netspeed"] = actual_netspeed
|
||||
data["download_name"] = "[downloaded_file.filename].[downloaded_file.filetype]"
|
||||
else if (provided_file)
|
||||
data["uploading"] = 1
|
||||
data["upload_uid"] = unique_token
|
||||
data["upload_clients"] = connected_clients.len
|
||||
data["upload_haspassword"] = server_password ? 1 : 0
|
||||
data["upload_filename"] = "[provided_file.filename].[provided_file.filetype]"
|
||||
else if (upload_menu)
|
||||
var/list/all_files[0]
|
||||
var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
|
||||
for(var/datum/computer_file/F in hard_drive.stored_files)
|
||||
all_files.Add(list(list(
|
||||
"uid" = F.uid,
|
||||
"filename" = "[F.filename].[F.filetype]",
|
||||
"size" = F.size
|
||||
)))
|
||||
data["upload_filelist"] = all_files
|
||||
else
|
||||
var/list/all_servers[0]
|
||||
for(var/datum/computer_file/program/nttransfer/P in SSnetworks.station_network.fileservers)
|
||||
all_servers.Add(list(list(
|
||||
"uid" = P.unique_token,
|
||||
"filename" = "[P.provided_file.filename].[P.provided_file.filetype]",
|
||||
"size" = P.provided_file.size,
|
||||
"haspassword" = P.server_password ? 1 : 0
|
||||
)))
|
||||
data["servers"] = all_servers
|
||||
|
||||
return data
|
||||
@@ -12,8 +12,6 @@
|
||||
network_destination = "power monitoring system"
|
||||
size = 9
|
||||
tgui_id = "NtosPowerMonitor"
|
||||
ui_x = 550
|
||||
ui_y = 700
|
||||
|
||||
var/has_alert = 0
|
||||
var/obj/structure/cable/attached_wire
|
||||
|
||||
@@ -2,31 +2,49 @@
|
||||
filename = "genericfinder"
|
||||
filedesc = "debug_finder"
|
||||
ui_header = "borg_mon.gif" //DEBUG -- new icon before PR
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "generic"
|
||||
program_icon_state = "radarntos"
|
||||
requires_ntnet = TRUE
|
||||
transfer_access = null
|
||||
available_on_ntnet = FALSE
|
||||
usage_flags = PROGRAM_LAPTOP | PROGRAM_TABLET
|
||||
network_destination = "tracking program"
|
||||
size = 5
|
||||
tgui_id = "NtosRadar"
|
||||
ui_x = 800
|
||||
ui_y = 600
|
||||
special_assets = list(
|
||||
/datum/asset/simple/radar_assets,
|
||||
)
|
||||
///List of trackable entities. Updated by the scan() proc.
|
||||
var/list/objects
|
||||
///Ref of the last trackable object selected by the user in the tgui window. Updated in the ui_act() proc.
|
||||
var/atom/selected
|
||||
///Used to store when the next scan is available. Updated by the scan() proc.
|
||||
var/next_scan = 0
|
||||
///Used to keep track of the last value program_icon_state was set to, to prevent constant unnecessary update_icon() calls
|
||||
var/last_icon_state = ""
|
||||
///Used by the tgui interface, themed NT or Syndicate.
|
||||
var/arrowstyle = "ntosradarpointer.png"
|
||||
///Used by the tgui interface, themed for NT or Syndicate colors.
|
||||
var/pointercolor = "green"
|
||||
|
||||
/datum/computer_file/program/radar/run_program(mob/living/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
return
|
||||
return FALSE
|
||||
|
||||
/datum/computer_file/program/radar/kill_program(forced = FALSE)
|
||||
objects = list()
|
||||
selected = null
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return ..()
|
||||
|
||||
/datum/computer_file/program/radar/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return ..()
|
||||
|
||||
/datum/computer_file/program/radar/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/simple/radar_assets),
|
||||
)
|
||||
|
||||
/datum/computer_file/program/radar/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
data["selected"] = selected
|
||||
@@ -65,7 +83,37 @@
|
||||
*
|
||||
*/
|
||||
/datum/computer_file/program/radar/proc/track()
|
||||
return
|
||||
var/atom/movable/signal = find_atom()
|
||||
if(!trackable(signal))
|
||||
return
|
||||
|
||||
var/turf/here_turf = (get_turf(computer))
|
||||
var/turf/target_turf = (get_turf(signal))
|
||||
var/userot = FALSE
|
||||
var/rot = 0
|
||||
var/pointer="crosshairs"
|
||||
var/locx = (target_turf.x - here_turf.x) + 24
|
||||
var/locy = (here_turf.y - target_turf.y) + 24
|
||||
|
||||
if(get_dist_euclidian(here_turf, target_turf) > 24)
|
||||
userot = TRUE
|
||||
rot = round(Get_Angle(here_turf, target_turf))
|
||||
else
|
||||
if(target_turf.z > here_turf.z)
|
||||
pointer="caret-up"
|
||||
else if(target_turf.z < here_turf.z)
|
||||
pointer="caret-down"
|
||||
|
||||
var/list/trackinfo = list(
|
||||
"locx" = locx,
|
||||
"locy" = locy,
|
||||
"userot" = userot,
|
||||
"rot" = rot,
|
||||
"arrowstyle" = arrowstyle,
|
||||
"color" = pointercolor,
|
||||
"pointer" = pointer,
|
||||
)
|
||||
return trackinfo
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -77,10 +125,12 @@
|
||||
**arg1 is the atom being evaluated.
|
||||
*/
|
||||
/datum/computer_file/program/radar/proc/trackable(atom/movable/signal)
|
||||
if(!signal)
|
||||
if(!signal || !computer)
|
||||
return FALSE
|
||||
var/turf/here = get_turf(computer)
|
||||
var/turf/there = get_turf(signal)
|
||||
if(!here || !there)
|
||||
return FALSE //I was still getting a runtime even after the above check while scanning, so fuck it
|
||||
return (there.z == here.z) || (is_station_level(here.z) && is_station_level(there.z))
|
||||
|
||||
/**
|
||||
@@ -98,6 +148,59 @@
|
||||
/datum/computer_file/program/radar/proc/scan()
|
||||
return
|
||||
|
||||
/**
|
||||
*
|
||||
*Finds the atom in the appropriate list that the `selected` var indicates
|
||||
*
|
||||
*The `selected` var holds a REF, which is a string. A mob REF may be
|
||||
*something like "mob_209". In order to find the actual atom, we need
|
||||
*to search the appropriate list for the REF string. This is dependant
|
||||
*on the program (Lifeline uses GLOB.human_list, while Fission360 uses
|
||||
*GLOB.poi_list), but the result will be the same; evaluate the string and
|
||||
*return an atom reference.
|
||||
*/
|
||||
/datum/computer_file/program/radar/proc/find_atom()
|
||||
return
|
||||
|
||||
//We use SSfastprocess for the program icon state because it runs faster than process_tick() does.
|
||||
/datum/computer_file/program/radar/process()
|
||||
if(computer.active_program != src)
|
||||
STOP_PROCESSING(SSfastprocess, src) //We're not the active program, it's time to stop.
|
||||
return
|
||||
if(!selected)
|
||||
return
|
||||
|
||||
var/atom/movable/signal = find_atom()
|
||||
if(!trackable(signal))
|
||||
program_icon_state = "[initial(program_icon_state)]lost"
|
||||
if(last_icon_state != program_icon_state)
|
||||
computer.update_icon()
|
||||
last_icon_state = program_icon_state
|
||||
return
|
||||
|
||||
var/here_turf = get_turf(computer)
|
||||
var/target_turf = get_turf(signal)
|
||||
var/trackdistance = get_dist_euclidian(here_turf, target_turf)
|
||||
switch(trackdistance)
|
||||
if(0)
|
||||
program_icon_state = "[initial(program_icon_state)]direct"
|
||||
if(1 to 12)
|
||||
program_icon_state = "[initial(program_icon_state)]close"
|
||||
if(13 to 24)
|
||||
program_icon_state = "[initial(program_icon_state)]medium"
|
||||
if(25 to INFINITY)
|
||||
program_icon_state = "[initial(program_icon_state)]far"
|
||||
|
||||
if(last_icon_state != program_icon_state)
|
||||
computer.update_icon()
|
||||
last_icon_state = program_icon_state
|
||||
computer.setDir(get_dir(here_turf, target_turf))
|
||||
|
||||
//We can use process_tick to restart fast processing, since the computer will be running this constantly either way.
|
||||
/datum/computer_file/program/radar/process_tick()
|
||||
if(computer.active_program == src)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
///////////////////
|
||||
//Suit Sensor App//
|
||||
///////////////////
|
||||
@@ -106,44 +209,13 @@
|
||||
/datum/computer_file/program/radar/lifeline
|
||||
filename = "Lifeline"
|
||||
filedesc = "Lifeline"
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "This program allows for tracking of crew members via their suit sensors."
|
||||
requires_ntnet = TRUE
|
||||
transfer_access = ACCESS_MEDICAL
|
||||
available_on_ntnet = TRUE
|
||||
|
||||
/datum/computer_file/program/radar/lifeline/track()
|
||||
var/mob/living/carbon/human/humanoid = locate(selected) in GLOB.human_list
|
||||
if(!istype(humanoid) || !trackable(humanoid))
|
||||
return
|
||||
|
||||
var/turf/here_turf = (get_turf(computer))
|
||||
var/turf/target_turf = (get_turf(humanoid))
|
||||
var/userot = FALSE
|
||||
var/rot = 0
|
||||
var/pointer="crosshairs"
|
||||
var/locx = (target_turf.x - here_turf.x)
|
||||
var/locy = (here_turf.y - target_turf.y)
|
||||
if(get_dist_euclidian(here_turf, target_turf) > 24) //If they're too far away, we need the angle for the arrow along the edge of the radar display
|
||||
userot = TRUE
|
||||
rot = round(Get_Angle(here_turf, target_turf))
|
||||
else
|
||||
locx = locx + 24
|
||||
locy = locy + 24
|
||||
if(target_turf.z > here_turf.z)
|
||||
pointer="caret-up"
|
||||
else if(target_turf.z < here_turf.z)
|
||||
pointer="caret-down"
|
||||
var/list/trackinfo = list(
|
||||
locx = locx,
|
||||
locy = locy,
|
||||
userot = userot,
|
||||
rot = rot,
|
||||
arrowstyle = "ntosradarpointer.png", //For the rotation arrow, it's stupid I know
|
||||
color = "green",
|
||||
pointer = pointer,
|
||||
)
|
||||
return trackinfo
|
||||
/datum/computer_file/program/radar/lifeline/find_atom()
|
||||
return locate(selected) in GLOB.human_list
|
||||
|
||||
/datum/computer_file/program/radar/lifeline/scan()
|
||||
if(world.time < next_scan)
|
||||
@@ -184,46 +256,18 @@
|
||||
/datum/computer_file/program/radar/fission360
|
||||
filename = "Fission360"
|
||||
filedesc = "Fission360"
|
||||
program_icon_state = "generic"
|
||||
program_icon_state = "radarsyndicate"
|
||||
extended_desc = "This program allows for tracking of nuclear authorization disks and warheads."
|
||||
requires_ntnet = FALSE
|
||||
transfer_access = null
|
||||
available_on_ntnet = FALSE
|
||||
available_on_syndinet = TRUE
|
||||
tgui_id = "NtosRadarSyndicate"
|
||||
arrowstyle = "ntosradarpointerS.png"
|
||||
pointercolor = "red"
|
||||
|
||||
/datum/computer_file/program/radar/fission360/track()
|
||||
var/obj/nuke = locate(selected) in GLOB.poi_list
|
||||
if(!trackable(nuke))
|
||||
return
|
||||
|
||||
var/turf/here_turf = (get_turf(computer))
|
||||
var/turf/target_turf = (get_turf(nuke))
|
||||
var/userot = FALSE
|
||||
var/rot = 0
|
||||
var/pointer="crosshairs"
|
||||
var/locx = (target_turf.x - here_turf.x)
|
||||
var/locy = (here_turf.y - target_turf.y)
|
||||
if(get_dist_euclidian(here_turf, target_turf) > 24) //If they're too far away, we need the angle for the arrow along the edge of the radar display
|
||||
userot = TRUE
|
||||
rot = round(Get_Angle(here_turf, target_turf))
|
||||
else
|
||||
locx = locx + 24
|
||||
locy = locy + 24
|
||||
if(target_turf.z > here_turf.z)
|
||||
pointer="caret-up"
|
||||
else if(target_turf.z < here_turf.z)
|
||||
pointer="caret-down"
|
||||
var/list/trackinfo = list(
|
||||
locx = locx,
|
||||
locy = locy,
|
||||
userot = userot,
|
||||
rot = rot,
|
||||
arrowstyle = "ntosradarpointerS.png",
|
||||
color = "red",
|
||||
pointer = pointer,
|
||||
)
|
||||
return trackinfo
|
||||
/datum/computer_file/program/radar/fission360/find_atom()
|
||||
return locate(selected) in GLOB.poi_list
|
||||
|
||||
/datum/computer_file/program/radar/fission360/scan()
|
||||
if(world.time < next_scan)
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
network_destination = "robotics control network"
|
||||
size = 12
|
||||
tgui_id = "NtosRoboControl"
|
||||
ui_x = 550
|
||||
ui_y = 550
|
||||
///Number of simple robots on-station.
|
||||
var/botcount = 0
|
||||
///Used to find the location of the user for the purposes of summoning robots.
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
network_destination = "supermatter monitoring system"
|
||||
size = 5
|
||||
tgui_id = "NtosSupermatterMonitor"
|
||||
ui_x = 600
|
||||
ui_y = 350
|
||||
var/last_status = SUPERMATTER_INACTIVE
|
||||
var/list/supermatters
|
||||
var/obj/machinery/power/supermatter_crystal/active // Currently selected supermatter crystal.
|
||||
|
||||
@@ -37,4 +37,4 @@
|
||||
icon_state = "cpu_super"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
power_usage = 75
|
||||
max_idle_programs = 2
|
||||
max_idle_programs = 2
|
||||
|
||||
@@ -32,28 +32,29 @@
|
||||
|
||||
|
||||
/obj/item/computer_hardware/attackby(obj/item/I, mob/living/user)
|
||||
// Multitool. Runs diagnostics
|
||||
if(istype(I, /obj/item/multitool))
|
||||
to_chat(user, "***** DIAGNOSTICS REPORT *****")
|
||||
diagnostics(user)
|
||||
to_chat(user, "******************************")
|
||||
return 1
|
||||
|
||||
// Cable coil. Works as repair method, but will probably require multiple applications and more cable.
|
||||
if(istype(I, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/S = I
|
||||
if(obj_integrity == max_integrity)
|
||||
to_chat(user, "<span class='warning'>\The [src] doesn't seem to require repairs.</span>")
|
||||
return 1
|
||||
if(I.use_tool(src, user, 0, 1))
|
||||
if(S.use(1))
|
||||
to_chat(user, "<span class='notice'>You patch up \the [src] with a bit of \the [I].</span>")
|
||||
obj_integrity = min(obj_integrity + 10, max_integrity)
|
||||
return 1
|
||||
|
||||
if(try_insert(I, user))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/computer_hardware/multitool_act(mob/living/user, obj/item/I)
|
||||
..()
|
||||
to_chat(user, "***** DIAGNOSTICS REPORT *****")
|
||||
diagnostics(user)
|
||||
to_chat(user, "******************************")
|
||||
return TRUE
|
||||
|
||||
// Called on multitool click, prints diagnostic information to the user.
|
||||
/obj/item/computer_hardware/proc/diagnostics(var/mob/user)
|
||||
to_chat(user, "Hardware Integrity Test... (Corruption: [damage]/[max_damage]) [damage > damage_failure ? "FAIL" : damage > damage_malfunction ? "WARN" : "PASS"]")
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
var/obj/item/aicard/stored_card = null
|
||||
var/locked = FALSE
|
||||
|
||||
/obj/item/computer_hardware/ai_slot/handle_atom_del(atom/A)
|
||||
if(A == stored_card)
|
||||
try_eject(0, null, TRUE)
|
||||
. = ..()
|
||||
|
||||
/obj/item/computer_hardware/ai_slot/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -41,13 +45,6 @@
|
||||
|
||||
|
||||
/obj/item/computer_hardware/ai_slot/try_eject(slot=0,mob/living/user = null,forced = 0)
|
||||
if (get_dist(src,user) > 1)
|
||||
if (iscarbon(user))
|
||||
var/mob/living/carbon/H = user
|
||||
if (!(H.dna && H.dna.check_mutation(TK) && tkMaxRangeCheck(src,H)))
|
||||
return FALSE
|
||||
else
|
||||
return FALSE
|
||||
if(!stored_card)
|
||||
to_chat(user, "<span class='warning'>There is no card in \the [src].</span>")
|
||||
return FALSE
|
||||
@@ -57,19 +54,21 @@
|
||||
return FALSE
|
||||
|
||||
if(stored_card)
|
||||
stored_card.forceMove(get_turf(src))
|
||||
to_chat(user, "<span class='notice'>You remove [stored_card] from [src].</span>")
|
||||
locked = FALSE
|
||||
stored_card.verb_pickup()
|
||||
if(user)
|
||||
user.put_in_hands(stored_card)
|
||||
else
|
||||
stored_card.forceMove(drop_location())
|
||||
stored_card = null
|
||||
|
||||
to_chat(user, "<span class='notice'>You remove the card from \the [src].</span>")
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/computer_hardware/ai_slot/attackby(obj/item/I, mob/living/user)
|
||||
if(..())
|
||||
return
|
||||
if(istype(I, /obj/item/screwdriver))
|
||||
if(I.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
to_chat(user, "<span class='notice'>You press down on the manual eject button with \the [I].</span>")
|
||||
try_eject(,user,1)
|
||||
return
|
||||
return
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
var/obj/item/stock_parts/cell/battery = null
|
||||
device_type = MC_CELL
|
||||
|
||||
/obj/item/computer_hardware/battery/get_cell()
|
||||
return battery
|
||||
|
||||
/obj/item/computer_hardware/battery/New(loc, battery_type = null)
|
||||
if(battery_type)
|
||||
battery = new battery_type(src)
|
||||
@@ -16,6 +19,11 @@
|
||||
. = ..()
|
||||
QDEL_NULL(battery)
|
||||
|
||||
/obj/item/computer_hardware/battery/handle_atom_del(atom/A)
|
||||
if(A == battery)
|
||||
try_eject(0, null, TRUE)
|
||||
. = ..()
|
||||
|
||||
/obj/item/computer_hardware/battery/try_insert(obj/item/I, mob/living/user = null)
|
||||
if(!holder)
|
||||
return FALSE
|
||||
@@ -45,7 +53,10 @@
|
||||
to_chat(user, "<span class='warning'>There is no power cell connected to \the [src].</span>")
|
||||
return FALSE
|
||||
else
|
||||
battery.forceMove(get_turf(src))
|
||||
if(user)
|
||||
user.put_in_hands(battery)
|
||||
else
|
||||
battery.forceMove(drop_location())
|
||||
to_chat(user, "<span class='notice'>You detach \the [battery] from \the [src].</span>")
|
||||
battery = null
|
||||
|
||||
|
||||
@@ -9,6 +9,13 @@
|
||||
var/obj/item/card/id/stored_card = null
|
||||
var/obj/item/card/id/stored_card2 = null
|
||||
|
||||
/obj/item/computer_hardware/card_slot/handle_atom_del(atom/A)
|
||||
if(A == stored_card)
|
||||
try_eject(1, null, TRUE)
|
||||
if(A == stored_card2)
|
||||
try_eject(2, null, TRUE)
|
||||
. = ..()
|
||||
|
||||
/obj/item/computer_hardware/card_slot/Destroy()
|
||||
try_eject()
|
||||
return ..()
|
||||
@@ -67,19 +74,15 @@
|
||||
else
|
||||
stored_card2 = I
|
||||
to_chat(user, "<span class='notice'>You insert \the [I] into \the [src].</span>")
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.sec_hud_set_ID()
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/computer_hardware/card_slot/try_eject(slot=0, mob/living/user = null, forced = 0)
|
||||
if (get_dist(src,user) > 1)
|
||||
if (iscarbon(user))
|
||||
var/mob/living/carbon/H = user
|
||||
if (!(H.dna && H.dna.check_mutation(TK) && tkMaxRangeCheck(src,H)))
|
||||
return FALSE
|
||||
else
|
||||
return FALSE
|
||||
if(!stored_card && !stored_card2)
|
||||
to_chat(user, "<span class='warning'>There are no cards in \the [src].</span>")
|
||||
return FALSE
|
||||
@@ -89,7 +92,7 @@
|
||||
if(user)
|
||||
user.put_in_hands(stored_card)
|
||||
else
|
||||
stored_card.forceMove(get_turf(src))
|
||||
stored_card.forceMove(drop_location())
|
||||
stored_card = null
|
||||
ejected++
|
||||
|
||||
@@ -97,7 +100,7 @@
|
||||
if(user)
|
||||
user.put_in_hands(stored_card2)
|
||||
else
|
||||
stored_card2.forceMove(get_turf(src))
|
||||
stored_card2.forceMove(drop_location())
|
||||
stored_card2 = null
|
||||
ejected++
|
||||
|
||||
@@ -109,16 +112,18 @@
|
||||
for(var/I in holder.idle_threads)
|
||||
var/datum/computer_file/program/P = I
|
||||
P.event_idremoved(1, slot)
|
||||
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.sec_hud_set_ID()
|
||||
to_chat(user, "<span class='notice'>You remove the card[ejected>1 ? "s" : ""] from \the [src].</span>")
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/computer_hardware/card_slot/attackby(obj/item/I, mob/living/user)
|
||||
if(..())
|
||||
return
|
||||
if(istype(I, /obj/item/screwdriver))
|
||||
if(I.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
to_chat(user, "<span class='notice'>You press down on the manual eject button with \the [I].</span>")
|
||||
try_eject(0,user)
|
||||
return
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user