From a986b6973765b0bb16038f04db8715c0aae14d3e Mon Sep 17 00:00:00 2001 From: lolman360 Date: Sun, 14 Feb 2021 21:56:51 +1100 Subject: [PATCH] Porting camera cnonsoles + getting them to work --- code/__HELPERS/game.dm | 14 + code/_onclick/hud/fullscreen.dm | 6 +- code/_onclick/hud/map_popups.dm | 171 ++++++++++ code/_onclick/hud/skybox.dm | 8 +- code/controllers/subsystems/skybox.dm | 2 +- code/game/machinery/camera/camera.dm | 9 +- code/game/machinery/camera/presets.dm | 2 +- code/game/machinery/computer/aifixer.dm | 217 ++++++------- code/game/machinery/computer/camera.dm | 225 ++----------- .../game/machinery/computer/camera_circuit.dm | 116 ------- code/game/machinery/computer/crew.dm | 12 +- .../circuitboards/computer/camera_monitor.dm | 2 +- code/game/objects/structures/mirror.dm | 4 +- code/game/sound.dm | 5 + code/modules/alarm/alarm.dm | 8 +- code/modules/clothing/glasses/hud.dm | 36 ++- .../mob/freelook/ai/update_triggers.dm | 1 - code/modules/mob/living/silicon/subystems.dm | 4 +- code/modules/mob/logout.dm | 3 +- .../computers/modular_computer/core.dm | 2 +- .../modular_computers/file_system/program.dm | 21 +- .../programs/antagonist/hacked_camera.dm | 22 +- .../file_system/programs/generic/camera.dm | 154 +-------- .../programs/medical/suit_sensors.dm | 65 +--- code/modules/nifsoft/software/06_screens.dm | 42 +-- code/modules/tgui/modules/_base.dm | 46 +++ code/modules/tgui/modules/camera.dm | 295 ++++++++++++++++++ code/modules/tgui/modules/crew_monitor.dm | 103 ++++++ code/modules/tgui/states/inventory.dm | 30 ++ code/modules/tgui/states/ntos.dm | 15 + code/modules/tgui/tgui.dm | 11 + icons/mob/map_backgrounds.dmi | Bin 0 -> 555 bytes .../code/modules/clothing/glasses/hud_vr.dm | 23 -- sound/machines/terminal_alert.ogg | Bin 0 -> 20530 bytes sound/machines/terminal_button01.ogg | Bin 0 -> 6933 bytes sound/machines/terminal_button02.ogg | Bin 0 -> 8238 bytes sound/machines/terminal_button03.ogg | Bin 0 -> 6987 bytes sound/machines/terminal_button04.ogg | Bin 0 -> 6736 bytes sound/machines/terminal_button05.ogg | Bin 0 -> 6551 bytes sound/machines/terminal_button06.ogg | Bin 0 -> 6750 bytes sound/machines/terminal_button07.ogg | Bin 0 -> 7402 bytes sound/machines/terminal_button08.ogg | Bin 0 -> 7346 bytes sound/machines/terminal_insert_disc.ogg | Bin 0 -> 15642 bytes sound/machines/terminal_off.ogg | Bin 0 -> 18204 bytes sound/machines/terminal_on.ogg | Bin 0 -> 12265 bytes sound/machines/terminal_prompt.ogg | Bin 0 -> 7099 bytes sound/machines/terminal_prompt_confirm.ogg | Bin 0 -> 6773 bytes sound/machines/terminal_prompt_deny.ogg | Bin 0 -> 6827 bytes tgui/docs/migration-to-v4-from-v3.md | 2 +- tgui/packages/tgui/interfaces/CrewMonitor.js | 173 ++++++++++ tgui/public/tgui-common.chunk.js | 2 +- tgui/public/tgui-panel.bundle.js | 2 +- tgui/public/tgui.bundle.js | 2 +- vorestation.dme | 6 +- 54 files changed, 1097 insertions(+), 764 deletions(-) create mode 100644 code/_onclick/hud/map_popups.dm delete mode 100644 code/game/machinery/computer/camera_circuit.dm create mode 100644 code/modules/tgui/modules/_base.dm create mode 100644 code/modules/tgui/modules/camera.dm create mode 100644 code/modules/tgui/modules/crew_monitor.dm create mode 100644 code/modules/tgui/states/ntos.dm create mode 100644 icons/mob/map_backgrounds.dmi delete mode 100644 modular_citadel/code/modules/clothing/glasses/hud_vr.dm create mode 100644 sound/machines/terminal_alert.ogg create mode 100644 sound/machines/terminal_button01.ogg create mode 100644 sound/machines/terminal_button02.ogg create mode 100644 sound/machines/terminal_button03.ogg create mode 100644 sound/machines/terminal_button04.ogg create mode 100644 sound/machines/terminal_button05.ogg create mode 100644 sound/machines/terminal_button06.ogg create mode 100644 sound/machines/terminal_button07.ogg create mode 100644 sound/machines/terminal_button08.ogg create mode 100644 sound/machines/terminal_insert_disc.ogg create mode 100644 sound/machines/terminal_off.ogg create mode 100644 sound/machines/terminal_on.ogg create mode 100644 sound/machines/terminal_prompt.ogg create mode 100644 sound/machines/terminal_prompt_confirm.ogg create mode 100644 sound/machines/terminal_prompt_deny.ogg create mode 100644 tgui/packages/tgui/interfaces/CrewMonitor.js diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index e5cfa74f2a0..c2a1ea6c21d 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -629,3 +629,17 @@ datum/projectile_data if (!client_or_usr) return winset(client_or_usr, "mainwindow", "flash=5") + +// used for the multiz camera console stolen from vorestatiobn +/proc/get_bbox_of_atoms(list/atoms) + var/list/list_x = list() + var/list/list_y = list() + for(var/_a in atoms) + var/atom/a = _a + list_x += a.x + list_y += a.y + return list( + min(list_x), + min(list_y), + max(list_x), + max(list_y)) \ No newline at end of file diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 7060451b275..67fc0086f2d 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -122,9 +122,5 @@ layer = FULLSCREEN_LAYER /obj/screen/fullscreen/fishbed - icon_state = "fishbed" + icon_state = "fishbed" -#undef FULLSCREEN_LAYER -#undef BLIND_LAYER -#undef DAMAGE_LAYER -#undef CRIT_LAYER \ No newline at end of file diff --git a/code/_onclick/hud/map_popups.dm b/code/_onclick/hud/map_popups.dm new file mode 100644 index 00000000000..aae5c808c97 --- /dev/null +++ b/code/_onclick/hud/map_popups.dm @@ -0,0 +1,171 @@ +/client + /** + * Assoc list with all the active maps - when a screen obj is added to + * a map, it's put in here as well. + * + * Format: list( = list(/obj/screen)) + */ + var/list/screen_maps = list() + +/obj/screen + /** + * Map name assigned to this object. + * Automatically set by /client/proc/register_map_obj. + */ + var/assigned_map + /** + * Mark this object as garbage-collectible after you clean the map + * it was registered on. + * + * This could probably be changed to be a proc, for conditional removal. + * But for now, this works. + */ + var/del_on_map_removal = TRUE + +/** + * A screen object, which acts as a container for turfs and other things + * you want to show on the map, which you usually attach to "vis_contents". + */ +/obj/screen/map_view + icon_state = "blank" + // Map view has to be on the lowest plane to enable proper lighting + layer = SPACE_PLANE + plane = SPACE_PLANE + +/** + * A generic background object. + * It is also implicitly used to allocate a rectangle on the map, which will + * be used for auto-scaling the map. + */ +/obj/screen/background + name = "background" + icon = 'icons/mob/map_backgrounds.dmi' + icon_state = "clear" + layer = SPACE_PLANE + plane = SPACE_PLANE + +/** + * Sets screen_loc of this screen object, in form of point coordinates, + * with optional pixel offset (px, py). + * + * If applicable, "assigned_map" has to be assigned before this proc call. + */ +/obj/screen/proc/set_position(x, y, px = 0, py = 0) + if(assigned_map) + screen_loc = "[assigned_map]:[x]:[px],[y]:[py]" + else + screen_loc = "[x]:[px],[y]:[py]" + +/** + * Sets screen_loc to fill a rectangular area of the map. + * + * If applicable, "assigned_map" has to be assigned before this proc call. + */ +/obj/screen/proc/fill_rect(x1, y1, x2, y2) + if(assigned_map) + screen_loc = "[assigned_map]:[x1],[y1] to [x2],[y2]" + else + screen_loc = "[x1],[y1] to [x2],[y2]" + +/** + * Registers screen obj with the client, which makes it visible on the + * assigned map, and becomes a part of the assigned map's lifecycle. + */ +/client/proc/register_map_obj(obj/screen/screen_obj) + if(!screen_obj.assigned_map) + CRASH("Can't register [screen_obj] without 'assigned_map' property.") + if(!screen_maps[screen_obj.assigned_map]) + screen_maps[screen_obj.assigned_map] = list() + // NOTE: Possibly an expensive operation + var/list/screen_map = screen_maps[screen_obj.assigned_map] + if(!screen_map.Find(screen_obj)) + screen_map += screen_obj + if(!screen.Find(screen_obj)) + screen += screen_obj + +/** + * Clears the map of registered screen objects. + * + * Not really needed most of the time, as the client's screen list gets reset + * on relog. any of the buttons are going to get caught by garbage collection + * anyway. they're effectively qdel'd. + */ +/client/proc/clear_map(map_name) + if(!map_name || !(map_name in screen_maps)) + return FALSE + for(var/obj/screen/screen_obj in screen_maps[map_name]) + screen_maps[map_name] -= screen_obj + if(screen_obj.del_on_map_removal) + qdel(screen_obj) + screen_maps -= map_name + +/** + * Clears all the maps of registered screen objects. + */ +/client/proc/clear_all_maps() + for(var/map_name in screen_maps) + clear_map(map_name) + +/** + * Creates a popup window with a basic map element in it, without any + * further initialization. + * + * Ratio is how many pixels by how many pixels (keep it simple). + * + * Returns a map name. + */ +/client/proc/create_popup(name, ratiox = 100, ratioy = 100) + winclone(src, "popupwindow", name) + var/list/winparams = list() + winparams["size"] = "[ratiox]x[ratioy]" + winparams["on-close"] = "handle-popup-close [name]" + winset(src, "[name]", list2params(winparams)) + winshow(src, "[name]", 1) + + var/list/params = list() + params["parent"] = "[name]" + params["type"] = "map" + params["size"] = "[ratiox]x[ratioy]" + params["anchor1"] = "0,0" + params["anchor2"] = "[ratiox],[ratioy]" + winset(src, "[name]_map", list2params(params)) + + return "[name]_map" + +/** + * Create the popup, and get it ready for generic use by giving + * it a background. + * + * Width and height are multiplied by 64 by default. + */ +/client/proc/setup_popup(popup_name, width = 9, height = 9, \ + tilesize = 2, bg_icon) + if(!popup_name) + return + clear_map("[popup_name]_map") + var/x_value = world.icon_size * tilesize * width + var/y_value = world.icon_size * tilesize * height + var/map_name = create_popup(popup_name, x_value, y_value) + + var/obj/screen/background/background = new + background.assigned_map = map_name + background.fill_rect(1, 1, width, height) + if(bg_icon) + background.icon_state = bg_icon + register_map_obj(background) + + return map_name + +/** + * Closes a popup. + */ +/client/proc/close_popup(popup) + winshow(src, popup, 0) + handle_popup_close(popup) + +/** + * When the popup closes in any way (player or proc call) it calls this. + */ +/client/verb/handle_popup_close(window_id as text) + set hidden = TRUE + clear_map("[window_id]_map") diff --git a/code/_onclick/hud/skybox.dm b/code/_onclick/hud/skybox.dm index 6c251676bc0..b85f2695d0c 100644 --- a/code/_onclick/hud/skybox.dm +++ b/code/_onclick/hud/skybox.dm @@ -3,8 +3,10 @@ #define SKYBOX_TURFS (SKYBOX_PIXELS/WORLD_ICON_SIZE) // Skybox screen object. -/obj/skybox +/obj/screen/skybox name = "skybox" + icon = null + appearance_flags = TILE_BOUND|PIXEL_SCALE mouse_opacity = 0 anchored = TRUE simulated = FALSE @@ -13,7 +15,7 @@ blend_mode = BLEND_MULTIPLY // You actually need to do it this way or you see it in occlusion. // Adjust transform property to scale for client's view var. We assume the skybox is 736x736 px -/obj/skybox/proc/scale_to_view(var/view) +/obj/screen/skybox/proc/scale_to_view(var/view) var/matrix/M = matrix() // Translate to center the icon over us! M.Translate(-(SKYBOX_PIXELS - WORLD_ICON_SIZE) / 2) @@ -23,7 +25,7 @@ src.transform = M /client - var/obj/skybox/skybox + var/obj/screen/skybox/skybox /client/proc/update_skybox(rebuild) if(!skybox) diff --git a/code/controllers/subsystems/skybox.dm b/code/controllers/subsystems/skybox.dm index 4ec9e76a8cc..b00f839deb5 100644 --- a/code/controllers/subsystems/skybox.dm +++ b/code/controllers/subsystems/skybox.dm @@ -136,7 +136,7 @@ SUBSYSTEM_DEF(skybox) for(var/z in zlevels) skybox_cache["[z]"] = generate_skybox(z) - for(var/client/C) + for(var/client/C in GLOB.clients) var/their_z = get_z(C.mob) if(!their_z) // Nullspace continue diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 9265d21b48c..1f64b2317b6 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -225,12 +225,7 @@ if(U.name == "Unknown") O << "[U] holds \a [itemname] up to one of your cameras ..." else O << "[U] holds \a [itemname] up to one of your cameras ..." O << browse(text("[][]", itemname, info), text("window=[]", itemname)) - for(var/mob/O in player_list) - if (istype(O.machine, /obj/machinery/computer/security)) - var/obj/machinery/computer/security/S = O.machine - if (S.current_camera == src) - to_chat(O, "[U] holds \a [itemname] up to one of the cameras ...") - O << browse(text("[][]", itemname, info), text("window=[]", itemname)) + else if (istype(W, /obj/item/camera_bug)) if (!src.can_use()) @@ -480,7 +475,7 @@ else cameranet.updateVisibility(src, 0) - invalidateCameraCache() + // Resets the camera's wires to fully operational state. Used by one of Malfunction abilities. /obj/machinery/camera/proc/reset_wires() diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index 3bdcbade8b1..f52084b8fdb 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -172,7 +172,7 @@ var/global/list/engineering_networks = list( if(C.number) number = max(number, C.number+1) c_tag = "[A.name] #[number]" - invalidateCameraCache() + // CHECKS diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index 591c7dd6542..950bb38651f 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -1,141 +1,132 @@ /obj/machinery/computer/aifixer name = "\improper AI system integrity restorer" - icon_keyboard = "rd_key" - icon_screen = "ai-fixer" - light_color = "#a97faa" - circuit = /obj/item/circuitboard/aifixer + desc = "Used with intelliCards containing nonfunctional AIs to restore them to working order." req_one_access = list(access_robotics, access_heads) - var/mob/living/silicon/ai/occupant = null - var/active = 0 + circuit = /obj/item/circuitboard/aifixer + icon_keyboard = "tech_key" + icon_screen = "ai-fixer" + light_color = LIGHT_COLOR_PINK -/obj/machinery/computer/aifixer/New() - ..() - update_icon() + active_power_usage = 1000 -/obj/machinery/computer/aifixer/proc/load_ai(var/mob/living/silicon/ai/transfer, var/obj/item/aicard/card, var/mob/user) - - if(!transfer) - return - - // Transfer over the AI. - to_chat(transfer, "You have been transferred into a stationary terminal. Sadly, there is no remote access from here.") - to_chat(user, "Transfer successful: [transfer.name] placed within stationary terminal.") - - transfer.loc = src - transfer.cancel_camera() - transfer.control_disabled = 1 - occupant = transfer - - if(card) - card.clear() - - update_icon() - -/obj/machinery/computer/aifixer/attackby(I as obj, user as mob) + /// Variable containing transferred AI + var/mob/living/silicon/ai/occupier + /// Variable dictating if we are in the process of restoring the occupier AI + var/restoring = FALSE +/obj/machinery/computer/aifixer/attackby(obj/item/I, mob/living/user) + if(I.is_screwdriver()) + if(occupier) + if(stat & (NOPOWER|BROKEN)) + to_chat(user, "The screws on [name]'s screen won't budge.") + else + to_chat(user, "The screws on [name]'s screen won't budge and it emits a warning beep.") + return if(istype(I, /obj/item/aicard)) - if(stat & (NOPOWER|BROKEN)) - to_chat(user, "This terminal isn't functioning right now.") + to_chat(user, "This terminal isn't functioning right now.") + return + if(restoring) + to_chat(user, "Terminal is busy restoring [occupier] right now.") return var/obj/item/aicard/card = I - var/mob/living/silicon/ai/comp_ai = locate() in src - var/mob/living/silicon/ai/card_ai = locate() in card + if(occupier) + if(card.grab_ai(occupier, user)) + occupier = null + else if(card.carded_ai) + var/mob/living/silicon/ai/new_occupant = card.carded_ai + to_chat(new_occupant, "You have been transferred into a stationary terminal. Sadly there is no remote access from here.") + to_chat(user, "Transfer Successful: [new_occupant] placed within stationary terminal.") + new_occupant.forceMove(src) + new_occupant.cancel_camera() + new_occupant.control_disabled = TRUE + occupier = new_occupant + card.clear() + update_icon() + else + to_chat(user, "There is no AI loaded onto this computer, and no AI loaded onto [I]. What exactly are you trying to do here?") + return ..() - if(istype(comp_ai)) - if(active) - to_chat(user, "ERROR: Reconstruction in progress.") - return - card.grab_ai(comp_ai, user) - if(!(locate(/mob/living/silicon/ai) in src)) occupant = null - else if(istype(card_ai)) - load_ai(card_ai,card,user) - occupant = locate(/mob/living/silicon/ai) in src - - update_icon() +/obj/machinery/computer/aifixer/attack_hand(mob/user) + if(stat & (NOPOWER|BROKEN)) return - ..() - return + ui_interact(user) -/obj/machinery/computer/aifixer/attack_ai(var/mob/user as mob) - return attack_hand(user) +/obj/machinery/computer/aifixer/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AiRestorer", name) + ui.open() -/obj/machinery/computer/aifixer/attack_hand(var/mob/user as mob) +/obj/machinery/computer/aifixer/ui_data(mob/user) + var/list/data = list() + + data["ejectable"] = FALSE + data["AI_present"] = FALSE + data["error"] = null + if(!occupier) + data["error"] = "Please transfer an AI unit." + else + data["AI_present"] = TRUE + data["name"] = occupier.name + data["restoring"] = restoring + data["health"] = (occupier.health + 100) / 2 + data["isDead"] = occupier.stat == DEAD + var/list/laws = list() + for(var/datum/ai_law/law in occupier.laws.all_laws()) + laws += "[law.get_index()]: [law.law]" + data["laws"] = laws + + return data + +/obj/machinery/computer/aifixer/ui_act(action, params) if(..()) return + if(!occupier) + restoring = FALSE - user.set_machine(src) - var/dat = "

