diff --git a/code/modules/tgui/external.dm b/code/modules/tgui/external.dm index 8f47c609b2..565c595473 100644 --- a/code/modules/tgui/external.dm +++ b/code/modules/tgui/external.dm @@ -1,4 +1,4 @@ -/** +/*! * External tgui definitions, such as src_object APIs. * * Copyright (c) 2020 Aleksej Komarov @@ -71,12 +71,13 @@ * required action string The action/button that has been invoked by the user. * required params list A list of parameters attached to the button. * - * return bool If the UI should be updated or not. + * return bool If the user's input has been handled and the UI should update. */ /datum/proc/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + // SHOULD_CALL_PARENT(TRUE) // If UI is not interactive or usr calling Topic is not the UI user, bail. if(!ui || ui.status != UI_INTERACTIVE) - return 1 + return TRUE /** * public @@ -157,7 +158,7 @@ // Name the verb, and hide it from the user panel. set name = "uiclose" set hidden = TRUE - var/mob/user = src && src.mob + var/mob/user = src?.mob if(!user) return // Close all tgui datums based on window_id. diff --git a/code/modules/tgui/states.dm b/code/modules/tgui/states.dm index fa88cc1338..cc66e71953 100644 --- a/code/modules/tgui/states.dm +++ b/code/modules/tgui/states.dm @@ -1,4 +1,4 @@ -/** +/*! * Base state and helpers for states. Just does some sanity checks, * implement a proper state for in-depth checks. * @@ -83,27 +83,12 @@ return ..() /mob/living/silicon/robot/shared_ui_interaction(src_object) - // Disable UIs if the Borg is unpowered or locked. - if(!cell || cell.charge <= 0 || locked_down) + // Disable UIs if the object isn't installed in the borg AND the borg is either locked, has a dead cell, or no cell. + var/atom/device = src_object + if((istype(device) && device.loc != src) && (!cell || cell.charge <= 0 || locked_down)) return UI_DISABLED return ..() -/** - * public - * - * Check the distance for a living mob. - * Really only used for checks outside the context of a mob. - * Otherwise, use shared_living_ui_distance(). - * - * required src_object The object which owns the UI. - * required user mob The mob who opened/is using the UI. - * - * return UI_state The state of the UI. - */ -/atom/proc/contents_ui_distance(src_object, mob/living/user) - // Just call this mob's check. - return user.shared_living_ui_distance(src_object) - /** * public * diff --git a/code/modules/tgui/states/admin.dm b/code/modules/tgui/states/admin.dm index 227a294078..4da5061dfc 100644 --- a/code/modules/tgui/states/admin.dm +++ b/code/modules/tgui/states/admin.dm @@ -1,10 +1,12 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + /** * tgui state: admin_state * * Checks that the user is an admin, end-of-story. - * - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT */ GLOBAL_DATUM_INIT(admin_state, /datum/ui_state/admin_state, new) diff --git a/code/modules/tgui/states/always.dm b/code/modules/tgui/states/always.dm index 210f0896a2..2406dbb2b9 100644 --- a/code/modules/tgui/states/always.dm +++ b/code/modules/tgui/states/always.dm @@ -1,10 +1,12 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + /** * tgui state: always_state * * Always grants the user UI_INTERACTIVE. Period. - * - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT */ GLOBAL_DATUM_INIT(always_state, /datum/ui_state/always_state, new) diff --git a/code/modules/tgui/states/conscious.dm b/code/modules/tgui/states/conscious.dm index 670ca7c07e..8e35a97da3 100644 --- a/code/modules/tgui/states/conscious.dm +++ b/code/modules/tgui/states/conscious.dm @@ -1,10 +1,12 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + /** * tgui state: conscious_state * * Only checks if the user is conscious. - * - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT */ GLOBAL_DATUM_INIT(conscious_state, /datum/ui_state/conscious_state, new) diff --git a/code/modules/tgui/states/contained.dm b/code/modules/tgui/states/contained.dm index 1eb8edba25..98187b746e 100644 --- a/code/modules/tgui/states/contained.dm +++ b/code/modules/tgui/states/contained.dm @@ -1,10 +1,12 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + /** * tgui state: contained_state * * Checks that the user is inside the src_object. - * - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT */ GLOBAL_DATUM_INIT(contained_state, /datum/ui_state/contained_state, new) diff --git a/code/modules/tgui/states/deep_inventory.dm b/code/modules/tgui/states/deep_inventory.dm index a2b9276a59..a7351a0d2d 100644 --- a/code/modules/tgui/states/deep_inventory.dm +++ b/code/modules/tgui/states/deep_inventory.dm @@ -1,11 +1,13 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + /** * tgui state: deep_inventory_state * * Checks that the src_object is in the user's deep * (backpack, box, toolbox, etc) inventory. - * - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT */ GLOBAL_DATUM_INIT(deep_inventory_state, /datum/ui_state/deep_inventory_state, new) diff --git a/code/modules/tgui/states/default.dm b/code/modules/tgui/states/default.dm index 367e57beff..56220105a5 100644 --- a/code/modules/tgui/states/default.dm +++ b/code/modules/tgui/states/default.dm @@ -1,11 +1,13 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + /** * tgui state: default_state * * Checks a number of things -- mostly physical distance for humans * and view for robots. - * - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT */ GLOBAL_DATUM_INIT(default_state, /datum/ui_state/default, new) @@ -18,15 +20,10 @@ GLOBAL_DATUM_INIT(default_state, /datum/ui_state/default, new) /mob/living/default_can_use_topic(src_object) . = shared_ui_interaction(src_object) - if(. > UI_CLOSE && loc) - . = min(., loc.contents_ui_distance(src_object, src)) // Check the distance... - if(. == UI_INTERACTIVE) // Non-human living mobs can only look, not touch. - return UI_UPDATE - -/mob/living/carbon/human/default_can_use_topic(src_object) - . = shared_ui_interaction(src_object) - if(. > UI_CLOSE) + if(. > UI_CLOSE && loc) //must not be in nullspace. . = min(., shared_living_ui_distance(src_object)) // Check the distance... + if(. == UI_INTERACTIVE && !IsAdvancedToolUser(src)) // unhandy living mobs can only look, not touch. + return UI_UPDATE /mob/living/silicon/robot/default_can_use_topic(src_object) . = shared_ui_interaction(src_object) @@ -49,14 +46,9 @@ GLOBAL_DATUM_INIT(default_state, /datum/ui_state/default, new) return UI_INTERACTIVE return UI_CLOSE -/mob/living/simple_animal/default_can_use_topic(src_object) - . = shared_ui_interaction(src_object) - if(. > UI_CLOSE) - . = min(., shared_living_ui_distance(src_object)) //simple animals can only use things they're near. - /mob/living/silicon/pai/default_can_use_topic(src_object) // pAIs can only use themselves and the owner's radio. if((src_object == src || src_object == radio) && !stat) return UI_INTERACTIVE else - return ..() + return min(..(), UI_UPDATE) diff --git a/code/modules/tgui/states/hands.dm b/code/modules/tgui/states/hands.dm index 1c885ed414..e8cb844bf7 100644 --- a/code/modules/tgui/states/hands.dm +++ b/code/modules/tgui/states/hands.dm @@ -1,10 +1,12 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + /** * tgui state: hands_state * * Checks that the src_object is in the user's hands. - * - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT */ GLOBAL_DATUM_INIT(hands_state, /datum/ui_state/hands_state, new) diff --git a/code/modules/tgui/states/human_adjacent.dm b/code/modules/tgui/states/human_adjacent.dm index 2ac7c8637b..b9208f96cd 100644 --- a/code/modules/tgui/states/human_adjacent.dm +++ b/code/modules/tgui/states/human_adjacent.dm @@ -1,11 +1,13 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + /** * tgui state: human_adjacent_state * * In addition to default checks, only allows interaction for a * human adjacent user. - * - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT */ GLOBAL_DATUM_INIT(human_adjacent_state, /datum/ui_state/human_adjacent_state, new) diff --git a/code/modules/tgui/states/inventory.dm b/code/modules/tgui/states/inventory.dm index dc5dd0d57e..4bc121b278 100644 --- a/code/modules/tgui/states/inventory.dm +++ b/code/modules/tgui/states/inventory.dm @@ -1,11 +1,13 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + /** * tgui state: inventory_state * * Checks that the src_object is in the user's top-level * (hand, ear, pocket, belt, etc) inventory. - * - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT */ GLOBAL_DATUM_INIT(inventory_state, /datum/ui_state/inventory_state, new) diff --git a/code/modules/tgui/states/language_menu.dm b/code/modules/tgui/states/language_menu.dm index 6389b05cd5..eaaa125786 100644 --- a/code/modules/tgui/states/language_menu.dm +++ b/code/modules/tgui/states/language_menu.dm @@ -1,10 +1,12 @@ -/** - * tgui state: language_menu_state - * +/*! * Copyright (c) 2020 Aleksej Komarov * SPDX-License-Identifier: MIT */ +/** + * tgui state: language_menu_state + */ + GLOBAL_DATUM_INIT(language_menu_state, /datum/ui_state/language_menu, new) /datum/ui_state/language_menu/can_use_topic(src_object, mob/user) diff --git a/code/modules/tgui/states/new_player.dm b/code/modules/tgui/states/new_player.dm new file mode 100644 index 0000000000..cf6f83ed3a --- /dev/null +++ b/code/modules/tgui/states/new_player.dm @@ -0,0 +1,13 @@ +/** + * tgui state: new_player_state + * + * Checks that the user is a new_player, or if user is an admin + */ + +GLOBAL_DATUM_INIT(new_player_state, /datum/ui_state/new_player_state, new) + +/datum/ui_state/new_player_state/can_use_topic(src_object, mob/user) + if(isnewplayer(user) || check_rights_for(user.client, R_ADMIN)) + return UI_INTERACTIVE + return UI_CLOSE + diff --git a/code/modules/tgui/states/not_incapacitated.dm b/code/modules/tgui/states/not_incapacitated.dm index 16dcb7881e..48787c81a7 100644 --- a/code/modules/tgui/states/not_incapacitated.dm +++ b/code/modules/tgui/states/not_incapacitated.dm @@ -1,10 +1,12 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + /** * tgui state: not_incapacitated_state * * Checks that the user isn't incapacitated - * - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT */ GLOBAL_DATUM_INIT(not_incapacitated_state, /datum/ui_state/not_incapacitated_state, new) @@ -25,7 +27,7 @@ GLOBAL_DATUM_INIT(not_incapacitated_turf_state, /datum/ui_state/not_incapacitate turf_check = no_turfs /datum/ui_state/not_incapacitated_state/can_use_topic(src_object, mob/user) - if(user.stat) + if(user.stat != CONSCIOUS) return UI_CLOSE if(user.incapacitated() || (turf_check && !isturf(user.loc))) return UI_DISABLED diff --git a/code/modules/tgui/states/notcontained.dm b/code/modules/tgui/states/notcontained.dm index 1d4e6aec19..018e0fa030 100644 --- a/code/modules/tgui/states/notcontained.dm +++ b/code/modules/tgui/states/notcontained.dm @@ -1,11 +1,13 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + /** * tgui state: notcontained_state * * Checks that the user is not inside src_object, and then makes the * default checks. - * - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT */ GLOBAL_DATUM_INIT(notcontained_state, /datum/ui_state/notcontained_state, new) diff --git a/code/modules/tgui/states/observer.dm b/code/modules/tgui/states/observer.dm index d105de1c0c..b749afa894 100644 --- a/code/modules/tgui/states/observer.dm +++ b/code/modules/tgui/states/observer.dm @@ -1,10 +1,12 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + /** * tgui state: observer_state * * Checks that the user is an observer/ghost. - * - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT */ GLOBAL_DATUM_INIT(observer_state, /datum/ui_state/observer_state, new) diff --git a/code/modules/tgui/states/physical.dm b/code/modules/tgui/states/physical.dm index 3073039d14..b559758f72 100644 --- a/code/modules/tgui/states/physical.dm +++ b/code/modules/tgui/states/physical.dm @@ -1,10 +1,12 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + /** * tgui state: physical_state * * Short-circuits the default state to only check physical distance. - * - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT */ GLOBAL_DATUM_INIT(physical_state, /datum/ui_state/physical, new) diff --git a/code/modules/tgui/states/self.dm b/code/modules/tgui/states/self.dm index 4b6e3b9fd9..f7cef3f600 100644 --- a/code/modules/tgui/states/self.dm +++ b/code/modules/tgui/states/self.dm @@ -1,10 +1,12 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + /** * tgui state: self_state * * Only checks that the user and src_object are the same. - * - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT */ GLOBAL_DATUM_INIT(self_state, /datum/ui_state/self_state, new) diff --git a/code/modules/tgui/states/zlevel.dm b/code/modules/tgui/states/zlevel.dm index 64ea2fa1c0..f1a2282b3c 100644 --- a/code/modules/tgui/states/zlevel.dm +++ b/code/modules/tgui/states/zlevel.dm @@ -1,10 +1,12 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + /** * tgui state: z_state * * Only checks that the Z-level of the user and src_object are the same. - * - * Copyright (c) 2020 Aleksej Komarov - * SPDX-License-Identifier: MIT */ GLOBAL_DATUM_INIT(z_state, /datum/ui_state/z_state, new) diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index 9393b9641f..b99783f67a 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -1,4 +1,4 @@ -/** +/*! * Copyright (c) 2020 Aleksej Komarov * SPDX-License-Identifier: MIT */ @@ -50,7 +50,7 @@ */ /datum/tgui/New(mob/user, datum/src_object, interface, title, ui_x, ui_y) log_tgui(user, - "new [interface] fancy [user.client.prefs.tgui_fancy]", + "new [interface] fancy [user?.client?.prefs.tgui_fancy]", src_object = src_object) src.user = user src.src_object = src_object @@ -67,18 +67,20 @@ * public * * Open this UI (and initialize it with data). + * + * return bool - TRUE if a new pooled window is opened, FALSE in all other situations including if a new pooled window didn't open because one already exists. */ /datum/tgui/proc/open() if(!user.client) - return null + return FALSE if(window) - return null + return FALSE process_status() if(status < UI_UPDATE) - return null + return FALSE window = SStgui.request_pooled_window(user) if(!window) - return null + return FALSE opened_at = world.time window.acquire_lock(src) if(!window.is_ready()) @@ -101,6 +103,8 @@ with_static_data = TRUE)) SStgui.on_open(src) + return TRUE + /** * public * @@ -156,7 +160,7 @@ */ /datum/tgui/proc/send_asset(datum/asset/asset) if(!window) - CRASH("send_asset() can only be called after open().") + CRASH("send_asset() was called either without calling open() first or when open() did not return TRUE.") return window.send_asset(asset) /** @@ -237,7 +241,7 @@ * Run an update cycle for this UI. Called internally by SStgui * every second or so. */ -/datum/tgui/process(force = FALSE) +/datum/tgui/process(delta_time, force = FALSE) if(closing) return var/datum/host = src_object.ui_host(user) diff --git a/code/modules/tgui/tgui_alert.dm b/code/modules/tgui/tgui_alert.dm new file mode 100644 index 0000000000..1a86cca705 --- /dev/null +++ b/code/modules/tgui/tgui_alert.dm @@ -0,0 +1,160 @@ +/** + * Creates a TGUI alert window and returns the user's response. + * + * This proc should be used to create alerts that the caller will wait for a response from. + * Arguments: + * * user - The user to show the alert to. + * * message - The content of the alert, shown in the body of the TGUI window. + * * title - The of the alert modal, shown on the top of the TGUI window. + * * buttons - The options that can be chosen by the user, each string is assigned a button on the UI. + * * timeout - The timeout of the alert, after which the modal will close and qdel itself. Set to zero for no timeout. + */ +/proc/tgui_alert(mob/user, message, title, list/buttons, timeout = 60 SECONDS) + if (!user) + user = usr + if (!istype(user)) + if (istype(user, /client)) + var/client/client = user + user = client.mob + else + return + var/datum/tgui_modal/alert = new(user, message, title, buttons, timeout) + alert.ui_interact(user) + alert.wait() + if (alert) + . = alert.choice + qdel(alert) + +/** + * Creates an asynchronous TGUI alert window with an associated callback. + * + * This proc should be used to create alerts that invoke a callback with the user's chosen option. + * Arguments: + * * user - The user to show the alert to. + * * message - The content of the alert, shown in the body of the TGUI window. + * * title - The of the alert modal, shown on the top of the TGUI window. + * * buttons - The options that can be chosen by the user, each string is assigned a button on the UI. + * * callback - The callback to be invoked when a choice is made. + * * timeout - The timeout of the alert, after which the modal will close and qdel itself. Set to zero for no timeout. + */ +/proc/tgui_alert_async(mob/user, message, title, list/buttons, datum/callback/callback, timeout = 60 SECONDS) + if (!user) + user = usr + if (!istype(user)) + if (istype(user, /client)) + var/client/client = user + user = client.mob + else + return + var/datum/tgui_modal/async/alert = new(user, message, title, buttons, callback, timeout) + alert.ui_interact(user) + +/** + * # tgui_modal + * + * Datum used for instantiating and using a TGUI-controlled modal that prompts the user with + * a message and has buttons for responses. + */ +/datum/tgui_modal + /// The title of the TGUI window + var/title + /// The textual body of the TGUI window + var/message + /// The list of buttons (responses) provided on the TGUI window + var/list/buttons + /// The button that the user has pressed, null if no selection has been made + var/choice + /// The time at which the tgui_modal was created, for displaying timeout progress. + var/start_time + /// The lifespan of the tgui_modal, after which the window will close and delete itself. + var/timeout + /// Boolean field describing if the tgui_modal was closed by the user. + var/closed + +/datum/tgui_modal/New(mob/user, message, title, list/buttons, timeout) + src.title = title + src.message = message + src.buttons = buttons.Copy() + if (timeout) + src.timeout = timeout + start_time = world.time + QDEL_IN(src, timeout) + +/datum/tgui_modal/Destroy(force, ...) + SStgui.close_uis(src) + QDEL_NULL(buttons) + . = ..() + +/** + * Waits for a user's response to the tgui_modal's prompt before returning. Returns early if + * the window was closed by the user. + */ +/datum/tgui_modal/proc/wait() + while (!choice && !closed) + stoplag(1) + +/datum/tgui_modal/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AlertModal") + ui.open() + +/datum/tgui_modal/ui_close(mob/user) + . = ..() + closed = TRUE + +/datum/tgui_modal/ui_state(mob/user) + return GLOB.always_state + +/datum/tgui_modal/ui_data(mob/user) + . = list( + "title" = title, + "message" = message, + "buttons" = buttons + ) + + if(timeout) + .["timeout"] = CLAMP01((timeout - (world.time - start_time) - 1 SECONDS) / (timeout - 1 SECONDS)) + +/datum/tgui_modal/ui_act(action, list/params) + . = ..() + if (.) + return + switch(action) + if("choose") + if (!(params["choice"] in buttons)) + return + choice = params["choice"] + SStgui.close_uis(src) + return TRUE + +/** + * # async tgui_modal + * + * An asynchronous version of tgui_modal to be used with callbacks instead of waiting on user responses. + */ +/datum/tgui_modal/async + /// The callback to be invoked by the tgui_modal upon having a choice made. + var/datum/callback/callback + +/datum/tgui_modal/async/New(mob/user, message, title, list/buttons, callback, timeout) + ..(user, title, message, buttons, timeout) + src.callback = callback + +/datum/tgui_modal/async/Destroy(force, ...) + QDEL_NULL(callback) + . = ..() + +/datum/tgui_modal/async/ui_close(mob/user) + . = ..() + qdel(src) + +/datum/tgui_modal/async/ui_act(action, list/params) + . = ..() + if (!. || choice == null) + return + callback.InvokeAsync(choice) + qdel(src) + +/datum/tgui_modal/async/wait() + return diff --git a/code/modules/tgui/tgui_window.dm b/code/modules/tgui/tgui_window.dm index f24a46e33d..61e4db27e7 100644 --- a/code/modules/tgui/tgui_window.dm +++ b/code/modules/tgui/tgui_window.dm @@ -1,4 +1,4 @@ -/** +/*! * Copyright (c) 2020 Aleksej Komarov * SPDX-License-Identifier: MIT */ diff --git a/code/modules/tgui_panel/audio.dm b/code/modules/tgui_panel/audio.dm index e62c4b5bc1..6806961599 100644 --- a/code/modules/tgui_panel/audio.dm +++ b/code/modules/tgui_panel/audio.dm @@ -1,4 +1,4 @@ -/** +/*! * Copyright (c) 2020 Aleksej Komarov * SPDX-License-Identifier: MIT */ diff --git a/code/modules/tgui_panel/external.dm b/code/modules/tgui_panel/external.dm index 35aa31eca7..89973a925d 100644 --- a/code/modules/tgui_panel/external.dm +++ b/code/modules/tgui_panel/external.dm @@ -1,4 +1,4 @@ -/** +/*! * Copyright (c) 2020 Aleksej Komarov * SPDX-License-Identifier: MIT */ @@ -12,19 +12,21 @@ set name = "Fix chat" set category = "OOC" var/action - log_tgui(src, "Started fixing.", - context = "verb/fix_tgui_panel") - // Not ready - if(!tgui_panel?.is_ready()) - log_tgui(src, "Panel is not ready", - context = "verb/fix_tgui_panel") - tgui_panel.window.send_message("ping", force = TRUE) - action = alert(src, "Method: Pinging the panel.\nWait a bit and tell me if it's fixed", "", "Fixed", "Nope") - if(action == "Fixed") - log_tgui(src, "Fixed by sending a ping", - context = "verb/fix_tgui_panel") - return - // Catch all solution + log_tgui(src, "Started fixing.", context = "verb/fix_tgui_panel") + + nuke_chat() + + // Failed to fix + action = alert(src, "Did that work?", "", "Yes", "No, switch to old ui") + if (action == "No, switch to old ui") + winset(src, "output", "on-show=&is-disabled=0&is-visible=1") + winset(src, "browseroutput", "is-disabled=1;is-visible=0") + log_tgui(src, "Failed to fix.", context = "verb/fix_tgui_panel") + +/client/proc/nuke_chat() + // Catch all solution (kick the whole thing in the pants) + winset(src, "output", "on-show=&is-disabled=0&is-visible=1") + winset(src, "browseroutput", "is-disabled=1;is-visible=0") if(!tgui_panel || !istype(tgui_panel)) log_tgui(src, "tgui_panel datum is missing", context = "verb/fix_tgui_panel") @@ -33,15 +35,3 @@ // Force show the panel to see if there are any errors winset(src, "output", "is-disabled=1&is-visible=0") winset(src, "browseroutput", "is-disabled=0;is-visible=1") - action = alert(src, "Method: Reinitializing the panel.\nWait a bit and tell me if it's fixed", "", "Fixed", "Nope") - if(action == "Fixed") - log_tgui(src, "Fixed by calling 'initialize'", - context = "verb/fix_tgui_panel") - return - // Failed to fix - action = alert(src, "Welp, I'm all out of ideas. Try closing BYOND and reconnecting.\nWe could also disable tgui_panel and re-enable the old UI", "", "Thanks anyways", "Switch to old UI") - if (action == "Switch to old UI") - winset(src, "output", "on-show=&is-disabled=0&is-visible=1") - winset(src, "browseroutput", "is-disabled=1;is-visible=0") - log_tgui(src, "Failed to fix.", - context = "verb/fix_tgui_panel") diff --git a/code/modules/tgui_panel/telemetry.dm b/code/modules/tgui_panel/telemetry.dm index 79087d8500..e1abfb1e12 100644 --- a/code/modules/tgui_panel/telemetry.dm +++ b/code/modules/tgui_panel/telemetry.dm @@ -1,4 +1,4 @@ -/** +/*! * Copyright (c) 2020 Aleksej Komarov * SPDX-License-Identifier: MIT */ diff --git a/code/modules/tgui_panel/tgui_panel.dm b/code/modules/tgui_panel/tgui_panel.dm index b983484046..b2fb120100 100644 --- a/code/modules/tgui_panel/tgui_panel.dm +++ b/code/modules/tgui_panel/tgui_panel.dm @@ -1,4 +1,4 @@ -/** +/*! * Copyright (c) 2020 Aleksej Komarov * SPDX-License-Identifier: MIT */ @@ -55,7 +55,7 @@ */ /datum/tgui_panel/proc/on_initialize_timed_out() // Currently does nothing but sending a message to old chat. - SEND_TEXT(client, "Failed to load fancy chat, reverting to old chat. Certain features won't work.") + SEND_TEXT(client, "Failed to load fancy chat, click HERE to attempt to reload it.") /** * private diff --git a/sound/machines/computer/computer_end.ogg b/sound/machines/computer/computer_end.ogg new file mode 100644 index 0000000000..cd3f770e0b Binary files /dev/null and b/sound/machines/computer/computer_end.ogg differ diff --git a/sound/machines/computer/computer_mid1.ogg b/sound/machines/computer/computer_mid1.ogg new file mode 100644 index 0000000000..d183bf5b7a Binary files /dev/null and b/sound/machines/computer/computer_mid1.ogg differ diff --git a/sound/machines/computer/computer_mid2.ogg b/sound/machines/computer/computer_mid2.ogg new file mode 100644 index 0000000000..15e53ded80 Binary files /dev/null and b/sound/machines/computer/computer_mid2.ogg differ diff --git a/sound/machines/computer/computer_start.ogg b/sound/machines/computer/computer_start.ogg new file mode 100644 index 0000000000..80fa526bbb Binary files /dev/null and b/sound/machines/computer/computer_start.ogg differ diff --git a/tgstation.dme b/tgstation.dme index b8ab2a32fe..f9de8bc0a0 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3512,6 +3512,7 @@ #include "code\modules\tgui\external.dm" #include "code\modules\tgui\states.dm" #include "code\modules\tgui\tgui.dm" +#include "code\modules\tgui\tgui_alert.dm" #include "code\modules\tgui\tgui_window.dm" #include "code\modules\tgui\states\admin.dm" #include "code\modules\tgui\states\always.dm" @@ -3524,6 +3525,7 @@ #include "code\modules\tgui\states\human_adjacent.dm" #include "code\modules\tgui\states\inventory.dm" #include "code\modules\tgui\states\language_menu.dm" +#include "code\modules\tgui\states\new_player.dm" #include "code\modules\tgui\states\not_incapacitated.dm" #include "code\modules\tgui\states\notcontained.dm" #include "code\modules\tgui\states\observer.dm"