Fix ByondUI small map preview (#90277)

## About The Pull Request
This PR should fix the problem of small previews in TGUI once and for
all (I hope).

What was causing it? Because TGUI takes a long time to open, that's why
previews were generated broken (small).

On Byond 515 this problem was not so noticeable as the interfaces opened
faster, but with the release of 516 it became much worse.
Previews were generated inside a window that was not yet open, so the
scale was broken, sometimes the window would open before the preview was
done and sent, usually with small interfaces, or when reopening.

I'm not very good at working with signals, and to tell the truth this is
my second experience with them, so I hope I did it right.

## Why It's Good For The Game
No more small map previews

<details> <summary> Video </summary>


https://github.com/user-attachments/assets/834f3820-cc6a-4f65-90e5-d6bb2a118bcf

</details>

## Changelog

🆑
fix: Fixed small character preview, color matrix preview, mech preview,
and other previews with uses ByondUI map
/🆑

---------

Co-authored-by: Gaxeer <44334376+Gaxeer@users.noreply.github.com>
This commit is contained in:
Aylong
2025-03-28 06:26:48 +02:00
committed by GitHub
parent 617b6762a8
commit 2df73da53e
21 changed files with 111 additions and 79 deletions

View File

@@ -0,0 +1,2 @@
/// Window is fully visible and we can make fragile calls
#define COMSIG_TGUI_WINDOW_VISIBLE "tgui_window_visible"

View File

@@ -19,17 +19,6 @@
/atom/movable/screen/proc/set_position(x, y, px = 0, py = 0) /atom/movable/screen/proc/set_position(x, y, px = 0, py = 0)
if(assigned_map) if(assigned_map)
screen_loc = "[assigned_map]:[x]:[px],[y]:[py]" screen_loc = "[assigned_map]:[x]:[px],[y]:[py]"
ASYNC
// HACK: This fixes the character creator in 516 being small and relying on other byondui things (like cameras) to open in order to update and refresh.
// This also will fix the camera console screen being offset, Gateway, and admin pod panel.
// Adding 100 then setting it back seemed to do the trick!
// Why the fuck does this work? This is some byond bug and I honestly have no fucking clue why this works.
// I don't think plane master will be affected, I hope.
// We're stuck in the belly of this awful machine.
sleep(0.2 SECONDS) // If it's too fast, it has a chance to fail? Idk. This seems like a good number.
screen_loc = "[assigned_map]:[x+100]:[px],[y+100]:[py]"
sleep(0.2 SECONDS)
screen_loc = "[assigned_map]:[x]:[px],[y]:[py]"
else else
screen_loc = "[x]:[px],[y]:[py]" screen_loc = "[x]:[px],[y]:[py]"

View File

@@ -28,8 +28,30 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/map_view)
assigned_map = map_key assigned_map = map_key
set_position(1, 1) set_position(1, 1)
/atom/movable/screen/map_view/proc/display_to(mob/show_to) /**
show_to.client.register_map_obj(src) * Generates and displays the map view to a client
* Make sure you at least try to pass tgui_window if map view needed on UI,
* so it will wait a signal from TGUI, which tells windows is fully visible.
*
* If you use map view not in TGUI, just call it as usualy.
* If UI needs planes, call display_to_client.
*
* * show_to - Mob which needs map view
* * window - Optional. TGUI window which needs map view
*/
/atom/movable/screen/map_view/proc/display_to(mob/show_to, datum/tgui_window/window)
if(window && !window.visible)
RegisterSignal(window, COMSIG_TGUI_WINDOW_VISIBLE, PROC_REF(display_on_ui_visible))
else
display_to_client(show_to.client)
/atom/movable/screen/map_view/proc/display_on_ui_visible(datum/tgui_window/window, client/show_to)
SIGNAL_HANDLER
display_to_client(show_to)
UnregisterSignal(window, COMSIG_TGUI_WINDOW_VISIBLE)
/atom/movable/screen/map_view/proc/display_to_client(client/show_to)
show_to.register_map_obj(src)
// We need to add planesmasters to the popup, otherwise // We need to add planesmasters to the popup, otherwise
// blending fucks up massively. Any planesmaster on the main screen does // blending fucks up massively. Any planesmaster on the main screen does
// NOT apply to map popups. If there's ever a way to make planesmasters // NOT apply to map popups. If there's ever a way to make planesmasters
@@ -37,7 +59,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/map_view)
// We lazy load this because there's no point creating all these if none's gonna see em // We lazy load this because there's no point creating all these if none's gonna see em
// Store this info in a client -> hud pattern, so ghosts closing the window nukes the right group // Store this info in a client -> hud pattern, so ghosts closing the window nukes the right group
var/datum/weakref/client_ref = WEAKREF(show_to.client) var/datum/weakref/client_ref = WEAKREF(show_to)
var/datum/weakref/hud_ref = viewers_to_huds[client_ref] var/datum/weakref/hud_ref = viewers_to_huds[client_ref]
var/datum/hud/our_hud = hud_ref?.resolve() var/datum/hud/our_hud = hud_ref?.resolve()
@@ -46,8 +68,8 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/map_view)
// Generate a new plane group for this case // Generate a new plane group for this case
var/datum/plane_master_group/popup/pop_planes = new(PLANE_GROUP_POPUP_WINDOW(src), assigned_map) var/datum/plane_master_group/popup/pop_planes = new(PLANE_GROUP_POPUP_WINDOW(src), assigned_map)
viewers_to_huds[client_ref] = WEAKREF(show_to.hud_used) viewers_to_huds[client_ref] = WEAKREF(show_to.mob.hud_used)
pop_planes.attach_to(show_to.hud_used) pop_planes.attach_to(show_to.mob.hud_used)
return pop_planes return pop_planes