AI System Integrity Restorer



" + switch(action) + if("PRG_beginReconstruction") + if(occupier?.health < 100) + to_chat(usr, "Reconstruction in progress. This will take several minutes.") + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, FALSE) + restoring = TRUE + var/mob/observer/dead/ghost = occupier.get_ghost() + if(ghost) + ghost.notify_revive("Your core files are being restored!", source = src) + . = TRUE - if (src.occupant) - var/laws - dat += "Stored AI: [src.occupant.name]
System integrity: [src.occupant.hardware_integrity()]%
Backup Capacitor: [src.occupant.backup_capacitor()]%
" +/obj/machinery/computer/aifixer/proc/Fix() + use_power(active_power_usage) + occupier.adjustOxyLoss(-5, 0, FALSE) + occupier.adjustFireLoss(-5, 0, FALSE) + occupier.adjustBruteLoss(-5, 0) + if(occupier.health >= 0 && occupier.stat == DEAD) + occupier.revive() - for (var/datum/ai_law/law in occupant.laws.all_laws()) - laws += "[law.get_index()]: [law.law]
" - - dat += "Laws:
[laws]
" - - if (src.occupant.stat == 2) - dat += "AI nonfunctional" - else - dat += "AI functional" - if (!src.active) - dat += {"

Begin Reconstruction"} - else - dat += "

