diff --git a/code/__HELPERS/cameras.dm b/code/__HELPERS/cameras.dm deleted file mode 100644 index 9d74f3fe71b..00000000000 --- a/code/__HELPERS/cameras.dm +++ /dev/null @@ -1,35 +0,0 @@ -/** - * get_camera_list - * - * Builds a list of all available cameras that can be seen to networks_available - * Args: - * networks_available - List of networks that we use to see which cameras are visible to it. - */ -/proc/get_camera_list(list/networks_available) - var/list/all_camera_list = list() - for(var/obj/machinery/camera/camera as anything in GLOB.cameranet.cameras) - all_camera_list.Add(camera) - - camera_sort(all_camera_list) - - var/list/usable_camera_list = list() - - for(var/obj/machinery/camera/camera as anything in all_camera_list) - var/list/tempnetwork = camera.network & networks_available - if(length(tempnetwork)) - usable_camera_list["[camera.c_tag][camera.can_use() ? null : " (Deactivated)"]"] = camera - - return usable_camera_list - -///Sorts the list of cameras by their c_tag to display to players. -/proc/camera_sort(list/camera_list) - var/obj/machinery/camera/camera_comparing_a - var/obj/machinery/camera/camera_comparing_b - - for(var/i = length(camera_list), i > 0, i--) - for(var/j = 1 to i - 1) - camera_comparing_a = camera_list[j] - camera_comparing_b = camera_list[j + 1] - if(sorttext(camera_comparing_a.c_tag, camera_comparing_b.c_tag) < 0) - camera_list.Swap(j, j + 1) - return camera_list diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm index 7451a99cdd2..21a5f00e31b 100644 --- a/code/__HELPERS/cmp.dm +++ b/code/__HELPERS/cmp.dm @@ -227,3 +227,7 @@ /proc/cmp_rped_sort(obj/item/first_item, obj/item/second_item) ///even though stacks aren't stock parts, get_part_rating() is defined on the item level (see /obj/item/proc/get_part_rating()) and defaults to returning 0. return second_item.get_part_rating() - first_item.get_part_rating() + +/// Orders cameras by their `c_tag` ascending +/proc/cmp_camera_ctag_asc(obj/machinery/camera/a, obj/machinery/camera/b) + return sorttext(b.c_tag, a.c_tag) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 21f5ed3db7b..a7ef903a04d 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -97,15 +97,7 @@ var/list/data = list() data["network"] = network data["mapRef"] = cam_screen.assigned_map - var/list/cameras = get_camera_list(network) - data["cameras"] = list() - for(var/i in cameras) - var/obj/machinery/camera/C = cameras[i] - data["cameras"] += list(list( - name = C.c_tag, - ref = REF(C), - )) - + data["cameras"] = GLOB.cameranet.get_available_cameras_data(network) return data /obj/machinery/computer/security/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index 5633fe49047..88ae57055df 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -218,39 +218,24 @@ var/mob/eye/camera/remote/remote_eye = owner.remote_control var/obj/machinery/computer/camera_advanced/origin = remote_eye.origin_ref.resolve() - var/list/L = list() - - for (var/obj/machinery/camera/cam as anything in GLOB.cameranet.cameras) - if(length(origin.z_lock) && !(cam.z in origin.z_lock)) - continue - L.Add(cam) - - camera_sort(L) - - var/list/T = list() - - for (var/obj/machinery/camera/netcam in L) - var/list/tempnetwork = netcam.network & origin.networks - if (length(tempnetwork)) - if(!netcam.c_tag) - continue - T["[netcam.c_tag][netcam.can_use() ? null : " (Deactivated)"]"] = netcam + var/list/cameras_by_tag = GLOB.cameranet.get_available_camera_by_tag_list(origin.networks, origin.z_lock) playsound(origin, 'sound/machines/terminal/terminal_prompt.ogg', 25, FALSE) - var/camera = tgui_input_list(usr, "Camera to view", "Cameras", T) + var/camera = tgui_input_list(usr, "Camera to view", "Cameras", cameras_by_tag) if(isnull(camera)) return - if(isnull(T[camera])) - return - var/obj/machinery/camera/final = T[camera] + playsound(src, SFX_TERMINAL_TYPE, 25, FALSE) - if(final) - playsound(origin, 'sound/machines/terminal/terminal_prompt_confirm.ogg', 25, FALSE) - remote_eye.setLoc(get_turf(final)) - owner.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/flash/static) - owner.clear_fullscreen("flash", 3) //Shorter flash than normal since it's an ~~advanced~~ console! - else + + var/obj/machinery/camera/chosen_camera = cameras_by_tag[camera] + if(isnull(chosen_camera)) playsound(origin, 'sound/machines/terminal/terminal_prompt_deny.ogg', 25, FALSE) + return + + playsound(origin, 'sound/machines/terminal/terminal_prompt_confirm.ogg', 25, FALSE) + remote_eye.setLoc(get_turf(chosen_camera)) + owner.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/flash/static) + owner.clear_fullscreen("flash", 3) //Shorter flash than normal since it's an ~~advanced~~ console! /datum/action/innate/camera_multiz_up name = "Move up a floor" diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 9c3b810dbf0..63fef281a51 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -1050,13 +1050,16 @@ REMOVE_TRAIT(src, TRAIT_INCAPACITATED, POWER_LACK_TRAIT) /mob/living/silicon/ai/proc/show_camera_list() - var/list/cameras = get_camera_list(network) - var/camera = tgui_input_list(src, "Choose which camera you want to view", "Cameras", cameras) - if(isnull(camera)) + var/list/cameras = GLOB.cameranet.get_available_camera_by_tag_list(network) + var/camera_tag = tgui_input_list(src, "Choose which camera you want to view", "Cameras", cameras) + if(isnull(camera_tag)) return - if(isnull(cameras[camera])) + + var/obj/machinery/camera/chosen_camera = cameras[camera_tag] + if(isnull(chosen_camera)) return - switchCamera(cameras[camera]) + + switchCamera(chosen_camera) /mob/living/silicon/on_handsblocked_start() return // AIs have no hands diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index 1f8c452f492..a5991d2ee6f 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -8,7 +8,7 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) /// Name to show for VV and stat() var/name = "Camera Net" - /// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del(). + /// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm in Initialize() and Destroy(). var/list/obj/machinery/camera/cameras = list() /// The chunks of the map, mapping the areas that the cameras can see. var/list/chunks = list() @@ -185,6 +185,60 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) if(chunk.visibleTurfs[position]) return chunk +/// Returns list of available cameras, ready to use for UIs displaying list of them +/// The format is: list("name" = "camera.c_tag", ref = REF(camera)) +/datum/cameranet/proc/get_available_cameras_data(list/networks_available, list/z_levels_available) + var/list/available_cameras_data = list() + for(var/obj/machinery/camera/camera as anything in get_filtered_and_sorted_cameras(networks_available, z_levels_available)) + available_cameras_data += list(list( + name = camera.c_tag, + ref = REF(camera), + )) + + return available_cameras_data + +/** + * get_available_camera_by_tag_list + * + * Builds a list of all available cameras that can be seen to networks_available and in z_levels_available. + * Entries are stored in `c_tag[camera.can_use() ? null : " (Deactivated)"]` => `camera` format + * Args: + * networks_available - List of networks that we use to see which cameras are visible to it. + * z_levels_available - List of z levels to filter camera by. If empty, all z levels are considered valid. + * sort_by_ctag - If the resulting list should be sorted by `c_tag`. + */ +/datum/cameranet/proc/get_available_camera_by_tag_list(list/networks_available, list/z_levels_available) + var/list/available_cameras_by_tag = list() + for(var/obj/machinery/camera/camera as anything in get_filtered_and_sorted_cameras(networks_available, z_levels_available)) + available_cameras_by_tag["[camera.c_tag][camera.can_use() ? null : " (Deactivated)"]"] = camera + + return available_cameras_by_tag + +/// Returns list of all cameras that passed `is_camera_available` filter and sorted by `cmp_camera_ctag_asc` +/datum/cameranet/proc/get_filtered_and_sorted_cameras(list/networks_available, list/z_levels_available) + PRIVATE_PROC(TRUE) + + var/list/filtered_cameras = list() + for(var/obj/machinery/camera/camera as anything in cameras) + if(!is_camera_available(camera, networks_available, z_levels_available)) + continue + + filtered_cameras += camera + + return sortTim(filtered_cameras, GLOBAL_PROC_REF(cmp_camera_ctag_asc)) + +/// Checks if the `camera_to_check` meets the requirements of availability. +/datum/cameranet/proc/is_camera_available(obj/machinery/camera/camera_to_check, list/networks_available, list/z_levels_available) + PRIVATE_PROC(TRUE) + + if(!camera_to_check.c_tag) + return FALSE + + if(length(z_levels_available) && !(camera_to_check.z in z_levels_available)) + return FALSE + + return length(camera_to_check.network & networks_available) > 0 + /obj/effect/overlay/camera_static name = "static" icon = null diff --git a/code/modules/modular_computers/file_system/programs/secureye.dm b/code/modules/modular_computers/file_system/programs/secureye.dm index b38200cfce1..ad90e736c95 100644 --- a/code/modules/modular_computers/file_system/programs/secureye.dm +++ b/code/modules/modular_computers/file_system/programs/secureye.dm @@ -127,15 +127,7 @@ data["network"] = network data["mapRef"] = cam_screen.assigned_map data["can_spy"] = !!spying - var/list/cameras = get_camera_list(network) - data["cameras"] = list() - for(var/i in cameras) - var/obj/machinery/camera/C = cameras[i] - data["cameras"] += list(list( - name = C.c_tag, - ref = REF(C), - )) - + data["cameras"] = GLOB.cameranet.get_available_cameras_data(network) return data /datum/computer_file/program/secureye/ui_act(action, params, datum/tgui/ui, datum/ui_state/state) diff --git a/tgstation.dme b/tgstation.dme index 3015a823b82..d097c62a2c7 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -416,7 +416,6 @@ #include "code\__HELPERS\atoms.dm" #include "code\__HELPERS\auxtools.dm" #include "code\__HELPERS\bitflag_lists.dm" -#include "code\__HELPERS\cameras.dm" #include "code\__HELPERS\chat.dm" #include "code\__HELPERS\chat_filter.dm" #include "code\__HELPERS\clients.dm"