View File

@@ -15,9 +15,7 @@
var/list/concurrent_users = list() var/list/concurrent_users = list()
// Stuff needed to render the map // Stuff needed to render the map
var/atom/movable/screen/map_view/cam_screen var/atom/movable/screen/map_view/camera/cam_screen
/// All the plane masters that need to be applied.
var/atom/movable/screen/background/cam_background
interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_REQUIRES_SIGHT interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_REQUIRES_SIGHT
@@ -34,13 +32,9 @@
// Initialize map objects // Initialize map objects
cam_screen = new cam_screen = new
cam_screen.generate_view(map_name) cam_screen.generate_view(map_name)
cam_background = new
cam_background.assigned_map = map_name
cam_background.del_on_map_removal = FALSE
/obj/machinery/computer/security/Destroy() /obj/machinery/computer/security/Destroy()
QDEL_NULL(cam_screen) QDEL_NULL(cam_screen)
QDEL_NULL(cam_background)
return ..() return ..()
/obj/machinery/computer/security/connect_to_shuttle(mapload, obj/docking_port/mobile/port, obj/docking_port/stationary/dock) /obj/machinery/computer/security/connect_to_shuttle(mapload, obj/docking_port/mobile/port, obj/docking_port/stationary/dock)
@@ -69,12 +63,11 @@
if(length(concurrent_users) == 1 && is_living) if(length(concurrent_users) == 1 && is_living)
playsound(src, 'sound/machines/terminal/terminal_on.ogg', 25, FALSE) playsound(src, 'sound/machines/terminal/terminal_on.ogg', 25, FALSE)
use_energy(active_power_usage) use_energy(active_power_usage)
// Register map objects
cam_screen.display_to(user)
user.client.register_map_obj(cam_background)
// Open UI // Open UI
ui = new(user, src, "CameraConsole", name) ui = new(user, src, "CameraConsole", name)
ui.open() ui.open()
// Register map objects
cam_screen.display_to(user, ui.window)
/obj/machinery/computer/security/ui_status(mob/user, datum/ui_state/state) /obj/machinery/computer/security/ui_status(mob/user, datum/ui_state/state)
. = ..() . = ..()
@@ -119,7 +112,7 @@
/obj/machinery/computer/security/proc/update_active_camera_screen() /obj/machinery/computer/security/proc/update_active_camera_screen()
// Show static if can't use the camera // Show static if can't use the camera
if(!active_camera?.can_use()) if(!active_camera?.can_use())
show_camera_static() cam_screen.show_camera_static()
return return
var/list/visible_turfs = list() var/list/visible_turfs = list()
@@ -147,9 +140,7 @@
var/size_x = bbox[3] - bbox[1] + 1 var/size_x = bbox[3] - bbox[1] + 1
var/size_y = bbox[4] - bbox[2] + 1 var/size_y = bbox[4] - bbox[2] + 1
cam_screen.vis_contents = visible_turfs cam_screen.show_camera(visible_turfs, size_x, size_y)
cam_background.icon_state = "clear"
cam_background.fill_rect(1, 1, size_x, size_y)
/obj/machinery/computer/security/ui_close(mob/user) /obj/machinery/computer/security/ui_close(mob/user)
. = ..() . = ..()
@@ -165,13 +156,35 @@
last_camera_turf = null last_camera_turf = null
playsound(src, 'sound/machines/terminal/terminal_off.ogg', 25, FALSE) playsound(src, 'sound/machines/terminal/terminal_off.ogg', 25, FALSE)
/obj/machinery/computer/security/proc/show_camera_static() /atom/movable/screen/map_view/camera
cam_screen.vis_contents.Cut() /// All the plane masters that need to be applied.
var/atom/movable/screen/background/cam_background
/atom/movable/screen/map_view/camera/Destroy()
QDEL_NULL(cam_background)
return ..()
/atom/movable/screen/map_view/camera/generate_view(map_key)
. = ..()
cam_background = new
cam_background.del_on_map_removal = FALSE
cam_background.assigned_map = assigned_map
/atom/movable/screen/map_view/camera/display_to_client(client/show_to)
show_to.register_map_obj(cam_background)
. = ..()
/atom/movable/screen/map_view/camera/proc/show_camera(list/visible_turfs, size_x, size_y)
vis_contents = visible_turfs
cam_background.icon_state = "clear"
cam_background.fill_rect(1, 1, size_x, size_y)
/atom/movable/screen/map_view/camera/proc/show_camera_static()
vis_contents.Cut()
cam_background.icon_state = "scanline2" cam_background.icon_state = "scanline2"
cam_background.fill_rect(1, 1, DEFAULT_MAP_SIZE, DEFAULT_MAP_SIZE) cam_background.fill_rect(1, 1, DEFAULT_MAP_SIZE, DEFAULT_MAP_SIZE)
// SECURITY MONITORS // SECURITY MONITORS
/obj/machinery/computer/security/wooden_tv /obj/machinery/computer/security/wooden_tv
name = "security camera monitor" name = "security camera monitor"
desc = "An old TV hooked into the station's camera network." desc = "An old TV hooked into the station's camera network."

