From 067d8f96804e9911972a66f4943941eebf126ff1 Mon Sep 17 00:00:00 2001 From: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Date: Sat, 9 May 2026 08:06:03 -0400 Subject: [PATCH] Reorganizing the non-game UI (#95383) --- code/__DEFINES/skin.dm | 23 + code/__HELPERS/game.dm | 2 +- code/_globalvars/tgui.dm | 1 + code/controllers/subsystem/server_maint.dm | 6 +- code/controllers/subsystem/statpanel.dm | 4 - code/datums/browser.dm | 2 +- code/datums/hotkeys_help.dm | 9 + code/datums/keybinding/communication.dm | 8 +- code/datums/mocking/client.dm | 2 +- code/datums/verbs.dm | 102 ---- code/datums/view.dm | 6 +- code/game/world.dm | 2 - code/modules/admin/holder2.dm | 2 + code/modules/admin/spawn_panel/spawn_panel.dm | 4 +- .../blood_worm/blood_worm_host_handling.dm | 2 + code/modules/client/client_defines.dm | 2 + code/modules/client/client_procs.dm | 53 +- code/modules/client/preferences/statpanel.dm | 5 + code/modules/client/preferences/status_bar.dm | 2 +- code/modules/client/preferences_menu.dm | 24 +- code/modules/client/verbs/ooc.dm | 4 +- code/modules/client/verbs/ping.dm | 22 - code/modules/client/verbs/stat_panel.dm | 21 + code/modules/emote_panel/emote_panel.dm | 9 - .../modules/mob/living/carbon/alien/organs.dm | 6 - code/modules/mob/login.dm | 4 + code/modules/tgui/tgui_window.dm | 2 + code/modules/tgui_input/say_modal/modal.dm | 4 +- code/modules/tgui_panel/external.dm | 6 +- html/statbrowser.js | 572 +++++++++--------- interface/interface.dm | 15 +- interface/menu.dm | 19 - interface/skin.dmf | 112 ++-- tgstation.dme | 5 +- tgui/packages/tgui-panel/ping/helpers.ts | 1 + .../packages/tgui-panel/settings/constants.ts | 4 + tgui/packages/tgui-panel/settings/scaling.ts | 11 +- tgui/packages/tgui-panel/settings/themes.ts | 22 +- tgui/packages/tgui/interfaces/HotkeysHelp.tsx | 15 +- 39 files changed, 521 insertions(+), 594 deletions(-) create mode 100644 code/__DEFINES/skin.dm delete mode 100644 code/datums/verbs.dm delete mode 100644 code/modules/client/verbs/ping.dm create mode 100644 code/modules/client/verbs/stat_panel.dm delete mode 100644 interface/menu.dm diff --git a/code/__DEFINES/skin.dm b/code/__DEFINES/skin.dm new file mode 100644 index 00000000000..32b0ff32f8d --- /dev/null +++ b/code/__DEFINES/skin.dm @@ -0,0 +1,23 @@ +//These defines are used in skin.dmf, if one is to be renamed/edited, this file must match it. +//IMPORTANT: TGUI & especially `PANE_SPLITTERS` does not use defines, if you rename something make sure you keep name parity! +//Ex: tgui-panel/index.tsx uses `browseroutput` & `output_selector` +//`setClientTheme` has a list of nearly every skin.dmf element in it. +#define SKIN_MAINWINDOW "mainwindow" +#define SKIN_MAINWINDOW_SPLIT "[SKIN_MAINWINDOW].split" + +#define SKIN_MAPWINDOW "mapwindow" +#define SKIN_MAPWINDOW_MAP "[SKIN_MAPWINDOW].map" +#define SKIN_MAPWINDOW_STATUS_BAR "[SKIN_MAPWINDOW].status_bar" + +#define INFOWINDOW "infowindow" +#define INFOWINDOW_INFO "[INFOWINDOW].info" + +#define SKIN_TGUISAY "tgui_say" +#define SKIN_TGUISAY_BROWSER "[SKIN_TGUISAY].browser" + +#define SKIN_DEFAULT "default" +#define SKIN_DEFAULT_SHIFT "[SKIN_DEFAULT].Shift" +#define SKIN_DEFAULT_SHIFTUP "[SKIN_DEFAULT].ShiftUp" + +#define OUTPUT_SELECTOR "output_selector" +#define OUTPUT_SELECTOR_LEGACY_OUTPUT_SELECTOR "[OUTPUT_SELECTOR].legacy_output_selector" diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index afe155b50d2..8dbec0cc56f 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -203,7 +203,7 @@ flashed_client = player_mob.client if(!flashed_client || (!flashed_client.prefs.read_preference(/datum/preference/toggle/window_flashing) && !ignorepref)) return - winset(flashed_client, "mainwindow", "flash=5") + winset(flashed_client, SKIN_MAINWINDOW, "flash=5") /** * Recursively checks if an item is inside a given type/atom, even through layers of storage. diff --git a/code/_globalvars/tgui.dm b/code/_globalvars/tgui.dm index cb768d3d6a3..58ed31ae8de 100644 --- a/code/_globalvars/tgui.dm +++ b/code/_globalvars/tgui.dm @@ -1,3 +1,4 @@ GLOBAL_DATUM(crew_manifest_tgui, /datum/crew_manifest) GLOBAL_DATUM(changelog_tgui, /datum/changelog) GLOBAL_DATUM(hotkeys_tgui, /datum/hotkeys_help) +GLOBAL_DATUM(emote_panel, /datum/emote_panel) diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm index 44a13093a7f..e26e142015e 100644 --- a/code/controllers/subsystem/server_maint.dm +++ b/code/controllers/subsystem/server_maint.dm @@ -66,8 +66,7 @@ SUBSYSTEM_DEF(server_maint) var/afk_period if(kick_inactive) afk_period = CONFIG_GET(number/afk_period) - for(var/I in currentrun) - var/client/C = I + for(var/client/C as anything in currentrun) //handle kicking inactive players if(round_started && kick_inactive && !C.holder && C.is_afk(afk_period)) var/cmob = C.mob @@ -77,9 +76,6 @@ SUBSYSTEM_DEF(server_maint) QDEL_IN(C, 1) //to ensure they get our message before getting disconnected continue - if (!(!C || world.time - C.connection_time < PING_BUFFER_TIME || C.inactivity >= (wait-1))) - winset(C, null, "command=.update_ping+[num2text(world.time+world.tick_lag*TICK_USAGE_REAL/100, 32)]") - if (MC_TICK_CHECK) //one day, when ss13 has 1000 people per server, you guys are gonna be glad I added this tick check return diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index 191d270dbbd..7c173ae293c 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -98,7 +98,6 @@ SUBSYSTEM_DEF(statpanels) return target.stat_panel.send_message("update_stat", list( "global_data" = global_data, - "ping_str" = "Ping: [round(target.lastping, 1)]ms (Average: [round(target.avgping, 1)]ms)", "other_str" = target.mob?.get_status_tab_items(), )) @@ -209,6 +208,3 @@ SUBSYSTEM_DEF(statpanels) else if(length(GLOB.sdql2_queries) && target.stat_tab == "SDQL2") set_SDQL2_tab(target) - -/// Stat panel window declaration -/client/var/datum/tgui_window/stat_panel diff --git a/code/datums/browser.dm b/code/datums/browser.dm index a143be58501..d16b2f93cab 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -260,7 +260,7 @@ if (focused_window) winset(user, focused_window, "focus=true") else - winset(user, "mapwindow", "focus=true") + winset(user, SKIN_MAPWINDOW, "focus=true") break if (timeout) addtimer(CALLBACK(src, PROC_REF(close)), timeout) diff --git a/code/datums/hotkeys_help.dm b/code/datums/hotkeys_help.dm index 0e90c7dffe5..5fe826f3682 100644 --- a/code/datums/hotkeys_help.dm +++ b/code/datums/hotkeys_help.dm @@ -10,6 +10,15 @@ ui = new(user, src, "HotkeysHelp") ui.open() +/datum/hotkeys_help/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + var/mob/user = ui.user + if(action == "open_keybindings") + user.client.prefs.current_window = PREFERENCE_TAB_KEYBINDINGS + user.client.prefs.ui_interact(usr) + user.client.uiclose(ui.window.id) + return TRUE + // Not static data since user could rebind keys. /datum/hotkeys_help/ui_data(mob/user) // List every keybind to chat. diff --git a/code/datums/keybinding/communication.dm b/code/datums/keybinding/communication.dm index a5aa6981243..767bc897cbd 100644 --- a/code/datums/keybinding/communication.dm +++ b/code/datums/keybinding/communication.dm @@ -15,7 +15,7 @@ winset(user, null, "command=[VERB_SAY]") return TRUE winset(user, null, "command=[user.tgui_say_create_open_command(SAY_CHANNEL)];") - winset(user, "tgui_say.browser", "focus=true") + winset(user, SKIN_TGUISAY_BROWSER, "focus=true") return TRUE /datum/keybinding/client/communication/radio @@ -32,7 +32,7 @@ winset(user, null, "command=[VERB_SAY]") return TRUE winset(user, null, "command=[user.tgui_say_create_open_command(RADIO_CHANNEL)]") - winset(user, "tgui_say.browser", "focus=true") + winset(user, SKIN_TGUISAY_BROWSER, "focus=true") return TRUE /datum/keybinding/client/communication/ooc @@ -49,7 +49,7 @@ winset(user, null, "command=[VERB_OOC]") return TRUE winset(user, null, "command=[user.tgui_say_create_open_command(OOC_CHANNEL)]") - winset(user, "tgui_say.browser", "focus=true") + winset(user, SKIN_TGUISAY_BROWSER, "focus=true") return TRUE /datum/keybinding/client/communication/me @@ -66,7 +66,7 @@ winset(user, null, "command=[VERB_ME]") return TRUE winset(user, null, "command=[user.tgui_say_create_open_command(ME_CHANNEL)]") - winset(user, "tgui_say.browser", "focus=true") + winset(user, SKIN_TGUISAY_BROWSER, "focus=true") return TRUE /datum/keybinding/client/communication/pray diff --git a/code/datums/mocking/client.dm b/code/datums/mocking/client.dm index 5c684f08521..79611ef0e9d 100644 --- a/code/datums/mocking/client.dm +++ b/code/datums/mocking/client.dm @@ -83,7 +83,7 @@ /datum/client_interface/proc/get_award_status(achievement_type, mob/user, value = 1) return FALSE -/datum/client_interface/proc/set_fullscreen(logging_in = FALSE) +/datum/client_interface/proc/set_fullscreen() return TRUE /datum/client_interface/proc/check_drag_proximity(atom/dragging, atom/over, src_location, over_location, src_control, over_control, params) diff --git a/code/datums/verbs.dm b/code/datums/verbs.dm deleted file mode 100644 index 9fed14c20c8..00000000000 --- a/code/datums/verbs.dm +++ /dev/null @@ -1,102 +0,0 @@ -/datum/verbs - var/name - var/list/children - var/datum/verbs/parent - var/list/verblist - var/abstract = FALSE - -//returns the master list for verbs of a type -/datum/verbs/proc/GetList() - CRASH("Abstract verblist for [type]") - -//do things for each entry in Generate_list -//return value sets Generate_list[verbpath] -/datum/verbs/proc/HandleVerb(list/entry, procpath/verbpath, ...) - return entry - -/datum/verbs/New() - var/mainlist = GetList() - var/ourentry = mainlist[type] - children = list() - verblist = list() - if (ourentry) - if (!islist(ourentry)) //some of our childern already loaded - qdel(src) - CRASH("Verb double load: [type]") - Add_children(ourentry) - - mainlist[type] = src - - Load_verbs(type, typesof("[type]/verb")) - - var/datum/verbs/parent = mainlist[parent_type] - if (!parent) - mainlist[parent_type] = list(src) - else if (islist(parent)) - parent += src - else - parent.Add_children(list(src)) - -/datum/verbs/proc/Set_parent(datum/verbs/_parent) - parent = _parent - if (abstract) - parent.Add_children(children) - var/list/verblistoftypes = list() - for(var/thing in verblist) - LAZYADD(verblistoftypes[verblist[thing]], thing) - - for(var/verbparenttype in verblistoftypes) - parent.Load_verbs(verbparenttype, verblistoftypes[verbparenttype]) - -/datum/verbs/proc/Add_children(list/kids) - if (abstract && parent) - parent.Add_children(kids) - return - - for(var/thing in kids) - var/datum/verbs/item = thing - item.Set_parent(src) - if (!item.abstract) - children += item - -/datum/verbs/proc/Load_verbs(verb_parent_type, list/verbs) - if (abstract && parent) - parent.Load_verbs(verb_parent_type, verbs) - return - - for (var/verbpath in verbs) - verblist[verbpath] = verb_parent_type - -/datum/verbs/proc/Generate_list(...) - . = list() - if (length(children)) - for (var/thing in children) - var/datum/verbs/child = thing - var/list/childlist = child.Generate_list(arglist(args)) - if (childlist) - var/childname = "[child]" - if (childname == "[child.type]") - var/list/tree = splittext(childname, "/") - childname = tree[tree.len] - .[child.type] = "parent=[url_encode("[type]")];name=[childname]" - . += childlist - - for (var/thing in verblist) - var/procpath/verbpath = thing - if (!verbpath) - stack_trace("Bad VERB in [type] verblist: [english_list(verblist)]") - var/list/entry = list() - entry["parent"] = "[type]" - entry["name"] = verbpath.desc - if (verbpath.name[1] == "@") - entry["command"] = copytext(verbpath.name, length(verbpath.name[1]) + 1) - else - entry["command"] = replacetext(verbpath.name, " ", "-") - - .[verbpath] = HandleVerb(arglist(list(entry, verbpath) + args)) - -/world/proc/LoadVerbs(verb_type) - if(!ispath(verb_type, /datum/verbs) || verb_type == /datum/verbs) - CRASH("Invalid verb_type: [verb_type]") - for (var/typepath in subtypesof(verb_type)) - new typepath() diff --git a/code/datums/view.dm b/code/datums/view.dm index b9a15f0cb05..4c2ccfc46ae 100644 --- a/code/datums/view.dm +++ b/code/datums/view.dm @@ -45,16 +45,16 @@ SEND_SIGNAL(chief.mob, COMSIG_VIEWDATA_UPDATE, getView()) /datum/view_data/proc/assertFormat()//T-Pose - winset(chief, "mapwindow.map", "zoom=0") + winset(chief, SKIN_MAPWINDOW_MAP, "zoom=0") zoom = 0 /datum/view_data/proc/resetFormat()//Cuck zoom = chief?.prefs.read_preference(/datum/preference/numeric/pixel_size) - winset(chief, "mapwindow.map", "zoom=[zoom]") + winset(chief, SKIN_MAPWINDOW_MAP, "zoom=[zoom]") chief?.attempt_auto_fit_viewport() // If you change zoom mode, fit the viewport /datum/view_data/proc/setZoomMode() - winset(chief, "mapwindow.map", "zoom-mode=[chief?.prefs.read_preference(/datum/preference/choiced/scaling_method)]") + winset(chief, SKIN_MAPWINDOW_MAP, "zoom-mode=[chief?.prefs.read_preference(/datum/preference/choiced/scaling_method)]") /datum/view_data/proc/isZooming() return (width || height) diff --git a/code/game/world.dm b/code/game/world.dm index 7561bfbd4bb..b010f3dc520 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -165,8 +165,6 @@ GLOBAL_VAR(restart_counter) // Initialize RETA system - code/modules/reta/reta_system.dm reta_init_config() - LoadVerbs(/datum/verbs/menu) - if(fexists(RESTART_COUNTER_PATH)) GLOB.restart_counter = text2num(trim(file2text(RESTART_COUNTER_PATH))) fdel(RESTART_COUNTER_PATH) diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index 9db5efee0db..3b78e552740 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -122,6 +122,7 @@ GLOBAL_PROTECT(href_token) add_verb(client, /client/proc/readmin) client.disable_combo_hud() client.update_special_keybinds() + client.set_stat_panel() /datum/admins/proc/associate(client/client) if(IsAdminAdvancedProcCall()) @@ -162,6 +163,7 @@ GLOBAL_PROTECT(href_token) owner.init_verbs() //re-initialize the verb list owner.update_special_keybinds() GLOB.admins |= client + client.set_stat_panel() try_give_profiling() diff --git a/code/modules/admin/spawn_panel/spawn_panel.dm b/code/modules/admin/spawn_panel/spawn_panel.dm index a5cc42a4391..cdde4d0b902 100644 --- a/code/modules/admin/spawn_panel/spawn_panel.dm +++ b/code/modules/admin/spawn_panel/spawn_panel.dm @@ -196,9 +196,9 @@ admin_client.mouse_pointer_icon = admin_client.mouse_override_icon admin_client.click_intercept = src - winset(admin_client, "mapwindow.map", "right-click=true") + winset(admin_client, SKIN_MAPWINDOW_MAP, "right-click=true") else - winset(admin_client, "mapwindow.map", "right-click=false") + winset(admin_client, SKIN_MAPWINDOW_MAP, "right-click=false") var/mob/holder_mob = admin_client.mob holder_mob?.update_mouse_pointer() diff --git a/code/modules/antagonists/blood_worm/blood_worm_host_handling.dm b/code/modules/antagonists/blood_worm/blood_worm_host_handling.dm index 2b87fd4c9f6..ebfeed40a64 100644 --- a/code/modules/antagonists/blood_worm/blood_worm_host_handling.dm +++ b/code/modules/antagonists/blood_worm/blood_worm_host_handling.dm @@ -22,6 +22,7 @@ RegisterSignal(host, COMSIG_LIVING_ADJUST_OXY_DAMAGE, PROC_REF(on_host_adjust_oxy_damage)) RegisterSignal(host, COMSIG_LIVING_PRE_UPDATE_BLOOD_STATUS, PROC_REF(on_host_pre_update_blood_status)) RegisterSignal(host, COMSIG_MOB_GET_STATUS_TAB_ITEMS, PROC_REF(on_host_get_status_tab_items)) + client?.set_stat_panel() RegisterSignal(host, COMSIG_MOB_EXAMINING, PROC_REF(on_host_examining)) START_PROCESSING(SSfastprocess, src) @@ -118,6 +119,7 @@ COMSIG_MOB_EXAMINING, COMSIG_MOB_HUD_CREATED, )) + client?.set_stat_panel() STOP_PROCESSING(SSfastprocess, src) diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 989ff3efa1e..a49169b9084 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -256,5 +256,7 @@ /// The DPI scale of the client. 1 is equivalent to 100% window scaling, 2 will be 200% window scaling var/window_scaling + var/datum/tgui_window/stat_panel + /// OOC colour of the clients messages. var/ooc_colour = null diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 0efbf0a819e..2f0f10646e6 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -557,8 +557,6 @@ GLOBAL_LIST_INIT(unrecommended_builds, list( to_chat(src, span_info("You have unread updates in the changelog.")) if(CONFIG_GET(flag/aggressive_changelog)) changelog() - else - winset(src, "infobuttons.changelog", "font-style=bold") if(ckey in GLOB.clientmessages) for(var/message in GLOB.clientmessages[ckey]) @@ -578,19 +576,16 @@ GLOBAL_LIST_INIT(unrecommended_builds, list( if(!tooltips) tooltips = new /datum/tooltip(src) - if (!interviewee) - initialize_menus() - loot_panel = new(src) view_size = new(src) - set_fullscreen(logging_in = TRUE) view_size.resetFormat() view_size.setZoomMode() view_size.apply() Master.UpdateTickRate() SEND_GLOBAL_SIGNAL(COMSIG_GLOB_CLIENT_CONNECT, src) fully_created = TRUE + set_fullscreen() ////////////// //DISCONNECT// @@ -1118,29 +1113,6 @@ GLOBAL_LIST_INIT(unrecommended_builds, list( return to_chat(src, span_userdanger("Statpanel failed to load, click here to reload the panel ")) -/** - * Initializes dropdown menus on client - */ -/client/proc/initialize_menus() - var/list/topmenus = GLOB.menulist[/datum/verbs/menu] - for (var/thing in topmenus) - var/datum/verbs/menu/topmenu = thing - var/topmenuname = "[topmenu]" - if (topmenuname == "[topmenu.type]") - var/list/tree = splittext(topmenuname, "/") - topmenuname = tree[tree.len] - winset(src, "[topmenu.type]", "parent=menu;name=[url_encode(topmenuname)]") - var/list/entries = topmenu.Generate_list(src) - for (var/child in entries) - winset(src, "[child]", "[entries[child]]") - if (!ispath(child, /datum/verbs/menu)) - var/procpath/verbpath = child - if (verbpath.name[1] != "@") - new child(src) - - // Place Help back at the end. - winset(src, "help-menu", "index=1000") - /client/proc/open_filter_editor(atom/in_atom) if(holder) holder.filterrific = new /datum/filter_editor(in_atom) @@ -1154,13 +1126,13 @@ GLOBAL_LIST_INIT(unrecommended_builds, list( /client/proc/set_right_click_menu_mode(shift_only) if(shift_only) - winset(src, "mapwindow.map", "right-click=true") - winset(src, "ShiftUp", "is-disabled=false") - winset(src, "Shift", "is-disabled=false") + winset(src, SKIN_MAPWINDOW_MAP, "right-click=true") + winset(src, SKIN_DEFAULT_SHIFTUP, "is-disabled=false") + winset(src, SKIN_DEFAULT_SHIFT, "is-disabled=false") else - winset(src, "mapwindow.map", "right-click=false") - winset(src, "default.Shift", "is-disabled=true") - winset(src, "default.ShiftUp", "is-disabled=true") + winset(src, SKIN_MAPWINDOW_MAP, "right-click=false") + winset(src, SKIN_DEFAULT_SHIFT, "is-disabled=true") + winset(src, SKIN_DEFAULT_SHIFTUP, "is-disabled=true") /client/proc/update_ambience_pref(value) if(value) @@ -1229,15 +1201,8 @@ GLOBAL_LIST_INIT(unrecommended_builds, list( prefs.write_preference(GLOB.preference_entries[/datum/preference/toggle/fullscreen_mode], !is_on) set_fullscreen() -/client/proc/set_fullscreen(logging_in = FALSE) - var/fullscreen = prefs?.read_preference(/datum/preference/toggle/fullscreen_mode) - //no need to set every login to not fullscreen, they already aren't. - //we also dont need to call attempt_auto_fit_viewport, Login does that for us. - if(logging_in) - if(fullscreen) - winset(src, "mainwindow", "menu=;is-fullscreen=[fullscreen ? "true" : "false"]") - return - winset(src, "mainwindow", "menu=;is-fullscreen=[fullscreen ? "true" : "false"]") +/client/proc/set_fullscreen() + winset(src, SKIN_MAINWINDOW, "is-fullscreen=[prefs?.read_preference(/datum/preference/toggle/fullscreen_mode) ? "true" : "false"]") attempt_auto_fit_viewport() /// Clears the client's screen, aside from ones that opt out diff --git a/code/modules/client/preferences/statpanel.dm b/code/modules/client/preferences/statpanel.dm index 4c9e3c51b26..3924e0743fe 100644 --- a/code/modules/client/preferences/statpanel.dm +++ b/code/modules/client/preferences/statpanel.dm @@ -9,3 +9,8 @@ return FALSE return is_admin(preferences.parent) + +/datum/preference/toggle/statpanel + savefile_key = "statpanel_open" + savefile_identifier = PREFERENCE_PLAYER + default_value = TRUE diff --git a/code/modules/client/preferences/status_bar.dm b/code/modules/client/preferences/status_bar.dm index 1f1724ff49e..853280cd7fc 100644 --- a/code/modules/client/preferences/status_bar.dm +++ b/code/modules/client/preferences/status_bar.dm @@ -7,4 +7,4 @@ /datum/preference/toggle/status_bar/apply_to_client(client/client, value) if(isnull(client) || istype(client, /datum/client_interface)) //no winset on mock clients. return - winset(client, "mapwindow.status_bar", "is-visible=[value]") + winset(client, SKIN_MAPWINDOW_STATUS_BAR, "is-visible=[value]") diff --git a/code/modules/client/preferences_menu.dm b/code/modules/client/preferences_menu.dm index 887816a0a0a..30c658d4541 100644 --- a/code/modules/client/preferences_menu.dm +++ b/code/modules/client/preferences_menu.dm @@ -1,26 +1,22 @@ -/datum/verbs/menu/Preferences/verb/open_character_preferences() +/client/verb/open_character_preferences() set category = "OOC" set name = "Open Character Preferences" set desc = "Open Character Preferences" - var/datum/preferences/preferences = usr?.client?.prefs - if (!preferences) + if(!prefs) return + prefs.current_window = PREFERENCE_TAB_CHARACTER_PREFERENCES + prefs.update_static_data(usr) + prefs.ui_interact(usr) - preferences.current_window = PREFERENCE_TAB_CHARACTER_PREFERENCES - preferences.update_static_data(usr) - preferences.ui_interact(usr) - -/datum/verbs/menu/Preferences/verb/open_game_preferences() +/client/verb/open_game_preferences() set category = "OOC" set name = "Open Game Preferences" set desc = "Open Game Preferences" - var/datum/preferences/preferences = usr?.client?.prefs - if (!preferences) + if(!prefs) return - - preferences.current_window = PREFERENCE_TAB_GAME_PREFERENCES - preferences.update_static_data(usr) - preferences.ui_interact(usr) + prefs.current_window = PREFERENCE_TAB_GAME_PREFERENCES + prefs.update_static_data(usr) + prefs.ui_interact(usr) diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index ce33331c6e4..771d805889e 100644 --- a/code/modules/client/verbs/ooc.dm +++ b/code/modules/client/verbs/ooc.dm @@ -394,7 +394,7 @@ ADMIN_VERB(reset_ooc_color, R_FUN, "Reset Player OOC Color", "Returns player OOC // Calculate and apply a best estimate // +4 pixels are for the width of the splitter's handle var/pct = 100 * (desired_width + 4) / split_width - winset(src, "mainwindow.split", "splitter=[pct]") + winset(src, SKIN_MAINWINDOW_SPLIT, "splitter=[pct]") // Apply an ever-lowering offset until we finish or fail var/delta @@ -414,7 +414,7 @@ ADMIN_VERB(reset_ooc_color, R_FUN, "Reset Player OOC Color", "Returns player OOC delta = -delta/2 pct += delta - winset(src, "mainwindow.split", "splitter=[pct]") + winset(src, SKIN_MAINWINDOW_SPLIT, "splitter=[pct]") /// Attempt to automatically fit the viewport, assuming the user wants it /client/proc/attempt_auto_fit_viewport() diff --git a/code/modules/client/verbs/ping.dm b/code/modules/client/verbs/ping.dm deleted file mode 100644 index 03603cea895..00000000000 --- a/code/modules/client/verbs/ping.dm +++ /dev/null @@ -1,22 +0,0 @@ -/client/verb/update_ping(time as num) - set instant = TRUE - set name = ".update_ping" - var/ping = pingfromtime(time) - lastping = ping - if (!avgping) - avgping = ping - else - avgping = MC_AVERAGE_SLOW(avgping, ping) - -/client/proc/pingfromtime(time) - return ((world.time+world.tick_lag*TICK_USAGE_REAL/100)-time)*100 - -/client/verb/display_ping(time as num) - set instant = TRUE - set name = ".display_ping" - to_chat(src, span_notice("Round trip ping took [round(pingfromtime(time),1)]ms")) - -/client/verb/ping() - set name = "Ping" - set category = "OOC" - winset(src, null, "command=.display_ping+[world.time+world.tick_lag*TICK_USAGE_REAL/100]") diff --git a/code/modules/client/verbs/stat_panel.dm b/code/modules/client/verbs/stat_panel.dm new file mode 100644 index 00000000000..b2833f88cf6 --- /dev/null +++ b/code/modules/client/verbs/stat_panel.dm @@ -0,0 +1,21 @@ +/client/verb/toggle_stat_panel() + set name = "Toggle Stat Panel" + set hidden = TRUE + + //Flip it + prefs.write_preference(GLOB.preference_entries[/datum/preference/toggle/statpanel], !prefs.read_preference(/datum/preference/toggle/statpanel)) + set_stat_panel() + +///Sets the stat panel's visibility to the player, depending on whether they need it/have it enabled or not. +/client/proc/set_stat_panel() + if(prefs.read_preference(/datum/preference/toggle/statpanel) || needs_stat_panel()) + winset(src, INFOWINDOW_INFO, "left=statwindow") + else + winset(src, INFOWINDOW_INFO, "left=null") + +///Returns TRUE if the player has something that necessitates the stat panel. +/client/proc/needs_stat_panel() + if(holder || interviewee) + return TRUE + . = mob.get_status_tab_items() + return length(.) >= 2 diff --git a/code/modules/emote_panel/emote_panel.dm b/code/modules/emote_panel/emote_panel.dm index d064161c232..c39631fbe3c 100644 --- a/code/modules/emote_panel/emote_panel.dm +++ b/code/modules/emote_panel/emote_panel.dm @@ -53,12 +53,3 @@ /datum/emote_panel/ui_state(mob/user) return GLOB.always_state - -/mob/living/verb/emote_panel() - set name = "Emote Panel" - set category = "IC" - - var/static/datum/emote_panel/emote_panel - if(isnull(emote_panel)) - emote_panel = new - emote_panel.ui_interact(src) diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm index ebbacdf2c02..92b6b6c0baf 100644 --- a/code/modules/mob/living/carbon/alien/organs.dm +++ b/code/modules/mob/living/carbon/alien/organs.dm @@ -85,7 +85,6 @@ /obj/item/organ/alien/plasmavessel/on_mob_insert(mob/living/carbon/organ_owner) . = ..() - RegisterSignal(organ_owner, COMSIG_MOB_GET_STATUS_TAB_ITEMS, PROC_REF(get_status_tab_item)) RegisterSignal(organ_owner, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) if (organ_owner.hud_used) on_hud_created() @@ -93,13 +92,8 @@ /obj/item/organ/alien/plasmavessel/on_mob_remove(mob/living/carbon/organ_owner) . = ..() UnregisterSignal(organ_owner, COMSIG_MOB_GET_STATUS_TAB_ITEMS) - UnregisterSignal(organ_owner, COMSIG_MOB_HUD_CREATED) organ_owner.hud_used?.remove_screen_object(HUD_ALIEN_PLASMA_DISPLAY) -/obj/item/organ/alien/plasmavessel/proc/get_status_tab_item(mob/living/carbon/source, list/items) - SIGNAL_HANDLER - items += "Plasma Stored: [stored_plasma]/[max_plasma]" - /obj/item/organ/alien/plasmavessel/proc/update_plasma_display() owner.hud_used?.screen_objects[HUD_ALIEN_PLASMA_DISPLAY]?.maptext = MAPTEXT( \ "
[round(owner.getPlasma())]
" \ diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 1f0069e203c..541734ff8e4 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -104,6 +104,7 @@ stop_sound_channel(CHANNEL_AMBIENCE) if(client) + client.view_size?.resetToDefault() // Resets the client.view in case it was changed. for(var/datum/action/A as anything in persistent_client.player_actions) @@ -121,6 +122,9 @@ ) auto_deadmin_on_login() + //Check if they should have a stat panel, after they deadmined. + client.set_stat_panel() + log_message("Client [key_name(src)] has taken ownership of mob [src]([src.type])", LOG_OWNERSHIP) log_mob_tag("TAG: [tag] NEW OWNER: [key_name(src)]") SEND_SIGNAL(src, COMSIG_MOB_CLIENT_LOGIN, client) diff --git a/code/modules/tgui/tgui_window.dm b/code/modules/tgui/tgui_window.dm index 2357e9030e9..f82457a8ba8 100644 --- a/code/modules/tgui/tgui_window.dm +++ b/code/modules/tgui/tgui_window.dm @@ -359,6 +359,8 @@ switch(type) if("ping") send_message("ping/reply", payload) + if("ping/set") + client?.avgping = payload["ping"] if("visible") visible = TRUE SEND_SIGNAL(src, COMSIG_TGUI_WINDOW_VISIBLE, client) diff --git a/code/modules/tgui_input/say_modal/modal.dm b/code/modules/tgui_input/say_modal/modal.dm index 5dc6d7d9a97..82e681b6dbd 100644 --- a/code/modules/tgui_input/say_modal/modal.dm +++ b/code/modules/tgui_input/say_modal/modal.dm @@ -42,7 +42,7 @@ /datum/tgui_say/New(client/client, id) src.client = client window = new(client, id) - winset(client, "tgui_say", "size=1,1;is-visible=0;") + winset(client, SKIN_TGUISAY, "size=1,1;is-visible=0;") window.subscribe(src, PROC_REF(on_message)) window.is_browser = TRUE @@ -69,7 +69,7 @@ /datum/tgui_say/proc/load() window_open = FALSE - winset(client, "tgui_say", "pos=848,500;is-visible=0;") + winset(client, SKIN_TGUISAY, "pos=848,500;is-visible=0;") window.send_message("props", list( "lightMode" = client.prefs?.read_preference(/datum/preference/toggle/tgui_say_light_mode), diff --git a/code/modules/tgui_panel/external.dm b/code/modules/tgui_panel/external.dm index 0d715b2bf53..ae504fdb0c5 100644 --- a/code/modules/tgui_panel/external.dm +++ b/code/modules/tgui_panel/external.dm @@ -19,19 +19,19 @@ // Failed to fix, using tg_alert as fallback action = tg_alert(src, "Did that work?", "", "Yes", "No, switch to old ui") if (action == "No, switch to old ui") - winset(src, "output_selector.legacy_output_selector", "left=output_legacy") + winset(src, OUTPUT_SELECTOR_LEGACY_OUTPUT_SELECTOR, "left=output_legacy") 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_selector.legacy_output_selector", "left=output_legacy") + winset(src, OUTPUT_SELECTOR_LEGACY_OUTPUT_SELECTOR, "left=output_legacy") if(!tgui_panel || !istype(tgui_panel)) log_tgui(src, "tgui_panel datum is missing", context = "verb/fix_tgui_panel") tgui_panel = new(src) tgui_panel.initialize(force = TRUE) // Force show the panel to see if there are any errors - winset(src, "output_selector.legacy_output_selector", "left=output_browser") + winset(src, OUTPUT_SELECTOR_LEGACY_OUTPUT_SELECTOR, "left=output_browser") /client/verb/refresh_tgui() set name = "Refresh TGUI" diff --git a/html/statbrowser.js b/html/statbrowser.js index d0f98fc60f7..2292f199096 100644 --- a/html/statbrowser.js +++ b/html/statbrowser.js @@ -10,33 +10,35 @@ if (!Array.prototype.includes) { } if (!String.prototype.trim) { String.prototype.trim = function () { - return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ""); + return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); }; } // Status panel implementation ------------------------------------------------ //status_tab_parts expects a list to be returned, to which we'll send a list within a list //with just "loading" to not appear broken. -var status_tab_parts = [["Loading..."]]; +var status_tab_parts = [['Loading...']]; var current_tab = null; //mc_tab_parts expects a list to be returned, to which we'll send a list within a list //with just "loading" to not appear broken. -var mc_tab_parts = [["Loading..."]]; +var mc_tab_parts = [['Loading...']]; var href_token = null; var verb_tabs = []; -var verbs = [["", ""]]; // list with a list inside +var verbs = [['', '']]; // list with a list inside var tickets = []; -var interviewManager = { status: "", interviews: [] }; +var interviewManager = { status: '', interviews: [] }; var sdql2 = []; var permanent_tabs = []; // tabs that won't be cleared by wipes var turfcontents = []; -var turfname = ""; +var turfname = ''; var imageRetryDelay = 500; var imageRetryLimit = 50; -var menu = document.getElementById("menu"); -var statcontentdiv = document.getElementById("statcontent"); +var menu = document.getElementById('menu'); +var statcontentdiv = document.getElementById('statcontent'); var storedimages = []; var split_admin_tabs = false; +//The 'default' tab that everyone should have, that we swap to if the tab you're on is deleted or anything similar. +var defaultTab = 'Status'; // Any BYOND commands that could result in the client's focus changing go through this // to ensure that when we relinquish our focus, we don't do it after the result of @@ -46,18 +48,18 @@ function run_after_focus(callback) { } function createStatusTab(name) { - if (name.indexOf(".") != -1) { - var splitName = name.split("."); - if (split_admin_tabs && splitName[0] === "Admin") name = splitName[1]; + if (name.indexOf('.') != -1) { + var splitName = name.split('.'); + if (split_admin_tabs && splitName[0] === 'Admin') name = splitName[1]; else name = splitName[0]; } - if (document.getElementById(name) || name.trim() == "") { + if (document.getElementById(name) || name.trim() == '') { return; } if (!verb_tabs.includes(name) && !permanent_tabs.includes(name)) { return; } - var button = document.createElement("DIV"); + var button = document.createElement('DIV'); button.onclick = function () { tab_change(name); this.blur(); @@ -65,7 +67,7 @@ function createStatusTab(name) { }; button.id = name; button.textContent = name; - button.className = "button"; + button.className = 'button'; //ORDERING ALPHABETICALLY button.style.order = { Status: 1, MC: 2 }[name] || name.charCodeAt(0); //END ORDERING @@ -87,7 +89,7 @@ function removeStatusTab(name) { } function sortVerbs() { - verbs.sort(function (a, b) { + verbs.sort((a, b) => { var selector = a[0] == b[0] ? 1 : 0; if (a[selector].toUpperCase() < b[selector].toUpperCase()) { return 1; @@ -143,13 +145,13 @@ function check_verbs() { function verbs_cat_check(cat) { var tabCat = cat; - if (cat.indexOf(".") != -1) { - var splitName = cat.split("."); - if (split_admin_tabs && splitName[0] === "Admin") tabCat = splitName[1]; + if (cat.indexOf('.') != -1) { + var splitName = cat.split('.'); + if (split_admin_tabs && splitName[0] === 'Admin') tabCat = splitName[1]; else tabCat = splitName[0]; } var verbs_in_cat = 0; - var verbcat = ""; + var verbcat = ''; if (!verb_tabs.includes(tabCat)) { removeStatusTab(tabCat); return; @@ -157,13 +159,12 @@ function verbs_cat_check(cat) { for (var v = 0; v < verbs.length; v++) { var part = verbs[v]; verbcat = part[0]; - if (verbcat.indexOf(".") != -1) { - var splitName = verbcat.split("."); - if (split_admin_tabs && splitName[0] === "Admin") verbcat = splitName[1]; + if (verbcat.indexOf('.') != -1) { + var splitName = verbcat.split('.'); + if (split_admin_tabs && splitName[0] === 'Admin') verbcat = splitName[1]; else verbcat = splitName[0]; } - if (verbcat != tabCat || verbcat.trim() == "") { - continue; + if (verbcat != tabCat || verbcat.trim() == '') { } else { verbs_in_cat = 1; break; // we only need one @@ -171,7 +172,7 @@ function verbs_cat_check(cat) { } if (verbs_in_cat != 1) { removeStatusTab(tabCat); - if (current_tab == tabCat) tab_change("Status"); + if (current_tab == tabCat) tab_change(defaultTab); } } @@ -182,14 +183,14 @@ function findVerbindex(name, verblist) { } } function wipe_verbs() { - verbs = [["", ""]]; + verbs = [['', '']]; verb_tabs = []; checkStatusTab(); // remove all empty verb tabs } function update_verbs() { wipe_verbs(); - Byond.sendMessage("Update-Verbs"); + Byond.sendMessage('Update-Verbs'); } function SendTabsToByond() { @@ -201,159 +202,158 @@ function SendTabsToByond() { } function SendTabToByond(tab) { - Byond.sendMessage("Send-Tabs", { tab: tab }); + Byond.sendMessage('Send-Tabs', { tab: tab }); } //Byond can't have this tab anymore since we're removing it function TakeTabFromByond(tab) { - Byond.sendMessage("Remove-Tabs", { tab: tab }); + Byond.sendMessage('Remove-Tabs', { tab: tab }); } function tab_change(tab) { if (tab == current_tab) return; if (document.getElementById(current_tab)) - document.getElementById(current_tab).className = "button"; // disable active on last button + document.getElementById(current_tab).className = 'button'; // disable active on last button current_tab = tab; set_byond_tab(tab); if (document.getElementById(tab)) - document.getElementById(tab).className = "button active"; // make current button active + document.getElementById(tab).className = 'button active'; // make current button active var verb_tabs_thingy = verb_tabs.includes(tab); - statcontentdiv.className = "statcontent"; - if (tab == "Status") { + statcontentdiv.className = 'statcontent'; + if (tab == 'Status') { draw_status(); - } else if (tab == "MC") { + } else if (tab == 'MC') { draw_mc(); } else if (verb_tabs_thingy) { draw_verbs(tab); - } else if (tab == "Debug Stat Panel") { + } else if (tab == 'Debug Stat Panel') { draw_debug(); - } else if (tab == "Tickets") { + } else if (tab == 'Tickets') { draw_tickets(); draw_interviews(); - } else if (tab == "SDQL2") { + } else if (tab == 'SDQL2') { draw_sdql2(); } else if (tab == turfname) { draw_listedturf(); } else { - statcontentdiv.textContext = "Loading..."; + statcontentdiv.textContext = 'Loading...'; } Byond.winset(Byond.windowId, { - "is-visible": true, + 'is-visible': true, }); } function set_byond_tab(tab) { - Byond.sendMessage("Set-Tab", { tab: tab }); + Byond.sendMessage('Set-Tab', { tab: tab }); } function draw_debug() { - statcontentdiv.textContent = ""; - var wipeverbstabs = document.createElement("div"); - var link = document.createElement("a"); - link.onclick = function () { + statcontentdiv.textContent = ''; + var wipeverbstabs = document.createElement('div'); + var link = document.createElement('a'); + link.onclick = () => { wipe_verbs(); }; - link.textContent = "Wipe All Verbs"; + link.textContent = 'Wipe All Verbs'; wipeverbstabs.appendChild(link); - document.getElementById("statcontent").appendChild(wipeverbstabs); - var wipeUpdateVerbsTabs = document.createElement("div"); - var updateLink = document.createElement("a"); - updateLink.onclick = function () { + document.getElementById('statcontent').appendChild(wipeverbstabs); + var wipeUpdateVerbsTabs = document.createElement('div'); + var updateLink = document.createElement('a'); + updateLink.onclick = () => { update_verbs(); }; - updateLink.textContent = "Wipe and Update All Verbs"; + updateLink.textContent = 'Wipe and Update All Verbs'; wipeUpdateVerbsTabs.appendChild(updateLink); - document.getElementById("statcontent").appendChild(wipeUpdateVerbsTabs); - var text = document.createElement("div"); - text.textContent = "Verb Tabs:"; - document.getElementById("statcontent").appendChild(text); - var table1 = document.createElement("table"); + document.getElementById('statcontent').appendChild(wipeUpdateVerbsTabs); + var text = document.createElement('div'); + text.textContent = 'Verb Tabs:'; + document.getElementById('statcontent').appendChild(text); + var table1 = document.createElement('table'); for (var i = 0; i < verb_tabs.length; i++) { var part = verb_tabs[i]; // Hide subgroups except admin subgroups if they are split - if (verb_tabs[i].lastIndexOf(".") != -1) { - var splitName = verb_tabs[i].split("."); - if (split_admin_tabs && splitName[0] === "Admin") part = splitName[1]; + if (verb_tabs[i].lastIndexOf('.') != -1) { + var splitName = verb_tabs[i].split('.'); + if (split_admin_tabs && splitName[0] === 'Admin') part = splitName[1]; else continue; } - var tr = document.createElement("tr"); - var td1 = document.createElement("td"); + var tr = document.createElement('tr'); + var td1 = document.createElement('td'); td1.textContent = part; - var a = document.createElement("a"); - a.onclick = (function (part) { - return function () { - removeStatusTab(part); - }; + var a = document.createElement('a'); + a.onclick = ((part) => () => { + removeStatusTab(part); })(part); - a.textContent = " Delete Tab " + part; + a.textContent = ' Delete Tab ' + part; td1.appendChild(a); tr.appendChild(td1); table1.appendChild(tr); } - document.getElementById("statcontent").appendChild(table1); - var header2 = document.createElement("div"); - header2.textContent = "Verbs:"; - document.getElementById("statcontent").appendChild(header2); - var table2 = document.createElement("table"); + document.getElementById('statcontent').appendChild(table1); + var header2 = document.createElement('div'); + header2.textContent = 'Verbs:'; + document.getElementById('statcontent').appendChild(header2); + var table2 = document.createElement('table'); for (var v = 0; v < verbs.length; v++) { var part2 = verbs[v]; - var trr = document.createElement("tr"); - var tdd1 = document.createElement("td"); + var trr = document.createElement('tr'); + var tdd1 = document.createElement('td'); tdd1.textContent = part2[0]; - var tdd2 = document.createElement("td"); + var tdd2 = document.createElement('td'); tdd2.textContent = part2[1]; trr.appendChild(tdd1); trr.appendChild(tdd2); table2.appendChild(trr); } - document.getElementById("statcontent").appendChild(table2); - var text3 = document.createElement("div"); - text3.textContent = "Permanent Tabs:"; - document.getElementById("statcontent").appendChild(text3); - var table3 = document.createElement("table"); + document.getElementById('statcontent').appendChild(table2); + var text3 = document.createElement('div'); + text3.textContent = 'Permanent Tabs:'; + document.getElementById('statcontent').appendChild(text3); + var table3 = document.createElement('table'); for (var i = 0; i < permanent_tabs.length; i++) { var part3 = permanent_tabs[i]; - var trrr = document.createElement("tr"); - var tddd1 = document.createElement("td"); + var trrr = document.createElement('tr'); + var tddd1 = document.createElement('td'); tddd1.textContent = part3; trrr.appendChild(tddd1); table3.appendChild(trrr); } - document.getElementById("statcontent").appendChild(table3); + document.getElementById('statcontent').appendChild(table3); } + function draw_status() { - if (!document.getElementById("Status")) { - createStatusTab("Status"); - current_tab = "Status"; + if (!document.getElementById('Status')) { + createStatusTab('Status'); + current_tab = 'Status'; } - statcontentdiv.textContent = ""; - var table = document.createElement("table"); + statcontentdiv.textContent = ''; + var table = document.createElement('table'); for (var i = 0; i < status_tab_parts.length; i++) { var part = status_tab_parts[i]; if (!Array.isArray(part)) { - var div = document.createElement("div"); - if (part.trim() == "") { - table.appendChild(document.createElement("br")); + var div = document.createElement('div'); + if (part.trim() == '') { + table.appendChild(document.createElement('br')); } else { div.textContent = part; table.appendChild(div); } } else { var div; - if (part[0].trim() == "same_line") { - var a = document.createElement("a"); - a.href = "byond://?" + part[2]; + if (part[0].trim() == 'same_line') { + var a = document.createElement('a'); + a.href = 'byond://?' + part[2]; a.textContent = part[1]; div.appendChild(a); } else { - div = document.createElement("div"); - if (part[0].trim() == "") { - table.appendChild(document.createElement("br")); + div = document.createElement('div'); + if (part[0].trim() == '') { + table.appendChild(document.createElement('br')); } else { div.textContent = part[0]; if (part[2]) { - var a = document.createElement("a"); - a.href = "byond://?" + part[2]; + var a = document.createElement('a'); + a.href = 'byond://?' + part[2]; a.textContent = part[1]; div.appendChild(a); } @@ -362,29 +362,29 @@ function draw_status() { } } } - document.getElementById("statcontent").appendChild(table); + document.getElementById('statcontent').appendChild(table); if (verb_tabs.length == 0 || !verbs) { - Byond.command("Fix-Stat-Panel"); + Byond.command('Fix-Stat-Panel'); } } function draw_mc() { - statcontentdiv.textContent = ""; - statcontentdiv.className = "mcstatcontent"; - var table = document.createElement("table"); + statcontentdiv.textContent = ''; + statcontentdiv.className = 'mcstatcontent'; + var table = document.createElement('table'); for (var i = 0; i < mc_tab_parts.length; i++) { var part = mc_tab_parts[i]; - var tr = document.createElement("tr"); - var td0 = document.createElement("td"); - td0.className = "monospace"; + var tr = document.createElement('tr'); + var td0 = document.createElement('td'); + td0.className = 'monospace'; td0.textContent = part[0]; - var td1 = document.createElement("td"); + var td1 = document.createElement('td'); td1.textContent = part[1]; - var td2 = document.createElement("td"); + var td2 = document.createElement('td'); if (part[3]) { - var a = document.createElement("a"); + var a = document.createElement('a'); a.href = - "byond://?_src_=vars;admin_token=" + href_token + ";Vars=" + part[3]; + 'byond://?_src_=vars;admin_token=' + href_token + ';Vars=' + part[3]; a.textContent = part[2]; td2.appendChild(a); } else { @@ -395,14 +395,14 @@ function draw_mc() { tr.appendChild(td2); table.appendChild(tr); } - document.getElementById("statcontent").appendChild(table); + document.getElementById('statcontent').appendChild(table); } function remove_tickets() { if (tickets) { tickets = []; - removePermanentTab("Tickets"); - if (current_tab == "Tickets") tab_change("Status"); + removePermanentTab('Tickets'); + if (current_tab == 'Tickets') tab_change(defaultTab); } checkStatusTab(); } @@ -410,8 +410,8 @@ function remove_tickets() { function remove_sdql2() { if (sdql2) { sdql2 = []; - removePermanentTab("SDQL2"); - if (current_tab == "SDQL2") tab_change("Status"); + removePermanentTab('SDQL2'); + if (current_tab == 'SDQL2') tab_change(defaultTab); } checkStatusTab(); } @@ -427,55 +427,55 @@ function iconError(e) { if (current_tab != turfname) { return; } - setTimeout(function () { + setTimeout(() => { var node = e.target; - var current_attempts = Number(node.getAttribute("data-attempts")) || 0; + var current_attempts = Number(node.getAttribute('data-attempts')) || 0; if (current_attempts > imageRetryLimit) { return; } var src = node.src; node.src = null; - node.src = src + "#" + current_attempts; - node.setAttribute("data-attempts", current_attempts + 1); + node.src = src + '#' + current_attempts; + node.setAttribute('data-attempts', current_attempts + 1); draw_listedturf(); }, imageRetryDelay); } function draw_listedturf() { - statcontentdiv.textContent = ""; - var table = document.createElement("table"); + statcontentdiv.textContent = ''; + var table = document.createElement('table'); for (var i = 0; i < turfcontents.length; i++) { var part = turfcontents[i]; - var clickfunc = (function (part) { + var clickfunc = ((part) => { // The outer function is used to close over a fresh "part" variable, // rather than every onmousedown getting the "part" of the last entry. - return function (e) { + return (e) => { e.preventDefault(); - clickcatcher = "byond://?src=" + part[1]; + clickcatcher = 'byond://?src=' + part[1]; switch (e.button) { case 1: - clickcatcher += ";statpanel_item_click=middle"; + clickcatcher += ';statpanel_item_click=middle'; break; case 2: - clickcatcher += ";statpanel_item_click=right"; + clickcatcher += ';statpanel_item_click=right'; break; default: - clickcatcher += ";statpanel_item_click=left"; + clickcatcher += ';statpanel_item_click=left'; } if (e.shiftKey) { - clickcatcher += ";statpanel_item_shiftclick=1"; + clickcatcher += ';statpanel_item_shiftclick=1'; } if (e.ctrlKey) { - clickcatcher += ";statpanel_item_ctrlclick=1"; + clickcatcher += ';statpanel_item_ctrlclick=1'; } if (e.altKey) { - clickcatcher += ";statpanel_item_altclick=1"; + clickcatcher += ';statpanel_item_altclick=1'; } window.location.href = clickcatcher; }; })(part); if (storedimages[part[1]] == null && part[2]) { - var img = document.createElement("img"); + var img = document.createElement('img'); img.src = part[2]; img.id = part[1]; storedimages[part[1]] = part[2]; @@ -483,51 +483,51 @@ function draw_listedturf() { img.onmousedown = clickfunc; table.appendChild(img); } else { - var img = document.createElement("img"); + var img = document.createElement('img'); img.onerror = iconError; img.onmousedown = clickfunc; img.src = storedimages[part[1]]; img.id = part[1]; table.appendChild(img); } - var b = document.createElement("div"); - var clickcatcher = ""; - b.className = "link"; + var b = document.createElement('div'); + var clickcatcher = ''; + b.className = 'link'; b.onmousedown = clickfunc; b.textContent = part[0]; table.appendChild(b); - table.appendChild(document.createElement("br")); + table.appendChild(document.createElement('br')); } - document.getElementById("statcontent").appendChild(table); + document.getElementById('statcontent').appendChild(table); } function remove_listedturf() { removePermanentTab(turfname); checkStatusTab(); if (current_tab == turfname) { - tab_change("Status"); + tab_change(defaultTab); } } function remove_mc() { - removePermanentTab("MC"); - if (current_tab == "MC") { - tab_change("Status"); + removePermanentTab('MC'); + if (current_tab == 'MC') { + tab_change(defaultTab); } } function draw_sdql2() { - statcontentdiv.textContent = ""; - var table = document.createElement("table"); + statcontentdiv.textContent = ''; + var table = document.createElement('table'); for (var i = 0; i < sdql2.length; i++) { var part = sdql2[i]; - var tr = document.createElement("tr"); - var td1 = document.createElement("td"); + var tr = document.createElement('tr'); + var td1 = document.createElement('td'); td1.textContent = part[0]; - var td2 = document.createElement("td"); + var td2 = document.createElement('td'); if (part[2]) { - var a = document.createElement("a"); - a.href = "byond://?src=" + part[2] + ";statpanel_item_click=left"; + var a = document.createElement('a'); + a.href = 'byond://?src=' + part[2] + ';statpanel_item_click=left'; a.textContent = part[1]; td2.appendChild(a); } else { @@ -537,34 +537,34 @@ function draw_sdql2() { tr.appendChild(td2); table.appendChild(tr); } - document.getElementById("statcontent").appendChild(table); + document.getElementById('statcontent').appendChild(table); } function draw_tickets() { - statcontentdiv.textContent = ""; - var table = document.createElement("table"); + statcontentdiv.textContent = ''; + var table = document.createElement('table'); if (!tickets) { return; } for (var i = 0; i < tickets.length; i++) { var part = tickets[i]; - var tr = document.createElement("tr"); - var td1 = document.createElement("td"); + var tr = document.createElement('tr'); + var td1 = document.createElement('td'); td1.textContent = part[0]; - var td2 = document.createElement("td"); + var td2 = document.createElement('td'); if (part[2]) { - var a = document.createElement("a"); + var a = document.createElement('a'); a.href = - "byond://?_src_=holder;admin_token=" + + 'byond://?_src_=holder;admin_token=' + href_token + - ";ahelp=" + + ';ahelp=' + part[2] + - ";ahelp_action=ticket;statpanel_item_click=left;action=ticket"; + ';ahelp_action=ticket;statpanel_item_click=left;action=ticket'; a.textContent = part[1]; td2.appendChild(a); } else if (part[3]) { - var a = document.createElement("a"); - a.href = "byond://?src=" + part[3] + ";statpanel_item_click=left"; + var a = document.createElement('a'); + a.href = 'byond://?src=' + part[3] + ';statpanel_item_click=left'; a.textContent = part[1]; td2.appendChild(a); } else { @@ -574,33 +574,33 @@ function draw_tickets() { tr.appendChild(td2); table.appendChild(tr); } - document.getElementById("statcontent").appendChild(table); + document.getElementById('statcontent').appendChild(table); } function draw_interviews() { - var body = document.createElement("div"); - var header = document.createElement("h3"); - header.textContent = "Interviews"; + var body = document.createElement('div'); + var header = document.createElement('h3'); + header.textContent = 'Interviews'; body.appendChild(header); - var manDiv = document.createElement("div"); - manDiv.className = "interview_panel_controls"; - var manLink = document.createElement("a"); - manLink.textContent = "Open Interview Manager Panel"; + var manDiv = document.createElement('div'); + manDiv.className = 'interview_panel_controls'; + var manLink = document.createElement('a'); + manLink.textContent = 'Open Interview Manager Panel'; manLink.href = - "byond://?_src_=holder;admin_token=" + + 'byond://?_src_=holder;admin_token=' + href_token + - ";interview_man=1;statpanel_item_click=left"; + ';interview_man=1;statpanel_item_click=left'; manDiv.appendChild(manLink); body.appendChild(manDiv); // List interview stats - var statsDiv = document.createElement("table"); - statsDiv.className = "interview_panel_stats"; + var statsDiv = document.createElement('table'); + statsDiv.className = 'interview_panel_stats'; for (var key in interviewManager.status) { - var d = document.createElement("div"); - var tr = document.createElement("tr"); - var stat_name = document.createElement("td"); - var stat_text = document.createElement("td"); + var d = document.createElement('div'); + var tr = document.createElement('tr'); + var stat_name = document.createElement('td'); + var stat_text = document.createElement('td'); stat_name.textContent = key; stat_text.textContent = interviewManager.status[key]; tr.appendChild(stat_name); @@ -608,94 +608,94 @@ function draw_interviews() { statsDiv.appendChild(tr); } body.appendChild(statsDiv); - document.getElementById("statcontent").appendChild(body); + document.getElementById('statcontent').appendChild(body); // List interviews if any are open - var table = document.createElement("table"); - table.className = "interview_panel_table"; + var table = document.createElement('table'); + table.className = 'interview_panel_table'; if (!interviewManager) { return; } for (var i = 0; i < interviewManager.interviews.length; i++) { var part = interviewManager.interviews[i]; - var tr = document.createElement("tr"); - var td = document.createElement("td"); - var a = document.createElement("a"); - a.textContent = part["status"]; + var tr = document.createElement('tr'); + var td = document.createElement('td'); + var a = document.createElement('a'); + a.textContent = part['status']; a.href = - "byond://?_src_=holder;admin_token=" + + 'byond://?_src_=holder;admin_token=' + href_token + - ";interview=" + - part["ref"] + - ";statpanel_item_click=left"; + ';interview=' + + part['ref'] + + ';statpanel_item_click=left'; td.appendChild(a); tr.appendChild(td); table.appendChild(tr); } - document.getElementById("statcontent").appendChild(table); + document.getElementById('statcontent').appendChild(table); } function make_verb_onclick(command) { - return function () { - run_after_focus(function () { + return () => { + run_after_focus(() => { Byond.command(command); }); }; } function draw_verbs(cat) { - statcontentdiv.textContent = ""; - var table = document.createElement("div"); + statcontentdiv.textContent = ''; + var table = document.createElement('div'); var additions = {}; // additional sub-categories to be rendered - table.className = "grid-container"; + table.className = 'grid-container'; sortVerbs(); - if (split_admin_tabs && cat.lastIndexOf(".") != -1) { - var splitName = cat.split("."); - if (splitName[0] === "Admin") cat = splitName[1]; + if (split_admin_tabs && cat.lastIndexOf('.') != -1) { + var splitName = cat.split('.'); + if (splitName[0] === 'Admin') cat = splitName[1]; } verbs.reverse(); // sort verbs backwards before we draw for (var i = 0; i < verbs.length; ++i) { var part = verbs[i]; var name = part[0]; - if (split_admin_tabs && name.lastIndexOf(".") != -1) { - var splitName = name.split("."); - if (splitName[0] === "Admin") name = splitName[1]; + if (split_admin_tabs && name.lastIndexOf('.') != -1) { + var splitName = name.split('.'); + if (splitName[0] === 'Admin') name = splitName[1]; } var command = part[1]; if ( command && name.lastIndexOf(cat, 0) != -1 && - (name.length == cat.length || name.charAt(cat.length) == ".") + (name.length == cat.length || name.charAt(cat.length) == '.') ) { - var subCat = name.lastIndexOf(".") != -1 ? name.split(".")[1] : null; + var subCat = name.lastIndexOf('.') != -1 ? name.split('.')[1] : null; if (subCat && !additions[subCat]) { - var newTable = document.createElement("div"); - newTable.className = "grid-container"; + var newTable = document.createElement('div'); + newTable.className = 'grid-container'; additions[subCat] = newTable; } - var a = document.createElement("a"); - a.href = "#"; - a.onclick = make_verb_onclick(command.replace(/\s/g, "-")); - a.className = "grid-item"; - var t = document.createElement("span"); + var a = document.createElement('a'); + a.href = '#'; + a.onclick = make_verb_onclick(command.replace(/\s/g, '-')); + a.className = 'grid-item'; + var t = document.createElement('span'); t.textContent = command; - t.className = "grid-item-text"; + t.className = 'grid-item-text'; a.appendChild(t); (subCat ? additions[subCat] : table).appendChild(a); } } // Append base table to view - var content = document.getElementById("statcontent"); + var content = document.getElementById('statcontent'); content.appendChild(table); // Append additional sub-categories if relevant for (var cat in additions) { - if (additions.hasOwnProperty(cat)) { + if (Object.hasOwn(additions, cat)) { // do addition here - var header = document.createElement("h3"); + var header = document.createElement('h3'); header.textContent = cat; content.appendChild(header); content.appendChild(additions[cat]); @@ -704,51 +704,51 @@ function draw_verbs(cat) { } function set_theme(which) { - if (which == "light") { - document.body.className = ""; - document.documentElement.className = "light"; - } else if (which == "dark") { - document.body.className = "dark"; - document.documentElement.className = "dark"; + if (which == 'light') { + document.body.className = ''; + document.documentElement.className = 'light'; + } else if (which == 'dark') { + document.body.className = 'dark'; + document.documentElement.className = 'dark'; } } function set_font_size(size) { - document.body.style.setProperty("font-size", size); + document.body.style.setProperty('font-size', size); } function set_tabs_style(style) { - if (style == "default") { - menu.classList.add("menu-wrap"); - menu.classList.remove("tabs-classic"); - } else if (style == "classic") { - menu.classList.add("menu-wrap"); - menu.classList.add("tabs-classic"); - } else if (style == "scrollable") { - menu.classList.remove("menu-wrap"); - menu.classList.remove("tabs-classic"); + if (style == 'default') { + menu.classList.add('menu-wrap'); + menu.classList.remove('tabs-classic'); + } else if (style == 'classic') { + menu.classList.add('menu-wrap'); + menu.classList.add('tabs-classic'); + } else if (style == 'scrollable') { + menu.classList.remove('menu-wrap'); + menu.classList.remove('tabs-classic'); } } function restoreFocus() { - run_after_focus(function () { - Byond.winset("map", { + run_after_focus(() => { + Byond.winset('map', { focus: true, }); }); } function getCookie(cname) { - var name = cname + "="; - var ca = document.cookie.split(";"); + var name = cname + '='; + var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; - while (c.charAt(0) == " ") c = c.substring(1); + while (c.charAt(0) == ' ') c = c.substring(1); if (c.indexOf(name) === 0) { return decoder(c.substring(name.length, c.length)); } } - return ""; + return ''; } function add_verb_list(payload) { @@ -758,9 +758,9 @@ function add_verb_list(payload) { var part = to_add[i]; if (!part[0]) continue; var category = part[0]; - if (category.indexOf(".") != -1) { - var splitName = category.split("."); - if (split_admin_tabs && splitName[0] === "Admin") category = splitName[1]; + if (category.indexOf('.') != -1) { + var splitName = category.split('.'); + if (split_admin_tabs && splitName[0] === 'Admin') category = splitName[1]; else category = splitName[0]; } if (findVerbindex(part[1], verbs)) continue; @@ -777,19 +777,19 @@ function add_verb_list(payload) { } } -document.addEventListener("mouseup", restoreFocus); -document.addEventListener("keyup", restoreFocus); +document.addEventListener('mouseup', restoreFocus); +document.addEventListener('keyup', restoreFocus); if (!current_tab) { - addPermanentTab("Status"); - tab_change("Status"); + addPermanentTab(defaultTab); + tab_change(defaultTab); } -window.onload = function () { - Byond.sendMessage("Update-Verbs"); +window.onload = () => { + Byond.sendMessage('Update-Verbs'); }; -Byond.subscribeTo("remove_verb_list", function (v) { +Byond.subscribeTo('remove_verb_list', (v) => { var to_remove = v; for (var i = 0; i < to_remove.length; i++) { remove_verb(to_remove[i]); @@ -801,13 +801,13 @@ Byond.subscribeTo("remove_verb_list", function (v) { // passes a 2D list of (verbcategory, verbname) creates tabs and adds verbs to respective list // example (IC, Say) -Byond.subscribeTo("init_verbs", function (payload) { +Byond.subscribeTo('init_verbs', (payload) => { wipe_verbs(); // remove all verb categories so we can replace them checkStatusTab(); // remove all status tabs verb_tabs = payload.panel_tabs; verb_tabs.sort(); // sort it var do_update = false; - var cat = ""; + var cat = ''; for (var i = 0; i < verb_tabs.length; i++) { cat = verb_tabs[i]; createStatusTab(cat); // create a category if the verb doesn't exist yet @@ -825,8 +825,8 @@ Byond.subscribeTo("init_verbs", function (payload) { SendTabsToByond(); }); -Byond.subscribeTo("update_stat", function (payload) { - status_tab_parts = [payload.ping_str]; +Byond.subscribeTo('update_stat', (payload) => { + status_tab_parts = []; var parsed = payload.global_data; @@ -838,44 +838,44 @@ Byond.subscribeTo("update_stat", function (payload) { for (var i = 0; i < parsed.length; i++) if (parsed[i] != null) status_tab_parts.push(parsed[i]); - if (current_tab == "Status") { + if (current_tab == 'Status') { draw_status(); - } else if (current_tab == "Debug Stat Panel") { + } else if (current_tab == 'Debug Stat Panel') { draw_debug(); } }); -Byond.subscribeTo("update_mc", function (payload) { +Byond.subscribeTo('update_mc', (payload) => { mc_tab_parts = payload.mc_data; - mc_tab_parts.splice(0, 0, ["", "Location:", payload.coord_entry]); + mc_tab_parts.splice(0, 0, ['', 'Location:', payload.coord_entry]); - if (!verb_tabs.includes("MC")) { - verb_tabs.push("MC"); + if (!verb_tabs.includes('MC')) { + verb_tabs.push('MC'); } - createStatusTab("MC"); + createStatusTab('MC'); - if (current_tab == "MC") { + if (current_tab == 'MC') { draw_mc(); } }); -Byond.subscribeTo("create_debug", function () { - if (!document.getElementById("Debug Stat Panel")) { - addPermanentTab("Debug Stat Panel"); +Byond.subscribeTo('create_debug', () => { + if (!document.getElementById('Debug Stat Panel')) { + addPermanentTab('Debug Stat Panel'); } else { - removePermanentTab("Debug Stat Panel"); + removePermanentTab('Debug Stat Panel'); } }); -Byond.subscribeTo("create_listedturf", function (TN) { +Byond.subscribeTo('create_listedturf', (TN) => { remove_listedturf(); // remove the last one if we had one turfname = TN; addPermanentTab(turfname); tab_change(turfname); }); -Byond.subscribeTo("remove_admin_tabs", function () { +Byond.subscribeTo('remove_admin_tabs', () => { href_token = null; remove_mc(); remove_tickets(); @@ -883,66 +883,66 @@ Byond.subscribeTo("remove_admin_tabs", function () { remove_interviews(); }); -Byond.subscribeTo("update_listedturf", function (TC) { +Byond.subscribeTo('update_listedturf', (TC) => { turfcontents = TC; if (current_tab == turfname) { draw_listedturf(); } }); -Byond.subscribeTo("update_interviews", function (I) { +Byond.subscribeTo('update_interviews', (I) => { interviewManager = I; - if (current_tab == "Tickets") { + if (current_tab == 'Tickets') { draw_interviews(); } }); -Byond.subscribeTo("update_split_admin_tabs", function (status) { +Byond.subscribeTo('update_split_admin_tabs', (status) => { status = status == true; if (split_admin_tabs !== status) { if (split_admin_tabs === true) { - removeStatusTab("Events"); - removeStatusTab("Fun"); - removeStatusTab("Game"); + removeStatusTab('Events'); + removeStatusTab('Fun'); + removeStatusTab('Game'); } update_verbs(); } split_admin_tabs = status; }); -Byond.subscribeTo("add_admin_tabs", function (ht) { +Byond.subscribeTo('add_admin_tabs', (ht) => { href_token = ht; - addPermanentTab("MC"); - addPermanentTab("Tickets"); + addPermanentTab('MC'); + addPermanentTab('Tickets'); }); -Byond.subscribeTo("update_sdql2", function (S) { +Byond.subscribeTo('update_sdql2', (S) => { sdql2 = S; - if (sdql2.length > 0 && !verb_tabs.includes("SDQL2")) { - verb_tabs.push("SDQL2"); - addPermanentTab("SDQL2"); + if (sdql2.length > 0 && !verb_tabs.includes('SDQL2')) { + verb_tabs.push('SDQL2'); + addPermanentTab('SDQL2'); } - if (current_tab == "SDQL2") { + if (current_tab == 'SDQL2') { draw_sdql2(); } }); -Byond.subscribeTo("update_tickets", function (T) { +Byond.subscribeTo('update_tickets', (T) => { tickets = T; - if (!verb_tabs.includes("Tickets")) { - verb_tabs.push("Tickets"); - addPermanentTab("Tickets"); + if (!verb_tabs.includes('Tickets')) { + verb_tabs.push('Tickets'); + addPermanentTab('Tickets'); } - if (current_tab == "Tickets") { + if (current_tab == 'Tickets') { draw_tickets(); } }); -Byond.subscribeTo("remove_listedturf", remove_listedturf); +Byond.subscribeTo('remove_listedturf', remove_listedturf); -Byond.subscribeTo("remove_sdql2", remove_sdql2); +Byond.subscribeTo('remove_sdql2', remove_sdql2); -Byond.subscribeTo("remove_mc", remove_mc); +Byond.subscribeTo('remove_mc', remove_mc); -Byond.subscribeTo("add_verb_list", add_verb_list); +Byond.subscribeTo('add_verb_list', add_verb_list); diff --git a/interface/interface.dm b/interface/interface.dm index cdf929c5efa..5f0378d5dd5 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -120,13 +120,24 @@ if(prefs.lastchangelog != GLOB.changelog_hash) prefs.lastchangelog = GLOB.changelog_hash prefs.save_preferences() - winset(src, "infobuttons.changelog", "font-style=;") /client/verb/hotkeys_help() set name = "Hotkeys Help" - set category = "OOC" + set hidden = TRUE if(!GLOB.hotkeys_tgui) GLOB.hotkeys_tgui = new /datum/hotkeys_help() GLOB.hotkeys_tgui.ui_interact(mob) + +/client/verb/emote_panel() + set name = "Emote Panel" + set hidden = TRUE + + if(!isliving(mob)) + to_chat(mob, span_notice("You can only use this while you're alive!")) + return + + if(!GLOB.emote_panel) + GLOB.emote_panel = new /datum/emote_panel() + GLOB.emote_panel.ui_interact(mob) diff --git a/interface/menu.dm b/interface/menu.dm deleted file mode 100644 index ec9719e8236..00000000000 --- a/interface/menu.dm +++ /dev/null @@ -1,19 +0,0 @@ -/* -/datum/verbs/menu/Example/verb/Example() - set name = "" //if this starts with @ the verb is not created and name becomes the command to invoke. - set desc = "" //desc is the text given to this entry in the menu - //You can not use src in these verbs. It will be the menu at compile time, but the client at runtime. -*/ - -GLOBAL_LIST_EMPTY(menulist) - -/datum/verbs/menu - var/default //default checked type. - //Set to true to append our children to our parent, - //Rather then add us as a node (used for having more then one checkgroups in the same menu) - -/datum/verbs/menu/GetList() - return GLOB.menulist - -/datum/verbs/menu/HandleVerb(list/entry, verbpath, client/C) - return list2params(entry) diff --git a/interface/skin.dmf b/interface/skin.dmf index 2b9460cd8ca..bcde5f0f46f 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -8,38 +8,6 @@ macro "default" name = "SHIFT+UP" command = ".winset :map.right-click=true" - -menu "menu" - elem - name = "&File" - command = "" - saved-params = "is-checked" - elem "reconnectbutton" - name = "&Reconnect" - command = ".reconnect" - category = "&File" - saved-params = "is-checked" - elem - name = "&Quit\tAlt-F4" - command = ".quit" - category = "&File" - saved-params = "is-checked" - elem "help-menu" - name = "&Help" - command = "" - saved-params = "is-checked" - elem - name = "&Admin Help\tF1" - command = "adminhelp" - category = "&Help" - saved-params = "is-checked" - elem - name = "&Hotkeys" - command = "Hotkeys-Help" - category = "&Help" - saved-params = "is-checked" - - window "mainwindow" elem "mainwindow" type = MAIN @@ -52,7 +20,6 @@ window "mainwindow" statusbar = false icon = 'icons\\ui\\common\\tg_32.png' macro = "default" - menu = "menu" elem "split" type = CHILD pos = 0,0 @@ -138,6 +105,7 @@ window "info_and_buttons" size = 640x477 anchor1 = 0,0 anchor2 = 100,100 + background-color = #ffc41f saved-params = "splitter" left = "infobuttons" right = "infowindow" @@ -145,6 +113,82 @@ window "info_and_buttons" splitter = 2 show-splitter = false +window "infobuttons" + elem "infobuttons" + type = MAIN + pos = 291,0 + size = 676x30 + anchor1 = 0,0 + anchor2 = 100,100 + background-color = none + saved-params = "pos;size;is-minimized;is-maximized" + is-pane = true + outer-size = 692x88 + outer-pos = 291,0 + inner-size = 676x30 + inner-pos = 8,31 + screen-size = 1920x1040 + elem "options" + type = BUTTON + pos = 0,5 + size = 88x27 + anchor1 = 0,0 + anchor2 = 15,100 + background-color = none + saved-params = "is-checked" + text = "Menu" + command = "open-escape-menu" + elem "hotkeys" + type = BUTTON + pos = 92,5 + size = 88x27 + anchor1 = 15,0 + anchor2 = 29,100 + background-color = none + saved-params = "is-checked" + text = "Hotkeys" + command = "Hotkeys-Help" + elem "emotes" + type = BUTTON + pos = 185,5 + size = 88x27 + anchor1 = 29,0 + anchor2 = 43,100 + background-color = none + saved-params = "is-checked" + text = "Emotes" + command = "Emote-Panel" + elem "fullscreen-toggle" + type = BUTTON + pos = 277,5 + size = 88x27 + anchor1 = 43,0 + anchor2 = 57,100 + background-color = none + saved-params = "is-checked" + text = "Fullscreen" + command = "fullscreen" + elem "reconnect" + type = BUTTON + pos = 369,5 + size = 88x27 + anchor1 = 57,0 + anchor2 = 71,100 + background-color = none + saved-params = "is-checked" + text = "Reconnect" + command = ".reconnect" + elem "chat" + type = BUTTON + pos = 560,5 + size = 112x27 + anchor1 = 85,0 + anchor2 = 99,100 + background-color = none + saved-params = "is-checked" + text = "Toggle Stat Panel" + command = "toggle-stat-panel" + window "infowindow" elem "infowindow" type = MAIN @@ -162,7 +206,7 @@ window "infowindow" size = 640x475 is-vert = false splitter = 97.5 - background-color = #ffc41f + background-color = #ffc41f show-splitter = false saved-params = "splitter" left = "info" diff --git a/tgstation.dme b/tgstation.dme index 8604a7465cb..d27510c11c0 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -227,6 +227,7 @@ #include "code\__DEFINES\si.dm" #include "code\__DEFINES\sight.dm" #include "code\__DEFINES\skills.dm" +#include "code\__DEFINES\skin.dm" #include "code\__DEFINES\song.dm" #include "code\__DEFINES\sort_types.dm" #include "code\__DEFINES\sound.dm" @@ -894,7 +895,6 @@ #include "code\datums\stock_market_events.dm" #include "code\datums\tgs_event_handler.dm" #include "code\datums\verb_callbacks.dm" -#include "code\datums\verbs.dm" #include "code\datums\view.dm" #include "code\datums\visual_data.dm" #include "code\datums\voice_of_god_command.dm" @@ -4169,7 +4169,7 @@ #include "code\modules\client\preferences\species_features\pod.dm" #include "code\modules\client\preferences\species_features\vampire.dm" #include "code\modules\client\verbs\ooc.dm" -#include "code\modules\client\verbs\ping.dm" +#include "code\modules\client\verbs\stat_panel.dm" #include "code\modules\client\verbs\suicide.dm" #include "code\modules\client\verbs\typing.dm" #include "code\modules\client\verbs\who.dm" @@ -6935,7 +6935,6 @@ #include "code\modules\zombie\items.dm" #include "code\modules\zombie\organs.dm" #include "interface\interface.dm" -#include "interface\menu.dm" #include "interface\stylesheet.dm" #include "interface\skin.dmf" #include "interface\fonts\fonts_datum.dm" diff --git a/tgui/packages/tgui-panel/ping/helpers.ts b/tgui/packages/tgui-panel/ping/helpers.ts index ff22c82abb4..f30441bc2fd 100644 --- a/tgui/packages/tgui-panel/ping/helpers.ts +++ b/tgui/packages/tgui-panel/ping/helpers.ts @@ -46,6 +46,7 @@ export function pingSuccess(roundtrip: number): void { failCount: 0, networkQuality, }); + Byond.sendMessage('ping/set', { ping: roundtrip }); store.set(lastPingedAtAtom, Date.now()); } diff --git a/tgui/packages/tgui-panel/settings/constants.ts b/tgui/packages/tgui-panel/settings/constants.ts index 0e076fc07f6..2e5056f785e 100644 --- a/tgui/packages/tgui-panel/settings/constants.ts +++ b/tgui/packages/tgui-panel/settings/constants.ts @@ -12,12 +12,16 @@ export const COLORS = { BG_SECOND: '#151515', BUTTON: '#404040', TEXT: '#A6A6A6', + TEXT_IMPORTANT: '#A6A6A6', + BG_IMPORTANT: '#492020', }, LIGHT: { BG_BASE: '#EEEEEE', BG_SECOND: '#FFFFFF', BUTTON: '#FFFFFF', TEXT: '#000000', + TEXT_IMPORTANT: '#A6A6A6', + BG_IMPORTANT: '#910707', }, } as const; diff --git a/tgui/packages/tgui-panel/settings/scaling.ts b/tgui/packages/tgui-panel/settings/scaling.ts index 77cc5f831ba..784a253876f 100644 --- a/tgui/packages/tgui-panel/settings/scaling.ts +++ b/tgui/packages/tgui-panel/settings/scaling.ts @@ -1,12 +1,11 @@ // This is the elements from the skin.dmf that we need to adjust the fontsize of const ELEMENTS_TO_ADJUST = [ - 'infobuttons.changelog', - 'infobuttons.rules', - 'infobuttons.wiki', - 'infobuttons.forum', - 'infobuttons.github', - 'infobuttons.report-issue', + 'infobuttons.options', + 'infobuttons.hotkeys', + 'infobuttons.emotes', 'infobuttons.fullscreen-toggle', + 'infobuttons.reconnect', + 'infobuttons.chat', 'inputwindow.input', 'inputbuttons.saybutton', 'inputbuttons.mebutton', diff --git a/tgui/packages/tgui-panel/settings/themes.ts b/tgui/packages/tgui-panel/settings/themes.ts index 1bfd05800cb..036962e72b6 100644 --- a/tgui/packages/tgui-panel/settings/themes.ts +++ b/tgui/packages/tgui-panel/settings/themes.ts @@ -46,20 +46,18 @@ export function setClientTheme(name): void | Promise { 'mainwindow.background-color': themeColor.BG_BASE, 'split.background-color': themeColor.BG_BASE, // Buttons - 'changelog.background-color': themeColor.BUTTON, - 'changelog.text-color': themeColor.TEXT, - 'rules.background-color': themeColor.BUTTON, - 'rules.text-color': themeColor.TEXT, - 'wiki.background-color': themeColor.BUTTON, - 'wiki.text-color': themeColor.TEXT, - 'forum.background-color': themeColor.BUTTON, - 'forum.text-color': themeColor.TEXT, - 'github.background-color': themeColor.BUTTON, - 'github.text-color': themeColor.TEXT, - 'report-issue.background-color': themeColor.BUTTON, - 'report-issue.text-color': themeColor.TEXT, + 'options.background-color': themeColor.BUTTON, + 'options.text-color': themeColor.TEXT, + 'hotkeys.background-color': themeColor.BUTTON, + 'hotkeys.text-color': themeColor.TEXT, + 'emotes.background-color': themeColor.BUTTON, + 'emotes.text-color': themeColor.TEXT, 'fullscreen-toggle.background-color': themeColor.BUTTON, 'fullscreen-toggle.text-color': themeColor.TEXT, + 'reconnect.background-color': themeColor.BG_IMPORTANT, + 'reconnect.text-color': themeColor.TEXT_IMPORTANT, + 'chat.background-color': themeColor.BUTTON, + 'chat.text-color': themeColor.TEXT, // Status and verb tabs 'output.background-color': themeColor.BG_BASE, 'output.text-color': themeColor.TEXT, diff --git a/tgui/packages/tgui/interfaces/HotkeysHelp.tsx b/tgui/packages/tgui/interfaces/HotkeysHelp.tsx index 21c980246c3..4f83f04a1e6 100644 --- a/tgui/packages/tgui/interfaces/HotkeysHelp.tsx +++ b/tgui/packages/tgui/interfaces/HotkeysHelp.tsx @@ -1,4 +1,4 @@ -import { Box, Section, Table, Tooltip } from 'tgui-core/components'; +import { Box, Button, Section, Table, Tooltip } from 'tgui-core/components'; import { useBackend } from '../backend'; import { Window } from '../layouts'; @@ -90,12 +90,19 @@ const KeyBinding = (props: KeyBindingBoxProps) => ( ); export const HotkeysHelp = (props) => { - const { data } = useBackend(); + const { act, data } = useBackend(); return ( - + -
+
act('open_keybindings')}> + Open Hotkey Settings + + } + >