forked from shiptest-ss13/Shiptest
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
256 additions
and
0 deletions.
There are no files selected for viewing
196 changes: 196 additions & 0 deletions
196
code/modules/modular_computers/file_system/programs/watchdog.dm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
#define DEFAULT_MAP_SIZE 15 | ||
|
||
/datum/computer_file/program/watchdog | ||
filename = "watchdog" | ||
filedesc = "Watchdog" | ||
ui_header = "borg_mon.gif" | ||
program_icon_state = "generic" | ||
extended_desc = "This program allows access to standard security camera networks." | ||
requires_ntnet = TRUE | ||
transfer_access = ACCESS_SECURITY | ||
usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP | PROGRAM_TABLET | ||
size = 5 | ||
tgui_id = "NtosWatchdog" | ||
program_icon = "eye" | ||
|
||
// Will need to modify the network to the "watchdog" network | ||
var/list/network = list("watchdog") | ||
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/map_name | ||
var/atom/movable/screen/map_view/cam_screen | ||
/// All the plane masters that need to be applied. | ||
var/list/cam_plane_masters | ||
var/atom/movable/screen/background/cam_background | ||
|
||
/datum/computer_file/program/watchdog/New() | ||
. = ..() | ||
// Map name has to start and end with an A-Z character, | ||
// and definitely NOT with a square bracket or even a number. | ||
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.name = "screen" | ||
cam_screen.assigned_map = map_name | ||
cam_screen.del_on_map_removal = FALSE | ||
cam_screen.screen_loc = "[map_name]:1,1" | ||
cam_plane_masters = list() | ||
for(var/plane in subtypesof(/atom/movable/screen/plane_master)) | ||
var/atom/movable/screen/instance = new plane() | ||
instance.assigned_map = map_name | ||
instance.del_on_map_removal = FALSE | ||
instance.screen_loc = "[map_name]:CENTER" | ||
cam_plane_masters += instance | ||
cam_background = new | ||
cam_background.assigned_map = map_name | ||
cam_background.del_on_map_removal = FALSE | ||
|
||
/datum/computer_file/program/watchdog/Destroy() | ||
qdel(cam_screen) | ||
QDEL_LIST(cam_plane_masters) | ||
qdel(cam_background) | ||
return ..() | ||
|
||
/datum/computer_file/program/watchdog/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 | ||
// Register map objects | ||
user.client.register_map_obj(cam_screen) | ||
for(var/plane in cam_plane_masters) | ||
user.client.register_map_obj(plane) | ||
user.client.register_map_obj(cam_background) | ||
return ..() | ||
|
||
/datum/computer_file/program/watchdog/ui_data() | ||
var/list/data = get_header_data() | ||
data["network"] = network | ||
data["activeCamera"] = null | ||
if(active_camera) | ||
data["activeCamera"] = list( | ||
name = active_camera.c_tag, | ||
status = active_camera.status, | ||
) | ||
return data | ||
|
||
/datum/computer_file/program/watchdog/ui_static_data() | ||
var/list/data = list() | ||
data["mapRef"] = map_name | ||
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 | ||
|
||
/datum/computer_file/program/watchdog/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("terminal_type"), 25, FALSE) | ||
|
||
if(!selected_camera) | ||
return TRUE | ||
|
||
update_active_camera_screen() | ||
|
||
return TRUE | ||
|
||
/datum/computer_file/program/watchdog/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 | ||
user.client.clear_map(map_name) | ||
// Turn off the console | ||
if(length(concurrent_users) == 0 && is_living) | ||
active_camera = null | ||
playsound(src, 'sound/machines/terminal_off.ogg', 25, FALSE) | ||
|
||
/datum/computer_file/program/watchdog/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() | ||
|
||
// Is this camera located in or attached to a living thing? If so, assume the camera's loc is the living thing. | ||
var/cam_location = isliving(active_camera.loc) ? active_camera.loc : 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. | ||
var/newturf = get_turf(cam_location) | ||
if(last_camera_turf == newturf) | ||
return | ||
|
||
// Cameras that get here are moving, and are likely attached to some moving atom such as cyborgs. | ||
last_camera_turf = get_turf(cam_location) | ||
|
||
var/list/visible_things = active_camera.isXRay() ? range(active_camera.view_range, cam_location) : view(active_camera.view_range, cam_location) | ||
|
||
for(var/turf/visible_turf in visible_things) | ||
visible_turfs += visible_turf | ||
|
||
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) | ||
|
||
/datum/computer_file/program/watchdog/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 | ||
/datum/computer_file/program/watchdog/proc/get_available_cameras() | ||
var/list/L = list() | ||
for (var/obj/machinery/camera/cam as anything in GLOB.cameranet.cameras) | ||
if(cam.virtual_z() != computer.virtual_z())//Only show cameras on the same level. | ||
continue | ||
L.Add(cam) | ||
var/list/camlist = list() | ||
for(var/obj/machinery/camera/cam as anything 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) | ||
camlist["[cam.c_tag]"] = cam | ||
return camlist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { useBackend } from '../backend'; | ||
import { Button, ByondUi } from '../components'; | ||
import { NtosWindow } from '../layouts'; | ||
import { | ||
prevNextCamera, | ||
selectCameras, | ||
CameraConsoleContent, | ||
} from './CameraConsole'; | ||
|
||
export const NtosWatchdog = (props, context) => { | ||
const { act, data, config } = useBackend(context); | ||
const { PC_device_theme, mapRef, activeCamera } = data; | ||
const cameras = selectCameras(data.cameras); | ||
const [prevCameraName, nextCameraName] = prevNextCamera( | ||
cameras, | ||
activeCamera | ||
); | ||
return ( | ||
<NtosWindow width={800} height={600} theme={PC_device_theme}> | ||
<NtosWindow.Content> | ||
<div className="CameraConsole__left"> | ||
<CameraConsoleContent /> | ||
</div> | ||
<div className="CameraConsole__right"> | ||
<div className="CameraConsole__toolbar"> | ||
<b>Camera: </b> | ||
{(activeCamera && activeCamera.name) || '—'} | ||
</div> | ||
<div className="CameraConsole__toolbarRight"> | ||
<Button | ||
icon="chevron-left" | ||
disabled={!prevCameraName} | ||
onClick={() => | ||
act('switch_camera', { | ||
name: prevCameraName, | ||
}) | ||
} | ||
/> | ||
<Button | ||
icon="chevron-right" | ||
disabled={!nextCameraName} | ||
onClick={() => | ||
act('switch_camera', { | ||
name: nextCameraName, | ||
}) | ||
} | ||
/> | ||
</div> | ||
<ByondUi | ||
className="CameraConsole__map" | ||
params={{ | ||
id: mapRef, | ||
type: 'map', | ||
}} | ||
/> | ||
</div> | ||
</NtosWindow.Content> | ||
</NtosWindow> | ||
); | ||
}; |