diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 82d6d0c2446..cccc2ffb1a9 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -113,6 +113,7 @@ jobs:
sudo apt update || true
sudo apt install zlib1g-dev:i386 libssl-dev:i386
ldd librust_g.so
+ ldd libverdigris.so
- name: Unit Tests
run: |
tools/ci/install_byond.sh
diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
index 185ac8c9c77..661ef6384e5 100644
--- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
@@ -292,7 +292,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
- "\The [user] unfastens \the [src].", \
+ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear ratchet.")
deconstruct()
diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm
index d05f4fdc824..70784f0519d 100644
--- a/code/ATMOSPHERICS/components/binary_devices/pump.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm
@@ -252,7 +252,7 @@ Thus, the two variables affect pump operation are set in New():
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
- "\The [user] unfastens \the [src].", \
+ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear ratchet.")
deconstruct()
diff --git a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm
index 60040ddd8bc..aecb911561c 100644
--- a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm
+++ b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm
@@ -91,7 +91,7 @@
playsound(src, W.usesound, 50, 1)
if(do_after(user, 40 * W.toolspeed))
user.visible_message( \
- "\The [user] unfastens \the [src].", \
+ span_infoplain(span_bold("\The [user]") + "unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
diff --git a/code/ATMOSPHERICS/components/portables_connector.dm b/code/ATMOSPHERICS/components/portables_connector.dm
index 1974cdb1d6c..2dbc9afc00e 100644
--- a/code/ATMOSPHERICS/components/portables_connector.dm
+++ b/code/ATMOSPHERICS/components/portables_connector.dm
@@ -162,7 +162,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
- "\The [user] unfastens \the [src].", \
+ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
index 3fd2380e0f7..ef3149f78ef 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
@@ -105,7 +105,7 @@
// return
// usr.set_machine(src)
// var/list/node_connects = get_node_connect_dirs()
- // var/dat = {"Power: [use_power?"On":"Off"]
+ // var/dat = {span_bold("Power: ") + "[use_power?"On":"Off"]
// Set Flow Rate Limit:
// [set_flow_rate]L/s | Change
//
diff --git a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm
index 61ade8f501a..9e1d183b9bb 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm
@@ -62,7 +62,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
- "\The [user] unfastens \the [src].", \
+ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
diff --git a/code/ATMOSPHERICS/components/tvalve.dm b/code/ATMOSPHERICS/components/tvalve.dm
index f220c459045..0e051d9067d 100644
--- a/code/ATMOSPHERICS/components/tvalve.dm
+++ b/code/ATMOSPHERICS/components/tvalve.dm
@@ -337,7 +337,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
- "\The [user] unfastens \the [src].", \
+ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
diff --git a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm
index 2f69eaacc53..7b6a5621eb1 100644
--- a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm
+++ b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm
@@ -81,7 +81,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
- "\The [user] unfastens \the [src].", \
+ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
diff --git a/code/ATMOSPHERICS/components/unary/outlet_injector.dm b/code/ATMOSPHERICS/components/unary/outlet_injector.dm
index fc817774194..fa47021ddde 100644
--- a/code/ATMOSPHERICS/components/unary/outlet_injector.dm
+++ b/code/ATMOSPHERICS/components/unary/outlet_injector.dm
@@ -171,7 +171,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
- "\The [user] unfastens \the [src].", \
+ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm
index e59f5fc4981..9f32aa32ecc 100644
--- a/code/ATMOSPHERICS/components/unary/vent_pump.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm
@@ -398,7 +398,7 @@
if(!src || !WT.isOn()) return
playsound(src, WT.usesound, 50, 1)
if(!welded)
- user.visible_message("\The [user] welds the vent shut.", span_notice("You weld the vent shut."), "You hear welding.")
+ user.visible_message(span_bold("\The [user]") + " welds the vent shut.", span_notice("You weld the vent shut."), "You hear welding.")
welded = 1
update_icon()
else
@@ -446,7 +446,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
- "\The [user] unfastens \the [src].", \
+ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
index 93082e06fe2..0fc8d0cff79 100644
--- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
@@ -287,7 +287,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
- "\The [user] unfastens \the [src].", \
+ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
diff --git a/code/ATMOSPHERICS/components/valve.dm b/code/ATMOSPHERICS/components/valve.dm
index a0612901841..9139f96e749 100644
--- a/code/ATMOSPHERICS/components/valve.dm
+++ b/code/ATMOSPHERICS/components/valve.dm
@@ -301,7 +301,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
- "\The [user] unfastens \the [src].", \
+ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
diff --git a/code/ATMOSPHERICS/pipes/pipe_base.dm b/code/ATMOSPHERICS/pipes/pipe_base.dm
index 0c7a40ae6b2..ff6fb4bba2f 100644
--- a/code/ATMOSPHERICS/pipes/pipe_base.dm
+++ b/code/ATMOSPHERICS/pipes/pipe_base.dm
@@ -130,7 +130,7 @@
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if (do_after(user, 10 * W.toolspeed))
user.visible_message( \
- "\The [user] unfastens \the [src].", \
+ span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
diff --git a/code/ZAS/Variable Settings.dm b/code/ZAS/Variable Settings.dm
index c4699c7ab02..8867060e6fc 100644
--- a/code/ZAS/Variable Settings.dm
+++ b/code/ZAS/Variable Settings.dm
@@ -110,7 +110,7 @@ var/global/vs_control/vsc = new
vw = vars[ch]
if("[ch]_DESC" in vars) vw_desc = vars["[ch]_DESC"]
if("[ch]_NAME" in vars) vw_name = vars["[ch]_NAME"]
- dat += "[vw_name] = [vw] \[Change\]
"
+ dat += span_bold("[vw_name] = [vw]") + " \[Change\]
"
dat += "[vw_desc]
"
user << browse(dat,"window=settings")
@@ -168,7 +168,7 @@ var/global/vs_control/vsc = new
vars[ch] = vw
if(how == "Toggle")
newvar = (newvar?"ON":"OFF")
- to_world(span_notice("[key_name(user)] changed the setting [display_description] to [newvar]."))
+ to_world(span_world(span_blue("[key_name(user)] changed the setting [display_description] to [newvar].")))
if(ch in plc.settings)
ChangeSettingsDialog(user,plc.settings)
else
@@ -321,7 +321,7 @@ var/global/vs_control/vsc = new
plc.N2O_HALLUCINATION = initial(plc.N2O_HALLUCINATION)
- to_world(span_notice("[key_name(user)] changed the global phoron/ZAS settings to \"[def]\""))
+ to_world(span_world(span_blue("[key_name(user)] changed the global phoron/ZAS settings to \"[def]\"")))
/pl_control/var/list/settings = list()
diff --git a/code/__defines/MC.dm b/code/__defines/MC.dm
index 57161ffac8c..5173da844c6 100644
--- a/code/__defines/MC.dm
+++ b/code/__defines/MC.dm
@@ -63,6 +63,10 @@
#define SS_PAUSED 3 /// paused by mc_tick_check
#define SS_SLEEPING 4 /// fire() slept.
#define SS_PAUSING 5 /// in the middle of pausing
+// Subsystem init stages
+#define INITSTAGE_EARLY 1 //! Early init stuff that doesn't need to wait for mapload
+#define INITSTAGE_MAIN 2 //! Main init stage
+#define INITSTAGE_MAX 2 //! Highest initstage.
#define SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/##X);\
/datum/controller/subsystem/##X/New(){\
diff --git a/code/__defines/_click.dm b/code/__defines/_click.dm
new file mode 100644
index 00000000000..3bc9c08734b
--- /dev/null
+++ b/code/__defines/_click.dm
@@ -0,0 +1,56 @@
+//Defines file for byond click related parameters
+//this is mostly for ease of use and for finding all the things that use say RIGHT_CLICK rather then just searching "right"
+
+//Mouse buttons held
+#define RIGHT_CLICK "right"
+#define MIDDLE_CLICK "middle"
+#define LEFT_CLICK "left"
+
+///Mouse button that was just clicked/released
+///if(modifiers[BUTTON] == LEFT_CLICK)
+#define BUTTON "button"
+
+//Keys held down during the mouse action
+#define CTRL_CLICK "ctrl"
+#define ALT_CLICK "alt"
+#define SHIFT_CLICK "shift"
+
+//Cells involved if using a Grid control
+#define DRAG_CELL "drag-cell"
+#define DROP_CELL "drop-cell"
+
+//The button used for dragging (only sent for unrelated mouse up/down messages during a drag)
+#define DRAG "drag"
+
+//If the mouse is over a link in maptext, or this event is related to clicking such a link
+#define LINK "link"
+
+//Pixel coordinates relative to the icon's position on screen
+#define VIS_X "vis-x"
+#define VIS_Y "vis-y"
+
+//Pixel coordinates within the icon, in the icon's coordinate space
+#define ICON_X "icon-x"
+#define ICON_Y "icon-y"
+
+//Pixel coordinates in screen_loc format ("[tile_x]:[pixel_x],[tile_y]:[pixel_y]")
+#define SCREEN_LOC "screen-loc"
+
+//https://secure.byond.com/docs/ref/info.html#/atom/var/mouse_opacity
+/// Objects will ignore being clicked on regardless of their transparency (used in parallax, lighting effects, holograms, lasers, etc.)
+#define MOUSE_OPACITY_TRANSPARENT 0
+/// Objects will be clicked on if it is the topmost object and the pixel isn't transparent at the position of the mouse (default behavior for 99.99% of game objects)
+#define MOUSE_OPACITY_ICON 1
+/// Objects will be always be clicked on regardless of pixel transparency or other objects at that location (used in space vines, storage containers)
+#define MOUSE_OPACITY_OPAQUE 2
+
+/// Whatever the base action datum thinks is best
+#define SCRN_OBJ_DEFAULT "default"
+/// Floating somewhere on the hud, not in any predefined place
+#define SCRN_OBJ_FLOATING "floating"
+/// In the list of buttons stored at the top of the screen
+#define SCRN_OBJ_IN_LIST "list"
+/// In the collapseable palette
+#define SCRN_OBJ_IN_PALETTE "palette"
+/// In cult spell list
+#define SCRN_OBJ_CULT_LIST "cult_list"
diff --git a/code/__defines/_helpers.dm b/code/__defines/_helpers.dm
new file mode 100644
index 00000000000..b2165492bd5
--- /dev/null
+++ b/code/__defines/_helpers.dm
@@ -0,0 +1,14 @@
+// Stuff that is relatively "core" and is used in other defines/helpers
+
+/**
+ * The game's world.icon_size. \
+ * Ideally divisible by 16. \
+ * Ideally a number, but it
+ * can be a string ("32x32"), so more exotic coders
+ * will be sad if you use this in math.
+ */
+#define ICON_SIZE_ALL 32
+/// The X/Width dimension of ICON_SIZE. This will more than likely be the bigger axis.
+#define ICON_SIZE_X 32
+/// The Y/Height dimension of ICON_SIZE. This will more than likely be the smaller axis.
+#define ICON_SIZE_Y 32
diff --git a/code/__defines/_tick.dm b/code/__defines/_tick.dm
index 54ac7d398d9..f336c2e27b2 100644
--- a/code/__defines/_tick.dm
+++ b/code/__defines/_tick.dm
@@ -1,15 +1,27 @@
+/// Percentage of tick to leave for master controller to run
+#define MAPTICK_MC_MIN_RESERVE 70
+#define MAPTICK_LAST_INTERNAL_TICK_USAGE (world.map_cpu)
#define TICK_LIMIT_RUNNING 80
+/// Tick limit used to resume things in stoplag
#define TICK_LIMIT_TO_RUN 70
+/// Tick limit for MC while running
#define TICK_LIMIT_MC 70
#define TICK_LIMIT_MC_INIT_DEFAULT 98
+/// for general usage of tick_usage
#define TICK_USAGE world.tick_usage
+/// to be used where the result isn't checked
+#define TICK_USAGE_REAL world.tick_usage
+/// Returns true if tick_usage is above the limit
#define TICK_CHECK ( TICK_USAGE > Master.current_ticklimit )
+/// runs stoplag if tick_usage is above the limit
#define CHECK_TICK ( TICK_CHECK ? stoplag() : 0 )
+/// Returns true if tick usage is above 95, for high priority usage
#define TICK_CHECK_HIGH_PRIORITY ( TICK_USAGE > 95 )
+/// runs stoplag if tick_usage is above 95, for high priority usage
#define CHECK_TICK_HIGH_PRIORITY ( TICK_CHECK_HIGH_PRIORITY? stoplag() : 0 )
-#define UNTIL(X) while(!(X)) stoplag()
\ No newline at end of file
+#define UNTIL(X) while(!(X)) stoplag()
diff --git a/code/__defines/action.dm b/code/__defines/action.dm
index bdbe228777c..3f9b8a5e414 100644
--- a/code/__defines/action.dm
+++ b/code/__defines/action.dm
@@ -1,5 +1,4 @@
#define AB_CHECK_RESTRAINED 1
#define AB_CHECK_STUNNED 2
#define AB_CHECK_LYING 4
-#define AB_CHECK_ALIVE 8
-#define AB_CHECK_INSIDE 16
+#define AB_CHECK_CONSCIOUS 8
diff --git a/code/__defines/cooldowns.dm b/code/__defines/cooldowns.dm
index d177ae1e815..ac73690d916 100644
--- a/code/__defines/cooldowns.dm
+++ b/code/__defines/cooldowns.dm
@@ -27,6 +27,7 @@
// random cooldowns
#define COOLDOWN_VENOM_MILKING "venom_milking"
+#define COOLDOWN_SHIP_REFRESH "ship_refresh"
// admin verb cooldowns
#define COOLDOWN_INTERNET_SOUND "internet_sound"
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index 3803d198d4f..270235992b7 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -310,11 +310,6 @@ var/global/list/##LIST_NAME = list();\
#define RAD_RESIST_CALC_DIV 0 // Each turf absorbs some fraction of the working radiation level
#define RAD_RESIST_CALC_SUB 1 // Each turf absorbs a fixed amount of radiation
-//https://secure.byond.com/docs/ref/info.html#/atom/var/mouse_opacity
-#define MOUSE_OPACITY_TRANSPARENT 0
-#define MOUSE_OPACITY_ICON 1
-#define MOUSE_OPACITY_OPAQUE 2
-
// Used by radios to indicate that they have sent a message via something other than subspace
#define RADIO_CONNECTION_FAIL 0
#define RADIO_CONNECTION_NON_SUBSPACE 1
diff --git a/code/__defines/span_vr.dm b/code/__defines/span_vr.dm
index 6a4748e5ee2..1412420fe23 100644
--- a/code/__defines/span_vr.dm
+++ b/code/__defines/span_vr.dm
@@ -47,6 +47,7 @@
#define span_say(str) ("" + str + "")
#define span_emote(str) ("" + str + "")
#define span_emote_subtle(str) ("" + str + "")
+#define span_filter_say(str) ("" + str + "")
// Filtered as NPC messages
#define span_npc_say(str) ("" + str + "")
@@ -58,13 +59,9 @@
// Unfiltered, only style!
#define span_name(str) ("" + str + "")
#define span_game(str) ("" + str + "")
-#define span_filter_say(str) ("" + str + "")
#define span_message(str) ("") // TODO: This makes no sense, check it!
#define span_notify(str) ("" + str + "") // TODO: This makes no sense, check it!
#define span_body(str) ("" + str + "")
-#define span_filter_warning(str) ("" + str + "")
-#define span_filter_combat(str) ("" + str + "")
-#define span_filter_notice(str) ("" + str + "")
// Filtered under combat!
#define span_attack(str) ("" + str + "")
@@ -72,6 +69,7 @@
#define span_passive(str) ("" + str + "")
#define span_danger(str) ("" + str + "")
#define span_bolddanger(str) ("" + str + "")
+#define span_filter_combat(str) ("" + str + "")
// Filtered under warning messages
#define span_critical(str) ("" + str + "")
@@ -79,7 +77,7 @@
#define span_warning(str) ("" + str + "")
#define span_warningplain(str) ("" + str + "")
#define span_boldwarning(str) ("" + str + "")
-#define span_sinister(str) ("" + str + "")
+#define span_filter_warning(str) ("" + str + "") // Close to warning plain, maybe replace
// FIltered under info
#define span_info(str) ("" + str + "")
@@ -88,11 +86,14 @@
#define span_unconscious(str) ("" + str + "")
#define span_hear(str) ("" + str + "")
#define span_notice(str) ("" + str + "")
+#define span_filter_notice(str) ("" + str + "") // Close to infoplain, maybe replace
#define span_boldnotice(str) ("" + str + "")
#define span_adminnotice(str) ("" + str + "")
#define span_alium(str) ("" + str + "")
#define span_cult(str) ("" + str + "")
+#define span_pnarrate(str) ("" + str + "")
+
/* Direct communication spans */
// Local pred / prey filter
#define span_psay(str) ("" + str + "")
@@ -148,6 +149,7 @@
#define span_orange(str) ("" + str + "")
#define span_blue(str) ("" + str + "")
#define span_green(str) ("" + str + "")
+#define span_darkgreen(str) ("" + str + "") // Do not use regularly!
#define span_purple(str) ("" + str + "")
#define span_yellow(str) ("" + str + "")
#define span_pink(str) ("" + str + "")
@@ -156,25 +158,29 @@
#define span_maroon(str) ("" + str + "")
#define span_brown(str) ("" + str + "")
#define span_lightpurple(str) ("" + str + "")
-#define span_darkpink(str) ("" + str + "")
+#define span_darkpink(str) ("" + str + "")
#define span_rose(str) ("" + str + "")
/* System and Debug */
// System filter
#define span_boldannounce(str) ("" + str + "")
+#define span_world(str) ("" + str + "") // Bold system messages, use this for important world messages to make sure players can't filter them!
+#define span_filter_system(str) ("" + str + "") // Plain system filter
+#define span_sinister(str) ("" + str + "")
// Unfiltered
#define span_prefix(str) ("" + str + "")
#define span_admin(str) ("" + str + "")
#define span_linkOn(str) ("" + str + "")
#define span_linkOff(str) ("" + str + "")
-#define span_filter_system(str) ("" + str + "")
-#define span_filter_pm(str) ("" + str + "")
-#define span_filter_pray(str) ("" + str + "")
+#define span_filter_pray(str) ("" + str + "") // (Uses the chat message type directly)
// Admin log filters
#define span_log_message(str) ("")
-#define span_filter_adminlog(str) ("" + str + "")
+#define span_filter_adminlog(str) ("" + str + "") // (Uses the chat message type directly)
+
+// Attack log filter
+#define span_filter_attacklog(str) ("" + str + "") // (Uses the chat message type directly)
// Debug filter
#define span_debug_error(str) ("" + str + "")
@@ -182,7 +188,7 @@
#define span_debug_info(str) ("" + str + "")
#define span_debug_debug(str) ("" + str + "")
#define span_debug_trace(str) ("" + str + "")
-#define span_filter_debuglogs(str) ("" + str + "")
+#define span_filter_debuglogs(str) ("" + str + "") // (Uses the chat message type directly)
/* Admin only usage */
// Admin pm filter
@@ -190,6 +196,7 @@
#define span_adminhelp(str) ("" + str + "")
#define span_admin_pm_notice(str) ("" + str + "")
#define span_admin_pm_warning(str) ("" + str + "")
+#define span_filter_pm(str) ("" + str + "")
// Mentor pm filter
#define span_mentor(str) ("" + str + "")
@@ -215,6 +222,10 @@
#define span_giant(str) "" + str + ""
+#define span_giganteus(str) "" + str + ""
+
+#define span_massive(str) "" + str + ""
+
#define span_narsie(str) "" + str + ""
#define span_cascade(str) "" + str + ""
@@ -227,3 +238,6 @@
// Links!
#define span_linkify(str) ("" + str + "")
+
+// Just used downstream
+#define span_wingdings(str) ("" + str + "")
diff --git a/code/__defines/statpanel.dm b/code/__defines/statpanel.dm
new file mode 100644
index 00000000000..1c304d7fb39
--- /dev/null
+++ b/code/__defines/statpanel.dm
@@ -0,0 +1,2 @@
+#define TURFLIST_UPDATED (1 << 0)
+#define TURFLIST_UPDATE_QUEUED (1 << 1)
diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm
index 84c6fbd8a7c..b2838f79a2e 100644
--- a/code/__defines/subsystems.dm
+++ b/code/__defines/subsystems.dm
@@ -109,6 +109,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define INIT_ORDER_SKYBOX -30 //Visual only, irrelevant to gameplay, but needs to be late enough to have overmap populated fully
#define INIT_ORDER_TICKER -50
#define INIT_ORDER_MAPRENAME -60 //Initiating after Ticker to ensure everything is loaded and everything we rely on us working
+#define INIT_ORDER_STATPANELS -98
#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
@@ -140,6 +141,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define FIRE_PRIORITY_MACHINES 100
#define FIRE_PRIORITY_TGUI 110
#define FIRE_PRIORITY_PROJECTILES 150
+#define FIRE_PRIORITY_STATPANEL 390
#define FIRE_PRIORITY_CHAT 400
#define FIRE_PRIORITY_OVERLAYS 500
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
diff --git a/code/__defines/tgs.config.dm b/code/__defines/tgs.config.dm
index 57afe12ed77..c57439c7e45 100644
--- a/code/__defines/tgs.config.dm
+++ b/code/__defines/tgs.config.dm
@@ -2,7 +2,7 @@
#define TGS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name)
#define TGS_READ_GLOBAL(Name) GLOB.##Name
#define TGS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value
-#define TGS_WORLD_ANNOUNCE(message) to_chat(world, span_boldannounce([html_encode(##message)]))
+#define TGS_WORLD_ANNOUNCE(message) to_chat(world, span_boldannounce("[html_encode(##message)]"))
#define TGS_INFO_LOG(message) log_to_dd("TGS Info: [##message]")
#define TGS_WARNING_LOG(message) log_to_dd("TGS Warn: [##message]")
#define TGS_ERROR_LOG(message) log_to_dd("TGS Error: [##message]")
diff --git a/code/__defines/time.dm b/code/__defines/time.dm
index 9b3c384cfb3..857e2fa1556 100644
--- a/code/__defines/time.dm
+++ b/code/__defines/time.dm
@@ -1,3 +1,6 @@
+///displays the current time into the round, with a lot of extra code just there for ensuring it looks okay after an entire day passes
+#define ROUND_TIME(...) ( "[world.time - SSticker.round_start_time > MIDNIGHT_ROLLOVER ? "[round((world.time - SSticker.round_start_time)/MIDNIGHT_ROLLOVER)]:[worldtime2text()]" : worldtime2text()]" )
+
/// Define that just has the current in-universe year for use in whatever context you might want to display that in. (For example, 2022 -> 2562 given a 540 year offset)
#define CURRENT_STATION_YEAR (GLOB.year_integer + STATION_YEAR_OFFSET)
diff --git a/code/__defines/verdigris/_verdigris.dm b/code/__defines/verdigris/_verdigris.dm
new file mode 100644
index 00000000000..021506ac466
--- /dev/null
+++ b/code/__defines/verdigris/_verdigris.dm
@@ -0,0 +1,18 @@
+/* This comment bypasses grep checks */ /var/__verdigris
+
+/proc/__detect_verdigris()
+ if (world.system_type == UNIX)
+ return __verdigris = (fexists("./libverdigris.so") ? "./libverdigris.so" : "libverdigris")
+ else
+ return __verdigris = "verdigris"
+
+#define VERDIGRIS (__verdigris || __detect_verdigris())
+#define VERDIGRIS_CALL(name, args...) call_ext(VERDIGRIS, "byond:" + name)(args)
+
+/proc/verdigris_version() return VERDIGRIS_CALL("verdigris_version")
+/proc/verdigris_features() return VERDIGRIS_CALL("verdigris_features")
+/proc/verdigris_cleanup() return VERDIGRIS_CALL("cleanup")
+
+/world/New()
+ verdigris_cleanup()
+ ..()
diff --git a/code/__defines/verdigris/random_map.dm b/code/__defines/verdigris/random_map.dm
new file mode 100644
index 00000000000..5f8a2372678
--- /dev/null
+++ b/code/__defines/verdigris/random_map.dm
@@ -0,0 +1,3 @@
+/proc/verdigris_generate_automata(limit_x, limit_y, iterations, initial_wall_cell) as /list
+ RETURN_TYPE(/list)
+ return VERDIGRIS_CALL("generate_automata", limit_x, limit_y, iterations, initial_wall_cell)
diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm
index a81c09b314f..ae731264726 100644
--- a/code/_helpers/icons.dm
+++ b/code/_helpers/icons.dm
@@ -97,203 +97,205 @@
// Ported from /tg/station
// Creates a single icon from a given /atom or /image. Only the first argument is required.
-/proc/getFlatIcon(image/A, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE)
- //Define... defines.
+// appearance_flags indicates whether appearance_flags should be respected (at the cost of about 10-20% perf)
+/proc/getFlatIcon(image/appearance, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE, force_south = FALSE, appearance_flags = FALSE)
+ // Loop through the underlays, then overlays, sorting them into the layers list
+ #define PROCESS_OVERLAYS_OR_UNDERLAYS(flat, process, base_layer) \
+ for (var/i in 1 to process.len) { \
+ var/image/current = process[i]; \
+ if (!current) { \
+ continue; \
+ } \
+ if (current.plane != FLOAT_PLANE && current.plane != appearance.plane) { \
+ continue; \
+ } \
+ var/current_layer = current.layer; \
+ if (current_layer < 0) { \
+ if (current_layer <= -1000) { \
+ return flat; \
+ } \
+ current_layer = base_layer + appearance.layer + current_layer / 1000; \
+ } \
+ for (var/index_to_compare_to in 1 to layers.len) { \
+ var/compare_to = layers[index_to_compare_to]; \
+ if (current_layer < layers[compare_to]) { \
+ layers.Insert(index_to_compare_to, current); \
+ break; \
+ } \
+ } \
+ layers[current] = current_layer; \
+ }
+
var/static/icon/flat_template = icon('icons/effects/effects.dmi', "nothing")
- #define BLANK icon(flat_template)
- #define SET_SELF(SETVAR) do { \
- var/icon/SELF_ICON=icon(icon(curicon, curstate, base_icon_dir),"",SOUTH,no_anim?1:null); \
- if(A.alpha<255) { \
- SELF_ICON.Blend(rgb(255,255,255,A.alpha),ICON_MULTIPLY);\
- } \
- if(A.color) { \
- if(islist(A.color)){ \
- SELF_ICON.MapColors(arglist(A.color))} \
- else{ \
- SELF_ICON.Blend(A.color,ICON_MULTIPLY)} \
- } \
- ##SETVAR=SELF_ICON;\
- } while (0)
- #define INDEX_X_LOW 1
- #define INDEX_X_HIGH 2
- #define INDEX_Y_LOW 3
- #define INDEX_Y_HIGH 4
-
- #define flatX1 flat_size[INDEX_X_LOW]
- #define flatX2 flat_size[INDEX_X_HIGH]
- #define flatY1 flat_size[INDEX_Y_LOW]
- #define flatY2 flat_size[INDEX_Y_HIGH]
- #define addX1 add_size[INDEX_X_LOW]
- #define addX2 add_size[INDEX_X_HIGH]
- #define addY1 add_size[INDEX_Y_LOW]
- #define addY2 add_size[INDEX_Y_HIGH]
-
- if(!A || A.alpha <= 0)
- return BLANK
-
- var/noIcon = FALSE
+ if(!appearance || appearance.alpha <= 0)
+ return icon(flat_template)
if(start)
if(!defdir)
- defdir = A.dir
+ defdir = appearance.dir
if(!deficon)
- deficon = A.icon
+ deficon = appearance.icon
if(!defstate)
- defstate = A.icon_state
+ defstate = appearance.icon_state
if(!defblend)
- defblend = A.blend_mode
+ defblend = appearance.blend_mode
- var/curicon = A.icon || deficon
- var/curstate = A.icon_state || defstate
+ var/curicon = appearance.icon || deficon
+ var/curstate = appearance.icon_state || defstate
+ var/curdir = (!appearance.dir || appearance.dir == SOUTH) ? defdir : appearance.dir
- if(!((noIcon = (!curicon))))
- var/curstates = cached_icon_states(curicon)
+ if(force_south)
+ curdir = SOUTH
+
+ var/render_icon = curicon
+
+ if (render_icon)
+ var/curstates = icon_states(curicon)
if(!(curstate in curstates))
- if("" in curstates)
+ if ("" in curstates)
curstate = ""
else
- noIcon = TRUE // Do not render this object.
+ render_icon = FALSE
- var/curdir
- var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have
+ var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have
- // Use the requested dir or the atom's current dir
- curdir = defdir || A.dir
-
- //Try to remove/optimize this section ASAP, CPU hog. //Slightly mitigated by implementing caching using cached_icon_states
+ //Try to remove/optimize this section ASAP, CPU hog.
//Determines if there's directionals.
- if(!noIcon && curdir != SOUTH)
- var/exist = FALSE
- var/static/list/checkdirs = list(NORTH, EAST, WEST)
- for(var/i in checkdirs) //Not using GLOB for a reason.
- if(length(cached_icon_states(icon(curicon, curstate, i))))
- exist = TRUE
- break
- if(!exist)
+ if(render_icon && curdir != SOUTH)
+ if (
+ !length(icon_states(icon(curicon, curstate, NORTH))) \
+ && !length(icon_states(icon(curicon, curstate, EAST))) \
+ && !length(icon_states(icon(curicon, curstate, WEST))) \
+ )
base_icon_dir = SOUTH
- //
if(!base_icon_dir)
base_icon_dir = curdir
- ASSERT(!BLEND_DEFAULT) //I might just be stupid but lets make sure this define is 0.
+ var/curblend = appearance.blend_mode || defblend
- var/curblend = A.blend_mode || defblend
-
- if(A.overlays.len || A.underlays.len)
- var/icon/flat = BLANK
+ if(appearance.overlays.len || appearance.underlays.len)
+ var/icon/flat = icon(flat_template)
// Layers will be a sorted list of icons/overlays, based on the order in which they are displayed
var/list/layers = list()
var/image/copy
// Add the atom's icon itself, without pixel_x/y offsets.
- if(!noIcon)
- copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=base_icon_dir)
- copy.color = A.color
- copy.alpha = A.alpha
+ if(render_icon)
+ copy = image(icon=curicon, icon_state=curstate, layer=appearance.layer, dir=base_icon_dir)
+ copy.color = appearance.color
+ copy.alpha = appearance.alpha
copy.blend_mode = curblend
- layers[copy] = A.layer
+ layers[copy] = appearance.layer
- // Loop through the underlays, then overlays, sorting them into the layers list
- for(var/process_set in 0 to 1)
- var/list/process = process_set? A.overlays : A.underlays
- for(var/i in 1 to process.len)
- var/image/current = process[i]
- if(!current)
- continue
- if(current.plane != FLOAT_PLANE && current.plane != A.plane)
- continue
- var/current_layer = current.layer
- if(current_layer < 0)
- //if(current_layer <= -1000)
- //return flat
- current_layer = process_set + A.layer + current_layer / 1000
-
- for(var/p in 1 to layers.len)
- var/image/cmp = layers[p]
- if(current_layer < layers[cmp])
- layers.Insert(p, current)
- break
- layers[current] = current_layer
-
- //sortTim(layers, GLOBAL_PROC_REF(cmp_image_layer_asc))
+ PROCESS_OVERLAYS_OR_UNDERLAYS(flat, appearance.underlays, 0)
+ PROCESS_OVERLAYS_OR_UNDERLAYS(flat, appearance.overlays, 1)
var/icon/add // Icon of overlay being added
- // Current dimensions of flattened icon
- var/list/flat_size = list(1, flat.Width(), 1, flat.Height())
- // Dimensions of overlay being added
- var/list/add_size[4]
+ var/flatX1 = 1
+ var/flatX2 = flat.Width()
+ var/flatY1 = 1
+ var/flatY2 = flat.Height()
- for(var/V in layers)
- var/image/I = V
- if(I.alpha == 0)
+ var/addX1 = 0
+ var/addX2 = 0
+ var/addY1 = 0
+ var/addY2 = 0
+
+ for(var/image/layer_image as anything in layers)
+ if(layer_image.alpha == 0)
continue
- if(I == copy) // 'I' is an /image based on the object being flattened.
+ // variables only relevant when accounting for appearance_flags:
+ var/apply_color = TRUE
+ var/apply_alpha = TRUE
+
+ if(layer_image == copy) // 'layer_image' is an /image based on the object being flattened.
curblend = BLEND_OVERLAY
- add = icon(I.icon, I.icon_state, base_icon_dir)
+ add = icon(layer_image.icon, layer_image.icon_state, base_icon_dir)
else // 'I' is an appearance object.
- add = getFlatIcon(image(I), curdir, curicon, curstate, curblend, FALSE, no_anim)
+ var/image/layer_as_image = image(layer_image)
+ if(appearance_flags)
+ if(layer_as_image.appearance_flags & RESET_COLOR)
+ apply_color = FALSE
+ if(layer_as_image.appearance_flags & RESET_ALPHA)
+ apply_alpha = FALSE
+ add = getFlatIcon(layer_as_image, curdir, curicon, curstate, curblend, FALSE, no_anim, force_south, appearance_flags)
if(!add)
continue
- // Find the new dimensions of the flat icon to fit the added overlay
- add_size = list(
- min(flatX1, I.pixel_x+1),
- max(flatX2, I.pixel_x+add.Width()),
- min(flatY1, I.pixel_y+1),
- max(flatY2, I.pixel_y+add.Height())
- )
- if(flat_size ~! add_size)
+ // Find the new dimensions of the flat icon to fit the added overlay
+ addX1 = min(flatX1, layer_image.pixel_x + 1)
+ addX2 = max(flatX2, layer_image.pixel_x + add.Width())
+ addY1 = min(flatY1, layer_image.pixel_y + 1)
+ addY2 = max(flatY2, layer_image.pixel_y + add.Height())
+
+ if (
+ addX1 != flatX1 \
+ || addX2 != flatX2 \
+ || addY1 != flatY1 \
+ || addY2 != flatY2 \
+ )
// Resize the flattened icon so the new icon fits
flat.Crop(
- addX1 - flatX1 + 1,
- addY1 - flatY1 + 1,
- addX2 - flatX1 + 1,
- addY2 - flatY1 + 1
+ addX1 - flatX1 + 1,
+ addY1 - flatY1 + 1,
+ addX2 - flatX1 + 1,
+ addY2 - flatY1 + 1
)
- flat_size = add_size.Copy()
+
+ flatX1 = addX1
+ flatX2 = addX2
+ flatY1 = addY1
+ flatY2 = addY2
+
+ if(appearance_flags)
+ // apply parent's color/alpha to the added layers if the layer didn't opt
+ if(apply_color && appearance.color)
+ if(islist(appearance.color))
+ add.MapColors(arglist(appearance.color))
+ else
+ add.Blend(appearance.color, ICON_MULTIPLY)
+
+ if(apply_alpha && appearance.alpha < 255)
+ add.Blend(rgb(255, 255, 255, appearance.alpha), ICON_MULTIPLY)
// Blend the overlay into the flattened icon
- flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1)
+ flat.Blend(add, blendMode2iconMode(curblend), layer_image.pixel_x + 2 - flatX1, layer_image.pixel_y + 2 - flatY1)
- if(A.color)
- if(islist(A.color))
- flat.MapColors(arglist(A.color))
- else
- flat.Blend(A.color, ICON_MULTIPLY)
+ if(!appearance_flags)
+ // If we didn't apply parent colors individually per layer respecting appearance_flags, then do it just the one time now
+ if(appearance.color)
+ if(islist(appearance.color))
+ flat.MapColors(arglist(appearance.color))
+ else
+ flat.Blend(appearance.color, ICON_MULTIPLY)
- if(A.alpha < 255)
- flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY)
+ if(appearance.alpha < 255)
+ flat.Blend(rgb(255, 255, 255, appearance.alpha), ICON_MULTIPLY)
if(no_anim)
//Clean up repeated frames
var/icon/cleaned = new /icon()
cleaned.Insert(flat, "", SOUTH, 1, 0)
- . = cleaned
+ return cleaned
else
- . = icon(flat, "", SOUTH)
- else //There's no overlays.
- if(!noIcon)
- SET_SELF(.)
+ return icon(flat, "", SOUTH)
+ else if (render_icon) // There's no overlays.
+ var/icon/final_icon = icon(icon(curicon, curstate, base_icon_dir), "", SOUTH, no_anim ? TRUE : null)
- //Clear defines
- #undef flatX1
- #undef flatX2
- #undef flatY1
- #undef flatY2
- #undef addX1
- #undef addX2
- #undef addY1
- #undef addY2
+ if (appearance.alpha < 255)
+ final_icon.Blend(rgb(255,255,255, appearance.alpha), ICON_MULTIPLY)
- #undef INDEX_X_LOW
- #undef INDEX_X_HIGH
- #undef INDEX_Y_LOW
- #undef INDEX_Y_HIGH
+ if (appearance.color)
+ if (islist(appearance.color))
+ final_icon.MapColors(arglist(appearance.color))
+ else
+ final_icon.Blend(appearance.color, ICON_MULTIPLY)
- #undef BLANK
- #undef SET_SELF
+ return final_icon
+
+ #undef PROCESS_OVERLAYS_OR_UNDERLAYS
/proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N
var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A.
@@ -676,7 +678,7 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
icon_state = thing.icon_state
//Despite casting to atom, this code path supports mutable appearances, so let's be nice to them
//if(isnull(icon_state) || (isatom(thing) && thing.flags_1 & HTML_USE_INITAL_ICON_1))
- if(isnull(icon_state) || isatom(thing))
+ if(isnull(icon_state) && isatom(thing))
icon_state = initial(thing.icon_state)
if (isnull(dir))
dir = initial(thing.dir)
@@ -745,7 +747,7 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
return ""
//Costlier version of icon2html() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs.
-/proc/costly_icon2html(thing, target, sourceonly = FALSE)
+/proc/costly_icon2html(thing, target, sourceonly = FALSE, force_south = FALSE)
if (!thing)
return
//if(SSlag_switch.measures[DISABLE_USR_ICON2HTML] && usr && !HAS_TRAIT(usr, TRAIT_BYPASS_MEASURES))
@@ -754,5 +756,5 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
if (isicon(thing))
return icon2html(thing, target)
- var/icon/I = getFlatIcon(thing)
+ var/icon/I = getFlatIcon(thing, force_south = force_south)
return icon2html(I, target, sourceonly = sourceonly)
diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm
index 2b61a877ba2..57795108c76 100644
--- a/code/_helpers/logging.dm
+++ b/code/_helpers/logging.dm
@@ -74,42 +74,42 @@
//Log the message to in-game dialogue logs, as well.
if(speaker.client)
- speaker.dialogue_log += "([time_stamp()]) ([speaker]/[speaker.client]) SAY: - [text]"
- GLOB.round_text_log += "([time_stamp()]) ([speaker]/[speaker.client]) SAY: - [text]"
+ speaker.dialogue_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("SAY:") + " - " + span_green("[text]")
+ GLOB.round_text_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("SAY:") + " - " + span_green("[text]")
/proc/log_ooc(text, client/user)
if (config.log_ooc)
WRITE_LOG(diary, "OOC: [user.simple_info_line()]: [html_decode(text)]")
- GLOB.round_text_log += "([time_stamp()]) ([user]) OOC: - [text]"
+ GLOB.round_text_log += span_bold("([time_stamp()])") + " (" + span_bold("[user]") + ") " + span_underline("OOC:") + " - " + span_blue(span_bold("[text]"))
/proc/log_aooc(text, client/user)
if (config.log_ooc)
WRITE_LOG(diary, "AOOC: [user.simple_info_line()]: [html_decode(text)]")
- GLOB.round_text_log += "([time_stamp()]) ([user]) AOOC: - [text]"
+ GLOB.round_text_log += span_bold("([time_stamp()])") + " (" + span_bold("[user]") + ") " + span_underline("AOOC:") + " - " + span_red(span_bold("[text]"))
/proc/log_looc(text, client/user)
if (config.log_ooc)
WRITE_LOG(diary, "LOOC: [user.simple_info_line()]: [html_decode(text)]")
- GLOB.round_text_log += "([time_stamp()]) ([user]) LOOC: - [text]"
+ GLOB.round_text_log += span_bold("([time_stamp()])") + " (" + span_bold("[user]") + ") " + span_underline("LOOC:") + " - " + span_orange(span_bold("[text]"))
/proc/log_whisper(text, mob/speaker)
if (config.log_whisper)
WRITE_LOG(diary, "WHISPER: [speaker.simple_info_line()]: [html_decode(text)]")
if(speaker.client)
- speaker.dialogue_log += "([time_stamp()]) ([speaker]/[speaker.client]) SAY: - [text]"
- GLOB.round_text_log += "([time_stamp()]) ([speaker]/[speaker.client]) SAY: - [text]"
+ speaker.dialogue_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("SAY:") + " - " + span_gray(span_italics("[text]"))
+ GLOB.round_text_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("SAY:") + " - " + span_gray(span_italics("[text]"))
/proc/log_emote(text, mob/speaker)
if (config.log_emote)
WRITE_LOG(diary, "EMOTE: [speaker.simple_info_line()]: [html_decode(text)]")
if(speaker.client)
- speaker.dialogue_log += "([time_stamp()]) ([speaker]/[speaker.client]) EMOTE: - [text]"
- GLOB.round_text_log += "([time_stamp()]) ([speaker]/[speaker.client]) EMOTE: - [text]"
+ speaker.dialogue_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("EMOTE:") + " - " + span_pink("[text]")
+ GLOB.round_text_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("EMOTE:") + " - " + span_pink("[text]")
/proc/log_attack(attacker, defender, message)
if (config.log_attack)
@@ -131,8 +131,8 @@
if (config.log_say)
WRITE_LOG(diary, "DEADCHAT: [speaker.simple_info_line()]: [html_decode(text)]")
- speaker.dialogue_log += "([time_stamp()]) ([speaker]/[speaker.client]) DEADSAY: - [text]"
- GLOB.round_text_log += "([time_stamp()]) ([speaker]/[speaker.client]) DEADSAY: - [text]"
+ speaker.dialogue_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("DEADSAY:") + " - " + span_green("[text]")
+ GLOB.round_text_log += span_small(span_purple(span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("DEADSAY:") + " - [text]"))
/proc/log_ghostemote(text, mob/speaker)
if (config.log_emote)
@@ -146,8 +146,8 @@
if (config.log_pda)
WRITE_LOG(diary, "PDA: [speaker.simple_info_line()]: [html_decode(text)]")
- speaker.dialogue_log += "([time_stamp()]) ([speaker]/[speaker.client]) MSG: - [text]"
- GLOB.round_text_log += "([time_stamp()]) ([speaker]/[speaker.client]) MSG: - [text]"
+ speaker.dialogue_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("MSG:") + " - " + span_darkgreen("[text]")
+ GLOB.round_text_log += span_bold("([time_stamp()])") + " (" + span_bold("[speaker]/[speaker.client]") + ") " + span_underline("MSG:") + " - " + span_darkgreen("[text]")
/proc/log_to_dd(text)
to_world_log(text) //this comes before the config check because it can't possibly runtime
diff --git a/code/_helpers/screen_objs.dm b/code/_helpers/screen_objs.dm
new file mode 100644
index 00000000000..00f6bd41570
--- /dev/null
+++ b/code/_helpers/screen_objs.dm
@@ -0,0 +1,115 @@
+/// Takes a screen loc string in the format
+/// "+-left-offset:+-pixel,+-bottom-offset:+-pixel"
+/// Where the :pixel is optional, and returns
+/// A list in the format (x_offset, y_offset)
+/// We require context to get info out of screen locs that contain relative info, so NORTH, SOUTH, etc
+/proc/screen_loc_to_offset(screen_loc, view)
+ if(!screen_loc)
+ return list(64, 64)
+ var/list/view_size = view_to_pixels(view)
+ var/x = 0
+ var/y = 0
+ // Time to parse for directional relative offsets
+ if(findtext(screen_loc, "EAST")) // If you're starting from the east, we start from the east too
+ x += view_size[1]
+ if(findtext(screen_loc, "WEST")) // HHHHHHHHHHHHHHHHHHHHHH WEST is technically a 1 tile offset from the start. Shoot me please
+ x += ICON_SIZE_X
+ if(findtext(screen_loc, "NORTH"))
+ y += view_size[2]
+ if(findtext(screen_loc, "SOUTH"))
+ y += ICON_SIZE_Y
+
+ var/list/x_and_y = splittext(screen_loc, ",")
+
+ var/list/x_pack = splittext(x_and_y[1], ":")
+ var/list/y_pack = splittext(x_and_y[2], ":")
+
+ var/x_coord = x_pack[1]
+ var/y_coord = y_pack[1]
+
+ if (findtext(x_coord, "CENTER"))
+ x += view_size[1] / 2
+
+ if (findtext(y_coord, "CENTER"))
+ y += view_size[2] / 2
+
+ x_coord = text2num(cut_relative_direction(x_coord))
+ y_coord = text2num(cut_relative_direction(y_coord))
+
+ x += x_coord * ICON_SIZE_X
+ y += y_coord * ICON_SIZE_Y
+
+ if(length(x_pack) > 1)
+ x += text2num(x_pack[2])
+ if(length(y_pack) > 1)
+ y += text2num(y_pack[2])
+ return list(x, y)
+
+/// Takes a list in the form (x_offset, y_offset)
+/// And converts it to a screen loc string
+/// Accepts an optional view string/size to force the screen_loc around, so it can't go out of scope
+/proc/offset_to_screen_loc(x_offset, y_offset, view = null)
+ if(view)
+ var/list/view_bounds = view_to_pixels(view)
+ x_offset = clamp(x_offset, ICON_SIZE_X, view_bounds[1])
+ y_offset = clamp(y_offset, ICON_SIZE_Y, view_bounds[2])
+
+ // Round with no argument is floor, so we get the non pixel offset here
+ var/x = round(x_offset / ICON_SIZE_X)
+ var/pixel_x = x_offset % ICON_SIZE_X
+ var/y = round(y_offset / ICON_SIZE_Y)
+ var/pixel_y = y_offset % ICON_SIZE_Y
+
+ var/list/generated_loc = list()
+ generated_loc += "[x]"
+ if(pixel_x)
+ generated_loc += ":[pixel_x]"
+ generated_loc += ",[y]"
+ if(pixel_y)
+ generated_loc += ":[pixel_y]"
+ return jointext(generated_loc, "")
+
+/**
+ * Returns a valid location to place a screen object without overflowing the viewport
+ *
+ * * target: The target location as a purely number based screen_loc string "+-left-offset:+-pixel,+-bottom-offset:+-pixel"
+ * * target_offset: The amount we want to offset the target location by. We explictly don't care about direction here, we will try all 4
+ * * view: The view variable of the client we're doing this for. We use this to get the size of the screen
+ *
+ * Returns a screen loc representing the valid location
+**/
+/proc/get_valid_screen_location(target_loc, target_offset, view)
+ var/list/offsets = screen_loc_to_offset(target_loc)
+ var/base_x = offsets[1]
+ var/base_y = offsets[2]
+
+ var/list/view_size = view_to_pixels(view)
+
+ // Bias to the right, down, left, and then finally up
+ if(base_x + target_offset < view_size[1])
+ return offset_to_screen_loc(base_x + target_offset, base_y, view)
+ if(base_y - target_offset > ICON_SIZE_Y)
+ return offset_to_screen_loc(base_x, base_y - target_offset, view)
+ if(base_x - target_offset > ICON_SIZE_X)
+ return offset_to_screen_loc(base_x - target_offset, base_y, view)
+ if(base_y + target_offset < view_size[2])
+ return offset_to_screen_loc(base_x, base_y + target_offset, view)
+ stack_trace("You passed in a scren location {[target_loc]} and offset {[target_offset]} that can't be fit in the viewport Width {[view_size[1]]}, Height {[view_size[2]]}. what did you do lad")
+ return null // The fuck did you do lad
+
+/// Takes a screen_loc string and cut out any directions like NORTH or SOUTH
+/proc/cut_relative_direction(fragment)
+ var/static/regex/regex = regex(@"([A-Z])\w+", "g")
+ return regex.Replace(fragment, "")
+
+/// Returns a screen_loc format for a tiling screen objects from start and end positions. Start should be bottom left corner, and end top right corner.
+/proc/spanning_screen_loc(start_px, start_py, end_px, end_py)
+ var/starting_tile_x = round(start_px / ICON_SIZE_X)
+ start_px -= starting_tile_x * ICON_SIZE_X
+ var/starting_tile_y = round(start_py/ ICON_SIZE_Y)
+ start_py -= starting_tile_y * ICON_SIZE_Y
+ var/ending_tile_x = round(end_px / ICON_SIZE_X)
+ end_px -= ending_tile_x * ICON_SIZE_X
+ var/ending_tile_y = round(end_py / ICON_SIZE_Y)
+ end_py -= ending_tile_y * ICON_SIZE_Y
+ return "[starting_tile_x]:[start_px],[starting_tile_y]:[start_py] to [ending_tile_x]:[end_px],[ending_tile_y]:[end_py]"
diff --git a/code/_helpers/time.dm b/code/_helpers/time.dm
index 802359a1b76..b1d372f435b 100644
--- a/code/_helpers/time.dm
+++ b/code/_helpers/time.dm
@@ -1,3 +1,7 @@
+//Returns the world time in english
+/proc/worldtime2text()
+ return gameTimestamp("hh:mm:ss", world.time)
+
#define TimeOfGame (get_game_time())
#define TimeOfTick (TICK_USAGE*0.01*world.tick_lag)
diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm
index 1a0d8434afe..c18a512db22 100644
--- a/code/_helpers/unsorted.dm
+++ b/code/_helpers/unsorted.dm
@@ -367,7 +367,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
if(isAI(src))
var/mob/living/silicon/ai/A = src
oldname = null//don't bother with the records update crap
- //to_world("[newname] is the AI!")
+ //to_world(span_world("[newname] is the AI!"))
//world << sound('sound/AI/newAI.ogg')
// Set eyeobj name
A.SetName(newname)
diff --git a/code/_helpers/verbs.dm b/code/_helpers/verbs.dm
new file mode 100644
index 00000000000..8a35bb9c6cf
--- /dev/null
+++ b/code/_helpers/verbs.dm
@@ -0,0 +1,94 @@
+/**
+ * handles adding verbs and updating the stat panel browser
+ *
+ * pass the verb type path to this instead of adding it directly to verbs so the statpanel can update
+ * Arguments:
+ * * target - Who the verb is being added to, client or mob typepath
+ * * verb - typepath to a verb, or a list of verbs, supports lists of lists
+ */
+/proc/add_verb(client/target, verb_or_list_to_add)
+ if(!target)
+ CRASH("add_verb called without a target")
+ if(IsAdminAdvancedProcCall())
+ return
+ var/mob/mob_target = null
+
+ if(ismob(target))
+ mob_target = target
+ target = mob_target.client
+ else if(!istype(target, /client))
+ CRASH("add_verb called on a non-mob and non-client")
+ var/list/verbs_list = list()
+ if(!islist(verb_or_list_to_add))
+ verbs_list += verb_or_list_to_add
+ else
+ var/list/verb_listref = verb_or_list_to_add
+ var/list/elements_to_process = verb_listref.Copy()
+ while(length(elements_to_process))
+ var/element_or_list = elements_to_process[length(elements_to_process)] //Last element
+ elements_to_process.len--
+ if(islist(element_or_list))
+ elements_to_process += element_or_list //list/a += list/b adds the contents of b into a, not the reference to the list itself
+ else
+ verbs_list += element_or_list
+
+ if(mob_target)
+ mob_target.verbs += verbs_list
+ if(!target)
+ return //Our work is done.
+ else
+ target.verbs += verbs_list
+
+ var/list/output_list = list()
+ for(var/thing in verbs_list)
+ var/procpath/verb_to_add = thing
+ output_list[++output_list.len] = list(verb_to_add.category, verb_to_add.name, verb_to_add.desc)
+
+ target.stat_panel.send_message("add_verb_list", output_list)
+
+/**
+ * handles removing verb and sending it to browser to update, use this for removing verbs
+ *
+ * pass the verb type path to this instead of removing it from verbs so the statpanel can update
+ * Arguments:
+ * * target - Who the verb is being removed from, client or mob typepath
+ * * verb - typepath to a verb, or a list of verbs, supports lists of lists
+ */
+/proc/remove_verb(client/target, verb_or_list_to_remove)
+ if(IsAdminAdvancedProcCall())
+ return
+
+ var/mob/mob_target = null
+ if(ismob(target))
+ mob_target = target
+ target = mob_target.client
+ else if(!istype(target, /client))
+ CRASH("remove_verb called on a non-mob and non-client")
+
+ var/list/verbs_list = list()
+ if(!islist(verb_or_list_to_remove))
+ verbs_list += verb_or_list_to_remove
+ else
+ var/list/verb_listref = verb_or_list_to_remove
+ var/list/elements_to_process = verb_listref.Copy()
+ while(length(elements_to_process))
+ var/element_or_list = elements_to_process[length(elements_to_process)] //Last element
+ elements_to_process.len--
+ if(islist(element_or_list))
+ elements_to_process += element_or_list //list/a += list/b adds the contents of b into a, not the reference to the list itself
+ else
+ verbs_list += element_or_list
+
+ if(mob_target)
+ mob_target.verbs -= verbs_list
+ if(!target)
+ return //Our work is done.
+ else
+ target.verbs -= verbs_list
+
+ var/list/output_list = list()
+ for(var/thing in verbs_list)
+ var/procpath/verb_to_remove = thing
+ output_list[++output_list.len] = list(verb_to_remove.category, verb_to_remove.name)
+
+ target.stat_panel.send_message("remove_verb_list", output_list)
diff --git a/code/_helpers/view.dm b/code/_helpers/view.dm
index be60a56697f..4615e0c97da 100644
--- a/code/_helpers/view.dm
+++ b/code/_helpers/view.dm
@@ -11,6 +11,15 @@
viewY = text2num(viewrangelist[2])
return list(viewX, viewY)
+/// Takes a string or num view, and converts it to pixel width/height in a list(pixel_width, pixel_height)
+/proc/view_to_pixels(view)
+ if(!view)
+ return list(0, 0)
+ var/list/view_info = getviewsize(view)
+ view_info[1] *= ICON_SIZE_X
+ view_info[2] *= ICON_SIZE_Y
+ return view_info
+
// Used to get `atom/O as obj|mob|turf in view()` to match against strings containing apostrophes immediately after substrings that match to other objects. Somehow. - Ater
/proc/_validate_atom(atom/A)
- return view()
\ No newline at end of file
+ return view()
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index d303529c1e0..3562ed09a7f 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -286,16 +286,9 @@
/atom/proc/AltClick(var/mob/user)
var/turf/T = get_turf(src)
if(T && user.TurfAdjacent(T))
- user.ToggleTurfTab(T)
+ user.set_listed_turf(T)
return 1
-/mob/proc/ToggleTurfTab(var/turf/T)
- if(listed_turf == T)
- listed_turf = null
- else
- listed_turf = T
- client.statpanel = "Turf"
-
/mob/proc/TurfAdjacent(var/turf/T)
return T.AdjacentQuick(src)
diff --git a/code/_onclick/hud/ability_screen_objects.dm b/code/_onclick/hud/ability_screen_objects.dm
index 905676ff17a..250e93823aa 100644
--- a/code/_onclick/hud/ability_screen_objects.dm
+++ b/code/_onclick/hud/ability_screen_objects.dm
@@ -312,7 +312,7 @@
if(object_used && verb_to_call)
call(object_used,verb_to_call)(arguments_to_use)
// call(object_used,verb_to_call)(arguments_to_use)
-// to_world("Attempted to call([object_used],[verb_to_call])([arguments_to_use])")
+// to_world(span_world("Attempted to call([object_used],[verb_to_call])([arguments_to_use])"))
// if(hascall(object_used, verb_to_call))
// call(object_used,verb_to_call)(arguments_to_use)
// else
diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm
deleted file mode 100644
index 288c4799226..00000000000
--- a/code/_onclick/hud/action.dm
+++ /dev/null
@@ -1,228 +0,0 @@
-#define AB_ITEM 1
-#define AB_SPELL 2
-#define AB_INNATE 3
-#define AB_GENERIC 4
-
-
-/datum/action
- var/name = "Generic Action"
- var/action_type = AB_ITEM
- var/procname = null
- var/atom/movable/target = null
- var/check_flags = 0
- var/processing = 0
- var/active = 0
- var/obj/screen/movable/action_button/button = null
- var/button_icon = 'icons/mob/actions.dmi'
- var/button_icon_state = "default"
- var/background_icon_state = "bg_default"
- var/mob/living/owner
-
-/datum/action/New(var/Target)
- target = Target
-
-/datum/action/Destroy()
- if(owner)
- Remove(owner)
- target = null
- QDEL_NULL(button)
- return ..()
-
-/datum/action/proc/Grant(mob/living/T)
- if(owner)
- if(owner == T)
- return
- Remove(owner)
- owner = T
- owner.actions.Add(src)
- owner.update_action_buttons()
- return
-
-/datum/action/proc/Remove(mob/living/T)
- if(button)
- if(T.client)
- T.client.screen -= button
- QDEL_NULL(button)
- T.actions.Remove(src)
- T.update_action_buttons()
- owner = null
- return
-
-/datum/action/proc/Trigger()
- if(!Checks())
- return
- switch(action_type)
- if(AB_ITEM)
- if(target)
- var/obj/item/item = target
- item.ui_action_click()
- //if(AB_SPELL)
- // if(target)
- // var/obj/effect/proc_holder/spell = target
- // spell.Click()
- if(AB_INNATE)
- if(!active)
- Activate()
- else
- Deactivate()
- if(AB_GENERIC)
- if(target && procname)
- call(target,procname)(usr)
- return
-
-/datum/action/proc/Activate()
- return
-
-/datum/action/proc/Deactivate()
- return
-
-/datum/action/process()
- return
-
-/datum/action/proc/CheckRemoval(mob/living/user) // 1 if action is no longer valid for this mob and should be removed
- return 0
-
-/datum/action/proc/IsAvailable()
- return Checks()
-
-/datum/action/proc/Checks()// returns 1 if all checks pass
- if(!owner)
- return 0
- if(check_flags & AB_CHECK_RESTRAINED)
- if(owner.restrained())
- return 0
- if(check_flags & AB_CHECK_STUNNED)
- if(owner.stunned)
- return 0
- if(check_flags & AB_CHECK_LYING)
- if(owner.lying)
- return 0
- if(check_flags & AB_CHECK_ALIVE)
- if(owner.stat)
- return 0
- if(check_flags & AB_CHECK_INSIDE)
- if(!(target in owner))
- return 0
- return 1
-
-/datum/action/proc/UpdateName()
- return name
-
-/obj/screen/movable/action_button
- var/datum/action/owner
- screen_loc = "WEST,NORTH"
-
-/obj/screen/movable/action_button/Click(location,control,params)
- var/list/modifiers = params2list(params)
- if(modifiers["shift"])
- moved = 0
- return 1
- if(!usr.checkClickCooldown())
- return
- owner.Trigger()
- return 1
-
-/obj/screen/movable/action_button/proc/UpdateIcon()
- if(!owner)
- return
- icon = owner.button_icon
- icon_state = owner.background_icon_state
-
- cut_overlays()
- var/image/img
- if(owner.action_type == AB_ITEM && owner.target)
- var/obj/item/I = owner.target
- img = image(I.icon, src , I.icon_state)
- else if(owner.button_icon && owner.button_icon_state)
- img = image(owner.button_icon,src,owner.button_icon_state)
- img.pixel_x = 0
- img.pixel_y = 0
- add_overlay(img)
-
- if(!owner.IsAvailable())
- color = rgb(128,0,0,128)
- else
- color = rgb(255,255,255,255)
-
-//Hide/Show Action Buttons ... Button
-/obj/screen/movable/action_button/hide_toggle
- name = "Hide Buttons"
- icon = 'icons/mob/actions.dmi'
- icon_state = "bg_default"
- var/hidden = 0
-
-/obj/screen/movable/action_button/hide_toggle/Click()
- usr.hud_used.action_buttons_hidden = !usr.hud_used.action_buttons_hidden
-
- hidden = usr.hud_used.action_buttons_hidden
- if(hidden)
- name = "Show Buttons"
- else
- name = "Hide Buttons"
- UpdateIcon()
- usr.update_action_buttons()
-
-
-/obj/screen/movable/action_button/hide_toggle/proc/InitialiseIcon(var/mob/living/user)
- if(isalien(user))
- icon_state = "bg_alien"
- else
- icon_state = "bg_default"
- UpdateIcon()
- return
-
-/obj/screen/movable/action_button/hide_toggle/UpdateIcon()
- cut_overlays()
- var/image/img = image(icon,src,hidden?"show":"hide")
- add_overlay(img)
- return
-
-//This is the proc used to update all the action buttons. Properly defined in /mob/living/
-/mob/proc/update_action_buttons()
- return
-
-#define AB_WEST_OFFSET 4
-#define AB_NORTH_OFFSET 26
-#define AB_MAX_COLUMNS 10
-
-/datum/hud/proc/ButtonNumberToScreenCoords(var/number) // TODO : Make this zero-indexed for readabilty
- var/row = round((number-1)/AB_MAX_COLUMNS)
- var/col = ((number - 1)%(AB_MAX_COLUMNS)) + 1
- var/coord_col = "+[col-1]"
- var/coord_col_offset = AB_WEST_OFFSET+2*col
- var/coord_row = "[-1 - row]"
- var/coord_row_offset = AB_NORTH_OFFSET
- return "WEST[coord_col]:[coord_col_offset],NORTH[coord_row]:[coord_row_offset]"
-
-/datum/hud/proc/SetButtonCoords(var/obj/screen/button,var/number)
- var/row = round((number-1)/AB_MAX_COLUMNS)
- var/col = ((number - 1)%(AB_MAX_COLUMNS)) + 1
- var/x_offset = 32*(col-1) + AB_WEST_OFFSET + 2*col
- var/y_offset = -32*(row+1) + AB_NORTH_OFFSET
-
- var/matrix/M = matrix()
- M.Translate(x_offset,y_offset)
- button.transform = M
-
-//Presets for item actions
-/datum/action/item_action
- check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_LYING|AB_CHECK_ALIVE|AB_CHECK_INSIDE
-
-/datum/action/item_action/CheckRemoval(mob/living/user)
- return !(target in user)
-
-/datum/action/item_action/hands_free
- check_flags = AB_CHECK_ALIVE|AB_CHECK_INSIDE
-
-#undef AB_WEST_OFFSET
-#undef AB_NORTH_OFFSET
-#undef AB_MAX_COLUMNS
-
-
-/datum/action/innate/
- action_type = AB_INNATE
-
-#undef AB_ITEM
-#undef AB_SPELL
-#undef AB_INNATE
-#undef AB_GENERIC
diff --git a/code/_onclick/hud/action/action.dm b/code/_onclick/hud/action/action.dm
new file mode 100644
index 00000000000..7e0c3ece55e
--- /dev/null
+++ b/code/_onclick/hud/action/action.dm
@@ -0,0 +1,156 @@
+/datum/action
+ var/name = "Generic Action"
+ var/atom/movable/target = null
+ var/check_flags = 0
+ var/processing = 0
+ var/obj/screen/movable/action_button/button = null
+ var/button_icon = 'icons/mob/actions.dmi'
+ var/button_icon_state = "default"
+ var/background_icon_state = "bg_default"
+ var/mob/living/owner
+
+/datum/action/New(Target)
+ target = Target
+ button = new
+ button.linked_action = src
+ button.name = name
+
+/datum/action/Destroy()
+ if(owner)
+ Remove(owner)
+ target = null
+ QDEL_NULL(button)
+ return ..()
+
+/datum/action/proc/Grant(mob/living/L)
+ if(owner)
+ if(owner == L)
+ return
+ Remove(owner)
+ owner = L
+ L.actions += src
+ if(L.client)
+ L.client.screen += button
+ L.update_action_buttons(TRUE)
+
+/datum/action/proc/Remove(mob/living/L)
+ if(L.client)
+ L.client.screen -= button
+ button.moved = FALSE
+ L.actions -= src
+ L.update_action_buttons(TRUE)
+ owner = null
+
+/datum/action/proc/Trigger()
+ if(!IsAvailable())
+ return 0
+ return 1
+
+/datum/action/process()
+ return
+
+/datum/action/proc/IsAvailable()
+ if(!owner)
+ return 0
+ if(check_flags & AB_CHECK_RESTRAINED)
+ if(owner.restrained())
+ return 0
+ if(check_flags & AB_CHECK_STUNNED)
+ if(owner.stunned)
+ return 0
+ if(check_flags & AB_CHECK_LYING)
+ if(owner.lying)
+ return 0
+ if(check_flags & AB_CHECK_CONSCIOUS)
+ if(owner.stat)
+ return 0
+ return 1
+
+/datum/action/proc/UpdateButtonIcon()
+ if(button)
+ button.icon = button_icon
+ button.icon_state = background_icon_state
+
+ ApplyIcon(button)
+
+ if(!IsAvailable())
+ button.color = rgb(128, 0, 0, 128)
+ else
+ button.color = rgb(255, 255, 255, 255)
+ return 1
+
+/datum/action/proc/ApplyIcon(obj/screen/movable/action_button/current_button)
+ current_button.cut_overlays()
+ if(button_icon && button_icon_state)
+ var/image/img
+ img = image(button_icon, current_button, button_icon_state)
+ img.pixel_x = 0
+ img.pixel_y = 0
+ current_button.add_overlay(img)
+
+//Presets for item actions
+/datum/action/item_action
+ check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_LYING|AB_CHECK_CONSCIOUS
+
+/datum/action/item_action/New(Target)
+ . = ..()
+ var/obj/item/I = target
+ I.actions += src
+
+/datum/action/item_action/Destroy()
+ var/obj/item/I = target
+ I.actions -= src
+ return ..()
+
+/datum/action/item_action/Trigger()
+ if(!..())
+ return 0
+ if(target)
+ var/obj/item/I = target
+ I.ui_action_click(owner, src.type)
+ return 1
+
+/datum/action/item_action/ApplyIcon(obj/screen/movable/action_button/current_button)
+ current_button.cut_overlays()
+ if(target)
+ var/mutable_appearance/ma = new(target.appearance)
+ ma.plane = FLOAT_PLANE
+ ma.layer = FLOAT_LAYER
+ ma.pixel_x = 0
+ ma.pixel_y = 0
+ current_button.add_overlay(ma)
+
+/datum/action/item_action/hands_free
+ check_flags = AB_CHECK_CONSCIOUS
+
+
+/datum/action/innate
+ check_flags = 0
+ var/active = 0
+
+/datum/action/innate/Trigger()
+ if(!..())
+ return 0
+ if(!active)
+ Activate()
+ else
+ Deactivate()
+ return 1
+
+/datum/action/innate/proc/Activate()
+ return
+
+/datum/action/innate/proc/Deactivate()
+ return
+
+//Preset for action that call specific procs (consider innate).
+/datum/action/generic
+ check_flags = 0
+ var/procname
+
+/datum/action/generic/Trigger()
+ if(!..())
+ return 0
+ if(target && procname)
+ call(target, procname)(usr)
+ return 1
diff --git a/code/_onclick/hud/action/action_screen_objects.dm b/code/_onclick/hud/action/action_screen_objects.dm
new file mode 100644
index 00000000000..f4b10fc001d
--- /dev/null
+++ b/code/_onclick/hud/action/action_screen_objects.dm
@@ -0,0 +1,132 @@
+
+/obj/screen/movable/action_button
+ var/datum/action/linked_action
+ screen_loc = null
+
+/obj/screen/movable/action_button/Click(location,control,params)
+ var/list/modifiers = params2list(params)
+ if(modifiers["shift"])
+ moved = FALSE
+ usr.update_action_buttons()
+ return 1
+ if(!usr.checkClickCooldown())
+ return
+ linked_action.Trigger()
+ return 1
+//Hide/Show Action Buttons ... Button
+/obj/screen/movable/action_button/hide_toggle
+ name = "Hide Buttons"
+ icon = 'icons/mob/actions.dmi'
+ icon_state = "bg_default"
+ var/hidden = 0
+
+/obj/screen/movable/action_button/hide_toggle/Click()
+ usr.hud_used.action_buttons_hidden = !usr.hud_used.action_buttons_hidden
+
+ hidden = usr.hud_used.action_buttons_hidden
+ if(hidden)
+ name = "Show Buttons"
+ else
+ name = "Hide Buttons"
+ UpdateIcon()
+ usr.update_action_buttons()
+
+/obj/screen/movable/action_button/hide_toggle/proc/InitialiseIcon(var/mob/living/user)
+ if(isalien(user))
+ icon_state = "bg_alien"
+ else
+ icon_state = "bg_default"
+ UpdateIcon()
+
+/obj/screen/movable/action_button/hide_toggle/proc/UpdateIcon()
+ cut_overlays()
+ var/image/img = image(icon, src, hidden ? "show" : "hide")
+ add_overlay(img)
+
+/obj/screen/movable/action_button/MouseEntered(location, control, params)
+ openToolTip(usr, src, params, title = name, content = desc)
+
+/obj/screen/movable/action_button/MouseExited(location, control, params)
+ closeToolTip(usr)
+
+//used to update the buttons icon.
+/mob/proc/update_action_buttons_icon()
+ return
+
+/mob/living/update_action_buttons_icon()
+ for(var/X in actions)
+ var/datum/action/A = X
+ A.UpdateButtonIcon()
+
+//This is the proc used to update all the action buttons. Properly defined in /mob/living/
+/mob/proc/update_action_buttons(reload_screen)
+ return
+
+/mob/living/update_action_buttons(reload_screen)
+ if(!hud_used || !client)
+ return
+
+ if(!hud_used.hud_shown) //Hud toggled to minimal
+ return
+
+ var/button_number = 0
+
+ if(hud_used.action_buttons_hidden)
+ for(var/datum/action/A in actions)
+ A.button.screen_loc = null
+ if(reload_screen)
+ client.screen += A.button
+ else
+ for(var/datum/action/A in actions)
+ button_number++
+ A.UpdateButtonIcon()
+ var/obj/screen/movable/action_button/B = A.button
+ if(!B.moved)
+ B.screen_loc = hud_used.ButtonNumberToScreenCoords(button_number)
+ else
+ B.screen_loc = B.moved
+ if(reload_screen)
+ client.screen += B
+
+ if(!button_number)
+ hud_used.hide_actions_toggle?.screen_loc = null
+ return
+
+ // not exactly sure how this happens but it does
+ if(hud_used.hide_actions_toggle)
+ if(!hud_used.hide_actions_toggle.moved)
+ hud_used.hide_actions_toggle.screen_loc = hud_used.ButtonNumberToScreenCoords(button_number+1)
+ else
+ hud_used.hide_actions_toggle.screen_loc = hud_used.hide_actions_toggle.moved
+ if(reload_screen)
+ client.screen += hud_used.hide_actions_toggle
+
+#define AB_WEST_OFFSET 4
+#define AB_NORTH_OFFSET 26
+#define AB_MAX_COLUMNS 10
+
+/datum/hud/proc/ButtonNumberToScreenCoords(var/number) // TODO : Make this zero-indexed for readabilty
+ var/row = round((number-1)/AB_MAX_COLUMNS)
+ var/col = ((number - 1)%(AB_MAX_COLUMNS)) + 1
+
+ var/coord_col = "+[col-1]"
+ var/coord_col_offset = AB_WEST_OFFSET+2*col
+
+ var/coord_row = "[-1 - row]"
+ var/coord_row_offset = AB_NORTH_OFFSET
+
+ return "WEST[coord_col]:[coord_col_offset],NORTH[coord_row]:[coord_row_offset]"
+
+/datum/hud/proc/SetButtonCoords(var/obj/screen/button,var/number)
+ var/row = round((number-1)/AB_MAX_COLUMNS)
+ var/col = ((number - 1)%(AB_MAX_COLUMNS)) + 1
+ var/x_offset = 32*(col-1) + AB_WEST_OFFSET + 2*col
+ var/y_offset = -32*(row+1) + AB_NORTH_OFFSET
+
+ var/matrix/M = matrix()
+ M.Translate(x_offset,y_offset)
+ button.transform = M
+
+#undef AB_WEST_OFFSET
+#undef AB_NORTH_OFFSET
+#undef AB_MAX_COLUMNS
diff --git a/code/_onclick/hud/action/types/item.dm b/code/_onclick/hud/action/types/item.dm
new file mode 100644
index 00000000000..df2d770aec5
--- /dev/null
+++ b/code/_onclick/hud/action/types/item.dm
@@ -0,0 +1,161 @@
+// Generic Classes
+/datum/action/item_action/activate
+
+/datum/action/item_action/activate/New(Target, name)
+ . = ..()
+ src.name = name
+ button.name = name
+
+// Specific names
+/datum/action/item_action/toggle_grippers
+ name = "Toggle Grippers"
+
+/datum/action/item_action/toggle_talons
+ name = "Toggle Talons"
+
+/datum/action/item_action/toggle_goggles
+ name = "Toggle Goggles"
+
+/datum/action/item_action/toggle_shield_projector
+ name = "Toggle Shield Projector"
+
+/datum/action/item_action/toggle_tesla_armor
+ name = "Toggle Tesla Armor"
+
+/datum/action/item_action/remove_replace_paddles
+ name = "Remove/Replace Paddles"
+
+/datum/action/item_action/toggle_flashlight
+ name = "Toggle Flashlight"
+
+/datum/action/item_action/toggle_shield
+ name = "Toggle Shield"
+
+/datum/action/item_action/toggle_heatsink
+ name = "Toggle Heatsink"
+
+/datum/action/item_action/remove_replace_handset
+ name = "Remove/Replace Handset"
+
+/datum/action/item_action/command
+ name = "Command"
+
+/datum/action/item_action/toggle_jetpack
+ name = "Toggle Jetpack"
+
+/datum/action/item_action/toggle_cataloguer
+ name = "Toggle Cataloguer"
+
+/datum/action/item_action/toggle_eyepatch
+ name = "Toggle Eyepatch"
+
+/datum/action/item_action/hands_free/change_scanning_pattern
+ name = "Change Scanning Pattern"
+
+/datum/action/item_action/toggle_hud
+ name = "Toggle HUD"
+
+/datum/action/item_action/toggle_mode
+ name = "Toggle Mode"
+
+/datum/action/item_action/flip_welding_goggles
+ name = "Flip Welding Goggles"
+
+/datum/action/item_action/toggle_monocle
+ name = "Toggle Monocle"
+
+/datum/action/item_action/adjust_orange_goggles
+ name = "Adjust Orange Goggles"
+
+/datum/action/item_action/ar_console_crew
+ name = "AR Console (Crew Monitor)"
+
+/datum/action/item_action/ar_console_security_alerts
+ name = "AR Console (Security Alerts)"
+
+/datum/action/item_action/ar_console_station_alerts
+ name = "AR Console (Station Alerts)"
+
+/datum/action/item_action/ar_console_all_alerts
+ name = "AR Console (All Alerts)"
+
+/datum/action/item_action/toggle_head_light
+ name = "Toggle Head-light"
+
+/datum/action/item_action/toggle_visor
+ name = "Toggle Visor"
+
+/datum/action/item_action/flip_welding_mask
+ name = "Flip Welding Mask"
+
+/datum/action/item_action/adjust_breath_mask
+ name = "Adjust Breath Mask"
+
+/datum/action/item_action/toggle_feeding_port
+ name = "Toggle Feeding Port"
+
+/datum/action/item_action/halt
+ name = "HALT!"
+
+/datum/action/item_action/hands_free/redraw_design
+ name = "Redraw Design"
+
+/datum/action/item_action/toggle_magboots
+ name = "Toggle Magboots"
+
+/datum/action/item_action/toggle_magclaws
+ name = "Toggle Magclaws"
+
+/datum/action/item_action/activate_jump_boots
+ name = "Activate Jump Boots"
+
+/datum/action/item_action/toggle_helmet_light
+ name = "Toggle Helmet Light"
+
+/datum/action/item_action/hardsuit_interface
+ name = "Hardsuit Interface"
+
+/datum/action/item_action/toggle_helmet
+ name = "Toggle Helmet"
+
+/datum/action/item_action/toggle_knight_headgear
+ name = "Toggle Knight Headgear"
+
+/datum/action/item_action/toggle_hood
+ name = "Toggle Hood"
+
+/datum/action/item_action/adjust_cloak
+ name = "Adjust Cloak"
+
+/datum/action/item_action/adjust_poncho
+ name = "Adjust Poncho"
+
+/datum/action/item_action/pull_on_gaiter
+ name = "Pull On Gaiter"
+
+/datum/action/item_action/toggle_uv_light
+ name = "Toggle UV Light"
+
+/datum/action/item_action/toggle_light
+ name = "Toggle Light"
+
+/datum/action/item_action/use_scope
+ name = "Use Scope"
+
+/datum/action/item_action/aim_down_sights
+ name = "Aim Down Sights"
+
+/datum/action/item_action/toggle_gunlight
+ name = "Toggle Gun-light"
+
+/datum/action/item_action/toggle_internal_generator
+ name = "Toggle Internal Generator"
+
+/datum/action/item_action/toggle_stock
+ name = "Toggle Stock"
+
+/datum/action/item_action/toggle_pom_pom
+ name = "Toggle Pom-Pom"
+
+/datum/action/item_action/toggle_mlembulance
+ name = "Toggle Mlembulance Mode"
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
index 123d94a7d84..7ba7bba1e1e 100644
--- a/code/_onclick/hud/hud.dm
+++ b/code/_onclick/hud/hud.dm
@@ -207,6 +207,7 @@ var/list/global_huds = list(
/datum/hud/Destroy()
. = ..()
QDEL_NULL_LIST(minihuds)
+ QDEL_NULL(hide_actions_toggle)
grab_intent = null
hurt_intent = null
disarm_intent = null
@@ -322,10 +323,12 @@ var/list/global_huds = list(
return 0
mymob.create_mob_hud(src)
+ hide_actions_toggle = new()
+ hide_actions_toggle.InitialiseIcon(mymob)
persistant_inventory_update()
mymob.reload_fullscreen() // Reload any fullscreen overlays this mob has.
- mymob.update_action_buttons()
+ mymob.update_action_buttons(TRUE)
reorganize_alerts()
/mob/proc/create_mob_hud(datum/hud/HUD, apply_to_client = TRUE)
@@ -404,10 +407,11 @@ var/list/global_huds = list(
hud_used?.action_intent.screen_loc = ui_acti //Restore intent selection to the original position
client.screen += zone_sel //This one is a special snowflake
+ client.screen += hud_used.hide_actions_toggle
hud_used.hidden_inventory_update()
hud_used.persistant_inventory_update()
- update_action_buttons()
+ update_action_buttons(TRUE)
hud_used.reorganize_alerts()
return TRUE
@@ -467,7 +471,7 @@ var/list/global_huds = list(
hud_used.hidden_inventory_update()
hud_used.persistant_inventory_update()
- update_action_buttons()
+ update_action_buttons(TRUE)
/mob/proc/add_click_catcher()
client.screen += client.void
diff --git a/code/_onclick/hud/movable_screen_objects.dm b/code/_onclick/hud/movable_screen_objects.dm
index 39d36738aa0..53e64c8b246 100644
--- a/code/_onclick/hud/movable_screen_objects.dm
+++ b/code/_onclick/hud/movable_screen_objects.dm
@@ -9,9 +9,10 @@
//Not tied to the grid, places it's center where the cursor is
/obj/screen/movable
+ mouse_drag_pointer = 'icons/effects/mouse_pointers/screen_drag.dmi'
var/snap2grid = FALSE
var/moved = FALSE
- var/x_off = -16
+ var/x_off = -16
var/y_off = -16
//Snap Screen Object
@@ -22,30 +23,33 @@
/obj/screen/movable/MouseDrop(over_object, src_location, over_location, src_control, over_control, params)
- var/list/PM = params2list(params)
-
- //No screen-loc information? abort.
- if(!PM || !PM["screen-loc"])
+ var/position = mouse_params_to_position(params)
+ if(!position)
return
- //Split screen-loc up into X+Pixel_X and Y+Pixel_Y
- var/list/screen_loc_params = splittext(PM["screen-loc"], ",")
+ screen_loc = position
+ moved = screen_loc
- //Split X+Pixel_X up into list(X, Pixel_X)
- var/list/screen_loc_X = splittext(screen_loc_params[1],":")
- screen_loc_X[1] = encode_screen_X(text2num(screen_loc_X[1]))
- //Split Y+Pixel_Y up into list(Y, Pixel_Y)
- var/list/screen_loc_Y = splittext(screen_loc_params[2],":")
- screen_loc_Y[1] = encode_screen_Y(text2num(screen_loc_Y[1]))
+/// Takes mouse parmas as input, returns a string representing the appropriate mouse position
+/obj/screen/movable/proc/mouse_params_to_position(params)
+ var/list/modifiers = params2list(params)
+
+ //No screen-loc information? abort.
+ if(!LAZYACCESS(modifiers, SCREEN_LOC))
+ return
+
+ var/client/our_client = usr.client
+ var/list/offset = screen_loc_to_offset(LAZYACCESS(modifiers, SCREEN_LOC), our_client?.view)
if(snap2grid) //Discard Pixel Values
- screen_loc = "[screen_loc_X[1]],[screen_loc_Y[1]]"
-
+ offset[1] = FLOOR(offset[1], ICON_SIZE_X) // drops any pixel offset
+ offset[2] = FLOOR(offset[2], ICON_SIZE_Y) // drops any pixel offset
else //Normalise Pixel Values (So the object drops at the center of the mouse, not 16 pixels off)
- var/pix_X = text2num(screen_loc_X[2]) + x_off
- var/pix_Y = text2num(screen_loc_Y[2]) + y_off
- screen_loc = "[screen_loc_X[1]]:[pix_X],[screen_loc_Y[1]]:[pix_Y]"
+ offset[1] += x_off
+ offset[2] += y_off
+ return offset_to_screen_loc(offset[1], offset[2], our_client?.view)
+// Must stay for now, for subtypes
/obj/screen/movable/proc/encode_screen_X(X)
var/view_dist = world.view
if(view_dist)
diff --git a/code/_onclick/hud/screen_objects_vr.dm b/code/_onclick/hud/screen_objects_vr.dm
index ea4fbaa9a47..d3e43bb628a 100644
--- a/code/_onclick/hud/screen_objects_vr.dm
+++ b/code/_onclick/hud/screen_objects_vr.dm
@@ -6,23 +6,23 @@
if("darkness")
var/turf/T = get_turf(usr)
var/darkness = round(1 - T.get_lumcount(),0.1)
- to_chat(usr,span_notice("Darkness: [darkness]"))
+ to_chat(usr,span_notice(span_bold("Darkness:") + " [darkness]"))
if("energy")
var/mob/living/simple_mob/shadekin/SK = usr
if(istype(SK))
- to_chat(usr,span_notice("Energy: [SK.energy] ([SK.dark_gains])"))
+ to_chat(usr,span_notice(span_bold("Energy:") + " [SK.energy] ([SK.dark_gains])"))
if("shadekin status")
var/turf/T = get_turf(usr)
if(T)
var/darkness = round(1 - T.get_lumcount(),0.1)
- to_chat(usr,span_notice("Darkness: [darkness]"))
+ to_chat(usr,span_notice(span_bold("Darkness:") + " [darkness]"))
var/mob/living/carbon/human/H = usr
if(istype(H) && istype(H.species, /datum/species/shadekin))
- to_chat(usr,span_notice("Energy: [H.shadekin_get_energy(H)]"))
+ to_chat(usr,span_notice(span_bold("Energy:") + " [H.shadekin_get_energy(H)]"))
if("glamour")
var/mob/living/carbon/human/H = usr
if(istype(H))
- to_chat(usr,span_notice("Energy: [H.species.lleill_energy]/[H.species.lleill_energy_max]"))
+ to_chat(usr,span_notice(span_bold("Energy:") + " [H.species.lleill_energy]/[H.species.lleill_energy_max]"))
if("danger level")
var/mob/living/carbon/human/H = usr
if(istype(H) && istype(H.species, /datum/species/xenochimera))
diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm
index 75d1208a402..f8dc673b5f9 100644
--- a/code/_onclick/observer.dm
+++ b/code/_onclick/observer.dm
@@ -41,7 +41,7 @@
if(modifiers["alt"]) // alt and alt-gr (rightalt)
var/turf/T = get_turf(A)
if(T && TurfAdjacent(T))
- ToggleTurfTab(T)
+ set_listed_turf(T)
return
// You are responsible for checking config.ghost_interaction when you override this function
// Not all of them require checking, see below
diff --git a/code/_onclick/rig.dm b/code/_onclick/rig.dm
index 2284226b373..dc57ad2150c 100644
--- a/code/_onclick/rig.dm
+++ b/code/_onclick/rig.dm
@@ -1,11 +1,11 @@
-#define MIDDLE_CLICK 0
-#define ALT_CLICK 1
-#define CTRL_CLICK 2
+#define HARDSUIT_MIDDLE_CLICK 0
+#define HARDSUIT_ALT_CLICK 1
+#define HARDSUIT_CTRL_CLICK 2
#define MAX_HARDSUIT_CLICK_MODE 2
/client
- var/hardsuit_click_mode = MIDDLE_CLICK
+ var/hardsuit_click_mode = HARDSUIT_MIDDLE_CLICK
/client/verb/toggle_hardsuit_mode()
set name = "Toggle Hardsuit Activation Mode"
@@ -17,32 +17,32 @@
hardsuit_click_mode = 0
switch(hardsuit_click_mode)
- if(MIDDLE_CLICK)
+ if(HARDSUIT_MIDDLE_CLICK)
to_chat(src, "Hardsuit activation mode set to middle-click.")
- if(ALT_CLICK)
+ if(HARDSUIT_ALT_CLICK)
to_chat(src, "Hardsuit activation mode set to alt-click.")
- if(CTRL_CLICK)
+ if(HARDSUIT_CTRL_CLICK)
to_chat(src, "Hardsuit activation mode set to control-click.")
else
// should never get here, but just in case:
soft_assert(0, "Bad hardsuit click mode: [hardsuit_click_mode] - expected 0 to [MAX_HARDSUIT_CLICK_MODE]")
to_chat(src, "Somehow you bugged the system. Setting your hardsuit mode to middle-click.")
- hardsuit_click_mode = MIDDLE_CLICK
+ hardsuit_click_mode = HARDSUIT_MIDDLE_CLICK
/mob/living/MiddleClickOn(atom/A)
- if(client && client.hardsuit_click_mode == MIDDLE_CLICK)
+ if(client && client.hardsuit_click_mode == HARDSUIT_MIDDLE_CLICK)
if(HardsuitClickOn(A))
return
..()
/mob/living/AltClickOn(atom/A)
- if(client && client.hardsuit_click_mode == ALT_CLICK)
+ if(client && client.hardsuit_click_mode == HARDSUIT_ALT_CLICK)
if(HardsuitClickOn(A))
return
..()
/mob/living/CtrlClickOn(atom/A)
- if(client && client.hardsuit_click_mode == CTRL_CLICK)
+ if(client && client.hardsuit_click_mode == HARDSUIT_CTRL_CLICK)
if(HardsuitClickOn(A))
return
..()
@@ -78,7 +78,7 @@
return 1
return 0
-#undef MIDDLE_CLICK
-#undef ALT_CLICK
-#undef CTRL_CLICK
+#undef HARDSUIT_MIDDLE_CLICK
+#undef HARDSUIT_ALT_CLICK
+#undef HARDSUIT_CTRL_CLICK
#undef MAX_HARDSUIT_CLICK_MODE
diff --git a/code/controllers/autotransfer.dm b/code/controllers/autotransfer.dm
index e94163ea464..d303142886a 100644
--- a/code/controllers/autotransfer.dm
+++ b/code/controllers/autotransfer.dm
@@ -19,7 +19,7 @@ var/datum/controller/transfer_controller/transfer_controller
//VOREStation Edit START
if (round_duration_in_ds >= shift_last_vote - 2 MINUTES)
shift_last_vote = 99999999 //Setting to a stupidly high number since it'll be not used again.
- to_world("Warning: You have one hour left in the shift. Wrap up your scenes in the next 60 minutes before the transfer is called.") //VOREStation Edit
+ to_world(span_world(span_notice("Warning: You have one hour left in the shift. Wrap up your scenes in the next 60 minutes before the transfer is called."))) //VOREStation Edit
if (round_duration_in_ds >= shift_hard_end - 1 MINUTE)
init_shift_change(null, 1)
shift_hard_end = timerbuffer + config.vote_autotransfer_interval //If shuttle somehow gets recalled, let's force it to call again next time a vote would occur.
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index bd846d11bcd..ff3deb6adbd 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -71,7 +71,7 @@ var/list/gamemode_cache = list()
var/static/respawn = 1
var/static/respawn_time = 3000 // time before a dead player is allowed to respawn (in ds, though the config file asks for minutes, and it's converted below)
- var/static/respawn_message = span_notice("Make sure to play a different character, and please roleplay correctly!")
+ var/static/respawn_message = span_boldnotice("Make sure to play a different character, and please roleplay correctly!")
var/static/guest_jobban = 1
var/static/usewhitelist = 0
@@ -529,7 +529,7 @@ var/list/gamemode_cache = list()
config.respawn_time = raw_minutes MINUTES
if ("respawn_message")
- config.respawn_message = span_notice("[value]")
+ config.respawn_message = span_boldnotice("[value]")
if ("servername")
config.server_name = value
diff --git a/code/controllers/controller.dm b/code/controllers/controller.dm
index c9d5f1e5650..1f0a01a072c 100644
--- a/code/controllers/controller.dm
+++ b/code/controllers/controller.dm
@@ -16,4 +16,4 @@
/datum/controller/proc/Recover()
-/datum/controller/proc/stat_entry()
+/datum/controller/proc/stat_entry(msg)
diff --git a/code/controllers/failsafe.dm b/code/controllers/failsafe.dm
index 3022944ec32..dfe8bc7234d 100644
--- a/code/controllers/failsafe.dm
+++ b/code/controllers/failsafe.dm
@@ -96,8 +96,9 @@ var/datum/controller/failsafe/Failsafe
/datum/controller/failsafe/proc/defcon_pretty()
return defcon
-/datum/controller/failsafe/stat_entry()
+/datum/controller/failsafe/stat_entry(msg)
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
- stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"))
+ msg = "Failsafe Controller: [statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])")]"
+ return msg
diff --git a/code/controllers/globals.dm b/code/controllers/globals.dm
index cd6e7544dd4..bf9c7e1e9ce 100644
--- a/code/controllers/globals.dm
+++ b/code/controllers/globals.dm
@@ -32,11 +32,12 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
return ..()
-/datum/controller/global_vars/stat_entry()
+/datum/controller/global_vars/stat_entry(msg)
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
- stat("GLOB:", statclick.update("Edit"))
+ msg = "GLOB: [statclick.update("Edit")]"
+ return msg
/datum/controller/global_vars/vv_edit_var(var_name, var_value)
if(gvars_datum_protected_varlist[var_name])
diff --git a/code/controllers/master.dm b/code/controllers/master.dm
index 49f34a5c978..049e687a95f 100644
--- a/code/controllers/master.dm
+++ b/code/controllers/master.dm
@@ -582,12 +582,14 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
-/datum/controller/master/stat_entry()
+/datum/controller/master/stat_entry(msg)
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
- stat("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%))")
- stat("Master Controller:", statclick.update("(TickRate:[Master.processing]) (Iteration:[Master.iteration])"))
+ msg = "Byond: (FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%))"
+ msg += "Master Controller: [statclick.update("(TickRate:[Master.processing]) (Iteration:[Master.iteration])")]"
+
+ return msg
/datum/controller/master/StartLoadingMap(var/quiet = TRUE)
if(map_loading)
diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm
index 5297314ab14..9c5fcbe5cb6 100644
--- a/code/controllers/subsystem.dm
+++ b/code/controllers/subsystem.dm
@@ -164,22 +164,11 @@
//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc.
/datum/controller/subsystem/stat_entry(msg)
- if(!statclick)
- statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
-
-
- if(SS_NO_FIRE & flags)
- msg = "NO FIRE\t[msg]"
- else if(can_fire <= 0)
- msg = "OFFLINE\t[msg]"
- else
+ if(can_fire && !(SS_NO_FIRE & flags))
msg = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)]\t[msg]"
-
- var/title = name
- if (can_fire)
- title = "\[[state_letter()]][title]"
-
- stat(title, statclick.update(msg))
+ else
+ msg = "OFFLINE\t[msg]"
+ return msg
/datum/controller/subsystem/proc/state_letter()
switch (state)
diff --git a/code/controllers/subsystems/ai.dm b/code/controllers/subsystems/ai.dm
index eb29e2fec2f..4e5256d9492 100644
--- a/code/controllers/subsystems/ai.dm
+++ b/code/controllers/subsystems/ai.dm
@@ -12,8 +12,9 @@ SUBSYSTEM_DEF(ai)
var/slept_mobs = 0
var/list/process_z = list()
-/datum/controller/subsystem/ai/stat_entry(msg_prefix)
- ..("P: [processing.len] | S: [slept_mobs]")
+/datum/controller/subsystem/ai/stat_entry(msg)
+ msg = "P: [processing.len] | S: [slept_mobs]"
+ return ..()
/datum/controller/subsystem/ai/fire(resumed = 0)
if (!resumed)
diff --git a/code/controllers/subsystems/aifast.dm b/code/controllers/subsystems/aifast.dm
index f045a7fd35c..2580c156ace 100644
--- a/code/controllers/subsystems/aifast.dm
+++ b/code/controllers/subsystems/aifast.dm
@@ -9,10 +9,9 @@ SUBSYSTEM_DEF(aifast)
var/list/processing = list()
var/list/currentrun = list()
-/datum/controller/subsystem/aifast/stat_entry(msg_prefix)
- var/list/msg = list(msg_prefix)
- msg += "P:[processing.len]"
- ..(msg.Join())
+/datum/controller/subsystem/aifast/stat_entry(msg)
+ msg = "P:[processing.len]"
+ return ..()
/datum/controller/subsystem/aifast/fire(resumed = 0)
if (!resumed)
diff --git a/code/controllers/subsystems/air.dm b/code/controllers/subsystems/air.dm
index 4886a11c273..1e5f1506ec6 100644
--- a/code/controllers/subsystems/air.dm
+++ b/code/controllers/subsystems/air.dm
@@ -244,9 +244,8 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
if(MC_TICK_CHECK)
return
-/datum/controller/subsystem/air/stat_entry(msg_prefix)
- var/list/msg = list(msg_prefix)
- msg += "S:[current_step ? part_names[current_step] : ""] "
+/datum/controller/subsystem/air/stat_entry(msg)
+ msg = "S:[current_step ? part_names[current_step] : ""] "
msg += "C:{"
msg += "T [round(cost_turfs, 1)] | "
msg += "E [round(cost_edges, 1)] | "
@@ -263,7 +262,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
msg += "H [active_hotspots.len] | "
msg += "Z [zones_to_update.len] "
msg += "}"
- ..(msg.Join())
+ return ..()
// ZAS might displace objects as the map loads if an air tick is processed mid-load.
/datum/controller/subsystem/air/StartLoadingMap(var/quiet = TRUE)
diff --git a/code/controllers/subsystems/alarm.dm b/code/controllers/subsystems/alarm.dm
index 868025eca3f..e3507a34e45 100644
--- a/code/controllers/subsystems/alarm.dm
+++ b/code/controllers/subsystems/alarm.dm
@@ -41,5 +41,6 @@ SUBSYSTEM_DEF(alarm)
/datum/controller/subsystem/alarm/proc/number_of_active_alarms()
return active_alarm_cache.len
-/datum/controller/subsystem/alarm/stat_entry()
- ..("[number_of_active_alarms()] alarm\s")
+/datum/controller/subsystem/alarm/stat_entry(msg)
+ msg = "[number_of_active_alarms()] alarm\s"
+ return ..()
diff --git a/code/controllers/subsystems/chemistry.dm b/code/controllers/subsystems/chemistry.dm
index 148e9755421..6f0c5959ebe 100644
--- a/code/controllers/subsystems/chemistry.dm
+++ b/code/controllers/subsystems/chemistry.dm
@@ -20,8 +20,9 @@ SUBSYSTEM_DEF(chemistry)
initialize_chemical_reactions()
..()
-/datum/controller/subsystem/chemistry/stat_entry()
- ..("C: [chemical_reagents.len] | R: [chemical_reactions.len]")
+/datum/controller/subsystem/chemistry/stat_entry(msg)
+ msg = "C: [chemical_reagents.len] | R: [chemical_reactions.len]"
+ return ..()
//Chemical Reactions - Initialises all /decl/chemical_reaction into a list
// It is filtered into multiple lists within a list.
@@ -43,7 +44,7 @@ SUBSYSTEM_DEF(chemistry)
// add_to = fusion_reactions_by_reagent
if(istype(D, /decl/chemical_reaction/distilling))
add_to = distilled_reactions_by_reagent
-
+
LAZYINITLIST(add_to[reagent_id])
add_to[reagent_id] += D
diff --git a/code/controllers/subsystems/events.dm b/code/controllers/subsystems/events.dm
index 83ab2fa00ca..5bdf83fdecc 100644
--- a/code/controllers/subsystems/events.dm
+++ b/code/controllers/subsystems/events.dm
@@ -41,8 +41,9 @@ SUBSYSTEM_DEF(events)
var/datum/event_container/EC = event_containers[i]
EC.process()
-/datum/controller/subsystem/events/stat_entry()
- ..("E:[active_events.len]")
+/datum/controller/subsystem/events/stat_entry(msg)
+ msg = "E:[active_events.len]"
+ return ..()
/datum/controller/subsystem/events/Recover()
if(SSevents.active_events)
diff --git a/code/controllers/subsystems/inactivity.dm b/code/controllers/subsystems/inactivity.dm
index 3795468f840..c921cff0220 100644
--- a/code/controllers/subsystems/inactivity.dm
+++ b/code/controllers/subsystems/inactivity.dm
@@ -56,8 +56,9 @@ SUBSYSTEM_DEF(inactivity)
if (MC_TICK_CHECK)
return
-/datum/controller/subsystem/inactivity/stat_entry()
- ..("Kicked: [number_kicked]")
+/datum/controller/subsystem/inactivity/stat_entry(msg)
+ msg = "Kicked: [number_kicked]"
+ return ..()
/datum/controller/subsystem/inactivity/proc/can_kick(var/client/C)
if(C.holder) return FALSE //VOREStation Add - Don't kick admins.
diff --git a/code/controllers/subsystems/machines.dm b/code/controllers/subsystems/machines.dm
index 67210025556..dea5b7ccc37 100644
--- a/code/controllers/subsystems/machines.dm
+++ b/code/controllers/subsystems/machines.dm
@@ -82,9 +82,8 @@ SUBSYSTEM_DEF(machines)
T.broadcast_status()
CHECK_TICK
-/datum/controller/subsystem/machines/stat_entry()
- var/msg = list()
- msg += "C:{"
+/datum/controller/subsystem/machines/stat_entry(msg)
+ msg = "C:{"
msg += "PI:[round(cost_pipenets,1)]|"
msg += "MC:[round(cost_machinery,1)]|"
msg += "PN:[round(cost_powernets,1)]|"
@@ -95,7 +94,7 @@ SUBSYSTEM_DEF(machines)
msg += "PN:[SSmachines.powernets.len]|"
msg += "PO:[SSmachines.powerobjs.len]|"
msg += "MC/MS:[round((cost ? SSmachines.processing_machines.len/cost_machinery : 0),0.1)]"
- ..(jointext(msg, null))
+ return ..()
/datum/controller/subsystem/machines/proc/process_pipenets(resumed = 0)
if (!resumed)
diff --git a/code/controllers/subsystems/mobs.dm b/code/controllers/subsystems/mobs.dm
index c124b5573ef..8fec502f21c 100644
--- a/code/controllers/subsystems/mobs.dm
+++ b/code/controllers/subsystems/mobs.dm
@@ -19,8 +19,9 @@ SUBSYSTEM_DEF(mobs)
var/slept_mobs = 0
var/list/process_z = list()
-/datum/controller/subsystem/mobs/stat_entry()
- ..("P: [global.mob_list.len] | S: [slept_mobs]")
+/datum/controller/subsystem/mobs/stat_entry(msg)
+ msg = "P: [global.mob_list.len] | S: [slept_mobs]"
+ return ..()
/datum/controller/subsystem/mobs/fire(resumed = 0)
if (!resumed)
@@ -90,4 +91,4 @@ SUBSYSTEM_DEF(mobs)
/datum/controller/subsystem/mobs/critfail()
..()
- log_recent()
\ No newline at end of file
+ log_recent()
diff --git a/code/controllers/subsystems/orbits.dm b/code/controllers/subsystems/orbits.dm
index 5cda1ce9dc4..af7a5ab7eab 100644
--- a/code/controllers/subsystems/orbits.dm
+++ b/code/controllers/subsystems/orbits.dm
@@ -7,8 +7,9 @@ SUBSYSTEM_DEF(orbit)
var/list/currentrun = list()
var/list/processing = list()
-/datum/controller/subsystem/orbit/stat_entry()
- ..("P:[processing.len]")
+/datum/controller/subsystem/orbit/stat_entry(msg)
+ msg = "P:[processing.len]"
+ return ..()
/datum/controller/subsystem/orbit/fire(resumed = 0)
@@ -40,5 +41,3 @@ SUBSYSTEM_DEF(orbit)
O.Check(targetloc)
if (MC_TICK_CHECK)
return
-
-
diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm
index 9d840933cb7..0a953e97828 100644
--- a/code/controllers/subsystems/overlays.dm
+++ b/code/controllers/subsystems/overlays.dm
@@ -32,8 +32,9 @@ SUBSYSTEM_DEF(overlays)
fire(FALSE, TRUE)
..()
-/datum/controller/subsystem/overlays/stat_entry()
- ..("Queued Atoms: [queue.len], Cache Size: [cache_size]")
+/datum/controller/subsystem/overlays/stat_entry(msg)
+ msg = "Queued Atoms: [queue.len], Cache Size: [cache_size]"
+ return ..()
/datum/controller/subsystem/overlays/fire(resumed, no_mc_tick)
diff --git a/code/controllers/subsystems/ping.dm b/code/controllers/subsystems/ping.dm
index 20cf8dd4465..8f4836290a4 100644
--- a/code/controllers/subsystems/ping.dm
+++ b/code/controllers/subsystems/ping.dm
@@ -12,8 +12,9 @@ SUBSYSTEM_DEF(ping)
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
var/list/currentrun = list()
-/datum/controller/subsystem/ping/stat_entry()
- ..("P:[GLOB.clients.len]")
+/datum/controller/subsystem/ping/stat_entry(msg)
+ msg = "P:[GLOB.clients.len]"
+ return ..()
/datum/controller/subsystem/ping/fire(resumed = FALSE)
// Prepare the new batch of clients
diff --git a/code/controllers/subsystems/plants.dm b/code/controllers/subsystems/plants.dm
index 42622b217d4..af4815395e1 100644
--- a/code/controllers/subsystems/plants.dm
+++ b/code/controllers/subsystems/plants.dm
@@ -22,8 +22,9 @@ SUBSYSTEM_DEF(plants)
var/list/processing = list()
var/list/currentrun = list()
-/datum/controller/subsystem/plants/stat_entry()
- ..("P:[processing.len]|S:[seeds.len]")
+/datum/controller/subsystem/plants/stat_entry(msg)
+ msg = "P:[processing.len]|S:[seeds.len]"
+ return ..()
/datum/controller/subsystem/plants/Initialize(timeofday)
setup()
diff --git a/code/controllers/subsystems/processing/obj_tab_items.dm b/code/controllers/subsystems/processing/obj_tab_items.dm
new file mode 100644
index 00000000000..53786daf011
--- /dev/null
+++ b/code/controllers/subsystems/processing/obj_tab_items.dm
@@ -0,0 +1,24 @@
+PROCESSING_SUBSYSTEM_DEF(obj_tab_items)
+ name = "Obj Tab Items"
+ flags = SS_NO_INIT
+ runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
+ wait = 0.1 SECONDS
+
+// I know this is mostly copypasta, but I want to change the processing logic
+// Sorry bestie :(
+/datum/controller/subsystem/processing/obj_tab_items/fire(resumed = FALSE)
+ if (!resumed)
+ currentrun = processing.Copy()
+ //cache for sanic speed (lists are references anyways)
+ var/list/current_run = currentrun
+
+ while(current_run.len)
+ var/datum/thing = current_run[current_run.len]
+ if(QDELETED(thing))
+ processing -= thing
+ else if(thing.process(wait * 0.1) == PROCESS_KILL)
+ // fully stop so that a future START_PROCESSING will work
+ STOP_PROCESSING(src, thing)
+ if (MC_TICK_CHECK)
+ return
+ current_run.len--
diff --git a/code/controllers/subsystems/processing/processing.dm b/code/controllers/subsystems/processing/processing.dm
index 16b4da021b1..51c1afe015f 100644
--- a/code/controllers/subsystems/processing/processing.dm
+++ b/code/controllers/subsystems/processing/processing.dm
@@ -24,8 +24,9 @@ SUBSYSTEM_DEF(processing)
if(CHECK_BITFIELD(D.datum_flags, DF_ISPROCESSING))
processing |= D
-/datum/controller/subsystem/processing/stat_entry()
- ..("[stat_tag]:[processing.len]")
+/datum/controller/subsystem/processing/stat_entry(msg)
+ msg = "[stat_tag]:[processing.len]"
+ return ..()
/datum/controller/subsystem/processing/fire(resumed = 0)
if (!resumed)
@@ -69,14 +70,14 @@ SUBSYSTEM_DEF(processing)
log_world(msg)
return
msg += "Lists: current_run: [currentrun.len], processing: [processing.len]\n"
-
+
if(!currentrun.len)
msg += "!!The subsystem just finished the processing list, and currentrun is empty (or has never run).\n"
msg += "!!The info below is the tail of processing instead of currentrun.\n"
-
+
var/datum/D = currentrun.len ? currentrun[currentrun.len] : processing[processing.len]
msg += "Tail entry: [describeThis(D)] (this is likely the item AFTER the problem item)\n"
-
+
var/position = processing.Find(D)
if(!position)
msg += "Unable to find context of tail entry in processing list.\n"
diff --git a/code/controllers/subsystems/radiation.dm b/code/controllers/subsystems/radiation.dm
index 8f140a5fc83..967c21992f4 100644
--- a/code/controllers/subsystems/radiation.dm
+++ b/code/controllers/subsystems/radiation.dm
@@ -54,8 +54,9 @@ SUBSYSTEM_DEF(radiation)
if (MC_TICK_CHECK)
return
-/datum/controller/subsystem/radiation/stat_entry()
- ..("S:[sources.len], RC:[resistance_cache.len]")
+/datum/controller/subsystem/radiation/stat_entry(msg)
+ msg = "S:[sources.len], RC:[resistance_cache.len]"
+ return ..()
// Ray trace from all active radiation sources to T and return the strongest effect.
/datum/controller/subsystem/radiation/proc/get_rads_at_turf(var/turf/T)
@@ -144,4 +145,4 @@ SUBSYSTEM_DEF(radiation)
if(!(power && source))
return
var/turf/epicentre = locate(round(world.maxx / 2), round(world.maxy / 2), source.z)
- flat_radiate(epicentre, power, world.maxx, respect_maint)
\ No newline at end of file
+ flat_radiate(epicentre, power, world.maxx, respect_maint)
diff --git a/code/controllers/subsystems/shuttles.dm b/code/controllers/subsystems/shuttles.dm
index 38ec9e5c83f..02f9cb91ebd 100644
--- a/code/controllers/subsystems/shuttles.dm
+++ b/code/controllers/subsystems/shuttles.dm
@@ -172,5 +172,6 @@ SUBSYSTEM_DEF(shuttles)
for(var/obj/effect/overmap/visitable/ship/ship_effect as anything in ships)
overmap_halted ? ship_effect.halt() : ship_effect.unhalt()
-/datum/controller/subsystem/shuttles/stat_entry()
- ..("Shuttles:[process_shuttles.len]/[shuttles.len], Ships:[ships.len], L:[registered_shuttle_landmarks.len][overmap_halted ? ", HALT" : ""]")
+/datum/controller/subsystem/shuttles/stat_entry(msg)
+ msg = "Shuttles:[process_shuttles.len]/[shuttles.len], Ships:[ships.len], L:[registered_shuttle_landmarks.len][overmap_halted ? ", HALT" : ""]"
+ return ..()
diff --git a/code/controllers/subsystems/statpanel.dm b/code/controllers/subsystems/statpanel.dm
new file mode 100644
index 00000000000..c80e7cd1fbe
--- /dev/null
+++ b/code/controllers/subsystems/statpanel.dm
@@ -0,0 +1,481 @@
+SUBSYSTEM_DEF(statpanels)
+ name = "Stat Panels"
+ wait = 4
+ init_order = INIT_ORDER_STATPANELS
+ //init_stage = INITSTAGE_EARLY
+ priority = FIRE_PRIORITY_STATPANEL
+ runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
+ flags = SS_NO_INIT
+ var/list/currentrun = list()
+ var/list/global_data
+ var/list/mc_data
+ var/list/cached_images = list()
+
+ ///how many subsystem fires between most tab updates
+ var/default_wait = 10
+ ///how many subsystem fires between updates of misc tabs
+ var/misc_wait = 3
+ ///how many subsystem fires between updates of the status tab
+ var/status_wait = 2
+ ///how many subsystem fires between updates of the MC tab
+ var/mc_wait = 5
+ ///how many full runs this subsystem has completed. used for variable rate refreshes.
+ var/num_fires = 0
+
+/datum/controller/subsystem/statpanels/fire(resumed = FALSE)
+ if (!resumed)
+ num_fires++
+ //var/datum/map_config/cached = SSmapping.next_map_config
+ global_data = list(
+ //"Map: [SSmapping.config?.map_name || "Loading..."]",
+ "Map: [using_map.name]",
+ //cached ? "Next Map: [cached.map_name]" : null,
+ //"Next Map: -- Not Available --",
+ // "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]",
+ "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]",
+ "Round Time: [ROUND_TIME()]",
+ "Station Date: [stationdate2text()]", // [capitalize(GLOB.world_time_season)]",
+ "Station Time: [stationtime2text()]",
+ "Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)"
+ )
+
+ if(emergency_shuttle.evac)
+ var/ETA = emergency_shuttle.get_status_panel_eta()
+ if(ETA)
+ global_data += "[ETA]"
+ src.currentrun = GLOB.clients.Copy()
+ mc_data = null
+
+ var/list/currentrun = src.currentrun
+ while(length(currentrun))
+ var/client/target = currentrun[length(currentrun)]
+ currentrun.len--
+
+ if(!target?.stat_panel?.is_ready()) // Null target client, client has null stat panel, or stat panel isn't ready
+ continue
+
+ if(target.stat_tab == "Status" && num_fires % status_wait == 0)
+ set_status_tab(target)
+
+ if(!target.holder)
+ target.stat_panel.send_message("remove_admin_tabs")
+ else
+ //target.stat_panel.send_message("update_split_admin_tabs", !!(target.prefs.toggles & SPLIT_ADMIN_TABS))
+ target.stat_panel.send_message("update_split_admin_tabs", FALSE)
+
+ if(!("MC" in target.panel_tabs) || !("Tickets" in target.panel_tabs))
+ target.stat_panel.send_message("add_admin_tabs", target.holder.href_token)
+
+ //if(target.stat_tab == "MC" && ((num_fires % mc_wait == 0) || target?.prefs.read_preference(/datum/preference/toggle/fast_mc_refresh)))
+ //set_MC_tab(target)
+ if(target.stat_tab == "MC" && ((num_fires % mc_wait == 0)))
+ set_MC_tab(target)
+
+ if(target.stat_tab == "Tickets" && num_fires % default_wait == 0)
+ set_tickets_tab(target)
+
+ if(!length(GLOB.sdql2_queries) && ("SDQL2" in target.panel_tabs))
+ target.stat_panel.send_message("remove_sdql2")
+
+ else if(length(GLOB.sdql2_queries) && (target.stat_tab == "SDQL2" || !("SDQL2" in target.panel_tabs)) && num_fires % default_wait == 0)
+ set_SDQL2_tab(target)
+
+ if(target.mob)
+ var/mob/target_mob = target.mob
+
+ // Handle the action panels of the stat panel
+
+ var/update_actions = FALSE
+ // We're on a spell tab, update the tab so we can see cooldowns progressing and such
+ if(target.stat_tab in target.spell_tabs)
+ update_actions = TRUE
+ // We're not on a spell tab per se, but we have cooldown actions, and we've yet to
+ // set up our spell tabs at all
+ //if(!length(target.spell_tabs) && locate(/datum/action/cooldown) in target_mob.actions)
+ //update_actions = TRUE
+
+ if(update_actions && num_fires % default_wait == 0)
+ set_action_tabs(target, target_mob)
+ //Update every fire if tab is open, otherwise update every 7 fires
+ if((num_fires % misc_wait == 0))
+ update_misc_tabs(target,target_mob)
+
+ var/datum/object_window_info/obj_window = target.obj_window
+ if(obj_window)
+ if(obj_window.flags & TURFLIST_UPDATE_QUEUED)
+ immediate_send_stat_data(target)
+ obj_window.flags = 0
+
+ if(MC_TICK_CHECK)
+ return
+
+/datum/controller/subsystem/statpanels/proc/update_misc_tabs(var/client/target,var/mob/target_mob)
+ target_mob.update_misc_tabs()
+ for(var/tab in target_mob.misc_tabs)
+ if(target_mob.misc_tabs[tab].len == 0 && (tab in target.misc_tabs))
+ target.misc_tabs -= tab
+ target.stat_panel.send_message("remove_misc",tab)
+
+ if(target_mob.misc_tabs[tab].len > 0)
+ if(!(tab in target.misc_tabs))
+ target.misc_tabs += tab
+ target.stat_panel.send_message("create_misc",tab)
+ target.stat_panel.send_message("update_misc",list(
+ TN = tab, \
+ TC = target_mob.misc_tabs[tab], \
+ ))
+
+ for(var/tab in target.misc_tabs)
+ if(!(tab in target_mob.misc_tabs))
+ target.misc_tabs -= tab
+ target.stat_panel.send_message("remove_misc",tab)
+
+/datum/controller/subsystem/statpanels/proc/set_status_tab(client/target)
+ if(!global_data)//statbrowser hasnt fired yet and we were called from immediate_send_stat_data()
+ return
+
+ target.stat_panel.send_message("update_stat", list(
+ global_data = global_data,
+ ping_str = "Ping: -- Not Available --", // [round(target.lastping, 1)]ms (Average: [round(target.avgping, 1)]ms)",
+ other_str = target.mob?.get_status_tab_items(),
+ ))
+
+/datum/controller/subsystem/statpanels/proc/set_MC_tab(client/target)
+ var/turf/eye_turf = get_turf(target.eye)
+ var/coord_entry = COORD(eye_turf)
+ if(!mc_data)
+ generate_mc_data()
+ target.stat_panel.send_message("update_mc", list(mc_data = mc_data, coord_entry = coord_entry))
+
+/datum/controller/subsystem/statpanels/proc/set_examine_tab(client/target)
+ var/description_holders = target.description_holders
+ var/list/examine_update = list()
+
+ if(!target.obj_window)
+ target.obj_window = new(target)
+ if(!target.examine_icon && !target.obj_window.examine_target && target.stat_tab == "Examine")
+ target.obj_window.examine_target = description_holders["icon"]
+ target.obj_window.atoms_to_show += target.obj_window.examine_target
+ START_PROCESSING(SSobj_tab_items, target.obj_window)
+ refresh_client_obj_view(target)
+ examine_update += "[target.examine_icon] [description_holders["name"]]" //The name, written in big letters.
+ examine_update += "[description_holders["desc"]]" //the default examine text.
+ if(description_holders["info"])
+ examine_update += "" + span_bold("[replacetext(description_holders["info"], "\n", "
")]") + "
" //Blue, informative text.
+ if(description_holders["interactions"])
+ for(var/line in description_holders["interactions"])
+ examine_update += "" + span_bold("[line]") + "
"
+ if(description_holders["fluff"])
+ examine_update += "" + span_bold("[replacetext(description_holders["fluff"], "\n", "
")]") + "
" //Green, fluff-related text.
+ if(description_holders["antag"])
+ examine_update += "" + span_bold("[description_holders["antag"]]") + "
" //Red, malicious antag-related text
+
+ target.stat_panel.send_message("update_examine", examine_update)
+
+/datum/controller/subsystem/statpanels/proc/set_tickets_tab(client/target)
+ var/list/tickets = GLOB.ahelp_tickets.stat_entry(target)
+ tickets += GLOB.mhelp_tickets.stat_entry(target)
+ target.stat_panel.send_message("update_tickets", tickets)
+
+/datum/controller/subsystem/statpanels/proc/set_SDQL2_tab(client/target)
+ var/list/sdql2A = list()
+ sdql2A[++sdql2A.len] = list("", "Access Global SDQL2 List", REF(GLOB.sdql2_vv_statobj))
+ var/list/sdql2B = list()
+ for(var/datum/SDQL2_query/query as anything in GLOB.sdql2_queries)
+ sdql2B = query.generate_stat()
+
+ sdql2A += sdql2B
+ target.stat_panel.send_message("update_sdql2", sdql2A)
+
+/// Set up the various action tabs.
+/datum/controller/subsystem/statpanels/proc/set_action_tabs(client/target, mob/target_mob)
+ return
+ //var/list/actions = target_mob.get_actions_for_statpanel()
+ //target.spell_tabs.Cut()
+
+ //for(var/action_data in actions)
+ // target.spell_tabs |= action_data[1]
+
+ //target.stat_panel.send_message("update_spells", list(spell_tabs = target.spell_tabs, actions = actions))
+
+/datum/controller/subsystem/statpanels/proc/set_turf_examine_tab(client/target, mob/target_mob)
+ if(!target)//statbrowser hasnt fired yet and we were called from immediate_send_stat_data()
+ return
+ var/list/overrides = list()
+ for(var/image/target_image as anything in target.images)
+ if(!target_image.loc || target_image.loc.loc != target_mob.listed_turf || !target_image.override)
+ continue
+ overrides += target_image.loc
+
+ var/list/atoms_to_display = list(target_mob.listed_turf)
+ for(var/atom/movable/turf_content as anything in target_mob.listed_turf)
+ if(turf_content.mouse_opacity == MOUSE_OPACITY_TRANSPARENT)
+ continue
+ if(turf_content.invisibility > target_mob.see_invisible)
+ continue
+ if(turf_content in overrides)
+ continue
+ //if(turf_content.IsObscured())
+ //continue
+ atoms_to_display += turf_content
+
+ /// Set the atoms we're meant to display
+ var/datum/object_window_info/obj_window = target.obj_window
+ if(!obj_window)
+ return // previous one no longer exists
+ obj_window.atoms_to_show = atoms_to_display
+ START_PROCESSING(SSobj_tab_items, obj_window)
+ refresh_client_obj_view(target)
+
+/datum/controller/subsystem/statpanels/proc/refresh_client_obj_view(client/refresh)
+ var/list/turf_items = return_object_images(refresh)
+ if(!length(turf_items)/* || !refresh.mob?.listed_turf*/)
+ return
+ refresh.stat_panel.send_message("update_listedturf", turf_items)
+
+#define OBJ_IMAGE_LOADING "statpanels obj loading temporary"
+/// Returns all our ready object tab images
+/// Returns a list in the form list(list(object_name, object_ref, loaded_image), ...)
+/datum/controller/subsystem/statpanels/proc/return_object_images(client/load_from)
+ // You might be inclined to think that this is a waste of cpu time, since we
+ // A: Double iterate over atoms in the build case, or
+ // B: Generate these lists over and over in the refresh case
+ // It's really not very hot. The hot portion of this code is genuinely mostly in the image generation
+ // So it's ok to pay a performance cost for cleanliness here
+
+ // No turf? go away
+ /*if(!load_from.mob?.listed_turf)
+ return list()*/
+ var/datum/object_window_info/obj_window = load_from.obj_window
+ var/list/already_seen = obj_window.atoms_to_images
+ var/list/to_make = obj_window.atoms_to_imagify
+ var/list/turf_items = list()
+ for(var/atom/turf_item as anything in obj_window.atoms_to_show)
+ // First, we fill up the list of refs to display
+ // If we already have one, just use that
+ var/existing_image = already_seen[turf_item]
+ if(existing_image == OBJ_IMAGE_LOADING)
+ continue
+ // We already have it. Success!
+ if(existing_image)
+ if(turf_item == obj_window.examine_target) //not actually a turf item get trolled
+ load_from.examine_icon = ""
+ obj_window.examine_target = null
+ set_examine_tab(load_from)
+ continue
+ turf_items[++turf_items.len] = list("[turf_item.name]", REF(turf_item), existing_image)
+ continue
+ // Now, we're gonna queue image generation out of those refs
+ to_make += turf_item
+ already_seen[turf_item] = OBJ_IMAGE_LOADING
+ obj_window.RegisterSignal(turf_item, COMSIG_PARENT_QDELETING, TYPE_PROC_REF(/datum/object_window_info,viewing_atom_deleted)) // we reset cache if anything in it gets deleted
+ return turf_items
+
+#undef OBJ_IMAGE_LOADING
+
+/datum/controller/subsystem/statpanels/proc/generate_mc_data()
+ mc_data = list(
+ list("CPU:", world.cpu),
+ list("Instances:", "[num2text(world.contents.len, 10)]"),
+ list("World Time:", "[world.time]"),
+ list("Globals:", GLOB.stat_entry(), "\ref[GLOB]"),
+ // list("[config]:", config.stat_entry(), "\ref[config]"),
+ list("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%)) (Internal Tick Usage: [round(MAPTICK_LAST_INTERNAL_TICK_USAGE,0.1)]%)"),
+ list("Master Controller:", Master.stat_entry(), "\ref[Master]"),
+ list("Failsafe Controller:", Failsafe.stat_entry(), "\ref[Failsafe]"),
+ list("","")
+ )
+ for(var/datum/controller/subsystem/sub_system as anything in Master.subsystems)
+ mc_data[++mc_data.len] = list("\[[sub_system.state_letter()]][sub_system.name]", sub_system.stat_entry(), "\ref[sub_system]")
+ mc_data[++mc_data.len] = list("Camera Net", "Cameras: [global.cameranet.cameras.len] | Chunks: [global.cameranet.chunks.len]", "\ref[global.cameranet]")
+
+///immediately update the active statpanel tab of the target client
+/datum/controller/subsystem/statpanels/proc/immediate_send_stat_data(client/target)
+ if(!target.stat_panel.is_ready())
+ return FALSE
+
+ if(target.stat_tab == "Examine")
+ set_examine_tab(target)
+ return TRUE
+
+ if(target.stat_tab == "Status")
+ set_status_tab(target)
+ return TRUE
+
+ var/mob/target_mob = target.mob
+
+ // Handle actions
+
+ var/update_actions = FALSE
+ if(target.stat_tab in target.spell_tabs)
+ update_actions = TRUE
+
+ //if(!length(target.spell_tabs) && locate(/datum/action/cooldown) in target_mob.actions)
+ //update_actions = TRUE
+
+ if(update_actions)
+ set_action_tabs(target, target_mob)
+ return TRUE
+
+ // Handle turfs
+
+ if(target_mob?.listed_turf)
+ if(!target_mob.TurfAdjacent(target_mob.listed_turf))
+ target.stat_panel.send_message("removed_listedturf")
+ target_mob.listed_turf = null
+
+ else if(target.stat_tab == target_mob?.listed_turf.name || !(target_mob?.listed_turf.name in target.panel_tabs))
+ set_turf_examine_tab(target, target_mob)
+ return TRUE
+
+ if(!target.holder)
+ return FALSE
+
+ if(target.stat_tab == "MC")
+ set_MC_tab(target)
+ return TRUE
+
+ if(target.stat_tab == "Tickets")
+ set_tickets_tab(target)
+ return TRUE
+
+ if(!length(GLOB.sdql2_queries) && ("SDQL2" in target.panel_tabs))
+ target.stat_panel.send_message("remove_sdql2")
+
+ else if(length(GLOB.sdql2_queries) && target.stat_tab == "SDQL2")
+ set_SDQL2_tab(target)
+
+/atom/proc/remove_from_cache()
+ SIGNAL_HANDLER
+ SSstatpanels.cached_images -= REF(src)
+
+/// Stat panel window declaration
+/client/var/datum/tgui_window/stat_panel
+
+/// Datum that holds and tracks info about a client's object window
+/// Really only exists because I want to be able to do logic with signals
+/// And need a safe place to do the registration
+/datum/object_window_info
+ /// list of atoms to show to our client via the object tab, at least currently
+ var/list/atoms_to_show = list()
+ /// list of atom -> image string for objects we have had in the right click tab
+ /// this is our caching
+ var/list/atoms_to_images = list()
+ /// list of atoms to turn into images for the object tab
+ var/list/atoms_to_imagify = list()
+ /// Our owner client
+ var/client/parent
+ /// Are we currently tracking a turf?
+ var/actively_tracking = FALSE
+ ///For reusing this logic for examines
+ var/atom/examine_target
+ var/flags = 0
+
+/datum/object_window_info/New(client/parent)
+ . = ..()
+ src.parent = parent
+
+/datum/object_window_info/Destroy(force, ...)
+ atoms_to_show = null
+ atoms_to_images = null
+ atoms_to_imagify = null
+ parent.obj_window = null
+ parent = null
+ STOP_PROCESSING(SSobj_tab_items, src)
+ return ..()
+
+/// Takes a client, attempts to generate object images for it
+/// We will update the client with any improvements we make when we're done
+/datum/object_window_info/process(seconds_per_tick)
+ // Cache the datum access for sonic speed
+ var/list/to_make = atoms_to_imagify
+ var/list/newly_seen = atoms_to_images
+ var/index = 0
+ for(index in 1 to length(to_make))
+ var/atom/thing = to_make[index]
+
+ if(!thing) // A null thing snuck in somehow
+ continue
+
+ var/generated_string
+ if(ismob(thing) || length(thing.overlays) > 0)
+ var/force_south = FALSE
+ if(isliving(thing))
+ force_south = TRUE
+ generated_string = costly_icon2html(thing, parent, sourceonly=TRUE, force_south = force_south)
+ else
+ generated_string = icon2html(thing, parent, sourceonly=TRUE)
+
+ newly_seen[thing] = generated_string
+ if(TICK_CHECK)
+ to_make.Cut(1, index + 1)
+ index = 0
+ break
+ // If we've not cut yet, do it now
+ if(index)
+ to_make.Cut(1, index + 1)
+ SSstatpanels.refresh_client_obj_view(parent)
+ if(!length(to_make))
+ return PROCESS_KILL
+
+/datum/object_window_info/proc/start_turf_tracking()
+ if(actively_tracking)
+ stop_turf_tracking()
+ var/static/list/connections = list(
+ COMSIG_MOVABLE_MOVED = PROC_REF(on_mob_move),
+ COMSIG_MOB_LOGOUT = PROC_REF(on_mob_logout),
+ )
+ AddComponent(/datum/component/connect_mob_behalf, parent, connections)
+ RegisterSignal(parent.mob.listed_turf, COMSIG_ATOM_ENTERED, PROC_REF(turflist_changed))
+ RegisterSignal(parent.mob.listed_turf, COMSIG_ATOM_EXITED, PROC_REF(turflist_changed))
+ actively_tracking = TRUE
+
+/datum/object_window_info/proc/stop_turf_tracking()
+ qdel(GetComponent(/datum/component/connect_mob_behalf))
+ UnregisterSignal(parent.mob.listed_turf, COMSIG_ATOM_ENTERED)
+ UnregisterSignal(parent.mob.listed_turf, COMSIG_ATOM_EXITED)
+ actively_tracking = FALSE
+
+/datum/object_window_info/proc/on_mob_move(mob/source)
+ SIGNAL_HANDLER
+ var/turf/listed = source.listed_turf
+ if(!listed || !source.TurfAdjacent(listed))
+ source.set_listed_turf(null)
+
+/datum/object_window_info/proc/on_mob_logout(mob/source)
+ SIGNAL_HANDLER
+ on_mob_move(parent.mob)
+
+/datum/object_window_info/proc/turflist_changed(mob/source)
+ if(!parent)//statbrowser hasnt fired yet and we still have a pending action
+ return
+ SIGNAL_HANDLER
+ if(!(flags & TURFLIST_UPDATED)) //Limit updates to 1 per tick
+ SSstatpanels.immediate_send_stat_data(parent)
+ flags |= TURFLIST_UPDATED
+ else if(!(flags & TURFLIST_UPDATE_QUEUED))
+ flags |= TURFLIST_UPDATE_QUEUED
+
+/// Clears any cached object window stuff
+/// We use hard refs cause we'd need a signal for this anyway. Cleaner this way
+/datum/object_window_info/proc/viewing_atom_deleted(atom/deleted)
+ SIGNAL_HANDLER
+ atoms_to_show -= deleted
+ atoms_to_imagify -= deleted
+ atoms_to_images -= deleted
+
+/mob/proc/set_listed_turf(turf/new_turf)
+ if(!client)
+ listed_turf = new_turf
+ return
+ if(!client.obj_window)
+ client.obj_window = new(client)
+ if(!new_turf)
+ client.obj_window.stop_turf_tracking() //Needs to go before listed_turf is set to null so signals can be removed
+ listed_turf = new_turf
+
+ if(listed_turf)
+ client.stat_panel.send_message("create_listedturf", listed_turf.name)
+ client.obj_window.start_turf_tracking()
+ else
+ client.stat_panel.send_message("remove_listedturf")
diff --git a/code/controllers/subsystems/supply.dm b/code/controllers/subsystems/supply.dm
index 84d4d4ee9ce..e7ead3b7706 100644
--- a/code/controllers/subsystems/supply.dm
+++ b/code/controllers/subsystems/supply.dm
@@ -39,8 +39,9 @@ SUBSYSTEM_DEF(supply)
/datum/controller/subsystem/supply/fire()
points += points_per_process
-/datum/controller/subsystem/supply/stat_entry()
- ..("Points: [points]")
+/datum/controller/subsystem/supply/stat_entry(msg)
+ msg = "Points: [points]"
+ return ..()
//To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types.
/datum/controller/subsystem/supply/proc/forbidden_atoms_check(atom/A)
diff --git a/code/controllers/subsystems/tgui.dm b/code/controllers/subsystems/tgui.dm
index 46b3ae90c2e..9f0baf12e65 100644
--- a/code/controllers/subsystems/tgui.dm
+++ b/code/controllers/subsystems/tgui.dm
@@ -35,8 +35,9 @@ SUBSYSTEM_DEF(tgui)
/datum/controller/subsystem/tgui/Shutdown()
close_all_uis()
-/datum/controller/subsystem/tgui/stat_entry()
- ..("P:[all_uis.len]")
+/datum/controller/subsystem/tgui/stat_entry(msg)
+ msg = "P:[all_uis.len]"
+ return ..()
/datum/controller/subsystem/tgui/fire(resumed = FALSE)
if(!resumed)
diff --git a/code/controllers/subsystems/throwing.dm b/code/controllers/subsystems/throwing.dm
index 797c5f88fb1..037970ef936 100644
--- a/code/controllers/subsystems/throwing.dm
+++ b/code/controllers/subsystems/throwing.dm
@@ -9,8 +9,9 @@ SUBSYSTEM_DEF(throwing)
var/list/currentrun
var/list/processing = list()
-/datum/controller/subsystem/throwing/stat_entry()
- ..("P:[processing.len]")
+/datum/controller/subsystem/throwing/stat_entry(msg)
+ msg = "P:[processing.len]"
+ return ..()
/datum/controller/subsystem/throwing/fire(resumed = 0)
if (!resumed)
diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm
index 88869572022..5b4ad3c60f9 100644
--- a/code/controllers/subsystems/ticker.dm
+++ b/code/controllers/subsystems/ticker.dm
@@ -41,6 +41,10 @@ SUBSYSTEM_DEF(ticker)
//Now we have a general cinematic centrally held within the gameticker....far more efficient!
var/obj/screen/cinematic = null
+ var/round_start_time = 0
+
+
+
// This global variable exists for legacy support so we don't have to rename every 'ticker' to 'SSticker' yet.
var/global/datum/controller/subsystem/ticker/ticker
/datum/controller/subsystem/ticker/PreInit()
@@ -101,6 +105,7 @@ var/global/datum/controller/subsystem/ticker/ticker
// Called during GAME_STATE_SETTING_UP (RUNLEVEL_SETUP)
/datum/controller/subsystem/ticker/proc/setup_tick(resumed = FALSE)
+ round_start_time = world.time // otherwise round_start_time would be 0 for the signals
if(!setup_choose_gamemode())
// It failed, go back to lobby state and re-send the welcome message
pregame_timeleft = config.pregame_time
@@ -123,7 +128,7 @@ var/global/datum/controller/subsystem/ticker/ticker
var/list/runnable_modes = config.get_runnable_modes()
if((master_mode == "random") || (master_mode == "secret"))
if(!runnable_modes.len)
- to_world(span_danger(span_bold("Unable to choose playable game mode.") + " Reverting to pregame lobby."))
+ to_world(span_filter_system(span_bold("Unable to choose playable game mode.") + " Reverting to pregame lobby."))
return 0
if(secret_force_mode != "secret")
src.mode = config.pick_mode(secret_force_mode)
@@ -136,7 +141,7 @@ var/global/datum/controller/subsystem/ticker/ticker
src.mode = config.pick_mode(master_mode)
if(!src.mode)
- to_world(span_danger("Serious error in mode setup! Reverting to pregame lobby.")) //Uses setup instead of set up due to computational context.
+ to_world(span_boldannounce("Serious error in mode setup! Reverting to pregame lobby.")) //Uses setup instead of set up due to computational context.
return 0
job_master.ResetOccupations()
@@ -145,21 +150,21 @@ var/global/datum/controller/subsystem/ticker/ticker
job_master.DivideOccupations() // Apparently important for new antagonist system to register specific job antags properly.
if(!src.mode.can_start())
- to_world(span_danger(span_bold("Unable to start [mode.name].") + " Not enough players readied, [config.player_requirements[mode.config_tag]] players needed. Reverting to pregame lobby."))
+ to_world(span_filter_system(span_bold("Unable to start [mode.name].") + " Not enough players readied, [config.player_requirements[mode.config_tag]] players needed. Reverting to pregame lobby."))
mode.fail_setup()
mode = null
job_master.ResetOccupations()
return 0
if(hide_mode)
- to_world(span_notice(span_bold("The current game mode is - Secret!")))
+ to_world(span_world(span_notice("The current game mode is - Secret!")))
if(runnable_modes.len)
var/list/tmpmodes = new
for (var/datum/game_mode/M in runnable_modes)
tmpmodes+=M.name
tmpmodes = sortList(tmpmodes)
if(tmpmodes.len)
- to_world(span_info(span_bold("Possibilities:") + " [english_list(tmpmodes, and_text= "; ", comma_text = "; ")]"))
+ to_world(span_filter_system(span_bold("Possibilities:") + " [english_list(tmpmodes, and_text= "; ", comma_text = "; ")]"))
else
src.mode.announce()
return 1
@@ -225,7 +230,7 @@ var/global/datum/controller/subsystem/ticker/ticker
end_game_state = END_GAME_MODE_FINISHED // Only do this cleanup once!
mode.cleanup()
//call a transfer shuttle vote
- to_world(span_danger("The round has ended!"))
+ to_world(span_boldannounce("The round has ended!"))
SSvote.start_vote(new /datum/vote/crew_transfer)
// Called during GAME_STATE_FINISHED (RUNLEVEL_POSTGAME)
@@ -238,7 +243,7 @@ var/global/datum/controller/subsystem/ticker/ticker
feedback_set_details("end_proper", "nuke")
restart_timeleft = 1 MINUTE // No point waiting five minutes if everyone's dead.
if(!delay_end)
- to_world(span_notice(span_bold("Rebooting due to destruction of [station_name()] in [round(restart_timeleft/600)] minute\s.")))
+ to_world(span_boldannounce("Rebooting due to destruction of [station_name()] in [round(restart_timeleft/600)] minute\s."))
last_restart_notify = world.time
else
feedback_set_details("end_proper", "proper completion")
@@ -252,14 +257,14 @@ var/global/datum/controller/subsystem/ticker/ticker
if(END_GAME_ENDING)
restart_timeleft -= (world.time - last_fire)
if(delay_end)
- to_world(span_notice(span_bold("An admin has delayed the round end.")))
+ to_world(span_boldannounce("An admin has delayed the round end."))
end_game_state = END_GAME_DELAYED
else if(restart_timeleft <= 0)
- to_world(span_warning(span_bold("Restarting world!")))
+ to_world(span_boldannounce("Restarting world!"))
sleep(5)
world.Reboot()
else if (world.time - last_restart_notify >= 1 MINUTE)
- to_world(span_notice(span_bold("Restarting in [round(restart_timeleft/600, 1)] minute\s.")))
+ to_world(span_boldannounce("Restarting in [round(restart_timeleft/600, 1)] minute\s."))
last_restart_notify = world.time
return
if(END_GAME_DELAYED)
@@ -418,6 +423,7 @@ var/global/datum/controller/subsystem/ticker/ticker
if(new_char.client)
var/obj/screen/splash/S = new(new_char.client, TRUE)
S.Fade(TRUE)
+ new_char.client.init_verbs()
// If they're a carbon, they can get manifested
if(J?.mob_type & JOB_CARBON)
@@ -478,7 +484,7 @@ var/global/datum/controller/subsystem/ticker/ticker
to_chat(Player, span_filter_system(span_red(span_bold("You did not survive the events on [station_name()]..."))))
else
to_chat(Player, span_filter_system(span_red(span_bold("You did not survive the events on [station_name()]..."))))
- to_world("
")
+ to_world(span_filter_system("
"))
for (var/mob/living/silicon/ai/aiPlayer in mob_list)
if (aiPlayer.stat != 2)
@@ -542,28 +548,29 @@ var/global/datum/controller/subsystem/ticker/ticker
return 1
-/datum/controller/subsystem/ticker/stat_entry()
+/datum/controller/subsystem/ticker/stat_entry(msg)
switch(current_state)
if(GAME_STATE_INIT)
..()
if(GAME_STATE_PREGAME) // RUNLEVEL_LOBBY
- ..("START [round_progressing ? "[round(pregame_timeleft)]s" : "(PAUSED)"]")
+ msg = "START [round_progressing ? "[round(pregame_timeleft)]s" : "(PAUSED)"]"
if(GAME_STATE_SETTING_UP) // RUNLEVEL_SETUP
- ..("SETUP")
+ msg = "SETUP"
if(GAME_STATE_PLAYING) // RUNLEVEL_GAME
- ..("GAME")
+ msg = "GAME"
if(GAME_STATE_FINISHED) // RUNLEVEL_POSTGAME
switch(end_game_state)
if(END_GAME_MODE_FINISHED)
- ..("MODE OVER, WAITING")
+ msg = "MODE OVER, WAITING"
if(END_GAME_READY_TO_END)
- ..("ENDGAME PROCESSING")
+ msg = "ENDGAME PROCESSING"
if(END_GAME_ENDING)
- ..("END IN [round(restart_timeleft/10)]s")
+ msg = "END IN [round(restart_timeleft/10)]s"
if(END_GAME_DELAYED)
- ..("END PAUSED")
+ msg = "END PAUSED"
else
- ..("ENDGAME ERROR:[end_game_state]")
+ msg = "ENDGAME ERROR:[end_game_state]"
+ return ..()
/datum/controller/subsystem/ticker/Recover()
flags |= SS_NO_INIT // Don't initialize again
@@ -579,3 +586,5 @@ var/global/datum/controller/subsystem/ticker/ticker
minds = SSticker.minds
random_players = SSticker.random_players
+
+ round_start_time = SSticker.round_start_time
diff --git a/code/controllers/subsystems/timer.dm b/code/controllers/subsystems/timer.dm
index 701307c6276..fc43b81fd39 100644
--- a/code/controllers/subsystems/timer.dm
+++ b/code/controllers/subsystems/timer.dm
@@ -34,7 +34,8 @@ SUBSYSTEM_DEF(timer)
bucket_resolution = world.tick_lag
/datum/controller/subsystem/timer/stat_entry(msg)
- ..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]")
+ msg = "B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]"
+ return ..()
/datum/controller/subsystem/timer/fire(resumed = FALSE)
var/lit = last_invoke_tick
diff --git a/code/controllers/subsystems/transcore_vr.dm b/code/controllers/subsystems/transcore_vr.dm
index d2292c32d89..13a4632b8de 100644
--- a/code/controllers/subsystems/transcore_vr.dm
+++ b/code/controllers/subsystems/transcore_vr.dm
@@ -122,9 +122,8 @@ SUBSYSTEM_DEF(transcore)
if(MC_TICK_CHECK)
return
-/datum/controller/subsystem/transcore/stat_entry()
- var/msg = list()
- msg += "$:{"
+/datum/controller/subsystem/transcore/stat_entry(msg)
+ msg = "$:{"
msg += "IM:[round(cost_implants,1)]|"
msg += "BK:[round(cost_backups,1)]"
msg += "} "
@@ -137,7 +136,7 @@ SUBSYSTEM_DEF(transcore)
msg += "DFB:[default_db.body_scans.len]|"
msg += "DFI:[default_db.implants.len]"
msg += "} "
- ..(jointext(msg, null))
+ return ..()
/datum/controller/subsystem/transcore/Recover()
for(var/key in SStranscore.databases)
diff --git a/code/controllers/subsystems/vote.dm b/code/controllers/subsystems/vote.dm
index c0476024973..102ffe5028b 100644
--- a/code/controllers/subsystems/vote.dm
+++ b/code/controllers/subsystems/vote.dm
@@ -25,7 +25,7 @@ SUBSYSTEM_DEF(vote)
if(mode)
time_remaining = round((started_time + duration - world.time)/10)
if(mode == VOTE_GAMEMODE && ticker.current_state >= GAME_STATE_SETTING_UP)
- to_chat(world, "Gamemode vote aborted: Game has already started.")
+ to_chat(world, span_bold("Gamemode vote aborted: Game has already started."))
reset()
return
if(time_remaining <= 0)
@@ -105,7 +105,7 @@ SUBSYSTEM_DEF(vote)
else
factor = 1.4
choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor)
- to_world(span_purple("Crew Transfer Factor: [factor]"))
+ to_world(span_filter_system(span_purple("Crew Transfer Factor: [factor]")))
greatest_votes = max(choices["Initiate Crew Transfer"], choices["Extend the Shift"]) //VOREStation Edit
. = list() // Get all options with that many votes and return them in a list
@@ -120,7 +120,7 @@ SUBSYSTEM_DEF(vote)
if(winners.len > 0)
if(winners.len > 1)
if(mode != VOTE_GAMEMODE || ticker.hide_mode == 0) // Here we are making sure we don't announce potential game modes
- text = "Vote Tied Between:\n"
+ text = span_bold("Vote Tied Between:") + "\n"
for(var/option in winners)
text += "\t[option]\n"
. = pick(winners)
@@ -129,12 +129,12 @@ SUBSYSTEM_DEF(vote)
if(choices[current_votes[key]] == .)
round_voters += key // Keep track of who voted for the winning round.
if(mode != VOTE_GAMEMODE || . == "Extended" || ticker.hide_mode == 0) // Announce Extended gamemode, but not other gamemodes
- text += "Vote Result: [mode == VOTE_GAMEMODE ? gamemode_names[.] : .]"
+ text += span_bold("Vote Result: [mode == VOTE_GAMEMODE ? gamemode_names[.] : .]")
else
- text += "The vote has ended."
+ text += span_bold("The vote has ended.")
else
- text += "Vote Result: Inconclusive - No Votes!"
+ text += span_bold("Vote Result: Inconclusive - No Votes!")
if(mode == VOTE_ADD_ANTAGONIST)
antag_add_failed = 1
log_vote(text)
@@ -167,10 +167,10 @@ SUBSYSTEM_DEF(vote)
if(mode == VOTE_GAMEMODE) //fire this even if the vote fails.
if(!round_progressing)
round_progressing = 1
- to_world(span_red("The round will start soon."))
+ to_world(span_boldannounce("The round will start soon."))
if(restart)
- to_world("World restarting due to vote...")
+ to_world(span_filter_system("World restarting due to vote..."))
feedback_set_details("end_error", "restart vote")
if(blackbox)
blackbox.save_all_data_to_sql()
@@ -253,14 +253,14 @@ SUBSYSTEM_DEF(vote)
log_vote(text)
- to_world(span_purple("[text]\nType vote or click here to place your votes.\nYou have [config.vote_period / 10] seconds to vote."))
+ to_world(span_filter_system(span_purple(span_bold("[text]") + "\nType " + span_bold("vote") + " or click here to place your votes.\nYou have [config.vote_period / 10] seconds to vote.")))
if(vote_type == VOTE_CREW_TRANSFER || vote_type == VOTE_GAMEMODE || vote_type == VOTE_CUSTOM)
world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
if(mode == VOTE_GAMEMODE && round_progressing)
gamemode_vote_called = TRUE
round_progressing = 0
- to_world(span_red("Round start has been delayed."))
+ to_world(span_boldannounce("Round start has been delayed."))
time_remaining = round(config.vote_period / 10)
return 1
diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm
index ef76e63ca7b..69bfa4773cb 100644
--- a/code/datums/ai_laws.dm
+++ b/code/datums/ai_laws.dm
@@ -227,9 +227,9 @@
if(law == zeroth_law_borg)
continue
if(law == zeroth_law)
- to_chat(who, span_danger("[law.get_index()]. [law.law]"))
+ to_chat(who, span_info(span_red("[law.get_index()]. [law.law]")))
else
- to_chat(who, "[law.get_index()]. [law.law]")
+ to_chat(who, span_infoplain("[law.get_index()]. [law.law]"))
/********************
* Stating Laws *
diff --git a/code/datums/chat_message.dm b/code/datums/chat_message.dm
index 65296088d48..9dc66a3cbc8 100644
--- a/code/datums/chat_message.dm
+++ b/code/datums/chat_message.dm
@@ -148,7 +148,7 @@ var/list/runechat_image_cache = list()
// Differnt from our own system of name emphasis, maybe unify
var/list/names = splittext(owner.name, " ")
for (var/word in names)
- text = replacetext(text, word, "[word]")
+ text = replacetext(text, word, span_bold("[word]"))
var/list/prefixes
diff --git a/code/datums/components/connect_mob_behalf.dm b/code/datums/components/connect_mob_behalf.dm
new file mode 100644
index 00000000000..1c1a8a65234
--- /dev/null
+++ b/code/datums/components/connect_mob_behalf.dm
@@ -0,0 +1,59 @@
+/// This component behaves similar to connect_loc_behalf, but working off clients and mobs instead of loc
+/// To be clear, we hook into a signal on a tracked client's mob
+/// We retain the ability to react to that signal on a seperate listener, which makes this quite powerful
+/datum/component/connect_mob_behalf
+ dupe_mode = COMPONENT_DUPE_UNIQUE
+
+ /// An assoc list of signal -> procpath to register to the mob our client "owns"
+ var/list/connections
+ /// The master client we're working with
+ var/client/tracked
+ /// The mob we're currently tracking
+ var/mob/tracked_mob
+
+/datum/component/connect_mob_behalf/Initialize(client/tracked, list/connections)
+ . = ..()
+ if (!istype(tracked))
+ return COMPONENT_INCOMPATIBLE
+ src.connections = connections
+ src.tracked = tracked
+
+/datum/component/connect_mob_behalf/RegisterWithParent()
+ RegisterSignal(tracked, COMSIG_PARENT_QDELETING, PROC_REF(handle_tracked_qdel))
+ update_signals()
+
+/datum/component/connect_mob_behalf/UnregisterFromParent()
+ unregister_signals()
+ UnregisterSignal(tracked, COMSIG_PARENT_QDELETING)
+
+ tracked = null
+ tracked_mob = null
+
+/datum/component/connect_mob_behalf/proc/handle_tracked_qdel()
+ SIGNAL_HANDLER
+ qdel(src)
+
+/datum/component/connect_mob_behalf/proc/update_signals()
+ unregister_signals()
+ // Yes this is a runtime silencer
+ // We could be in a position where logout is sent to two things, one thing intercepts it, then deletes the client's new mob
+ // It's rare, and the same check in connect_loc_behalf is more fruitful, but it's still worth doing
+ if(QDELETED(tracked?.mob))
+ return
+ tracked_mob = tracked.mob
+ RegisterSignal(tracked_mob, COMSIG_MOB_LOGOUT, PROC_REF(on_logout))
+ for (var/signal in connections)
+ parent.RegisterSignal(tracked_mob, signal, connections[signal])
+
+/datum/component/connect_mob_behalf/proc/unregister_signals()
+ if(isnull(tracked_mob))
+ return
+
+ parent.UnregisterSignal(tracked_mob, connections)
+ UnregisterSignal(tracked_mob, COMSIG_MOB_LOGOUT)
+
+ tracked_mob = null
+
+/datum/component/connect_mob_behalf/proc/on_logout(mob/source)
+ SIGNAL_HANDLER
+ update_signals()
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index 59cd16434e6..be1b1236adb 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -91,7 +91,7 @@
/datum/proc/vv_get_header()
. = list()
if(("name" in vars) && !isatom(src))
- . += "[vars["name"]]
"
+ . += span_bold("[vars["name"]]") + "
"
/datum/proc/on_reagent_change(changetype)
return
diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm
index ad9a210c79a..1cce0db9c5d 100644
--- a/code/datums/helper_datums/getrev.dm
+++ b/code/datums/helper_datums/getrev.dm
@@ -64,19 +64,19 @@ GLOBAL_DATUM(revdata, /datum/getrev)
var/list/msg = list()
if(GLOB.revdata.revision)
- msg += "Server revision: B:[GLOB.revdata.branch] D:[GLOB.revdata.date]"
+ msg += span_bold("Server revision:") + " B:[GLOB.revdata.branch] D:[GLOB.revdata.date]"
if(config.githuburl)
- msg += "Commit: [GLOB.revdata.revision]"
+ msg += span_bold("Commit:") + " [GLOB.revdata.revision]"
else
- msg += "Commit: GLOB.revdata.revision"
+ msg += span_bold("Commit:") + " GLOB.revdata.revision"
else
- msg += "Server revision: Unknown"
+ msg += span_bold("Server revision:") + " Unknown"
if(world.TgsAvailable())
var/datum/tgs_version/version = world.TgsVersion()
- msg += "TGS version: [version.raw_parameter]"
+ msg += span_bold("TGS version:") + " [version.raw_parameter]"
var/datum/tgs_version/api_version = world.TgsApiVersion()
- msg += "DMAPI version: [api_version.raw_parameter]"
+ msg += span_bold("DMAPI version:") + " [api_version.raw_parameter]"
if(GLOB.revdata.testmerge.len)
msg += GLOB.revdata.GetTestMergeInfo()
diff --git a/code/datums/managed_browsers/feedback_form.dm b/code/datums/managed_browsers/feedback_form.dm
index ea6ef32b9f5..d44b1265f61 100644
--- a/code/datums/managed_browsers/feedback_form.dm
+++ b/code/datums/managed_browsers/feedback_form.dm
@@ -58,14 +58,14 @@ GENERAL_PROTECT_DATUM(/datum/managed_browser/feedback_form)
if(can_be_private())
if(!feedback_hide_author)
dat += "[my_client.ckey] "
- dat += span_linkOn("Visible")
+ dat += span_linkOn(span_bold("Visible"))
dat += " | "
dat += href(src, list("feedback_hide_author" = 1), "Hashed")
else
dat += "[md5(ckey(lowertext(my_client.ckey + SSsqlite.get_feedback_pepper())))] "
dat += href(src, list("feedback_hide_author" = 0), "Visible")
dat += " | "
- dat += span_linkOn("Hashed")
+ dat += span_linkOn(span_bold("Hashed"))
else
dat += my_client.ckey
dat += "
"
@@ -79,7 +79,7 @@ GENERAL_PROTECT_DATUM(/datum/managed_browser/feedback_form)
if(feedback_body)
dat += replacetext(feedback_body, "\n", "
") // So newlines will look like they work in the preview.
else
- dat += "\[Feedback goes here...\]"
+ dat += span_italics("\[Feedback goes here...\]")
dat += "
"
dat += href(src, list("feedback_edit_body" = 1), "Edit")
dat += "
| "
output += ""
@@ -437,18 +437,18 @@
if("PERMABAN")
typedesc = "PERMABAN"
if("TEMPBAN")
- typedesc = "TEMPBAN ([duration] minutes) [(unbanned || auto) ? "" : "(Edit)"] Expires [expiration]" + typedesc = span_bold("TEMPBAN") + " ([duration] minutes) [(unbanned || auto) ? "" : "(Edit)"] Expires [expiration]" if("JOB_PERMABAN") - typedesc = "JOBBAN ([job])" + typedesc = span_bold("JOBBAN") + " ([job])" if("JOB_TEMPBAN") - typedesc = "TEMP JOBBAN ([job]) ([duration] minutes Expires [expiration]" + typedesc = span_bold("TEMP JOBBAN") + " ([job]) ([duration] minutes Expires [expiration]" output += " | |||||||||||||||||||||||||||||||||||||
| [typedesc] | " output += "[ckey] | " output += "[bantime] | " output += "[ackey] | " - output += "[(unbanned || auto) ? "" : "Unban"] | " + output += "[(unbanned || auto) ? "" : span_bold("Unban")] | " output += "||||||||||||||||||||||||||||||||
| IP: [ip] | " diff --git a/code/modules/admin/ToRban.dm b/code/modules/admin/ToRban.dm index 4027234428e..d8e39edfd96 100644 --- a/code/modules/admin/ToRban.dm +++ b/code/modules/admin/ToRban.dm @@ -73,14 +73,14 @@ var/choice = tgui_input_list(src,"Please select an IP address to remove from the ToR banlist:","Remove ToR ban", F.dir) if(choice) F.dir.Remove(choice) - to_chat(src, span_filter_adminlog("Address removed")) + to_chat(src, span_filter_adminlog(span_bold("Address removed"))) if("remove all") - to_chat(src, span_filter_adminlog("[TORFILE] was [fdel(TORFILE)?"":"not "]removed.")) + to_chat(src, span_filter_adminlog(span_bold("[TORFILE] was [fdel(TORFILE)?"":"not "]removed."))) if("find") var/input = tgui_input_text(src,"Please input an IP address to search for:","Find ToR ban",null) if(input) if(ToRban_isbanned(input)) - to_chat(src, span_filter_adminlog("[span_orange("Address is a known ToR address")]")) + to_chat(src, span_filter_adminlog("[span_orange(span_bold("Address is a known ToR address"))]")) else to_chat(src, span_filter_adminlog(span_danger("Address is not a known ToR address"))) return diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 8a91738a56e..4eb8e4172e6 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -3,7 +3,7 @@ var/global/floorIsLava = 0 //////////////////////////////// /proc/message_admins(var/msg) - msg = "" + msg = span_filter_adminlog(span_log_message(span_prefix("ADMIN LOG:") + span_message("[msg]"))) //log_adminwarn(msg) //log_and_message_admins is for this for(var/client/C in GLOB.admins) @@ -14,7 +14,7 @@ var/global/floorIsLava = 0 confidential = TRUE) /proc/msg_admin_attack(var/text) //Toggleable Attack Messages - var/rendered = "" + var/rendered = span_filter_attacklog(span_log_message(span_prefix("ATTACK:") + span_message("[text]"))) for(var/client/C in GLOB.admins) if((R_ADMIN|R_MOD) & C.holder.rights) if(C.prefs?.read_preference(/datum/preference/toggle/show_attack_logs)) @@ -104,7 +104,7 @@ var/global/floorIsLava = 0 if (M.client) if(!istype(M, /mob/new_player)) body += "|||||||||||||||||||||||||||||||||||||
" // Table within a table for alignment, also allows you to easily add more columns.
. += "
")]") to_chat(src,msg) @@ -88,7 +88,7 @@ temp += "\t[C] is a [C.holder.rank]" if(holder) if(C.holder.fakekey) - temp += " (as [C.holder.fakekey])" + temp += " " + span_italics("(as [C.holder.fakekey])") if(isobserver(C.mob)) temp += " - Observing" @@ -111,16 +111,16 @@ if(R_EVENT) eventMmsg += temp - msg = "Current Admins ([num_admins_online]):\n" + msg + msg = span_bold("Current Admins ([num_admins_online]):") + "\n" + msg if(config.show_mods) - msg += "\n Current Game Masters ([num_mods_online]):\n" + modmsg + msg += "\n" + span_bold(" Current Game Masters ([num_mods_online]):") + "\n" + modmsg if(config.show_devs) - msg += "\n Current Developers ([num_devs_online]):\n" + devmsg + msg += "\n" + span_bold(" Current Developers ([num_devs_online]):") + "\n" + devmsg if(config.show_event_managers) - msg += "\n Current Miscellaneous ([num_event_managers_online]):\n" + eventMmsg + msg += "\n" + span_bold(" Current Miscellaneous ([num_event_managers_online]):") + "\n" + eventMmsg var/num_mentors_online = 0 var/mmsg = "" @@ -142,8 +142,8 @@ mmsg += "\n" if(config.show_mentors) - msg += "\n Current Mentors ([num_mentors_online]):\n" + mmsg + msg += "\n" + span_bold(" Current Mentors ([num_mentors_online]):") + "\n" + mmsg - msg += "\nAdminhelps are also sent to Discord. If no admins are available in game try anyway and an admin on Discord may see it and respond." + msg += "\n" + span_info("Adminhelps are also sent to Discord. If no admins are available in game try anyway and an admin on Discord may see it and respond.") to_chat(src,span_filter_notice("[jointext(msg, " ")]")) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index af8fc6ecd2d..617396500db 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -485,7 +485,8 @@ update_light() update_icon(user) - user.update_action_buttons() + spawn(10) // FIXME: Remove when SSoverlays stops queueing overlay changes + user.update_action_buttons_icon() /obj/item/clothing/head/attack_ai(var/mob/user) if(!mob_wear_hat(user)) @@ -670,7 +671,7 @@ user.unEquip(I) I.forceMove(src) holding = I - user.visible_message("\The [user] shoves \the [I] into \the [src].") + user.visible_message(span_infoplain(span_bold("\The [user]") + " shoves \the [I] into \the [src].")) verbs |= /obj/item/clothing/shoes/proc/draw_knife update_icon() else diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 3af787763e2..5ed049694c8 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -71,7 +71,7 @@ BLIND // can't see anything tint = initial(tint) enables_planes = away_planes away_planes = null - user.update_action_buttons() + user.update_action_buttons_icon() user.recalculate_vis() /obj/item/clothing/glasses/attack_self(mob/user) @@ -91,7 +91,7 @@ BLIND // can't see anything desc = "Used for seeing walls, floors, and stuff through anything." icon_state = "meson" item_state_slots = list(slot_r_hand_str = "meson", slot_l_hand_str = "meson") - action_button_name = "Toggle Goggles" + actions_types = list(/datum/action/item_action/toggle_goggles) origin_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2) toggleable = 1 vision_flags = SEE_TURFS @@ -111,7 +111,7 @@ BLIND // can't see anything icon_state = "aviator_eng" off_state = "aviator" item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") - action_button_name = "Toggle HUD" + actions_types = list(/datum/action/item_action/toggle_hud) activation_sound = 'sound/effects/pop.ogg' /obj/item/clothing/glasses/meson/aviator/prescription @@ -124,7 +124,7 @@ BLIND // can't see anything desc = "Modified aviator glasses with a toggled health HUD." icon_state = "aviator_med" off_state = "aviator" - action_button_name = "Toggle Mode" + actions_types = list(/datum/action/item_action/toggle_mode) toggleable = 1 activation_sound = 'sound/effects/pop.ogg' @@ -139,7 +139,7 @@ BLIND // can't see anything icon_state = "purple" item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") toggleable = 1 - action_button_name = "Toggle Goggles" + actions_types = list(/datum/action/item_action/toggle_goggles) item_flags = AIRTIGHT /obj/item/clothing/glasses/science/New() @@ -162,7 +162,7 @@ BLIND // can't see anything origin_tech = list(TECH_MAGNET = 2) darkness_view = 7 toggleable = 1 - action_button_name = "Toggle Goggles" + actions_types = list(/datum/action/item_action/toggle_goggles) off_state = "denight" flash_protection = FLASH_PROTECTION_REDUCED enables_planes = list(VIS_FULLBRIGHT) @@ -238,7 +238,7 @@ BLIND // can't see anything item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") origin_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 3) toggleable = 1 - action_button_name = "Toggle Goggles" + actions_types = list(/datum/action/item_action/toggle_goggles) vision_flags = SEE_OBJS enables_planes = list(VIS_FULLBRIGHT) @@ -258,7 +258,7 @@ BLIND // can't see anything origin_tech = list(TECH_MAGNET = 2, TECH_BLUESPACE = 1) darkness_view = 5 toggleable = 1 - action_button_name = "Toggle Goggles" + actions_types = list(/datum/action/item_action/toggle_goggles) off_state = "denight" vision_flags = SEE_OBJS | SEE_TURFS flash_protection = FLASH_PROTECTION_REDUCED @@ -375,7 +375,7 @@ BLIND // can't see anything desc = "Protects the eyes from welders, approved by the mad scientist association." icon_state = "welding-g" item_state_slots = list(slot_r_hand_str = "welding-g", slot_l_hand_str = "welding-g") - action_button_name = "Flip Welding Goggles" + actions_types = list(/datum/action/item_action/flip_welding_goggles) matter = list(MAT_STEEL = 1500, MAT_GLASS = 1000) item_flags = AIRTIGHT var/up = 0 @@ -408,7 +408,7 @@ BLIND // can't see anything tint = TINT_NONE to_chat(usr, "You push \the [src] up out of your face.") update_clothing_icon() - usr.update_action_buttons() + usr.update_action_buttons_icon() /obj/item/clothing/glasses/welding/superior name = "superior welding goggles" @@ -481,7 +481,7 @@ BLIND // can't see anything desc = "Modified aviator glasses that can be switch between HUD and flash protection modes." icon_state = "aviator_sec" off_state = "aviator" - action_button_name = "Toggle Mode" + actions_types = list(/datum/action/item_action/toggle_mode) var/on = 1 toggleable = 1 activation_sound = 'sound/effects/pop.ogg' @@ -503,7 +503,7 @@ BLIND // can't see anything user << activation_sound user.recalculate_vis() user.update_inv_glasses() - user.update_action_buttons() + user.update_action_buttons_icon() /obj/item/clothing/glasses/sunglasses/sechud/aviator/update_icon() if(on) @@ -529,7 +529,7 @@ BLIND // can't see anything item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") origin_tech = list(TECH_MAGNET = 3) toggleable = 1 - action_button_name = "Toggle Goggles" + actions_types = list(/datum/action/item_action/toggle_goggles) vision_flags = SEE_MOBS enables_planes = list(VIS_FULLBRIGHT, VIS_CLOAKED) flash_protection = FLASH_PROTECTION_REDUCED @@ -562,7 +562,7 @@ BLIND // can't see anything /obj/item/clothing/glasses/thermal/plain toggleable = 0 activation_sound = null - action_button_name = null + actions_types = list() /obj/item/clothing/glasses/thermal/plain/monocle name = "thermonocle" @@ -570,7 +570,7 @@ BLIND // can't see anything icon_state = "thermoncle" item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") toggleable = 1 - action_button_name = "Toggle Monocle" + actions_types = list(/datum/action/item_action/toggle_monocle) flags = null //doesn't protect eyes because it's a monocle, duh body_parts_covered = 0 @@ -582,7 +582,7 @@ BLIND // can't see anything item_state_slots = list(slot_r_hand_str = "blindfold", slot_l_hand_str = "blindfold") body_parts_covered = 0 toggleable = 1 - action_button_name = "Toggle Eyepatch" + actions_types = list(/datum/action/item_action/toggle_eyepatch) /obj/item/clothing/glasses/thermal/plain/jensen name = "optical thermal implants" @@ -595,7 +595,7 @@ BLIND // can't see anything desc = "Teshari designed lightweight goggles." icon_state = "orange-g" item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") - action_button_name = "Adjust Orange Goggles" + actions_types = list(/datum/action/item_action/adjust_orange_goggles) var/up = 0 item_flags = AIRTIGHT body_parts_covered = EYES @@ -623,4 +623,4 @@ BLIND // can't see anything icon_state = "[initial(icon_state)]up" to_chat(usr, "You push \the [src] up from in front of your eyes.") update_clothing_icon() - usr.update_action_buttons() + usr.update_action_buttons_icon() diff --git a/code/modules/clothing/glasses/glasses_vr.dm b/code/modules/clothing/glasses/glasses_vr.dm index 88baa9bf120..35399268f77 100644 --- a/code/modules/clothing/glasses/glasses_vr.dm +++ b/code/modules/clothing/glasses/glasses_vr.dm @@ -68,7 +68,7 @@ icon_override = 'icons/inventory/eyes/mob_vr.dmi' icon_state = "medgravpatch" item_state_slots = list(slot_r_hand_str = "blindfold", slot_l_hand_str = "blindfold") - action_button_name = "Toggle Eyepatch" + actions_types = list(/datum/action/item_action/toggle_eyepatch) off_state = "eyepatch" enables_planes = list(VIS_CH_STATUS,VIS_CH_HEALTH,VIS_FULLBRIGHT,VIS_MESONS) @@ -82,8 +82,7 @@ flash_protection = FLASH_PROTECTION_MODERATE item_flags = AIRTIGHT body_parts_covered = EYES - action_button_name = "Change scanning pattern" - action_button_is_hands_free = TRUE + actions_types = list(/datum/action/item_action/hands_free/change_scanning_pattern) var/static/list/tac_sec_vis_anim = list() /obj/item/clothing/glasses/sunglasses/sechud/tactical_sec_vis/Initialize(mapload) @@ -107,7 +106,7 @@ if(src && choice && !user.incapacitated() && in_range(user,src)) icon_state = options[choice] user.update_inv_glasses() - user.update_action_buttons() + user.update_action_buttons_icon() to_chat(user, span_notice("Your [src] now displays [choice] .")) return 1 diff --git a/code/modules/clothing/glasses/hud_vr.dm b/code/modules/clothing/glasses/hud_vr.dm index 06e8fbf72a8..1e13f56d177 100644 --- a/code/modules/clothing/glasses/hud_vr.dm +++ b/code/modules/clothing/glasses/hud_vr.dm @@ -33,9 +33,9 @@ /obj/item/clothing/glasses/omnihud/examine() . = ..() if(ar_toggled) - . += "\n The HUD indicator reads ON." + . += "\n " + span_notice("The HUD indicator reads ON.") else - . += "\n The HUD indicator reads OFF." + . += "\n " + span_notice("The HUD indicator reads OFF.") /obj/item/clothing/glasses/omnihud/emp_act(var/severity) @@ -141,7 +141,7 @@ away_planes = null to_chat(usr, span_notice("You enabled the Augmented Reality HUD of your [src.name].")) ar_toggled = !ar_toggled - usr.update_action_buttons() + usr.update_action_buttons_icon() usr.recalculate_vis() @@ -167,7 +167,7 @@ These have been upgraded with medical records access and virus database integration. \ They can also read data from active suit sensors using the crew monitoring system." mode = "med" - action_button_name = "AR Console (Crew Monitor)" + actions_types = list(/datum/action/item_action/ar_console_crew) tgarscreen_path = /datum/tgui_module/crew_monitor/glasses enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_STATUS_R,VIS_CH_BACKUP,VIS_AUGMENTED) @@ -183,7 +183,7 @@ They also have access to security alerts such as camera and motion sensor alarms." mode = "sec" flash_protection = FLASH_PROTECTION_MODERATE //weld protection is a little too widespread - action_button_name = "AR Console (Security Alerts)" + actions_types = list(/datum/action/item_action/ar_console_security_alerts) tgarscreen_path = /datum/tgui_module/alarm_monitor/security/glasses enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_WANTED,VIS_AUGMENTED) @@ -199,7 +199,7 @@ and can also display a list of atmospheric, fire, and power alarms." mode = "eng" flash_protection = FLASH_PROTECTION_MAJOR - action_button_name = "AR Console (Station Alerts)" + actions_types = list(/datum/action/item_action/ar_console_station_alerts) tgarscreen_path = /datum/tgui_module/alarm_monitor/engineering/glasses /obj/item/clothing/glasses/omnihud/eng/ar_interact(var/mob/living/carbon/human/user) @@ -249,7 +249,7 @@ item_state = initial(item_state) usr.update_inv_glasses() to_chat(usr, "You activate the retinal projector on the [src].") - usr.update_action_buttons() + usr.update_action_buttons_icon() /obj/item/clothing/glasses/omnihud/all name = "\improper AR-B glasses" @@ -259,7 +259,7 @@ mode = "best" flash_protection = FLASH_PROTECTION_MAJOR enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_STATUS_R,VIS_CH_BACKUP,VIS_CH_WANTED,VIS_AUGMENTED) - action_button_name = "AR Console (All Alerts)" + actions_types = list(/datum/action/item_action/ar_console_all_alerts) tgarscreen_path = /datum/tgui_module/alarm_monitor/all/glasses /obj/item/clothing/glasses/omnihud/all/ar_interact(var/mob/living/carbon/human/user) diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index f65a9b0a128..3862469c857 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -62,7 +62,7 @@ //TODO: Make inflating gloves a thing /*/obj/item/clothing/gloves/sterile/proc/Inflate(/mob/living/carbon/human/user) - user.visible_message("\The [src] expands!") + user.visible_message(span_infoplain(span_bold("\The [src]") + " expands!")) qdel(src)*/ /obj/item/clothing/gloves/sterile/latex diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 308672b3b72..02bb0f5313b 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -19,7 +19,7 @@ armor = list(melee = 30, bullet = 5, laser = 20,energy = 10, bomb = 20, bio = 10, rad = 20) flags_inv = 0 siemens_coefficient = 0.9 - action_button_name = "Toggle Head-light" + actions_types = list(/datum/action/item_action/toggle_head_light) w_class = ITEMSIZE_NORMAL ear_protection = 1 drop_sound = 'sound/items/drop/helm.ogg' diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 236f7857967..4106d577af7 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -66,7 +66,7 @@ armor = list(melee = 80, bullet = 10, laser = 10, energy = 10, bomb = 0, bio = 0, rad = 0) siemens_coefficient = 0.7 valid_accessory_slots = null - action_button_name = "Toggle Visor" + actions_types = list(/datum/action/item_action/toggle_visor) /obj/item/clothing/head/helmet/riot/attack_self(mob/user as mob) if(src.icon_state == initial(icon_state)) @@ -113,7 +113,7 @@ siemens_coefficient = 0.6 light_range = 6 light_overlay = "helmet_light_dual_green" - action_button_name = "Toggle Head-light" + actions_types = list(/datum/action/item_action/toggle_head_light) min_cold_protection_temperature = T0C - 20 cold_protection = HEAD @@ -150,7 +150,7 @@ /obj/item/clothing/head/helmet/thunderdome name = "\improper Thunderdome helmet" - desc = "'Let the battle commence!'" + desc = span_italics("'Let the battle commence!'") icon_state = "thunderdome" armor = list(melee = 80, bullet = 60, laser = 50,energy = 10, bomb = 25, bio = 10, rad = 0) cold_protection = HEAD diff --git a/code/modules/clothing/head/helmet_vr.dm b/code/modules/clothing/head/helmet_vr.dm index 53e9c581af4..b02024594c1 100644 --- a/code/modules/clothing/head/helmet_vr.dm +++ b/code/modules/clothing/head/helmet_vr.dm @@ -28,7 +28,7 @@ icon = 'icons/inventory/head/item_vr.dmi' icon_override = 'icons/inventory/head/mob_vr.dmi' -// Armor Versions Here +// Armor Versions Here /obj/item/clothing/head/helmet/combat/crusader name = "crusader helmet" desc = "ye olde armored helmet" @@ -47,10 +47,10 @@ armor = list(melee = 80, bullet = 50, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0) tint = TINT_HEAVY siemens_coefficient = 2 - + var/base_state var/up = FALSE - + /obj/item/clothing/head/helmet/combat/bedevere/attack_self() toggle() @@ -83,8 +83,8 @@ if (ismob(src.loc)) //should allow masks to update when it is opened/closed var/mob/M = src.loc M.update_inv_wear_mask() - usr.update_action_buttons() - + usr.update_action_buttons_icon() + // Costume Versions Here /obj/item/clothing/head/helmet/combat/crusader_costume name = "crusader costume helmet" @@ -104,10 +104,10 @@ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) tint = TINT_HEAVY siemens_coefficient = 1 - + var/base_state var/up = FALSE - + /obj/item/clothing/head/helmet/combat/bedevere_costume/attack_self() toggle() @@ -140,4 +140,4 @@ if (ismob(src.loc)) //should allow masks to update when it is opened/closed var/mob/M = src.loc M.update_inv_wear_mask() - usr.update_action_buttons() \ No newline at end of file + usr.update_action_buttons_icon() diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 2572bffa4b4..7d9fb9b54ab 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -110,7 +110,7 @@ name = "redcoat's hat" icon_state = "redcoat" item_state_slots = list(slot_r_hand_str = "pirate", slot_l_hand_str = "pirate") - desc = "'I guess it's a redhead.'" + desc = span_italics("'I guess it's a redhead.'") body_parts_covered = 0 /obj/item/clothing/head/mailman diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index b5fd02b17e6..76467e49726 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -23,7 +23,7 @@ armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) flags_inv = (HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE) body_parts_covered = HEAD|FACE|EYES - action_button_name = "Flip Welding Mask" + actions_types = list(/datum/action/item_action/flip_welding_mask) siemens_coefficient = 0.9 w_class = ITEMSIZE_NORMAL var/base_state @@ -65,7 +65,7 @@ if (ismob(src.loc)) //should allow masks to update when it is opened/closed var/mob/M = src.loc M.update_inv_wear_mask() - usr.update_action_buttons() + usr.update_action_buttons_icon() /obj/item/clothing/head/welding/demon name = "demonic welding helmet" diff --git a/code/modules/clothing/head/pilot_helmet.dm b/code/modules/clothing/head/pilot_helmet.dm index 590cba4dd1a..b035fb5a4f4 100644 --- a/code/modules/clothing/head/pilot_helmet.dm +++ b/code/modules/clothing/head/pilot_helmet.dm @@ -188,7 +188,7 @@ name = "pilot helmet" desc = "Standard pilot gear. Protects the head from impacts. This one has a retractable visor" icon_state = "pilot_helmet2" - action_button_name = "Toggle Visor" + actions_types = list(/datum/action/item_action/toggle_visor) /obj/item/clothing/head/pilot/alt/attack_self(mob/user as mob) if(src.icon_state == initial(icon_state)) @@ -197,4 +197,4 @@ else src.icon_state = initial(icon_state) to_chat(user, "You lower the visor on the pilot helmet.") - update_clothing_icon() //so our mob-overlays update \ No newline at end of file + update_clothing_icon() //so our mob-overlays update diff --git a/code/modules/clothing/head/pilot_helmet_vr.dm b/code/modules/clothing/head/pilot_helmet_vr.dm index ab4b2335c82..8aa36238a88 100644 --- a/code/modules/clothing/head/pilot_helmet_vr.dm +++ b/code/modules/clothing/head/pilot_helmet_vr.dm @@ -15,7 +15,7 @@ sprite_sheets = list( SPECIES_TESHARI = 'icons/inventory/head/mob_vr_teshari.dmi' ) - action_button_name = "Toggle Visor" + actions_types = list(/datum/action/item_action/toggle_visor) /obj/item/clothing/head/pilot_vr/attack_self(mob/user as mob) if(src.icon_state == initial(icon_state)) @@ -34,7 +34,7 @@ sprite_sheets = list( SPECIES_TESHARI = 'icons/inventory/head/mob_vr_teshari.dmi' ) - action_button_name = "Toggle Visor" + actions_types = list(/datum/action/item_action/toggle_visor) /obj/item/clothing/head/pilot_vr/alt/attack_self(mob/user as mob) if(src.icon_state == initial(icon_state)) @@ -55,7 +55,7 @@ sprite_sheets = list( SPECIES_TESHARI = 'icons/inventory/head/mob_vr_teshari.dmi' ) - action_button_name = "Toggle Visor" + actions_types = list(/datum/action/item_action/toggle_visor) /obj/item/clothing/head/pilot_vr/talon/attack_self(mob/user as mob) if(src.icon_state == initial(icon_state)) @@ -77,7 +77,7 @@ sprite_sheets = list( SPECIES_TESHARI = 'icons/inventory/head/mob_vr_teshari.dmi' ) - action_button_name = "Toggle Visor" + actions_types = list(/datum/action/item_action/toggle_visor) /obj/item/clothing/head/pilot_vr/mbill/attack_self(mob/user as mob) if(src.icon_state == initial(icon_state)) @@ -86,4 +86,4 @@ else src.icon_state = initial(icon_state) to_chat(user, "You lower the visor on the pilot helmet.") - update_clothing_icon() //so our mob-overlays update \ No newline at end of file + update_clothing_icon() //so our mob-overlays update diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm index c9e5baaf2c5..4c4781b8a89 100644 --- a/code/modules/clothing/masks/breath.dm +++ b/code/modules/clothing/masks/breath.dm @@ -9,7 +9,7 @@ gas_transfer_coefficient = 0.10 permeability_coefficient = 0.50 var/hanging = 0 - action_button_name = "Adjust Breath Mask" + actions_types = list(/datum/action/item_action/adjust_breath_mask) pickup_sound = 'sound/items/pickup/component.ogg' drop_sound = 'sound/items/drop/component.ogg' diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 90acb425cd9..59541aebc21 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -90,7 +90,7 @@ species_restricted = list(SPECIES_VOX) filtered_gases = list("oxygen", "nitrous_oxide") var/mask_open = FALSE // Controls if the Vox can eat through this mask - action_button_name = "Toggle Feeding Port" + actions_types = list(/datum/action/item_action/toggle_feeding_port) /obj/item/clothing/mask/gas/swat/vox/proc/feeding_port(mob/user) if(user.canmove && !user.stat) diff --git a/code/modules/clothing/masks/hailer.dm b/code/modules/clothing/masks/hailer.dm index 77ef4b83203..b3d265b86cf 100644 --- a/code/modules/clothing/masks/hailer.dm +++ b/code/modules/clothing/masks/hailer.dm @@ -4,7 +4,7 @@ description_info = "This mask has a hailer attached, you can activate it on the button or use the Halt! verb, for switching phrases you can alt+click it or change it using the change phrase verb." icon_state = "halfgas" armor = list(melee = 10, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 55, rad = 0) - action_button_name = "HALT!" + actions_types = list(/datum/action/item_action/halt) body_parts_covered = FACE var/obj/item/hailer/hailer var/cooldown = 0 @@ -53,7 +53,7 @@ phrase = 12 -/obj/item/clothing/mask/gas/sechailer/ui_action_click() +/obj/item/clothing/mask/gas/sechailer/ui_action_click(mob/user, actiontype) halt() /obj/item/clothing/mask/gas/sechailer/AltClick(mob/user) @@ -155,11 +155,11 @@ if(cooldown < world.time - 35) // A cooldown, to stop people being jerks if(!safety) message = "FUCK YOUR CUNT YOU SHIT EATING COCKSUCKER MAN EAT A DONG FUCKING ASS RAMMING SHIT FUCK EAT PENISES IN YOUR FUCK FACE AND SHIT OUT ABORTIONS OF FUCK AND DO SHIT IN YOUR ASS YOU COCK FUCK SHIT MONKEY FUCK ASS WANKER FROM THE DEPTHS OF SHIT." - usr.visible_message("[usr]'s Compli-o-Nator: [span_red("[message]")]") + usr.visible_message(span_infoplain("[usr]'s Compli-o-Nator: " + span_red(span_huge(span_bold("[message]"))))) playsound(src, 'sound/voice/binsult.ogg', 50, 0, 4) //Future sound channel = something like SFX cooldown = world.time return - usr.visible_message("[usr]'s Compli-o-Nator: [span_red("[message]")]") + usr.visible_message(span_infoplain("[usr]'s Compli-o-Nator: " + span_red(span_huge(span_bold("[message]"))))) playsound(src, "sound/voice/complionator/[key].ogg", 50, 0, 4) //future sound channel = something like SFX cooldown = world.time diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index 22b32e40f9f..c821aeeca23 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -320,8 +320,7 @@ w_class = ITEMSIZE_SMALL body_parts_covered = FACE icon_state = "papermask" - action_button_name = "Redraw Design" - action_button_is_hands_free = TRUE + actions_types = list(/datum/action/item_action/hands_free/redraw_design) var/list/papermask_designs = list() /obj/item/clothing/mask/paper/Initialize(mapload) @@ -374,7 +373,7 @@ if(src && choice && !user.incapacitated() && in_range(user,src)) icon_state = options[choice] user.update_inv_wear_mask() - user.update_action_buttons() + user.update_action_buttons_icon() to_chat(user, span_notice("Your paper mask now is now [choice].")) return 1 @@ -384,8 +383,7 @@ w_class = ITEMSIZE_SMALL body_parts_covered = FACE icon_state = "joy" - action_button_name = "Redraw Design" - action_button_is_hands_free = TRUE + actions_types = list(/datum/action/item_action/hands_free/redraw_design) var/static/list/joymask_designs = list() @@ -410,7 +408,7 @@ if(src && choice && !user.incapacitated() && in_range(user,src)) icon_state = options[choice] user.update_inv_wear_mask() - user.update_action_buttons() + user.update_action_buttons_icon() to_chat(user, span_notice("Your [src] now displays a [choice] emotion.")) return 1 diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index dd921661156..9a1c384478e 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -12,7 +12,7 @@ preserve_item = 1 var/magpulse = 0 var/icon_base = "magboots" - action_button_name = "Toggle Magboots" + actions_types = list(/datum/action/item_action/toggle_magboots) var/obj/item/clothing/shoes/shoes = null //Undershoes var/mob/living/carbon/human/wearer = null //For shoe procs step_volume_mod = 1.3 @@ -41,7 +41,7 @@ playsound(src, 'sound/effects/magnetclamp.ogg', 20) to_chat(user, "You enable the mag-pulse traction system.") user.update_inv_shoes() //so our mob-overlays update - user.update_action_buttons() + user.update_action_buttons_icon() /obj/item/clothing/shoes/magboots/mob_can_equip(mob/user, slot, disable_warning = FALSE) var/mob/living/carbon/human/H = user @@ -90,8 +90,7 @@ icon_state = "boots-vox" flags = PHORONGUARD species_restricted = list(SPECIES_VOX) - - action_button_name = "Toggle the magclaws" + actions_types = list(/datum/action/item_action/toggle_magclaws) /obj/item/clothing/shoes/magboots/vox/attack_self(mob/user) if(src.magpulse) @@ -112,7 +111,7 @@ magpulse = 1 canremove = FALSE //kinda hard to take off magclaws when you are gripping them tightly. to_chat(user, "You dig your claws deeply into the flooring, bracing yourself.") - user.update_action_buttons() + user.update_action_buttons_icon() //In case they somehow come off while enabled. /obj/item/clothing/shoes/magboots/vox/dropped(mob/user as mob) @@ -126,4 +125,4 @@ /obj/item/clothing/shoes/magboots/vox/examine(mob/user) . = ..() if(magpulse) - . += "It would be hard to take these off without relaxing your grip first." // Theoretically this message should only be seen by the wearer when the claws are equipped. \ No newline at end of file + . += "It would be hard to take these off without relaxing your grip first." // Theoretically this message should only be seen by the wearer when the claws are equipped. diff --git a/code/modules/clothing/shoes/miscellaneous_vr.dm b/code/modules/clothing/shoes/miscellaneous_vr.dm index 1485517ff92..9d9bd1dcc2d 100644 --- a/code/modules/clothing/shoes/miscellaneous_vr.dm +++ b/code/modules/clothing/shoes/miscellaneous_vr.dm @@ -14,7 +14,7 @@ icon = 'icons/inventory/feet/item_vr.dmi' icon_override = 'icons/inventory/feet/mob_vr.dmi' // resistance_flags = FIRE_PROOF - action_button_name = "Activate Jump Boots" + actions_types = list(/datum/action/item_action/activate_jump_boots) permeability_coefficient = 0.05 var/jumpdistance = 5 //-1 from to see the actual distance, e.g 4 goes over 3 tiles var/jumpspeed = 3 @@ -22,7 +22,7 @@ var/recharging_time = 0 //time until next dash // var/jumping = FALSE //are we mid-jump? We have no throw_at callback, so we have to check user.throwing. -/obj/item/clothing/shoes/bhop/ui_action_click() +/obj/item/clothing/shoes/bhop/ui_action_click(mob/unused_user, actiontype) var/mob/living/user = loc if(!isliving(user)) return diff --git a/code/modules/clothing/spacesuits/breaches.dm b/code/modules/clothing/spacesuits/breaches.dm index 836b297ea43..aa6e0649ea6 100644 --- a/code/modules/clothing/spacesuits/breaches.dm +++ b/code/modules/clothing/spacesuits/breaches.dm @@ -81,7 +81,7 @@ var/global/list/breach_burn_descriptors = list( amount_left = 0 B.update_descriptor() - user.visible_message("[user] patches some of the damage on \the [src].") + user.visible_message(span_infoplain(span_bold("[user]") + " patches some of the damage on \the [src].")) calc_breach_damage() /obj/item/clothing/suit/space/proc/create_breaches(var/damtype, var/amount) @@ -119,9 +119,9 @@ var/global/list/breach_burn_descriptors = list( amount -= needs if(existing.damtype == BRUTE) - T.visible_message("\The [existing.descriptor] on [src] gapes wider!") + T.visible_message(span_warning("\The [existing.descriptor] on [src] gapes wider!")) else if(existing.damtype == BURN) - T.visible_message("\The [existing.descriptor] on [src] widens!") + T.visible_message(span_warning("\The [existing.descriptor] on [src] widens!")) if (amount) //Spawn a new breach. @@ -135,9 +135,9 @@ var/global/list/breach_burn_descriptors = list( B.holder = src if(B.damtype == BRUTE) - T.visible_message("\A [B.descriptor] opens up on [src]!") + T.visible_message(span_warning("\A [B.descriptor] opens up on [src]!")) else if(B.damtype == BURN) - T.visible_message("\A [B.descriptor] marks the surface of [src]!") + T.visible_message(span_warning("\A [B.descriptor] marks the surface of [src]!")) calc_breach_damage() @@ -227,4 +227,4 @@ var/global/list/breach_burn_descriptors = list( . = ..() if(can_breach && breaches?.len) for(var/datum/breach/B in breaches) - . += span_red("It has \a [B.descriptor].") + . += span_red(span_bold("It has \a [B.descriptor].")) diff --git a/code/modules/clothing/spacesuits/rig/modules/combat.dm b/code/modules/clothing/spacesuits/rig/modules/combat.dm index a031ba5e34d..e54980b2131 100644 --- a/code/modules/clothing/spacesuits/rig/modules/combat.dm +++ b/code/modules/clothing/spacesuits/rig/modules/combat.dm @@ -54,7 +54,7 @@ to_chat(user, span_danger("Another grenade of that type will not fit into the module.")) return 0 - to_chat(user, span_blue("You slot \the [input_device] into the suit module.")) + to_chat(user, span_boldnotice("You slot \the [input_device] into the suit module.")) user.drop_from_inventory(input_device) qdel(input_device) accepted_item.charges++ @@ -256,7 +256,7 @@ else var/obj/item/new_weapon = new fabrication_type() new_weapon.forceMove(H) - to_chat(H, span_blue("You quickly fabricate \a [new_weapon].")) + to_chat(H, span_boldnotice("You quickly fabricate \a [new_weapon].")) H.put_in_hands(new_weapon) return 1 diff --git a/code/modules/clothing/spacesuits/rig/modules/computer.dm b/code/modules/clothing/spacesuits/rig/modules/computer.dm index 77639a35f4d..e8e786d0128 100644 --- a/code/modules/clothing/spacesuits/rig/modules/computer.dm +++ b/code/modules/clothing/spacesuits/rig/modules/computer.dm @@ -368,7 +368,7 @@ if(interfaced_with) if(holder && holder.wearer) - to_chat(holder.wearer, "Your power sink retracts as the module deactivates.") + to_chat(holder.wearer, span_warning("Your power sink retracts as the module deactivates.")) drain_complete() interfaced_with = null total_power_drained = 0 @@ -400,7 +400,7 @@ if(target.drain_power(1) <= 0) return 0 - to_chat(H, "You begin draining power from [target]!") + to_chat(H, span_danger("You begin draining power from [target]!")) interfaced_with = target drain_loc = interfaced_with.loc @@ -434,17 +434,17 @@ H.break_cloak() if(!holder.cell) - to_chat(H, "Your power sink flashes an error; there is no cell in your rig.") + to_chat(H, span_danger("Your power sink flashes an error; there is no cell in your rig.")) drain_complete(H) return if(!interfaced_with || !interfaced_with.Adjacent(H) || !(interfaced_with.loc == drain_loc)) - to_chat(H, "Your power sink retracts into its casing.") + to_chat(H, span_warning("Your power sink retracts into its casing.")) drain_complete(H) return if(holder.cell.fully_charged()) - to_chat(H, "Your power sink flashes an amber light; your rig cell is full.") + to_chat(H, span_warning("Your power sink flashes an amber light; your rig cell is full.")) drain_complete(H) return @@ -453,7 +453,7 @@ var/to_drain = min(12.5*holder.cell.maxcharge, ((holder.cell.maxcharge - holder.cell.charge) / CELLRATE)) var/target_drained = interfaced_with.drain_power(0,0,to_drain) if(target_drained <= 0) - to_chat(H, "Your power sink flashes a red light; there is no power left in [interfaced_with].") + to_chat(H, span_danger("Your power sink flashes a red light; there is no power left in [interfaced_with].")) drain_complete(H) return @@ -466,10 +466,10 @@ if(!interfaced_with) if(M) - to_chat(M, span_blue("Total power drained: [round(total_power_drained*CELLRATE)] cell units.")) + to_chat(M, span_notice(span_bold("Total power drained:") + " [round(total_power_drained*CELLRATE)] cell units.")) else if(M) - to_chat(M, span_blue("Total power drained from [interfaced_with]: [round(total_power_drained*CELLRATE)] cell units.")) + to_chat(M, span_notice(span_bold("Total power drained from [interfaced_with]:") + " [round(total_power_drained*CELLRATE)] cell units.")) interfaced_with.drain_power(0,1,0) // Damage the victim. drain_loc = null diff --git a/code/modules/clothing/spacesuits/rig/modules/modules.dm b/code/modules/clothing/spacesuits/rig/modules/modules.dm index 128cc19a545..15a303769db 100644 --- a/code/modules/clothing/spacesuits/rig/modules/modules.dm +++ b/code/modules/clothing/spacesuits/rig/modules/modules.dm @@ -234,28 +234,6 @@ /obj/item/rig_module/proc/accepts_item(var/obj/item/input_device) return 0 -/mob/living/carbon/human/Stat() - . = ..() - - if(. && istype(back,/obj/item/rig)) - var/obj/item/rig/R = back - SetupStat(R) - - else if(. && istype(belt,/obj/item/rig)) - var/obj/item/rig/R = belt - SetupStat(R) - -/mob/proc/SetupStat(var/obj/item/rig/R) - if(R && !R.canremove && R.installed_modules.len && statpanel("Hardsuit Modules")) - var/cell_status = R.cell ? "[R.cell.charge]/[R.cell.maxcharge]" : "ERROR" - stat("Suit charge", cell_status) - for(var/obj/item/rig_module/module in R.installed_modules) - { - for(var/stat_rig_module/SRM in module.stat_modules) - if(SRM.CanUse()) - stat(SRM.module.interface_name,SRM) - } - /stat_rig_module parent_type = /atom/movable var/module_mode = "" @@ -282,6 +260,10 @@ module.holder.selected_module = module if("engage") module.engage() + if("activate") + module.activate() + if("deactivate") + module.deactivate() if("toggle") if(module.active) module.deactivate() diff --git a/code/modules/clothing/spacesuits/rig/modules/ninja.dm b/code/modules/clothing/spacesuits/rig/modules/ninja.dm index 5c88aefc8c7..90a3b06be8b 100644 --- a/code/modules/clothing/spacesuits/rig/modules/ninja.dm +++ b/code/modules/clothing/spacesuits/rig/modules/ninja.dm @@ -37,7 +37,7 @@ var/mob/living/carbon/human/H = holder.wearer - to_chat(H, span_blue("You are now nearly invisible to normal detection.")) + to_chat(H, span_boldnotice("You are now nearly invisible to normal detection.")) H.alpha = 5 anim(get_turf(H), H, 'icons/effects/effects.dmi', "electricity",null,20,null) diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/ai_container.dm b/code/modules/clothing/spacesuits/rig/modules/specific/ai_container.dm index e8fb6002380..b65417f3ec1 100644 --- a/code/modules/clothing/spacesuits/rig/modules/specific/ai_container.dm +++ b/code/modules/clothing/spacesuits/rig/modules/specific/ai_container.dm @@ -46,13 +46,6 @@ else integrated_ai.get_rig_stats = 0 -/mob/living/Stat() - . = ..() - if(. && get_rig_stats) - var/obj/item/rig/rig = get_rig() - if(rig) - SetupStat(rig) - /obj/item/rig_module/ai_container/proc/update_verb_holder() if(!verb_holder) verb_holder = new(src) diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/cleaner_launcher.dm b/code/modules/clothing/spacesuits/rig/modules/specific/cleaner_launcher.dm index 33e119ccaf8..39f9d02c62f 100644 --- a/code/modules/clothing/spacesuits/rig/modules/specific/cleaner_launcher.dm +++ b/code/modules/clothing/spacesuits/rig/modules/specific/cleaner_launcher.dm @@ -34,7 +34,7 @@ to_chat(user, span_danger("Another grenade of that type will not fit into the module.")) return 0 - to_chat(user, span_blue("You slot \the [input_device] into the suit module.")) + to_chat(user, span_boldnotice("You slot \the [input_device] into the suit module.")) user.drop_from_inventory(input_device) qdel(input_device) accepted_item.charges++ diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/cloak.dm b/code/modules/clothing/spacesuits/rig/modules/specific/cloak.dm index 8e10a86d817..9e51ef9832d 100644 --- a/code/modules/clothing/spacesuits/rig/modules/specific/cloak.dm +++ b/code/modules/clothing/spacesuits/rig/modules/specific/cloak.dm @@ -29,7 +29,7 @@ var/mob/living/carbon/human/H = holder.wearer - to_chat(H, span_blue("You are now nearly invisible to normal detection.")) + to_chat(H, span_boldnotice("You are now nearly invisible to normal detection.")) H.alpha = 5 anim(get_turf(H), H, 'icons/effects/effects.dmi', "electricity",null,20,null) diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/grenade_launcher.dm b/code/modules/clothing/spacesuits/rig/modules/specific/grenade_launcher.dm index 1f0916487f4..d7ae54ce073 100644 --- a/code/modules/clothing/spacesuits/rig/modules/specific/grenade_launcher.dm +++ b/code/modules/clothing/spacesuits/rig/modules/specific/grenade_launcher.dm @@ -36,7 +36,7 @@ to_chat(user, span_danger("Another grenade of that type will not fit into the module.")) return 0 - to_chat(user, span_blue("You slot \the [input_device] into the suit module.")) + to_chat(user, span_boldnotice("You slot \the [input_device] into the suit module.")) user.drop_from_inventory(input_device) qdel(input_device) accepted_item.charges++ diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/inhand_fabricator.dm b/code/modules/clothing/spacesuits/rig/modules/specific/inhand_fabricator.dm index 90b96a1283a..f993d81a2b5 100644 --- a/code/modules/clothing/spacesuits/rig/modules/specific/inhand_fabricator.dm +++ b/code/modules/clothing/spacesuits/rig/modules/specific/inhand_fabricator.dm @@ -34,7 +34,7 @@ else var/obj/item/new_weapon = new fabrication_type() new_weapon.forceMove(H) - to_chat(H, span_blue("You quickly fabricate \a [new_weapon].")) + to_chat(H, span_boldnotice("You quickly fabricate \a [new_weapon].")) H.put_in_hands(new_weapon) return 1 diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/passive_protection.dm b/code/modules/clothing/spacesuits/rig/modules/specific/passive_protection.dm index 87c3de0576f..ddb72b5ad2a 100644 --- a/code/modules/clothing/spacesuits/rig/modules/specific/passive_protection.dm +++ b/code/modules/clothing/spacesuits/rig/modules/specific/passive_protection.dm @@ -34,7 +34,7 @@ var/obj/item/clothing/head/helmet/space/rig/helmet = holder.helmet var/obj/item/clothing/gloves/gauntlets/rig/gloves = holder.gloves - to_chat(H, span_blue("You activate your suit's powered radiation shielding.")) + to_chat(H, span_boldnotice("You activate your suit's powered radiation shielding.")) stored_rad_armor = holder.armor["rad"] if(boots) boots.armor["rad"] = 100 @@ -117,7 +117,7 @@ stored_max_pressure = holder.max_pressure_protection stored_max_temp = holder.max_heat_protection_temperature - to_chat(H, span_blue("You activate your suit's powered atmospheric shielding.")) + to_chat(H, span_boldnotice("You activate your suit's powered atmospheric shielding.")) if(boots) boots.max_pressure_protection = INFINITY @@ -145,7 +145,7 @@ var/obj/item/clothing/head/helmet/space/rig/helmet = holder.helmet var/obj/item/clothing/gloves/gauntlets/rig/gloves = holder.gloves - to_chat(H, span_danger("You deactivate your suit's powered atmospheric shielding.")) + to_chat(H, span_boldnotice("You deactivate your suit's powered atmospheric shielding.")) if(boots) boots.max_pressure_protection = stored_max_pressure diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/powersink.dm b/code/modules/clothing/spacesuits/rig/modules/specific/powersink.dm index 562f874af12..3b166f5915f 100644 --- a/code/modules/clothing/spacesuits/rig/modules/specific/powersink.dm +++ b/code/modules/clothing/spacesuits/rig/modules/specific/powersink.dm @@ -20,7 +20,7 @@ if(interfaced_with) if(holder && holder.wearer) - to_chat(holder.wearer, "Your power sink retracts as the module deactivates.") + to_chat(holder.wearer, span_warning("Your power sink retracts as the module deactivates.")) drain_complete() interfaced_with = null total_power_drained = 0 @@ -52,7 +52,7 @@ if(target.drain_power(1) <= 0) return 0 - to_chat(H, "You begin draining power from [target]!") + to_chat(H, span_danger("You begin draining power from [target]!")) interfaced_with = target drain_loc = interfaced_with.loc @@ -86,17 +86,17 @@ H.break_cloak() if(!holder.cell) - to_chat(H, "Your power sink flashes an error; there is no cell in your rig.") + to_chat(H, span_danger("Your power sink flashes an error; there is no cell in your rig.")) drain_complete(H) return if(!interfaced_with || !interfaced_with.Adjacent(H) || !(interfaced_with.loc == drain_loc)) - to_chat(H, "Your power sink retracts into its casing.") + to_chat(H, span_warning("Your power sink retracts into its casing.")) drain_complete(H) return if(holder.cell.fully_charged()) - to_chat(H, "Your power sink flashes an amber light; your rig cell is full.") + to_chat(H, span_warning("Your power sink flashes an amber light; your rig cell is full.")) drain_complete(H) return @@ -105,7 +105,7 @@ var/to_drain = min(12.5*holder.cell.maxcharge, ((holder.cell.maxcharge - holder.cell.charge) / CELLRATE)) var/target_drained = interfaced_with.drain_power(0,0,to_drain) if(target_drained <= 0) - to_chat(H, "Your power sink flashes a red light; there is no power left in [interfaced_with].") + to_chat(H, span_danger("Your power sink flashes a red light; there is no power left in [interfaced_with].")) drain_complete(H) return @@ -118,10 +118,10 @@ if(!interfaced_with) if(M) - to_chat(M, span_blue("Total power drained: [round(total_power_drained*CELLRATE)] cell units.")) + to_chat(M, span_notice(span_bold("Total power drained:") + " [round(total_power_drained*CELLRATE)] cell units.")) else if(M) - to_chat(M, span_blue("Total power drained from [interfaced_with]: [round(total_power_drained*CELLRATE)] cell units.")) + to_chat(M, span_notice(span_bold("Total power drained from [interfaced_with]:") + " [round(total_power_drained*CELLRATE)] cell units.")) interfaced_with.drain_power(0,1,0) // Damage the victim. drain_loc = null diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/sprinter.dm b/code/modules/clothing/spacesuits/rig/modules/specific/sprinter.dm index 6fb036e1867..f18d67d8e38 100644 --- a/code/modules/clothing/spacesuits/rig/modules/specific/sprinter.dm +++ b/code/modules/clothing/spacesuits/rig/modules/specific/sprinter.dm @@ -27,7 +27,7 @@ var/mob/living/carbon/human/H = holder.wearer - to_chat(H, span_blue("You activate the suit's sprint mode.")) + to_chat(H, span_boldnotice("You activate the suit's sprint mode.")) holder.slowdown = initial(holder.slowdown) - sprint_speed diff --git a/code/modules/clothing/spacesuits/rig/modules/utility.dm b/code/modules/clothing/spacesuits/rig/modules/utility.dm index 4ea1c598f74..6e66d2504fd 100644 --- a/code/modules/clothing/spacesuits/rig/modules/utility.dm +++ b/code/modules/clothing/spacesuits/rig/modules/utility.dm @@ -508,7 +508,7 @@ to_chat(user, span_danger("Another grenade of that type will not fit into the module.")) return 0 - to_chat(user, span_blue("You slot \the [input_device] into the suit module.")) + to_chat(user, span_boldnotice("You slot \the [input_device] into the suit module.")) user.drop_from_inventory(input_device) qdel(input_device) accepted_item.charges++ @@ -632,7 +632,7 @@ var/mob/living/carbon/human/H = holder.wearer - to_chat(H, span_blue("You activate the suit's sprint mode.")) + to_chat(H, span_boldnotice("You activate the suit's sprint mode.")) holder.slowdown = initial(holder.slowdown) - sprint_speed diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index b3c441921e9..653ea9a58a1 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -15,7 +15,7 @@ req_one_access = list() req_access = list() w_class = ITEMSIZE_HUGE - action_button_name = "Toggle Heatsink" + actions_types = list(/datum/action/item_action/toggle_heatsink) // These values are passed on to all component pieces. armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20) @@ -98,7 +98,7 @@ var/datum/mini_hud/rig/minihud // Action button - action_button_name = "Hardsuit Interface" + actions_types = list(/datum/action/item_action/hardsuit_interface) /obj/item/rig/New() ..() @@ -384,7 +384,7 @@ QDEL_NULL(minihud) else minihud = new (M.hud_used, src) - to_chat(M, span_notice("Your entire suit [canremove ? "loosens as the components relax" : "tightens around you as the components lock into place"].")) + to_chat(M, span_boldnotice("Your entire suit [canremove ? "loosens as the components relax" : "tightens around you as the components lock into place"].")) playsound(src, 'sound/machines/rig/rigstarted.ogg', 10, FALSE) M.client?.screen -= booting_L qdel(booting_L) @@ -407,9 +407,6 @@ else update_airtight(piece, 1) // Seal -/obj/item/rig/ui_action_click() - toggle_cooling(usr) - /obj/item/rig/proc/toggle_cooling(var/mob/user) if(cooling_on) turn_cooling_off(user) @@ -675,7 +672,7 @@ return if(istype(M) && (M.back == src || M.belt == src)) - M.visible_message(span_notice("[M] struggles into \the [src]."), span_notice("You struggle into \the [src].")) + M.visible_message(span_boldnotice("[M] struggles into \the [src]."), span_boldnotice("You struggle into \the [src].")) wearer = M wearer.wearing_rig = src update_icon() @@ -725,7 +722,7 @@ holder = use_obj.loc if(istype(holder)) if(use_obj && check_slot == use_obj) - to_chat(H, span_notice("Your [use_obj.name] [use_obj.gender == PLURAL ? "retract" : "retracts"] swiftly.")) + to_chat(H, span_boldnotice("Your [use_obj.name] [use_obj.gender == PLURAL ? "retract" : "retracts"] swiftly.")) playsound(src, 'sound/machines/rig/rigservo.ogg', 10, FALSE) use_obj.canremove = TRUE holder.drop_from_inventory(use_obj) @@ -788,7 +785,7 @@ toggle_piece(piece, H, ONLY_DEPLOY) /obj/item/rig/dropped(var/mob/user) - ..() + . = ..(user) for(var/piece in list("helmet","gauntlets","chest","boots")) toggle_piece(piece, user, ONLY_RETRACT) if(wearer && wearer.wearing_rig == src) @@ -953,7 +950,7 @@ M.stop_pulling() if(wearer.pinned.len) - to_chat(src, "Your host is pinned to a wall by [wearer.pinned[1]]!") + to_chat(src, span_notice("Your host is pinned to a wall by [wearer.pinned[1]]!")) return 0 // AIs are a bit slower than regular and ignore move intent. diff --git a/code/modules/clothing/spacesuits/rig/rig_verbs.dm b/code/modules/clothing/spacesuits/rig/rig_verbs.dm index bbedbf082ad..9eb0724b0ef 100644 --- a/code/modules/clothing/spacesuits/rig/rig_verbs.dm +++ b/code/modules/clothing/spacesuits/rig/rig_verbs.dm @@ -10,9 +10,9 @@ tgui_interact(usr) // So the UI button clicks come here -/obj/item/rig/ui_action_click() - if(usr == wearer && (wearer.back == src || wearer.belt == src)) - tgui_interact(usr) +/obj/item/rig/ui_action_click(mob/user, actiontype) + if(user == wearer && (wearer.back == src || wearer.belt == src)) + tgui_interact(user) /obj/item/rig/verb/toggle_vision() @@ -223,11 +223,11 @@ if(!istype(module)) selected_module = null - to_chat(usr, span_blue("Primary system is now: deselected.")) + to_chat(usr, span_boldnotice("Primary system is now: deselected.")) return selected_module = module - to_chat(usr, span_blue("Primary system is now: [selected_module.interface_name].")) + to_chat(usr, span_boldnotice("Primary system is now: [selected_module.interface_name].")) /obj/item/rig/verb/toggle_module() @@ -261,10 +261,10 @@ return if(module.active) - to_chat(usr, span_blue("You attempt to deactivate \the [module.interface_name].")) + to_chat(usr, span_boldnotice("You attempt to deactivate \the [module.interface_name].")) module.deactivate() else - to_chat(usr, span_blue("You attempt to activate \the [module.interface_name].")) + to_chat(usr, span_boldnotice("You attempt to activate \the [module.interface_name].")) module.activate() /obj/item/rig/verb/engage_module() @@ -298,5 +298,5 @@ if(!istype(module)) return - to_chat(usr, span_blue("You attempt to engage the [module.interface_name].")) + to_chat(usr, span_boldnotice("You attempt to engage the [module.interface_name].")) module.engage() diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index e435f24f404..b70ddc6a571 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -27,7 +27,7 @@ var/obj/machinery/camera/camera var/list/camera_networks - action_button_name = "Toggle Helmet Light" + actions_types = list(/datum/action/item_action/toggle_helmet_light) light_overlay = "helmet_light" light_range = 4 diff --git a/code/modules/clothing/spacesuits/void/military_vr.dm b/code/modules/clothing/spacesuits/void/military_vr.dm index 88701c2da74..e4b40097e4f 100644 --- a/code/modules/clothing/spacesuits/void/military_vr.dm +++ b/code/modules/clothing/spacesuits/void/military_vr.dm @@ -27,7 +27,7 @@ /obj/item/clothing/head/helmet/space/void/merc/odst name = "\improper ODST Helmet" - desc = "\"... we are glad to plunge feet first into hell in the knowledge that we will rise.\"" + desc = span_italics("\"... we are glad to plunge feet first into hell in the knowledge that we will rise.\"") icon_state = "rig0-odst" item_state = "rig0-odst" item_state_slots = null @@ -46,7 +46,7 @@ /obj/item/clothing/suit/space/void/merc/odst name = "ODST Armor" - desc = "\"... we are glad to plunge feet first into hell in the knowledge that we will rise.\"" + desc = span_italics("\"... we are glad to plunge feet first into hell in the knowledge that we will rise.\"") icon_state = "odst" item_state = "odst" item_state_slots = null diff --git a/code/modules/clothing/spacesuits/void/void.dm b/code/modules/clothing/spacesuits/void/void.dm index 763ee110aa0..a8c4c0f53d7 100644 --- a/code/modules/clothing/spacesuits/void/void.dm +++ b/code/modules/clothing/spacesuits/void/void.dm @@ -32,7 +32,7 @@ max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE min_pressure_protection = 0 * ONE_ATMOSPHERE max_pressure_protection = 10 * ONE_ATMOSPHERE - action_button_name = "Toggle Helmet" + actions_types = list(/datum/action/item_action/toggle_helmet) species_restricted = list("Human", SPECIES_SKRELL, "Promethean") sprite_sheets = VR_SPECIES_SPRITE_SHEETS_SUIT_MOB sprite_sheets_obj = VR_SPECIES_SPRITE_SHEETS_SUIT_ITEM diff --git a/code/modules/clothing/suits/aliens/teshari.dm b/code/modules/clothing/suits/aliens/teshari.dm index fe0e29ffc0a..89975b9f160 100644 --- a/code/modules/clothing/suits/aliens/teshari.dm +++ b/code/modules/clothing/suits/aliens/teshari.dm @@ -256,7 +256,7 @@ item_state_slots = list(slot_r_hand_str = "tesh_hcloak_bo", slot_l_hand_str = "tesh_hcloak_bo") body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS flags_inv = HIDEHOLSTER|HIDETIE - action_button_name = "Toggle Cloak Hood" + actions_types = list(/datum/action/item_action/toggle_hood) hoodtype = /obj/item/clothing/head/tesh_hood allowed = list (/obj/item/pen, /obj/item/paper, /obj/item/flashlight,/obj/item/tank/emergency/oxygen, /obj/item/storage/fancy/cigarettes, /obj/item/storage/box/matches, /obj/item/reagent_containers/food/drinks/flask) diff --git a/code/modules/clothing/suits/hooded.dm b/code/modules/clothing/suits/hooded.dm index 984629cee42..aa7d1bf8fb4 100644 --- a/code/modules/clothing/suits/hooded.dm +++ b/code/modules/clothing/suits/hooded.dm @@ -7,7 +7,7 @@ var/hoodtype = null //so the chaplain hoodie or other hoodies can override this var/hood_up = FALSE var/toggleicon - action_button_name = "Toggle Hood" + actions_types = list(/datum/action/item_action/toggle_hood) /obj/item/clothing/suit/storage/hooded/New() toggleicon = "[initial(icon_state)]" @@ -23,7 +23,7 @@ var/obj/item/clothing/head/hood/H = new hoodtype(src) hood = H -/obj/item/clothing/suit/storage/hooded/ui_action_click() +/obj/item/clothing/suit/storage/hooded/ui_action_click(mob/user, actiontype) ToggleHood() /obj/item/clothing/suit/storage/hooded/equipped(mob/user, slot) @@ -74,7 +74,7 @@ body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS flags_inv = HIDEJUMPSUIT|HIDETIE|HIDEHOLSTER cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS - action_button_name = "Toggle Hood" + actions_types = list(/datum/action/item_action/toggle_hood) /obj/item/clothing/suit/storage/hooded/costume/siffet name = "siffet costume" diff --git a/code/modules/clothing/suits/hooded_vr.dm b/code/modules/clothing/suits/hooded_vr.dm index aaf729045ae..57cc6314048 100644 --- a/code/modules/clothing/suits/hooded_vr.dm +++ b/code/modules/clothing/suits/hooded_vr.dm @@ -22,7 +22,7 @@ hoodtype = /obj/item/clothing/head/hood/galahad armor = list(melee = 80, bullet = 50, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0) siemens_coefficient = 2 - action_button_name = "Toggle Knight Headgear" + actions_types = list(/datum/action/item_action/toggle_knight_headgear) /obj/item/clothing/suit/storage/hooded/knight/galahad name = "crusader's armor" @@ -53,7 +53,7 @@ icon = 'icons/obj/clothing/knights_vr.dmi' icon_override = 'icons/obj/clothing/knights_vr.dmi' hoodtype = /obj/item/clothing/head/hood/galahad_costume - action_button_name = "Toggle Knight Headgear" + actions_types = list(/datum/action/item_action/toggle_knight_headgear) /obj/item/clothing/suit/storage/hooded/knight_costume/galahad icon_state = "galahad" @@ -84,7 +84,7 @@ body_parts_covered = UPPER_TORSO|LOWER_TORSO flags_inv = HIDETIE|HIDEHOLSTER cold_protection = UPPER_TORSO|LOWER_TORSO - action_button_name = "Toggle Hood" + actions_types = list(/datum/action/item_action/toggle_hood) /obj/item/clothing/suit/storage/hooded/foodcostume/hotdog //Belly filler uniform :^). name = "hotdog costume" diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index 9039018a805..7c4b968b093 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -557,7 +557,7 @@ item_flags = FLEXIBLEMATERIAL var/breath_masked = FALSE var/obj/item/clothing/mask/breath/breathmask - action_button_name = "Pull On Gaiter" + actions_types = list(/datum/action/item_action/pull_on_gaiter) /obj/item/clothing/accessory/gaiter/update_clothing_icon() . = ..() diff --git a/code/modules/clothing/under/accessories/accessory_vr.dm b/code/modules/clothing/under/accessories/accessory_vr.dm index 7043d09d893..7b68ced88a5 100644 --- a/code/modules/clothing/under/accessories/accessory_vr.dm +++ b/code/modules/clothing/under/accessories/accessory_vr.dm @@ -400,7 +400,7 @@ return if(H.size_multiplier != target_size) if(!(world.time - last_activated > 10 SECONDS)) - to_chat(M, "\The [src] flickers. It seems to be recharging.") + to_chat(M, span_warning("\The [src] flickers. It seems to be recharging.")) return last_activated = world.time original_size = H.size_multiplier @@ -418,7 +418,7 @@ original_size = null H.visible_message(span_warning("The space around [H] distorts as they return to their original size!"),span_notice("The space around you distorts as you return to your original size!")) log_admin("Admin [key_name(M)]'s size was altered by a bluespace collar.") - to_chat(M, "\The [src] flickers. It is now recharging and will be ready again in ten seconds.") + to_chat(M, span_warning("\The [src] flickers. It is now recharging and will be ready again in ten seconds.")) s.set_up(3, 1, M) s.start() return @@ -501,7 +501,7 @@ return if(H.size_multiplier != target_size) if(!(world.time - last_activated > 10 SECONDS)) - to_chat(M, "\The [src] flickers. It seems to be recharging.") + to_chat(M, span_warning("\The [src] flickers. It seems to be recharging.")) return last_activated = world.time original_size = H.size_multiplier @@ -519,7 +519,7 @@ original_size = null H.visible_message(span_warning("The space around [H] distorts as they return to their original size!"),span_notice("The space around you distorts as you return to your original size!")) log_admin("Admin [key_name(M)]'s size was altered by a bluespace collar.") - to_chat(M, "\The [src] flickers. It is now recharging and will be ready again in ten seconds.") + to_chat(M, span_warning("\The [src] flickers. It is now recharging and will be ready again in ten seconds.")) s.set_up(3, 1, M) s.start() return @@ -573,7 +573,7 @@ return if(currently_shrinking == 0) if(!(world.time - last_activated > 10 SECONDS)) - to_chat(M, "\The [src] flickers. It seems to be recharging.") + to_chat(M, span_warning("\The [src] flickers. It seems to be recharging.")) return last_activated = world.time original_size = H.size_multiplier @@ -593,7 +593,7 @@ currently_shrinking = 0 H.visible_message(span_warning("The space around [H] distorts as they return to their original size!"),span_notice("The space around you distorts as you return to your original size!")) log_admin("Admin [key_name(M)]'s size was altered by a bluespace collar.") - to_chat(M, "\The [src] flickers. It is now recharging and will be ready again in ten seconds.") + to_chat(M, span_warning("\The [src] flickers. It is now recharging and will be ready again in ten seconds.")) s.set_up(3, 1, M) s.start() return @@ -714,7 +714,7 @@ desc = "The latest fashion innovations by the Nanotrasen Uniform & Fashion Department have provided the brilliant invention of slicing a regular cloak in half! All the ponce, half the cost!" icon_state = "roughcloak" item_state = "roughcloak" - action_button_name = "Adjust Cloak" + actions_types = list(/datum/action/item_action/adjust_cloak) /obj/item/clothing/accessory/poncho/roles/cloak/half/update_clothing_icon() . = ..() @@ -985,7 +985,7 @@ desc = "Aim for the Heart, Ramon." icon_state = "neo_ranger" item_state = "neo_ranger" - action_button_name = "Adjust Poncho" + actions_types = list(/datum/action/item_action/adjust_poncho) /obj/item/clothing/accessory/poncho/roles/neo_ranger/update_clothing_icon() . = ..() diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm index b64261ef07d..676c5440818 100644 --- a/code/modules/clothing/under/accessories/holster.dm +++ b/code/modules/clothing/under/accessories/holster.dm @@ -151,7 +151,7 @@ /obj/item/clothing/accessory/holster/hip name = "hip holster" - desc = "No one dared to ask his business, no one dared to make a slip. The stranger there among them had a big iron on his hip." + desc = span_italics("No one dared to ask his business, no one dared to make a slip. The stranger there among them had a big iron on his hip.") icon_state = "holster_hip" concealed_holster = 0 diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index c00de40e7fd..152b107ecfb 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -54,7 +54,7 @@ /obj/item/clothing/under/rank/mailman name = "mailman's jumpsuit" - desc = "'Special delivery!'" + desc = span_italics("'Special delivery!'") icon_state = "mailman" item_state_slots = list(slot_r_hand_str = "blue", slot_l_hand_str = "blue") rolled_sleeves = 0 diff --git a/code/modules/clothing/under/miscellaneous_vr.dm b/code/modules/clothing/under/miscellaneous_vr.dm index 312c186f73e..c216ca4579e 100644 --- a/code/modules/clothing/under/miscellaneous_vr.dm +++ b/code/modules/clothing/under/miscellaneous_vr.dm @@ -138,7 +138,7 @@ return if(H.size_multiplier != target_size) if(!(world.time - last_activated > 10 SECONDS)) - to_chat(M, "\The [src] flickers. It seems to be recharging.") + to_chat(M, span_warning("\The [src] flickers. It seems to be recharging.")) return last_activated = world.time original_size = H.size_multiplier @@ -157,7 +157,7 @@ original_size = null H.visible_message(span_warning("The space around [H] distorts as they return to their original size!"),span_notice("The space around you distorts as you return to your original size!")) log_admin("Admin [key_name(M)]'s size was altered by a bluespace bracelet.") - to_chat(M, "\The [src] flickers. It is now recharging and will be ready again in thirty seconds.") + to_chat(M, span_warning("\The [src] flickers. It is now recharging and will be ready again in thirty seconds.")) /obj/item/clothing/gloves/bluespace/examine(var/mob/user) . = ..() diff --git a/code/modules/detectivework/microscope/dnascanner.dm b/code/modules/detectivework/microscope/dnascanner.dm index 5f6c252dfb8..3539153b7bb 100644 --- a/code/modules/detectivework/microscope/dnascanner.dm +++ b/code/modules/detectivework/microscope/dnascanner.dm @@ -121,8 +121,8 @@ data += "Blood type: [bloodsamp.dna[blood]] \nDNA: [blood] " else data += "No DNA found. " - P.info = "[src] analysis report #[report_num] " - P.info += "Scanned item: [bloodsamp.name] [bloodsamp.desc] " + data + P.info = span_bold("[src] analysis report #[report_num]") + " " + P.info += span_bold("Scanned item:") + " [bloodsamp.name] [bloodsamp.desc] " + data P.forceMove(loc) P.update_icon() scanning = FALSE diff --git a/code/modules/detectivework/microscope/microscope.dm b/code/modules/detectivework/microscope/microscope.dm index f5ba97ca0e5..62185b7538e 100644 --- a/code/modules/detectivework/microscope/microscope.dm +++ b/code/modules/detectivework/microscope/microscope.dm @@ -46,7 +46,7 @@ var/obj/item/forensics/swab/swab = sample report.name = "GSR report #[++report_num]: [swab.name]" - report.info = "Scanned item: [swab.name] " + report.info = span_bold("Scanned item:") + " [swab.name] " if(swab.gsr) report.info += "Residue from a [swab.gsr] bullet detected." @@ -56,16 +56,16 @@ else if(istype(sample, /obj/item/sample/fibers)) var/obj/item/sample/fibers/fibers = sample report.name = "Fiber report #[++report_num]: [fibers.name]" - report.info = "Scanned item: [fibers.name] " + report.info = span_bold("Scanned item:") + " [fibers.name] " if(fibers.evidence) report.info = "Molecular analysis on provided sample has determined the presence of unique fiber strings. " for(var/fiber in fibers.evidence) - report.info += "Most likely match for fibers: [fiber] " + report.info += span_notice("Most likely match for fibers: [fiber]") + " " else report.info += "No fibers found." else if(istype(sample, /obj/item/sample/print)) report.name = "Fingerprint report #[report_num]: [sample.name]" - report.info = "Fingerprint analysis report #[report_num]: [sample.name] " + report.info = span_bold("Fingerprint analysis report #[report_num]") + ": [sample.name] " var/obj/item/sample/print/card = sample if(card.evidence && card.evidence.len) report.info += "Surface analysis has determined unique fingerprint strings: " diff --git a/code/modules/detectivework/tools/rag.dm b/code/modules/detectivework/tools/rag.dm index 1522f4f5e87..52ccc6558c3 100644 --- a/code/modules/detectivework/tools/rag.dm +++ b/code/modules/detectivework/tools/rag.dm @@ -147,7 +147,7 @@ return if(A.reagents && A.reagents.trans_to_obj(src, reagents.maximum_volume)) - user.visible_message("\The [user] soaks [src] using [A].", span_notice("You soak [src] using [A].")) + user.visible_message(span_infoplain(span_bold("\The [user]") + " soaks [src] using [A]."), span_notice("You soak [src] using [A].")) update_name() return diff --git a/code/modules/detectivework/tools/scanner.dm b/code/modules/detectivework/tools/scanner.dm index cfb9b83812d..b00ab89f39d 100644 --- a/code/modules/detectivework/tools/scanner.dm +++ b/code/modules/detectivework/tools/scanner.dm @@ -112,7 +112,7 @@ if(reveal_fibers && do_after(user, 5 SECONDS)) to_chat(user, span_notice("Apparel samples scanned:")) for(var/sample in A.suit_fibers) - to_chat(user, " - [sample]") + to_chat(user, " - " + span_notice("[sample]")) //Blood if (A.blood_DNA && A.blood_DNA.len) @@ -120,7 +120,7 @@ if(reveal_blood && do_after(user, 5 SECONDS)) flick("[icon_state]1",src) for(var/blood in A.blood_DNA) - to_chat(user, "Blood type: [A.blood_DNA[blood]] DNA: [blood]") + to_chat(user, "Blood type: " + span_warning("[A.blood_DNA[blood]]") + " DNA: " + span_warning("[blood]")) user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\ span_notice("You finish scanning \the [A]."),\ @@ -165,7 +165,7 @@ var/print = fprints[i] if(stringpercent(print) <= FINGERPRINT_COMPLETE) complete_prints += print - to_chat(user, " - [print]") + to_chat(user, " - " + span_notice("[print]")) else incomplete_prints += print @@ -174,19 +174,19 @@ if(reveal_incompletes) for(var/print in incomplete_prints) - to_chat(user, " - [print]") + to_chat(user, " - " + span_notice("[print]")) if(fibers && fibers.len) to_chat(user, span_notice("[fibers.len] samples of material were present.")) if(reveal_fibers) for(var/sample in fibers) - to_chat(user, " - [sample]") + to_chat(user, " - " + span_notice("[sample]")) if(bloods && bloods.len) to_chat(user, span_notice("[bloods.len] samples of blood were present.")) if(reveal_blood) for(var/bloodsample in bloods) - to_chat(user, " - [bloodsample] Type: [bloods[bloodsample]]") + to_chat(user, " - " + span_warning("[bloodsample]") + " Type: [bloods[bloodsample]]") /obj/item/detective_scanner/verb/wipe() set name = "Wipe Forensic Data" diff --git a/code/modules/detectivework/tools/uvlight.dm b/code/modules/detectivework/tools/uvlight.dm index 6e487d6d963..28afb25655a 100644 --- a/code/modules/detectivework/tools/uvlight.dm +++ b/code/modules/detectivework/tools/uvlight.dm @@ -5,7 +5,7 @@ slot_flags = SLOT_BELT w_class = ITEMSIZE_SMALL item_state = "electronic" - action_button_name = "Toggle UV light" + actions_types = list(/datum/action/item_action/toggle_uv_light) matter = list(MAT_STEEL = 150) origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1) diff --git a/code/modules/economy/ATM.dm b/code/modules/economy/ATM.dm index 704700139fd..652b23757a2 100644 --- a/code/modules/economy/ATM.dm +++ b/code/modules/economy/ATM.dm @@ -85,7 +85,7 @@ log transactions if(istype(I, /obj/item/card)) if(emagged > 0) //prevent inserting id into an emagged ATM - to_chat(user, span_red("[icon2html(src, user.client)] CARD READER ERROR. This system has been compromised!")) + to_chat(user, span_boldwarning("[icon2html(src, user.client)] CARD READER ERROR. This system has been compromised!")) return else if(istype(I,/obj/item/card/emag)) I.resolve_attackby(src, user) @@ -190,7 +190,7 @@ log transactions release_held_id(usr) else if(emagged > 0) - to_chat(usr, span_red("[icon2html(src, usr.client)] The ATM card reader rejected your ID because this machine has been sabotaged!")) + to_chat(usr, span_boldwarning("[icon2html(src, usr.client)] The ATM card reader rejected your ID because this machine has been sabotaged!")) else var/obj/item/I = usr.get_active_hand() if(istype(I, /obj/item/card/id)) @@ -211,12 +211,12 @@ log transactions var/obj/item/paper/R = new(loc) R.name = "Account balance: [authenticated_account.owner_name]" - R.info = "NT Automated Teller Account Statement " - R.info += "Account holder: [authenticated_account.owner_name] " - R.info += "Account number: [authenticated_account.account_number] " - R.info += "Balance: $[authenticated_account.money] " - R.info += "Date and time: [stationtime2text()], [current_date_string] " - R.info += "Service terminal ID: [machine_id] " + R.info = span_bold("NT Automated Teller Account Statement") + " " + R.info += span_italics("Account holder:") + " [authenticated_account.owner_name] " + R.info += span_italics("Account number:") + " [authenticated_account.account_number] " + R.info += span_italics("Balance:") + " $[authenticated_account.money] " + R.info += span_italics("Date and time:") + " [stationtime2text()], [current_date_string] " + R.info += span_italics("Service terminal ID:") + " [machine_id] " //stamp the paper var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') @@ -225,7 +225,7 @@ log transactions R.stamped = new R.stamped += /obj/item/stamp R.add_overlay(stampoverlay) - R.stamps += " This paper has been stamped by the Automatic Teller Machine." + R.stamps += " " + span_italics("This paper has been stamped by the Automatic Teller Machine.") if(prob(50)) playsound(src, 'sound/items/polaroid1.ogg', 50, 1) @@ -240,19 +240,19 @@ log transactions var/obj/item/paper/R = new(loc) R.name = "Transaction logs: [authenticated_account.owner_name]" - R.info = "Transaction logs " - R.info += "Account holder: [authenticated_account.owner_name] " - R.info += "Account number: [authenticated_account.account_number] " - R.info += "Date and time: [stationtime2text()], [current_date_string] " - R.info += "Service terminal ID: [machine_id] " + R.info = span_bold("Transaction logs") + " " + R.info += span_italics("Account holder:") + " [authenticated_account.owner_name] " + R.info += span_italics("Account number:") + " [authenticated_account.account_number] " + R.info += span_italics("Date and time:") + " [stationtime2text()], [current_date_string] " + R.info += span_italics("Service terminal ID:") + " [machine_id] " R.info += "
|