Files
Batrachophreno 1c8c0c2221 Bugfix pile (#22823)
Fixes several runtimes from the past few weeks, some additional material
repath regressions, and the fact that if I shoot you with a stream of
ionized deuterium particles, it doesn't riddle you with cancer.

changes:
- bugfix: "Fixes emergency shields runtiming when hit by thrown
objects."
  - bugfix: "Fixes several stale global list runtimes."
- bugfix: "Fixes several health percentage checks that could use unset
initial health values."
  - bugfix: "Fixes additional materials regressions in INDRA code."
  - bugfix: "Fixes invalid fuel injector depletion math."
- bugfix: "Makes accelerated particles apply radiation damage to living
mobs they pass through."
2026-07-12 18:06:28 +00:00

323 lines
9.5 KiB
Plaintext

/obj/structure/machinery/computer/security
name = "security camera monitor"
desc = "Used to access the various cameras on the station."
icon_screen = "cameras"
icon_keyboard = "yellow_key"
icon_keyboard_emis = "yellow_key_mask"
light_color = LIGHT_COLOR_YELLOW
var/current_network = null
var/obj/structure/machinery/camera/current_camera = null
var/last_pic = 1.0
var/list/console_networks
var/mapping = 0
var/cache_id = 0
/// A currently active program running on the computer.
var/datum/computer_file/program/camera_monitor/camera_monitor_program
circuit = /obj/item/circuitboard/security
/obj/structure/machinery/computer/security/Initialize()
if(!console_networks)
console_networks = SSatlas.current_map.station_networks.Copy()
. = ..()
if(console_networks.len)
current_network = console_networks[1]
// Create a new camera_monitor program that can run independently of a modular computer.
camera_monitor_program = new("Compless")
// Make sure that camera_monitor knows its been generated from a dedicated console; this will define its network access.
camera_monitor_program.monitored_networks = console_networks
/obj/structure/machinery/computer/security/Destroy()
if(camera_monitor_program)
camera_monitor_program = null
. = ..()
/obj/structure/machinery/computer/security/attack_ai(var/mob/user as mob)
if(!ai_can_interact(user))
return
return attack_hand(user)
/obj/structure/machinery/computer/security/check_eye(var/mob/user as mob)
if (user.stat || user.blinded || !operable())
return -1
if(!current_camera)
return 0
var/viewflag = current_camera.check_eye(user)
if ( viewflag < 0 ) //camera doesn't work
reset_current()
return viewflag
/obj/structure/machinery/computer/security/grants_equipment_vision(var/mob/user as mob)
if(user.stat || user.blinded || !operable())
return FALSE
if(!current_camera)
return FALSE
var/viewflag = current_camera.check_eye(user)
if (viewflag < 0) //camera doesn't work
return FALSE
return TRUE
/obj/structure/machinery/computer/security/proc/can_access_network(var/mob/user, var/network_access)
// No access passed, or 0 which is considered no access requirement. Allow it.
if(!network_access)
return TRUE
return (check_camera_access(user, ACCESS_SECURITY) && GLOB.security_level >= SEC_LEVEL_BLUE) || check_camera_access(user, network_access)
/obj/structure/machinery/computer/security/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
if(camera_monitor_program)
ui = new(user, src, camera_monitor_program.tgui_id, camera_monitor_program.filedesc)
ui.autoupdate = camera_monitor_program.ui_auto_update
else
to_chat(usr, "Something has gone wrong; please report the circumstances in which you received this message to the GitHub issues tracker.")
return
ui.open()
/obj/structure/machinery/computer/security/ui_data(mob/user)
var/list/data = list()
if(camera_monitor_program)
data += camera_monitor_program.ui_data(user)
return data
/obj/structure/machinery/computer/security/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
if(camera_monitor_program)
. = camera_monitor_program.ui_act(action, params, ui, state)
/obj/structure/machinery/computer/security/attack_hand(var/mob/user as mob)
if (!(src.z in GetConnectedZlevels(starting_z_level)))
to_chat(user, "Unable to establish a connection.")
return
if(stat & (NOPOWER|BROKEN)) return
if(!isAI(user))
user.set_machine(src)
user.reset_view(current_camera)
ui_interact(user)
/obj/structure/machinery/computer/security/proc/switch_to_camera(var/mob/user, var/obj/structure/machinery/camera/C)
//don't need to check if the camera works for AI because the AI jumps to the camera location and doesn't actually look through cameras.
if(isAI(user))
var/mob/living/silicon/ai/A = user
// Only allow non-carded AIs to view because the interaction with the eye gets all wonky otherwise.
if(!A.is_in_chassis())
return 0
A.eyeobj.setLoc(get_turf(C))
A.client.eye = A.eyeobj
return 1
if (user.stat || user.blinded || !operable())
return 0
set_current(C)
if (!(C.z in GetConnectedZlevels(starting_z_level)))
to_chat(user, SPAN_NOTICE("This camera is too far away to connect to!"))
return FALSE
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.reset_view(current_camera)
else
user.reset_view(current_camera)
check_eye(user)
return 1
/obj/structure/machinery/computer/security/proc/check_camera_access(var/mob/user, var/access)
if(!access)
return 1
if(!istype(user))
return 0
var/I = user.GetIdCard()
if(!I)
return 0
var/list/access_list
if(islist(I))
access_list = I
else if(istype(I, /obj/item))
var/obj/item/item = I
access_list = item.GetAccess()
if(access in access_list)
return 1
return 0
//Camera control: moving.
/obj/structure/machinery/computer/security/proc/jump_on_click(var/mob/user,var/A)
if(user.machine != src)
return
var/obj/structure/machinery/camera/jump_to
if(istype(A,/obj/structure/machinery/camera))
jump_to = A
else if(ismob(A))
if(ishuman(A))
var/mob/living/carbon/human/H = A
jump_to = locate() in H.head
else if(isrobot(A))
var/mob/living/silicon/robot/R = A
jump_to = R.camera
else if(isobj(A))
jump_to = locate() in A
else if(isturf(A))
var/best_dist = INFINITY
var/check_area = get_area(A)
if (!check_area)
return
var/list/invalid_cameras
for(var/cc in SSmachinery.all_cameras)
if(!istype(cc, /obj/structure/machinery/camera))
LAZYADD(invalid_cameras, cc)
continue
var/obj/structure/machinery/camera/camera = cc
if(QDELETED(camera))
LAZYADD(invalid_cameras, cc)
continue
if(!camera.loc)
continue
if (camera.loc.loc != check_area)
continue
if(!camera.can_use())
continue
if(!can_access_camera(camera))
continue
var/dist = get_dist(camera,A)
if(dist < best_dist)
best_dist = dist
jump_to = camera
if(invalid_cameras)
SSmachinery.all_cameras -= invalid_cameras
if(isnull(jump_to))
return
if(can_access_camera(jump_to))
switch_to_camera(user,jump_to)
/obj/structure/machinery/computer/security/proc/can_access_camera(var/obj/structure/machinery/camera/C)
var/list/shared_networks = src.console_networks & C.network
if(shared_networks.len)
return 1
return 0
/obj/structure/machinery/computer/security/proc/set_current(var/obj/structure/machinery/camera/C)
if(current_camera == C)
return
if(current_camera)
reset_current()
src.current_camera = C
if(current_camera)
update_use_power(POWER_USE_ACTIVE)
var/mob/living/L = current_camera.loc
if(istype(L))
L.tracking_initiated()
/obj/structure/machinery/computer/security/proc/reset_current()
if(current_camera)
var/mob/living/L = current_camera.loc
if(istype(L))
L.tracking_cancelled()
current_camera = null
update_use_power(POWER_USE_IDLE)
/obj/structure/machinery/computer/security/telescreen
name = "Telescreen"
desc = "Used for watching an empty arena."
icon = 'icons/obj/computer.dmi'
icon_state = "wallframe"
icon_screen = null
light_range_on = 0
console_networks = list(NETWORK_THUNDER)
density = 0
circuit = null
is_holographic = FALSE
/obj/structure/machinery/computer/security/telescreen/entertainment
name = "entertainment monitor"
desc = "Damn, why do they never have anything interesting on these things?"
icon_screen = "entertainment"
light_color = "#FFEEDB"
light_range_on = 2
circuit = null
/obj/structure/machinery/computer/security/wooden_tv
name = "security camera monitor"
desc = "An old TV hooked into the stations camera network."
icon = 'icons/obj/computer.dmi'
icon_state = "television"
icon_screen = "detective_tv"
circuit = null
light_color = "#3848B3"
light_power_on = 0.5
/obj/structure/machinery/computer/security/mining
name = "outpost camera monitor"
desc = "Used to access the various cameras on the outpost."
icon_screen = "miningcameras"
icon_keyboard = "purple_key"
icon_keyboard_emis = "purple_key_mask"
light_color = LIGHT_COLOR_PURPLE
console_networks = list("MINE")
circuit = /obj/item/circuitboard/security/mining
/obj/structure/machinery/computer/security/engineering
name = "engineering camera monitor"
desc = "Used to monitor fires and breaches."
icon_screen = "engineeringcameras"
icon_keyboard = "yellow_key"
icon_keyboard_emis = "yellow_key_mask"
light_color = LIGHT_COLOR_YELLOW
circuit = /obj/item/circuitboard/security/engineering
/obj/structure/machinery/computer/security/engineering/terminal
name = "engineering camera monitor"
icon = 'icons/obj/modular_computers/modular_terminal.dmi'
icon_screen = "engines"
icon_keyboard = "power_key"
icon_keyboard_emis = "power_key_mask"
is_connected = TRUE
has_off_keyboards = TRUE
can_pass_under = FALSE
light_power_on = 1
/obj/structure/machinery/computer/security/engineering/Initialize()
if(!console_networks)
console_networks = GLOB.engineering_networks.Copy()
. = ..()
/obj/structure/machinery/computer/security/nuclear
name = "head mounted camera monitor"
desc = "Used to access the built-in cameras in helmets."
icon_screen = "syndicam"
icon_keyboard = "red_key"
icon_keyboard_emis = "red_key_mask"
light_color = LIGHT_COLOR_RED
console_networks = list(NETWORK_MERCENARY)
circuit = null
/obj/structure/machinery/computer/security/nuclear/Initialize()
. = ..()
req_access = list(150)
/obj/structure/machinery/computer/security/terminal
name = "camera monitor terminal"
icon = 'icons/obj/modular_computers/modular_terminal.dmi'
icon_screen = "cameras"
icon_keyboard = "security_key"
icon_keyboard_emis = "security_key_mask"
is_connected = TRUE
has_off_keyboards = TRUE
can_pass_under = FALSE
light_power_on = 1