diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm
index 3d15412efe..2273d34c82 100644
--- a/code/__DEFINES/colors.dm
+++ b/code/__DEFINES/colors.dm
@@ -2,19 +2,6 @@
#define COLOR_INPUT_DISABLED "#F0F0F0"
#define COLOR_INPUT_ENABLED "#D3B5B5"
-
-#define COLOR_DARKMODE_INFO_BUTTONS_BG "#40628A"
-#define COLOR_DARKMODE_ISSUE_BUTTON_BG "#A92C2C"
-#define COLOR_DARKMODE_BACKGROUND "#272727"
-#define COLOR_DARKMODE_DARKBACKGROUND "#242424"
-#define COLOR_DARKMODE_TEXT "#E0E0E0"
-
-#define COLOR_WHITEMODE_INFO_BUTTONS_BG "#90B3DD"
-#define COLOR_WHITEMODE_ISSUE_BUTTON_BG "#EF7F7F"
-#define COLOR_WHITEMODE_BACKGROUND "#F0F0F0"
-#define COLOR_WHITEMODE_DARKBACKGROUND "#E6E6E6"
-#define COLOR_WHITEMODE_TEXT "#000000"
-
#define COLOR_FLOORTILE_GRAY "#8D8B8B"
#define COLOR_ALMOST_BLACK "#333333"
#define COLOR_BLACK "#000000"
@@ -64,4 +51,4 @@
#define COLOR_ASSEMBLY_LBLUE "#5D99BE"
#define COLOR_ASSEMBLY_BLUE "#38559E"
#define COLOR_ASSEMBLY_PURPLE "#6F6192"
-#define COLOR_ASSEMBLY_PINK "#ff4adc"
\ No newline at end of file
+#define COLOR_ASSEMBLY_PINK "#ff4adc"
diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm
index a4bf69b2ad..e9881677ba 100644
--- a/code/__DEFINES/configuration.dm
+++ b/code/__DEFINES/configuration.dm
@@ -1,6 +1,7 @@
//config files
#define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X)
#define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y)
+/// Gets the datum of the object, for when editing a const define.
#define CONFIG_GET_ENTRY(X) global.config.GetEntryDatum(/datum/config_entry/##X)
#define CONFIG_MAPS_FILE "maps.txt"
diff --git a/code/__DEFINES/dye_keys.dm b/code/__DEFINES/dye_keys.dm
index 133f9c47d3..a01dcacc18 100644
--- a/code/__DEFINES/dye_keys.dm
+++ b/code/__DEFINES/dye_keys.dm
@@ -4,6 +4,7 @@
#define DYE_REGISTRY_SNEAKERS "sneakers"
#define DYE_REGISTRY_FANNYPACK "fannypack"
#define DYE_REGISTRY_BEDSHEET "bedsheet"
+#define DYE_LAWYER_SPECIAL "lawyer_special"
#define DYE_RED "red"
#define DYE_ORANGE "orange"
@@ -16,6 +17,7 @@
#define DYE_RAINBOW "rainbow"
#define DYE_MIME "mime"
#define DYE_COSMIC "cosmic"
+#define DYE_SYNDICATE "syndicate"
#define DYE_QM "qm"
#define DYE_LAW "law"
#define DYE_CAPTAIN "captain"
@@ -26,3 +28,5 @@
#define DYE_CMO "cmo"
#define DYE_REDCOAT "redcoat"
#define DYE_CLOWN "clown"
+#define DYE_CHAP "chap"
+#define DYE_CENTCOM "centcom"
diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm
index 0e8e34d20e..df5b7d9f11 100644
--- a/code/__DEFINES/machines.dm
+++ b/code/__DEFINES/machines.dm
@@ -41,11 +41,13 @@
#define MC_HDD "HDD"
#define MC_SDD "SDD"
#define MC_CARD "CARD"
+#define MC_CARD2 "CARD2"
#define MC_NET "NET"
#define MC_PRINT "PRINT"
#define MC_CELL "CELL"
#define MC_CHARGE "CHARGE"
#define MC_AI "AI"
+#define MC_SENSORS "SENSORS"
//NTNet stuff, for modular computers
// NTNet module-configuration values. Do not change these. If you need to add another use larger number (5..6..7 etc)
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 927b661898..0704947dda 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -116,6 +116,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
#define CRAYON_FONT "Comic Sans MS"
#define PRINTER_FONT "Times New Roman"
#define SIGNFONT "Times New Roman"
+#define CHARCOAL_FONT "Candara"
#define RESIZE_DEFAULT_SIZE 1
@@ -318,9 +319,9 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define SHELTER_DEPLOY_ANCHORED_OBJECTS "anchored objects"
//debug printing macros
-#define debug_world(msg) if (GLOB.Debug2) to_chat(world, "DEBUG: [msg]")
-#define debug_usr(msg) if (GLOB.Debug2&&usr) to_chat(usr, "DEBUG: [msg]")
-#define debug_admins(msg) if (GLOB.Debug2) to_chat(GLOB.admins, "DEBUG: [msg]")
+#define debug_world(msg) if (GLOB.Debug2) to_chat(world, "DEBUG: [msg]")
+#define debug_usr(msg) if (GLOB.Debug2&&usr) to_chat(usr, "DEBUG: [msg]")
+#define debug_admins(msg) if (GLOB.Debug2) to_chat(GLOB.admins, "DEBUG: [msg]")
#define debug_world_log(msg) if (GLOB.Debug2) log_world("DEBUG: [msg]")
#define INCREMENT_TALLY(L, stat) if(L[stat]){L[stat]++}else{L[stat] = 1}
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 81b5c5620f..37ca1c66dd 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -93,7 +93,6 @@
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
#define FIRE_PRIORITY_VORE 5
-#define FIRE_PRIORITY_PING 10
#define FIRE_PRIORITY_IDLE_NPC 10
#define FIRE_PRIORITY_SERVER_MAINT 10
#define FIRE_PRIORITY_RESEARCH 10
diff --git a/code/__DEFINES/tgui.dm b/code/__DEFINES/tgui.dm
index f5adeadade..467058f27a 100644
--- a/code/__DEFINES/tgui.dm
+++ b/code/__DEFINES/tgui.dm
@@ -26,3 +26,10 @@
#define TGUI_WINDOW_ID(index) "tgui-window-[index]"
/// Get a pool index of the provided window id
#define TGUI_WINDOW_INDEX(window_id) text2num(copytext(window_id, 13))
+
+/// Creates a message packet for sending via output()
+#define TGUI_CREATE_MESSAGE(type, payload) ( \
+ url_encode(json_encode(list( \
+ "type" = type, \
+ "payload" = payload, \
+ ))))
\ No newline at end of file
diff --git a/code/__HELPERS/_cit_helpers.dm b/code/__HELPERS/_cit_helpers.dm
index 5e57dd5328..a5ffda36f9 100644
--- a/code/__HELPERS/_cit_helpers.dm
+++ b/code/__HELPERS/_cit_helpers.dm
@@ -17,7 +17,7 @@
var/matrix/mtrx=new()
return mtrx.Scale(0.65)
-proc/get_racelist(var/mob/user)//This proc returns a list of species that 'user' has available to them. It searches the list of ckeys attached to the 'whitelist' var for a species and also checks if they're an admin.
+/proc/get_racelist(mob/user)//This proc returns a list of species that 'user' has available to them. It searches the list of ckeys attached to the 'whitelist' var for a species and also checks if they're an admin.
for(var/spath in subtypesof(/datum/species))
var/datum/species/S = new spath()
var/list/wlist = S.whitelist
diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm
index 3155fe2548..11332863f5 100644
--- a/code/__HELPERS/icons.dm
+++ b/code/__HELPERS/icons.dm
@@ -1103,15 +1103,26 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
alpha += 25
obj_flags &= ~FROZEN
+/// Save file used in icon2base64. Used for converting icons to base64.
+GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of icons for the browser output
-//Converts an icon to base64. Operates by putting the icon in the iconCache savefile,
-// exporting it as text, and then parsing the base64 from that.
-// (This relies on byond automatically storing icons in savefiles as base64)
-/proc/icon2base64(icon/icon, iconKey = "misc")
+
+/// Generate a filename for this asset
+/// The same asset will always lead to the same asset name
+/// (Generated names do not include file extention.)
+/proc/generate_asset_name(file)
+ return "asset.[md5(fcopy_rsc(file))]"
+
+/**
+ * Converts an icon to base64. Operates by putting the icon in the iconCache savefile,
+ * exporting it as text, and then parsing the base64 from that.
+ * (This relies on byond automatically storing icons in savefiles as base64)
+ */
+/proc/icon2base64(icon/icon)
if (!isicon(icon))
return FALSE
- WRITE_FILE(GLOB.iconCache[iconKey], icon)
- var/iconData = GLOB.iconCache.ExportText(iconKey)
+ WRITE_FILE(GLOB.dummySave["dummy"], icon)
+ var/iconData = GLOB.dummySave.ExportText("dummy")
var/list/partial = splittext(iconData, "{")
return replacetext(copytext_char(partial[2], 3, -5), "\n", "")
@@ -1137,10 +1148,10 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
if (isfile(thing)) //special snowflake
var/name = sanitize_filename("[generate_asset_name(thing)].png")
if(!SSassets.cache[name])
- register_asset(name, thing)
+ SSassets.transport.register_asset(name, thing)
for (var/thing2 in targets)
- send_asset(thing2, key)
- return ""
+ SSassets.transport.send_assets(thing2, name)
+ return "
"
var/atom/A = thing
if (isnull(dir))
dir = A.dir
@@ -1162,11 +1173,11 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
key = "[generate_asset_name(I)].png"
if(!SSassets.cache[key])
- register_asset(key, I)
+ SSassets.transport.register_asset(key, I)
for (var/thing2 in targets)
- send_asset(thing2, key)
+ SSassets.transport.send_assets(thing2, key)
- return "
"
+ return "
"
/proc/icon2base64html(thing)
if (!thing)
diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index 045ca2c519..6dcb5f2534 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -358,7 +358,7 @@
roundend_report.stylesheets = list()
roundend_report.add_stylesheet("roundend", 'html/browser/roundend.css')
roundend_report.add_stylesheet("font-awesome", 'html/font-awesome/css/all.min.css')
- roundend_report.open(0)
+ roundend_report.open(FALSE)
/datum/controller/subsystem/ticker/proc/personal_report(client/C, popcount)
var/list/parts = list()
diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm
index 7a18d2ce01..c4d105a3a6 100644
--- a/code/__HELPERS/type2type.dm
+++ b/code/__HELPERS/type2type.dm
@@ -620,6 +620,12 @@
else //regex everything else (works for /proc too)
return lowertext(replacetext("[the_type]", "[type2parent(the_type)]/", ""))
+
+/// Return html to load a url.
+/// for use inside of browse() calls to html assets that might be loaded on a cdn.
+/proc/url2htmlloader(url)
+ return {"