mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-10 00:43:14 +00:00
* Fixes malf camera upgrade appearing on security camera consoles (#73970) ## About The Pull Request Wow that was easier than I thought Malf AI camera upgrade no longer shows up camera consoles. Advanced Camera consoles probably still show it but those are harder to get so someone else can fix those ## Why It's Good For The Game It is admittedly very funny to instantly valid a malf ai but probably not fun ## Changelog 🆑 Melbert fix: Malf AI's xray camera upgrade no longer shows on station security camera consoles /🆑 * Fixes malf camera upgrade appearing on security camera consoles --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
245 lines
7.8 KiB
Plaintext
245 lines
7.8 KiB
Plaintext
#define DEFAULT_MAP_SIZE 15
|
|
|
|
/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
|
|
light_color = COLOR_SOFT_RED
|
|
|
|
var/list/network = list("ss13")
|
|
var/obj/machinery/camera/active_camera
|
|
/// The turf where the camera was last updated.
|
|
var/turf/last_camera_turf
|
|
var/list/concurrent_users = list()
|
|
|
|
// Stuff needed to render the map
|
|
var/atom/movable/screen/map_view/cam_screen
|
|
/// All the plane masters that need to be applied.
|
|
var/atom/movable/screen/background/cam_background
|
|
|
|
interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_SET_MACHINE|INTERACT_MACHINE_REQUIRES_SIGHT
|
|
|
|
/obj/machinery/computer/security/Initialize(mapload)
|
|
. = ..()
|
|
// Map name has to start and end with an A-Z character,
|
|
// and definitely NOT with a square bracket or even a number.
|
|
// I wasted 6 hours on this. :agony:
|
|
var/map_name = "camera_console_[REF(src)]_map"
|
|
// Convert networks to lowercase
|
|
for(var/i in network)
|
|
network -= i
|
|
network += lowertext(i)
|
|
// Initialize map objects
|
|
cam_screen = new
|
|
cam_screen.generate_view(map_name)
|
|
cam_background = new
|
|
cam_background.assigned_map = map_name
|
|
cam_background.del_on_map_removal = FALSE
|
|
|
|
/obj/machinery/computer/security/Destroy()
|
|
QDEL_NULL(cam_screen)
|
|
QDEL_NULL(cam_background)
|
|
return ..()
|
|
|
|
/obj/machinery/computer/security/connect_to_shuttle(mapload, obj/docking_port/mobile/port, obj/docking_port/stationary/dock)
|
|
for(var/i in network)
|
|
network -= i
|
|
network += "[port.shuttle_id]_[i]"
|
|
|
|
/obj/machinery/computer/security/ui_interact(mob/user, datum/tgui/ui)
|
|
. = ..()
|
|
// Update UI
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
|
|
// Update the camera, showing static if necessary and updating data if the location has moved.
|
|
update_active_camera_screen()
|
|
|
|
if(!ui)
|
|
var/user_ref = REF(user)
|
|
var/is_living = isliving(user)
|
|
// Ghosts shouldn't count towards concurrent users, which produces
|
|
// an audible terminal_on click.
|
|
if(is_living)
|
|
concurrent_users += user_ref
|
|
// Turn on the console
|
|
if(length(concurrent_users) == 1 && is_living)
|
|
playsound(src, 'sound/machines/terminal_on.ogg', 25, FALSE)
|
|
use_power(active_power_usage)
|
|
// Register map objects
|
|
cam_screen.display_to(user)
|
|
user.client.register_map_obj(cam_background)
|
|
// Open UI
|
|
ui = new(user, src, "CameraConsole", name)
|
|
ui.open()
|
|
|
|
/obj/machinery/computer/security/ui_status(mob/user)
|
|
. = ..()
|
|
if(. == UI_DISABLED)
|
|
return UI_CLOSE
|
|
return .
|
|
|
|
/obj/machinery/computer/security/ui_data()
|
|
var/list/data = list()
|
|
data["network"] = network
|
|
data["activeCamera"] = null
|
|
if(active_camera)
|
|
data["activeCamera"] = list(
|
|
name = active_camera.c_tag,
|
|
status = active_camera.status,
|
|
)
|
|
return data
|
|
|
|
/obj/machinery/computer/security/ui_static_data()
|
|
var/list/data = list()
|
|
data["mapRef"] = cam_screen.assigned_map
|
|
var/list/cameras = get_available_cameras()
|
|
data["cameras"] = list()
|
|
for(var/i in cameras)
|
|
var/obj/machinery/camera/C = cameras[i]
|
|
data["cameras"] += list(list(
|
|
name = C.c_tag,
|
|
))
|
|
|
|
return data
|
|
|
|
/obj/machinery/computer/security/ui_act(action, params)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
|
|
if(action == "switch_camera")
|
|
var/c_tag = params["name"]
|
|
var/list/cameras = get_available_cameras()
|
|
var/obj/machinery/camera/selected_camera = cameras[c_tag]
|
|
active_camera = selected_camera
|
|
playsound(src, get_sfx(SFX_TERMINAL_TYPE), 25, FALSE)
|
|
|
|
if(!selected_camera)
|
|
return TRUE
|
|
|
|
update_active_camera_screen()
|
|
|
|
return TRUE
|
|
|
|
/obj/machinery/computer/security/proc/update_active_camera_screen()
|
|
// Show static if can't use the camera
|
|
if(!active_camera?.can_use())
|
|
show_camera_static()
|
|
return
|
|
|
|
var/list/visible_turfs = list()
|
|
|
|
// Get the camera's turf to correctly gather what's visible from it's turf, in case it's located in a moving object (borgs / mechs)
|
|
var/new_cam_turf = get_turf(active_camera)
|
|
|
|
// If we're not forcing an update for some reason and the cameras are in the same location,
|
|
// we don't need to update anything.
|
|
// Most security cameras will end here as they're not moving.
|
|
if(last_camera_turf == new_cam_turf)
|
|
return
|
|
|
|
// Cameras that get here are moving, and are likely attached to some moving atom such as cyborgs.
|
|
last_camera_turf = new_cam_turf
|
|
|
|
//Here we gather what's visible from the camera's POV based on its view_range and xray modifier if present
|
|
var/list/visible_things = active_camera.isXRay(ignore_malf_upgrades = TRUE) ? range(active_camera.view_range, new_cam_turf) : view(active_camera.view_range, new_cam_turf)
|
|
|
|
for(var/turf/visible_turf in visible_things)
|
|
visible_turfs += visible_turf
|
|
|
|
//Get coordinates for a rectangle area that contains the turfs we see so we can then clear away the static in the resulting rectangle area
|
|
var/list/bbox = get_bbox_of_atoms(visible_turfs)
|
|
var/size_x = bbox[3] - bbox[1] + 1
|
|
var/size_y = bbox[4] - bbox[2] + 1
|
|
|
|
cam_screen.vis_contents = visible_turfs
|
|
cam_background.icon_state = "clear"
|
|
cam_background.fill_rect(1, 1, size_x, size_y)
|
|
|
|
/obj/machinery/computer/security/ui_close(mob/user)
|
|
. = ..()
|
|
var/user_ref = REF(user)
|
|
var/is_living = isliving(user)
|
|
// Living creature or not, we remove you anyway.
|
|
concurrent_users -= user_ref
|
|
// Unregister map objects
|
|
cam_screen.hide_from(user)
|
|
// Turn off the console
|
|
if(length(concurrent_users) == 0 && is_living)
|
|
active_camera = null
|
|
playsound(src, 'sound/machines/terminal_off.ogg', 25, FALSE)
|
|
use_power(0)
|
|
|
|
/obj/machinery/computer/security/proc/show_camera_static()
|
|
cam_screen.vis_contents.Cut()
|
|
cam_background.icon_state = "scanline2"
|
|
cam_background.fill_rect(1, 1, DEFAULT_MAP_SIZE, DEFAULT_MAP_SIZE)
|
|
|
|
// 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/cam as anything in GLOB.cameranet.cameras)
|
|
//Get the camera's turf in case it's inside something like a borg
|
|
var/turf/camera_turf = get_turf(cam)
|
|
if((is_away_level(z) || is_away_level(camera_turf.z)) && (camera_turf.z != z))//if on away mission, can only receive feed from same z_level cameras
|
|
continue
|
|
L.Add(cam)
|
|
var/list/D = list()
|
|
for(var/obj/machinery/camera/cam in L)
|
|
if(!cam.network)
|
|
stack_trace("Camera in a cameranet has no camera network")
|
|
continue
|
|
if(!(islist(cam.network)))
|
|
stack_trace("Camera in a cameranet has a non-list camera network")
|
|
continue
|
|
var/list/tempnetwork = cam.network & network
|
|
if(tempnetwork.len)
|
|
D["[cam.c_tag]"] = cam
|
|
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"
|
|
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 = "\improper 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 = "\improper Quartermaster's camera console"
|
|
desc = "A console with access to the mining, auxiliary base and vault camera networks."
|
|
network = list("mine", "auxbase", "vault")
|
|
circuit = null
|
|
|
|
#undef DEFAULT_MAP_SIZE
|