diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index 5d7d9a0d88309..3c0659f279347 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -155,6 +155,7 @@ #define CAMERA_UPGRADE_XRAY (1<<0) #define CAMERA_UPGRADE_EMP_PROOF (1<<1) #define CAMERA_UPGRADE_MOTION (1<<2) +#define CAMERA_UPGRADE_NO_AI (1<<3) /// Max length of a status line in the status display #define MAX_STATUS_LINE_LENGTH 40 diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index f784849135f98..8916281214e97 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -295,4 +295,4 @@ // /mob/living/silicon/ai/TurfAdjacent(turf/target_turf) - return (SScameras && SScameras.turf_visible_by_cameras(target_turf)) + return (SScameras && SScameras.turf_visible_by_cameras(target_turf, src)) diff --git a/code/controllers/subsystem/cameras.dm b/code/controllers/subsystem/cameras.dm index 44a4ca5dda27b..b3aa9de7718ce 100644 --- a/code/controllers/subsystem/cameras.dm +++ b/code/controllers/subsystem/cameras.dm @@ -123,20 +123,20 @@ SUBSYSTEM_DEF(cameras) var/datum/cameranet/net = nets[net_id] net.bare_major_chunk_change(changed) -/datum/controller/subsystem/cameras/proc/is_visible_by_cameras(atom/target) - return default_net.is_visible_by_cameras(target) +/datum/controller/subsystem/cameras/proc/is_visible_by_cameras(atom/target, mob/user) + return default_net.is_visible_by_cameras(target, user) -/datum/controller/subsystem/cameras/proc/turf_visible_by_cameras(turf/position) - return default_net.turf_visible_by_cameras(position) +/datum/controller/subsystem/cameras/proc/turf_visible_by_cameras(turf/position, mob/user) + return default_net.turf_visible_by_cameras(position, user) -/datum/controller/subsystem/cameras/proc/get_turf_camera_chunk(turf/position) - return default_net.get_turf_camera_chunk(position) +/datum/controller/subsystem/cameras/proc/get_turf_camera_chunk(turf/position, mob/user) + return default_net.get_turf_camera_chunk(position, user) -/datum/controller/subsystem/cameras/proc/get_available_cameras_data(list/networks_available, list/z_levels_available) - return default_net.get_available_cameras_data(networks_available, z_levels_available) +/datum/controller/subsystem/cameras/proc/get_available_cameras_data(list/networks_available, list/z_levels_available, mob/user) + return default_net.get_available_cameras_data(networks_available, z_levels_available, user) -/datum/controller/subsystem/cameras/proc/get_available_camera_by_tag_list(list/networks_available, list/z_levels_available) - return default_net.get_available_camera_by_tag_list(networks_available, z_levels_available) +/datum/controller/subsystem/cameras/proc/get_available_camera_by_tag_list(list/networks_available, list/z_levels_available, mob/user) + return default_net.get_available_camera_by_tag_list(networks_available, z_levels_available, user) /obj/effect/overlay/camera_static name = "static" diff --git a/code/datums/station_alert.dm b/code/datums/station_alert.dm index 4c5f3ca7c51c5..9baaf0dfb56a3 100644 --- a/code/datums/station_alert.dm +++ b/code/datums/station_alert.dm @@ -66,9 +66,11 @@ if(.) return + var/mob/user = ui.user + switch(action) if("select_camera") - var/mob/living/silicon/ai/ai = usr + var/mob/living/silicon/ai/ai = user if(!istype(ai)) return @@ -96,8 +98,8 @@ if(isnull(chosen_camera)) return var/obj/machinery/camera/selected_camera = named_cameras[chosen_camera] - if(!selected_camera.can_use()) - to_chat(ai, span_warning("Camera is unavailable!")) + if(!selected_camera.can_use(user)) + to_chat(user, span_warning("Camera is unavailable!")) return ai.switchCamera(selected_camera) return TRUE diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 14f8bd4b2671a..d54bfbf1bef03 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -709,7 +709,7 @@ var/mob/user = ui.user add_fingerprint(user) update_last_used(user) - if(isAI(user) && !SScameras.turf_visible_by_cameras(get_turf(src))) //We check if they're an AI specifically here, so borgs/adminghosts/human wand can still access off-camera stuff. + if(isAI(user) && !SScameras.turf_visible_by_cameras(get_turf(src), user)) //We check if they're an AI specifically here, so borgs/adminghosts/human wand can still access off-camera stuff. to_chat(user, span_warning("You can no longer connect to this device!")) return FALSE return ..() diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 1c4b9bf2cfc02..7231c4e963adf 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -296,7 +296,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/autoname/old, 0) /obj/machinery/camera/attack_ai(mob/living/silicon/ai/user) if (!istype(user)) return - if (!can_use()) + if (!can_use(user)) return user.switchCamera(src) @@ -381,7 +381,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/autoname/old, 0) /obj/machinery/camera/proc/toggle_cam(mob/user, displaymessage = TRUE) camera_enabled = !camera_enabled - if(can_use()) + if(can_use(user)) SScameras.add_camera_to_chunk(src) if (isturf(loc)) myarea = get_area(src) @@ -432,7 +432,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/autoname/old, 0) alarm_on = FALSE alarm_manager.clear_alarm(ALARM_CAMERA) -/obj/machinery/camera/proc/can_use() +/obj/machinery/camera/proc/can_use(mob/living/user) if(!camera_enabled) return FALSE if(machine_stat & EMPED) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 9ef27b4e98a39..b801f77ab6f43 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -84,11 +84,11 @@ ) return data -/obj/machinery/computer/security/ui_static_data() +/obj/machinery/computer/security/ui_static_data(mob/user) var/list/data = list() data["network"] = network data["mapRef"] = cam_screen.assigned_map - data["cameras"] = SScameras.get_available_cameras_data(network) + data["cameras"] = SScameras.get_available_cameras_data(network, user = null) //AIs can check bodycams through this. 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 375411ce7b4a7..3b9d5e5bb199b 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -182,11 +182,11 @@ else camera_location = myturf else - if((!consider_zlock || (myturf.z in z_lock)) && camnet.turf_visible_by_cameras(myturf)) + if((!consider_zlock || (myturf.z in z_lock)) && camnet.turf_visible_by_cameras(myturf, user)) camera_location = myturf else for(var/obj/machinery/camera/C as anything in camnet.cameras) - if(!C.can_use() || consider_zlock && !(C.z in z_lock)) + if(!C.can_use(user) || consider_zlock && !(C.z in z_lock)) continue var/list/network_overlap = networks & C.network if(length(network_overlap)) @@ -228,7 +228,7 @@ var/mob/eye/camera/remote/remote_eye = owner.remote_control var/obj/machinery/computer/camera_advanced/origin = remote_eye.origin_ref.resolve() - var/list/cameras_by_tag = origin.camnet.get_available_camera_by_tag_list(origin.networks, origin.z_lock) + var/list/cameras_by_tag = origin.camnet.get_available_camera_by_tag_list(origin.networks, origin.z_lock, owner) playsound(origin, 'sound/machines/terminal_prompt.ogg', 25, FALSE) var/camera = tgui_input_list(usr, "Camera to view", "Cameras", cameras_by_tag) diff --git a/code/modules/antagonists/abductor/machinery/camera.dm b/code/modules/antagonists/abductor/machinery/camera.dm index ff8c246962348..6dc673b355626 100644 --- a/code/modules/antagonists/abductor/machinery/camera.dm +++ b/code/modules/antagonists/abductor/machinery/camera.dm @@ -68,7 +68,7 @@ use_delay = (world.time + abductor_pad_cooldown) - if(SScameras.turf_visible_by_cameras(remote_eye.loc)) + if(SScameras.turf_visible_by_cameras(remote_eye.loc, owner)) P.PadToLoc(remote_eye.loc) /datum/action/innate/teleport_out @@ -108,7 +108,7 @@ use_delay = (world.time + teleport_self_cooldown) - if(SScameras.turf_visible_by_cameras(remote_eye.loc)) + if(SScameras.turf_visible_by_cameras(remote_eye.loc, owner)) P.MobToLoc(remote_eye.loc,C) /datum/action/innate/vest_mode_swap diff --git a/code/modules/antagonists/darkspawn/darkspawn_objects/veil_camera.dm b/code/modules/antagonists/darkspawn/darkspawn_objects/veil_camera.dm index afdacd2866c9e..f3a1319a2fc35 100644 --- a/code/modules/antagonists/darkspawn/darkspawn_objects/veil_camera.dm +++ b/code/modules/antagonists/darkspawn/darkspawn_objects/veil_camera.dm @@ -96,7 +96,7 @@ GLOBAL_DATUM(thrallnet, /datum/cameranet) continue if(!length(netcam.network & origin.networks)) continue - T["[netcam.c_tag][netcam.can_use() ? null : " (Deactivated)"]"] = netcam + T["[netcam.c_tag][netcam.can_use(owner) ? null : " (Deactivated)"]"] = netcam playsound(origin, "crawling_shadows_walk", 25, FALSE) var/camera = tgui_input_list(usr, menu_prompt, menu_title, T) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 9a06cd96973f7..101ce07d4f1ec 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1329,7 +1329,7 @@ if(is_away_level(T.z)) return FALSE // Now, are they viewable by a camera? (This is last because it's the most intensive check) - if(!SScameras.is_visible_by_cameras(src)) + if(!SScameras.is_visible_by_cameras(src, user)) return FALSE return TRUE diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 40d7975ab2643..db8cb0a8fd859 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -492,7 +492,7 @@ return ISINRANGE(target_turf.x, ai_turf.x - interaction_range, ai_turf.x + interaction_range) \ && ISINRANGE(target_turf.y, ai_turf.y - interaction_range, ai_turf.y + interaction_range) else - return SScameras.turf_visible_by_cameras(target_turf) + return SScameras.turf_visible_by_cameras(target_turf, src) /mob/living/silicon/ai/cancel_camera() view_core() @@ -589,7 +589,7 @@ if(controlled_equipment) to_chat(src, span_warning("You are already loaded into an onboard computer!")) return - if(!SScameras.is_visible_by_cameras(M)) + if(!SScameras.is_visible_by_cameras(M, src)) to_chat(src, span_warning("Exosuit is no longer near active cameras.")) return if(!isvalidAIloc(loc)) @@ -649,7 +649,7 @@ //The target must be in view of a camera or near the core. if(turf_check in range(get_turf(src))) call_bot(turf_check) - else if(SScameras && SScameras.turf_visible_by_cameras(turf_check)) + else if(SScameras && SScameras.turf_visible_by_cameras(turf_check, src)) call_bot(turf_check) else to_chat(src, span_danger("Selected location is not visible.")) @@ -678,7 +678,7 @@ if (length(cameras)) var/obj/machinery/camera/cam = cameras[1] - if (cam.can_use()) + if (cam.can_use(src)) queueAlarm("--- [alarm_type] alarm detected in [home_name]! ([cam.c_tag])", alarm_type) else var/first_run = FALSE @@ -716,7 +716,7 @@ var/list/tempnetwork = C.network if(!camera_turf || !(is_station_level(camera_turf.z) || is_mining_level(camera_turf.z) || (CAMERANET_NETWORK_SS13 in tempnetwork))) continue - if(!C.can_use()) + if(!C.can_use(src)) continue tempnetwork.Remove(CAMERANET_NETWORK_RD, CAMERANET_NETWORK_ORDNANCE, CAMERANET_NETWORK_PRISON) if(length(tempnetwork)) @@ -733,7 +733,7 @@ network = old_network // If nothing is selected else for(var/obj/machinery/camera/C in SScameras.cameras) - if(!C.can_use()) + if(!C.can_use(src)) continue if(network in C.network) U.eyeobj.setLoc(get_turf(C)) @@ -889,7 +889,7 @@ for(var/obj/machinery/camera/camera as anything in z_cameras) if(QDELETED(camera)) continue - if(!camera.can_use() || get_dist(camera, eyeobj) > 7 || !camera.internal_light) + if(!camera.can_use(src) || get_dist(camera, eyeobj) > 7 || !camera.internal_light) continue visible |= camera @@ -962,7 +962,7 @@ if(isvalidAIloc(loc)) //AI in core, check if on cameras //get_turf_pixel() is because APCs in maint aren't actually in view of the inner camera //apc_override is needed here because AIs use their own APC when depowered - return ((SScameras && SScameras.turf_visible_by_cameras(get_turf_pixel(A))) || (A == apc_override)) + return ((SScameras && SScameras.turf_visible_by_cameras(get_turf_pixel(A), src)) || (A == apc_override)) //AI is carded/shunted //view(src) returns nothing for carded/shunted AIs and they have X-ray vision so just use get_dist var/list/viewscale = getviewsize(client.view) @@ -1235,7 +1235,7 @@ REMOVE_TRAIT(src, TRAIT_INCAPACITATED, POWER_LACK_TRAIT) /mob/living/silicon/ai/proc/show_camera_list() - var/list/cameras = SScameras.get_available_camera_by_tag_list(network) + var/list/cameras = SScameras.get_available_camera_by_tag_list(network, user = src) var/camera_tag = tgui_input_list(src, "Choose which camera you want to view", "Cameras", cameras) if(isnull(camera_tag)) return diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index b14088b09b3e8..ebf3e1d64b491 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -187,39 +187,43 @@ /// Will check if an atom is on a viewable turf. /// Returns TRUE if the atom is visible by any camera, FALSE otherwise. -/datum/cameranet/proc/is_visible_by_cameras(atom/target) - return turf_visible_by_cameras(get_turf(target)) +/datum/cameranet/proc/is_visible_by_cameras(atom/target, mob/user) + return turf_visible_by_cameras(get_turf(target), user) /// Checks if the passed turf is visible by any camera. /// Returns TRUE if the turf is visible by any camera, FALSE otherwise. -/datum/cameranet/proc/turf_visible_by_cameras(turf/position) +/datum/cameranet/proc/turf_visible_by_cameras(turf/position, mob/user) if(isnull(position)) return FALSE var/datum/camerachunk/chunk = generate_chunk(position.x, position.y, position.z) if(isnull(chunk)) return FALSE chunk.force_update(only_if_necessary = TRUE) // Update NOW if necessary + if(!isAI(user) && chunk.cameraTurfs[position]) + return TRUE if(chunk.visibleTurfs[position]) return TRUE return FALSE /// Gets the camera chunk the passed turf is in. /// Returns the chunk if it exists and is visible, null otherwise. -/datum/cameranet/proc/get_turf_camera_chunk(turf/position) +/datum/cameranet/proc/get_turf_camera_chunk(turf/position, mob/user) RETURN_TYPE(/datum/camerachunk) var/datum/camerachunk/chunk = generate_chunk(position.x, position.y, position.z) if(!chunk) return null chunk.force_update(only_if_necessary = TRUE) // Update NOW if necessary + if(!isAI(user) && chunk.cameraTurfs[position]) + return TRUE if(chunk.visibleTurfs[position]) return chunk return null /// 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) +/datum/cameranet/proc/get_available_cameras_data(list/networks_available, list/z_levels_available, mob/user) 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)) + for(var/obj/machinery/camera/camera as anything in get_filtered_and_sorted_cameras(networks_available, z_levels_available, user)) available_cameras_data += list(list( name = camera.c_tag, ref = REF(camera), @@ -236,20 +240,20 @@ * 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. */ -/datum/cameranet/proc/get_available_camera_by_tag_list(list/networks_available, list/z_levels_available) +/datum/cameranet/proc/get_available_camera_by_tag_list(list/networks_available, list/z_levels_available, mob/user) 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)) + for(var/obj/machinery/camera/camera as anything in get_filtered_and_sorted_cameras(networks_available, z_levels_available, user)) 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) +/datum/cameranet/proc/get_filtered_and_sorted_cameras(list/networks_available, list/z_levels_available, mob/user) 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)) + if(!is_camera_available(camera, networks_available, z_levels_available, user)) continue filtered_cameras += camera @@ -257,7 +261,7 @@ 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) +/datum/cameranet/proc/is_camera_available(obj/machinery/camera/camera_to_check, list/networks_available, list/z_levels_available, mob/user) PRIVATE_PROC(TRUE) if(!camera_to_check.c_tag) @@ -266,6 +270,9 @@ if(length(z_levels_available) && !(camera_to_check.z in z_levels_available)) return FALSE + if(user && isAI(user) && (camera_to_check.camera_upgrade_bitflags & CAMERA_UPGRADE_NO_AI)) + return FALSE + return length(camera_to_check.network & networks_available) > 0 #undef ADD_CAMERA diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index c6cf403c8b79f..a451274f5db60 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -6,6 +6,8 @@ /datum/camerachunk ///turfs our cameras cant see but are inside our grid. associative list of the form: list(obscured turf = static image on that turf) var/list/obscuredTurfs = list() + ///turfs our bodycameras can see inside our grid + var/list/cameraTurfs = list() ///turfs our cameras can see inside our grid var/list/visibleTurfs = list() ///cameras that can see into our grid @@ -162,8 +164,12 @@ if(get_dist(point, current_camera) > MAX_CAMERA_RANGE + (CHUNK_SIZE / 2)) continue - for(var/turf/vis_turf as anything in current_camera.can_see() & turfs) - updated_visible_turfs[vis_turf] = vis_turf + if(current_camera.camera_upgrade_bitflags & CAMERA_UPGRADE_NO_AI) + for(var/turf/vis_turf as anything in current_camera.can_see() & turfs) + cameraTurfs[vis_turf] = vis_turf + else + for(var/turf/vis_turf as anything in current_camera.can_see() & turfs) + updated_visible_turfs[vis_turf] = vis_turf if(TICK_CHECK) return FALSE @@ -194,8 +200,12 @@ continue // The return value of can_see being the left-hand operand here is a load-bearing performance pillar - for(var/turf/vis_turf as anything in current_camera.can_see() & turfs) - updated_visible_turfs[vis_turf] = vis_turf + if(current_camera.camera_upgrade_bitflags & CAMERA_UPGRADE_NO_AI) + for(var/turf/vis_turf as anything in current_camera.can_see() & turfs) + cameraTurfs[vis_turf] = vis_turf + else + for(var/turf/vis_turf as anything in current_camera.can_see() & turfs) + updated_visible_turfs[vis_turf] = vis_turf update_with_turfs(updated_visible_turfs) @@ -232,6 +242,7 @@ obscuredTurfs[obscured_turf] = static_image active_static_images += static_image + visibleTurfs = updated_visible_turfs for(var/mob/eye/camera/client_eye as anything in seenby) @@ -279,6 +290,8 @@ continue if(camera_loc.y + MAX_CAMERA_RANGE < lower_y || camera_loc.y - MAX_CAMERA_RANGE > upper_y) continue + if(camera.camera_upgrade_bitflags & CAMERA_UPGRADE_NO_AI) + continue if(stack != SSmapping.get_connected_levels(camera_loc.z)) continue if(!camera.can_use()) diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index 7c250b699fbad..08b2a1bf395fb 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -232,7 +232,7 @@ /mob/eye/camera/ai/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods = list(), message_range) . = ..() - if(relay_speech && speaker && ai && !radio_freq && speaker != ai && SScameras.is_visible_by_cameras(speaker)) + if(relay_speech && speaker && ai && !radio_freq && speaker != ai && SScameras.is_visible_by_cameras(speaker, src)) ai.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans, message_mods) /obj/effect/overlay/ai_detect_hud diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 80dfef7a7aac0..a9a1146bf7a20 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -43,7 +43,7 @@ var/crew_hud = DATA_HUD_CREW //MONKE, lets silicons tell who is crew. var/law_change_counter = 0 - var/obj/machinery/camera/bodycamera/builtInCamera = null + var/obj/machinery/camera/builtInCamera = null var/updating = FALSE //portable camera camerachunk update ///Whether we have been emagged var/emagged = FALSE @@ -502,7 +502,7 @@ //if their camera is online, it's safe to assume they are in cameranets //since it takes a while for camera vis to update, this lets us bypass that so AIs can always see their borgs, //without making cameras constantly update every time a borg moves. - if(builtInCamera && builtInCamera.can_use()) + if(builtInCamera && builtInCamera.can_use(user)) return TRUE return ..() diff --git a/code/modules/mob/living/silicon/silicon_movement.dm b/code/modules/mob/living/silicon/silicon_movement.dm index 028332984558e..cee696ad6fc29 100644 --- a/code/modules/mob/living/silicon/silicon_movement.dm +++ b/code/modules/mob/living/silicon/silicon_movement.dm @@ -1,13 +1,13 @@ //We only call a camera static update if we have successfully moved and the camera is present and working /mob/living/silicon/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE) . = ..() - if(builtInCamera?.can_use()) + if(builtInCamera?.can_use(user = null)) update_camera_location(old_loc) /obj/machinery/ai/data_core/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE) . = ..() for(var/mob/living/silicon/ai/internal_ai in contents) - if(internal_ai.builtInCamera?.can_use()) + if(internal_ai.builtInCamera?.can_use(user = null)) internal_ai.update_camera_location(old_loc) /mob/living/silicon/proc/update_camera_location(oldLoc) diff --git a/code/modules/modular_computers/file_system/programs/secureye.dm b/code/modules/modular_computers/file_system/programs/secureye.dm index 6aff77f27404e..c5bd8612eb5a2 100644 --- a/code/modules/modular_computers/file_system/programs/secureye.dm +++ b/code/modules/modular_computers/file_system/programs/secureye.dm @@ -112,7 +112,7 @@ data["network"] = network data["mapRef"] = cam_screen.assigned_map data["can_spy"] = !!spying - data["cameras"] = SScameras.get_available_cameras_data(network) + data["cameras"] = SScameras.get_available_cameras_data(network, user = user) return data /datum/computer_file/program/secureye/ui_act(action, params, datum/tgui/ui, datum/ui_state/state) @@ -145,7 +145,7 @@ /datum/computer_file/program/secureye/proc/on_track_target(datum/trackable/source, atom/movable/target) SIGNAL_HANDLER - var/datum/camerachunk/target_camerachunk = SScameras.get_turf_camera_chunk(get_turf(target)) + var/datum/camerachunk/target_camerachunk = SScameras.get_turf_camera_chunk(get_turf(target), source.tracking_holder) if(!target_camerachunk) CRASH("[src] was able to track [target] through /datum/trackable, but was not on a visible turf to cameras.") for(var/obj/machinery/camera/cameras as anything in target_camerachunk.cameras["[target.z]"]) diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm index d7d6ea8eb74a8..ea3c99b14a3cd 100644 --- a/code/modules/photography/camera/camera.dm +++ b/code/modules/photography/camera/camera.dm @@ -118,7 +118,7 @@ var/turf/T = get_turf(target) if(!T) return FALSE - if(through_camera_console && SScameras.turf_visible_by_cameras(T)) + if(through_camera_console && SScameras.turf_visible_by_cameras(T, user)) return TRUE if(istype(user)) if(user.client && !(get_turf(target) in get_hear(user.client.view, user))) @@ -216,7 +216,7 @@ if(!placeholder) break - if(placeholder && ((through_camera_console && SScameras.turf_visible_by_cameras(placeholder)) || (placeholder in seen))) + if(placeholder && ((through_camera_console && SScameras.turf_visible_by_cameras(placeholder, user)) || (placeholder in seen))) turfs += placeholder for(var/mob/M in placeholder) mobs += M diff --git a/monkestation/code/modules/clothing/suit_accessories/camera.dm b/monkestation/code/modules/clothing/suit_accessories/camera.dm index dfa4852576661..c6b3ae882273a 100644 --- a/monkestation/code/modules/clothing/suit_accessories/camera.dm +++ b/monkestation/code/modules/clothing/suit_accessories/camera.dm @@ -6,3 +6,15 @@ /obj/machinery/camera/bodycamera start_active = TRUE internal_light = FALSE + camera_upgrade_bitflags = CAMERA_UPGRADE_NO_AI + +/obj/machinery/camera/bodycamera/can_use(mob/living/user) + . = ..() + if(!.) + return . + if(isnull(user)) + return TRUE + return !!isAI(user) //AIs cant see through body cameras. + +/obj/machinery/camera/bodycamera/Togglelight(on=0) + return //no lights