This commit is contained in:
Seris02
2020-01-13 12:53:52 +08:00
1027 changed files with 196105 additions and 197892 deletions
+128 -128
View File
@@ -1,128 +1,128 @@
#define MENU_OPERATION 1
#define MENU_SURGERIES 2
/obj/machinery/computer/operating
name = "operating computer"
desc = "Monitors patient vitals and displays surgery steps. Can be loaded with surgery disks to perform experimental procedures."
icon_screen = "crew"
icon_keyboard = "med_key"
circuit = /obj/item/circuitboard/computer/operating
var/mob/living/carbon/human/patient
var/obj/structure/table/optable/table
var/list/advanced_surgeries = list()
var/datum/techweb/linked_techweb
var/menu = MENU_OPERATION
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/operating/Initialize()
. = ..()
linked_techweb = SSresearch.science_tech
find_table()
/obj/machinery/computer/operating/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/disk/surgery))
user.visible_message("[user] begins to load \the [O] in \the [src]...",
"You begin to load a surgery protocol from \the [O]...",
"You hear the chatter of a floppy drive.")
var/obj/item/disk/surgery/D = O
if(do_after(user, 10, target = src))
advanced_surgeries |= D.surgeries
return TRUE
return ..()
/obj/machinery/computer/operating/proc/sync_surgeries()
for(var/i in linked_techweb.researched_designs)
var/datum/design/surgery/D = SSresearch.techweb_design_by_id(i)
if(!istype(D))
continue
advanced_surgeries |= D.surgery
/obj/machinery/computer/operating/proc/find_table()
for(var/direction in GLOB.cardinals)
table = locate(/obj/structure/table/optable, get_step(src, direction))
if(table)
table.computer = src
break
/obj/machinery/computer/operating/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.not_incapacitated_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "operating_computer", name, 350, 470, master_ui, state)
ui.open()
/obj/machinery/computer/operating/ui_data(mob/user)
var/list/data = list()
data["table"] = table
if(table)
data["menu"] = menu
var/list/surgeries = list()
for(var/X in advanced_surgeries)
var/datum/surgery/S = X
var/list/surgery = list()
surgery["name"] = initial(S.name)
surgery["desc"] = initial(S.desc)
surgeries += list(surgery)
data["surgeries"] = surgeries
data["patient"] = list()
if(table.check_patient())
patient = table.patient
switch(patient.stat)
if(CONSCIOUS)
data["patient"]["stat"] = "Conscious"
data["patient"]["statstate"] = "good"
if(SOFT_CRIT)
data["patient"]["stat"] = "Conscious"
data["patient"]["statstate"] = "average"
if(UNCONSCIOUS)
data["patient"]["stat"] = "Unconscious"
data["patient"]["statstate"] = "average"
if(DEAD)
data["patient"]["stat"] = "Dead"
data["patient"]["statstate"] = "bad"
data["patient"]["health"] = patient.health
data["patient"]["blood_type"] = patient.dna.blood_type
data["patient"]["maxHealth"] = patient.maxHealth
data["patient"]["minHealth"] = HEALTH_THRESHOLD_DEAD
data["patient"]["bruteLoss"] = patient.getBruteLoss()
data["patient"]["fireLoss"] = patient.getFireLoss()
data["patient"]["toxLoss"] = patient.getToxLoss()
data["patient"]["oxyLoss"] = patient.getOxyLoss()
if(patient.surgeries.len)
data["procedures"] = list()
for(var/datum/surgery/procedure in patient.surgeries)
var/datum/surgery_step/surgery_step = procedure.get_surgery_step()
var/chems_needed = surgery_step.get_chem_list()
var/alternative_step
var/alt_chems_needed = ""
if(surgery_step.repeatable)
var/datum/surgery_step/next_step = procedure.get_surgery_next_step()
if(next_step)
alternative_step = capitalize(next_step.name)
alt_chems_needed = next_step.get_chem_list()
else
alternative_step = "Finish operation"
data["procedures"] += list(list(
"name" = capitalize(procedure.name),
"next_step" = capitalize(surgery_step.name),
"chems_needed" = chems_needed,
"alternative_step" = alternative_step,
"alt_chems_needed" = alt_chems_needed
))
return data
/obj/machinery/computer/operating/ui_act(action, params)
if(..())
return
switch(action)
if("change_menu")
menu = text2num(params["menu"])
. = TRUE
if("sync")
sync_surgeries()
. = TRUE
. = TRUE
#undef MENU_OPERATION
#undef MENU_SURGERIES
#define MENU_OPERATION 1
#define MENU_SURGERIES 2
/obj/machinery/computer/operating
name = "operating computer"
desc = "Monitors patient vitals and displays surgery steps. Can be loaded with surgery disks to perform experimental procedures."
icon_screen = "crew"
icon_keyboard = "med_key"
circuit = /obj/item/circuitboard/computer/operating
var/mob/living/carbon/human/patient
var/obj/structure/table/optable/table
var/list/advanced_surgeries = list()
var/datum/techweb/linked_techweb
var/menu = MENU_OPERATION
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/operating/Initialize()
. = ..()
linked_techweb = SSresearch.science_tech
find_table()
/obj/machinery/computer/operating/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/disk/surgery))
user.visible_message("[user] begins to load \the [O] in \the [src]...",
"You begin to load a surgery protocol from \the [O]...",
"You hear the chatter of a floppy drive.")
var/obj/item/disk/surgery/D = O
if(do_after(user, 10, target = src))
advanced_surgeries |= D.surgeries
return TRUE
return ..()
/obj/machinery/computer/operating/proc/sync_surgeries()
for(var/i in linked_techweb.researched_designs)
var/datum/design/surgery/D = SSresearch.techweb_design_by_id(i)
if(!istype(D))
continue
advanced_surgeries |= D.surgery
/obj/machinery/computer/operating/proc/find_table()
for(var/direction in GLOB.cardinals)
table = locate(/obj/structure/table/optable, get_step(src, direction))
if(table)
table.computer = src
break
/obj/machinery/computer/operating/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.not_incapacitated_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "operating_computer", name, 350, 470, master_ui, state)
ui.open()
/obj/machinery/computer/operating/ui_data(mob/user)
var/list/data = list()
data["table"] = table
if(table)
data["menu"] = menu
var/list/surgeries = list()
for(var/X in advanced_surgeries)
var/datum/surgery/S = X
var/list/surgery = list()
surgery["name"] = initial(S.name)
surgery["desc"] = initial(S.desc)
surgeries += list(surgery)
data["surgeries"] = surgeries
data["patient"] = list()
if(table.check_patient())
patient = table.patient
switch(patient.stat)
if(CONSCIOUS)
data["patient"]["stat"] = "Conscious"
data["patient"]["statstate"] = "good"
if(SOFT_CRIT)
data["patient"]["stat"] = "Conscious"
data["patient"]["statstate"] = "average"
if(UNCONSCIOUS)
data["patient"]["stat"] = "Unconscious"
data["patient"]["statstate"] = "average"
if(DEAD)
data["patient"]["stat"] = "Dead"
data["patient"]["statstate"] = "bad"
data["patient"]["health"] = patient.health
data["patient"]["blood_type"] = patient.dna.blood_type
data["patient"]["maxHealth"] = patient.maxHealth
data["patient"]["minHealth"] = HEALTH_THRESHOLD_DEAD
data["patient"]["bruteLoss"] = patient.getBruteLoss()
data["patient"]["fireLoss"] = patient.getFireLoss()
data["patient"]["toxLoss"] = patient.getToxLoss()
data["patient"]["oxyLoss"] = patient.getOxyLoss()
if(patient.surgeries.len)
data["procedures"] = list()
for(var/datum/surgery/procedure in patient.surgeries)
var/datum/surgery_step/surgery_step = procedure.get_surgery_step()
var/chems_needed = surgery_step.get_chem_list()
var/alternative_step
var/alt_chems_needed = ""
if(surgery_step.repeatable)
var/datum/surgery_step/next_step = procedure.get_surgery_next_step()
if(next_step)
alternative_step = capitalize(next_step.name)
alt_chems_needed = next_step.get_chem_list()
else
alternative_step = "Finish operation"
data["procedures"] += list(list(
"name" = capitalize(procedure.name),
"next_step" = capitalize(surgery_step.name),
"chems_needed" = chems_needed,
"alternative_step" = alternative_step,
"alt_chems_needed" = alt_chems_needed
))
return data
/obj/machinery/computer/operating/ui_act(action, params)
if(..())
return
switch(action)
if("change_menu")
menu = text2num(params["menu"])
. = TRUE
if("sync")
sync_surgeries()
. = TRUE
. = TRUE
#undef MENU_OPERATION
#undef MENU_SURGERIES
+150 -150
View File
@@ -1,150 +1,150 @@
/obj/machinery/computer/aifixer
name = "\improper AI system integrity restorer"
desc = "Used with intelliCards containing nonfunctional AIs to restore them to working order."
req_access = list(ACCESS_CAPTAIN, ACCESS_ROBOTICS, ACCESS_HEADS)
var/mob/living/silicon/ai/occupier = null
var/active = 0
circuit = /obj/item/circuitboard/computer/aifixer
icon_keyboard = "tech_key"
icon_screen = "ai-fixer"
light_color = LIGHT_COLOR_PINK
/obj/machinery/computer/aifixer/attackby(obj/I, mob/user, params)
if(occupier && istype(I, /obj/item/screwdriver))
if(stat & (NOPOWER|BROKEN))
to_chat(user, "<span class='warning'>The screws on [name]'s screen won't budge.</span>")
else
to_chat(user, "<span class='warning'>The screws on [name]'s screen won't budge and it emits a warning beep.</span>")
else
return ..()
/obj/machinery/computer/aifixer/ui_interact(mob/user)
. = ..()
var/dat = ""
if (src.occupier)
var/laws
dat += "<h3>Stored AI: [src.occupier.name]</h3>"
dat += "<b>System integrity:</b> [(src.occupier.health+100)/2]%<br>"
if (src.occupier.laws.zeroth)
laws += "<b>0:</b> [src.occupier.laws.zeroth]<BR>"
for (var/index = 1, index <= src.occupier.laws.hacked.len, index++)
var/law = src.occupier.laws.hacked[index]
if (length(law) > 0)
var/num = ionnum()
laws += "<b>[num]:</b> [law]<BR>"
for (var/index = 1, index <= src.occupier.laws.ion.len, index++)
var/law = src.occupier.laws.ion[index]
if (length(law) > 0)
var/num = ionnum()
laws += "<b>[num]:</b> [law]<BR>"
var/number = 1
for (var/index = 1, index <= src.occupier.laws.inherent.len, index++)
var/law = src.occupier.laws.inherent[index]
if (length(law) > 0)
laws += "<b>[number]:</b> [law]<BR>"
number++
for (var/index = 1, index <= src.occupier.laws.supplied.len, index++)
var/law = src.occupier.laws.supplied[index]
if (length(law) > 0)
laws += "<b>[number]:</b> [law]<BR>"
number++
dat += "<b>Laws:</b><br>[laws]<br>"
if (src.occupier.stat == DEAD)
dat += "<span class='bad'>AI non-functional</span>"
else
dat += "<span class='good'>AI functional</span>"
if (!src.active)
dat += {"<br><br><A href='byond://?src=[REF(src)];fix=1'>Begin Reconstruction</A>"}
else
dat += "<br><br>Reconstruction in process, please wait.<br>"
dat += {"<br><A href='?src=[REF(user)];mach_close=computer'>Close</A>"}
var/datum/browser/popup = new(user, "computer", "AI System Integrity Restorer", 400, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return
/obj/machinery/computer/aifixer/proc/Fix()
use_power(1000)
occupier.adjustOxyLoss(-1, 0)
occupier.adjustFireLoss(-1, 0)
occupier.adjustToxLoss(-1, 0)
occupier.adjustBruteLoss(-1, 0)
occupier.updatehealth()
if(occupier.health >= 0 && occupier.stat == DEAD)
occupier.revive()
return occupier.health < 100
/obj/machinery/computer/aifixer/process()
if(..())
if(active)
var/oldstat = occupier.stat
active = Fix()
if(oldstat != occupier.stat)
update_icon()
updateDialog()
/obj/machinery/computer/aifixer/Topic(href, href_list)
if(..())
return
if(href_list["fix"])
to_chat(usr, "<span class='notice'>Reconstruction in progress. This will take several minutes.</span>")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0)
active = TRUE
add_fingerprint(usr)
updateUsrDialog()
/obj/machinery/computer/aifixer/update_icon()
..()
if(stat & (NOPOWER|BROKEN))
return
else
if(active)
add_overlay("ai-fixer-on")
if (occupier)
switch (occupier.stat)
if (0)
add_overlay("ai-fixer-full")
if (2)
add_overlay("ai-fixer-404")
else
add_overlay("ai-fixer-empty")
/obj/machinery/computer/aifixer/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card)
if(!..())
return
//Downloading AI from card to terminal.
if(interaction == AI_TRANS_FROM_CARD)
if(stat & (NOPOWER|BROKEN))
to_chat(user, "[src] is offline and cannot take an AI at this time!")
return
AI.forceMove(src)
occupier = AI
AI.control_disabled = 1
AI.radio_enabled = 0
to_chat(AI, "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here.")
to_chat(user, "<span class='boldnotice'>Transfer successful</span>: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.")
card.AI = null
update_icon()
else //Uploading AI from terminal to card
if(occupier && !active)
to_chat(occupier, "You have been downloaded to a mobile storage device. Still no remote access.")
to_chat(user, "<span class='boldnotice'>Transfer successful</span>: [occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.")
occupier.forceMove(card)
card.AI = occupier
occupier = null
update_icon()
else if (active)
to_chat(user, "<span class='boldannounce'>ERROR</span>: Reconstruction in progress.")
else if (!occupier)
to_chat(user, "<span class='boldannounce'>ERROR</span>: Unable to locate artificial intelligence.")
/obj/machinery/computer/aifixer
name = "\improper AI system integrity restorer"
desc = "Used with intelliCards containing nonfunctional AIs to restore them to working order."
req_access = list(ACCESS_CAPTAIN, ACCESS_ROBOTICS, ACCESS_HEADS)
var/mob/living/silicon/ai/occupier = null
var/active = 0
circuit = /obj/item/circuitboard/computer/aifixer
icon_keyboard = "tech_key"
icon_screen = "ai-fixer"
light_color = LIGHT_COLOR_PINK
/obj/machinery/computer/aifixer/attackby(obj/I, mob/user, params)
if(occupier && istype(I, /obj/item/screwdriver))
if(stat & (NOPOWER|BROKEN))
to_chat(user, "<span class='warning'>The screws on [name]'s screen won't budge.</span>")
else
to_chat(user, "<span class='warning'>The screws on [name]'s screen won't budge and it emits a warning beep.</span>")
else
return ..()
/obj/machinery/computer/aifixer/ui_interact(mob/user)
. = ..()
var/dat = ""
if (src.occupier)
var/laws
dat += "<h3>Stored AI: [src.occupier.name]</h3>"
dat += "<b>System integrity:</b> [(src.occupier.health+100)/2]%<br>"
if (src.occupier.laws.zeroth)
laws += "<b>0:</b> [src.occupier.laws.zeroth]<BR>"
for (var/index = 1, index <= src.occupier.laws.hacked.len, index++)
var/law = src.occupier.laws.hacked[index]
if (length(law) > 0)
var/num = ionnum()
laws += "<b>[num]:</b> [law]<BR>"
for (var/index = 1, index <= src.occupier.laws.ion.len, index++)
var/law = src.occupier.laws.ion[index]
if (length(law) > 0)
var/num = ionnum()
laws += "<b>[num]:</b> [law]<BR>"
var/number = 1
for (var/index = 1, index <= src.occupier.laws.inherent.len, index++)
var/law = src.occupier.laws.inherent[index]
if (length(law) > 0)
laws += "<b>[number]:</b> [law]<BR>"
number++
for (var/index = 1, index <= src.occupier.laws.supplied.len, index++)
var/law = src.occupier.laws.supplied[index]
if (length(law) > 0)
laws += "<b>[number]:</b> [law]<BR>"
number++
dat += "<b>Laws:</b><br>[laws]<br>"
if (src.occupier.stat == DEAD)
dat += "<span class='bad'>AI non-functional</span>"
else
dat += "<span class='good'>AI functional</span>"
if (!src.active)
dat += {"<br><br><A href='byond://?src=[REF(src)];fix=1'>Begin Reconstruction</A>"}
else
dat += "<br><br>Reconstruction in process, please wait.<br>"
dat += {"<br><A href='?src=[REF(user)];mach_close=computer'>Close</A>"}
var/datum/browser/popup = new(user, "computer", "AI System Integrity Restorer", 400, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return
/obj/machinery/computer/aifixer/proc/Fix()
use_power(1000)
occupier.adjustOxyLoss(-1, 0)
occupier.adjustFireLoss(-1, 0)
occupier.adjustToxLoss(-1, 0)
occupier.adjustBruteLoss(-1, 0)
occupier.updatehealth()
if(occupier.health >= 0 && occupier.stat == DEAD)
occupier.revive()
return occupier.health < 100
/obj/machinery/computer/aifixer/process()
if(..())
if(active)
var/oldstat = occupier.stat
active = Fix()
if(oldstat != occupier.stat)
update_icon()
updateDialog()
/obj/machinery/computer/aifixer/Topic(href, href_list)
if(..())
return
if(href_list["fix"])
to_chat(usr, "<span class='notice'>Reconstruction in progress. This will take several minutes.</span>")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0)
active = TRUE
add_fingerprint(usr)
updateUsrDialog()
/obj/machinery/computer/aifixer/update_icon()
..()
if(stat & (NOPOWER|BROKEN))
return
else
if(active)
add_overlay("ai-fixer-on")
if (occupier)
switch (occupier.stat)
if (0)
add_overlay("ai-fixer-full")
if (2)
add_overlay("ai-fixer-404")
else
add_overlay("ai-fixer-empty")
/obj/machinery/computer/aifixer/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card)
if(!..())
return
//Downloading AI from card to terminal.
if(interaction == AI_TRANS_FROM_CARD)
if(stat & (NOPOWER|BROKEN))
to_chat(user, "[src] is offline and cannot take an AI at this time!")
return
AI.forceMove(src)
occupier = AI
AI.control_disabled = 1
AI.radio_enabled = 0
to_chat(AI, "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here.")
to_chat(user, "<span class='boldnotice'>Transfer successful</span>: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.")
card.AI = null
update_icon()
else //Uploading AI from terminal to card
if(occupier && !active)
to_chat(occupier, "You have been downloaded to a mobile storage device. Still no remote access.")
to_chat(user, "<span class='boldnotice'>Transfer successful</span>: [occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.")
occupier.forceMove(card)
card.AI = occupier
occupier = null
update_icon()
else if (active)
to_chat(user, "<span class='boldannounce'>ERROR</span>: Reconstruction in progress.")
else if (!occupier)
to_chat(user, "<span class='boldannounce'>ERROR</span>: Unable to locate artificial intelligence.")
+100 -100
View File
@@ -1,100 +1,100 @@
/obj/machinery/computer/atmos_alert
name = "atmospheric alert console"
desc = "Used to monitor the station's air alarms."
circuit = /obj/item/circuitboard/computer/atmos_alert
icon_screen = "alert:0"
icon_keyboard = "atmos_key"
var/list/priority_alarms = list()
var/list/minor_alarms = list()
var/receive_frequency = FREQ_ATMOS_ALARMS
var/datum/radio_frequency/radio_connection
light_color = LIGHT_COLOR_CYAN
/obj/machinery/computer/atmos_alert/Initialize()
. = ..()
set_frequency(receive_frequency)
/obj/machinery/computer/atmos_alert/Destroy()
SSradio.remove_object(src, receive_frequency)
return ..()
/obj/machinery/computer/atmos_alert/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)
if(!ui)
ui = new(user, src, ui_key, "atmos_alert", name, 350, 300, master_ui, state)
ui.open()
/obj/machinery/computer/atmos_alert/ui_data(mob/user)
var/list/data = list()
data["priority"] = list()
for(var/zone in priority_alarms)
data["priority"] += zone
data["minor"] = list()
for(var/zone in minor_alarms)
data["minor"] += zone
return data
/obj/machinery/computer/atmos_alert/ui_act(action, params)
if(..())
return
switch(action)
if("clear")
var/zone = params["zone"]
if(zone in priority_alarms)
to_chat(usr, "Priority alarm for [zone] cleared.")
priority_alarms -= zone
. = TRUE
if(zone in minor_alarms)
to_chat(usr, "Minor alarm for [zone] cleared.")
minor_alarms -= zone
. = TRUE
update_icon()
/obj/machinery/computer/atmos_alert/proc/set_frequency(new_frequency)
SSradio.remove_object(src, receive_frequency)
receive_frequency = new_frequency
radio_connection = SSradio.add_object(src, receive_frequency, RADIO_ATMOSIA)
/obj/machinery/computer/atmos_alert/receive_signal(datum/signal/signal)
if(!signal)
return
var/zone = signal.data["zone"]
var/severity = signal.data["alert"]
if(!zone || !severity)
return
minor_alarms -= zone
priority_alarms -= zone
if(severity == "severe")
priority_alarms += zone
else if (severity == "minor")
minor_alarms += zone
update_icon()
return
/obj/machinery/computer/atmos_alert/update_icon()
..()
cut_overlays()
SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays)
var/overlay_state = icon_screen
if(stat & (NOPOWER|BROKEN))
add_overlay("[icon_keyboard]_off")
return
add_overlay(icon_keyboard)
if(priority_alarms.len)
overlay_state = "alert:2"
add_overlay("alert:2")
else if(minor_alarms.len)
overlay_state = "alert:1"
add_overlay("alert:1")
else
overlay_state = "alert:0"
add_overlay("alert:0")
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, layer, plane, dir)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir, alpha=128)
/obj/machinery/computer/atmos_alert
name = "atmospheric alert console"
desc = "Used to monitor the station's air alarms."
circuit = /obj/item/circuitboard/computer/atmos_alert
icon_screen = "alert:0"
icon_keyboard = "atmos_key"
var/list/priority_alarms = list()
var/list/minor_alarms = list()
var/receive_frequency = FREQ_ATMOS_ALARMS
var/datum/radio_frequency/radio_connection
light_color = LIGHT_COLOR_CYAN
/obj/machinery/computer/atmos_alert/Initialize()
. = ..()
set_frequency(receive_frequency)
/obj/machinery/computer/atmos_alert/Destroy()
SSradio.remove_object(src, receive_frequency)
return ..()
/obj/machinery/computer/atmos_alert/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)
if(!ui)
ui = new(user, src, ui_key, "atmos_alert", name, 350, 300, master_ui, state)
ui.open()
/obj/machinery/computer/atmos_alert/ui_data(mob/user)
var/list/data = list()
data["priority"] = list()
for(var/zone in priority_alarms)
data["priority"] += zone
data["minor"] = list()
for(var/zone in minor_alarms)
data["minor"] += zone
return data
/obj/machinery/computer/atmos_alert/ui_act(action, params)
if(..())
return
switch(action)
if("clear")
var/zone = params["zone"]
if(zone in priority_alarms)
to_chat(usr, "Priority alarm for [zone] cleared.")
priority_alarms -= zone
. = TRUE
if(zone in minor_alarms)
to_chat(usr, "Minor alarm for [zone] cleared.")
minor_alarms -= zone
. = TRUE
update_icon()
/obj/machinery/computer/atmos_alert/proc/set_frequency(new_frequency)
SSradio.remove_object(src, receive_frequency)
receive_frequency = new_frequency
radio_connection = SSradio.add_object(src, receive_frequency, RADIO_ATMOSIA)
/obj/machinery/computer/atmos_alert/receive_signal(datum/signal/signal)
if(!signal)
return
var/zone = signal.data["zone"]
var/severity = signal.data["alert"]
if(!zone || !severity)
return
minor_alarms -= zone
priority_alarms -= zone
if(severity == "severe")
priority_alarms += zone
else if (severity == "minor")
minor_alarms += zone
update_icon()
return
/obj/machinery/computer/atmos_alert/update_icon()
..()
cut_overlays()
SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays)
var/overlay_state = icon_screen
if(stat & (NOPOWER|BROKEN))
add_overlay("[icon_keyboard]_off")
return
add_overlay(icon_keyboard)
if(priority_alarms.len)
overlay_state = "alert:2"
add_overlay("alert:2")
else if(minor_alarms.len)
overlay_state = "alert:1"
add_overlay("alert:1")
else
overlay_state = "alert:0"
add_overlay("alert:0")
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, layer, plane, dir)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir, alpha=128)
+305 -305
View File
@@ -1,305 +1,305 @@
/////////////////////////////////////////////////////////////
// AIR SENSOR (found in gas tanks)
/////////////////////////////////////////////////////////////
/obj/machinery/air_sensor
name = "gas sensor"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "gsensor1"
var/on = TRUE
var/id_tag
var/frequency = FREQ_ATMOS_STORAGE
var/datum/radio_frequency/radio_connection
/obj/machinery/air_sensor/atmos/toxin_tank
name = "plasma tank gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_TOX
/obj/machinery/air_sensor/atmos/toxins_mixing_tank
name = "toxins mixing gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB
/obj/machinery/air_sensor/atmos/oxygen_tank
name = "oxygen tank gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_O2
/obj/machinery/air_sensor/atmos/nitrogen_tank
name = "nitrogen tank gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_N2
/obj/machinery/air_sensor/atmos/mix_tank
name = "mix tank gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_MIX
/obj/machinery/air_sensor/atmos/nitrous_tank
name = "nitrous oxide tank gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_N2O
/obj/machinery/air_sensor/atmos/air_tank
name = "air mix tank gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_AIR
/obj/machinery/air_sensor/atmos/carbon_tank
name = "carbon dioxide tank gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_CO2
/obj/machinery/air_sensor/atmos/incinerator_tank
name = "incinerator chamber gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_INCINERATOR
/obj/machinery/air_sensor/update_icon()
icon_state = "gsensor[on]"
/obj/machinery/air_sensor/process_atmos()
if(on)
var/datum/gas_mixture/air_sample = return_air()
var/datum/signal/signal = new(list(
"sigtype" = "status",
"id_tag" = id_tag,
"timestamp" = world.time,
"pressure" = air_sample.return_pressure(),
"temperature" = air_sample.temperature,
"gases" = list()
))
var/total_moles = air_sample.total_moles()
if(total_moles)
for(var/gas_id in air_sample.gases)
var/gas_name = GLOB.meta_gas_names[gas_id]
signal.data["gases"][gas_name] = air_sample.gases[gas_id] / total_moles * 100
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
/obj/machinery/air_sensor/proc/set_frequency(new_frequency)
SSradio.remove_object(src, frequency)
frequency = new_frequency
radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
/obj/machinery/air_sensor/Initialize()
. = ..()
SSair.atmos_machinery += src
set_frequency(frequency)
/obj/machinery/air_sensor/Destroy()
SSair.atmos_machinery -= src
SSradio.remove_object(src, frequency)
return ..()
/////////////////////////////////////////////////////////////
// GENERAL AIR CONTROL (a.k.a atmos computer)
/////////////////////////////////////////////////////////////
GLOBAL_LIST_EMPTY(atmos_air_controllers)
/obj/machinery/computer/atmos_control
name = "atmospherics monitoring"
desc = "Used to monitor the station's atmospherics sensors."
icon_screen = "tank"
icon_keyboard = "atmos_key"
circuit = /obj/item/circuitboard/computer/atmos_control
var/frequency = FREQ_ATMOS_STORAGE
var/list/sensors = list(
ATMOS_GAS_MONITOR_SENSOR_N2 = "Nitrogen Tank",
ATMOS_GAS_MONITOR_SENSOR_O2 = "Oxygen Tank",
ATMOS_GAS_MONITOR_SENSOR_CO2 = "Carbon Dioxide Tank",
ATMOS_GAS_MONITOR_SENSOR_TOX = "Plasma Tank",
ATMOS_GAS_MONITOR_SENSOR_N2O = "Nitrous Oxide Tank",
ATMOS_GAS_MONITOR_SENSOR_AIR = "Mixed Air Tank",
ATMOS_GAS_MONITOR_SENSOR_MIX = "Mix Tank",
ATMOS_GAS_MONITOR_LOOP_DISTRIBUTION = "Distribution Loop",
ATMOS_GAS_MONITOR_LOOP_ATMOS_WASTE = "Atmos Waste Loop",
ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber",
ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB = "Toxins Mixing Chamber"
)
var/list/sensor_information = list()
var/datum/radio_frequency/radio_connection
light_color = LIGHT_COLOR_CYAN
/obj/machinery/computer/atmos_control/Initialize()
. = ..()
GLOB.atmos_air_controllers += src
set_frequency(frequency)
/obj/machinery/computer/atmos_control/Destroy()
GLOB.atmos_air_controllers -= src
SSradio.remove_object(src, frequency)
return ..()
/obj/machinery/computer/atmos_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)
if(!ui)
ui = new(user, src, ui_key, "atmos_control", name, 400, 925, master_ui, state)
ui.open()
/obj/machinery/computer/atmos_control/ui_data(mob/user)
var/data = list()
data["sensors"] = list()
for(var/id_tag in sensors)
var/long_name = sensors[id_tag]
var/list/info = sensor_information[id_tag]
if(!info)
continue
data["sensors"] += list(list(
"id_tag" = id_tag,
"long_name" = sanitize(long_name),
"pressure" = info["pressure"],
"temperature" = info["temperature"],
"gases" = info["gases"]
))
return data
/obj/machinery/computer/atmos_control/receive_signal(datum/signal/signal)
if(!signal)
return
var/id_tag = signal.data["id_tag"]
if(!id_tag || !sensors.Find(id_tag))
return
sensor_information[id_tag] = signal.data
/obj/machinery/computer/atmos_control/proc/set_frequency(new_frequency)
SSradio.remove_object(src, frequency)
frequency = new_frequency
radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
/////////////////////////////////////////////////////////////
// LARGE TANK CONTROL
/////////////////////////////////////////////////////////////
/obj/machinery/computer/atmos_control/tank
var/input_tag
var/output_tag
frequency = FREQ_ATMOS_STORAGE
circuit = /obj/item/circuitboard/computer/atmos_control/tank
var/list/input_info
var/list/output_info
/obj/machinery/computer/atmos_control/tank/oxygen_tank
name = "Oxygen Supply Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_O2
output_tag = ATMOS_GAS_MONITOR_OUTPUT_O2
sensors = list(ATMOS_GAS_MONITOR_SENSOR_O2 = "Oxygen Tank")
/obj/machinery/computer/atmos_control/tank/toxin_tank
name = "Plasma Supply Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_TOX
output_tag = ATMOS_GAS_MONITOR_OUTPUT_TOX
sensors = list(ATMOS_GAS_MONITOR_SENSOR_TOX = "Plasma Tank")
/obj/machinery/computer/atmos_control/tank/air_tank
name = "Mixed Air Supply Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_AIR
output_tag = ATMOS_GAS_MONITOR_OUTPUT_AIR
sensors = list(ATMOS_GAS_MONITOR_SENSOR_AIR = "Air Mix Tank")
/obj/machinery/computer/atmos_control/tank/mix_tank
name = "Gas Mix Tank Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_MIX
output_tag = ATMOS_GAS_MONITOR_OUTPUT_MIX
sensors = list(ATMOS_GAS_MONITOR_SENSOR_MIX = "Gas Mix Tank")
/obj/machinery/computer/atmos_control/tank/nitrous_tank
name = "Nitrous Oxide Supply Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_N2O
output_tag = ATMOS_GAS_MONITOR_OUTPUT_N2O
sensors = list(ATMOS_GAS_MONITOR_SENSOR_N2O = "Nitrous Oxide Tank")
/obj/machinery/computer/atmos_control/tank/nitrogen_tank
name = "Nitrogen Supply Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_N2
output_tag = ATMOS_GAS_MONITOR_OUTPUT_N2
sensors = list(ATMOS_GAS_MONITOR_SENSOR_N2 = "Nitrogen Tank")
/obj/machinery/computer/atmos_control/tank/carbon_tank
name = "Carbon Dioxide Supply Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_CO2
output_tag = ATMOS_GAS_MONITOR_OUTPUT_CO2
sensors = list(ATMOS_GAS_MONITOR_SENSOR_CO2 = "Carbon Dioxide Tank")
/obj/machinery/computer/atmos_control/tank/incinerator
name = "Incinerator Air Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_INCINERATOR
output_tag = ATMOS_GAS_MONITOR_OUTPUT_INCINERATOR
sensors = list(ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber")
// This hacky madness is the evidence of the fact that a lot of machines were never meant to be constructable, im so sorry you had to see this
/obj/machinery/computer/atmos_control/tank/proc/reconnect(mob/user)
var/list/IO = list()
var/datum/radio_frequency/freq = SSradio.return_frequency(FREQ_ATMOS_STORAGE)
var/list/devices = freq.devices["_default"]
for(var/obj/machinery/atmospherics/components/unary/vent_pump/U in devices)
var/list/text = splittext(U.id_tag, "_")
IO |= text[1]
for(var/obj/machinery/atmospherics/components/unary/outlet_injector/U in devices)
var/list/text = splittext(U.id, "_")
IO |= text[1]
if(!IO.len)
to_chat(user, "<span class='alert'>No machinery detected.</span>")
var/S = input("Select the device set: ", "Selection", IO[1]) as anything in IO
if(src)
src.input_tag = "[S]_in"
src.output_tag = "[S]_out"
name = "[uppertext(S)] Supply Control"
var/list/new_devices = freq.devices["4"]
for(var/obj/machinery/air_sensor/U in new_devices)
var/list/text = splittext(U.id_tag, "_")
if(text[1] == S)
sensors = list("[S]_sensor" = "Tank")
break
for(var/obj/machinery/atmospherics/components/unary/outlet_injector/U in devices)
U.broadcast_status()
for(var/obj/machinery/atmospherics/components/unary/vent_pump/U in devices)
U.broadcast_status()
/obj/machinery/computer/atmos_control/tank/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)
if(!ui)
ui = new(user, src, ui_key, "atmos_control", name, 500, 305, master_ui, state)
ui.open()
/obj/machinery/computer/atmos_control/tank/ui_data(mob/user)
var/list/data = ..()
data["tank"] = TRUE
data["inputting"] = input_info ? input_info["power"] : FALSE
data["inputRate"] = input_info ? input_info["volume_rate"] : 0
data["outputting"] = output_info ? output_info["power"] : FALSE
data["outputPressure"] = output_info ? output_info["internal"] : 0
return data
/obj/machinery/computer/atmos_control/tank/ui_act(action, params)
if(..() || !radio_connection)
return
var/datum/signal/signal = new(list("sigtype" = "command", "user" = usr))
switch(action)
if("reconnect")
reconnect(usr)
. = TRUE
if("input")
signal.data += list("tag" = input_tag, "power_toggle" = TRUE)
. = TRUE
if("output")
signal.data += list("tag" = output_tag, "power_toggle" = TRUE)
. = TRUE
if("pressure")
var/target = input("New target pressure:", name, output_info ? output_info["internal"] : 0) as num|null
if(!isnull(target) && !..())
target = CLAMP(target, 0, 50 * ONE_ATMOSPHERE)
signal.data += list("tag" = output_tag, "set_internal_pressure" = target)
. = TRUE
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
/obj/machinery/computer/atmos_control/tank/receive_signal(datum/signal/signal)
if(!signal)
return
var/id_tag = signal.data["tag"]
if(input_tag == id_tag)
input_info = signal.data
else if(output_tag == id_tag)
output_info = signal.data
else
..(signal)
/////////////////////////////////////////////////////////////
// AIR SENSOR (found in gas tanks)
/////////////////////////////////////////////////////////////
/obj/machinery/air_sensor
name = "gas sensor"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "gsensor1"
var/on = TRUE
var/id_tag
var/frequency = FREQ_ATMOS_STORAGE
var/datum/radio_frequency/radio_connection
/obj/machinery/air_sensor/atmos/toxin_tank
name = "plasma tank gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_TOX
/obj/machinery/air_sensor/atmos/toxins_mixing_tank
name = "toxins mixing gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB
/obj/machinery/air_sensor/atmos/oxygen_tank
name = "oxygen tank gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_O2
/obj/machinery/air_sensor/atmos/nitrogen_tank
name = "nitrogen tank gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_N2
/obj/machinery/air_sensor/atmos/mix_tank
name = "mix tank gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_MIX
/obj/machinery/air_sensor/atmos/nitrous_tank
name = "nitrous oxide tank gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_N2O
/obj/machinery/air_sensor/atmos/air_tank
name = "air mix tank gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_AIR
/obj/machinery/air_sensor/atmos/carbon_tank
name = "carbon dioxide tank gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_CO2
/obj/machinery/air_sensor/atmos/incinerator_tank
name = "incinerator chamber gas sensor"
id_tag = ATMOS_GAS_MONITOR_SENSOR_INCINERATOR
/obj/machinery/air_sensor/update_icon()
icon_state = "gsensor[on]"
/obj/machinery/air_sensor/process_atmos()
if(on)
var/datum/gas_mixture/air_sample = return_air()
var/datum/signal/signal = new(list(
"sigtype" = "status",
"id_tag" = id_tag,
"timestamp" = world.time,
"pressure" = air_sample.return_pressure(),
"temperature" = air_sample.temperature,
"gases" = list()
))
var/total_moles = air_sample.total_moles()
if(total_moles)
for(var/gas_id in air_sample.gases)
var/gas_name = GLOB.meta_gas_names[gas_id]
signal.data["gases"][gas_name] = air_sample.gases[gas_id] / total_moles * 100
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
/obj/machinery/air_sensor/proc/set_frequency(new_frequency)
SSradio.remove_object(src, frequency)
frequency = new_frequency
radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
/obj/machinery/air_sensor/Initialize()
. = ..()
SSair.atmos_machinery += src
set_frequency(frequency)
/obj/machinery/air_sensor/Destroy()
SSair.atmos_machinery -= src
SSradio.remove_object(src, frequency)
return ..()
/////////////////////////////////////////////////////////////
// GENERAL AIR CONTROL (a.k.a atmos computer)
/////////////////////////////////////////////////////////////
GLOBAL_LIST_EMPTY(atmos_air_controllers)
/obj/machinery/computer/atmos_control
name = "atmospherics monitoring"
desc = "Used to monitor the station's atmospherics sensors."
icon_screen = "tank"
icon_keyboard = "atmos_key"
circuit = /obj/item/circuitboard/computer/atmos_control
var/frequency = FREQ_ATMOS_STORAGE
var/list/sensors = list(
ATMOS_GAS_MONITOR_SENSOR_N2 = "Nitrogen Tank",
ATMOS_GAS_MONITOR_SENSOR_O2 = "Oxygen Tank",
ATMOS_GAS_MONITOR_SENSOR_CO2 = "Carbon Dioxide Tank",
ATMOS_GAS_MONITOR_SENSOR_TOX = "Plasma Tank",
ATMOS_GAS_MONITOR_SENSOR_N2O = "Nitrous Oxide Tank",
ATMOS_GAS_MONITOR_SENSOR_AIR = "Mixed Air Tank",
ATMOS_GAS_MONITOR_SENSOR_MIX = "Mix Tank",
ATMOS_GAS_MONITOR_LOOP_DISTRIBUTION = "Distribution Loop",
ATMOS_GAS_MONITOR_LOOP_ATMOS_WASTE = "Atmos Waste Loop",
ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber",
ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB = "Toxins Mixing Chamber"
)
var/list/sensor_information = list()
var/datum/radio_frequency/radio_connection
light_color = LIGHT_COLOR_CYAN
/obj/machinery/computer/atmos_control/Initialize()
. = ..()
GLOB.atmos_air_controllers += src
set_frequency(frequency)
/obj/machinery/computer/atmos_control/Destroy()
GLOB.atmos_air_controllers -= src
SSradio.remove_object(src, frequency)
return ..()
/obj/machinery/computer/atmos_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)
if(!ui)
ui = new(user, src, ui_key, "atmos_control", name, 400, 925, master_ui, state)
ui.open()
/obj/machinery/computer/atmos_control/ui_data(mob/user)
var/data = list()
data["sensors"] = list()
for(var/id_tag in sensors)
var/long_name = sensors[id_tag]
var/list/info = sensor_information[id_tag]
if(!info)
continue
data["sensors"] += list(list(
"id_tag" = id_tag,
"long_name" = sanitize(long_name),
"pressure" = info["pressure"],
"temperature" = info["temperature"],
"gases" = info["gases"]
))
return data
/obj/machinery/computer/atmos_control/receive_signal(datum/signal/signal)
if(!signal)
return
var/id_tag = signal.data["id_tag"]
if(!id_tag || !sensors.Find(id_tag))
return
sensor_information[id_tag] = signal.data
/obj/machinery/computer/atmos_control/proc/set_frequency(new_frequency)
SSradio.remove_object(src, frequency)
frequency = new_frequency
radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
/////////////////////////////////////////////////////////////
// LARGE TANK CONTROL
/////////////////////////////////////////////////////////////
/obj/machinery/computer/atmos_control/tank
var/input_tag
var/output_tag
frequency = FREQ_ATMOS_STORAGE
circuit = /obj/item/circuitboard/computer/atmos_control/tank
var/list/input_info
var/list/output_info
/obj/machinery/computer/atmos_control/tank/oxygen_tank
name = "Oxygen Supply Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_O2
output_tag = ATMOS_GAS_MONITOR_OUTPUT_O2
sensors = list(ATMOS_GAS_MONITOR_SENSOR_O2 = "Oxygen Tank")
/obj/machinery/computer/atmos_control/tank/toxin_tank
name = "Plasma Supply Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_TOX
output_tag = ATMOS_GAS_MONITOR_OUTPUT_TOX
sensors = list(ATMOS_GAS_MONITOR_SENSOR_TOX = "Plasma Tank")
/obj/machinery/computer/atmos_control/tank/air_tank
name = "Mixed Air Supply Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_AIR
output_tag = ATMOS_GAS_MONITOR_OUTPUT_AIR
sensors = list(ATMOS_GAS_MONITOR_SENSOR_AIR = "Air Mix Tank")
/obj/machinery/computer/atmos_control/tank/mix_tank
name = "Gas Mix Tank Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_MIX
output_tag = ATMOS_GAS_MONITOR_OUTPUT_MIX
sensors = list(ATMOS_GAS_MONITOR_SENSOR_MIX = "Gas Mix Tank")
/obj/machinery/computer/atmos_control/tank/nitrous_tank
name = "Nitrous Oxide Supply Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_N2O
output_tag = ATMOS_GAS_MONITOR_OUTPUT_N2O
sensors = list(ATMOS_GAS_MONITOR_SENSOR_N2O = "Nitrous Oxide Tank")
/obj/machinery/computer/atmos_control/tank/nitrogen_tank
name = "Nitrogen Supply Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_N2
output_tag = ATMOS_GAS_MONITOR_OUTPUT_N2
sensors = list(ATMOS_GAS_MONITOR_SENSOR_N2 = "Nitrogen Tank")
/obj/machinery/computer/atmos_control/tank/carbon_tank
name = "Carbon Dioxide Supply Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_CO2
output_tag = ATMOS_GAS_MONITOR_OUTPUT_CO2
sensors = list(ATMOS_GAS_MONITOR_SENSOR_CO2 = "Carbon Dioxide Tank")
/obj/machinery/computer/atmos_control/tank/incinerator
name = "Incinerator Air Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_INCINERATOR
output_tag = ATMOS_GAS_MONITOR_OUTPUT_INCINERATOR
sensors = list(ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber")
// This hacky madness is the evidence of the fact that a lot of machines were never meant to be constructable, im so sorry you had to see this
/obj/machinery/computer/atmos_control/tank/proc/reconnect(mob/user)
var/list/IO = list()
var/datum/radio_frequency/freq = SSradio.return_frequency(FREQ_ATMOS_STORAGE)
var/list/devices = freq.devices["_default"]
for(var/obj/machinery/atmospherics/components/unary/vent_pump/U in devices)
var/list/text = splittext(U.id_tag, "_")
IO |= text[1]
for(var/obj/machinery/atmospherics/components/unary/outlet_injector/U in devices)
var/list/text = splittext(U.id, "_")
IO |= text[1]
if(!IO.len)
to_chat(user, "<span class='alert'>No machinery detected.</span>")
var/S = input("Select the device set: ", "Selection", IO[1]) as anything in IO
if(src)
src.input_tag = "[S]_in"
src.output_tag = "[S]_out"
name = "[uppertext(S)] Supply Control"
var/list/new_devices = freq.devices["4"]
for(var/obj/machinery/air_sensor/U in new_devices)
var/list/text = splittext(U.id_tag, "_")
if(text[1] == S)
sensors = list("[S]_sensor" = "Tank")
break
for(var/obj/machinery/atmospherics/components/unary/outlet_injector/U in devices)
U.broadcast_status()
for(var/obj/machinery/atmospherics/components/unary/vent_pump/U in devices)
U.broadcast_status()
/obj/machinery/computer/atmos_control/tank/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)
if(!ui)
ui = new(user, src, ui_key, "atmos_control", name, 500, 305, master_ui, state)
ui.open()
/obj/machinery/computer/atmos_control/tank/ui_data(mob/user)
var/list/data = ..()
data["tank"] = TRUE
data["inputting"] = input_info ? input_info["power"] : FALSE
data["inputRate"] = input_info ? input_info["volume_rate"] : 0
data["outputting"] = output_info ? output_info["power"] : FALSE
data["outputPressure"] = output_info ? output_info["internal"] : 0
return data
/obj/machinery/computer/atmos_control/tank/ui_act(action, params)
if(..() || !radio_connection)
return
var/datum/signal/signal = new(list("sigtype" = "command", "user" = usr))
switch(action)
if("reconnect")
reconnect(usr)
. = TRUE
if("input")
signal.data += list("tag" = input_tag, "power_toggle" = TRUE)
. = TRUE
if("output")
signal.data += list("tag" = output_tag, "power_toggle" = TRUE)
. = TRUE
if("pressure")
var/target = input("New target pressure:", name, output_info ? output_info["internal"] : 0) as num|null
if(!isnull(target) && !..())
target = CLAMP(target, 0, 50 * ONE_ATMOSPHERE)
signal.data += list("tag" = output_tag, "set_internal_pressure" = target)
. = TRUE
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
/obj/machinery/computer/atmos_control/tank/receive_signal(datum/signal/signal)
if(!signal)
return
var/id_tag = signal.data["tag"]
if(input_tag == id_tag)
input_info = signal.data
else if(output_tag == id_tag)
output_info = signal.data
else
..(signal)
+145 -145
View File
@@ -1,145 +1,145 @@
/obj/structure/frame/computer
name = "computer frame"
icon_state = "0"
state = 0
/obj/structure/frame/computer/attackby(obj/item/P, mob/user, params)
add_fingerprint(user)
switch(state)
if(0)
if(istype(P, /obj/item/wrench))
to_chat(user, "<span class='notice'>You start wrenching the frame into place...</span>")
if(P.use_tool(src, user, 20, volume=50))
to_chat(user, "<span class='notice'>You wrench the frame into place.</span>")
setAnchored(TRUE)
state = 1
return
if(istype(P, /obj/item/weldingtool))
if(!P.tool_start_check(user, amount=0))
return
to_chat(user, "<span class='notice'>You start deconstructing the frame...</span>")
if(P.use_tool(src, user, 20, volume=50) && state == 0)
to_chat(user, "<span class='notice'>You deconstruct the frame.</span>")
var/obj/item/stack/sheet/metal/M = new (drop_location(), 5)
M.add_fingerprint(user)
qdel(src)
return
if(1)
if(istype(P, /obj/item/wrench))
to_chat(user, "<span class='notice'>You start to unfasten the frame...</span>")
if(P.use_tool(src, user, 20, volume=50) && state == 1)
to_chat(user, "<span class='notice'>You unfasten the frame.</span>")
setAnchored(FALSE)
state = 0
return
if(istype(P, /obj/item/circuitboard/computer) && !circuit)
if(!user.transferItemToLoc(P, src))
return
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "<span class='notice'>You place [P] inside the frame.</span>")
icon_state = "1"
circuit = P
circuit.add_fingerprint(user)
return
else if(istype(P, /obj/item/circuitboard) && !circuit)
to_chat(user, "<span class='warning'>This frame does not accept circuit boards of this type!</span>")
return
if(istype(P, /obj/item/screwdriver) && circuit)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You screw [circuit] into place.</span>")
state = 2
icon_state = "2"
return
if(istype(P, /obj/item/crowbar) && circuit)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove [circuit].</span>")
state = 1
icon_state = "0"
circuit.forceMove(drop_location())
circuit.add_fingerprint(user)
circuit = null
return
if(2)
if(istype(P, /obj/item/screwdriver) && circuit)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You unfasten the circuit board.</span>")
state = 1
icon_state = "1"
return
if(istype(P, /obj/item/stack/cable_coil))
if(!P.tool_start_check(user, amount=5))
return
to_chat(user, "<span class='notice'>You start adding cables to the frame...</span>")
if(P.use_tool(src, user, 20, 5, 50, CALLBACK(src, .proc/check_state, 2)))
to_chat(user, "<span class='notice'>You add cables to the frame.</span>")
state = 3
icon_state = "3"
return
if(3)
if(istype(P, /obj/item/wirecutters))
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove the cables.</span>")
state = 2
icon_state = "2"
var/obj/item/stack/cable_coil/A = new (drop_location(), 5)
A.add_fingerprint(user)
return
if(istype(P, /obj/item/stack/sheet/glass))
if(!P.tool_start_check(user, amount=2))
return
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "<span class='notice'>You start to put in the glass panel...</span>")
if(P.use_tool(src, user, 20, 2, 0, CALLBACK(src, .proc/check_state, 3)))
to_chat(user, "<span class='notice'>You put in the glass panel.</span>")
state = 4
src.icon_state = "4"
return
if(4)
if(istype(P, /obj/item/crowbar))
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove the glass panel.</span>")
state = 3
icon_state = "3"
var/obj/item/stack/sheet/glass/G = new(drop_location(), 2)
G.add_fingerprint(user)
return
if(istype(P, /obj/item/screwdriver))
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You connect the monitor.</span>")
var/obj/B = new circuit.build_path (loc, circuit)
B.setDir(dir)
transfer_fingerprints_to(B)
qdel(src)
return
if(user.a_intent == INTENT_HARM)
return ..()
//callback proc used on stacks use_tool to stop unnecessary amounts being wasted from spam clicking.
/obj/structure/frame/computer/proc/check_state(target_state)
if(state == target_state)
return TRUE
return FALSE
/obj/structure/frame/computer/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(state == 4)
new /obj/item/shard(drop_location())
new /obj/item/shard(drop_location())
if(state >= 3)
new /obj/item/stack/cable_coil(drop_location(), 5)
..()
/obj/structure/frame/computer/AltClick(mob/user)
. = ..()
if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
if(anchored)
to_chat(usr, "<span class='warning'>You must unwrench [src] before rotating it!</span>")
return TRUE
setDir(turn(dir, -90))
return TRUE
/obj/structure/frame/computer
name = "computer frame"
icon_state = "0"
state = 0
/obj/structure/frame/computer/attackby(obj/item/P, mob/user, params)
add_fingerprint(user)
switch(state)
if(0)
if(istype(P, /obj/item/wrench))
to_chat(user, "<span class='notice'>You start wrenching the frame into place...</span>")
if(P.use_tool(src, user, 20, volume=50))
to_chat(user, "<span class='notice'>You wrench the frame into place.</span>")
setAnchored(TRUE)
state = 1
return
if(istype(P, /obj/item/weldingtool))
if(!P.tool_start_check(user, amount=0))
return
to_chat(user, "<span class='notice'>You start deconstructing the frame...</span>")
if(P.use_tool(src, user, 20, volume=50) && state == 0)
to_chat(user, "<span class='notice'>You deconstruct the frame.</span>")
var/obj/item/stack/sheet/metal/M = new (drop_location(), 5)
M.add_fingerprint(user)
qdel(src)
return
if(1)
if(istype(P, /obj/item/wrench))
to_chat(user, "<span class='notice'>You start to unfasten the frame...</span>")
if(P.use_tool(src, user, 20, volume=50) && state == 1)
to_chat(user, "<span class='notice'>You unfasten the frame.</span>")
setAnchored(FALSE)
state = 0
return
if(istype(P, /obj/item/circuitboard/computer) && !circuit)
if(!user.transferItemToLoc(P, src))
return
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "<span class='notice'>You place [P] inside the frame.</span>")
icon_state = "1"
circuit = P
circuit.add_fingerprint(user)
return
else if(istype(P, /obj/item/circuitboard) && !circuit)
to_chat(user, "<span class='warning'>This frame does not accept circuit boards of this type!</span>")
return
if(istype(P, /obj/item/screwdriver) && circuit)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You screw [circuit] into place.</span>")
state = 2
icon_state = "2"
return
if(istype(P, /obj/item/crowbar) && circuit)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove [circuit].</span>")
state = 1
icon_state = "0"
circuit.forceMove(drop_location())
circuit.add_fingerprint(user)
circuit = null
return
if(2)
if(istype(P, /obj/item/screwdriver) && circuit)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You unfasten the circuit board.</span>")
state = 1
icon_state = "1"
return
if(istype(P, /obj/item/stack/cable_coil))
if(!P.tool_start_check(user, amount=5))
return
to_chat(user, "<span class='notice'>You start adding cables to the frame...</span>")
if(P.use_tool(src, user, 20, 5, 50, CALLBACK(src, .proc/check_state, 2)))
to_chat(user, "<span class='notice'>You add cables to the frame.</span>")
state = 3
icon_state = "3"
return
if(3)
if(istype(P, /obj/item/wirecutters))
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove the cables.</span>")
state = 2
icon_state = "2"
var/obj/item/stack/cable_coil/A = new (drop_location(), 5)
A.add_fingerprint(user)
return
if(istype(P, /obj/item/stack/sheet/glass))
if(!P.tool_start_check(user, amount=2))
return
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "<span class='notice'>You start to put in the glass panel...</span>")
if(P.use_tool(src, user, 20, 2, 0, CALLBACK(src, .proc/check_state, 3)))
to_chat(user, "<span class='notice'>You put in the glass panel.</span>")
state = 4
src.icon_state = "4"
return
if(4)
if(istype(P, /obj/item/crowbar))
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove the glass panel.</span>")
state = 3
icon_state = "3"
var/obj/item/stack/sheet/glass/G = new(drop_location(), 2)
G.add_fingerprint(user)
return
if(istype(P, /obj/item/screwdriver))
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You connect the monitor.</span>")
var/obj/B = new circuit.build_path (loc, circuit)
B.setDir(dir)
transfer_fingerprints_to(B)
qdel(src)
return
if(user.a_intent == INTENT_HARM)
return ..()
//callback proc used on stacks use_tool to stop unnecessary amounts being wasted from spam clicking.
/obj/structure/frame/computer/proc/check_state(target_state)
if(state == target_state)
return TRUE
return FALSE
/obj/structure/frame/computer/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(state == 4)
new /obj/item/shard(drop_location())
new /obj/item/shard(drop_location())
if(state >= 3)
new /obj/item/stack/cable_coil(drop_location(), 5)
..()
/obj/structure/frame/computer/AltClick(mob/user)
. = ..()
if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
if(anchored)
to_chat(usr, "<span class='warning'>You must unwrench [src] before rotating it!</span>")
return TRUE
setDir(turn(dir, -90))
return TRUE
+254 -254
View File
@@ -1,254 +1,254 @@
/obj/machinery/computer/security
name = "security camera console"
desc = "Used to access the various cameras on the station."
icon_screen = "cameras"
icon_keyboard = "security_key"
circuit = /obj/item/circuitboard/computer/security
var/last_pic = 1
var/list/network = list("ss13")
var/list/watchers = list() //who's using the console, associated with the camera they're on.
light_color = LIGHT_COLOR_RED
/obj/machinery/computer/security/Initialize()
. = ..()
for(var/i in network)
network -= i
network += lowertext(i)
/obj/machinery/computer/security/check_eye(mob/user)
if(!can_interact(user) || !(user in watchers) || !watchers[user])
user.unset_machine()
return
var/obj/machinery/camera/C = watchers[user]
if(!C.can_use())
user.unset_machine()
return
/obj/machinery/computer/security/on_unset_machine(mob/user)
watchers.Remove(user)
user.reset_perspective(null)
/obj/machinery/computer/security/Destroy()
if(watchers.len)
for(var/mob/M in watchers)
M.unset_machine() //to properly reset the view of the users if the console is deleted.
return ..()
/obj/machinery/computer/security/can_interact(mob/user)
if((!issilicon(user) && !Adjacent(user)) || is_blind(user) || !in_view_range(user, src))
return FALSE
return ..()
/obj/machinery/computer/security/interact(mob/user, special_state)
. = ..()
if (ismob(user) && !isliving(user)) // ghosts don't need cameras
return
if (!network)
CRASH("No camera network")
user.unset_machine()
return FALSE
if (!(islist(network)))
CRASH("Camera network is not a list")
user.unset_machine()
return FALSE
var/list/camera_list = get_available_cameras()
if(!(user in watchers))
for(var/Num in camera_list)
var/obj/machinery/camera/CAM = camera_list[Num]
if(istype(CAM) && CAM.can_use())
watchers[user] = CAM //let's give the user the first usable camera, and then let him change to the camera he wants.
break
if(!(user in watchers))
user.unset_machine() // no usable camera on the network, we disconnect the user from the computer.
return FALSE
playsound(src, 'sound/machines/terminal_prompt.ogg', 25, 0)
use_camera_console(user)
/obj/machinery/computer/security/proc/use_camera_console(mob/user)
var/list/camera_list = get_available_cameras()
var/t = input(user, "Which camera should you change to?") as null|anything in camera_list
if(!src || user.machine != src) //while we were choosing we got disconnected from our computer or are using another machine.
return
if(!t || t == "Cancel")
user.unset_machine()
playsound(src, 'sound/machines/terminal_off.ogg', 25, 0)
return
var/obj/machinery/camera/C = camera_list[t]
if(!C || !C.can_use() || !can_interact(user))
user.unset_machine()
return FALSE
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0)
if(isAI(user))
var/mob/living/silicon/ai/A = user
A.eyeobj.setLoc(get_turf(C))
A.client.eye = A.eyeobj
else
user.reset_perspective(C)
user.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static)
user.clear_fullscreen("flash", 5)
watchers[user] = C
use_power(50)
addtimer(CALLBACK(src, .proc/use_camera_console, user), 5)
//returns the list of cameras accessible from this computer
/obj/machinery/computer/security/proc/get_available_cameras()
var/list/L = list()
for (var/obj/machinery/camera/C in GLOB.cameranet.cameras)
if((is_away_level(z) || is_away_level(C.z)) && (C.z != z))//if on away mission, can only receive feed from same z_level cameras
continue
L.Add(C)
camera_sort(L)
var/list/D = list()
D["Cancel"] = "Cancel"
for(var/obj/machinery/camera/C in L)
if(!C.network)
stack_trace("Camera in a cameranet has no camera network")
continue
if(!(islist(C.network)))
stack_trace("Camera in a cameranet has a non-list camera network")
continue
var/list/tempnetwork = C.network&network
if(tempnetwork.len)
D["[C.c_tag][(C.status ? null : " (Deactivated)")]"] = C
return D
// SECURITY MONITORS
/obj/machinery/computer/security/wooden_tv
name = "security camera monitor"
desc = "An old TV hooked into the station's camera network."
icon_state = "television"
icon_keyboard = null
icon_screen = "detective_tv"
clockwork = TRUE //it'd look weird
pass_flags = PASSTABLE
/obj/machinery/computer/security/mining
name = "outpost camera console"
desc = "Used to access the various cameras on the outpost."
icon_screen = "mining"
icon_keyboard = "mining_key"
network = list("mine", "auxbase")
circuit = /obj/item/circuitboard/computer/mining
/obj/machinery/computer/security/research
name = "research camera console"
desc = "Used to access the various cameras in science."
network = list("rd")
circuit = /obj/item/circuitboard/computer/research
/obj/machinery/computer/security/hos
name = "Head of Security's camera console"
desc = "A custom security console with added access to the labor camp network."
network = list("ss13", "labor")
circuit = null
/obj/machinery/computer/security/labor
name = "labor camp monitoring"
desc = "Used to access the various cameras on the labor camp."
network = list("labor")
circuit = null
/obj/machinery/computer/security/qm
name = "Quartermaster's camera console"
desc = "A console with access to the mining, auxillary base and vault camera networks."
network = list("mine", "auxbase", "vault")
circuit = null
// TELESCREENS
/obj/machinery/computer/security/telescreen
name = "\improper Telescreen"
desc = "Used for watching an empty arena."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "telescreen"
network = list("thunder")
density = FALSE
circuit = null
clockwork = TRUE //it'd look very weird
light_power = 0
/obj/machinery/computer/security/telescreen/update_icon()
icon_state = initial(icon_state)
if(stat & BROKEN)
icon_state += "b"
return
/obj/machinery/computer/security/telescreen/entertainment
name = "entertainment monitor"
desc = "Damn, they better have the /tg/ channel on these things."
icon = 'icons/obj/status_display.dmi'
icon_state = "entertainment"
network = list("thunder")
/obj/machinery/computer/security/telescreen/rd
name = "Research Director's telescreen"
desc = "Used for watching the AI and the RD's goons from the safety of his office."
network = list("rd", "aicore", "aiupload", "minisat", "xeno", "test")
/obj/machinery/computer/security/telescreen/circuitry
name = "circuitry telescreen"
desc = "Used for watching the other eggheads from the safety of the circuitry lab."
network = list("rd")
/obj/machinery/computer/security/telescreen/ce
name = "Chief Engineer's telescreen"
desc = "Used for watching the engine, telecommunications and the minisat."
network = list("engine", "singularity", "tcomms", "minisat")
/obj/machinery/computer/security/telescreen/cmo
name = "Chief Medical Officer's telescreen"
desc = "A telescreen with access to the medbay's camera network."
network = list("medbay")
/obj/machinery/computer/security/telescreen/vault
name = "Vault monitor"
desc = "A telescreen that connects to the vault's camera network."
network = list("vault")
/obj/machinery/computer/security/telescreen/toxins
name = "Bomb test site monitor"
desc = "A telescreen that connects to the bomb test site's camera."
network = list("toxin")
/obj/machinery/computer/security/telescreen/engine
name = "engine monitor"
desc = "A telescreen that connects to the engine's camera network."
network = list("engine")
/obj/machinery/computer/security/telescreen/turbine
name = "turbine monitor"
desc = "A telescreen that connects to the turbine's camera."
network = list("turbine")
/obj/machinery/computer/security/telescreen/interrogation
name = "interrogation room monitor"
desc = "A telescreen that connects to the interrogation room's camera."
network = list("interrogation")
/obj/machinery/computer/security/telescreen/prison
name = "prison monitor"
desc = "A telescreen that connects to the permabrig's camera network."
network = list("prison")
/obj/machinery/computer/security/telescreen/auxbase
name = "auxillary base monitor"
desc = "A telescreen that connects to the auxillary base's camera."
network = list("auxbase")
/obj/machinery/computer/security/telescreen/minisat
name = "minisat monitor"
desc = "A telescreen that connects to the minisat's camera network."
network = list("minisat")
/obj/machinery/computer/security/telescreen/aiupload
name = "AI upload monitor"
desc = "A telescreen that connects to the AI upload's camera network."
network = list("aiupload")
/obj/machinery/computer/security
name = "security camera console"
desc = "Used to access the various cameras on the station."
icon_screen = "cameras"
icon_keyboard = "security_key"
circuit = /obj/item/circuitboard/computer/security
var/last_pic = 1
var/list/network = list("ss13")
var/list/watchers = list() //who's using the console, associated with the camera they're on.
light_color = LIGHT_COLOR_RED
/obj/machinery/computer/security/Initialize()
. = ..()
for(var/i in network)
network -= i
network += lowertext(i)
/obj/machinery/computer/security/check_eye(mob/user)
if(!can_interact(user) || !(user in watchers) || !watchers[user])
user.unset_machine()
return
var/obj/machinery/camera/C = watchers[user]
if(!C.can_use())
user.unset_machine()
return
/obj/machinery/computer/security/on_unset_machine(mob/user)
watchers.Remove(user)
user.reset_perspective(null)
/obj/machinery/computer/security/Destroy()
if(watchers.len)
for(var/mob/M in watchers)
M.unset_machine() //to properly reset the view of the users if the console is deleted.
return ..()
/obj/machinery/computer/security/can_interact(mob/user)
if((!issilicon(user) && !Adjacent(user)) || is_blind(user) || !in_view_range(user, src))
return FALSE
return ..()
/obj/machinery/computer/security/interact(mob/user, special_state)
. = ..()
if (ismob(user) && !isliving(user)) // ghosts don't need cameras
return
if (!network)
CRASH("No camera network")
user.unset_machine()
return FALSE
if (!(islist(network)))
CRASH("Camera network is not a list")
user.unset_machine()
return FALSE
var/list/camera_list = get_available_cameras()
if(!(user in watchers))
for(var/Num in camera_list)
var/obj/machinery/camera/CAM = camera_list[Num]
if(istype(CAM) && CAM.can_use())
watchers[user] = CAM //let's give the user the first usable camera, and then let him change to the camera he wants.
break
if(!(user in watchers))
user.unset_machine() // no usable camera on the network, we disconnect the user from the computer.
return FALSE
playsound(src, 'sound/machines/terminal_prompt.ogg', 25, 0)
use_camera_console(user)
/obj/machinery/computer/security/proc/use_camera_console(mob/user)
var/list/camera_list = get_available_cameras()
var/t = input(user, "Which camera should you change to?") as null|anything in camera_list
if(!src || user.machine != src) //while we were choosing we got disconnected from our computer or are using another machine.
return
if(!t || t == "Cancel")
user.unset_machine()
playsound(src, 'sound/machines/terminal_off.ogg', 25, 0)
return
var/obj/machinery/camera/C = camera_list[t]
if(!C || !C.can_use() || !can_interact(user))
user.unset_machine()
return FALSE
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0)
if(isAI(user))
var/mob/living/silicon/ai/A = user
A.eyeobj.setLoc(get_turf(C))
A.client.eye = A.eyeobj
else
user.reset_perspective(C)
user.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static)
user.clear_fullscreen("flash", 5)
watchers[user] = C
use_power(50)
addtimer(CALLBACK(src, .proc/use_camera_console, user), 5)
//returns the list of cameras accessible from this computer
/obj/machinery/computer/security/proc/get_available_cameras()
var/list/L = list()
for (var/obj/machinery/camera/C in GLOB.cameranet.cameras)
if((is_away_level(z) || is_away_level(C.z)) && (C.z != z))//if on away mission, can only receive feed from same z_level cameras
continue
L.Add(C)
camera_sort(L)
var/list/D = list()
D["Cancel"] = "Cancel"
for(var/obj/machinery/camera/C in L)
if(!C.network)
stack_trace("Camera in a cameranet has no camera network")
continue
if(!(islist(C.network)))
stack_trace("Camera in a cameranet has a non-list camera network")
continue
var/list/tempnetwork = C.network&network
if(tempnetwork.len)
D["[C.c_tag][(C.status ? null : " (Deactivated)")]"] = C
return D
// SECURITY MONITORS
/obj/machinery/computer/security/wooden_tv
name = "security camera monitor"
desc = "An old TV hooked into the station's camera network."
icon_state = "television"
icon_keyboard = null
icon_screen = "detective_tv"
clockwork = TRUE //it'd look weird
pass_flags = PASSTABLE
/obj/machinery/computer/security/mining
name = "outpost camera console"
desc = "Used to access the various cameras on the outpost."
icon_screen = "mining"
icon_keyboard = "mining_key"
network = list("mine", "auxbase")
circuit = /obj/item/circuitboard/computer/mining
/obj/machinery/computer/security/research
name = "research camera console"
desc = "Used to access the various cameras in science."
network = list("rd")
circuit = /obj/item/circuitboard/computer/research
/obj/machinery/computer/security/hos
name = "Head of Security's camera console"
desc = "A custom security console with added access to the labor camp network."
network = list("ss13", "labor")
circuit = null
/obj/machinery/computer/security/labor
name = "labor camp monitoring"
desc = "Used to access the various cameras on the labor camp."
network = list("labor")
circuit = null
/obj/machinery/computer/security/qm
name = "Quartermaster's camera console"
desc = "A console with access to the mining, auxillary base and vault camera networks."
network = list("mine", "auxbase", "vault")
circuit = null
// TELESCREENS
/obj/machinery/computer/security/telescreen
name = "\improper Telescreen"
desc = "Used for watching an empty arena."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "telescreen"
network = list("thunder")
density = FALSE
circuit = null
clockwork = TRUE //it'd look very weird
light_power = 0
/obj/machinery/computer/security/telescreen/update_icon()
icon_state = initial(icon_state)
if(stat & BROKEN)
icon_state += "b"
return
/obj/machinery/computer/security/telescreen/entertainment
name = "entertainment monitor"
desc = "Damn, they better have the /tg/ channel on these things."
icon = 'icons/obj/status_display.dmi'
icon_state = "entertainment"
network = list("thunder")
/obj/machinery/computer/security/telescreen/rd
name = "Research Director's telescreen"
desc = "Used for watching the AI and the RD's goons from the safety of his office."
network = list("rd", "aicore", "aiupload", "minisat", "xeno", "test")
/obj/machinery/computer/security/telescreen/circuitry
name = "circuitry telescreen"
desc = "Used for watching the other eggheads from the safety of the circuitry lab."
network = list("rd")
/obj/machinery/computer/security/telescreen/ce
name = "Chief Engineer's telescreen"
desc = "Used for watching the engine, telecommunications and the minisat."
network = list("engine", "singularity", "tcomms", "minisat")
/obj/machinery/computer/security/telescreen/cmo
name = "Chief Medical Officer's telescreen"
desc = "A telescreen with access to the medbay's camera network."
network = list("medbay")
/obj/machinery/computer/security/telescreen/vault
name = "Vault monitor"
desc = "A telescreen that connects to the vault's camera network."
network = list("vault")
/obj/machinery/computer/security/telescreen/toxins
name = "Bomb test site monitor"
desc = "A telescreen that connects to the bomb test site's camera."
network = list("toxin")
/obj/machinery/computer/security/telescreen/engine
name = "engine monitor"
desc = "A telescreen that connects to the engine's camera network."
network = list("engine")
/obj/machinery/computer/security/telescreen/turbine
name = "turbine monitor"
desc = "A telescreen that connects to the turbine's camera."
network = list("turbine")
/obj/machinery/computer/security/telescreen/interrogation
name = "interrogation room monitor"
desc = "A telescreen that connects to the interrogation room's camera."
network = list("interrogation")
/obj/machinery/computer/security/telescreen/prison
name = "prison monitor"
desc = "A telescreen that connects to the permabrig's camera network."
network = list("prison")
/obj/machinery/computer/security/telescreen/auxbase
name = "auxillary base monitor"
desc = "A telescreen that connects to the auxillary base's camera."
network = list("auxbase")
/obj/machinery/computer/security/telescreen/minisat
name = "minisat monitor"
desc = "A telescreen that connects to the minisat's camera network."
network = list("minisat")
/obj/machinery/computer/security/telescreen/aiupload
name = "AI upload monitor"
desc = "A telescreen that connects to the AI upload's camera network."
network = list("aiupload")
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+209 -209
View File
@@ -1,210 +1,210 @@
#define SENSORS_UPDATE_PERIOD 100 //How often the sensor data updates.
/obj/machinery/computer/crew
name = "crew monitoring console"
desc = "Used to monitor active health sensors built into most of the crew's uniforms."
icon_screen = "crew"
icon_keyboard = "med_key"
use_power = IDLE_POWER_USE
idle_power_usage = 250
active_power_usage = 500
circuit = /obj/item/circuitboard/computer/crew
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/crew/syndie
icon_keyboard = "syndie_key"
/obj/machinery/computer/crew/interact(mob/user)
GLOB.crewmonitor.show(user,src)
GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
/datum/crewmonitor
var/list/ui_sources = list() //List of user -> ui source
var/list/jobs
var/list/data_by_z = list()
var/list/last_update = list()
/datum/crewmonitor/New()
. = ..()
var/list/jobs = new/list()
jobs["Captain"] = 00
jobs["Head of Security"] = 10
jobs["Warden"] = 11
jobs["Security Officer"] = 12
jobs["Detective"] = 13
jobs["Chief Medical Officer"] = 20
jobs["Chemist"] = 21
jobs["Geneticist"] = 22
jobs["Virologist"] = 23
jobs["Medical Doctor"] = 24
jobs["Research Director"] = 30
jobs["Scientist"] = 31
jobs["Roboticist"] = 32
jobs["Chief Engineer"] = 40
jobs["Station Engineer"] = 41
jobs["Atmospheric Technician"] = 42
jobs["Quartermaster"] = 50
jobs["Shaft Miner"] = 51
jobs["Cargo Technician"] = 52
jobs["Head of Personnel"] = 60
jobs["Bartender"] = 61
jobs["Cook"] = 62
jobs["Botanist"] = 63
jobs["Curator"] = 64
jobs["Chaplain"] = 65
jobs["Clown"] = 66
jobs["Mime"] = 67
jobs["Janitor"] = 68
jobs["Lawyer"] = 69
jobs["Admiral"] = 200
jobs["CentCom Commander"] = 210
jobs["Custodian"] = 211
jobs["Medical Officer"] = 212
jobs["Research Officer"] = 213
jobs["Emergency Response Team Commander"] = 220
jobs["Security Response Officer"] = 221
jobs["Engineer Response Officer"] = 222
jobs["Medical Response Officer"] = 223
jobs["Assistant"] = 999 //Unknowns/custom jobs should appear after civilians, and before assistants
src.jobs = jobs
/datum/crewmonitor/Destroy()
return ..()
/datum/crewmonitor/ui_interact(mob/user, ui_key = "crew", 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)
if (!ui)
ui = new(user, src, ui_key, "crew", "crew monitor", 800, 600 , master_ui, state)
ui.open()
/datum/crewmonitor/proc/show(mob/M, source)
ui_sources[M] = source
ui_interact(M)
/datum/crewmonitor/ui_host(mob/user)
return ui_sources[user]
/datum/crewmonitor/ui_data(mob/user)
var/z = user.z
if(!z)
var/turf/T = get_turf(user)
z = T.z
var/list/zdata = update_data(z)
. = list()
.["sensors"] = zdata
.["link_allowed"] = isAI(user)
/datum/crewmonitor/proc/update_data(z)
if(data_by_z["[z]"] && last_update["[z]"] && world.time <= last_update["[z]"] + SENSORS_UPDATE_PERIOD)
return data_by_z["[z]"]
var/list/results_damaged = list()
var/list/results_undamaged = list()
var/obj/item/clothing/under/U
var/obj/item/card/id/I
var/turf/pos
var/ijob
var/name
var/assignment
var/oxydam
var/toxdam
var/burndam
var/brutedam
var/totaldam
var/area
var/pos_x
var/pos_y
var/life_status
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
var/nanite_sensors = FALSE
if(H in SSnanites.nanite_monitored_mobs)
nanite_sensors = TRUE
// Check if their z-level is correct and if they are wearing a uniform.
// Accept H.z==0 as well in case the mob is inside an object.
if ((H.z == 0 || H.z == z) && istype(H.w_uniform, /obj/item/clothing/under) || nanite_sensors)
U = H.w_uniform
// Are the suit sensors on?
if (nanite_sensors || ((U.has_sensor > 0) && U.sensor_mode))
pos = H.z == 0 || (nanite_sensors || U.sensor_mode == SENSOR_COORDS) ? get_turf(H) : null
// Special case: If the mob is inside an object confirm the z-level on turf level.
if (H.z == 0 && (!pos || pos.z != z))
continue
I = H.wear_id ? H.wear_id.GetID() : null
if (I)
name = I.registered_name
assignment = I.assignment
ijob = jobs[I.assignment]
else
name = "Unknown"
assignment = ""
ijob = 80
if (nanite_sensors || U.sensor_mode >= SENSOR_LIVING)
life_status = (!H.stat ? TRUE : FALSE)
else
life_status = null
if (nanite_sensors || U.sensor_mode >= SENSOR_VITALS)
oxydam = round(H.getOxyLoss(),1)
toxdam = round(H.getToxLoss(),1)
burndam = round(H.getFireLoss(),1)
brutedam = round(H.getBruteLoss(),1)
totaldam = oxydam + toxdam + burndam + brutedam
else
oxydam = null
toxdam = null
burndam = null
brutedam = null
totaldam = 0
if (nanite_sensors || U.sensor_mode >= SENSOR_COORDS)
if (!pos)
pos = get_turf(H)
area = get_area_name(H, TRUE)
pos_x = pos.x
pos_y = pos.y
else
area = null
pos_x = null
pos_y = null
var/total_list = list("name" = name, "assignment" = assignment, "ijob" = ijob, "life_status" = life_status, "oxydam" = oxydam, "toxdam" = toxdam, "burndam" = burndam, "brutedam" = brutedam, "totaldam" = totaldam, "area" = area, "pos_x" = pos_x, "pos_y" = pos_y, "can_track" = H.can_track(null))
if(totaldam)
results_damaged[++results_damaged.len] = total_list
else
results_undamaged[++results_undamaged.len] = total_list
var/list/returning = sortTim(results_damaged,/proc/damage_compare) + sortTim(results_undamaged,/proc/ijob_compare)
data_by_z["[z]"] = returning
last_update["[z]"] = world.time
return returning
/proc/ijob_compare(list/a,list/b)
return a["ijob"] - b["ijob"]
/proc/damage_compare(list/a,list/b)
return b["totaldam"] - a["totaldam"]
/datum/crewmonitor/ui_act(action,params)
var/mob/living/silicon/ai/AI = usr
if(!istype(AI))
return
switch (action)
if ("select_person")
AI.ai_camera_track(params["name"])
#define SENSORS_UPDATE_PERIOD 100 //How often the sensor data updates.
/obj/machinery/computer/crew
name = "crew monitoring console"
desc = "Used to monitor active health sensors built into most of the crew's uniforms."
icon_screen = "crew"
icon_keyboard = "med_key"
use_power = IDLE_POWER_USE
idle_power_usage = 250
active_power_usage = 500
circuit = /obj/item/circuitboard/computer/crew
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/crew/syndie
icon_keyboard = "syndie_key"
/obj/machinery/computer/crew/interact(mob/user)
GLOB.crewmonitor.show(user,src)
GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
/datum/crewmonitor
var/list/ui_sources = list() //List of user -> ui source
var/list/jobs
var/list/data_by_z = list()
var/list/last_update = list()
/datum/crewmonitor/New()
. = ..()
var/list/jobs = new/list()
jobs["Captain"] = 00
jobs["Head of Security"] = 10
jobs["Warden"] = 11
jobs["Security Officer"] = 12
jobs["Detective"] = 13
jobs["Chief Medical Officer"] = 20
jobs["Chemist"] = 21
jobs["Geneticist"] = 22
jobs["Virologist"] = 23
jobs["Medical Doctor"] = 24
jobs["Research Director"] = 30
jobs["Scientist"] = 31
jobs["Roboticist"] = 32
jobs["Chief Engineer"] = 40
jobs["Station Engineer"] = 41
jobs["Atmospheric Technician"] = 42
jobs["Quartermaster"] = 50
jobs["Shaft Miner"] = 51
jobs["Cargo Technician"] = 52
jobs["Head of Personnel"] = 60
jobs["Bartender"] = 61
jobs["Cook"] = 62
jobs["Botanist"] = 63
jobs["Curator"] = 64
jobs["Chaplain"] = 65
jobs["Clown"] = 66
jobs["Mime"] = 67
jobs["Janitor"] = 68
jobs["Lawyer"] = 69
jobs["Admiral"] = 200
jobs["CentCom Commander"] = 210
jobs["Custodian"] = 211
jobs["Medical Officer"] = 212
jobs["Research Officer"] = 213
jobs["Emergency Response Team Commander"] = 220
jobs["Security Response Officer"] = 221
jobs["Engineer Response Officer"] = 222
jobs["Medical Response Officer"] = 223
jobs["Assistant"] = 999 //Unknowns/custom jobs should appear after civilians, and before assistants
src.jobs = jobs
/datum/crewmonitor/Destroy()
return ..()
/datum/crewmonitor/ui_interact(mob/user, ui_key = "crew", 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)
if (!ui)
ui = new(user, src, ui_key, "crew", "crew monitor", 800, 600 , master_ui, state)
ui.open()
/datum/crewmonitor/proc/show(mob/M, source)
ui_sources[M] = source
ui_interact(M)
/datum/crewmonitor/ui_host(mob/user)
return ui_sources[user]
/datum/crewmonitor/ui_data(mob/user)
var/z = user.z
if(!z)
var/turf/T = get_turf(user)
z = T.z
var/list/zdata = update_data(z)
. = list()
.["sensors"] = zdata
.["link_allowed"] = isAI(user)
/datum/crewmonitor/proc/update_data(z)
if(data_by_z["[z]"] && last_update["[z]"] && world.time <= last_update["[z]"] + SENSORS_UPDATE_PERIOD)
return data_by_z["[z]"]
var/list/results_damaged = list()
var/list/results_undamaged = list()
var/obj/item/clothing/under/U
var/obj/item/card/id/I
var/turf/pos
var/ijob
var/name
var/assignment
var/oxydam
var/toxdam
var/burndam
var/brutedam
var/totaldam
var/area
var/pos_x
var/pos_y
var/life_status
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
var/nanite_sensors = FALSE
if(H in SSnanites.nanite_monitored_mobs)
nanite_sensors = TRUE
// Check if their z-level is correct and if they are wearing a uniform.
// Accept H.z==0 as well in case the mob is inside an object.
if ((H.z == 0 || H.z == z) && istype(H.w_uniform, /obj/item/clothing/under) || nanite_sensors)
U = H.w_uniform
// Are the suit sensors on?
if (nanite_sensors || ((U.has_sensor > 0) && U.sensor_mode))
pos = H.z == 0 || (nanite_sensors || U.sensor_mode == SENSOR_COORDS) ? get_turf(H) : null
// Special case: If the mob is inside an object confirm the z-level on turf level.
if (H.z == 0 && (!pos || pos.z != z))
continue
I = H.wear_id ? H.wear_id.GetID() : null
if (I)
name = I.registered_name
assignment = I.assignment
ijob = jobs[I.assignment]
else
name = "Unknown"
assignment = ""
ijob = 80
if (nanite_sensors || U.sensor_mode >= SENSOR_LIVING)
life_status = (!H.stat ? TRUE : FALSE)
else
life_status = null
if (nanite_sensors || U.sensor_mode >= SENSOR_VITALS)
oxydam = round(H.getOxyLoss(),1)
toxdam = round(H.getToxLoss(),1)
burndam = round(H.getFireLoss(),1)
brutedam = round(H.getBruteLoss(),1)
totaldam = oxydam + toxdam + burndam + brutedam
else
oxydam = null
toxdam = null
burndam = null
brutedam = null
totaldam = 0
if (nanite_sensors || U.sensor_mode >= SENSOR_COORDS)
if (!pos)
pos = get_turf(H)
area = get_area_name(H, TRUE)
pos_x = pos.x
pos_y = pos.y
else
area = null
pos_x = null
pos_y = null
var/total_list = list("name" = name, "assignment" = assignment, "ijob" = ijob, "life_status" = life_status, "oxydam" = oxydam, "toxdam" = toxdam, "burndam" = burndam, "brutedam" = brutedam, "totaldam" = totaldam, "area" = area, "pos_x" = pos_x, "pos_y" = pos_y, "can_track" = H.can_track(null))
if(totaldam)
results_damaged[++results_damaged.len] = total_list
else
results_undamaged[++results_undamaged.len] = total_list
var/list/returning = sortTim(results_damaged,/proc/damage_compare) + sortTim(results_undamaged,/proc/ijob_compare)
data_by_z["[z]"] = returning
last_update["[z]"] = world.time
return returning
/proc/ijob_compare(list/a,list/b)
return a["ijob"] - b["ijob"]
/proc/damage_compare(list/a,list/b)
return b["totaldam"] - a["totaldam"]
/datum/crewmonitor/ui_act(action,params)
var/mob/living/silicon/ai/AI = usr
if(!istype(AI))
return
switch (action)
if ("select_person")
AI.ai_camera_track(params["name"])
#undef SENSORS_UPDATE_PERIOD
+71 -71
View File
@@ -1,72 +1,72 @@
/obj/machinery/computer/upload
var/mob/living/silicon/current = null //The target of future law uploads
icon_screen = "command"
/obj/machinery/computer/upload/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/aiModule))
var/obj/item/aiModule/M = O
if(src.stat & (NOPOWER|BROKEN|MAINT))
return
if(!current)
to_chat(user, "<span class='caution'>You haven't selected anything to transmit laws to!</span>")
return
if(!can_upload_to(current))
to_chat(user, "<span class='caution'>Upload failed!</span> Check to make sure [current.name] is functioning properly.")
current = null
return
var/turf/currentloc = get_turf(current)
if(currentloc && user.z != currentloc.z)
to_chat(user, "<span class='caution'>Upload failed!</span> Unable to establish a connection to [current.name]. You're too far away!")
current = null
return
M.install(current.laws, user)
else
return ..()
/obj/machinery/computer/upload/proc/can_upload_to(mob/living/silicon/S)
if(S.stat == DEAD)
return 0
return 1
/obj/machinery/computer/upload/ai
name = "\improper AI upload console"
desc = "Used to upload laws to the AI."
circuit = /obj/item/circuitboard/computer/aiupload
/obj/machinery/computer/upload/ai/interact(mob/user)
src.current = select_active_ai(user)
if (!src.current)
to_chat(user, "<span class='caution'>No active AIs detected!</span>")
else
to_chat(user, "[src.current.name] selected for law changes.")
/obj/machinery/computer/upload/ai/can_upload_to(mob/living/silicon/ai/A)
if(!A || !isAI(A))
return 0
if(A.control_disabled)
return 0
return ..()
/obj/machinery/computer/upload/borg
name = "cyborg upload console"
desc = "Used to upload laws to Cyborgs."
circuit = /obj/item/circuitboard/computer/borgupload
/obj/machinery/computer/upload/borg/interact(mob/user)
src.current = select_active_free_borg(user)
if(!src.current)
to_chat(user, "<span class='caution'>No active unslaved cyborgs detected!</span>")
else
to_chat(user, "[src.current.name] selected for law changes.")
/obj/machinery/computer/upload/borg/can_upload_to(mob/living/silicon/robot/B)
if(!B || !iscyborg(B))
return 0
if(B.scrambledcodes || B.emagged)
return 0
/obj/machinery/computer/upload
var/mob/living/silicon/current = null //The target of future law uploads
icon_screen = "command"
/obj/machinery/computer/upload/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/aiModule))
var/obj/item/aiModule/M = O
if(src.stat & (NOPOWER|BROKEN|MAINT))
return
if(!current)
to_chat(user, "<span class='caution'>You haven't selected anything to transmit laws to!</span>")
return
if(!can_upload_to(current))
to_chat(user, "<span class='caution'>Upload failed!</span> Check to make sure [current.name] is functioning properly.")
current = null
return
var/turf/currentloc = get_turf(current)
if(currentloc && user.z != currentloc.z)
to_chat(user, "<span class='caution'>Upload failed!</span> Unable to establish a connection to [current.name]. You're too far away!")
current = null
return
M.install(current.laws, user)
else
return ..()
/obj/machinery/computer/upload/proc/can_upload_to(mob/living/silicon/S)
if(S.stat == DEAD)
return 0
return 1
/obj/machinery/computer/upload/ai
name = "\improper AI upload console"
desc = "Used to upload laws to the AI."
circuit = /obj/item/circuitboard/computer/aiupload
/obj/machinery/computer/upload/ai/interact(mob/user)
src.current = select_active_ai(user)
if (!src.current)
to_chat(user, "<span class='caution'>No active AIs detected!</span>")
else
to_chat(user, "[src.current.name] selected for law changes.")
/obj/machinery/computer/upload/ai/can_upload_to(mob/living/silicon/ai/A)
if(!A || !isAI(A))
return 0
if(A.control_disabled)
return 0
return ..()
/obj/machinery/computer/upload/borg
name = "cyborg upload console"
desc = "Used to upload laws to Cyborgs."
circuit = /obj/item/circuitboard/computer/borgupload
/obj/machinery/computer/upload/borg/interact(mob/user)
src.current = select_active_free_borg(user)
if(!src.current)
to_chat(user, "<span class='caution'>No active unslaved cyborgs detected!</span>")
else
to_chat(user, "[src.current.name] selected for law changes.")
/obj/machinery/computer/upload/borg/can_upload_to(mob/living/silicon/robot/B)
if(!B || !iscyborg(B))
return 0
if(B.scrambledcodes || B.emagged)
return 0
return ..()
File diff suppressed because it is too large Load Diff
+133 -133
View File
@@ -1,133 +1,133 @@
/obj/machinery/computer/pod
name = "mass driver launch control"
desc = "A combined blastdoor and mass driver control unit."
var/obj/machinery/mass_driver/connected = null
var/title = "Mass Driver Controls"
var/id = 1
var/timing = 0
var/time = 30
var/range = 4
/obj/machinery/computer/pod/Initialize()
. = ..()
for(var/obj/machinery/mass_driver/M in range(range, src))
if(M.id == id)
connected = M
/obj/machinery/computer/pod/proc/alarm()
if(stat & (NOPOWER|BROKEN))
return
if(!connected)
say("Cannot locate mass driver connector. Cancelling firing sequence!")
return
for(var/obj/machinery/door/poddoor/M in range(range, src))
if(M.id == id)
M.open()
sleep(20)
for(var/obj/machinery/mass_driver/M in range(range, src))
if(M.id == id)
M.power = connected.power
M.drive()
sleep(50)
for(var/obj/machinery/door/poddoor/M in range(range, src))
if(M.id == id)
M.close()
/obj/machinery/computer/pod/ui_interact(mob/user)
. = ..()
if(!allowed(user))
to_chat(user, "<span class='warning'>Access denied.</span>")
return
var/dat = ""
if(connected)
var/d2
if(timing) //door controls do not need timers.
d2 = "<A href='?src=[REF(src)];time=0'>Stop Time Launch</A>"
else
d2 = "<A href='?src=[REF(src)];time=1'>Initiate Time Launch</A>"
dat += "<HR>\nTimer System: [d2]\nTime Left: [DisplayTimeText(time)] <A href='?src=[REF(src)];tp=-30'>-</A> <A href='?src=[REF(src)];tp=-1'>-</A> <A href='?src=[REF(src)];tp=1'>+</A> <A href='?src=[REF(src)];tp=30'>+</A>"
var/temp = ""
var/list/L = list( 0.25, 0.5, 1, 2, 4, 8, 16 )
for(var/t in L)
if(t == connected.power)
temp += "[t] "
else
temp += "<A href = '?src=[REF(src)];power=[t]'>[t]</A> "
dat += "<HR>\nPower Level: [temp]<BR>\n<A href = '?src=[REF(src)];alarm=1'>Firing Sequence</A><BR>\n<A href = '?src=[REF(src)];drive=1'>Test Fire Driver</A><BR>\n<A href = '?src=[REF(src)];door=1'>Toggle Outer Door</A><BR>"
else
dat += "<BR>\n<A href = '?src=[REF(src)];door=1'>Toggle Outer Door</A><BR>"
dat += "<BR><BR><A href='?src=[REF(user)];mach_close=computer'>Close</A>"
add_fingerprint(usr)
var/datum/browser/popup = new(user, "computer", title, 400, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
/obj/machinery/computer/pod/process()
if(!..())
return
if(timing)
if(time > 0)
time = round(time) - 1
else
alarm()
time = 0
timing = 0
updateDialog()
/obj/machinery/computer/pod/Topic(href, href_list)
if(..())
return
if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr))
usr.set_machine(src)
if(href_list["power"])
var/t = text2num(href_list["power"])
t = min(max(0.25, t), 16)
if(connected)
connected.power = t
if(href_list["alarm"])
alarm()
if(href_list["time"])
timing = text2num(href_list["time"])
if(href_list["tp"])
var/tp = text2num(href_list["tp"])
time += tp
time = min(max(round(time), 0), 120)
if(href_list["door"])
for(var/obj/machinery/door/poddoor/M in range(range, src))
if(M.id == id)
if(M.density)
M.open()
else
M.close()
if(href_list["drive"])
for(var/obj/machinery/mass_driver/M in range(range, src))
if(M.id == id)
M.power = connected.power
M.drive()
updateUsrDialog()
/obj/machinery/computer/pod/old
name = "\improper DoorMex control console"
title = "Door Controls"
icon_state = "oldcomp"
icon_screen = "library"
icon_keyboard = null
/obj/machinery/computer/pod/old/syndicate
name = "\improper ProComp Executive IIc"
desc = "The Syndicate operate on a tight budget. Operates external airlocks."
title = "External Airlock Controls"
req_access = list(ACCESS_SYNDICATE)
/obj/machinery/computer/pod/old/swf
name = "\improper Magix System IV"
desc = "An arcane artifact that holds much magic. Running E-Knock 2.2: Sorcerer's Edition."
/obj/machinery/computer/pod
name = "mass driver launch control"
desc = "A combined blastdoor and mass driver control unit."
var/obj/machinery/mass_driver/connected = null
var/title = "Mass Driver Controls"
var/id = 1
var/timing = 0
var/time = 30
var/range = 4
/obj/machinery/computer/pod/Initialize()
. = ..()
for(var/obj/machinery/mass_driver/M in range(range, src))
if(M.id == id)
connected = M
/obj/machinery/computer/pod/proc/alarm()
if(stat & (NOPOWER|BROKEN))
return
if(!connected)
say("Cannot locate mass driver connector. Cancelling firing sequence!")
return
for(var/obj/machinery/door/poddoor/M in range(range, src))
if(M.id == id)
M.open()
sleep(20)
for(var/obj/machinery/mass_driver/M in range(range, src))
if(M.id == id)
M.power = connected.power
M.drive()
sleep(50)
for(var/obj/machinery/door/poddoor/M in range(range, src))
if(M.id == id)
M.close()
/obj/machinery/computer/pod/ui_interact(mob/user)
. = ..()
if(!allowed(user))
to_chat(user, "<span class='warning'>Access denied.</span>")
return
var/dat = ""
if(connected)
var/d2
if(timing) //door controls do not need timers.
d2 = "<A href='?src=[REF(src)];time=0'>Stop Time Launch</A>"
else
d2 = "<A href='?src=[REF(src)];time=1'>Initiate Time Launch</A>"
dat += "<HR>\nTimer System: [d2]\nTime Left: [DisplayTimeText(time)] <A href='?src=[REF(src)];tp=-30'>-</A> <A href='?src=[REF(src)];tp=-1'>-</A> <A href='?src=[REF(src)];tp=1'>+</A> <A href='?src=[REF(src)];tp=30'>+</A>"
var/temp = ""
var/list/L = list( 0.25, 0.5, 1, 2, 4, 8, 16 )
for(var/t in L)
if(t == connected.power)
temp += "[t] "
else
temp += "<A href = '?src=[REF(src)];power=[t]'>[t]</A> "
dat += "<HR>\nPower Level: [temp]<BR>\n<A href = '?src=[REF(src)];alarm=1'>Firing Sequence</A><BR>\n<A href = '?src=[REF(src)];drive=1'>Test Fire Driver</A><BR>\n<A href = '?src=[REF(src)];door=1'>Toggle Outer Door</A><BR>"
else
dat += "<BR>\n<A href = '?src=[REF(src)];door=1'>Toggle Outer Door</A><BR>"
dat += "<BR><BR><A href='?src=[REF(user)];mach_close=computer'>Close</A>"
add_fingerprint(usr)
var/datum/browser/popup = new(user, "computer", title, 400, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
/obj/machinery/computer/pod/process()
if(!..())
return
if(timing)
if(time > 0)
time = round(time) - 1
else
alarm()
time = 0
timing = 0
updateDialog()
/obj/machinery/computer/pod/Topic(href, href_list)
if(..())
return
if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr))
usr.set_machine(src)
if(href_list["power"])
var/t = text2num(href_list["power"])
t = min(max(0.25, t), 16)
if(connected)
connected.power = t
if(href_list["alarm"])
alarm()
if(href_list["time"])
timing = text2num(href_list["time"])
if(href_list["tp"])
var/tp = text2num(href_list["tp"])
time += tp
time = min(max(round(time), 0), 120)
if(href_list["door"])
for(var/obj/machinery/door/poddoor/M in range(range, src))
if(M.id == id)
if(M.density)
M.open()
else
M.close()
if(href_list["drive"])
for(var/obj/machinery/mass_driver/M in range(range, src))
if(M.id == id)
M.power = connected.power
M.drive()
updateUsrDialog()
/obj/machinery/computer/pod/old
name = "\improper DoorMex control console"
title = "Door Controls"
icon_state = "oldcomp"
icon_screen = "library"
icon_keyboard = null
/obj/machinery/computer/pod/old/syndicate
name = "\improper ProComp Executive IIc"
desc = "The Syndicate operate on a tight budget. Operates external airlocks."
title = "External Airlock Controls"
req_access = list(ACCESS_SYNDICATE)
/obj/machinery/computer/pod/old/swf
name = "\improper Magix System IV"
desc = "An arcane artifact that holds much magic. Running E-Knock 2.2: Sorcerer's Edition."
+165 -165
View File
@@ -1,165 +1,165 @@
/obj/machinery/computer/robotics
name = "robotics control console"
desc = "Used to remotely lockdown or detonate linked Cyborgs and Drones."
icon_screen = "robot"
icon_keyboard = "rd_key"
req_access = list(ACCESS_ROBOTICS)
circuit = /obj/item/circuitboard/computer/robotics
var/temp = null
light_color = LIGHT_COLOR_PINK
/obj/machinery/computer/robotics/proc/can_control(mob/user, mob/living/silicon/robot/R)
if(!istype(R))
return 0
if(isAI(user))
if (R.connected_ai != user)
return 0
if(iscyborg(user))
if (R != user)
return 0
if(R.scrambledcodes)
return 0
return 1
/obj/machinery/computer/robotics/ui_interact(mob/user)
. = ..()
if (src.z > 6)
to_chat(user, "<span class='boldannounce'>Unable to establish a connection</span>: \black You're too far away from the station!")
return
user.set_machine(src)
var/dat
var/robots = 0
for(var/mob/living/silicon/robot/R in GLOB.silicon_mobs)
if(!can_control(user, R))
continue
robots++
dat += "[R.name] |"
if(R.stat)
dat += " Not Responding |"
else if (!R.canmove)
dat += " Locked Down |"
else
dat += " Operating Normally |"
if (!R.canmove)
else if(R.cell)
dat += " Battery Installed ([R.cell.charge]/[R.cell.maxcharge]) |"
else
dat += " No Cell Installed |"
if(R.module)
dat += " Module Installed ([R.module.name]) |"
else
dat += " No Module Installed |"
if(R.connected_ai)
dat += " Slaved to [R.connected_ai.name] |"
else
dat += " Independent from AI |"
if(issilicon(user) && user != R)
var/mob/living/silicon/S = user
if(is_servant_of_ratvar(S))
dat += "<A href='?src=[REF(src)];convert=[REF(R)]'>(<font color=#BE8700><i>Convert</i></font>)</A> "
else if(S.hack_software && !R.emagged)
dat += "<A href='?src=[REF(src)];magbot=[REF(R)]'>(<font color=blue><i>Hack</i></font>)</A> "
else if(IsAdminGhost(user) && !R.emagged)
dat += "<A href='?src=[REF(src)];magbot=[REF(R)]'>(<font color=blue><i>Hack</i></font>)</A> "
dat += "<A href='?src=[REF(src)];stopbot=[REF(R)]'>(<font color=green><i>[R.canmove ? "Lockdown" : "Release"]</i></font>)</A> "
dat += "<A href='?src=[REF(src)];killbot=[REF(R)]'>(<font color=red><i>Destroy</i></font>)</A>"
dat += "<BR>"
if(!robots)
dat += "No Cyborg Units detected within access parameters."
dat += "<BR>"
var/drones = 0
for(var/mob/living/simple_animal/drone/D in GLOB.drones_list)
if(D.hacked)
continue
drones++
dat += "[D.name] |"
if(D.stat)
dat += " Not Responding |"
dat += "<A href='?src=[REF(src)];killdrone=[REF(D)]'>(<font color=red><i>Destroy</i></font>)</A>"
dat += "<BR>"
if(!drones)
dat += "No Drone Units detected within access parameters."
var/datum/browser/popup = new(user, "computer", "Cyborg Control Console", 400, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return
/obj/machinery/computer/robotics/Topic(href, href_list)
if(..())
return
if (href_list["temp"])
src.temp = null
else if (href_list["killbot"])
if(src.allowed(usr))
var/mob/living/silicon/robot/R = locate(href_list["killbot"]) in GLOB.silicon_mobs
if(can_control(usr, R))
var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm" && can_control(usr, R) && !..())
var/turf/T = get_turf(R)
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(R, R.client)] at [ADMIN_VERBOSEJMP(T)]!</span>")
log_game("\<span class='notice'>[key_name(usr)] detonated [key_name(R)]!</span>")
if(R.connected_ai)
to_chat(R.connected_ai, "<br><br><span class='alert'>ALERT - Cyborg detonation detected: [R.name]</span><br>")
R.self_destruct()
else
to_chat(usr, "<span class='danger'>Access Denied.</span>")
else if (href_list["stopbot"])
if(src.allowed(usr))
var/mob/living/silicon/robot/R = locate(href_list["stopbot"]) in GLOB.silicon_mobs
if(can_control(usr, R))
var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm" && can_control(usr, R) && !..())
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] [R.canmove ? "locked down" : "released"] [key_name(R, R.client)][ADMIN_LOOKUPFLW(R)]!</span>")
log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [key_name(R)]!")
R.SetLockdown(!R.lockcharge)
to_chat(R, "[!R.lockcharge ? "<span class='notice'>Your lockdown has been lifted!" : "<span class='alert'>You have been locked down!"]</span>")
if(R.connected_ai)
to_chat(R.connected_ai, "[!R.lockcharge ? "<span class='notice'>NOTICE - Cyborg lockdown lifted" : "<span class='alert'>ALERT - Cyborg lockdown detected"]: <a href='?src=[REF(R.connected_ai)];track=[html_encode(R.name)]'>[R.name]</a></span><br>")
else
to_chat(usr, "<span class='danger'>Access Denied.</span>")
else if (href_list["magbot"])
var/mob/living/silicon/S = usr
if((istype(S) && S.hack_software) || IsAdminGhost(usr))
var/mob/living/silicon/robot/R = locate(href_list["magbot"]) in GLOB.silicon_mobs
if(istype(R) && !R.emagged && (R.connected_ai == usr || IsAdminGhost(usr)) && !R.scrambledcodes && can_control(usr, R))
log_game("[key_name(usr)] emagged [key_name(R)] using robotic console!")
message_admins("[ADMIN_LOOKUPFLW(usr)] emagged cyborg [key_name_admin(R)] using robotic console!")
R.SetEmagged(1)
else if(href_list["convert"])
if(isAI(usr) && is_servant_of_ratvar(usr))
var/mob/living/silicon/robot/R = locate(href_list["convert"]) in GLOB.silicon_mobs
if(istype(R) && !is_servant_of_ratvar(R) && R.connected_ai == usr)
log_game("[key_name(usr)] converted [key_name(R)] using robotic console!")
message_admins("[ADMIN_LOOKUPFLW(usr)] converted cyborg [key_name_admin(R)] using robotic console!")
add_servant_of_ratvar(R)
else if (href_list["killdrone"])
if(src.allowed(usr))
var/mob/living/simple_animal/drone/D = locate(href_list["killdrone"]) in GLOB.mob_list
if(D.hacked)
to_chat(usr, "<span class='danger'>ERROR: [D] is not responding to external commands.</span>")
else
var/turf/T = get_turf(D)
message_admins("[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(D)] at [ADMIN_VERBOSEJMP(T)]!")
log_game("[key_name(usr)] detonated [key_name(D)]!")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, D)
s.start()
D.visible_message("<span class='danger'>\the [D] self destructs!</span>")
D.gib()
src.updateUsrDialog()
return
/obj/machinery/computer/robotics
name = "robotics control console"
desc = "Used to remotely lockdown or detonate linked Cyborgs and Drones."
icon_screen = "robot"
icon_keyboard = "rd_key"
req_access = list(ACCESS_ROBOTICS)
circuit = /obj/item/circuitboard/computer/robotics
var/temp = null
light_color = LIGHT_COLOR_PINK
/obj/machinery/computer/robotics/proc/can_control(mob/user, mob/living/silicon/robot/R)
if(!istype(R))
return 0
if(isAI(user))
if (R.connected_ai != user)
return 0
if(iscyborg(user))
if (R != user)
return 0
if(R.scrambledcodes)
return 0
return 1
/obj/machinery/computer/robotics/ui_interact(mob/user)
. = ..()
if (src.z > 6)
to_chat(user, "<span class='boldannounce'>Unable to establish a connection</span>: \black You're too far away from the station!")
return
user.set_machine(src)
var/dat
var/robots = 0
for(var/mob/living/silicon/robot/R in GLOB.silicon_mobs)
if(!can_control(user, R))
continue
robots++
dat += "[R.name] |"
if(R.stat)
dat += " Not Responding |"
else if (!R.canmove)
dat += " Locked Down |"
else
dat += " Operating Normally |"
if (!R.canmove)
else if(R.cell)
dat += " Battery Installed ([R.cell.charge]/[R.cell.maxcharge]) |"
else
dat += " No Cell Installed |"
if(R.module)
dat += " Module Installed ([R.module.name]) |"
else
dat += " No Module Installed |"
if(R.connected_ai)
dat += " Slaved to [R.connected_ai.name] |"
else
dat += " Independent from AI |"
if(issilicon(user) && user != R)
var/mob/living/silicon/S = user
if(is_servant_of_ratvar(S))
dat += "<A href='?src=[REF(src)];convert=[REF(R)]'>(<font color=#BE8700><i>Convert</i></font>)</A> "
else if(S.hack_software && !R.emagged)
dat += "<A href='?src=[REF(src)];magbot=[REF(R)]'>(<font color=blue><i>Hack</i></font>)</A> "
else if(IsAdminGhost(user) && !R.emagged)
dat += "<A href='?src=[REF(src)];magbot=[REF(R)]'>(<font color=blue><i>Hack</i></font>)</A> "
dat += "<A href='?src=[REF(src)];stopbot=[REF(R)]'>(<font color=green><i>[R.canmove ? "Lockdown" : "Release"]</i></font>)</A> "
dat += "<A href='?src=[REF(src)];killbot=[REF(R)]'>(<font color=red><i>Destroy</i></font>)</A>"
dat += "<BR>"
if(!robots)
dat += "No Cyborg Units detected within access parameters."
dat += "<BR>"
var/drones = 0
for(var/mob/living/simple_animal/drone/D in GLOB.drones_list)
if(D.hacked)
continue
drones++
dat += "[D.name] |"
if(D.stat)
dat += " Not Responding |"
dat += "<A href='?src=[REF(src)];killdrone=[REF(D)]'>(<font color=red><i>Destroy</i></font>)</A>"
dat += "<BR>"
if(!drones)
dat += "No Drone Units detected within access parameters."
var/datum/browser/popup = new(user, "computer", "Cyborg Control Console", 400, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return
/obj/machinery/computer/robotics/Topic(href, href_list)
if(..())
return
if (href_list["temp"])
src.temp = null
else if (href_list["killbot"])
if(src.allowed(usr))
var/mob/living/silicon/robot/R = locate(href_list["killbot"]) in GLOB.silicon_mobs
if(can_control(usr, R))
var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm" && can_control(usr, R) && !..())
var/turf/T = get_turf(R)
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(R, R.client)] at [ADMIN_VERBOSEJMP(T)]!</span>")
log_game("\<span class='notice'>[key_name(usr)] detonated [key_name(R)]!</span>")
if(R.connected_ai)
to_chat(R.connected_ai, "<br><br><span class='alert'>ALERT - Cyborg detonation detected: [R.name]</span><br>")
R.self_destruct()
else
to_chat(usr, "<span class='danger'>Access Denied.</span>")
else if (href_list["stopbot"])
if(src.allowed(usr))
var/mob/living/silicon/robot/R = locate(href_list["stopbot"]) in GLOB.silicon_mobs
if(can_control(usr, R))
var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm" && can_control(usr, R) && !..())
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] [R.canmove ? "locked down" : "released"] [key_name(R, R.client)][ADMIN_LOOKUPFLW(R)]!</span>")
log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [key_name(R)]!")
R.SetLockdown(!R.lockcharge)
to_chat(R, "[!R.lockcharge ? "<span class='notice'>Your lockdown has been lifted!" : "<span class='alert'>You have been locked down!"]</span>")
if(R.connected_ai)
to_chat(R.connected_ai, "[!R.lockcharge ? "<span class='notice'>NOTICE - Cyborg lockdown lifted" : "<span class='alert'>ALERT - Cyborg lockdown detected"]: <a href='?src=[REF(R.connected_ai)];track=[html_encode(R.name)]'>[R.name]</a></span><br>")
else
to_chat(usr, "<span class='danger'>Access Denied.</span>")
else if (href_list["magbot"])
var/mob/living/silicon/S = usr
if((istype(S) && S.hack_software) || IsAdminGhost(usr))
var/mob/living/silicon/robot/R = locate(href_list["magbot"]) in GLOB.silicon_mobs
if(istype(R) && !R.emagged && (R.connected_ai == usr || IsAdminGhost(usr)) && !R.scrambledcodes && can_control(usr, R))
log_game("[key_name(usr)] emagged [key_name(R)] using robotic console!")
message_admins("[ADMIN_LOOKUPFLW(usr)] emagged cyborg [key_name_admin(R)] using robotic console!")
R.SetEmagged(1)
else if(href_list["convert"])
if(isAI(usr) && is_servant_of_ratvar(usr))
var/mob/living/silicon/robot/R = locate(href_list["convert"]) in GLOB.silicon_mobs
if(istype(R) && !is_servant_of_ratvar(R) && R.connected_ai == usr)
log_game("[key_name(usr)] converted [key_name(R)] using robotic console!")
message_admins("[ADMIN_LOOKUPFLW(usr)] converted cyborg [key_name_admin(R)] using robotic console!")
add_servant_of_ratvar(R)
else if (href_list["killdrone"])
if(src.allowed(usr))
var/mob/living/simple_animal/drone/D = locate(href_list["killdrone"]) in GLOB.mob_list
if(D.hacked)
to_chat(usr, "<span class='danger'>ERROR: [D] is not responding to external commands.</span>")
else
var/turf/T = get_turf(D)
message_admins("[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(D)] at [ADMIN_VERBOSEJMP(T)]!")
log_game("[key_name(usr)] detonated [key_name(D)]!")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, D)
s.start()
D.visible_message("<span class='danger'>\the [D] self destructs!</span>")
D.gib()
src.updateUsrDialog()
return
File diff suppressed because it is too large Load Diff
+98 -98
View File
@@ -1,98 +1,98 @@
/obj/machinery/computer/station_alert
name = "station alert console"
desc = "Used to access the station's automated alert system."
icon_screen = "alert:0"
icon_keyboard = "atmos_key"
circuit = /obj/item/circuitboard/computer/stationalert
var/alarms = list("Fire" = list(), "Atmosphere" = list(), "Power" = list())
light_color = LIGHT_COLOR_CYAN
/obj/machinery/computer/station_alert/Initialize()
. = ..()
GLOB.alert_consoles += src
/obj/machinery/computer/station_alert/Destroy()
GLOB.alert_consoles -= src
return ..()
/obj/machinery/computer/station_alert/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)
if(!ui)
ui = new(user, src, ui_key, "station_alert", name, 300, 500, master_ui, state)
ui.open()
/obj/machinery/computer/station_alert/ui_data(mob/user)
. = list()
.["alarms"] = list()
for(var/class in alarms)
.["alarms"][class] = list()
for(var/area in alarms[class])
.["alarms"][class] += area
/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/A, O, obj/source)
if(source.z != z)
return
if(stat & (BROKEN))
return
var/list/L = alarms[class]
for(var/I in L)
if (I == A.name)
var/list/alarm = L[I]
var/list/sources = alarm[3]
if (!(source in sources))
sources += source
return 1
var/obj/machinery/camera/C = null
var/list/CL = null
if(O && islist(O))
CL = O
if (CL.len == 1)
C = CL[1]
else if(O && istype(O, /obj/machinery/camera))
C = O
L[A.name] = list(A, (C ? C : O), list(source))
return 1
/obj/machinery/computer/station_alert/proc/cancelAlarm(class, area/A, obj/origin)
if(stat & (BROKEN))
return
var/list/L = alarms[class]
var/cleared = 0
for (var/I in L)
if (I == A.name)
var/list/alarm = L[I]
var/list/srcs = alarm[3]
if (origin in srcs)
srcs -= origin
if (srcs.len == 0)
cleared = 1
L -= I
return !cleared
/obj/machinery/computer/station_alert/update_icon()
..()
cut_overlays()
SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays)
var/overlay_state = icon_screen
if(stat & (NOPOWER|BROKEN))
add_overlay("[icon_keyboard]_off")
return
add_overlay(icon_keyboard)
var/active_alarms = FALSE
for(var/cat in alarms)
var/list/L = alarms[cat]
if(L.len)
active_alarms = TRUE
if(active_alarms)
overlay_state = "alert:2"
add_overlay("alert:2")
else
overlay_state = "alert:0"
add_overlay("alert:0")
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, layer, plane, dir)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir, alpha=128)
/obj/machinery/computer/station_alert
name = "station alert console"
desc = "Used to access the station's automated alert system."
icon_screen = "alert:0"
icon_keyboard = "atmos_key"
circuit = /obj/item/circuitboard/computer/stationalert
var/alarms = list("Fire" = list(), "Atmosphere" = list(), "Power" = list())
light_color = LIGHT_COLOR_CYAN
/obj/machinery/computer/station_alert/Initialize()
. = ..()
GLOB.alert_consoles += src
/obj/machinery/computer/station_alert/Destroy()
GLOB.alert_consoles -= src
return ..()
/obj/machinery/computer/station_alert/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)
if(!ui)
ui = new(user, src, ui_key, "station_alert", name, 300, 500, master_ui, state)
ui.open()
/obj/machinery/computer/station_alert/ui_data(mob/user)
. = list()
.["alarms"] = list()
for(var/class in alarms)
.["alarms"][class] = list()
for(var/area in alarms[class])
.["alarms"][class] += area
/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/A, O, obj/source)
if(source.z != z)
return
if(stat & (BROKEN))
return
var/list/L = alarms[class]
for(var/I in L)
if (I == A.name)
var/list/alarm = L[I]
var/list/sources = alarm[3]
if (!(source in sources))
sources += source
return 1
var/obj/machinery/camera/C = null
var/list/CL = null
if(O && islist(O))
CL = O
if (CL.len == 1)
C = CL[1]
else if(O && istype(O, /obj/machinery/camera))
C = O
L[A.name] = list(A, (C ? C : O), list(source))
return 1
/obj/machinery/computer/station_alert/proc/cancelAlarm(class, area/A, obj/origin)
if(stat & (BROKEN))
return
var/list/L = alarms[class]
var/cleared = 0
for (var/I in L)
if (I == A.name)
var/list/alarm = L[I]
var/list/srcs = alarm[3]
if (origin in srcs)
srcs -= origin
if (srcs.len == 0)
cleared = 1
L -= I
return !cleared
/obj/machinery/computer/station_alert/update_icon()
..()
cut_overlays()
SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays)
var/overlay_state = icon_screen
if(stat & (NOPOWER|BROKEN))
add_overlay("[icon_keyboard]_off")
return
add_overlay(icon_keyboard)
var/active_alarms = FALSE
for(var/cat in alarms)
var/list/L = alarms[cat]
if(L.len)
active_alarms = TRUE
if(active_alarms)
overlay_state = "alert:2"
add_overlay("alert:2")
else
overlay_state = "alert:0"
add_overlay("alert:0")
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, layer, plane, dir)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir, alpha=128)
@@ -1,215 +1,215 @@
#define NUKESCALINGMODIFIER 1
GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","Echo","Foxtrot","Zero", "Niner"))
/obj/machinery/computer/telecrystals
name = "\improper telecrystal assignment station"
desc = "A device used to manage telecrystals during group operations. You shouldn't be looking at this particular one..."
icon_state = "tcstation"
icon_keyboard = "tcstation_key"
icon_screen = "syndie"
clockwork = TRUE //it'd look weird, at least if ratvar ever got there
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
light_color = LIGHT_COLOR_RED
/////////////////////////////////////////////
/obj/machinery/computer/telecrystals/uplinker
name = "\improper telecrystal upload/receive station"
desc = "A device used to manage telecrystals during group operations. To use, simply insert your uplink. With your uplink installed \
you can upload your telecrystals to the group's pool using the console, or be assigned additional telecrystals by your lieutenant."
var/obj/item/uplinkholder = null
var/obj/machinery/computer/telecrystals/boss/linkedboss = null
/obj/machinery/computer/telecrystals/uplinker/Initialize()
. = ..()
var/ID = pick_n_take(GLOB.possible_uplinker_IDs)
if(!ID)
ID = rand(1,999)
name = "[name] [ID]"
/obj/machinery/computer/telecrystals/uplinker/attackby(obj/item/I, mob/user, params)
if(uplinkholder)
to_chat(user, "<span class='notice'>[src] already has an uplink in it.</span>")
return
var/datum/component/uplink/hidden_uplink = I.GetComponent(/datum/component/uplink)
if(hidden_uplink)
if(!user.transferItemToLoc(I, src))
return
uplinkholder = I
I.add_fingerprint(user)
update_icon()
updateUsrDialog()
else
to_chat(user, "<span class='notice'>[I] doesn't appear to be an uplink...</span>")
/obj/machinery/computer/telecrystals/uplinker/update_icon()
..()
if(uplinkholder)
add_overlay("[initial(icon_state)]-closed")
/obj/machinery/computer/telecrystals/uplinker/proc/ejectuplink()
if(uplinkholder)
uplinkholder.forceMove(drop_location())
uplinkholder = null
update_icon()
/obj/machinery/computer/telecrystals/uplinker/proc/donateTC(amt, addLog = 1)
if(uplinkholder && linkedboss)
var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink)
if(amt < 0)
linkedboss.storedcrystals += hidden_uplink.telecrystals
if(addLog)
linkedboss.logTransfer("[src] donated [hidden_uplink.telecrystals] telecrystals to [linkedboss].")
hidden_uplink.telecrystals = 0
else if(amt <= hidden_uplink.telecrystals)
hidden_uplink.telecrystals -= amt
linkedboss.storedcrystals += amt
if(addLog)
linkedboss.logTransfer("[src] donated [amt] telecrystals to [linkedboss].")
/obj/machinery/computer/telecrystals/uplinker/proc/giveTC(amt, addLog = 1)
if(uplinkholder && linkedboss)
var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink)
if(amt < 0)
hidden_uplink.telecrystals += linkedboss.storedcrystals
if(addLog)
linkedboss.logTransfer("[src] received [linkedboss.storedcrystals] telecrystals from [linkedboss].")
linkedboss.storedcrystals = 0
else if(amt <= linkedboss.storedcrystals)
hidden_uplink.telecrystals += amt
linkedboss.storedcrystals -= amt
if(addLog)
linkedboss.logTransfer("[src] received [amt] telecrystals from [linkedboss].")
///////
/obj/machinery/computer/telecrystals/uplinker/ui_interact(mob/user)
. = ..()
var/dat = ""
if(linkedboss)
dat += "[linkedboss] has [linkedboss.storedcrystals] telecrystals available for distribution. <BR><BR>"
else
dat += "No linked management consoles detected. Scan for uplink stations using the management console.<BR><BR>"
if(uplinkholder)
var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink)
dat += "[hidden_uplink.telecrystals] telecrystals remain in this uplink.<BR>"
if(linkedboss)
dat += "Donate TC: <a href='byond://?src=[REF(src)];donate=1'>1</a> | <a href='byond://?src=[REF(src)];donate=5'>5</a> | <a href='byond://?src=[REF(src)];donate=-1'>All</a>"
dat += "<br><a href='byond://?src=[REF(src)];eject=1'>Eject Uplink</a>"
var/datum/browser/popup = new(user, "computer", "Telecrystal Upload/Receive Station", 700, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
/obj/machinery/computer/telecrystals/uplinker/Topic(href, href_list)
if(..())
return
if(href_list["donate"])
var/tcamt = text2num(href_list["donate"])
donateTC(tcamt)
if(href_list["eject"])
ejectuplink()
src.updateUsrDialog()
/////////////////////////////////////////
/obj/machinery/computer/telecrystals/boss
name = "team telecrystal management console"
desc = "A device used to manage telecrystals during group operations. To use, simply initialize the machine by scanning for nearby uplink stations. \
Once the consoles are linked up, you can assign any telecrystals amongst your operatives; be they donated by your agents or rationed to the squad \
based on the danger rating of the mission."
icon_state = "computer"
icon_screen = "tcboss"
icon_keyboard = "syndie_key"
var/virgin = 1
var/scanrange = 10
var/storedcrystals = 0
var/list/TCstations = list()
var/list/transferlog = list()
/obj/machinery/computer/telecrystals/boss/proc/logTransfer(logmessage)
transferlog += ("<b>[STATION_TIME_TIMESTAMP("hh:mm:ss")]</b> [logmessage]")
/obj/machinery/computer/telecrystals/boss/proc/scanUplinkers()
for(var/obj/machinery/computer/telecrystals/uplinker/A in urange(scanrange, src.loc))
if(!A.linkedboss)
TCstations += A
A.linkedboss = src
if(virgin)
getDangerous()
virgin = 0
/obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population.
var/list/nukeops = get_antag_minds(/datum/antagonist/nukeop)
var/danger = GLOB.joined_player_list.len - nukeops.len
danger = CEILING(danger, 10)
scaleTC(danger)
/obj/machinery/computer/telecrystals/boss/proc/scaleTC(amt)//Its own proc, since it'll probably need a lot of tweaks for balance, use a fancier algorhithm, etc.
storedcrystals += amt * NUKESCALINGMODIFIER
/////////
/obj/machinery/computer/telecrystals/boss/ui_interact(mob/user)
. = ..()
var/dat = ""
dat += "<a href='byond://?src=[REF(src)];scan=1'>Scan for TC stations.</a><BR>"
dat += "[storedcrystals] telecrystals are available for distribution. <BR>"
dat += "<BR><BR>"
for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations)
dat += "[A.name] | "
if(A.uplinkholder)
var/datum/component/uplink/hidden_uplink = A.uplinkholder.GetComponent(/datum/component/uplink)
dat += "[hidden_uplink.telecrystals] telecrystals."
if(storedcrystals)
dat+= "<BR>Add TC: <a href ='?src=[REF(src)];target=[REF(A)];give=1'>1</a> | <a href ='?src=[REF(src)];target=[REF(A)];give=5'>5</a> | <a href ='?src=[REF(src)];target=[REF(A)];give=10'>10</a> | <a href ='?src=[REF(src)];target=[REF(A)];give=-1'>All</a>"
dat += "<BR>"
if(TCstations.len && storedcrystals)
dat += "<BR><BR><a href='byond://?src=[REF(src)];distrib=1'>Evenly distribute remaining TC.</a><BR><BR>"
for(var/entry in transferlog)
dat += "<small>[entry]</small><BR>"
var/datum/browser/popup = new(user, "computer", "Team Telecrystal Management Console", 700, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
/obj/machinery/computer/telecrystals/boss/Topic(href, href_list)
if(..())
return
if(href_list["scan"])
scanUplinkers()
if(href_list["give"])
var/tcamt = text2num(href_list["give"])
if(TCstations.len) // sanity
var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["target"]) in TCstations
A.giveTC(tcamt)
if(href_list["distrib"])
var/sanity = 0
while(storedcrystals && sanity < 100)
for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations)
A.giveTC(1,0)
sanity++
logTransfer("[src] evenly distributed telecrystals.")
src.updateUsrDialog()
return
#undef NUKESCALINGMODIFIER
#define NUKESCALINGMODIFIER 1
GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","Echo","Foxtrot","Zero", "Niner"))
/obj/machinery/computer/telecrystals
name = "\improper telecrystal assignment station"
desc = "A device used to manage telecrystals during group operations. You shouldn't be looking at this particular one..."
icon_state = "tcstation"
icon_keyboard = "tcstation_key"
icon_screen = "syndie"
clockwork = TRUE //it'd look weird, at least if ratvar ever got there
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
light_color = LIGHT_COLOR_RED
/////////////////////////////////////////////
/obj/machinery/computer/telecrystals/uplinker
name = "\improper telecrystal upload/receive station"
desc = "A device used to manage telecrystals during group operations. To use, simply insert your uplink. With your uplink installed \
you can upload your telecrystals to the group's pool using the console, or be assigned additional telecrystals by your lieutenant."
var/obj/item/uplinkholder = null
var/obj/machinery/computer/telecrystals/boss/linkedboss = null
/obj/machinery/computer/telecrystals/uplinker/Initialize()
. = ..()
var/ID = pick_n_take(GLOB.possible_uplinker_IDs)
if(!ID)
ID = rand(1,999)
name = "[name] [ID]"
/obj/machinery/computer/telecrystals/uplinker/attackby(obj/item/I, mob/user, params)
if(uplinkholder)
to_chat(user, "<span class='notice'>[src] already has an uplink in it.</span>")
return
var/datum/component/uplink/hidden_uplink = I.GetComponent(/datum/component/uplink)
if(hidden_uplink)
if(!user.transferItemToLoc(I, src))
return
uplinkholder = I
I.add_fingerprint(user)
update_icon()
updateUsrDialog()
else
to_chat(user, "<span class='notice'>[I] doesn't appear to be an uplink...</span>")
/obj/machinery/computer/telecrystals/uplinker/update_icon()
..()
if(uplinkholder)
add_overlay("[initial(icon_state)]-closed")
/obj/machinery/computer/telecrystals/uplinker/proc/ejectuplink()
if(uplinkholder)
uplinkholder.forceMove(drop_location())
uplinkholder = null
update_icon()
/obj/machinery/computer/telecrystals/uplinker/proc/donateTC(amt, addLog = 1)
if(uplinkholder && linkedboss)
var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink)
if(amt < 0)
linkedboss.storedcrystals += hidden_uplink.telecrystals
if(addLog)
linkedboss.logTransfer("[src] donated [hidden_uplink.telecrystals] telecrystals to [linkedboss].")
hidden_uplink.telecrystals = 0
else if(amt <= hidden_uplink.telecrystals)
hidden_uplink.telecrystals -= amt
linkedboss.storedcrystals += amt
if(addLog)
linkedboss.logTransfer("[src] donated [amt] telecrystals to [linkedboss].")
/obj/machinery/computer/telecrystals/uplinker/proc/giveTC(amt, addLog = 1)
if(uplinkholder && linkedboss)
var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink)
if(amt < 0)
hidden_uplink.telecrystals += linkedboss.storedcrystals
if(addLog)
linkedboss.logTransfer("[src] received [linkedboss.storedcrystals] telecrystals from [linkedboss].")
linkedboss.storedcrystals = 0
else if(amt <= linkedboss.storedcrystals)
hidden_uplink.telecrystals += amt
linkedboss.storedcrystals -= amt
if(addLog)
linkedboss.logTransfer("[src] received [amt] telecrystals from [linkedboss].")
///////
/obj/machinery/computer/telecrystals/uplinker/ui_interact(mob/user)
. = ..()
var/dat = ""
if(linkedboss)
dat += "[linkedboss] has [linkedboss.storedcrystals] telecrystals available for distribution. <BR><BR>"
else
dat += "No linked management consoles detected. Scan for uplink stations using the management console.<BR><BR>"
if(uplinkholder)
var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink)
dat += "[hidden_uplink.telecrystals] telecrystals remain in this uplink.<BR>"
if(linkedboss)
dat += "Donate TC: <a href='byond://?src=[REF(src)];donate=1'>1</a> | <a href='byond://?src=[REF(src)];donate=5'>5</a> | <a href='byond://?src=[REF(src)];donate=-1'>All</a>"
dat += "<br><a href='byond://?src=[REF(src)];eject=1'>Eject Uplink</a>"
var/datum/browser/popup = new(user, "computer", "Telecrystal Upload/Receive Station", 700, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
/obj/machinery/computer/telecrystals/uplinker/Topic(href, href_list)
if(..())
return
if(href_list["donate"])
var/tcamt = text2num(href_list["donate"])
donateTC(tcamt)
if(href_list["eject"])
ejectuplink()
src.updateUsrDialog()
/////////////////////////////////////////
/obj/machinery/computer/telecrystals/boss
name = "team telecrystal management console"
desc = "A device used to manage telecrystals during group operations. To use, simply initialize the machine by scanning for nearby uplink stations. \
Once the consoles are linked up, you can assign any telecrystals amongst your operatives; be they donated by your agents or rationed to the squad \
based on the danger rating of the mission."
icon_state = "computer"
icon_screen = "tcboss"
icon_keyboard = "syndie_key"
var/virgin = 1
var/scanrange = 10
var/storedcrystals = 0
var/list/TCstations = list()
var/list/transferlog = list()
/obj/machinery/computer/telecrystals/boss/proc/logTransfer(logmessage)
transferlog += ("<b>[STATION_TIME_TIMESTAMP("hh:mm:ss")]</b> [logmessage]")
/obj/machinery/computer/telecrystals/boss/proc/scanUplinkers()
for(var/obj/machinery/computer/telecrystals/uplinker/A in urange(scanrange, src.loc))
if(!A.linkedboss)
TCstations += A
A.linkedboss = src
if(virgin)
getDangerous()
virgin = 0
/obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population.
var/list/nukeops = get_antag_minds(/datum/antagonist/nukeop)
var/danger = GLOB.joined_player_list.len - nukeops.len
danger = CEILING(danger, 10)
scaleTC(danger)
/obj/machinery/computer/telecrystals/boss/proc/scaleTC(amt)//Its own proc, since it'll probably need a lot of tweaks for balance, use a fancier algorhithm, etc.
storedcrystals += amt * NUKESCALINGMODIFIER
/////////
/obj/machinery/computer/telecrystals/boss/ui_interact(mob/user)
. = ..()
var/dat = ""
dat += "<a href='byond://?src=[REF(src)];scan=1'>Scan for TC stations.</a><BR>"
dat += "[storedcrystals] telecrystals are available for distribution. <BR>"
dat += "<BR><BR>"
for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations)
dat += "[A.name] | "
if(A.uplinkholder)
var/datum/component/uplink/hidden_uplink = A.uplinkholder.GetComponent(/datum/component/uplink)
dat += "[hidden_uplink.telecrystals] telecrystals."
if(storedcrystals)
dat+= "<BR>Add TC: <a href ='?src=[REF(src)];target=[REF(A)];give=1'>1</a> | <a href ='?src=[REF(src)];target=[REF(A)];give=5'>5</a> | <a href ='?src=[REF(src)];target=[REF(A)];give=10'>10</a> | <a href ='?src=[REF(src)];target=[REF(A)];give=-1'>All</a>"
dat += "<BR>"
if(TCstations.len && storedcrystals)
dat += "<BR><BR><a href='byond://?src=[REF(src)];distrib=1'>Evenly distribute remaining TC.</a><BR><BR>"
for(var/entry in transferlog)
dat += "<small>[entry]</small><BR>"
var/datum/browser/popup = new(user, "computer", "Team Telecrystal Management Console", 700, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
/obj/machinery/computer/telecrystals/boss/Topic(href, href_list)
if(..())
return
if(href_list["scan"])
scanUplinkers()
if(href_list["give"])
var/tcamt = text2num(href_list["give"])
if(TCstations.len) // sanity
var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["target"]) in TCstations
A.giveTC(tcamt)
if(href_list["distrib"])
var/sanity = 0
while(storedcrystals && sanity < 100)
for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations)
A.giveTC(1,0)
sanity++
logTransfer("[src] evenly distributed telecrystals.")
src.updateUsrDialog()
return
#undef NUKESCALINGMODIFIER