Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into tggenetics
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -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
@@ -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."
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user