View File

@@ -32,7 +32,6 @@
return return
ui = SStgui.try_update_ui(user, src, ui) ui = SStgui.try_update_ui(user, src, ui)
if (!ui) if (!ui)
character_preview_view = create_character_preview_view(user)
ui = new(user, src, "MedicalRecords") ui = new(user, src, "MedicalRecords")
ui.set_autoupdate(FALSE) ui.set_autoupdate(FALSE)
ui.open() ui.open()

View File

@@ -100,30 +100,31 @@
if(!target) if(!target)
return FALSE return FALSE
update_preview(user, params["assigned_view"], target) update_preview(user, params["assigned_view"], target, ui.window)
return TRUE return TRUE
return FALSE return FALSE
/// Creates a character preview view for the UI. /// Creates a character preview view for the UI.
/obj/machinery/computer/records/proc/create_character_preview_view(mob/user) /obj/machinery/computer/records/proc/create_character_preview_view(mob/user, datum/tgui_window/window)
var/assigned_view = USER_PREVIEW_ASSIGNED_VIEW(user.ckey) var/assigned_view = USER_PREVIEW_ASSIGNED_VIEW(user.ckey)
if(user.client?.screen_maps[assigned_view]) if(user.client?.screen_maps[assigned_view])
return return
var/atom/movable/screen/map_view/char_preview/new_view = new(null, src) var/atom/movable/screen/map_view/char_preview/new_view = new(null, src)
new_view.generate_view(assigned_view) new_view.generate_view(assigned_view)
new_view.display_to(user) new_view.display_to(user, window)
return new_view return new_view
/// Takes a record and updates the character preview view to match it. /// Takes a record and updates the character preview view to match it.
/obj/machinery/computer/records/proc/update_preview(mob/user, assigned_view, datum/record/crew/target) /obj/machinery/computer/records/proc/update_preview(mob/user, assigned_view, datum/record/crew/target, datum/tgui_window/window)
var/mutable_appearance/preview = new(target.character_appearance) var/mutable_appearance/preview = new(target.character_appearance)
preview.underlays += mutable_appearance('icons/effects/effects.dmi', "static_base", alpha = 20) preview.underlays += mutable_appearance('icons/effects/effects.dmi', "static_base", alpha = 20)
preview.add_overlay(mutable_appearance(generate_icon_alpha_mask('icons/effects/effects.dmi', "scanline"), alpha = 20)) preview.add_overlay(mutable_appearance(generate_icon_alpha_mask('icons/effects/effects.dmi', "scanline"), alpha = 20))
var/atom/movable/screen/map_view/char_preview/old_view = user.client?.screen_maps[assigned_view]?[1] var/atom/movable/screen/map_view/char_preview/old_view = user.client?.screen_maps[assigned_view]?[1]
if(!old_view) if(!old_view)
character_preview_view = create_character_preview_view(user, window)
return return
old_view.appearance = preview.appearance old_view.appearance = preview.appearance

