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
+
+ }
+ >