[MIRROR] Replaces Camera bug with Camera tablet app [MDB IGNORE] (#23275)

* Replaces Camera bug with Camera tablet app

* Modular changes

---------

Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-08-23 22:33:01 +02:00
committed by GitHub
parent 9638396677
commit 30d57e41dc
34 changed files with 167 additions and 427 deletions
@@ -128,7 +128,7 @@
switch(action)
if("PC_exit")
active_program.kill_program()
active_program.kill_program(usr)
return TRUE
if("PC_shutdown")
shutdown_computer()
@@ -146,7 +146,7 @@
if(!istype(killed_program))
return
killed_program.kill_program()
killed_program.kill_program(usr)
to_chat(usr, span_notice("Program [killed_program.filename].[killed_program.filetype] with PID [rand(100,999)] has been killed."))
return TRUE
@@ -221,3 +221,8 @@
if(physical)
return physical
return src
/obj/item/modular_computer/ui_close(mob/user)
. = ..()
if(active_program)
active_program.ui_close(user)
@@ -0,0 +1,8 @@
/obj/item/computer_disk/syndicate
name = "golden data disk"
desc = "A data disk with some high-tech programs, probably expensive as hell."
icon_state = "datadisk8"
custom_materials = list(/datum/material/gold = SMALL_MATERIAL_AMOUNT)
/obj/item/computer_disk/syndicate/camera_app
starting_programs = list(/datum/computer_file/program/secureye/syndicate)
@@ -41,6 +41,8 @@
var/alert_pending = FALSE
/// How well this program will help combat detomatix viruses.
var/detomatix_resistance = NONE
///Boolean on whether or not only one copy of the app can exist. This means it deletes itself when cloned elsewhere.
var/unique_copy = FALSE
/datum/computer_file/program/clone()
var/datum/computer_file/program/temp = ..()
@@ -49,6 +51,11 @@
temp.program_icon_state = program_icon_state
temp.requires_ntnet = requires_ntnet
temp.usage_flags = usage_flags
if(unique_copy)
if(computer)
computer.remove_file(src)
if(disk_host)
disk_host.remove_file(src)
return temp
/**
@@ -173,9 +180,9 @@
* Use this proc to kill the program.
* Designed to be implemented by each program if it requires on-quit logic, such as the NTNRC client.
* Args:
* - reload_ui - Whether we reload the UI on computer's shutdown.
* - user - If there's a user, this is the person killing the program.
**/
/datum/computer_file/program/proc/kill_program()
/datum/computer_file/program/proc/kill_program(mob/user)
SHOULD_CALL_PARENT(TRUE)
if(src == computer.active_program)
@@ -30,7 +30,7 @@
examine_text += span_info("Alt-click to eject the intelliCard.")
return examine_text
/datum/computer_file/program/ai_restorer/kill_program()
/datum/computer_file/program/ai_restorer/kill_program(mob/user)
try_eject(forced = TRUE)
return ..()
@@ -32,7 +32,7 @@
target = null
error = "Connection to destination relay lost."
/datum/computer_file/program/ntnet_dos/kill_program()
/datum/computer_file/program/ntnet_dos/kill_program(mob/user)
if(target)
target.dos_sources.Remove(src)
target = null
@@ -19,7 +19,7 @@
DL_source = null
return ..()
/datum/computer_file/program/borg_monitor/kill_program()
/datum/computer_file/program/borg_monitor/kill_program(mob/user)
loglist = null //Not everything is saved if you close an app
DL_source = null
DL_progress = 0
@@ -99,9 +99,9 @@
)
data["cyborgs"] += list(cyborg_data)
data["DL_progress"] = DL_progress
data["borglog"] = loglist
return data
/datum/computer_file/program/borg_monitor/ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
@@ -79,7 +79,7 @@
return FALSE
computer.crew_manifest_update = TRUE
/datum/computer_file/program/card_mod/kill_program()
/datum/computer_file/program/card_mod/kill_program(mob/user)
computer.crew_manifest_update = FALSE
var/obj/item/card/id/inserted_auth_card = computer.computer_id_slot
if(inserted_auth_card)
@@ -7,10 +7,4 @@
/datum/computer_file/program/maintenance
filetype = "MNT"
available_on_ntnet = FALSE
/datum/computer_file/program/maintenance/clone(rename = FALSE)
. = ..()
if(computer)
computer.remove_file(src)
if(disk_host)
disk_host.remove_file(src)
unique_copy = TRUE
@@ -162,6 +162,6 @@
return TRUE
return FALSE
/datum/computer_file/program/ntnetdownload/kill_program()
/datum/computer_file/program/ntnetdownload/kill_program(mob/user)
abort_file_download()
return ..()
@@ -200,7 +200,7 @@
channel.offline_clients.Remove(src)
channel.active_clients.Add(src)
/datum/computer_file/program/chatclient/kill_program()
/datum/computer_file/program/chatclient/kill_program(mob/user)
for(var/datum/ntnet_conversation/channel as anything in SSmodular_computers.chat_channels)
channel.go_offline(src)
active_channel = null
@@ -31,7 +31,7 @@
scan()
START_PROCESSING(SSfastprocess, src)
/datum/computer_file/program/radar/kill_program()
/datum/computer_file/program/radar/kill_program(mob/user)
objects = list()
selected = null
STOP_PROCESSING(SSfastprocess, src)
@@ -320,7 +320,7 @@
RegisterSignal(SSdcs, COMSIG_GLOB_NUKE_DEVICE_ARMED, PROC_REF(on_nuke_armed))
/datum/computer_file/program/radar/fission360/kill_program()
/datum/computer_file/program/radar/fission360/kill_program(mob/user)
UnregisterSignal(SSdcs, COMSIG_GLOB_NUKE_DEVICE_ARMED)
return ..()
@@ -14,18 +14,42 @@
tgui_id = "NtosSecurEye"
program_icon = "eye"
///Boolean on whether or not the app will make noise when flipping around the channels.
var/spying = FALSE
var/list/network = list("ss13")
///List of weakrefs of all users watching the program.
var/list/concurrent_users = list()
/// Weakref to the active camera
var/datum/weakref/camera_ref
/// 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
/datum/computer_file/program/secureye/New()
///Internal tracker used to find a specific person and keep them on cameras.
var/datum/trackable/internal_tracker
///Syndicate subtype that has no access restrictions and is available on Syndinet
/datum/computer_file/program/secureye/syndicate
filename = "syndeye"
filedesc = "SyndEye"
extended_desc = "This program allows for illegal access to security camera networks."
transfer_access = list()
available_on_ntnet = FALSE
available_on_syndinet = TRUE
requires_ntnet = FALSE
usage_flags = PROGRAM_ALL
unique_copy = TRUE
network = list("ss13", "mine", "rd", "labor", "ordnance", "minisat")
spying = TRUE
/datum/computer_file/program/secureye/on_install(datum/computer_file/source, obj/item/modular_computer/computer_installing)
. = ..()
// Map name has to start and end with an A-Z character,
// and definitely NOT with a square bracket or even a number.
@@ -40,30 +64,33 @@
cam_background = new
cam_background.assigned_map = map_name
cam_background.del_on_map_removal = FALSE
RegisterSignal(src, COMSIG_TRACKABLE_TRACKING_TARGET, PROC_REF(on_track_target))
/datum/computer_file/program/secureye/Destroy()
QDEL_NULL(cam_screen)
QDEL_NULL(cam_background)
QDEL_NULL(internal_tracker)
last_camera_turf = null
return ..()
/datum/computer_file/program/secureye/kill_program(mob/user)
if(user)
ui_close(user)
return ..()
/datum/computer_file/program/secureye/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
cam_screen.display_to(user)
user.client.register_map_obj(cam_background)
return ..()
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
cam_screen.display_to(user)
user.client.register_map_obj(cam_background)
/datum/computer_file/program/secureye/ui_status(mob/user)
. = ..()
@@ -86,6 +113,7 @@
/datum/computer_file/program/secureye/ui_static_data(mob/user)
var/list/data = list()
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)
@@ -100,22 +128,49 @@
. = ..()
if(.)
return
if(action == "switch_camera")
var/c_tag = format_text(params["name"])
var/list/cameras = get_camera_list(network)
var/obj/machinery/camera/selected_camera = cameras[c_tag]
camera_ref = WEAKREF(selected_camera)
playsound(src, get_sfx(SFX_TERMINAL_TYPE), 25, FALSE)
switch(action)
if("switch_camera")
var/c_tag = format_text(params["name"])
var/list/cameras = get_camera_list(network)
var/obj/machinery/camera/selected_camera = cameras[c_tag]
camera_ref = WEAKREF(selected_camera)
if(!spying)
playsound(computer, get_sfx(SFX_TERMINAL_TYPE), 25, FALSE)
if(!selected_camera)
return TRUE
if(internal_tracker && internal_tracker.tracking)
internal_tracker.set_tracking(FALSE)
if(!selected_camera)
update_active_camera_screen()
return TRUE
update_active_camera_screen()
if("start_tracking")
if(!internal_tracker)
internal_tracker = new(src)
internal_tracker.set_tracked_mob(usr)
return TRUE
return TRUE
/datum/computer_file/program/secureye/proc/on_track_target(datum/trackable/source, mob/living/target)
SIGNAL_HANDLER
var/datum/camerachunk/target_camerachunk = GLOB.cameranet.getTurfVis(get_turf(target))
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]"])
var/found_target = locate(target) in cameras.can_see()
if(!found_target)
continue
var/new_camera = WEAKREF(cameras)
if(camera_ref == new_camera)
return
camera_ref = new_camera
update_active_camera_screen()
return
/datum/computer_file/program/secureye/ui_close(mob/user)
. = ..()
//don't track anyone while we're shutting off.
if(internal_tracker && internal_tracker.tracking)
internal_tracker.set_tracking(FALSE)
var/user_ref = REF(user)
var/is_living = isliving(user)
// Living creature or not, we remove you anyway.
@@ -125,7 +180,9 @@
// Turn off the console
if(length(concurrent_users) == 0 && is_living)
camera_ref = null
playsound(src, 'sound/machines/terminal_off.ogg', 25, FALSE)
last_camera_turf = null
if(!spying)
playsound(computer, 'sound/machines/terminal_off.ogg', 25, FALSE)
/datum/computer_file/program/secureye/proc/update_active_camera_screen()
var/obj/machinery/camera/active_camera = camera_ref?.resolve()
@@ -19,7 +19,7 @@
. = ..()
set_frequency(signal_frequency)
/datum/computer_file/program/signal_commander/kill_program()
/datum/computer_file/program/signal_commander/kill_program(mob/user)
. = ..()
SSradio.remove_object(computer, signal_frequency)
@@ -22,7 +22,7 @@
refresh()
/// Apparently destroy calls this [/datum/computer_file/Destroy]. Here just to clean our references.
/datum/computer_file/program/supermatter_monitor/kill_program()
/datum/computer_file/program/supermatter_monitor/kill_program(mob/user)
for(var/supermatter in supermatters)
clear_supermatter(supermatter)
return ..()