View File

@@ -78,7 +78,6 @@
return return
ui = SStgui.try_update_ui(user, src, ui) ui = SStgui.try_update_ui(user, src, ui)
if(!ui) if(!ui)
character_preview_view = create_character_preview_view(user)
ui = new(user, src, "SecurityRecords") ui = new(user, src, "SecurityRecords")
ui.set_autoupdate(FALSE) ui.set_autoupdate(FALSE)
ui.open() ui.open()

View File

@@ -25,7 +25,6 @@
proxy_view.appearance = view proxy_view.appearance = view
proxy_view.color = current_color proxy_view.color = current_color
proxy_view.display_to(owner.mob)
/datum/color_matrix_editor/Destroy(force) /datum/color_matrix_editor/Destroy(force)
QDEL_NULL(proxy_view) QDEL_NULL(proxy_view)
@@ -51,6 +50,7 @@
if(!ui) if(!ui)
ui = new(user, src, "ColorMatrixEditor") ui = new(user, src, "ColorMatrixEditor")
ui.open() ui.open()
proxy_view.display_to(owner.mob, ui.window)
/datum/color_matrix_editor/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) /datum/color_matrix_editor/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..() . = ..()

View File

@@ -83,8 +83,7 @@
// Generate movement detector (to update the view on MMI movement) // Generate movement detector (to update the view on MMI movement)
update_view_tracker = new(brain_ref, CALLBACK(src, PROC_REF(update_mmi_view))) update_view_tracker = new(brain_ref, CALLBACK(src, PROC_REF(update_mmi_view)))
// Shows the view to the user foremost // Register map objects
mmi_view.display_to(user)
user.client.register_map_obj(mmi_view_background) user.client.register_map_obj(mmi_view_background)
update_mmi_view() update_mmi_view()
// Makes the MMI relay heard messages // Makes the MMI relay heard messages
@@ -97,6 +96,8 @@
if(!ui) if(!ui)
ui = new(user, src, "LingMMITalk") ui = new(user, src, "LingMMITalk")
ui.open() ui.open()
// Open map view
mmi_view.display_to(user, ui.window)
/datum/action/changeling/mmi_talk/ui_close(mob/user) /datum/action/changeling/mmi_talk/ui_close(mob/user)
var/obj/item/mmi/mmi = brain_ref.loc var/obj/item/mmi/mmi = brain_ref.loc