Reconstruction in process, please wait.
" - dat += {" Close"} - - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") - return + return occupier.health < 100 /obj/machinery/computer/aifixer/process() if(..()) - src.updateDialog() - return - -/obj/machinery/computer/aifixer/Topic(href, href_list) - if(..()) - return 1 - if (href_list["fix"]) - src.active = 1 - src.overlays += image(icon, "ai-fixer-on") - while (src.occupant.getOxyLoss() > 0 || src.occupant.getFireLoss() > 0 || src.occupant.getToxLoss() > 0 || src.occupant.getBruteLoss() > 0) - src.occupant.adjustOxyLoss(-1) - src.occupant.adjustFireLoss(-1) - src.occupant.adjustToxLoss(-1) - src.occupant.adjustBruteLoss(-1) - src.occupant.updatehealth() - if (src.occupant.health >= 0 && src.occupant.stat == DEAD) - src.occupant.stat = CONSCIOUS - src.occupant.lying = 0 - dead_mob_list -= src.occupant - living_mob_list += src.occupant - src.overlays -= image(icon, "ai-fixer-404") - src.overlays += image(icon, "ai-fixer-full") - src.occupant.add_ai_verbs() - src.updateUsrDialog() - sleep(10) - src.active = 0 - src.overlays -= image(icon, "ai-fixer-on") - - - src.add_fingerprint(usr) - src.updateUsrDialog() - return - + if(restoring) + var/oldstat = occupier.stat + restoring = Fix() + if(oldstat != occupier.stat) + update_icon() /obj/machinery/computer/aifixer/update_icon() - ..() - if((stat & BROKEN) || (stat & NOPOWER)) + . = ..() + if(stat & (NOPOWER|BROKEN)) return - if(occupant) - if(occupant.stat) - overlays += image(icon, "ai-fixer-404", overlay_layer) - else - overlays += image(icon, "ai-fixer-full", overlay_layer) + if(restoring) + . += "ai-fixer-on" + if (occupier) + switch (occupier.stat) + if (CONSCIOUS) + . += "ai-fixer-full" + if (UNCONSCIOUS) + . += "ai-fixer-404" else - overlays += image(icon, "ai-fixer-empty", overlay_layer) + . += "ai-fixer-empty" diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 829a27bf97f..7904a2a228a 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -3,204 +3,46 @@ /obj/machinery/computer/security name = "security camera monitor" desc = "Used to access the various cameras on the station." + icon_keyboard = "security_key" icon_screen = "cameras" light_color = "#a91515" - var/current_network = null - var/obj/machinery/camera/current_camera = null - var/last_pic = 1.0 - var/list/network - var/mapping = 0//For the overview file, interesting bit of code. - var/cache_id = 0 circuit = /obj/item/circuitboard/security -/obj/machinery/computer/security/New() - if(!network) + var/mapping = 0//For the overview file, interesting bit of code. + var/list/network = list() + + var/datum/tgui_module/camera/camera + +/obj/machinery/computer/security/Initialize() + . = ..() + if(!LAZYLEN(network)) network = GLOB.using_map.station_networks.Copy() - ..() - if(network.len) - current_network = network[1] + camera = new(src, network) -/obj/machinery/computer/security/attack_ai(var/mob/user as mob) - return attack_hand(user) +/obj/machinery/computer/security/Destroy() + QDEL_NULL(camera) + return ..() -/obj/machinery/computer/security/check_eye(var/mob/user as mob) - if (user.stat || ((get_dist(user, src) > 1 || !( user.canmove ) || user.blinded) && !istype(user, /mob/living/silicon))) //user can't see - not sure why canmove is here. - return -1 - if(!current_camera) - return 0 - var/viewflag = current_camera.check_eye(user) - if ( viewflag < 0 ) //camera doesn't work - reset_current() - return viewflag +/obj/machinery/computer/security/ui_interact(mob/user, datum/tgui/ui = null) + camera.ui_interact(user, ui) -/obj/machinery/computer/security/nano_ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) - if(stat & (NOPOWER|BROKEN)) return - if(user.stat) return - - var/data[0] - - data["current_camera"] = current_camera ? current_camera.nano_structure() : null - data["current_network"] = current_network - data["networks"] = network ? network : list() - if(current_network) - data["cameras"] = camera_repository.cameras_in_network(current_network) - if(current_camera) - switch_to_camera(user, current_camera) - data["map_levels"] = GLOB.using_map.get_map_levels(src.z) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "sec_camera.tmpl", "Camera Console", 900, 800) - - // adding a template with the key "mapContent" enables the map ui functionality - ui.add_template("mapContent", "sec_camera_map_content.tmpl") - // adding a template with the key "mapHeader" replaces the map header content - ui.add_template("mapHeader", "sec_camera_map_header.tmpl") - - ui.set_initial_data(data) - ui.open() - -/obj/machinery/computer/security/Topic(href, href_list) - if(..()) - return 1 - if(href_list["switch_camera"]) - if(stat&(NOPOWER|BROKEN)) return //VOREStation Edit - Removed zlevel check - if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return - var/obj/machinery/camera/C = locate(href_list["switch_camera"]) in cameranet.cameras - if(!C) - return - if(!(current_network in C.network)) - return - - switch_to_camera(usr, C) - return 1 - else if(href_list["switch_network"]) - if(stat&(NOPOWER|BROKEN)) return //VOREStation Edit - Removed zlevel check - if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return - if(href_list["switch_network"] in network) - current_network = href_list["switch_network"] - return 1 - else if(href_list["reset"]) - if(stat&(NOPOWER|BROKEN)) return //VOREStation Edit - Removed zlevel check - if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return - reset_current() - usr.reset_view(current_camera) - return 1 - else - . = ..() - -/obj/machinery/computer/security/attack_hand(var/mob/user as mob) - if (GLOB.using_map && !(src.z in GLOB.using_map.contact_levels)) - to_chat(user, "Unable to establish a connection: You're too far away from the station!") +/obj/machinery/computer/security/attack_hand(mob/user) + add_fingerprint(user) + if(stat & (BROKEN|NOPOWER)) return - if(stat & (NOPOWER|BROKEN)) return + ui_interact(user) - if(!isAI(user)) - user.set_machine(src) - nano_ui_interact(user) +/obj/machinery/computer/security/attack_ai(mob/user) + to_chat(user, "You realise its kind of stupid to access a camera console when you have the entire camera network at your metaphorical fingertips") + return -/obj/machinery/computer/security/proc/switch_to_camera(var/mob/user, var/obj/machinery/camera/C) - //don't need to check if the camera works for AI because the AI jumps to the camera location and doesn't actually look through cameras. - if(isAI(user)) - var/mob/living/silicon/ai/A = user - // Only allow non-carded AIs to view because the interaction with the eye gets all wonky otherwise. - if(!A.is_in_chassis()) - return 0 +/obj/machinery/computer/security/proc/set_network(list/new_network) + network = new_network + camera.network = network + camera.access_based = FALSE - A.eyeobj.setLoc(get_turf(C)) - A.client.eye = A.eyeobj - return 1 - - if (!C.can_use() || user.stat || (get_dist(user, src) > 1 || user.machine != src || user.blinded || !( user.canmove ) && !istype(user, /mob/living/silicon))) - return 0 - set_current(C) - user.reset_view(current_camera) - check_eye(user) - return 1 - -//Camera control: moving. -/obj/machinery/computer/security/proc/jump_on_click(var/mob/user,var/A) - if(user.machine != src) - return - var/obj/machinery/camera/jump_to - if(istype(A,/obj/machinery/camera)) - jump_to = A - else if(ismob(A)) - if(ishuman(A)) - jump_to = locate() in A:head - else if(isrobot(A)) - jump_to = A:camera - else if(isobj(A)) - jump_to = locate() in A - else if(isturf(A)) - var/best_dist = INFINITY - for(var/obj/machinery/camera/camera in get_area(A)) - if(!camera.can_use()) - continue - if(!can_access_camera(camera)) - continue - var/dist = get_dist(camera,A) - if(dist < best_dist) - best_dist = dist - jump_to = camera - if(isnull(jump_to)) - return - if(can_access_camera(jump_to)) - switch_to_camera(user,jump_to) - -/obj/machinery/computer/security/process() - if(cache_id != camera_repository.camera_cache_id) - cache_id = camera_repository.camera_cache_id - SSnanoui.update_uis(src) - -/obj/machinery/computer/security/proc/can_access_camera(var/obj/machinery/camera/C) - var/list/shared_networks = src.network & C.network - if(shared_networks.len) - return 1 - return 0 - -/obj/machinery/computer/security/proc/set_current(var/obj/machinery/camera/C) - if(current_camera == C) - return - - if(current_camera) - reset_current() - - src.current_camera = C - if(current_camera) - current_camera.camera_computers_using_this.Add(src) - update_use_power(USE_POWER_ACTIVE) - var/mob/living/L = current_camera.loc - if(istype(L)) - L.tracking_initiated() - -/obj/machinery/computer/security/proc/reset_current() - if(current_camera) - current_camera.camera_computers_using_this.Remove(src) - var/mob/living/L = current_camera.loc - if(istype(L)) - L.tracking_cancelled() - current_camera = null - use_power = USE_POWER_IDLE - -//Camera control: mouse. -/atom/DblClick() - ..() - if(istype(usr.machine,/obj/machinery/computer/security)) - var/obj/machinery/computer/security/console = usr.machine - console.jump_on_click(usr,src) //Camera control: arrow keys. -/mob/Move(n,direct) - if(istype(machine,/obj/machinery/computer/security)) - var/obj/machinery/computer/security/console = machine - var/turf/T = get_turf(console.current_camera) - for(var/i;i<10;i++) - T = get_step(T,direct) - console.jump_on_click(src,T) - return - return ..(n,direct) - /obj/machinery/computer/security/telescreen name = "Telescreen" desc = "Used for watching an empty arena." @@ -244,7 +86,7 @@ /obj/machinery/computer/security/wooden_tv name = "security camera monitor" - desc = "An old TV hooked into the stations camera network." + desc = "An old TV hooked into the station's camera network." icon_state = "television" icon_keyboard = null icon_screen = "detective_tv" @@ -252,20 +94,9 @@ light_color = "#3848B3" light_power_on = 0.5 -/obj/machinery/computer/security/wooden_tv/service - name = "security camera monitor" - desc = "An old TV hooked into the stations entertainment network." - icon_state = "television" - icon_keyboard = null - icon_screen = "detective_tv" - network = list(NETWORK_THUNDER) - circuit = /obj/item/circuitboard/security/telescreen/entertainment - light_color = "#3848B3" - light_power_on = 0.9 - /obj/machinery/computer/security/mining name = "outpost camera monitor" - desc = "Used to access the various cameras on the outpost." + desc = "Used to watch over mining operations." icon_keyboard = "mining_key" icon_screen = "mining" network = list("Mining Outpost") diff --git a/code/game/machinery/computer/camera_circuit.dm b/code/game/machinery/computer/camera_circuit.dm deleted file mode 100644 index c27aa77a6d3..00000000000 --- a/code/game/machinery/computer/camera_circuit.dm +++ /dev/null @@ -1,116 +0,0 @@ - -//the researchable camera circuit that can connect to any camera network - -/obj/item/circuitboard/camera - //name = "Circuit board (Camera)" - var/secured = 1 - var/authorised = 0 - var/possibleNets[0] - var/network = "" - build_path = null - -//when adding a new camera network, you should only need to update these two procs - New() - possibleNets["Engineering"] = access_ce - possibleNets["SS13"] = access_hos - possibleNets["Mining"] = access_mining - possibleNets["Cargo"] = access_qm - possibleNets["Research"] = access_rd - possibleNets["Medbay"] = access_cmo - ..() - - proc/updateBuildPath() - build_path = null - if(authorised && secured) - switch(network) - if("SS13") - build_path = /obj/machinery/computer/security - if("Engineering") - build_path = /obj/machinery/computer/security/engineering - if("Mining") - build_path = /obj/machinery/computer/security/mining - if("Research") - build_path = /obj/machinery/computer/security/research - if("Medbay") - build_path = /obj/machinery/computer/security/medbay - if("Cargo") - build_path = /obj/machinery/computer/security/cargo - - attackby(var/obj/item/I, var/mob/user)//if(health > 50) - ..() - else if(I.is_screwdriver()) - secured = !secured - user.visible_message("The [src] can [secured ? "no longer" : "now"] be modified.") - playsound(src, I.usesound, 50, 1) - updateBuildPath() - return - - attack_self(var/mob/user) - if(!secured && ishuman(user)) - user.machine = src - interact(user, 0) - - proc/interact(var/mob/user, var/ai=0) - if(secured) - return - if (!ishuman(user)) - return ..(user) - var/t = "Circuitboard Console - Camera Monitoring Computer
" - t += "Close
" - t += "
Please select a camera network:
" - - for(var/curNet in possibleNets) - if(network == curNet) - t += "- [curNet]
" - else - t += "- [curNet]
" - t += "
" - if(network) - if(authorised) - t += "Authenticated (Clear Auth)
" - else - t += "*Authenticate* (Requires an appropriate access ID)
" - else - t += "*Authenticate* (Requires an appropriate access ID)
" - t += "Close
" - user << browse(t, "window=camcircuit;size=500x400") - onclose(user, "camcircuit") - - Topic(href, href_list) - ..() - if( href_list["close"] ) - usr << browse(null, "window=camcircuit") - usr.machine = null - return - else if(href_list["net"]) - network = href_list["net"] - authorised = 0 - else if( href_list["auth"] ) - var/mob/M = usr - var/obj/item/card/id/I = M.equipped() - if (istype(I, /obj/item/pda)) - var/obj/item/pda/pda = I - I = pda.id - if (I && istype(I)) - if(access_captain in I.access) - authorised = 1 - else if (possibleNets[network] in I.access) - authorised = 1 - if(istype(I,/obj/item/card/emag)) - I.resolve_attackby(src, usr) - else if( href_list["removeauth"] ) - authorised = 0 - updateDialog() - - updateDialog() - if(istype(src.loc,/mob)) - attack_self(src.loc) - -/obj/item/circuitboard/camera/emag_act(var/remaining_charges, var/mob/user) - if(network) - authorised = 1 - to_chat(user, "You authorised the circuit network!") - updateDialog() - return 1 - else - to_chat(user, "You must select a camera network circuit!") diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index aac32a03a81..54241800ee9 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -8,7 +8,7 @@ idle_power_usage = 250 active_power_usage = 500 circuit = /obj/item/circuitboard/crew - var/datum/nano_module/crew_monitor/crew_monitor + var/datum/tgui_module/crew_monitor/crew_monitor /obj/machinery/computer/crew/New() crew_monitor = new(src) @@ -20,16 +20,16 @@ ..() /obj/machinery/computer/crew/attack_ai(mob/user) - nano_ui_interact(user) + attack_hand(user) /obj/machinery/computer/crew/attack_hand(mob/user) add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) return - nano_ui_interact(user) + ui_interact(user) -/obj/machinery/computer/crew/nano_ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - crew_monitor.nano_ui_interact(user, ui_key, ui, force_open) +/obj/machinery/computer/crew/ui_interact(mob/user, datum/tgui/ui = null) + crew_monitor.ui_interact(user, ui) /obj/machinery/computer/crew/interact(mob/user) - crew_monitor.nano_ui_interact(user) + crew_monitor.ui_interact(user) diff --git a/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm b/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm index b715d7ef070..498a5a978ab 100644 --- a/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm +++ b/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm @@ -45,7 +45,7 @@ /obj/item/circuitboard/security/construct(var/obj/machinery/computer/security/C) if (..(C)) - C.network = network.Copy() + C.set_network(network.Copy()) /obj/item/circuitboard/security/deconstruct(var/obj/machinery/computer/security/C) if (..(C)) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 433a1781fcb..91b407efcf2 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -28,7 +28,7 @@ AC = new(src, user) AC.name = "SalonPro Nano-Mirror™" ui_users[user] = AC - AC.ui_interact(user) + AC.nano_ui_interact(user) /obj/structure/mirror/proc/shatter() if(!glass) return @@ -142,6 +142,7 @@ qdel(user) ..() + //Long mirrors. /obj/structure/mirror/long name = "mirror" @@ -193,4 +194,3 @@ icon_state = "long_mir_r_broke" density = 0 anchored = 1 - shattered = 1 diff --git a/code/game/sound.dm b/code/game/sound.dm index 03153dacd26..298f2a8f1bb 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -259,6 +259,11 @@ GLOBAL_VAR_INIT(sound_distance_offscreen, 7) if("smdelam") soundin = pick('sound/machines/sm/accent/delam/1.ogg', 'sound/machines/sm/accent/normal/2.ogg', 'sound/machines/sm/accent/normal/3.ogg', 'sound/machines/sm/accent/normal/4.ogg', 'sound/machines/sm/accent/normal/5.ogg', 'sound/machines/sm/accent/normal/6.ogg', 'sound/machines/sm/accent/normal/7.ogg', 'sound/machines/sm/accent/normal/8.ogg', 'sound/machines/sm/accent/normal/9.ogg', 'sound/machines/sm/accent/normal/10.ogg', 'sound/machines/sm/accent/normal/11.ogg', 'sound/machines/sm/accent/normal/12.ogg', 'sound/machines/sm/accent/normal/13.ogg', 'sound/machines/sm/accent/normal/14.ogg', 'sound/machines/sm/accent/normal/15.ogg', 'sound/machines/sm/accent/normal/16.ogg', 'sound/machines/sm/accent/normal/17.ogg', 'sound/machines/sm/accent/normal/18.ogg', 'sound/machines/sm/accent/normal/19.ogg', 'sound/machines/sm/accent/normal/20.ogg', 'sound/machines/sm/accent/normal/21.ogg', 'sound/machines/sm/accent/normal/22.ogg', 'sound/machines/sm/accent/normal/23.ogg', 'sound/machines/sm/accent/normal/24.ogg', 'sound/machines/sm/accent/normal/25.ogg', 'sound/machines/sm/accent/normal/26.ogg', 'sound/machines/sm/accent/normal/27.ogg', 'sound/machines/sm/accent/normal/28.ogg', 'sound/machines/sm/accent/normal/29.ogg', 'sound/machines/sm/accent/normal/30.ogg', 'sound/machines/sm/accent/normal/31.ogg', 'sound/machines/sm/accent/normal/32.ogg', 'sound/machines/sm/accent/normal/33.ogg', 'sound/machines/sm/supermatter1.ogg', 'sound/machines/sm/supermatter2.ogg', 'sound/machines/sm/supermatter3.ogg') + if ("terminal_type") + soundin = pick('sound/machines/terminal_button01.ogg', 'sound/machines/terminal_button02.ogg', 'sound/machines/terminal_button03.ogg', \ + 'sound/machines/terminal_button04.ogg', 'sound/machines/terminal_button05.ogg', 'sound/machines/terminal_button06.ogg', \ + 'sound/machines/terminal_button07.ogg', 'sound/machines/terminal_button08.ogg') + //END VORESTATION EDIT return soundin diff --git a/code/modules/alarm/alarm.dm b/code/modules/alarm/alarm.dm index ac9b103b560..3ad1df433f9 100644 --- a/code/modules/alarm/alarm.dm +++ b/code/modules/alarm/alarm.dm @@ -18,7 +18,6 @@ var/list/sources = new() //List of sources triggering the alarm. Used to determine when the alarm should be cleared. var/list/sources_assoc = new() //Associative list of source triggers. Used to efficiently acquire the alarm source. var/list/cameras //List of cameras that can be switched to, if the player has that capability. - var/cache_id //ID for camera cache, changed by invalidateCameraCache(). var/area/last_area //The last acquired area, used should origin be lost (for example a destroyed borg containing an alarming camera). var/area/last_name //The last acquired name, used should origin be lost var/area/last_camera_area //The last area in which cameras where fetched, used to see if the camera list should be updated. @@ -78,15 +77,10 @@ return last_name /datum/alarm/proc/cameras() - // reset camera cache - if(camera_repository.camera_cache_id != cache_id) - cameras = null - cache_id = camera_repository.camera_cache_id // If the alarm origin has changed area, for example a borg containing an alarming camera, reset the list of cameras - else if(cameras && (last_camera_area != alarm_area())) + if(cameras && (last_camera_area != alarm_area())) cameras = null - // The list of cameras is also reset by /proc/invalidateCameraCache() if(!cameras) cameras = origin ? origin.get_alarm_cameras() : last_area.get_alarm_cameras() diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 782a76a6d5f..7fad7dd8697 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -53,6 +53,8 @@ icon_state = "glasses" var/datum/nano_module/arscreen var/arscreen_path + var/datum/tgui_module/tgarscreen + var/tgarscreen_path var/flash_prot = 0 //0 for none, 1 for flash weapon protection, 2 for welder protection enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_AUGMENTED,VIS_CH_BACKUP) plane_slots = list(slot_glasses) @@ -61,21 +63,29 @@ ..() if(arscreen_path) arscreen = new arscreen_path(src) + if(tgarscreen_path) + tgarscreen = new tgarscreen_path(src) /obj/item/clothing/glasses/omnihud/Destroy() QDEL_NULL(arscreen) + QDEL_NULL(tgarscreen) . = ..() /obj/item/clothing/glasses/omnihud/dropped() if(arscreen) SSnanoui.close_uis(src) + if(tgarscreen) + SStgui.close_uis(src) ..() /obj/item/clothing/glasses/omnihud/emp_act(var/severity) var/disconnect_ar = arscreen arscreen = null + var/disconnect_tgar = tgarscreen + tgarscreen = null spawn(20 SECONDS) arscreen = disconnect_ar + tgarscreen = disconnect_tgar ..() /obj/item/clothing/glasses/omnihud/proc/flashed() @@ -116,13 +126,13 @@ These have been upgraded with medical records access and virus database integration." mode = "med" action_button_name = "AR Console (Crew Monitor)" - arscreen_path = /datum/nano_module/crew_monitor + tgarscreen_path = /datum/tgui_module/crew_monitor/glasses enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_STATUS_R,VIS_CH_BACKUP,VIS_AUGMENTED) - ar_interact(var/mob/living/carbon/human/user) - if(arscreen) - arscreen.nano_ui_interact(user,"main",null,1,glasses_state) - return 1 +/obj/item/clothing/glasses/omnihud/med/ar_interact(var/mob/living/carbon/human/user) + if(tgarscreen) + tgarscreen.ui_interact(user) + return 1 /obj/item/clothing/glasses/omnihud/sec name = "\improper AR-S glasses" @@ -134,10 +144,10 @@ arscreen_path = /datum/nano_module/alarm_monitor/security enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_WANTED,VIS_AUGMENTED) - ar_interact(var/mob/living/carbon/human/user) - if(arscreen) - arscreen.nano_ui_interact(user,"main",null,1,glasses_state) - return 1 +/obj/item/clothing/glasses/omnihud/sec/ar_interact(var/mob/living/carbon/human/user) + if(arscreen) + arscreen.nano_ui_interact(user,"main",null,1,glasses_state) + return 1 /obj/item/clothing/glasses/omnihud/eng name = "\improper AR-E glasses" @@ -148,10 +158,10 @@ action_button_name = "AR Console (Station Alerts)" arscreen_path = /datum/nano_module/alarm_monitor/engineering - ar_interact(var/mob/living/carbon/human/user) - if(arscreen) - arscreen.nano_ui_interact(user,"main",null,1,glasses_state) - return 1 +/obj/item/clothing/glasses/omnihud/eng/ar_interact(var/mob/living/carbon/human/user) + if(arscreen) + arscreen.nano_ui_interact(user,"main",null,1,glasses_state) + return 1 /obj/item/clothing/glasses/omnihud/rnd name = "\improper AR-R glasses" diff --git a/code/modules/mob/freelook/ai/update_triggers.dm b/code/modules/mob/freelook/ai/update_triggers.dm index 045d0522efe..797e5cc23b5 100644 --- a/code/modules/mob/freelook/ai/update_triggers.dm +++ b/code/modules/mob/freelook/ai/update_triggers.dm @@ -39,7 +39,6 @@ /obj/machinery/camera/deactivate(user as mob, var/choice = 1) ..(user, choice) - invalidateCameraCache() if(src.can_use()) cameranet.addCamera(src) else diff --git a/code/modules/mob/living/silicon/subystems.dm b/code/modules/mob/living/silicon/subystems.dm index a143dacb6fc..bdbd90a1f89 100644 --- a/code/modules/mob/living/silicon/subystems.dm +++ b/code/modules/mob/living/silicon/subystems.dm @@ -2,7 +2,7 @@ var/register_alarms = 1 var/datum/nano_module/alarm_monitor/all/alarm_monitor var/datum/nano_module/atmos_control/atmos_control - var/datum/nano_module/crew_monitor/crew_monitor + var/datum/tgui_module/crew_monitor/robot/crew_monitor var/datum/nano_module/law_manager/law_manager var/datum/nano_module/power_monitor/power_monitor var/datum/nano_module/rcon/rcon @@ -67,7 +67,7 @@ set category = "Subystems" set name = "Crew Monitor" - crew_monitor.nano_ui_interact(usr, state = self_state) + crew_monitor.ui_interact(usr, state = self_state) /**************** * Law Manager * diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm index 573c55f1740..ec5f059d311 100644 --- a/code/modules/mob/logout.dm +++ b/code/modules/mob/logout.dm @@ -1,6 +1,7 @@ /mob/Logout() SEND_SIGNAL(src, COMSIG_MOB_CLIENT_LOGOUT, client) SSnanoui.user_logout(src) // this is used to clean up (remove) this user's Nano UIs + SStgui.on_logout(src) // Cleanup any TGUIs the user has open player_list -= src disconnect_time = world.realtime //VOREStation Addition: logging when we disappear. update_client_z(null) @@ -14,4 +15,4 @@ send2irc("LOGOUT", "[key_name(src)] logged out - no more admins online.") ..() - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/modular_computers/computers/modular_computer/core.dm b/code/modules/modular_computers/computers/modular_computer/core.dm index e2660d3a777..7ceb2c59481 100644 --- a/code/modules/modular_computers/computers/modular_computer/core.dm +++ b/code/modules/modular_computers/computers/modular_computer/core.dm @@ -163,6 +163,7 @@ idle_threads.Add(active_program) active_program.program_state = PROGRAM_STATE_BACKGROUND // Should close any existing UIs SSnanoui.close_uis(active_program.NM ? active_program.NM : active_program) + SStgui.close_uis(active_program.TM ? active_program.TM : active_program) active_program = null update_icon() if(istype(user)) @@ -202,7 +203,6 @@ minimize_program(user) if(P.run_program(user)) - active_program = P update_icon() return 1 diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index 8d1419537cc..d9e3e3d78b6 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -5,8 +5,13 @@ var/required_access = null // List of required accesses to run/download the program. var/requires_access_to_run = 1 // Whether the program checks for required_access when run. var/requires_access_to_download = 1 // Whether the program checks for required_access when downloading. + //nanoui var/datum/nano_module/NM = null // If the program uses NanoModule, put it here and it will be automagically opened. Otherwise implement nano_ui_interact. var/nanomodule_path = null // Path to nanomodule, make sure to set this if implementing new program. + // t gui + var/datum/tgui_module/TM = null // If the program uses TGUIModule, put it here and it will be automagically opened. Otherwise implement ui_interact. + var/tguimodule_path = null // Path to tguimodule, make sure to set this if implementing new program. + // misc program stuff var/program_state = PROGRAM_STATE_KILLED// PROGRAM_STATE_KILLED or PROGRAM_STATE_BACKGROUND or PROGRAM_STATE_ACTIVE - specifies whether this program is running. var/obj/item/modular_computer/computer // Device that runs this program. var/filedesc = "Unknown Program" // User-friendly name of this program. @@ -125,9 +130,14 @@ // When implementing new program based device, use this to run the program. /datum/computer_file/program/proc/run_program(var/mob/living/user) if(can_run(user, 1) || !requires_access_to_run) + computer.active_program = src if(nanomodule_path) NM = new nanomodule_path(src, new /datum/topic_manager/program(src), src) NM.using_access = user.GetAccess() + if(tguimodule_path) + TM = new tguimodule_path(src) + TM.using_access = user.GetAccess() + TM.ui_interact(user) if(requires_ntnet && network_destination) generate_network_log("Connection opened to [network_destination].") program_state = PROGRAM_STATE_ACTIVE @@ -139,9 +149,11 @@ program_state = PROGRAM_STATE_KILLED if(network_destination) generate_network_log("Connection to [network_destination] closed.") - if(NM) - qdel(NM) - NM = null + QDEL_NULL(NM) + if(TM) + SStgui.close_uis(TM) + qdel(TM) + TM = null return 1 // This is called every tick when the program is enabled. Ensure you do parent call if you override it. If parent returns 1 continue with UI initialisation. @@ -154,6 +166,9 @@ if(istype(NM)) NM.nano_ui_interact(user, ui_key, null, force_open) return 0 + if(istype(TM)) + TM.ui_interact(user) + return 0 return 1 diff --git a/code/modules/modular_computers/file_system/programs/antagonist/hacked_camera.dm b/code/modules/modular_computers/file_system/programs/antagonist/hacked_camera.dm index 4a5d158d90e..ba38e00ef25 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/hacked_camera.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/hacked_camera.dm @@ -1,7 +1,7 @@ /datum/computer_file/program/camera_monitor/hacked filename = "camcrypt" filedesc = "Camera Decryption Tool" - nanomodule_path = /datum/nano_module/camera_monitor/hacked + tguimodule_path = /datum/tgui_module/camera/ntos/hacked program_icon_state = "hostile" program_key_state = "security_key" program_menu_icon = "zoomin" @@ -15,25 +15,9 @@ if(program_state != PROGRAM_STATE_ACTIVE) // Background programs won't trigger alarms. return - var/datum/nano_module/camera_monitor/hacked/HNM = NM // The program is active and connected to one of the station's networks. Has a very small chance to trigger IDS alarm every tick. - if(HNM && HNM.current_network && (HNM.current_network in GLOB.using_map.station_networks) && prob(0.1)) + if(prob(0.1)) if(ntnet_global.intrusion_detection_enabled) - ntnet_global.add_log("IDS WARNING - Unauthorised access detected to camera network [HNM.current_network] by device with NID [computer.network_card.get_network_tag()]") + ntnet_global.add_log("IDS WARNING - Unauthorised access detected to camera network by device with NID [computer.network_card.get_network_tag()]") ntnet_global.intrusion_detection_alarm = 1 - - -/datum/nano_module/camera_monitor/hacked - name = "Hacked Camera Monitoring Program" - //available_to_ai = FALSE - -/datum/nano_module/camera_monitor/hacked/can_access_network(var/mob/user, var/network_access) - return 1 - -// The hacked variant has access to all commonly used networks. -/datum/nano_module/camera_monitor/hacked/modify_networks_list(var/list/networks) - networks.Add(list(list("tag" = NETWORK_MERCENARY, "has_access" = 1))) - networks.Add(list(list("tag" = NETWORK_ERT, "has_access" = 1))) - networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1))) - return networks \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/generic/camera.dm b/code/modules/modular_computers/file_system/programs/generic/camera.dm index f589301da3a..4ec7667d80e 100644 --- a/code/modules/modular_computers/file_system/programs/generic/camera.dm +++ b/code/modules/modular_computers/file_system/programs/generic/camera.dm @@ -24,7 +24,7 @@ /datum/computer_file/program/camera_monitor filename = "cammon" filedesc = "Camera Monitoring" - nanomodule_path = /datum/nano_module/camera_monitor + tguimodule_path = /datum/tgui_module/camera/ntos program_icon_state = "cameras" program_key_state = "generic_key" program_menu_icon = "search" @@ -33,161 +33,11 @@ available_on_ntnet = 1 requires_ntnet = 1 -/datum/nano_module/camera_monitor - name = "Camera Monitoring program" - var/obj/machinery/camera/current_camera = null - var/current_network = null - -/datum/nano_module/camera_monitor/nano_ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, state = default_state) - var/list/data = host.initial_data() - - data["current_camera"] = current_camera ? current_camera.nano_structure() : null - data["current_network"] = current_network - - var/list/all_networks[0] - for(var/network in GLOB.using_map.station_networks) - if(can_access_network(user, get_camera_access(network), 1)) - all_networks.Add(list(list( - "tag" = network, - "has_access" = 1 - ))) - for(var/network in GLOB.using_map.secondary_networks) - if(can_access_network(user, get_camera_access(network), 0)) - all_networks.Add(list(list( - "tag" = network, - "has_access" = 1 - ))) - - all_networks = modify_networks_list(all_networks) - - data["networks"] = all_networks - - if(current_network) - data["cameras"] = camera_repository.cameras_in_network(current_network) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "mod_sec_camera.tmpl", "Camera Monitoring", 900, 800) - // ui.auto_update_layout = 1 // Disabled as with suit sensors monitor - breaks the UI map. Re-enable once it's fixed somehow. - - ui.add_template("mapContent", "sec_camera_map_content.tmpl") - ui.add_template("mapHeader", "mod_sec_camera_map_header.tmpl") - ui.set_initial_data(data) - ui.open() - -// Intended to be overriden by subtypes to manually add non-station networks to the list. -/datum/nano_module/camera_monitor/proc/modify_networks_list(var/list/networks) - return networks - -/datum/nano_module/camera_monitor/proc/can_access_network(var/mob/user, var/network_access, var/station_network = 0) - // No access passed, or 0 which is considered no access requirement. Allow it. - if(!network_access) - return 1 - - if(station_network) - return check_access(user, network_access) || check_access(user, access_security) || check_access(user, access_heads) - else - return check_access(user, network_access) - -/datum/nano_module/camera_monitor/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["switch_camera"]) - var/obj/machinery/camera/C = locate(href_list["switch_camera"]) in cameranet.cameras - if(!C) - return - if(!(current_network in C.network)) - return - - switch_to_camera(usr, C) - return 1 - - else if(href_list["switch_network"]) - // Either security access, or access to the specific camera network's department is required in order to access the network. - if(can_access_network(usr, get_camera_access(href_list["switch_network"]), (href_list["switch_network"] in GLOB.using_map.station_networks))) - current_network = href_list["switch_network"] - else - to_chat(usr, "\The [nano_host()] shows an \"Network Access Denied\" error message.") - return 1 - - else if(href_list["reset"]) - reset_current() - usr.reset_view(current_camera) - return 1 - -/datum/nano_module/camera_monitor/proc/switch_to_camera(var/mob/user, var/obj/machinery/camera/C) - //don't need to check if the camera works for AI because the AI jumps to the camera location and doesn't actually look through cameras. - if(isAI(user)) - var/mob/living/silicon/ai/A = user - // Only allow non-carded AIs to view because the interaction with the eye gets all wonky otherwise. - if(!A.is_in_chassis()) - return 0 - - A.eyeobj.setLoc(get_turf(C)) - A.client.eye = A.eyeobj - return 1 - - set_current(C) - user.machine = nano_host() - user.reset_view(C) - return 1 - -/datum/nano_module/camera_monitor/proc/set_current(var/obj/machinery/camera/C) - if(current_camera == C) - return - - if(current_camera) - reset_current() - - current_camera = C - if(current_camera) - var/mob/living/L = current_camera.loc - if(istype(L)) - L.tracking_initiated() - -/datum/nano_module/camera_monitor/proc/reset_current() - if(current_camera) - var/mob/living/L = current_camera.loc - if(istype(L)) - L.tracking_cancelled() - current_camera = null - -/datum/nano_module/camera_monitor/check_eye(var/mob/user as mob) - if(!current_camera) - return 0 - var/viewflag = current_camera.check_eye(user) - if ( viewflag < 0 ) //camera doesn't work - reset_current() - return viewflag - - // ERT Variant of the program /datum/computer_file/program/camera_monitor/ert filename = "ntcammon" filedesc = "Advanced Camera Monitoring" extended_desc = "This program allows remote access to the camera system. Some camera networks may have additional access requirements. This version has an integrated database with additional encrypted keys." size = 14 - nanomodule_path = /datum/nano_module/camera_monitor/ert + tguimodule_path = /datum/tgui_module/camera/ntos/ert available_on_ntnet = 0 - -/datum/nano_module/camera_monitor/ert - name = "Advanced Camera Monitoring Program" - //available_to_ai = FALSE - -// The ERT variant has access to ERT and crescent cams, but still checks for accesses. ERT members should be able to use it. -/datum/nano_module/camera_monitor/ert/modify_networks_list(var/list/networks) - ..() - networks.Add(list(list("tag" = NETWORK_ERT, "has_access" = 1))) - networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1))) - return networks - -/datum/nano_module/camera_monitor/apply_visual(mob/M) - if(current_camera) - current_camera.apply_visual(M) - else - remove_visual(M) - -/datum/nano_module/camera_monitor/remove_visual(mob/M) - if(current_camera) - current_camera.remove_visual(M) diff --git a/code/modules/modular_computers/file_system/programs/medical/suit_sensors.dm b/code/modules/modular_computers/file_system/programs/medical/suit_sensors.dm index b96cba454ae..9b94707eb22 100644 --- a/code/modules/modular_computers/file_system/programs/medical/suit_sensors.dm +++ b/code/modules/modular_computers/file_system/programs/medical/suit_sensors.dm @@ -1,7 +1,7 @@ /datum/computer_file/program/suit_sensors filename = "sensormonitor" filedesc = "Suit Sensors Monitoring" - nanomodule_path = /datum/nano_module/crew_monitor + tguimodule_path = /datum/tgui_module/crew_monitor/ntos program_icon_state = "crew" program_key_state = "med_key" program_menu_icon = "heart" @@ -10,66 +10,3 @@ requires_ntnet = 1 network_destination = "crew lifesigns monitoring system" size = 11 - - - - - -/datum/nano_module/crew_monitor - name = "Crew monitor" - -/datum/nano_module/crew_monitor/Topic(href, href_list) - if(..()) return 1 - var/turf/T = get_turf(nano_host()) // TODO: Allow setting any GLOB.using_map.contact_levels from the interface. - if (!T || !(T.z in GLOB.using_map.player_levels)) - to_chat(usr, "Unable to establish a connection: You're too far away from the station!") - return 0 - if(href_list["track"]) - if(isAI(usr)) - var/mob/living/silicon/ai/AI = usr - var/mob/living/carbon/human/H = locate(href_list["track"]) in mob_list - if(hassensorlevel(H, SUIT_SENSOR_TRACKING)) - AI.ai_actual_track(H) - return 1 - -/datum/nano_module/crew_monitor/nano_ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - var/list/data = host.initial_data() - var/turf/T = get_turf(nano_host()) - - data["isAI"] = isAI(user) - data["map_levels"] = GLOB.using_map.get_map_levels(T.z, FALSE) - data["crewmembers"] = list() - for(var/z in data["map_levels"]) // VOREStation Edit - data["crewmembers"] += crew_repository.health_data(z) - - if(!data["map_levels"].len) - to_chat(user, "The crew monitor doesn't seem like it'll work here.") - if(ui) // VOREStation Addition - ui.close() // VOREStation Addition - return - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800, state = state) - - // adding a template with the key "mapContent" enables the map ui functionality - ui.add_template("mapContent", "crew_monitor_map_content.tmpl") - // adding a template with the key "mapHeader" replaces the map header content - ui.add_template("mapHeader", "crew_monitor_map_header.tmpl") - if(!(ui.map_z_level in data["map_levels"])) - ui.set_map_z_level(data["map_levels"][1]) - - ui.set_initial_data(data) - ui.open() - - // should make the UI auto-update; doesn't seem to? - ui.set_auto_update(1) - -/*/datum/nano_module/crew_monitor/proc/scan() - for(var/mob/living/carbon/human/H in mob_list) - if(istype(H.w_uniform, /obj/item/clothing/under)) - var/obj/item/clothing/under/C = H.w_uniform - if (C.has_sensor) - tracked |= C - return 1 -*/ diff --git a/code/modules/nifsoft/software/06_screens.dm b/code/modules/nifsoft/software/06_screens.dm index 787430008f1..487745f9efd 100644 --- a/code/modules/nifsoft/software/06_screens.dm +++ b/code/modules/nifsoft/software/06_screens.dm @@ -5,23 +5,23 @@ access = access_medical cost = 625 p_drain = 0.025 - var/datum/nano_module/crew_monitor/arscreen + var/datum/tgui_module/crew_monitor/nif/arscreen - New() - ..() - arscreen = new(nif) +/datum/nifsoft/crewmonitor/New() + ..() + arscreen = new(nif) - Destroy() +/datum/nifsoft/crewmonitor/Destroy() QDEL_NULL(arscreen) return ..() - activate() - if((. = ..())) - arscreen.nano_ui_interact(nif.human,"main",null,1,nif_state) - return TRUE +/datum/nifsoft/crewmonitor/activate() + if((. = ..())) + arscreen.ui_interact(nif.human) + return TRUE - stat_text() - return "Show Monitor" +/datum/nifsoft/crewmonitor/stat_text() + return "Show Monitor" /datum/nifsoft/alarmmonitor name = "Alarm Monitor" @@ -32,18 +32,18 @@ p_drain = 0.025 var/datum/nano_module/alarm_monitor/engineering/arscreen - New() - ..() - arscreen = new(nif) +/datum/nifsoft/alarmmonitor/New() + ..() + arscreen = new(nif) - Destroy() +/datum/nifsoft/alarmmonitor/Destroy() QDEL_NULL(arscreen) return ..() - activate() - if((. = ..())) - arscreen.nano_ui_interact(nif.human,"main",null,1,nif_state) - return TRUE +/datum/nifsoft/alarmmonitor/activate() + if((. = ..())) + arscreen.nano_ui_interact(nif.human,"main",null,1,nif_state) + return TRUE - stat_text() - return "Show Monitor" +/datum/nifsoft/alarmmonitor/stat_text() + return "Show Monitor" diff --git a/code/modules/tgui/modules/_base.dm b/code/modules/tgui/modules/_base.dm new file mode 100644 index 00000000000..c85ba2751ef --- /dev/null +++ b/code/modules/tgui/modules/_base.dm @@ -0,0 +1,46 @@ +/* +TGUI MODULES + +This allows for datum-based TGUIs that can be hooked into objects. +This is useful for things such as the power monitor, which needs to exist on a physical console in the world, but also as a virtual device the AI can use + +Code is pretty much ripped verbatim from nano modules, but with un-needed stuff removed +*/ +/datum/tgui_module + var/name + var/datum/host + var/list/using_access + + var/tgui_id + +/datum/tgui_module/New(var/host) + src.host = host + +/datum/tgui_module/ui_host() + return host ? host : src + +/datum/tgui_module/ui_close(mob/user) + if(host) + host.ui_close(user) + +/datum/tgui_module/proc/check_access(mob/user, access) + if(!access) + return 1 + + if(using_access) + if(access in using_access) + return 1 + else + return 0 + + if(!istype(user)) + return 0 + + var/obj/item/card/id/I = user.GetIdCard() + if(!I) + return 0 + + if(access in I.access) + return 1 + + return 0 \ No newline at end of file diff --git a/code/modules/tgui/modules/camera.dm b/code/modules/tgui/modules/camera.dm new file mode 100644 index 00000000000..72521648513 --- /dev/null +++ b/code/modules/tgui/modules/camera.dm @@ -0,0 +1,295 @@ +/datum/tgui_module/camera + name = "Security Cameras" + tgui_id = "CameraConsole" + + var/access_based = FALSE + var/list/network = list() + var/list/additional_networks = list() + + var/obj/machinery/camera/active_camera + var/list/concurrent_users = list() + + // Stuff needed to render the map + var/map_name + var/const/default_map_size = 15 + var/obj/screen/map_view/cam_screen + /// All the plane masters that need to be applied. + var/list/cam_plane_masters + var/obj/screen/background/cam_background + var/obj/screen/background/cam_foreground + var/obj/screen/skybox/local_skybox + // Needed for moving camera support + var/camera_diff_x = -1 + var/camera_diff_y = -1 + var/camera_diff_z = -1 + +/datum/tgui_module/camera/New(host, list/network_computer) + . = ..() + if(!LAZYLEN(network_computer)) + access_based = TRUE + else + network = network_computer + map_name = "camera_console_[REF(src)]_map" + // 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(/obj/screen/plane_master)) + var/obj/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 + + local_skybox = new() + local_skybox.assigned_map = map_name + local_skybox.del_on_map_removal = FALSE + local_skybox.screen_loc = "[map_name]:CENTER,CENTER" + cam_plane_masters += local_skybox + + cam_background = new + cam_background.assigned_map = map_name + cam_background.del_on_map_removal = FALSE + + var/mutable_appearance/scanlines = mutable_appearance('icons/effects/static.dmi', "scanlines") + scanlines.alpha = 50 + scanlines.layer = FULLSCREEN_LAYER + + var/mutable_appearance/noise = mutable_appearance('icons/effects/static.dmi', "1 light") + noise.layer = FULLSCREEN_LAYER + + cam_foreground = new + cam_foreground.assigned_map = map_name + cam_foreground.del_on_map_removal = FALSE + cam_foreground.plane = PLANE_FULLSCREEN + cam_foreground.add_overlay(scanlines) + cam_foreground.add_overlay(noise) + +/datum/tgui_module/camera/Destroy() + qdel(cam_screen) + QDEL_LIST(cam_plane_masters) + qdel(cam_background) + qdel(cam_foreground) + return ..() + +/datum/tgui_module/camera/ui_interact(mob/user, datum/tgui/ui = null) + // Update UI + ui = SStgui.try_update_ui(user, src, ui) + // Show static if can't use the camera + if(!active_camera?.can_use()) + show_camera_static() + 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(ui_host(), 'sound/machines/terminal_on.ogg', 25, FALSE) + // 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) + user.client.register_map_obj(cam_foreground) + // Open UI + ui = new(user, src, tgui_id, name) + ui.open() + +/datum/tgui_module/camera/ui_data() + var/list/data = list() + data["activeCamera"] = null + if(active_camera) + differential_check() + data["activeCamera"] = list( + name = active_camera.c_tag, + status = active_camera.status, + ) + return data + +/datum/tgui_module/camera/ui_static_data(mob/user) + var/list/data = list() + data["mapRef"] = map_name + var/list/cameras = get_available_cameras(user) + data["cameras"] = list() + data["allNetworks"] = list() + for(var/i in cameras) + var/obj/machinery/camera/C = cameras[i] + data["cameras"] += list(list( + name = C.c_tag, + networks = C.network + )) + data["allNetworks"] |= C.network + return data + +/datum/tgui_module/camera/ui_act(action, params) + if(..()) + return + + if(action == "switch_camera") + var/c_tag = params["name"] + var/list/cameras = get_available_cameras(usr) + var/obj/machinery/camera/C = cameras["[ckey(c_tag)]"] + active_camera = C + playsound(ui_host(), get_sfx("terminal_type"), 25, FALSE) + + reload_cameraview() + + return TRUE + +/datum/tgui_module/camera/proc/differential_check() + var/turf/T = get_turf(active_camera) + if(T) + var/new_x = T.x + var/new_y = T.y + var/new_z = T.z + if((new_x != camera_diff_x) || (new_y != camera_diff_y) || (new_z != camera_diff_z)) + reload_cameraview() + +/datum/tgui_module/camera/proc/reload_cameraview() + // Show static if can't use the camera + if(!active_camera?.can_use()) + show_camera_static() + return TRUE + + var/turf/camTurf = get_turf(active_camera) + + camera_diff_x = camTurf.x + camera_diff_y = camTurf.y + camera_diff_z = camTurf.z + + var/list/visible_turfs = list() + for(var/turf/T in (active_camera.isXRay() \ + ? range(active_camera.view_range, camTurf) \ + : view(active_camera.view_range, camTurf))) + visible_turfs += T + + 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) + + cam_foreground.fill_rect(1, 1, size_x, size_y) + + local_skybox.cut_overlays() + local_skybox.add_overlay(SSskybox.get_skybox(get_z(camTurf))) + local_skybox.scale_to_view(size_x) + local_skybox.set_position("CENTER", "CENTER", (world.maxx>>1) - camTurf.x, (world.maxy>>1) - camTurf.y) + +// Returns the list of cameras accessible from this computer +// This proc operates in two distinct ways depending on the context in which the module is created. +// It can either return a list of cameras sharing the same the internal `network` variable, or +// It can scan all station networks and determine what cameras to show based on the access of the user. +/datum/tgui_module/camera/proc/get_available_cameras(mob/user) + var/list/all_networks = list() + // Access Based + if(access_based) + for(var/network in GLOB.using_map.station_networks) + if(can_access_network(user, get_camera_access(network), 1)) + all_networks.Add(network) + for(var/network in GLOB.using_map.secondary_networks) + if(can_access_network(user, get_camera_access(network), 0)) + all_networks.Add(network) + // Network Based + else + all_networks = network.Copy() + + if(additional_networks) + all_networks += additional_networks + + var/list/D = list() + for(var/obj/machinery/camera/C in cameranet.cameras) + if(!C.network) + stack_trace("Camera in a cameranet has no camera network") + continue + if(!(islist(C.network))) + stack_trace("Camera in a cameranet has a non-list camera network") + continue + var/list/tempnetwork = C.network & all_networks + if(tempnetwork.len) + D["[ckey(C.c_tag)]"] = C + return D + +/datum/tgui_module/camera/proc/can_access_network(mob/user, network_access, station_network = 0) + // No access passed, or 0 which is considered no access requirement. Allow it. + if(!network_access) + return 1 + + if(station_network) + return check_access(user, network_access) || check_access(user, access_security) || check_access(user, access_heads) + else + return check_access(user, network_access) + +/datum/tgui_module/camera/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) + local_skybox.cut_overlays() + +/datum/tgui_module/camera/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 + if(user.client) + user.client.clear_map(map_name) + // Turn off the console + if(length(concurrent_users) == 0 && is_living) + active_camera = null + playsound(ui_host(), 'sound/machines/terminal_off.ogg', 25, FALSE) + +// NTOS Version +// Please note, this isn't a very good replacement for converting modular computers 100% to TGUI +// If/when that is done, just move all the PC_ specific data and stuff to the modular computers themselves +// instead of copying this approach here. +/datum/tgui_module/camera/ntos + tgui_id = "NtosCameraConsole" + +/datum/tgui_module/camera/ntos/ui_state() + return GLOB.ntos_state + +/datum/tgui_module/camera/ntos/ui_static_data() + . = ..() + + var/datum/computer_file/program/host = ui_host() + if(istype(host) && host.computer) + . += host.computer.get_header_data() + +/datum/tgui_module/camera/ntos/ui_act(action, params) + if(..()) + return + + var/datum/computer_file/program/host = ui_host() + if(istype(host) && host.computer) + if(action == "PC_exit") + host.computer.kill_program() + return TRUE + if(action == "PC_shutdown") + host.computer.shutdown_computer() + return TRUE + if(action == "PC_minimize") + host.computer.minimize_program(usr) + return TRUE + +// ERT Version provides some additional networks. +/datum/tgui_module/camera/ntos/ert + additional_networks = list(NETWORK_ERT, NETWORK_CRESCENT) + +// Hacked version also provides some additional networks, +// but we want it to show *all* the networks 24/7, so we convert it into a non-access-based UI. +/datum/tgui_module/camera/ntos/hacked + additional_networks = list(NETWORK_MERCENARY, NETWORK_ERT, NETWORK_CRESCENT) + +/datum/tgui_module/camera/ntos/hacked/New(host) + . = ..(host, GLOB.using_map.station_networks.Copy()) diff --git a/code/modules/tgui/modules/crew_monitor.dm b/code/modules/tgui/modules/crew_monitor.dm new file mode 100644 index 00000000000..f9684b7f70a --- /dev/null +++ b/code/modules/tgui/modules/crew_monitor.dm @@ -0,0 +1,103 @@ +/datum/tgui_module/crew_monitor + name = "Crew monitor" + tgui_id = "CrewMonitor" + +/datum/tgui_module/crew_monitor/ui_act(action, params, datum/tgui/ui) + if(..()) + return TRUE + + var/turf/T = get_turf(usr) + if(!T || !(T.z in GLOB.using_map.player_levels)) + to_chat(usr, "Unable to establish a connection: You're too far away from the station!") + return FALSE + + switch(action) + if("track") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + var/mob/living/carbon/human/H = locate(params["track"]) in mob_list + if(hassensorlevel(H, SUIT_SENSOR_TRACKING)) + AI.ai_actual_track(H) + return TRUE + if("setZLevel") + ui.set_map_z_level(params["mapZLevel"]) + SStgui.update_uis(src) + +/datum/tgui_module/crew_monitor/ui_interact(mob/user, datum/tgui/ui = null) + var/z = get_z(user) + var/list/map_levels = GLOB.using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE) + + if(!map_levels.len) + to_chat(user, "The crew monitor doesn't seem like it'll work here.") + if(ui) + ui.close() + return null + + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, tgui_id, name) + ui.autoupdate = TRUE + ui.open() + + +/datum/tgui_module/crew_monitor/ui_data(mob/user, ui_key = "main", datum/tgui_state/state = GLOB.default_state) + var/data[0] + + data["isAI"] = isAI(user) + + var/z = get_z(user) + var/list/map_levels = uniqueList(GLOB.using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE)) + data["map_levels"] = map_levels + + data["crewmembers"] = list() + for(var/zlevel in map_levels) + data["crewmembers"] += crew_repository.health_data(zlevel) + + return data + +/datum/tgui_module/crew_monitor/ntos + tgui_id = "NtosCrewMonitor" + +/datum/tgui_module/crew_monitor/ntos/ui_state(mob/user) + return GLOB.ntos_state + +/datum/tgui_module/crew_monitor/ntos/ui_static_data() + . = ..() + + var/datum/computer_file/program/host = ui_host() + if(istype(host) && host.computer) + . += host.computer.get_header_data() + +/datum/tgui_module/crew_monitor/ntos/ui_act(action, params) + if(..()) + return + + var/datum/computer_file/program/host = ui_host() + if(istype(host) && host.computer) + if(action == "PC_exit") + host.computer.kill_program() + return TRUE + if(action == "PC_shutdown") + host.computer.shutdown_computer() + return TRUE + if(action == "PC_minimize") + host.computer.minimize_program(usr) + return TRUE + +// Subtype for glasses_state +/datum/tgui_module/crew_monitor/glasses + +/datum/tgui_module/crew_monitor/glasses/ui_state(mob/user) + return GLOB.ui_glasses_state + +// Subtype for self_state +/datum/tgui_module/crew_monitor/robot + +/datum/tgui_module/crew_monitor/robot/ui_state(mob/user) + return GLOB.self_state + +// Subtype for nif_state +/datum/tgui_module/crew_monitor/nif + +/datum/tgui_module/crew_monitor/nif/ui_state(mob/user) + return GLOB.ui_nif_state diff --git a/code/modules/tgui/states/inventory.dm b/code/modules/tgui/states/inventory.dm index dc5dd0d57e6..56afbd2addd 100644 --- a/code/modules/tgui/states/inventory.dm +++ b/code/modules/tgui/states/inventory.dm @@ -14,3 +14,33 @@ GLOBAL_DATUM_INIT(inventory_state, /datum/ui_state/inventory_state, new) if(!(src_object in user)) return UI_CLOSE return user.shared_ui_interaction(src_object) + +GLOBAL_DATUM_INIT(ui_glasses_state, /datum/ui_state/glasses_state, new) + +/datum/ui_state/glasses_state/can_use_topic(var/src_object, var/mob/user) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.glasses == src_object) + return user.shared_ui_interaction() + + return STATUS_CLOSE + +GLOBAL_DATUM_INIT(ui_nif_state, /datum/ui_state/nif_state, new) + +/datum/ui_state/nif_state/can_use_topic(var/src_object, var/mob/user) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.nif && H.nif.stat == NIF_WORKING && src_object == H.nif) + return user.shared_ui_interaction() + + return STATUS_CLOSE + +GLOBAL_DATUM_INIT(ui_commlink_state, /datum/ui_state/commlink_state, new) + +/datum/ui_state/commlink_state/can_use_topic(var/src_object, var/mob/user) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.nif && H.nif.stat == NIF_WORKING && H.nif.comm == src_object) + return user.shared_ui_interaction() + + return STATUS_CLOSE diff --git a/code/modules/tgui/states/ntos.dm b/code/modules/tgui/states/ntos.dm new file mode 100644 index 00000000000..dd29544225e --- /dev/null +++ b/code/modules/tgui/states/ntos.dm @@ -0,0 +1,15 @@ +/** + * tgui state: ntos_state + * + * Checks a number of things -- mostly physical distance for humans and view for robots. + * This is basically the same as default, except instead of src_object, it uses the computer + * it's attached to. + **/ + +GLOBAL_DATUM_INIT(ntos_state, /datum/ui_state/ntos, new) + +/datum/ui_state/ntos/can_use_topic(src_object, mob/user) + var/datum/computer_file/program/P = src_object + if(!istype(P) || !P.computer) + return FALSE + return user.default_can_use_ui_topic(P.computer) // Call the individual mob-overridden procs. \ No newline at end of file diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index 7322c4179bb..9f0eae08080 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -33,6 +33,8 @@ var/status = UI_INTERACTIVE /// Topic state used to determine status/interactability. var/datum/ui_state/state = null + // The map z-level to display. + var/map_z_level = 1 /** * public @@ -268,6 +270,15 @@ if(needs_update) window.send_message("update", get_payload()) + +/** + Sets the current map z level of the tgui window (so we know which Z we need to be interacting with.) + */ + +/datum/tgui/proc/set_map_z_level(nz) + map_z_level = nz + + /** * private * diff --git a/icons/mob/map_backgrounds.dmi b/icons/mob/map_backgrounds.dmi new file mode 100644 index 0000000000000000000000000000000000000000..dc6e3e46b16633f940c69c9a3c85a426f6bd34ce GIT binary patch literal 555 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 literal 0 HcmV?d00001 diff --git a/sound/machines/terminal_button01.ogg b/sound/machines/terminal_button01.ogg new file mode 100644 index 0000000000000000000000000000000000000000..88b10c88912b3f7f602485a274d60a8850ef960d GIT binary patch literal 6933 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 gwCp{J+xLD}1gEa5?xAzQKy#!iSzi#>Z} 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%0AHBmC(5?|)%+F@K=9JAL-fQ4dpjyAsVEA3RF?0T> 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 literal 0 HcmV?d00001 diff --git a/sound/machines/terminal_button05.ogg b/sound/machines/terminal_button05.ogg new file mode 100644 index 0000000000000000000000000000000000000000..e660ecf154c78199bd8393147fa694645cd5fb48 GIT binary patch literal 6551 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 LZtr^}kCy%)6e<-G literal 0 HcmV?d00001 diff --git a/sound/machines/terminal_button06.ogg b/sound/machines/terminal_button06.ogg new file mode 100644 index 0000000000000000000000000000000000000000..bef143ac521fc76a939f15314738746cb02db847 GIT binary patch literal 6750 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 A7XSbN literal 0 HcmV?d00001 diff --git a/sound/machines/terminal_button08.ogg b/sound/machines/terminal_button08.ogg new file mode 100644 index 0000000000000000000000000000000000000000..fc0131f5f4ed83fae9af53ff6bf413bec9f8fcb2 GIT binary patch literal 7346 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 literal 0 HcmV?d00001 diff --git a/sound/machines/terminal_insert_disc.ogg b/sound/machines/terminal_insert_disc.ogg new file mode 100644 index 0000000000000000000000000000000000000000..dd226c1ebdea6e5634fa4066971fa1ad0c883924 GIT binary patch literal 15642 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 MGo`@I)1m;)b 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 z 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 literal 0 HcmV?d00001 diff --git a/sound/machines/terminal_prompt.ogg b/sound/machines/terminal_prompt.ogg new file mode 100644 index 0000000000000000000000000000000000000000..74de1c9a2986d1e1e15127c552ea039cfa4a5cc2 GIT binary patch literal 7099 zcmai22|UzY_y3J`tl83tYKRzHMnaHtjQC`z7NuZDND9w8M0*`vL>N;%98B+ zzEzY$Xw{;K|DDnEywCsr|3B~h``o#o`@84fbM86kd(Q9NF>-b`g&3gUPuby}!S_Wo zdDwnfptqmBD~UD*(=PwLFkkuNJRy-qJpBr5u}unrY6dkqg@njJP3Ux@fZjcUo_ivFL*hoC zWli`oLq~K>%?t_P39z*YBu)edOaum7rA63047Pe0VKW(F`#s`3BJy`z51#!_Yjo9- zFevvRHgz7AFSa-T6*iwSJhGeta-^9A$(AIBN-EGRa&oJ5&8%}NtMlxsmhGwLq%Q$J zWul!1%5}{s`ajLdDwX)(o4QMZN4I1z#4eD5kHItNp*r`H~~ySv&esbuF~-W z6cN4clr!(E_*=)h+hhx_JJ~rCizr#lz`0e~8 zqW$(YWN z0!~FbCTOq-(Ssy1&956(45H$nj{7J+z`JkgA8p{1hzXwrXhVu}rbko>W(12sPpex2 zGY=wcCj(|Df@ddg*zJk@cVPV;IS>e%aC%Hq?BmcKSz%{1*>)WKSLFB#bR>#&C5r1; ziyIEh_I*||T2mV0*D+BtG~I1Gv^!u#kZ7uGJAxsO5Qt-e#Hl)>&4Xa8y59k_6E?FG z0sn{`T8M~Y+Jcb10bk5fm5HJM@;Z?V|dIMUXEa<`kx~PP{))EN0fkJQy@qPf(`;Fhx5evC1`r7 zTEfu_;>>wimb|Bk@M4}LoLDX~{{#(5)rU#gR?f9Kywq-OgRmPCN8^!PPm0d!y-|UK zw8sRQKoA+-iGGUk>(}eb)$T{L-KKP6C8^27dMLS6#1WK45ud|+R>81dS0M$VA9K5q z&mp=3Y=T(9k0Wm|VK+=&0D|l}@$9Gw3ceq;kbv(-zY)RXu*F%X{aEz=-cS@^eOG{?S@WmoF%lr~g! zS65|LmaWu%;AoXyY49nntSqZurBNFyR@!}68WgS+p?ZqSmK#bM8oX8-e0%FWMG8un z8>M@mRCQN>SZO$16Ci3r2zXAhowopbc-mdaw)q}W?RmVZVxt={7+%K?c#G77ZTG!| z!Cd>AjM{mXc&c*-IB97`W@*_^M%7AdYx`HFvq4PW2fcs3l@5ZtDZvh2&IoUdH0&Ku&*x>J0&l8nl zAgjP27STlkQy%Fyq(2XS8ChtCW)UTw!L^A{jB#$Flu_w+q*=UPXI3&F&ILso#0wDYTt!L}zBenG#wsixr-!Ob!Wn>5;c)jN@YWva@hrRt2Am48O2T=_ zwOiX5)CTZabI?y!QETq*R?!ZGOHdK|xO=sN?q2AHy*Sqjn(&e~L7R9W+|(UYH10+t z*m$arXOM6eW+fZ*Wycr4@chrcwpcav)$x38cHm%f*h1cWb4TgPE3!}fqx5 zu<@ubN_7K-418?u!ZgVP^KI0+oF+pbd?83T>%W?VtV3pm)X8kbTv`gDg{?*uzF*Ik z$FCPF&8FFll`Qcy&_tmKy&7)0zya76LE_ew7INshGrHJZcX@Z za18LR>cxVNM-vc0y_XjTIx1zDM!@6VBEcMr>Q5t3@azyI?E@;JDicT2wZvSIGZ~rYR4Vb~1h#84rx7UDt4IJ14@@8rfK|J-7OtYr(!ElYI&NQ% znE)WJUC4090fKv9Jp?^tW`(L4g>{rA5p2>*j&vo+NMOb|bfkcN40wHfk1VbJhyw)h+71ZVMG;z;MT-AdVe+pL+yA3P38=Gp&B52Y9U%s4z&&|dIINTeKnV&3-~%F>VvS2D;qlTE)KpsP7`4X90p6?<)N#BUka7%8tr?|> zn$*xmQOB)g6CK3;pv`yNVqYH=eAU+WeQh5K#&>Y>@qM+E;q+6SIF~9>~dVr;R${`_VT>=80_hLL|vga#25ul6)?rSFJ;-snHb%6z@b~qDdsq- z#B0NT<+Xvm;6{mrLkc{iN3N>F1Q4A-P&g9`%B^Z1M4x41dd;WE&dJ^pP8xP)gm}U` zITNESIr;cYujbnygDlVf(aB2Yym6x@mSah=nc4PP05TlOBpTHQ6G$M3@p}cm;xc;J z!gfrD%Dr;|hC%xwD2WRxCYFJX=f1fsfhUnSi7%O-0^kclb1?EQh%C+=6&2+aU(h)`O6s|pi+OuryAE&sk!(=Ny~F`61*HzW_sV=zbLWaQ;!Wl>5P zX(eSPS&Z^w8F~4`3i2u{!yS+AKdNae%vj~=c`TfB+$MxANW@>lSdiQLJ?qnK1EH;?9=sJpJ%?lD1e|6DJ9NU3NGT7}fMxIDV6#i|u-nIGhm>h4y1jSM`0Up4gZV|Noe zC?vJ@lI^bxS}a{%O?RNp^>f>j>v}Qbe5<#<*WG0u>IhQUXbM<%3p#e^@k(`~*4?!> z*@MNKcO6cy-;;N1ogoSOFer)I{VI315FZn1Gi;e)O@xUwx{2hRn0ToWi3s8fIXr*y z!;Ix~rBKNi4^);v`{ak$d&@!g{D-YW+YmTrGOFFwbspFq9~hdfZ* zvlIF^D~}qf=N8pm3}=PTs@PSg)K8qvZH&dmrYhNMNi!z(@y}n*Q9NQG0Tv5qzm&tk zuqLK=-tG%yYM%{r7N02E;QQuTHr43tYx1DMzXwM?EaWJ+J#s)^7%`;H;595kO=ni+ zdzk!VV?HTPbVQyNwrCv@Kl~Z-M|CRvBy+gNcB_RI=N(^#KGAEOf67eF&m*Ig96g`G z7HyPkzFm($nsRfwdCM2dB7|;UeH^f%)*?UrYiy#g7qL&rA>zbZP9?m<(3kJF#|QaC zqO8HTseDG8tGAVvF1D#a;X2zR#YwuC+EU2AvDm7+z@b6JnPka@H+iY8X=)MI@5_AD ztuUG%zrN1y=KFDDO0`agEnIIq*#cK!@5{&I_h70O$-FD%(f!8i(>BmUjw|1_%To-i zHhV($_PxunZlZA){VWi#KuCu^BLk2*hXec6n7^O~NC^@M~alW@c6 zo<#o%mq7g*V(4q*3vY6c!D8BsJ{%t(La_F44u9ElT-VfR%VaDY{4S&7cgQ)eZh6^F zT6N`KvB9LuaTvv9d)`V$HZ-3tDEj9Hl?llhgj~?^tMTxE@qk#iw=ImYR?(|@EZ40( z?N8FX#g6RdEwL-A+Xrs?>Ar5@_pxS6I0@%s+e}N(*k|fxKpj^#w#hsRGvWL^6gXsT zrU?~VZMVL_bUHgRMA~b8o$BSBQ#ih4YACzCIl}m`B7)OyI4IzK^Oc{McJG@NT2K7w zop3|U|B-8G6}I({?oft)m#+n5CdRN6mYzS~J1JiFOetE_OtX_nLMgb$RUD6^Y}qtr z@{-;}^s_;6dfOv}S)1u?wzOyucZM&W3hT3*${W6qF*n-I#YBXb9IkjD{QB&-P-RmE zWDFt;EYEaL?!5@KARTwnjb>b#u)|y*@E}23!e(0KChwb081eYqR@K1DtwOJSavy)C z-z#9=E#3>tKPu`X+X~{Vwtanz=x~Do8wj~c0>TS>W?do}&LLTXPSm!gR3;X!~{r#^h zLpcW;sFyh^a3wjKt7C@c)2DFXZ76SGZj zMSc6KbX)dR^z4gmXzm18>>WgwiJj`x_gxEzvR#BvyI+rwVMTm6!a9o|dH?C>nvv+r zl(ddxB#K{nrtq$I@l}qx7uTiJ`x?$%5>D_~`IRbPwz+Fk`=gsL z!}HOyLbIAcZk1m0+6z)(r1p)E+v~NLe~u}W$UoGs-)emutdf4HIEsv`wf=SVDqQ}s zihB?&!JCg)6~-~`%WGh57ph$Gr8^{q#l^BGY|!PZrv$7~%KX@eoW*O_db-Uzv)W;M zf39&P@{q1ZUtvAQ<#=XK)gQ#pu$!9El#YSz?L$+ZtWS3Vecv8q`Le^3yF`sU40%(PI+CLFtU+m@5Pm~7v1c?db#+QzL?hYj(a(E>RsNz zmfnn0&v3N=tI9{)ZRNcod7CK;jhRNW>QfxMk3n1CYIbR^b0fWv6J9>B&p#J(B5t5+ z{~?!YrG;{0F{vC%sAvkC-ICnSbr1?WH*nUw>&@khqn_IANf#WlH~qwY%ya8ixzDOF zq+hAEGUNW~{k0~Q13IbfIO>OfeCKl4Zl`$;3*MO|=Clqu^TpKzg3Tvwk2-(RWhV>r z?e68eQ~!BSbD4U9o|S%CJBI&^{D}o=X7vZx@5lD7P4ur>H>#=M(}h;{*XAlxxxNIQ z(z?!)mTJD=wb*V?Gvmp~-oBWpv2y5-Wl7kt7ncqXo*MirVJM!J{u-Oh&l!WxynH!e z`Q`Rj`V4;I(20@{PT%576{NA?kL$wWSE1h5Quw87>X6CWuMd5mX|q|C4Er1*1~INF zc)vC}8bx(|eL>b@bc5BdnOXW&KtMaWC~iRf*M;*OtKST#nWF9~l)b(*dbI4pa)*se zLfp@7o;TS!4+V6;X{a$l!pM*FUs}zZ8JX1CUq0(7q6~HV9Hr_&*@WKWk7|xA2pp55xnpMM<5XUR}z zJ__s7zL7D;GP0PstMvxT`2Riz?S5xYbYxr(@+~D@`sS=`ma+s`>tN29}FPRJ- z3Otv6k*K}LB`&3LG3v8n;dzafgg^%9g-%T@5BcbXn(1spuXX)E>$0%}lOUv5HhD<= zbe}+O&w=?d!};w!pAUKltgr4qxd92}8O!lN$N|EPmAWPWA5N=Z-qOJ+ll@BQb8*`u@6uk}^3aGQ`tw zIk}SJtBm_EiI<2lD?2~G;_I{AEXHw-F;{5s5Bu@q1$`Y2l90MiH|h$j;nUVu&sQTK zL|oZf-!`zGJ3k{e1D{;MN+SOX}w5qP!$h=aYReh?@_| z-dy}k-ZA;F4|!Ol*&@mX1)%18WAEN)fBlr^xBb<^J)>3j8p-_Kry#__IS3jEXbBFn z>}HA`F19(?A%SIXlvg)2Df)IHre=@osUSrRCi%<-hnHk&v6l}d_O5RghqUL{6sDPR zH8Ec)BxVRwo4d}CGy85~Ogl=R$jzN&QrrAEd+^GizFDQrb#WU%E|M6%w3=A{2gXZ4 AB>(^b literal 0 HcmV?d00001 diff --git a/sound/machines/terminal_prompt_confirm.ogg b/sound/machines/terminal_prompt_confirm.ogg new file mode 100644 index 0000000000000000000000000000000000000000..897fec28e9aa41807d9bb0dd9f60a79065e88506 GIT binary patch literal 6773 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 KG5M15g!n&MUv+-~ literal 0 HcmV?d00001 diff --git a/tgui/docs/migration-to-v4-from-v3.md b/tgui/docs/migration-to-v4-from-v3.md index 6f047a6cc7e..6e019c148c3 100644 --- a/tgui/docs/migration-to-v4-from-v3.md +++ b/tgui/docs/migration-to-v4-from-v3.md @@ -14,7 +14,7 @@ - `code/__HELPERS/_logging.dm` If you have a dual nano/tgui setup, then make sure to rename all ui procs -on `/datum`, such as `ui_interact` to `tgui_interact`, to avoid namespace +on `/datum`, such as `ui_interact` to `ui_interact`, to avoid namespace clashing. Usual stuff. ## Update `ui_interact` proc signatures diff --git a/tgui/packages/tgui/interfaces/CrewMonitor.js b/tgui/packages/tgui/interfaces/CrewMonitor.js new file mode 100644 index 00000000000..e5d8dff2ba8 --- /dev/null +++ b/tgui/packages/tgui/interfaces/CrewMonitor.js @@ -0,0 +1,173 @@ +import { sortBy } from 'common/collections'; +import { useBackend, useLocalState } from "../backend"; +import { Window } from "../layouts"; +import { NanoMap, Box, Table, Button, Tabs, Icon, NumberInput } from "../components"; +import { TableCell } from '../components/Table'; +import { COLORS } from '../constants.js'; +import { Fragment } from 'inferno'; + +export const CrewMonitor = () => { + return ( + + + + + + ); +}; + +export const CrewMonitorContent = (props, context) => { + const { act, data, config } = useBackend(context); + const [tabIndex, setTabIndex] = useLocalState(context, 'tabIndex', 0); + const crew = sortBy( + cm => cm.name, + )(data.crewmembers || []); + + const [ + mapZoom, + setZoom, + ] = useLocalState(context, 'number', 1); + let body; + // Data view + if (tabIndex === 0) { + body = ( + + + + Name + + + Status + + + Location + + + {crew.map(cm => ( + + + {cm.name} ({cm.assignment}) + + + + {cm.dead ? 'Deceased' : 'Living'} + + {cm.sensor_type >= 2 ? ( + + {'('} + + {cm.brute} + + {'|'} + + {cm.fire} + + {'|'} + + {cm.tox} + + {'|'} + + {cm.oxy} + + {')'} + + ) : null} + + + {cm.sensor_type === 3 ? ( + data.isAI ? ( +
+ ); + } else if (tabIndex === 1) { + body = ( + + Zoom Level: + setZoom(value)} /> + Z-Level: + {data.map_levels + .sort((a, b) => Number(a) - Number(b)) + .map(level => ( +