View File

@@ -341,8 +341,8 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
. = ..() . = ..()
ui = SStgui.try_update_ui(user, src, ui) ui = SStgui.try_update_ui(user, src, ui)
if(!ui) if(!ui)
G.portal_visuals.display_to(user)
ui = new(user, src, "Gateway", name) ui = new(user, src, "Gateway", name)
G.portal_visuals.display_to(user, ui.window)
ui.open() ui.open()
/obj/machinery/computer/gateway_control/ui_data(mob/user) /obj/machinery/computer/gateway_control/ui_data(mob/user)
@@ -418,7 +418,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
QDEL_NULL(cam_background) QDEL_NULL(cam_background)
return ..() return ..()
/atom/movable/screen/map_view/gateway_port/display_to(mob/show_to) /atom/movable/screen/map_view/gateway_port/display_on_ui_visible(mob/show_to)
. = ..() . = ..()
show_to.client.register_map_obj(cam_background) show_to.client.register_map_obj(cam_background)

View File

@@ -63,8 +63,7 @@ ADMIN_VERB(centcom_podlauncher, R_ADMIN, "Config/Launch Supplypod", "Configure a
var/obj/structure/closet/supplypod/centcompod/temp_pod //The temporary pod that is modified by this datum, then cloned. The buildObject() clone of this pod is what is launched var/obj/structure/closet/supplypod/centcompod/temp_pod //The temporary pod that is modified by this datum, then cloned. The buildObject() clone of this pod is what is launched
// Stuff needed to render the map // Stuff needed to render the map
var/map_name var/map_name
var/atom/movable/screen/map_view/cam_screen var/atom/movable/screen/map_view/camera/cam_screen
var/atom/movable/screen/background/cam_background
var/tabIndex = 1 var/tabIndex = 1
var/renderLighting = FALSE var/renderLighting = FALSE
var/static/list/pod_style_info var/static/list/pod_style_info
@@ -109,17 +108,13 @@ ADMIN_VERB(centcom_podlauncher, R_ADMIN, "Config/Launch Supplypod", "Configure a
cam_screen = new cam_screen = new
cam_screen.generate_view(map_name) cam_screen.generate_view(map_name)
var/datum/plane_master_group/planes = cam_screen.display_to(holder.mob) // display_to doesn't send the planes to the client, so we have to do it via display_to_client
var/datum/plane_master_group/planes = cam_screen.display_to_client(holder)
if(!renderLighting) if(!renderLighting)
for(var/atom/movable/screen/plane_master/instance as anything in holder.mob.hud_used.get_true_plane_masters(LIGHTING_PLANE, planes.key)) for(var/atom/movable/screen/plane_master/instance as anything in holder.mob.hud_used.get_true_plane_masters(LIGHTING_PLANE, planes.key))
instance.set_alpha(100) instance.set_alpha(100)
cam_background = new
cam_background.assigned_map = map_name
cam_background.del_on_map_removal = TRUE
refreshView() refreshView()
holder.register_map_obj(cam_background)
/datum/centcom_podlauncher/ui_state(mob/user) /datum/centcom_podlauncher/ui_state(mob/user)
if (SSticker.current_state >= GAME_STATE_FINISHED) if (SSticker.current_state >= GAME_STATE_FINISHED)
@@ -525,7 +520,6 @@ ADMIN_VERB(centcom_podlauncher, R_ADMIN, "Config/Launch Supplypod", "Configure a
. = TRUE . = TRUE
if("refreshView") if("refreshView")
initMap() initMap()
refreshView()
. = TRUE . = TRUE
if("renderLighting") if("renderLighting")
renderLighting = !renderLighting renderLighting = !renderLighting
@@ -553,7 +547,6 @@ ADMIN_VERB(centcom_podlauncher, R_ADMIN, "Config/Launch Supplypod", "Configure a
/datum/centcom_podlauncher/ui_close(mob/user) //Uses the destroy() proc. When the user closes the UI, we clean up the temp_pod and supplypod_selector variables. /datum/centcom_podlauncher/ui_close(mob/user) //Uses the destroy() proc. When the user closes the UI, we clean up the temp_pod and supplypod_selector variables.
QDEL_NULL(temp_pod) QDEL_NULL(temp_pod)
QDEL_NULL(cam_screen) QDEL_NULL(cam_screen)
QDEL_NULL(cam_background)
qdel(src) qdel(src)
/datum/centcom_podlauncher/proc/setupViewPod() /datum/centcom_podlauncher/proc/setupViewPod()
@@ -575,9 +568,7 @@ ADMIN_VERB(centcom_podlauncher, R_ADMIN, "Config/Launch Supplypod", "Configure a
var/size_x = bbox[3] - bbox[1] + 1 var/size_x = bbox[3] - bbox[1] + 1
var/size_y = bbox[4] - bbox[2] + 1 var/size_y = bbox[4] - bbox[2] + 1
cam_screen.vis_contents = visible_turfs cam_screen.show_camera(visible_turfs, size_x, size_y)
cam_background.icon_state = "clear"
cam_background.fill_rect(1, 1, size_x, size_y)
/datum/centcom_podlauncher/proc/updateCursor(forceClear = FALSE) //Update the mouse of the user /datum/centcom_podlauncher/proc/updateCursor(forceClear = FALSE) //Update the mouse of the user
if (!holder) //Can't update the mouse icon if the client doesnt exist! if (!holder) //Can't update the mouse icon if the client doesnt exist!

View File

@@ -138,10 +138,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
ui = SStgui.try_update_ui(user, src, ui) ui = SStgui.try_update_ui(user, src, ui)
if(!ui) if(!ui)
character_preview_view = create_character_preview_view(user) character_preview_view = create_character_preview_view(user)
ui = new(user, src, "PreferencesMenu") ui = new(user, src, "PreferencesMenu")
ui.set_autoupdate(FALSE) ui.set_autoupdate(FALSE)
ui.open() ui.open()
character_preview_view.display_to(user, ui.window)
/datum/preferences/ui_state(mob/user) /datum/preferences/ui_state(mob/user)
return GLOB.always_state return GLOB.always_state
@@ -287,7 +287,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
character_preview_view = new(null, src) character_preview_view = new(null, src)
character_preview_view.generate_view("character_preview_[REF(character_preview_view)]") character_preview_view.generate_view("character_preview_[REF(character_preview_view)]")
character_preview_view.update_body() character_preview_view.update_body()
character_preview_view.display_to(user)
return character_preview_view return character_preview_view

View File

@@ -332,7 +332,6 @@
paint_kit.proxy_view.appearance = paint_kit.editing_mod.appearance paint_kit.proxy_view.appearance = paint_kit.editing_mod.appearance
paint_kit.proxy_view.color = null paint_kit.proxy_view.color = null
paint_kit.proxy_view.display_to(user)
paint_kit.ui_interact(user) paint_kit.ui_interact(user)
return ITEM_INTERACT_SUCCESS return ITEM_INTERACT_SUCCESS
else // Left click else // Left click

View File

@@ -30,6 +30,7 @@
if(!ui) if(!ui)
ui = new(user, src, "MODpaint", name) ui = new(user, src, "MODpaint", name)
ui.open() ui.open()
proxy_view.display_to(user, ui.window)
/obj/item/mod/paint/ui_host() /obj/item/mod/paint/ui_host()
return editing_mod return editing_mod

View File

@@ -28,9 +28,7 @@
var/turf/last_camera_turf var/turf/last_camera_turf
// Stuff needed to render the map // Stuff needed to render the map
var/atom/movable/screen/map_view/cam_screen var/atom/movable/screen/map_view/camera/cam_screen
/// All the plane masters that need to be applied.
var/atom/movable/screen/background/cam_background
///Internal tracker used to find a specific person and keep them on cameras. ///Internal tracker used to find a specific person and keep them on cameras.
var/datum/trackable/internal_tracker var/datum/trackable/internal_tracker
@@ -75,13 +73,9 @@
// Initialize map objects // Initialize map objects
cam_screen = new cam_screen = new
cam_screen.generate_view(map_name) cam_screen.generate_view(map_name)
cam_background = new
cam_background.assigned_map = map_name
cam_background.del_on_map_removal = FALSE
/datum/computer_file/program/secureye/Destroy() /datum/computer_file/program/secureye/Destroy()
QDEL_NULL(cam_screen) QDEL_NULL(cam_screen)
QDEL_NULL(cam_background)
QDEL_NULL(internal_tracker) QDEL_NULL(internal_tracker)
last_camera_turf = null last_camera_turf = null
return ..() return ..()
@@ -102,8 +96,7 @@
if(is_living) if(is_living)
concurrent_users += user_ref concurrent_users += user_ref
// Register map objects // Register map objects
cam_screen.display_to(user) cam_screen.display_to(user, ui.window)
user.client.register_map_obj(cam_background)
/datum/computer_file/program/secureye/ui_status(mob/user, datum/ui_state/state) /datum/computer_file/program/secureye/ui_status(mob/user, datum/ui_state/state)
. = ..() . = ..()
@@ -197,7 +190,7 @@
var/obj/machinery/camera/active_camera = camera_ref?.resolve() var/obj/machinery/camera/active_camera = camera_ref?.resolve()
// Show static if can't use the camera // Show static if can't use the camera
if(!active_camera?.can_use()) if(!active_camera?.can_use())
show_camera_static() cam_screen.show_camera_static()
return return
var/list/visible_turfs = list() var/list/visible_turfs = list()
@@ -225,13 +218,6 @@
var/size_x = bbox[3] - bbox[1] + 1 var/size_x = bbox[3] - bbox[1] + 1
var/size_y = bbox[4] - bbox[2] + 1 var/size_y = bbox[4] - bbox[2] + 1
cam_screen.vis_contents = visible_turfs cam_screen.show_camera(visible_turfs, size_x, size_y)
cam_background.icon_state = "clear"
cam_background.fill_rect(1, 1, size_x, size_y)
/datum/computer_file/program/secureye/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)
#undef DEFAULT_MAP_SIZE #undef DEFAULT_MAP_SIZE

View File

@@ -11,6 +11,7 @@
var/is_browser = FALSE var/is_browser = FALSE
var/status = TGUI_WINDOW_CLOSED var/status = TGUI_WINDOW_CLOSED
var/locked = FALSE var/locked = FALSE
var/visible = FALSE
var/datum/tgui/locked_by var/datum/tgui/locked_by
var/datum/subscriber_object var/datum/subscriber_object
var/subscriber_delegate var/subscriber_delegate
@@ -238,6 +239,7 @@
log_tgui(client, log_tgui(client,
context = "[id]/close (suspending)", context = "[id]/close (suspending)",
window = src) window = src)
visible = FALSE
status = TGUI_WINDOW_READY status = TGUI_WINDOW_READY
send_message("suspend") send_message("suspend")
return return
@@ -245,6 +247,7 @@
context = "[id]/close", context = "[id]/close",
window = src) window = src)
release_lock() release_lock()
visible = FALSE
status = TGUI_WINDOW_CLOSED status = TGUI_WINDOW_CLOSED
message_queue = null message_queue = null
// Do not close the window to give user some time // Do not close the window to give user some time
@@ -379,6 +382,9 @@
switch(type) switch(type)
if("ping") if("ping")
send_message("ping/reply", payload) send_message("ping/reply", payload)
if("visible")
visible = TRUE
SEND_SIGNAL(src, COMSIG_TGUI_WINDOW_VISIBLE, client)
if("suspend") if("suspend")
close(can_be_suspended = TRUE) close(can_be_suspended = TRUE)
if("close") if("close")

View File

@@ -7,7 +7,7 @@
if(!ui) if(!ui)
ui = new(user, src, "Mecha", name) ui = new(user, src, "Mecha", name)
ui.open() ui.open()
ui_view.display_to(user) ui_view.display_to(user, ui.window)
/obj/vehicle/sealed/mecha/ui_status(mob/user, datum/ui_state/state) /obj/vehicle/sealed/mecha/ui_status(mob/user, datum/ui_state/state)
var/common_status = min( var/common_status = min(

View File

@@ -373,6 +373,7 @@
#include "code\__DEFINES\dcs\signals\signals_subsystem.dm" #include "code\__DEFINES\dcs\signals\signals_subsystem.dm"
#include "code\__DEFINES\dcs\signals\signals_swab.dm" #include "code\__DEFINES\dcs\signals\signals_swab.dm"
#include "code\__DEFINES\dcs\signals\signals_techweb.dm" #include "code\__DEFINES\dcs\signals\signals_techweb.dm"
#include "code\__DEFINES\dcs\signals\signals_tgui.dm"
#include "code\__DEFINES\dcs\signals\signals_tools.dm" #include "code\__DEFINES\dcs\signals\signals_tools.dm"
#include "code\__DEFINES\dcs\signals\signals_traitor.dm" #include "code\__DEFINES\dcs\signals\signals_traitor.dm"
#include "code\__DEFINES\dcs\signals\signals_transform.dm" #include "code\__DEFINES\dcs\signals\signals_transform.dm"

View File

@@ -217,6 +217,7 @@ export const backendMiddleware = (store) => {
Byond.winset(Byond.windowId, { Byond.winset(Byond.windowId, {
'is-visible': true, 'is-visible': true,
}); });
Byond.sendMessage('visible');
perf.mark('resume/finish'); perf.mark('resume/finish');
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
logger.log( logger.log(

View File

@@ -96,6 +96,19 @@ const CrewTab = (props: { record: MedicalRecord }) => {
if (selectedRecord?.crew_ref === crew_ref) { if (selectedRecord?.crew_ref === crew_ref) {
setSelectedRecord(undefined); setSelectedRecord(undefined);
} else { } else {
// GOD, I REALLY HATE IT!
// THIS FUCKING HACK NEEDED CAUSE "WINSET MAP"
// MAKING UI DISAPPEAR, AND WE NEED RE-RENDER SHIT
// AFTER BYOND DONE MAKING THEIR SHIT
// Anyway... that's better than hack before
if (selectedRecord === undefined) {
setTimeout(() => {
act('view_record', {
assigned_view: assigned_view,
crew_ref: crew_ref,
});
});
}
setSelectedRecord(record); setSelectedRecord(record);
act('view_record', { assigned_view: assigned_view, crew_ref: crew_ref }); act('view_record', { assigned_view: assigned_view, crew_ref: crew_ref });
} }

View File

@@ -97,6 +97,15 @@ const CrewTab = (props: { record: SecurityRecord }) => {
if (selectedRecord?.crew_ref === crew_ref) { if (selectedRecord?.crew_ref === crew_ref) {
setSelectedRecord(undefined); setSelectedRecord(undefined);
} else { } else {
// See MedicalRecords/RecordTabs.tsx for explanation
if (selectedRecord === undefined) {
setTimeout(() => {
act('view_record', {
assigned_view: assigned_view,
crew_ref: crew_ref,
});
});
}
setSelectedRecord(record); setSelectedRecord(record);
act('view_record', { assigned_view: assigned_view, crew_ref: crew_ref }); act('view_record', { assigned_view: assigned_view, crew_ref: crew_ref });
} }