diff --git a/citadel.dme b/citadel.dme
index 852b2c90aaf..ca1f2f1cb5b 100644
--- a/citadel.dme
+++ b/citadel.dme
@@ -85,6 +85,7 @@
#include "code\__DEFINES\spans.dm"
#include "code\__DEFINES\spells.dm"
#include "code\__DEFINES\stat_tracking.dm"
+#include "code\__DEFINES\statpanel.dm"
#include "code\__DEFINES\status_effects.dm"
#include "code\__DEFINES\storage.dm"
#include "code\__DEFINES\strack_trace.dm"
@@ -295,6 +296,7 @@
#include "code\__HELPERS\unsorted.dm"
#include "code\__HELPERS\varset_callback.dm"
#include "code\__HELPERS\vector.dm"
+#include "code\__HELPERS\verbs.dm"
#include "code\__HELPERS\view.dm"
#include "code\__HELPERS\datastructs\armor.dm"
#include "code\__HELPERS\datastructs\bodytypes.dm"
@@ -304,7 +306,6 @@
#include "code\__HELPERS\files\walk.dm"
#include "code\__HELPERS\icons\download.dm"
#include "code\__HELPERS\icons\flatten.dm"
-#include "code\__HELPERS\icons\flatten_old.dm"
#include "code\__HELPERS\lists\_string_lists.dm"
#include "code\__HELPERS\lists\asset_sorted.dm"
#include "code\__HELPERS\lists\associations.dm"
@@ -487,6 +488,7 @@
#include "code\controllers\subsystem\shuttles.dm"
#include "code\controllers\subsystem\sonar.dm"
#include "code\controllers\subsystem\spacedrift.dm"
+#include "code\controllers\subsystem\statpanel.dm"
#include "code\controllers\subsystem\sun.dm"
#include "code\controllers\subsystem\supply.dm"
#include "code\controllers\subsystem\tgui.dm"
@@ -540,7 +542,6 @@
#include "code\controllers\subsystem\sound\soundbyte_manager.dm"
#include "code\datums\ai_law_sets.dm"
#include "code\datums\ai_laws.dm"
-#include "code\datums\appearance.dm"
#include "code\datums\beam.dm"
#include "code\datums\callback.dm"
#include "code\datums\category.dm"
@@ -636,6 +637,8 @@
#include "code\datums\helper_datums\global_iterator.dm"
#include "code\datums\helper_datums\teleport.dm"
#include "code\datums\helper_datums\topic_input.dm"
+#include "code\datums\interfaces\appearance.dm"
+#include "code\datums\interfaces\procpath.dm"
#include "code\datums\locations\locations.dm"
#include "code\datums\locations\nyx.dm"
#include "code\datums\locations\qerrvallis.dm"
@@ -2058,9 +2061,9 @@
#include "code\modules\client\client_procs.dm"
#include "code\modules\client\data.dm"
#include "code\modules\client\database.dm"
-#include "code\modules\client\movement.dm"
#include "code\modules\client\player_details.dm"
#include "code\modules\client\spam_prevention.dm"
+#include "code\modules\client\statpanel.dm"
#include "code\modules\client\throttling.dm"
#include "code\modules\client\ui_style.dm"
#include "code\modules\client\viewport.dm"
diff --git a/code/__DEFINES/controllers/_subsystems.dm b/code/__DEFINES/controllers/_subsystems.dm
index 29a6adddfc5..0865d039242 100644
--- a/code/__DEFINES/controllers/_subsystems.dm
+++ b/code/__DEFINES/controllers/_subsystems.dm
@@ -66,15 +66,15 @@ DEFINE_BITFIELD(runlevels, list(
BITFIELD(RUNLEVEL_POSTGAME),
))
-
/**
*! Subsystem init_order, from highest priority to lowest priority.
*? Subsystems shutdown in the reverse of the order they initialize in.
*? The numbers just define the ordering, they are meaningless otherwise.
*/
-#define INIT_ORDER_PROTOTYPES 103
-#define INIT_ORDER_FAIL2TOPIC 102
+#define INIT_ORDER_FAIL2TOPIC 104
+#define INIT_ORDER_STATPANELS 103
+#define INIT_ORDER_PROTOTYPES 102
#define INIT_ORDER_DBCORE 101
#define INIT_ORDER_INPUT 100
#define INIT_ORDER_JOBS 99
@@ -153,6 +153,7 @@ DEFINE_BITFIELD(runlevels, list(
#define FIRE_PRIORITY_PROJECTILES 150
#define FIRE_PRIORITY_THROWING 150
#define FIRE_PRIORITY_CHAT 400
+#define FIRE_PRIORITY_STATPANELS 400
#define FIRE_PRIORITY_OVERLAYS 500
#define FIRE_PRIORITY_SMOOTHING 500
#define FIRE_PRIORITY_TIMER 700
diff --git a/code/__DEFINES/procs/clickcode.dm b/code/__DEFINES/procs/clickcode.dm
index ac5facc19c6..52f2a7051f4 100644
--- a/code/__DEFINES/procs/clickcode.dm
+++ b/code/__DEFINES/procs/clickcode.dm
@@ -21,6 +21,8 @@
#define CLICKCHAIN_TOOL_ACT (1<<2)
/// redirected by something - like when a switchtool to another item
#define CLICKCHAIN_REDIRECTED (1<<3)
+/// this is from tgui or the js statpanel - we should probably be paranoid
+#define CLICKCHAIN_FROM_HREF (1<<4)
//! Reachability Depths - checked from level of DirectAccess and turf adjacency.
/// default reachability depth
diff --git a/code/__DEFINES/skin.dm b/code/__DEFINES/skin.dm
index ae37f4970e0..e334d3e200c 100644
--- a/code/__DEFINES/skin.dm
+++ b/code/__DEFINES/skin.dm
@@ -17,6 +17,13 @@
/// main window split
#define SKIN_SPLITTER_ID_MAIN "mainwindow.split"
+//! Stat System
+#define SKIN_TAB_ID_STAT "stat_tab"
+#define SKIN_PANE_ID_BYONDSTAT "stat_pane_byond"
+#define SKIN_PANE_ID_BROWSERSTAT "stat_pane_browser"
+#define SKIN_BROWSER_ID_STAT "statbrowser"
+#define SKIN_INFO_ID_STAT "statpanel"
+
//? Dynamic skin IDs used by code-generated elements
//? button groups MUST have unique ids to all skin elements!
// TOP LEVEL MENU //
diff --git a/code/__DEFINES/statpanel.dm b/code/__DEFINES/statpanel.dm
new file mode 100644
index 00000000000..a5fe3c3ec7b
--- /dev/null
+++ b/code/__DEFINES/statpanel.dm
@@ -0,0 +1,9 @@
+//! helpers for forming list entries in statpanel_data().
+/// direct text output - cheaply encode without list, js side will view as string
+#define STATPANEL_DATA_LINE(line) . += line
+/// key, value
+#define STATPANEL_DATA_ENTRY(k, v) . += list(list(k, v))
+/// kev, value, target ref; will route to statpanel_click().
+#define STATPANEL_DATA_CLICK(k, v, t) . += list(list(k, v, t))
+
+// todo: click with action param instead of just click
diff --git a/code/__HELPERS/icons/flatten.dm b/code/__HELPERS/icons/flatten.dm
index cd510c8f332..0435f7b6e1e 100644
--- a/code/__HELPERS/icons/flatten.dm
+++ b/code/__HELPERS/icons/flatten.dm
@@ -41,9 +41,9 @@
/proc/get_flat_icon(appearance/appearancelike, dir, no_anim)
if(!dir && isloc(appearancelike))
dir = appearancelike.dir
- return get_flat_icon_new_actual(appearancelike, dir, no_anim, null, TRUE)
+ return _get_flat_icon(appearancelike, dir, no_anim, null, TRUE)
-/proc/get_flat_icon_new_actual(image/A, defdir, no_anim, deficon, start)
+/proc/_get_flat_icon(image/A, defdir, no_anim, deficon, start)
// start with blank image
var/static/icon/template = icon('icons/system/blank_32x32.dmi', "")
@@ -205,7 +205,7 @@
else
// use full get_flat_icon
blend_mode = copying.blend_mode
- adding = get_flat_icon_new_actual(copying, defdir, no_anim, icon)
+ adding = _get_flat_icon(copying, defdir, no_anim, icon)
// if we got nothing, skip
if(!adding)
diff --git a/code/__HELPERS/icons/flatten_old.dm b/code/__HELPERS/icons/flatten_old.dm
deleted file mode 100644
index 20305a19b3d..00000000000
--- a/code/__HELPERS/icons/flatten_old.dm
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
-
---- Why is this code still here?
---- Because I don't trust myself, so, I'll leave the old reference code here incase this breaks later.
-
-/proc/get_flat_icon(A, defdir, no_anim)
- get_flat_icon_old(A, defdir, null, null, null, null, no_anim)
- return get_flat_icon_new(A, defdir, no_anim)
-
-/proc/get_flat_icon_test(A, B, C)
- var/icon/_A = get_flat_icon_old(A, B, null, null, null, null, C)
- var/icon/_B = get_flat_icon_new(A, B, C)
- to_chat(world, "[icon2html(_A, world)]")
- to_chat(world, "[icon2html(_B, world)]")
-
-// todo: rework
-// Creates a single icon from a given /atom or /image. Only the first argument is required.
-/proc/get_flat_icon_old(image/A, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE)
- //Define... defines.
- 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(start)
- if(!defdir)
- defdir = A.dir
- if(!deficon)
- deficon = A.icon
- if(!defstate)
- defstate = A.icon_state
- if(!defblend)
- defblend = A.blend_mode
-
- var/curicon = A.icon || deficon
- var/curstate = A.icon_state || defstate
-
- if(!((noIcon = (!curicon))))
- var/curstates = icon_states(curicon)
- if(!(curstate in curstates))
- if("" in curstates)
- curstate = ""
- else
- noIcon = TRUE // Do not render this object.
-
- 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
-
- //These should use the parent's direction (most likely)
- if(!A.dir || A.dir == SOUTH)
- curdir = defdir
- else
- curdir = A.dir
-
- //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(icon_states(icon(curicon, curstate, i))))
- exist = TRUE
- break
- if(!exist)
- 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 = A.blend_mode || defblend
-
- if(A.overlays.len || A.underlays.len)
- var/icon/flat = BLANK
- // 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
- copy.blend_mode = curblend
- layers[copy] = A.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
-
- //tim_sort(layers, /proc/cmp_image_layer_asc)
-
- 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]
-
- for(var/V in layers)
- var/image/I = V
- if(I.alpha == 0)
- continue
-
- if(I == copy) // 'I' is an /image based on the object being flattened.
- curblend = BLEND_OVERLAY
- add = icon(I.icon, I.icon_state, base_icon_dir)
- else // 'I' is an appearance object.
- add = get_flat_icon_old(image(I), curdir, curicon, curstate, curblend, FALSE, no_anim)
- 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)
- // Resize the flattened icon so the new icon fits
- flat.Crop(
- addX1 - flatX1 + 1,
- addY1 - flatY1 + 1,
- addX2 - flatX1 + 1,
- addY2 - flatY1 + 1
- )
- flat_size = add_size.Copy()
-
- // Blend the overlay into the flattened icon
- flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1)
-
- if(A.color)
- if(islist(A.color))
- flat.MapColors(arglist(A.color))
- else
- flat.Blend(A.color, ICON_MULTIPLY)
-
- if(A.alpha < 255)
- flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY)
-
- if(no_anim)
- //Clean up repeated frames
- var/icon/cleaned = new /icon()
- cleaned.Insert(flat, "", SOUTH, 1, 0)
- . = cleaned
- else
- . = icon(flat, "", SOUTH)
- else //There's no overlays.
- if(!noIcon)
- SET_SELF(.)
-
- //Clear defines
- #undef flatX1
- #undef flatX2
- #undef flatY1
- #undef flatY2
- #undef addX1
- #undef addX2
- #undef addY1
- #undef addY2
-
- #undef INDEX_X_LOW
- #undef INDEX_X_HIGH
- #undef INDEX_Y_LOW
- #undef INDEX_Y_HIGH
-
- #undef BLANK
- #undef SET_SELF
-*/
diff --git a/code/__HELPERS/lists/associations.dm b/code/__HELPERS/lists/associations.dm
index cf4c390fcab..7e2610cb0ba 100644
--- a/code/__HELPERS/lists/associations.dm
+++ b/code/__HELPERS/lists/associations.dm
@@ -1,7 +1,8 @@
-#if DM_VERSION > 514
-#error Remie said that lummox was adding a way to get a lists
-#error contents via list.values, if that is true remove this
-#error otherwise, update the version and bug lummox
+#if DM_VERSION > 515
+// this is just a warn now, we give up
+#warn Remie said that lummox was adding a way to get a lists
+#warn contents via list.values, if that is true remove this
+#warn otherwise, update the version and bug lummox
#endif
/**
diff --git a/code/__HELPERS/verbs.dm b/code/__HELPERS/verbs.dm
new file mode 100644
index 00000000000..23c2fb181dc
--- /dev/null
+++ b/code/__HELPERS/verbs.dm
@@ -0,0 +1,118 @@
+/**
+ * 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
+ if(verb_to_add.hidden)
+ continue
+ if(!istext(verb_to_add.category) || !verb_to_add.name)
+ continue
+ if(verb_to_add.name[1] == ".")
+ continue
+ if(!islist(output_list[verb_to_add.category]))
+ output_list[verb_to_add.category] = list()
+ output_list[verb_to_add.category] += verb_to_add.name
+ output_list = url_encode(json_encode(output_list))
+ target << output("[output_list]", "statbrowser:byond_add_verbs")
+
+/**
+ * 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
+ if(!islist(output_list[verb_to_remove.category]))
+ output_list[verb_to_remove.category] = list()
+ output_list[verb_to_remove.category] += verb_to_remove.name
+ output_list = url_encode(json_encode(output_list))
+ target << output("[output_list]", "statbrowser:byond_remove_verbs")
+
+/**
+ * handles adding an obj verb
+ * makes replacing easier later
+ */
+/proc/add_obj_verb(atom/A, verb_or_list_to_add)
+ A.verbs += verb_or_list_to_add
+
+/**
+ * handles removing an obj verb
+ * makes replacing easier later
+ */
+/proc/remove_obj_verb(atom/A, verb_or_list_to_remove)
+ A.verbs -= verb_or_list_to_remove
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index d456d4a4ead..5bef886b537 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -35,20 +35,24 @@
usr.MouseWheelOn(src, delta_x, delta_y, params)
-/*
- Standard mob ClickOn()
- Handles exceptions: Buildmode, middle click, modified clicks, mech actions
- After that, mostly just check your state, check whether you're holding an item,
- check whether you're adjacent to the target, then pass off the click to whoever
- is recieving it.
- The most common are:
- * mob/UnarmedAttack(atom,adjacent) - used here only when adjacent, with no item in hand; in the case of humans, checks gloves
- * atom/attackby(item,user) - used only when adjacent
- * item/afterattack(atom,user,adjacent,params) - used both ranged and adjacent
- * mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed
-*/
-/mob/proc/ClickOn(var/atom/A, var/params)
+/**
+ * click handling entrypoint
+ *
+ * handles some intercepts (many of which will be potentially moved into other procs later)
+ * handles root level intercepts like admin buildmode / panel
+ *
+ * ! Warning: Any custom calls to this must ensure 'params' argument adheres to BYOND specifications. !
+ *
+ * todo: better description
+ * todo: accept params as string from BYOND or pre-built list
+ *
+ * @params
+ * * A - /atom clicked on
+ * * params - byond params list
+ * * clickchain_flags - allows additional flags to be passed down from, say, the statpanel if this is a routed call.
+ */
+/mob/proc/ClickOn(atom/A, params, clickchain_flags)
if(world.time < next_click) // Hard check, before anything else, to avoid crashing
return
next_click = world.time + 1
@@ -63,6 +67,8 @@
// packed version things have to unpack a second or even third time
// because they can't check the test version???
var/list/unpacked_params = params2list(params)
+ // todo: this is shitcode, entire click params system needs an overhaul to support stuff better.
+ // notably we should stop relying on old button=1 params, as opposed to button=left/right/middle param.
if(unpacked_params["shift"] && unpacked_params["ctrl"])
CtrlShiftClickOn(A)
return 1
@@ -81,6 +87,12 @@
if(unpacked_params["ctrl"])
CtrlClickOn(A)
return 1
+ switch(unpacked_params["button"])
+ if("right")
+ if("left")
+ if("middle")
+ MiddleClickOn(A)
+ return 1
if(stat || paralysis || stunned || weakened)
return
@@ -126,18 +138,18 @@
if(Reachability(A, null, I?.reach, I))
//? attempt melee attack chain
if(I)
- I.melee_attack_chain(A, src, CLICKCHAIN_HAS_PROXIMITY, unpacked_params)
+ I.melee_attack_chain(A, src, clickchain_flags | CLICKCHAIN_HAS_PROXIMITY, unpacked_params)
else
- melee_attack_chain(A, CLICKCHAIN_HAS_PROXIMITY, unpacked_params)
+ melee_attack_chain(A, clickchain_flags | CLICKCHAIN_HAS_PROXIMITY, unpacked_params)
// todo: refactor aiming
trigger_aiming(TARGET_CAN_CLICK)
return
else if(ranged_generics_allowed)
//? attempt ranged attack chain
if(I)
- I.ranged_attack_chain(A, src, NONE, params)
+ I.ranged_attack_chain(A, src, clickchain_flags , params)
else
- ranged_attack_chain(A, NONE, unpacked_params)
+ ranged_attack_chain(A, clickchain_flags , unpacked_params)
// todo: refactor aiming
trigger_aiming(TARGET_CAN_CLICK)
return
@@ -260,17 +272,22 @@
/mob/proc/altclick_listed_turf(atom/A)
var/turf/T = get_turf(A)
- if(T == A.loc || T == A)
- if(T == listed_turf)
- listed_turf = null
- else if(TurfAdjacent(T))
- listed_turf = T
- client.statpanel = T.name
+ if(!T)
+ return
+ if(!TurfAdjacent(T))
+ return
+ if(!client)
+ return
+ if(T == client.statpanel_turf)
+ client.unlist_turf()
+ return
+ client.list_turf(T)
/atom/proc/AltClick(var/mob/user)
SEND_SIGNAL(src, COMSIG_CLICK_ALT, user)
return FALSE
+// todo: rework
/mob/proc/TurfAdjacent(var/turf/T)
return T.AdjacentQuick(src)
diff --git a/code/_rendering/mob.dm b/code/_rendering/mob.dm
index 413af28f7d1..0828921ddc2 100644
--- a/code/_rendering/mob.dm
+++ b/code/_rendering/mob.dm
@@ -11,7 +11,6 @@
client.CreateParallax()
else
client.parallax_holder.Reset(force = TRUE)
-
reload_fullscreen()
client.update_clickcatcher()
INVOKE_ASYNC(client, /client/proc/init_viewport_blocking)
diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm
index 9cd848f8834..68a176db01a 100644
--- a/code/controllers/configuration/configuration.dm
+++ b/code/controllers/configuration/configuration.dm
@@ -211,9 +211,7 @@
return !(var_name in banned_edits) && ..()
/datum/controller/configuration/stat_entry()
- if(!statclick)
- statclick = new/obj/effect/statclick/debug(null, "Edit", src)
- stat("[name]:", statclick)
+ return "Edit"
/datum/controller/configuration/proc/Get(entry_type)
var/datum/config_entry/E = GetEntryDatum(entry_type)
diff --git a/code/controllers/controller.dm b/code/controllers/controller.dm
index 24289b18797..78504e6a59f 100644
--- a/code/controllers/controller.dm
+++ b/code/controllers/controller.dm
@@ -18,4 +18,12 @@
/datum/controller/proc/Recover()
+/datum/controller/proc/stat_key()
+ return "[name]:"
+
/datum/controller/proc/stat_entry()
+ return "\[DEBUG\]"
+
+/datum/controller/statpanel_click(client/C, action)
+ C.debug_variables(src)
+ message_admins("Admin [key_name_admin(C)] is debugging the [name] controller.")
diff --git a/code/controllers/failsafe.dm b/code/controllers/failsafe.dm
index 4c00409351b..61216903e45 100644
--- a/code/controllers/failsafe.dm
+++ b/code/controllers/failsafe.dm
@@ -96,7 +96,4 @@ var/datum/controller/failsafe/Failsafe
return defcon
/datum/controller/failsafe/stat_entry()
- 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])"))
+ return "Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"
diff --git a/code/controllers/globals.dm b/code/controllers/globals.dm
index aca1eb60cfa..61acf321099 100644
--- a/code/controllers/globals.dm
+++ b/code/controllers/globals.dm
@@ -33,10 +33,7 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
return ..()
/datum/controller/global_vars/stat_entry()
- if(!statclick)
- statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
-
- stat("Globals:", statclick.update("Edit"))
+ return "Edit"
/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 ec53c9f1ba9..18475d978a3 100644
--- a/code/controllers/master.dm
+++ b/code/controllers/master.dm
@@ -21,6 +21,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
var/processing = TRUE
// How many times have we ran
var/iteration = 0
+ /// initialized?
+ var/initialized = FALSE
// world.time of last fire, for tracking lag outside of the mc
var/last_run
@@ -173,6 +175,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
Master.subsystems += new BadBoy.type //NEW_SS_GLOBAL will remove the old one
subsystems = Master.subsystems
current_runlevel = Master.current_runlevel
+ initialized = TRUE
StartProcessing(10)
else
to_chat(world, SPAN_BOLDANNOUNCE("The Master Controller is having some issues, we will need to re-initialize EVERYTHING"))
@@ -232,6 +235,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
world.sleep_offline = FALSE
initializations_finished_with_no_players_logged_in = initialized_tod < REALTIMEOFDAY - 10
+ initialized = TRUE
+
// Loop.
Master.StartProcessing(0)
@@ -604,11 +609,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
. = 1
/datum/controller/master/stat_entry()
- 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)]%)) (Internal Tick Usage: [round(MAPTICK_LAST_INTERNAL_TICK_USAGE,0.1)]%)")
- stat("Master Controller:", statclick.update("(TickRate:[Master.processing]) (Iteration:[Master.iteration])"))
+ return "(TickRate:[Master.processing]) (Iteration:[Master.iteration])"
/datum/controller/master/StartLoadingMap()
//disallow more than one map to load at once, multithreading it will just cause race conditions
diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm
index d50acdfd852..d5c34875173 100644
--- a/code/controllers/subsystem.dm
+++ b/code/controllers/subsystem.dm
@@ -253,22 +253,14 @@
return time
//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)
-
-
-
+/datum/controller/subsystem/stat_entry()
if(can_fire && !(SS_NO_FIRE & subsystem_flags))
- msg = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)]\t[msg]"
+ . = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)] "
else
- msg = "OFFLINE\t[msg]"
+ . = "OFFLINE "
- var/title = name
- if (can_fire)
- title = "\[[state_letter()]][title]"
-
- stat(title, statclick.update(msg))
+/datum/controller/subsystem/stat_key()
+ return can_fire? "\[[state_letter()]\][name]" : name
/datum/controller/subsystem/proc/state_letter()
switch (state)
diff --git a/code/controllers/subsystem/ai.dm b/code/controllers/subsystem/ai.dm
index 66aac46fa7a..e89bbd6ac3d 100644
--- a/code/controllers/subsystem/ai.dm
+++ b/code/controllers/subsystem/ai.dm
@@ -11,10 +11,8 @@ SUBSYSTEM_DEF(ai)
var/list/busy_z_levels = list()
var/slept_mobs = 0
-/datum/controller/subsystem/ai/stat_entry(msg_prefix)
- var/list/msg = list(msg_prefix)
- msg += "P:[processing.len]"
- ..(msg.Join())
+/datum/controller/subsystem/ai/stat_entry()
+ return ..() + " P:[length(processing)]"
/datum/controller/subsystem/ai/fire(resumed = 0)
if (!resumed)
diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm
index 31a5d739b2b..4bec0db1d65 100644
--- a/code/controllers/subsystem/air.dm
+++ b/code/controllers/subsystem/air.dm
@@ -35,14 +35,26 @@ SUBSYSTEM_DEF(air)
// This is used to tell Travis WHERE the edges are.
var/list/startup_active_edge_log = list()
-/datum/controller/subsystem/air/stat_entry(msg_prefix)
- var/list/msg = list(
- msg_prefix,
- "\tSt: [current_step ? part_names[current_step] : ""] Z: [zones.len] E: [edges.len] ",
- "\tCost: { T: [round(cost_turfs, 1)] | E: [round(cost_edges, 1)] | F: [round(cost_firezones, 1)] | H: [round(cost_hotspots, 1)] | Z: [round(cost_zones, 1)] } ",
- "\tCyc: [current_cycle] U: { T: [tiles_to_update.len] | E: [active_edges.len] | F: [active_fire_zones.len] | H: [active_hotspots.len] | Z: [zones_to_update.len] }",
- )
- ..(msg.Join("\n"))
+/datum/controller/subsystem/air/stat_entry()
+ var/list/msg = list()
+ msg += "S:[current_step ? part_names[current_step] : ""] "
+ msg += "C:{"
+ msg += "T [round(cost_turfs, 1)] | "
+ msg += "E [round(cost_edges, 1)] | "
+ msg += "F [round(cost_firezones, 1)] | "
+ msg += "H [round(cost_hotspots, 1)] | "
+ msg += "Z [round(cost_zones, 1)] "
+ msg += "}"
+ msg += "Z: [zones.len] "
+ msg += "E: [edges.len] "
+ msg += "Cycle: [current_cycle] {"
+ msg += "T [tiles_to_update.len] | "
+ msg += "E [active_edges.len] | "
+ msg += "F [active_fire_zones.len] | "
+ msg += "H [active_hotspots.len] | "
+ msg += "Z [zones_to_update.len] "
+ msg += "}"
+ return ..() + " [msg.Join()]"
/datum/controller/subsystem/air/PreInit(recovering)
air_master = src
diff --git a/code/controllers/subsystem/alarm.dm b/code/controllers/subsystem/alarm.dm
index bd49631cb6f..749ce940ffc 100644
--- a/code/controllers/subsystem/alarm.dm
+++ b/code/controllers/subsystem/alarm.dm
@@ -41,4 +41,4 @@ SUBSYSTEM_DEF(alarms)
return active_alarm_cache.len
/datum/controller/subsystem/alarms/stat_entry()
- ..("[number_of_active_alarms()] alarm\s")
+ return ..() + " [number_of_active_alarms()] alarm\s"
diff --git a/code/controllers/subsystem/ambient_lighting.dm b/code/controllers/subsystem/ambient_lighting.dm
index 18211da5f7f..ad475390cda 100644
--- a/code/controllers/subsystem/ambient_lighting.dm
+++ b/code/controllers/subsystem/ambient_lighting.dm
@@ -9,7 +9,7 @@ SUBSYSTEM_DEF(ambient_lighting)
var/list/queued = list()
/datum/controller/subsystem/ambient_lighting/stat_entry()
- ..("Queue:[length(queued)]")
+ return ..() + " Queue:[length(queued)]"
/datum/controller/subsystem/ambient_lighting/fire(resumed = FALSE, no_mc_tick = FALSE)
var/list/curr = queued
diff --git a/code/controllers/subsystem/ao.dm b/code/controllers/subsystem/ao.dm
index d2790c4a975..6ca30ba066a 100644
--- a/code/controllers/subsystem/ao.dm
+++ b/code/controllers/subsystem/ao.dm
@@ -10,7 +10,7 @@ SUBSYSTEM_DEF(ao)
/datum/controller/subsystem/ao/stat_entry()
- ..("Queue: [queue.len]")
+ return ..() + "Queue: [queue.len]"
/datum/controller/subsystem/ao/fire(resume = 0, no_mc_tick = FALSE)
if (!queue.len)
diff --git a/code/controllers/subsystem/bellies_vr.dm b/code/controllers/subsystem/bellies_vr.dm
index 120531178fd..bbf286ea6cc 100644
--- a/code/controllers/subsystem/bellies_vr.dm
+++ b/code/controllers/subsystem/bellies_vr.dm
@@ -17,7 +17,7 @@ SUBSYSTEM_DEF(bellies)
var/ignored_bellies = 0
/datum/controller/subsystem/bellies/stat_entry()
- ..("#: [belly_list.len] | P: [ignored_bellies]")
+ return ..() + " #: [belly_list.len] | P: [ignored_bellies]"
/datum/controller/subsystem/bellies/fire(resumed = 0)
if (!resumed)
diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm
index 26ebc6b3ac6..f0e44eddf49 100644
--- a/code/controllers/subsystem/events.dm
+++ b/code/controllers/subsystem/events.dm
@@ -55,7 +55,7 @@ SUBSYSTEM_DEF(events)
EC.process(dt)
/datum/controller/subsystem/events/stat_entry()
- ..("E:[active_events.len]")
+ return ..() + " E:[active_events.len]"
/datum/controller/subsystem/events/Recover()
if(SSevents.active_events)
diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm
index 07a401f1bd5..b6843e5c550 100644
--- a/code/controllers/subsystem/garbage.dm
+++ b/code/controllers/subsystem/garbage.dm
@@ -38,10 +38,11 @@ SUBSYSTEM_DEF(garbage)
pass_counts[i] = 0
fail_counts[i] = 0
-/datum/controller/subsystem/garbage/stat_entry(msg)
+/datum/controller/subsystem/garbage/stat_entry()
var/list/counts = list()
for (var/list/L in queues)
counts += length(L)
+ var/list/msg = list()
msg += "Q:[counts.Join(",")]|D:[delslasttick]|G:[gcedlasttick]|"
msg += "GR:"
if (!(delslasttick+gcedlasttick))
@@ -56,7 +57,7 @@ SUBSYSTEM_DEF(garbage)
msg += "TGR:[round((totalgcs/(totaldels+totalgcs))*100, 0.01)]%"
msg += " P:[pass_counts.Join(",")]"
msg += "|F:[fail_counts.Join(",")]"
- ..(msg)
+ return ..() + " [jointext(msg, "")]"
/datum/controller/subsystem/garbage/Shutdown()
//Adds the del() log to the qdel log file
diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm
index e4e4c5daafd..0897d9d201b 100644
--- a/code/controllers/subsystem/lighting.dm
+++ b/code/controllers/subsystem/lighting.dm
@@ -39,13 +39,13 @@ SUBSYSTEM_DEF(lighting)
/datum/controller/subsystem/lighting/stat_entry()
var/list/out = list(
#ifdef USE_INTELLIGENT_LIGHTING_UPDATES
- "IUR: [total_ss_updates ? round(total_instant_updates/(total_instant_updates+total_ss_updates)*100, 0.1) : "NaN"]% Instant: [force_queued ? "Disabled" : "Allowed"] \n",
+ "IUR: [total_ss_updates ? round(total_instant_updates/(total_instant_updates+total_ss_updates)*100, 0.1) : "NaN"]% Instant: [force_queued ? "Disabled" : "Allowed"] The dormant husk of [src] bursts open, revealing a new, intact copy in the pool of viscera.
",
#endif
- "\tT:{L:[total_lighting_sources] C:[lighting_corners.len] O:[total_lighting_overlays]}\n",
- "\tP:{L:[light_queue.len - (lq_idex - 1)]|C:[corner_queue.len - (cq_idex - 1)]|O:[overlay_queue.len - (oq_idex - 1)]}\n",
- "\tL:{L:[processed_lights]|C:[processed_corners]|O:[processed_overlays]}\n"
+ " T:{L:[total_lighting_sources] C:[lighting_corners.len] O:[total_lighting_overlays]}
",
+ " P:{L:[light_queue.len - (lq_idex - 1)]|C:[corner_queue.len - (cq_idex - 1)]|O:[overlay_queue.len - (oq_idex - 1)]}
",
+ " L:{L:[processed_lights]|C:[processed_corners]|O:[processed_overlays]}
"
)
- ..(out.Join())
+ return ..() + out.Join()
#ifdef USE_INTELLIGENT_LIGHTING_UPDATES
diff --git a/code/controllers/subsystem/machines.dm b/code/controllers/subsystem/machines.dm
index e27b86fe919..a84bad184c0 100644
--- a/code/controllers/subsystem/machines.dm
+++ b/code/controllers/subsystem/machines.dm
@@ -35,10 +35,10 @@ SUBSYSTEM_DEF(machines)
/datum/controller/subsystem/machines/stat_entry()
var/msg = list(
"MC/MS: [round((cost ? global.processing_machines.len/cost_machinery : 0),0.1)]",
- "\tCost: { PiNet: [round(cost_pipenets,1)] | M: [round(cost_machinery,1)] | PowNet: [round(cost_powernets,1)] | PowObj: [round(cost_power_objects,1)] }",
- "\tTotal: { PiNet [global.pipe_networks.len] | M: [global.processing_machines.len] | PowNet: [global.powernets.len] | PowObj: [global.processing_power_items.len] }"
+ " Cost: { PiNet: [round(cost_pipenets,1)] | M: [round(cost_machinery,1)] | PowNet: [round(cost_powernets,1)] | PowObj: [round(cost_power_objects,1)] }",
+ " Total: { PiNet [global.pipe_networks.len] | M: [global.processing_machines.len] | PowNet: [global.powernets.len] | PowObj: [global.processing_power_items.len] }"
)
- ..(jointext(msg, "\n"))
+ return ..() + jointext(msg, "
")
/datum/controller/subsystem/machines/Initialize(timeofday)
makepowernets()
diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm
index 608abd19889..2b72fa146db 100644
--- a/code/controllers/subsystem/mobs.dm
+++ b/code/controllers/subsystem/mobs.dm
@@ -18,7 +18,7 @@ SUBSYSTEM_DEF(mobs)
var/slept_mobs = 0
/datum/controller/subsystem/mobs/stat_entry()
- ..("P: [global.GLOB.mob_list.len] | S: [slept_mobs]")
+ return ..() + " P: [global.GLOB.mob_list.len] | S: [slept_mobs]"
/datum/controller/subsystem/mobs/fire(resumed = 0)
var/list/busy_z_levels = src.busy_z_levels
diff --git a/code/controllers/subsystem/nanoui.dm b/code/controllers/subsystem/nanoui.dm
index 31fa8c3f68c..095dbe8e860 100644
--- a/code/controllers/subsystem/nanoui.dm
+++ b/code/controllers/subsystem/nanoui.dm
@@ -13,7 +13,7 @@ SUBSYSTEM_DEF(nanoui)
processing_uis |= SSnanoui.processing_uis
/datum/controller/subsystem/nanoui/stat_entry()
- return ..("[processing_uis.len] UIs")
+ return ..() + " [processing_uis.len] UIs"
/datum/controller/subsystem/nanoui/fire(resumed)
for(var/thing in processing_uis)
diff --git a/code/controllers/subsystem/overlays.dm b/code/controllers/subsystem/overlays.dm
index c6a0acfe8b2..9734bda1d7c 100644
--- a/code/controllers/subsystem/overlays.dm
+++ b/code/controllers/subsystem/overlays.dm
@@ -22,7 +22,7 @@ SUBSYSTEM_DEF(overlays)
/datum/controller/subsystem/overlays/stat_entry()
- ..("Ov:[length(queue)]")
+ return ..() + " Ov:[length(queue)]"
/datum/controller/subsystem/overlays/Shutdown()
diff --git a/code/controllers/subsystem/ping.dm b/code/controllers/subsystem/ping.dm
index 3dc8172176a..d8b5ba01b9c 100644
--- a/code/controllers/subsystem/ping.dm
+++ b/code/controllers/subsystem/ping.dm
@@ -13,7 +13,7 @@ SUBSYSTEM_DEF(ping)
var/list/currentrun = list()
/datum/controller/subsystem/ping/stat_entry()
- ..("P:[GLOB.clients.len]")
+ return ..() + " P:[GLOB.clients.len]"
/datum/controller/subsystem/ping/fire(resumed = FALSE)
// Prepare the new batch of clients
diff --git a/code/controllers/subsystem/plants.dm b/code/controllers/subsystem/plants.dm
index 1cc0fb55256..a4c5c5bba92 100644
--- a/code/controllers/subsystem/plants.dm
+++ b/code/controllers/subsystem/plants.dm
@@ -30,7 +30,7 @@ SUBSYSTEM_DEF(plants)
var/list/currentrun = list()
/datum/controller/subsystem/plants/stat_entry()
- ..("P:[processing.len]|S:[seeds.len]")
+ return ..() + " P:[processing.len]|S:[seeds.len]"
/datum/controller/subsystem/plants/Initialize(timeofday)
setup()
diff --git a/code/controllers/subsystem/processing/processing.dm b/code/controllers/subsystem/processing/processing.dm
index 0c7014803aa..d6f66d2f667 100644
--- a/code/controllers/subsystem/processing/processing.dm
+++ b/code/controllers/subsystem/processing/processing.dm
@@ -10,9 +10,8 @@ SUBSYSTEM_DEF(processing)
var/list/processing = list()
var/list/currentrun = list()
-/datum/controller/subsystem/processing/stat_entry(msg)
- msg = "[stat_tag]:[length(processing)]"
- return ..()
+/datum/controller/subsystem/processing/stat_entry()
+ return ..() + " [stat_tag]:[length(processing)]"
/datum/controller/subsystem/processing/fire(resumed = FALSE)
if (!resumed)
diff --git a/code/controllers/subsystem/shuttles.dm b/code/controllers/subsystem/shuttles.dm
index 50069b4eb4b..1428bb93e49 100644
--- a/code/controllers/subsystem/shuttles.dm
+++ b/code/controllers/subsystem/shuttles.dm
@@ -209,4 +209,4 @@ SUBSYSTEM_DEF(shuttle)
overmap_halted ? ship_effect.halt() : ship_effect.unhalt()
/datum/controller/subsystem/shuttle/stat_entry()
- ..("Shuttles:[process_shuttles.len]/[shuttles.len], Ships:[ships.len], L:[registered_shuttle_landmarks.len][overmap_halted ? ", HALT" : ""]")
+ return ..() + " Shuttles:[process_shuttles.len]/[shuttles.len], Ships:[ships.len], L:[registered_shuttle_landmarks.len][overmap_halted ? ", HALT" : ""]"
diff --git a/code/controllers/subsystem/spacedrift.dm b/code/controllers/subsystem/spacedrift.dm
index 24be67a5486..56c74294b59 100644
--- a/code/controllers/subsystem/spacedrift.dm
+++ b/code/controllers/subsystem/spacedrift.dm
@@ -9,8 +9,7 @@ SUBSYSTEM_DEF(spacedrift)
var/list/processing = list()
/datum/controller/subsystem/spacedrift/stat_entry()
- ..("P:[processing.len]")
-
+ return ..() + " P:[processing.len]"
/datum/controller/subsystem/spacedrift/fire(resumed = 0)
if (!resumed)
diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm
new file mode 100644
index 00000000000..112e55a7587
--- /dev/null
+++ b/code/controllers/subsystem/statpanel.dm
@@ -0,0 +1,161 @@
+SUBSYSTEM_DEF(statpanels)
+ name = "Stat Panels"
+ wait = 4
+ init_order = INIT_ORDER_STATPANELS
+ priority = FIRE_PRIORITY_STATPANELS
+ runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
+
+ //! ticking
+ /// current clients we're pushing to
+ var/list/currentrun = list()
+
+ //! caching
+ /// cached mc data
+ var/cache_mc_data
+ /// cached server-wide data
+ var/cache_server_data
+ /// cached tickets data
+ var/cache_ticket_data
+ /// cached sdql2 data
+ var/cache_sdql_data
+
+/datum/controller/subsystem/statpanels/Initialize()
+ spawn()
+ manual_ticking()
+ return ..()
+
+/datum/controller/subsystem/statpanels/fire(resumed = FALSE, no_tick_check)
+ if(!resumed)
+ // dispose / rebuild caches
+ cache_mc_data = null
+ cache_server_data = null
+ build_server_data()
+ cache_ticket_data = null
+ cache_sdql_data = null
+ // reset currentrun
+ src.currentrun = GLOB.clients.Copy()
+ // go through clients
+ // cache for sanic speed
+ var/list/currentrun = src.currentrun
+ while(length(currentrun))
+ if(!no_tick_check && MC_TICK_CHECK)
+ return
+ // grab victim
+ var/client/player = currentrun[length(currentrun)]
+ --currentrun.len
+ // check listed turf
+ if(player.statpanel_turf && !player.list_turf_check(player.statpanel_turf))
+ player.unlist_turf()
+ // check if we're even on the js one
+ if(player.statpanel_on_byond)
+ continue
+ // check if ready
+ if(!player.statpanel_ready)
+ continue
+ // are they an admin?
+ var/is_admin = !!player.holder
+ // grab their mob data
+ var/list/additional = player._statpanel_data()
+ // server data has priority
+ // assert primary status tab
+ var/server_data
+ if(player.statpanel_tab("Status", TRUE))
+ server_data = cache_server_data
+ // assert admin tabs - these are special and do not check for additional info
+ else if(player.statpanel_tab("MC", is_admin))
+ server_data = fetch_mc_data()
+ else if(player.statpanel_tab("Tickets", is_admin))
+ server_data = fetch_ticket_data()
+ else if(player.statpanel_tab("SDQL2", is_admin && length(GLOB.sdql2_queries)))
+ server_data = fetch_sdql2_data()
+ else
+ server_data = "%5b%5d" // "[]"
+ // send additional
+ player << output("[server_data];[url_encode(json_encode(additional))]", "statbrowser:byond_update")
+
+//? Cache generator procs
+//? Errors will cause JS panel error spam.
+//? Thus, we rigidly check references, even for things like GLOB which shouldn't ever be missing.
+
+/datum/controller/subsystem/statpanels/proc/fetch_mc_data()
+ if(cache_mc_data)
+ return cache_mc_data
+ . = list()
+ STATPANEL_DATA_ENTRY("CPU:", num2text(world.cpu))
+ STATPANEL_DATA_ENTRY("Instances:", num2text(world.contents.len, 10))
+ STATPANEL_DATA_ENTRY("World Time:", num2text(world.time))
+ if(GLOB)
+ STATPANEL_DATA_CLICK(GLOB.stat_key(), GLOB.stat_entry(), "\ref[GLOB]")
+ else
+ STATPANEL_DATA_LINE("FATAL - NO GLOB")
+ if(config)
+ STATPANEL_DATA_CLICK(config.stat_key(), config.stat_entry(), "\ref[config]")
+ else
+ STATPANEL_DATA_LINE("FATAL - NO CONFIG")
+ STATPANEL_DATA_ENTRY("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)]%)")
+ if(Master)
+ STATPANEL_DATA_CLICK(Master.stat_key(), Master.stat_entry(), "\ref[Master]")
+ else
+ STATPANEL_DATA_LINE("FATAL - NO MASTER CONTROLLER")
+ if(Failsafe)
+ STATPANEL_DATA_CLICK(Failsafe.stat_key(), Failsafe.stat_entry(), "\ref[Failsafe]")
+ else
+ STATPANEL_DATA_LINE("WARNING - NO FAILSAFE")
+ STATPANEL_DATA_LINE("")
+ for(var/datum/controller/subsystem/S as anything in Master.subsystems)
+ STATPANEL_DATA_CLICK(S.stat_key(), S.stat_entry(), "\ref[S]")
+ . = url_encode(json_encode(.))
+ cache_mc_data = .
+
+/datum/controller/subsystem/statpanels/proc/build_server_data()
+ if(cache_server_data)
+ return cache_server_data
+ . = list()
+ //L += SSmapping.stat_map_name
+ STATPANEL_DATA_ENTRY("Round ID", "[GLOB?.round_id || "ERROR"]")
+ // VIRGO START
+ STATPANEL_DATA_ENTRY("Station Time", stationtime2text())
+ STATPANEL_DATA_ENTRY("Station Date", stationdate2text())
+ STATPANEL_DATA_ENTRY("Round Duration", roundduration2text())
+ // VIRGO END
+ STATPANEL_DATA_ENTRY("Time dilation", SStime_track.stat_time_text)
+ //L += SSshuttle.emergency_shuttle_stat_text
+ var/shuttle_eta = SSemergencyshuttle.get_status_panel_eta()
+ if(shuttle_eta)
+ STATPANEL_DATA_ENTRY("Shuttle", shuttle_eta)
+ . = url_encode(json_encode(.))
+ cache_server_data = .
+
+/datum/controller/subsystem/statpanels/proc/fetch_ticket_data()
+ if(cache_ticket_data)
+ return cache_ticket_data
+ if(!GLOB.ahelp_tickets)
+ . = list()
+ STATPANEL_DATA_LINE("FATAL - NO GLOBAL TICKETS HOLDER")
+ . = url_encode(json_encode(.))
+ else
+ . = url_encode(json_encode(GLOB.ahelp_tickets.stat_data()))
+ cache_ticket_data = .
+
+/datum/controller/subsystem/statpanels/proc/fetch_sdql2_data()
+ if(cache_sdql_data)
+ return cache_sdql_data
+ . = list()
+ STATPANEL_DATA_CLICK("Global SDQL2 List:", "\[Edit\]", "\ref[GLOB?.sdql2_vv_statobj]")
+ for(var/datum/SDQL2_query/Q in GLOB.sdql2_queries)
+ . += Q.generate_stat()
+ . = url_encode(json_encode(.))
+ cache_sdql_data = .
+
+/**
+ * is this shitcode?
+ * yes it is
+ * if you wanna do better, do better; i'm not at the point of janking up our MC with my own
+ * fuckery.
+ *
+ * tl;dr this ensures we push data while MC is initializing.
+ */
+/datum/controller/subsystem/statpanels/proc/manual_ticking()
+ while(!Master.initialized)
+ fire(null, TRUE)
+ sleep(10)
diff --git a/code/controllers/subsystem/tgui.dm b/code/controllers/subsystem/tgui.dm
index 6013064d9c2..2c617614445 100644
--- a/code/controllers/subsystem/tgui.dm
+++ b/code/controllers/subsystem/tgui.dm
@@ -42,7 +42,7 @@ SUBSYSTEM_DEF(tgui)
*/
/datum/controller/subsystem/tgui/stat_entry()
- return ..("P:[length(open_uis)]")
+ return ..() + " P:[length(open_uis)]"
/datum/controller/subsystem/tgui/fire(resumed = FALSE)
if(!resumed)
diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm
index 91654f5d1d8..3f7e7a28290 100644
--- a/code/controllers/subsystem/throwing.dm
+++ b/code/controllers/subsystem/throwing.dm
@@ -9,7 +9,7 @@ SUBSYSTEM_DEF(throwing)
var/list/processing = list()
/datum/controller/subsystem/throwing/stat_entry()
- ..("P:[processing.len]")
+ return ..() + " P:[processing.len]"
/datum/controller/subsystem/throwing/fire(resumed = 0)
if (!resumed)
diff --git a/code/controllers/subsystem/time_track.dm b/code/controllers/subsystem/time_track.dm
index 61ce3184153..bf861d0ff76 100644
--- a/code/controllers/subsystem/time_track.dm
+++ b/code/controllers/subsystem/time_track.dm
@@ -19,8 +19,8 @@ SUBSYSTEM_DEF(time_track)
var/last_measurement = 0
var/measurement_delay = 60
- var/stat_time_text
- var/time_dilation_text
+ var/stat_time_text = "Calculating..."
+ var/time_dilation_text = "Calculating..."
/datum/controller/subsystem/time_track/fire()
if(++last_measurement == measurement_delay)
diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm
index 911649f912e..72c33d0fe13 100644
--- a/code/controllers/subsystem/timer.dm
+++ b/code/controllers/subsystem/timer.dm
@@ -66,9 +66,8 @@ SUBSYSTEM_DEF(timer)
head_offset = world.time
bucket_resolution = world.tick_lag
-/datum/controller/subsystem/timer/stat_entry(msg)
- 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/stat_entry()
+ return ..() + " B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]"
/datum/controller/subsystem/timer/fire(resumed = FALSE)
// Store local references to datum vars as it is faster to access them
diff --git a/code/controllers/subsystem/transcore_vr.dm b/code/controllers/subsystem/transcore_vr.dm
index 26d6fc805a4..c06a6112f32 100644
--- a/code/controllers/subsystem/transcore_vr.dm
+++ b/code/controllers/subsystem/transcore_vr.dm
@@ -109,7 +109,7 @@ SUBSYSTEM_DEF(transcore)
msg += "IM:[implants.len]|"
msg += "BK:[backed_up.len]"
msg += "} "
- ..(jointext(msg, null))
+ return ..() + " [jointext(msg, null)]"
/datum/controller/subsystem/transcore/proc/m_backup(var/datum/mind/mind, var/obj/item/nif/nif, var/one_time = FALSE)
ASSERT(mind)
diff --git a/code/controllers/subsystem/xenoarch.dm b/code/controllers/subsystem/xenoarch.dm
index 4f05d0685cd..664c5975895 100644
--- a/code/controllers/subsystem/xenoarch.dm
+++ b/code/controllers/subsystem/xenoarch.dm
@@ -24,11 +24,6 @@ SUBSYSTEM_DEF(xenoarch)
if (istype(SSxenoarch.digsite_spawning_turfs))
digsite_spawning_turfs = SSxenoarch.digsite_spawning_turfs
-/datum/controller/subsystem/xenoarch/stat_entry(msg)
- if (!GLOB.Debug2)
- return // Only show up in stat panel if debugging is enabled.
- . = ..()
-
/datum/controller/subsystem/xenoarch/proc/SetupXenoarch()
var/list/faster = list()
var/start
diff --git a/code/controllers/subsystem/zmimic.dm b/code/controllers/subsystem/zmimic.dm
index 148f9f5d3f3..625131efa05 100644
--- a/code/controllers/subsystem/zmimic.dm
+++ b/code/controllers/subsystem/zmimic.dm
@@ -125,7 +125,7 @@ SUBSYSTEM_DEF(zmimic)
"T: { T: [openspace_turfs] O: [openspace_overlays] } Q: { T: [queued_turfs.len - (qt_idex - 1)] O: [queued_overlays.len - (qo_idex - 1)] } Sk: { T: [multiqueue_skips_turf] O: [multiqueue_skips_object] }",
"F: { H: [fixup_hit] M: [fixup_miss] N: [fixup_noop] FC: [fixup_cache.len] FKG: [fixup_known_good.len] }", // Fixup stats.
)
- ..(entries.Join("\n\t"))
+ return ..() + entries.Join("
")
// 1, 2, 3..=7, 8
/datum/controller/subsystem/zmimic/proc/build_zstack_display()
diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm
index 3eea5118497..03ab864a634 100644
--- a/code/controllers/verbs.dm
+++ b/code/controllers/verbs.dm
@@ -18,7 +18,10 @@ INITIALIZE_IMMEDIATE(/obj/effect/statclick)
if(name == text)
return src // let's ont change for no reason shall we
name = text
- return src
+ return name
+
+/obj/effect/statclick/statpanel_click(client/C, action)
+ Click()
/obj/effect/statclick/debug
var/class
diff --git a/code/datums/components/rotation.dm b/code/datums/components/rotation.dm
index 8820813dea9..d8734226dfa 100644
--- a/code/datums/components/rotation.dm
+++ b/code/datums/components/rotation.dm
@@ -55,18 +55,18 @@
if(rotation_flags & ROTATION_VERBS)
var/atom/movable/AM = parent
if(rotation_flags & ROTATION_FLIP)
- AM.verbs += /atom/movable/proc/simple_rotate_flip
+ add_obj_verb(AM, /atom/movable/proc/simple_rotate_flip)
if(src.rotation_flags & ROTATION_CLOCKWISE)
- AM.verbs += /atom/movable/proc/simple_rotate_clockwise
+ add_obj_verb(AM, /atom/movable/proc/simple_rotate_clockwise)
if(src.rotation_flags & ROTATION_COUNTERCLOCKWISE)
- AM.verbs += /atom/movable/proc/simple_rotate_counterclockwise
+ add_obj_verb(AM, /atom/movable/proc/simple_rotate_counterclockwise)
/datum/component/simple_rotation/proc/remove_verbs()
if(parent)
var/atom/movable/AM = parent
- AM.verbs -= /atom/movable/proc/simple_rotate_flip
- AM.verbs -= /atom/movable/proc/simple_rotate_clockwise
- AM.verbs -= /atom/movable/proc/simple_rotate_counterclockwise
+ remove_obj_verb(AM, /atom/movable/proc/simple_rotate_flip)
+ remove_obj_verb(AM, /atom/movable/proc/simple_rotate_clockwise)
+ remove_obj_verb(AM, /atom/movable/proc/simple_rotate_counterclockwise)
/datum/component/simple_rotation/proc/remove_signals()
UnregisterSignal(parent, list(COMSIG_CLICK_ALT, COMSIG_PARENT_EXAMINE, COMSIG_PARENT_ATTACKBY))
diff --git a/code/datums/appearance.dm b/code/datums/interfaces/appearance.dm
similarity index 100%
rename from code/datums/appearance.dm
rename to code/datums/interfaces/appearance.dm
diff --git a/code/datums/interfaces/procpath.dm b/code/datums/interfaces/procpath.dm
new file mode 100644
index 00000000000..642ca3eab6c
--- /dev/null
+++ b/code/datums/interfaces/procpath.dm
@@ -0,0 +1,26 @@
+/// Represents a proc or verb path.
+///
+/// Despite having no DM-defined static type, proc paths have some variables,
+/// listed below. These are not modifiable, but for a given procpath P,
+/// `new P(null, "Name", "Desc")` can be used to create a new procpath with the
+/// same code but new `name` and `desc` values. The other variables cannot be
+/// changed in this way.
+///
+/// This type exists only to act as an annotation, providing reasonable static
+/// typing for procpaths. Previously, types like `/atom/verb` were used, with
+/// the `name` and `desc` vars of `/atom` thus being accessible. Proc and verb
+/// paths will fail `istype` and `ispath` checks against `/procpath`.
+/procpath
+ // Although these variables are effectively const, if they are marked const
+ // below, their accesses are optimized away.
+
+ /// A text string of the verb's name.
+ var/name as text
+ /// The verb's help text or description.
+ var/desc as text
+ /// The category or tab the verb will appear in.
+ var/category as text
+ /// Only clients/mobs with `see_invisibility` higher can use the verb.
+ var/invisibility as num
+ /// Whether or not the verb appears in statpanel and commandbar when you press space
+ var/hidden as num
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 152603932d7..d2b91a176b1 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -93,7 +93,7 @@
if(current) //remove ourself from our old body's mind variable
if(changeling)
current.remove_changeling_powers()
- current.verbs -= /datum/changeling/proc/EvolutionMenu
+ remove_verb(current, /datum/changeling/proc/EvolutionMenu)
current.mind = null
SSnanoui.user_transferred(current, new_character) // transfer active NanoUI instances to new user
@@ -506,7 +506,7 @@
mind.name = real_name
mind.current = src
if(player_is_antag(mind))
- src.client.verbs += /client/proc/aooc
+ add_verb(client, /client/proc/aooc)
//HUMAN
/mob/living/carbon/human/mind_initialize()
diff --git a/code/game/antagonist/antagonist_add.dm b/code/game/antagonist/antagonist_add.dm
index c9d3aa9d115..d88c79ae88a 100644
--- a/code/game/antagonist/antagonist_add.dm
+++ b/code/game/antagonist/antagonist_add.dm
@@ -28,16 +28,16 @@
current_antagonists |= player
if(faction_verb && player.current)
- player.current.verbs |= faction_verb
+ add_verb(player.current, faction_verb)
spawn(1 SECOND) //Added a delay so that this should pop up at the bottom and not the top of the text flood the new antag gets.
to_chat(player.current, "Once you decide on a goal to pursue, you can optionally display it to \
everyone at the end of the shift with the Set Ambition verb, located in the IC tab. You can change this at any time, \
and it otherwise has no bearing on your round.")
- player.current.verbs |= /mob/living/proc/write_ambition
+ add_verb(player.current, /mob/living/proc/write_ambition)
if(can_speak_aooc)
- player.current.client.verbs += /client/proc/aooc
+ add_verb(player.current.client, /client/proc/aooc)
// Handle only adding a mind and not bothering with gear etc.
if(nonstandard_role_type)
@@ -51,7 +51,7 @@
/datum/antagonist/proc/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted)
if(player.current && faction_verb)
- player.current.verbs -= faction_verb
+ remove_verb(player.current, faction_verb)
if(player in current_antagonists)
to_chat(player.current, "You are no longer a [role_text]!")
current_antagonists -= player
@@ -60,8 +60,8 @@
update_icons_removed(player)
player.current.update_hud_antag()
if(!is_special_character(player))
- player.current.verbs -= /mob/living/proc/write_ambition
- player.current.client.verbs -= /client/proc/aooc
+ remove_verb(player.current, /mob/living/proc/write_ambition)
+ remove_verb(player.current.client, /client/proc/aooc)
player.ambitions = ""
return 1
return 0
diff --git a/code/game/dna/genes/powers.dm b/code/game/dna/genes/powers.dm
index 359e389874d..2e608f28a47 100644
--- a/code/game/dna/genes/powers.dm
+++ b/code/game/dna/genes/powers.dm
@@ -20,7 +20,7 @@
/datum/gene/basic/remoteview/activate(mob/M, connected, flags)
..(M,connected,flags)
- M.verbs += /mob/living/carbon/human/proc/remoteobserve
+ add_verb(M, /mob/living/carbon/human/proc/remoteobserve)
/datum/gene/basic/regenerate
name = "Regenerate"
@@ -48,7 +48,7 @@
/datum/gene/basic/remotetalk/activate(mob/M, connected, flags)
..(M,connected,flags)
- M.verbs += /mob/living/carbon/human/proc/remotesay
+ add_verb(M, /mob/living/carbon/human/proc/remotesay)
/datum/gene/basic/morph
name = "Morph"
@@ -60,7 +60,7 @@
/datum/gene/basic/morph/activate(mob/M)
..(M)
- M.verbs += /mob/living/carbon/human/proc/morph
+ add_verb(M, /mob/living/carbon/human/proc/morph)
/* Not used on bay
/datum/gene/basic/heat_resist
diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm
index 4077e210a72..8b8c4834f3d 100644
--- a/code/game/gamemodes/changeling/changeling_powers.dm
+++ b/code/game/gamemodes/changeling/changeling_powers.dm
@@ -74,8 +74,8 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
if(!mind.changeling)
mind.changeling = new /datum/changeling(gender)
- verbs += /datum/changeling/proc/EvolutionMenu
- verbs += /mob/proc/changeling_respec
+ add_verb(src, /datum/changeling/proc/EvolutionMenu)
+ add_verb(src, /mob/proc/changeling_respec)
add_language("Changeling")
var/lesser_form = !ishuman(src)
@@ -94,7 +94,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
if(P.isVerb)
if(lesser_form && !P.allowduringlesserform) continue
if(!(P in src.verbs))
- src.verbs += P.verbpath
+ add_verb(src, P.verbpath)
if(P.make_hud_button)
if(!src.ability_master)
src.ability_master = new /atom/movable/screen/movable/ability_master(src)
@@ -123,7 +123,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
return
for(var/datum/power/changeling/P in mind.changeling.purchased_powers)
if(P.isVerb)
- verbs -= P.verbpath
+ remove_verb(src, P.verbpath)
var/atom/movable/screen/ability/verb_based/changeling/C = ability_master.get_ability_by_proc_ref(P.verbpath)
if(C)
ability_master.remove_ability(C)
@@ -252,9 +252,9 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
changeling.chem_charges -= required_chems
changeling.sting_range = 1
- src.verbs -= verb_path
+ remove_verb(src, verb_path)
spawn(10)
- src.verbs += verb_path
+ add_verb(src, verb_path)
to_chat(src, SPAN_NOTICE("We stealthily sting [T]."))
if(!T.mind || !T.mind.changeling)
diff --git a/code/game/gamemodes/changeling/powers/boost_range.dm b/code/game/gamemodes/changeling/powers/boost_range.dm
index 7ab97c7bd63..7bb7859df13 100644
--- a/code/game/gamemodes/changeling/powers/boost_range.dm
+++ b/code/game/gamemodes/changeling/powers/boost_range.dm
@@ -24,8 +24,8 @@
range = range + 3
to_chat(src, "We can fire our next sting from five squares away.")
changeling.sting_range = range
- src.verbs -= /mob/proc/changeling_boost_range
+ remove_verb(src, /mob/proc/changeling_boost_range)
spawn(5)
- src.verbs += /mob/proc/changeling_boost_range
+ add_verb(src, /mob/proc/changeling_boost_range)
feedback_add_details("changeling_powers","RS")
return 1
diff --git a/code/game/gamemodes/changeling/powers/cryo_sting.dm b/code/game/gamemodes/changeling/powers/cryo_sting.dm
index 8313ee0884b..1b6afec48f5 100644
--- a/code/game/gamemodes/changeling/powers/cryo_sting.dm
+++ b/code/game/gamemodes/changeling/powers/cryo_sting.dm
@@ -24,8 +24,8 @@
if(T.reagents)
T.reagents.add_reagent("cryotoxin", inject_amount)
feedback_add_details("changeling_powers","CS")
- src.verbs -= /mob/proc/changeling_cryo_sting
+ remove_verb(src, /mob/proc/changeling_cryo_sting)
spawn(3 MINUTES)
to_chat(src, "Our cryogenic string is ready to be used once more.")
- src.verbs |= /mob/proc/changeling_cryo_sting
+ add_verb(src, /mob/proc/changeling_cryo_sting)
return 1
diff --git a/code/game/gamemodes/changeling/powers/digital_camo.dm b/code/game/gamemodes/changeling/powers/digital_camo.dm
index e03f7e34aad..b67e2d3b63d 100644
--- a/code/game/gamemodes/changeling/powers/digital_camo.dm
+++ b/code/game/gamemodes/changeling/powers/digital_camo.dm
@@ -29,8 +29,8 @@
C.mind.changeling.chem_charges = max(C.mind.changeling.chem_charges - 1, 0)
sleep(40)
- src.verbs -= /mob/proc/changeling_digitalcamo
+ remove_verb(src, /mob/proc/changeling_digitalcamo)
spawn(5)
- src.verbs += /mob/proc/changeling_digitalcamo
+ add_verb(src, /mob/proc/changeling_digitalcamo)
feedback_add_details("changeling_powers","CAM")
return 1
diff --git a/code/game/gamemodes/changeling/powers/fake_death.dm b/code/game/gamemodes/changeling/powers/fake_death.dm
index 9459872817b..c7b2e9f98ee 100644
--- a/code/game/gamemodes/changeling/powers/fake_death.dm
+++ b/code/game/gamemodes/changeling/powers/fake_death.dm
@@ -43,7 +43,7 @@
spawn(rand(2 MINUTES, 4 MINUTES))
//The ling will now be able to choose when to revive
- src.verbs += /mob/proc/changeling_revive
+ add_verb(src, /mob/proc/changeling_revive)
to_chat(src, "We are ready to rise. Use the Revive verb when you are ready.")
feedback_add_details("changeling_powers","FD")
diff --git a/code/game/gamemodes/changeling/powers/fleshmend.dm b/code/game/gamemodes/changeling/powers/fleshmend.dm
index 92cc9cbd839..6fedc419ad5 100644
--- a/code/game/gamemodes/changeling/powers/fleshmend.dm
+++ b/code/game/gamemodes/changeling/powers/fleshmend.dm
@@ -33,9 +33,9 @@
C.adjustFireLoss(-heal_amount)
sleep(1 SECOND)
- src.verbs -= /mob/proc/changeling_fleshmend
+ remove_verb(src, /mob/proc/changeling_fleshmend)
spawn(50 SECONDS)
to_chat(src, "Our regeneration has slowed to normal levels.")
- src.verbs += /mob/proc/changeling_fleshmend
+ add_verb(src, /mob/proc/changeling_fleshmend)
feedback_add_details("changeling_powers","FM")
return 1
diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm
index c8ed281b700..bd34b55995f 100644
--- a/code/game/gamemodes/changeling/powers/revive.dm
+++ b/code/game/gamemodes/changeling/powers/revive.dm
@@ -57,7 +57,7 @@
C.set_stat(CONSCIOUS)
C.forbid_seeing_deadchat = FALSE
C.timeofdeath = null
- src.verbs -= /mob/proc/changeling_revive
+ remove_verb(src, /mob/proc/changeling_revive)
// re-add our changeling powers
C.make_changeling()
diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm
index 0bb26e08834..009080bcf6a 100644
--- a/code/game/gamemodes/changeling/powers/transform.dm
+++ b/code/game/gamemodes/changeling/powers/transform.dm
@@ -53,9 +53,9 @@
for(var/datum/modifier/mod in chosen_dna.genMods)
self.modifiers.Add(mod.type)
- src.verbs -= /mob/proc/changeling_transform
+ remove_verb(src, /mob/proc/changeling_transform)
spawn(10)
- src.verbs += /mob/proc/changeling_transform
+ add_verb(src, /mob/proc/changeling_transform)
src.regenerate_icons()
feedback_add_details("changeling_powers","TR")
diff --git a/code/game/gamemodes/malfunction/malf_hardware.dm b/code/game/gamemodes/malfunction/malf_hardware.dm
index ef6a93301aa..8036f45240d 100644
--- a/code/game/gamemodes/malfunction/malf_hardware.dm
+++ b/code/game/gamemodes/malfunction/malf_hardware.dm
@@ -12,7 +12,7 @@
if(owner && istype(owner))
owner.hardware = src
if(driver)
- owner.verbs += driver
+ add_verb(owner, driver)
/datum/malf_hardware/proc/get_examine_desc()
return "It has some sort of hardware attached to its core"
diff --git a/code/game/gamemodes/malfunction/malf_research.dm b/code/game/gamemodes/malfunction/malf_research.dm
index 37475a0a41c..7f41241344a 100644
--- a/code/game/gamemodes/malfunction/malf_research.dm
+++ b/code/game/gamemodes/malfunction/malf_research.dm
@@ -32,7 +32,7 @@
if(!focus)
return
to_chat(owner, "Research Completed: [focus.name]")
- owner.verbs.Add(focus.ability)
+ add_verb(owner, focus.ability)
available_abilities -= focus
if(focus.next)
available_abilities += focus.next
diff --git a/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm
index f1e78d5ff22..b9a3ce15dcb 100644
--- a/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm
+++ b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm
@@ -203,7 +203,7 @@
user.hack_can_fail = 0
user.hacking = 0
user.system_override = 2
- user.verbs += new/datum/game_mode/malfunction/verb/ai_destroy_station()
+ add_verb(user, /datum/game_mode/malfunction/verb/ai_destroy_station)
// END ABILITY VERBS
diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm
index 943d422bfee..9ac85720d74 100644
--- a/code/game/gamemodes/sandbox/h_sandbox.dm
+++ b/code/game/gamemodes/sandbox/h_sandbox.dm
@@ -23,7 +23,7 @@ mob
sandbox.owner = src.ckey
if(src.client.holder)
sandbox.admin = 1
- verbs += new/mob/proc/sandbox_panel
+ add_verb(src, new/mob/proc/sandbox_panel)
sandbox_panel()
if(sandbox)
sandbox.update()
diff --git a/code/game/gamemodes/technomancer/core_obj.dm b/code/game/gamemodes/technomancer/core_obj.dm
index 53f0982ff23..3fae544560f 100644
--- a/code/game/gamemodes/technomancer/core_obj.dm
+++ b/code/game/gamemodes/technomancer/core_obj.dm
@@ -157,23 +157,21 @@
/obj/spellbutton/DblClick()
return Click()
-/mob/living/carbon/human/Stat()
+/mob/living/carbon/human/statpanel_data(client/C)
. = ..()
-
- if(. && istype(back,/obj/item/technomancer_core))
+ if(istype(back,/obj/item/technomancer_core) && C.statpanel_tab("Spell Core"))
var/obj/item/technomancer_core/core = back
- setup_technomancer_stat(core)
+ . += technomancer_stat(core)
-/mob/living/carbon/human/proc/setup_technomancer_stat(var/obj/item/technomancer_core/core)
- if(core && statpanel("Spell Core"))
- var/charge_status = "[core.energy]/[core.max_energy] ([round( (core.energy / core.max_energy) * 100)]%) \
- ([round(core.energy_delta)]/s)"
- var/instability_delta = instability - last_instability
- var/instability_status = "[src.instability] ([round(instability_delta, 0.1)]/s)"
- stat("Core charge", charge_status)
- stat("User instability", instability_status)
- for(var/obj/spellbutton/button in core.spells)
- stat(button)
+/mob/living/carbon/human/proc/technomancer_stat(obj/item/technomancer_core/core)
+ var/charge_status = "[core.energy]/[core.max_energy] ([round( (core.energy / core.max_energy) * 100)]%) \
+ ([round(core.energy_delta)]/s)"
+ var/instability_delta = instability - last_instability
+ var/instability_status = "[src.instability] ([round(instability_delta, 0.1)]/s)"
+ STATPANEL_DATA_ENTRY("Core charge", charge_status)
+ STATPANEL_DATA_ENTRY("User instability", instability_status)
+ for(var/obj/spellbutton/button in core.spells)
+ STATPANEL_DATA_CLICK(button.name, "Trigger", "\ref[button]")
/obj/item/technomancer_core/proc/add_spell(var/path, var/new_name, var/ability_icon_state)
if(!path || !ispath(path))
diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm
index 2b893814996..177ce050915 100644
--- a/code/game/machinery/computer/computer.dm
+++ b/code/game/machinery/computer/computer.dm
@@ -45,12 +45,12 @@
return
if (prob(50))
for(var/x in verbs)
- verbs -= x
+ remove_obj_verb(src, x)
set_broken()
if(3.0)
if (prob(25))
for(var/x in verbs)
- verbs -= x
+ remove_obj_verb(src, x)
set_broken()
else
return
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index 1fba6520d2c..2463fb01b75 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -258,7 +258,7 @@
/obj/machinery/iv_drip/verb/eject_beaker()
set category = "Object"
set name = "Remove IV Container"
- set src in view(1)
+ set src in oview(1)
if(!isliving(usr))
to_chat(usr, SPAN_WARNING("You can't do that!"))
@@ -278,7 +278,7 @@
/obj/machinery/iv_drip/verb/toggle_mode()
set category = "Object"
set name = "Toggle Mode"
- set src in view(1)
+ set src in oview(1)
if(!isliving(usr))
to_chat(usr, SPAN_WARNING("You can't do that!"))
diff --git a/code/game/machinery/overview.dm b/code/game/machinery/overview.dm
index d2aa5c3423b..0a8d18ab296 100644
--- a/code/game/machinery/overview.dm
+++ b/code/game/machinery/overview.dm
@@ -2,7 +2,9 @@
/obj/machinery/computer/security/verb/station_map()
set name = ".map"
set category = "Object"
- set src in view(1)
+ set src in oview(1)
+ set hidden = TRUE
+
usr.set_machine(src)
if(!mapping) return
log_game("[usr]([usr.key]) used station map L[z] in [src.loc.loc]")
diff --git a/code/game/machinery/pointdefense.dm b/code/game/machinery/pointdefense.dm
index 34076e96c6c..43f58df8eeb 100644
--- a/code/game/machinery/pointdefense.dm
+++ b/code/game/machinery/pointdefense.dm
@@ -32,10 +32,10 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
circuit = new circuit(src)
default_apply_parts()
-/obj/machinery/pointdefense_control/get_description_interaction()
+/obj/machinery/pointdefense_control/get_description_interaction(mob/user)
. = ..()
if(!id_tag)
- . += "[desc_panel_image("multitool")]to set ident tag"
+ . += "[desc_panel_image("multitool", user)]to set ident tag"
/obj/machinery/pointdefense_control/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
@@ -156,10 +156,10 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
if(powernet)
. += "It is connected to a power cable below."
-/obj/machinery/power/pointdefense/get_description_interaction()
+/obj/machinery/power/pointdefense/get_description_interaction(mob/user)
. = ..()
if(!id_tag)
- . += "[desc_panel_image("multitool")]to set ident tag and connect to a mainframe."
+ . += "[desc_panel_image("multitool", user)]to set ident tag and connect to a mainframe."
/obj/machinery/power/pointdefense/update_icon()
if(!active || !id_tag || inoperable())
diff --git a/code/game/mecha/equipment/tools/passenger.dm b/code/game/mecha/equipment/tools/passenger.dm
index 156f30b68e7..e133e5a72eb 100644
--- a/code/game/mecha/equipment/tools/passenger.dm
+++ b/code/game/mecha/equipment/tools/passenger.dm
@@ -28,8 +28,13 @@
if(do_after(user, 40, needhand=0))
if(!src.occupant)
- user.forceMove(src)
- user.update_perspective()
+ //? WARNING WARNING SHITCODE ALERT
+ //? BYOND WILL REFUSE TO PROPERLY UPDATE STUFF IF WE MOVE IN IMMEDIATELY
+ //? THUS, SLEEP A SINGLE TICK.
+ spawn(world.tick_lag)
+ user.forceMove(src)
+ user.update_perspective()
+ add_verb(user, /mob/proc/verb_eject_mech_passenger)
occupant = user
log_message("[user] boarded.")
occupant_message("[user] boarded.")
@@ -38,23 +43,30 @@
else
to_chat(user, "You stop entering the exosuit.")
-/obj/item/mecha_parts/mecha_equipment/tool/passenger/verb/eject()
- set name = "Eject"
+// todo: action
+/mob/proc/verb_eject_mech_passenger()
+ set name = "Eject Passenger"
set category = "Exosuit Interface"
- set src = usr.loc
- set popup_menu = 0
+ set src = usr
- if(usr != occupant)
+ var/obj/item/mecha_parts/mecha_equipment/tool/passenger/pod = loc
+ if(!istype(pod))
+ remove_verb(src, /mob/proc/verb_eject_mech_passenger)
return
- to_chat(occupant, "You climb out from \the [src].")
- go_out()
- occupant_message("[occupant] disembarked.")
- log_message("[occupant] disembarked.")
- add_fingerprint(usr)
+ if(src != pod.occupant)
+ forceMove(get_turf(pod))
+ remove_verb(src, /mob/proc/verb_eject_mech_passenger)
+ return
+ to_chat(src, "You climb out from \the [src].")
+ pod.go_out()
+ pod.occupant_message("[pod.occupant] disembarked.")
+ pod.log_message("[pod.occupant] disembarked.")
+ pod.add_fingerprint(src)
/obj/item/mecha_parts/mecha_equipment/tool/passenger/proc/go_out()
if(!occupant)
return
+ remove_verb(occupant, /mob/proc/verb_eject_mech_passenger)
occupant.forceMove(get_turf(src))
occupant.update_perspective()
occupant = null
@@ -63,7 +75,7 @@
/obj/item/mecha_parts/mecha_equipment/tool/passenger/attach()
..()
if (chassis)
- chassis.verbs |= /obj/mecha/proc/move_inside_passenger
+ add_obj_verb(chassis, /obj/mecha/proc/move_inside_passenger)
/obj/item/mecha_parts/mecha_equipment/tool/passenger/detach()
if(occupant)
@@ -73,7 +85,7 @@
var/obj/mecha/M = chassis
..()
if (M && !(locate(/obj/item/mecha_parts/mecha_equipment/tool/passenger) in M))
- M.verbs -= /obj/mecha/proc/move_inside_passenger
+ remove_verb(M, /obj/mecha/proc/move_inside_passenger)
/obj/item/mecha_parts/mecha_equipment/tool/passenger/get_equip_info()
return "[..()]
[occupant? "\[Occupant: [occupant]\]|" : ""]Exterior Hatch: Toggle Lock"
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 965dc4280e8..11047df6fce 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -385,10 +385,10 @@
////////////////////////
/obj/mecha/proc/removeVerb(verb_path)
- verbs -= verb_path
+ remove_obj_verb(src, verb_path)
/obj/mecha/proc/addVerb(verb_path)
- verbs += verb_path
+ add_obj_verb(src, verb_path)
/obj/mecha/proc/add_airtank()
internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src)
@@ -1611,7 +1611,7 @@
brainmob.reset_perspective(src)
brainmob.canmove = 1
mmi_as_oc.mecha = src
- src.verbs += /obj/mecha/verb/eject
+ add_obj_verb(src, /obj/mecha/verb/eject)
src.Entered(mmi_as_oc)
src.Move(src.loc)
update_icon()
@@ -1699,8 +1699,8 @@
if(possible_port)
if(connect(possible_port))
occupant_message("\The [name] connects to the port.")
- verbs += /obj/mecha/verb/disconnect_from_port
- verbs -= /obj/mecha/verb/connect_to_port
+ add_obj_verb(src, /obj/mecha/verb/disconnect_from_port)
+ remove_obj_verb(src, /obj/mecha/verb/connect_to_port)
return
else
occupant_message("\The [name] failed to connect to the port.")
@@ -1723,8 +1723,8 @@
if(disconnect())
occupant_message("[name] disconnects from the port.")
- verbs -= /obj/mecha/verb/disconnect_from_port
- verbs += /obj/mecha/verb/connect_to_port
+ remove_obj_verb(src, /obj/mecha/verb/disconnect_from_port)
+ add_obj_verb(src, /obj/mecha/verb/connect_to_port)
else
occupant_message("[name] is not connected to the port at the moment.")
@@ -1878,7 +1878,7 @@
H.update_perspective()
occupant = H
add_fingerprint(H)
- verbs += /obj/mecha/verb/eject
+ add_obj_verb(src, /obj/mecha/verb/eject)
log_append_to_last("[H] moved in as pilot.")
update_icon()
if(occupant.hud_used)
@@ -1888,21 +1888,21 @@
//And it's not like this 10yo code wasn't clunky before.
if(!smoke_possible) //Can't use smoke? No verb for you.
- verbs -= /obj/mecha/verb/toggle_smoke
+ remove_obj_verb(src, /obj/mecha/verb/toggle_smoke)
if(!thrusters_possible) //Can't use thrusters? No verb for you.
- verbs -= /obj/mecha/verb/toggle_thrusters
+ remove_obj_verb(src, /obj/mecha/verb/toggle_thrusters)
if(!defence_mode_possible) //Do i need to explain everything?
- verbs -= /obj/mecha/verb/toggle_defence_mode
+ remove_obj_verb(src, /obj/mecha/verb/toggle_defence_mode)
if(!overload_possible)
- verbs -= /obj/mecha/verb/toggle_overload
+ remove_obj_verb(src, /obj/mecha/verb/toggle_overload)
if(!zoom_possible)
- verbs -= /obj/mecha/verb/toggle_zoom
+ remove_obj_verb(src, /obj/mecha/verb/toggle_zoom)
if(!phasing_possible)
- verbs -= /obj/mecha/verb/toggle_phasing
+ remove_obj_verb(src, /obj/mecha/verb/toggle_phasing)
if(!switch_dmg_type_possible)
- verbs -= /obj/mecha/verb/switch_damtype
+ remove_obj_verb(src, /obj/mecha/verb/switch_damtype)
if(!cloak_possible)
- verbs -= /obj/mecha/verb/toggle_cloak
+ remove_obj_verb(src, /obj/mecha/verb/toggle_cloak)
occupant.in_enclosed_vehicle = 1 //Useful for when you need to know if someone is in a mecho.
update_cell_alerts()
@@ -2000,7 +2000,7 @@
occupant = null
update_appearance()
setDir(dir_in)
- verbs -= /obj/mecha/verb/eject
+ remove_obj_verb(src, /obj/mecha/verb/eject)
// Doesn't seem needed.
if(src.occupant && src.occupant.client)
diff --git a/code/game/objects/effects/debris/cleanable/humans.dm b/code/game/objects/effects/debris/cleanable/humans.dm
index f42e2a0ee72..d05f58925a1 100644
--- a/code/game/objects/effects/debris/cleanable/humans.dm
+++ b/code/game/objects/effects/debris/cleanable/humans.dm
@@ -135,7 +135,7 @@ var/global/list/image/splatter_cache=list()
user.bloody_hands += taken
user.hand_blood_color = basecolor
user.update_inv_gloves(1)
- user.verbs += /mob/living/carbon/human/proc/bloody_doodle
+ add_verb(user, /mob/living/carbon/human/proc/bloody_doodle)
/obj/effect/debris/cleanable/blood/splatter
random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5")
diff --git a/code/game/objects/items/bells.dm b/code/game/objects/items/bells.dm
index 46738e3c1e1..ca4c9a0c61d 100644
--- a/code/game/objects/items/bells.dm
+++ b/code/game/objects/items/bells.dm
@@ -45,7 +45,7 @@
// Once the player has decided their option, choose the behaviour that will happen under said option.
switch(choice)
if("examine")
- examine(user)
+ user.do_examinate(src)
if("use")
if(check_ability(user))
diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm
index 77e6f63d5e0..8f322e4bf08 100644
--- a/code/game/objects/items/bodybag.dm
+++ b/code/game/objects/items/bodybag.dm
@@ -221,7 +221,7 @@
if(syringe)
. += "It has a syringe added to it."
for(var/mob/living/L in contents)
- L.examine(user)
+ user.do_examinate(L)
/obj/structure/closet/body_bag/cryobag/attackby(obj/item/W, mob/user)
if(opened)
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index bcc7b50d825..77f48eac246 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -35,7 +35,7 @@
brightness_levels = list("low" = 0.25, "medium" = 0.5, "high" = 1)
power_usage = brightness_levels[brightness_level]
else
- verbs -= /obj/item/flashlight/verb/toggle
+ remove_obj_verb(src, /obj/item/flashlight/verb/toggle)
update_appearance()
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 8ee51935ed1..fd0de2d5a67 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -31,7 +31,7 @@ HALOGEN COUNTER - Radcount on mobs
/obj/item/healthanalyzer/Initialize(mapload)
. = ..()
if(advscan >= 1)
- verbs += /obj/item/healthanalyzer/proc/toggle_adv
+ add_obj_verb(src, /obj/item/healthanalyzer/proc/toggle_adv)
/obj/item/healthanalyzer/do_surgery(mob/living/M, mob/living/user)
if(user.a_intent != INTENT_HELP) //in case it is ever used as a surgery tool
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index c9fd42993a5..8ae9e760259 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -229,5 +229,5 @@
if(/mob/living/proc/set_size in R.verbs)
return FALSE
- R.verbs += /mob/living/proc/set_size
+ add_verb(R, /mob/living/proc/set_size)
return TRUE
diff --git a/code/game/objects/items/storage/_storage.dm b/code/game/objects/items/storage/_storage.dm
index 53460553dd5..7d2d1e1a83a 100644
--- a/code/game/objects/items/storage/_storage.dm
+++ b/code/game/objects/items/storage/_storage.dm
@@ -516,14 +516,14 @@
. = ..()
if(allow_quick_empty)
- verbs += /obj/item/storage/verb/quick_empty
+ add_obj_verb(src, /obj/item/storage/verb/quick_empty)
else
- verbs -= /obj/item/storage/verb/quick_empty
+ remove_obj_verb(src, /obj/item/storage/verb/quick_empty)
if(allow_quick_gather)
- verbs += /obj/item/storage/verb/toggle_gathering_mode
+ add_obj_verb(src, /obj/item/storage/verb/toggle_gathering_mode)
else
- verbs -= /obj/item/storage/verb/toggle_gathering_mode
+ remove_obj_verb(src, /obj/item/storage/verb/toggle_gathering_mode)
src.boxes = new /atom/movable/screen/storage( )
src.boxes.name = "storage"
diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm
index dc0f33d7915..8afe439e5c1 100644
--- a/code/game/objects/items/storage/bags.dm
+++ b/code/game/objects/items/storage/bags.dm
@@ -186,13 +186,12 @@
. += "It holds:"
for(var/ore in stored_ore)
. += "- [stored_ore[ore]] [ore]"
- return
/obj/item/storage/bag/ore/open(mob/user as mob) //No opening it for the weird UI of having shit-tons of ore inside it.
if(world.time > last_update + 10)
update_ore_count()
last_update = world.time
- examine(user)
+ user.do_examinate(src)
/obj/item/storage/bag/ore/proc/update_ore_count() //Stolen from ore boxes.
diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm
index 3dc238d69b7..d1437407eaa 100644
--- a/code/game/objects/items/storage/firstaid.dm
+++ b/code/game/objects/items/storage/firstaid.dm
@@ -254,7 +254,7 @@
/obj/item/storage/pill_bottle/Initialize(mapload)
. = ..()
if(base_icon == "pill_canister")
- verbs += /obj/item/storage/pill_bottle/proc/choose_color
+ add_obj_verb(src, /obj/item/storage/pill_bottle/proc/choose_color)
update_icon()
/obj/item/storage/pill_bottle/antitox
diff --git a/code/game/objects/items/storage/internal.dm b/code/game/objects/items/storage/internal.dm
index b9a3a8c7414..6197817efcb 100644
--- a/code/game/objects/items/storage/internal.dm
+++ b/code/game/objects/items/storage/internal.dm
@@ -7,7 +7,7 @@
/obj/item/storage/internal/Initialize(mapload)
. = ..()
master_item = loc
- verbs -= /obj/item/verb/verb_pickup //make sure this is never picked up.
+ remove_obj_verb(src, /obj/item/verb/verb_pickup) //make sure this is never picked up.
/obj/item/storage/internal/Destroy()
master_item = null
diff --git a/code/game/objects/items/weapons/implants/implantcircuits.dm b/code/game/objects/items/weapons/implants/implantcircuits.dm
index d8ce553ee6a..507c12057a7 100644
--- a/code/game/objects/items/weapons/implants/implantcircuits.dm
+++ b/code/game/objects/items/weapons/implants/implantcircuits.dm
@@ -36,7 +36,7 @@
IC.emp_act(severity)
/obj/item/implant/integrated_circuit/examine(mob/user)
- IC.examine(user)
+ return IC.examine(user)
/obj/item/implant/integrated_circuit/attackby(var/obj/item/O, var/mob/user)
if(O.is_crowbar() || istype(O, /obj/item/integrated_electronics) || istype(O, /obj/item/integrated_circuit) || O.is_screwdriver() || istype(O, /obj/item/cell/device) )
diff --git a/code/game/objects/items/weapons/implants/implantreagent_vr.dm b/code/game/objects/items/weapons/implants/implantreagent_vr.dm
index 5ddaa9dfb42..e3f4ae3f482 100644
--- a/code/game/objects/items/weapons/implants/implantreagent_vr.dm
+++ b/code/game/objects/items/weapons/implants/implantreagent_vr.dm
@@ -45,7 +45,7 @@
else
return
else
- imp_in.verbs -= assigned_proc
+ remove_verb(imp_in, assigned_proc)
return
if(reagents)
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index 4ea01c202e6..b76d8bf81cc 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -228,11 +228,11 @@
else
user.visible_message("You can't put the crystal onto the stunprod while it has a power cell installed!")
-/obj/item/melee/baton/get_description_interaction()
+/obj/item/melee/baton/get_description_interaction(mob/user)
var/list/results = list()
if(bcell)
- results += "[desc_panel_image("offhand")]to remove the weapon cell."
+ results += "[desc_panel_image("offhand", user)]to remove the weapon cell."
else
results += "[desc_panel_image("weapon cell")]to add a new weapon cell."
diff --git a/code/game/objects/items/weapons/traps.dm b/code/game/objects/items/weapons/traps.dm
index e2a51024eea..5d1762bd592 100644
--- a/code/game/objects/items/weapons/traps.dm
+++ b/code/game/objects/items/weapons/traps.dm
@@ -25,13 +25,13 @@
if(ishuman(src.loc))
var/mob/living/carbon/human/H = src.loc
if(H.wear_mask == src)
- H.verbs |= /mob/living/proc/shred_limb_temp
+ add_verb(H, /mob/living/proc/shred_limb_temp)
else
- H.verbs -= /mob/living/proc/shred_limb_temp
+ remove_verb(H, /mob/living/proc/shred_limb_temp)
..()
/obj/item/beartrap/dropped(mob/user, flags, atom/newLoc)
- user.verbs -= /mob/living/proc/shred_limb_temp
+ remove_verb(user, /mob/living/proc/shred_limb_temp)
..()
/obj/item/beartrap/suicide_act(mob/user)
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 12182ed1beb..f333d308f99 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -17,7 +17,7 @@
. = ..()
if(climbable)
- verbs += /obj/structure/proc/climb_on
+ add_obj_verb(src, /obj/structure/proc/climb_on)
if(smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK))
QUEUE_SMOOTH(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm
index 3168db1621c..4152336a47b 100644
--- a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm
+++ b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm
@@ -156,6 +156,7 @@
/obj/structure/closet/fireaxecabinet/verb/toggle_openness() //nice name, huh? HUH?! -Erro //YEAH -Agouri
set name = "Open/Close"
set category = "Object"
+ set src in oview(1)
if (isrobot(usr) || src.locked || src.smashed)
if(src.locked)
@@ -170,6 +171,7 @@
/obj/structure/closet/fireaxecabinet/verb/remove_fire_axe()
set name = "Remove Fire Axe"
set category = "Object"
+ set src in oview(1)
if (isrobot(usr))
return
diff --git a/code/game/objects/structures/dancepole.dm b/code/game/objects/structures/dancepole.dm
index de5f609d741..41a8e3b8bd9 100644
--- a/code/game/objects/structures/dancepole.dm
+++ b/code/game/objects/structures/dancepole.dm
@@ -25,11 +25,11 @@
new /obj/item/stack/material/steel(loc)
qdel(src)
-/obj/structure/dancepole/get_description_interaction()
+/obj/structure/dancepole/get_description_interaction(mob/user)
var/list/results = list()
- results += "[desc_panel_image("welder")] to deconstruct."
+ results += "[desc_panel_image("welder", user)] to deconstruct."
if(anchored)
- results += "[desc_panel_image("wrench")] to unbolt from the floor."
+ results += "[desc_panel_image("wrench", user)] to unbolt from the floor."
else
- results += "[desc_panel_image("wrench")] to anchor to the floor."
+ results += "[desc_panel_image("wrench", user)] to anchor to the floor."
return results
diff --git a/code/game/objects/structures/fence.dm b/code/game/objects/structures/fence.dm
index b07bc1bfc39..2e6e9f14dda 100644
--- a/code/game/objects/structures/fence.dm
+++ b/code/game/objects/structures/fence.dm
@@ -39,10 +39,10 @@
if(LARGE_HOLE)
. += "\The [src] has been completely cut through."
-/obj/structure/fence/get_description_interaction()
+/obj/structure/fence/get_description_interaction(mob/user)
var/list/results = list()
if(cuttable && !invulnerable && hole_size < MAX_HOLE_SIZE)
- results += "[desc_panel_image("wirecutters")]to [hole_size > NO_HOLE ? "expand the":"cut a"] hole into the fence, allowing passage."
+ results += "[desc_panel_image("wirecutters", user)]to [hole_size > NO_HOLE ? "expand the":"cut a"] hole into the fence, allowing passage."
return results
/obj/structure/fence/end
diff --git a/code/game/objects/structures/flora/trees.dm b/code/game/objects/structures/flora/trees.dm
index f4ba01a090e..43b6bd1ce49 100644
--- a/code/game/objects/structures/flora/trees.dm
+++ b/code/game/objects/structures/flora/trees.dm
@@ -129,11 +129,11 @@
adjust_health(-power / 100, TRUE) // Kills most trees in one lightning strike.
..()
-/obj/structure/flora/tree/get_description_interaction()
+/obj/structure/flora/tree/get_description_interaction(mob/user)
var/list/results = list()
if(!is_stump)
- results += "[desc_panel_image("hatchet")]to cut down this tree into logs. Any sharp and strong weapon will do."
+ results += "[desc_panel_image("hatchet", user)]to cut down this tree into logs. Any sharp and strong weapon will do."
results += ..()
diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm
index 31c720d23b5..ec51f830796 100644
--- a/code/game/objects/structures/inflatable.dm
+++ b/code/game/objects/structures/inflatable.dm
@@ -126,7 +126,7 @@
if(isobserver(usr) || usr.restrained() || !usr.Adjacent(src))
return
- verbs -= /obj/structure/inflatable/verb/hand_deflate
+ remove_obj_verb(src, /obj/structure/inflatable/verb/hand_deflate)
deflate()
/obj/structure/inflatable/attack_generic(var/mob/user, var/damage, var/attack_verb)
diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm
index fa615047e4c..e1a77b24411 100644
--- a/code/game/objects/structures/noticeboard.dm
+++ b/code/game/objects/structures/noticeboard.dm
@@ -44,7 +44,7 @@
qdel(src)
/obj/structure/noticeboard/attack_hand(var/mob/user)
- examine(user)
+ user.do_examinate(src)
// Since Topic() never seems to interact with usr on more than a superficial
// level, it should be fine to let anyone mess with the board other than ghosts.
diff --git a/code/game/objects/structures/railing.dm b/code/game/objects/structures/railing.dm
index baf35009303..81847ef91a2 100644
--- a/code/game/objects/structures/railing.dm
+++ b/code/game/objects/structures/railing.dm
@@ -26,7 +26,7 @@
if (constructed) // player-constructed railings
anchored = 0
if(climbable)
- verbs += /obj/structure/proc/climb_on
+ add_obj_verb(src, /obj/structure/proc/climb_on)
if(src.anchored)
update_icon(0)
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 1d9db11b258..857dfa31577 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -428,11 +428,11 @@
//Updates the availabiliy of the rotation verbs
/obj/structure/window/proc/update_verbs()
if(anchored || is_fulltile())
- verbs -= /obj/structure/window/verb/rotate_counterclockwise
- verbs -= /obj/structure/window/verb/rotate_clockwise
+ remove_obj_verb(src, /obj/structure/window/verb/rotate_counterclockwise)
+ remove_obj_verb(src, /obj/structure/window/verb/rotate_clockwise)
else if(!is_fulltile())
- verbs += /obj/structure/window/verb/rotate_counterclockwise
- verbs += /obj/structure/window/verb/rotate_clockwise
+ add_obj_verb(src, /obj/structure/window/verb/rotate_counterclockwise)
+ add_obj_verb(src, /obj/structure/window/verb/rotate_clockwise)
//merges adjacent full-tile windows into one (blatant ripoff from game/smoothwall.dm)
/obj/structure/window/update_icon()
diff --git a/code/game/vehicles/vehicle.dm b/code/game/vehicles/vehicle.dm
index 43500478d83..060686f3810 100644
--- a/code/game/vehicles/vehicle.dm
+++ b/code/game/vehicles/vehicle.dm
@@ -82,10 +82,10 @@
/obj/vehicle/proc/removeVerb(verb_path)
- verbs -= verb_path
+ remove_obj_verb(src, verb_path)
/obj/vehicle/proc/addVerb(verb_path)
- verbs += verb_path
+ add_obj_verb(src, verb_path)
/*/obj/vehicle/proc/add_airtank() //In airtight.dm -Agouri
internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src)
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index e9117e19859..96862c1a4c9 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -419,27 +419,27 @@ var/list/admin_verbs_event_manager = list(
/client/proc/add_admin_verbs()
if(holder)
- verbs += admin_verbs_default
- if(holder.rights & R_BUILDMODE) verbs += /client/proc/togglebuildmodeself
- if(holder.rights & R_ADMIN) verbs += admin_verbs_admin
- if(holder.rights & R_BAN) verbs += admin_verbs_ban
- if(holder.rights & R_FUN) verbs += admin_verbs_fun
- if(holder.rights & R_SERVER) verbs += admin_verbs_server
+ add_verb(src, admin_verbs_default)
+ if(holder.rights & R_BUILDMODE) add_verb(src, /client/proc/togglebuildmodeself)
+ if(holder.rights & R_ADMIN) add_verb(src, admin_verbs_admin)
+ if(holder.rights & R_BAN) add_verb(src, admin_verbs_ban)
+ if(holder.rights & R_FUN) add_verb(src, admin_verbs_fun)
+ if(holder.rights & R_SERVER) add_verb(src, admin_verbs_server)
if(holder.rights & R_DEBUG)
- verbs += admin_verbs_debug
+ add_verb(src, admin_verbs_debug)
if(config_legacy.debugparanoid && !(holder.rights & R_ADMIN))
- verbs.Remove(admin_verbs_paranoid_debug) //Right now it's just callproc but we can easily add others later on.
- if(holder.rights & R_POSSESS) verbs += admin_verbs_possess
- if(holder.rights & R_PERMISSIONS) verbs += admin_verbs_permissions
- if(holder.rights & R_STEALTH) verbs += /client/proc/stealth
- if(holder.rights & R_REJUVINATE) verbs += admin_verbs_rejuv
- if(holder.rights & R_SOUNDS) verbs += admin_verbs_sounds
- if(holder.rights & R_SPAWN) verbs += admin_verbs_spawn
- if(holder.rights & R_MOD) verbs += admin_verbs_mod
- if(holder.rights & R_EVENT) verbs += admin_verbs_event_manager
+ remove_verb(src, admin_verbs_paranoid_debug) //Right now it's just callproc but we can easily add others later on.
+ if(holder.rights & R_POSSESS) add_verb(src, admin_verbs_possess)
+ if(holder.rights & R_PERMISSIONS) add_verb(src, admin_verbs_permissions)
+ if(holder.rights & R_STEALTH) add_verb(src, /client/proc/stealth)
+ if(holder.rights & R_REJUVINATE) add_verb(src, admin_verbs_rejuv)
+ if(holder.rights & R_SOUNDS) add_verb(src, admin_verbs_sounds)
+ if(holder.rights & R_SPAWN) add_verb(src, admin_verbs_spawn)
+ if(holder.rights & R_MOD) add_verb(src, admin_verbs_mod)
+ if(holder.rights & R_EVENT) add_verb(src, admin_verbs_event_manager)
/client/proc/remove_admin_verbs()
- verbs.Remove(
+ remove_verb(src, list(
admin_verbs_default,
/client/proc/togglebuildmodeself,
admin_verbs_admin,
@@ -454,14 +454,14 @@ var/list/admin_verbs_event_manager = list(
admin_verbs_sounds,
admin_verbs_spawn,
debug_verbs
- )
+ ))
/client/proc/hide_most_verbs()//Allows you to keep some functionality while hiding some verbs
set name = "Adminverbs - Hide Most"
set category = "Admin"
- verbs.Remove(/client/proc/hide_most_verbs, admin_verbs_hideable)
- verbs += /client/proc/show_verbs
+ remove_verb(src, list(/client/proc/hide_most_verbs, admin_verbs_hideable))
+ add_verb(src, /client/proc/show_verbs)
to_chat(src, "Most of your adminverbs have been hidden.")
feedback_add_details("admin_verb","HMV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -472,7 +472,7 @@ var/list/admin_verbs_event_manager = list(
set category = "Admin"
remove_admin_verbs()
- verbs += /client/proc/show_verbs
+ add_verb(src, /client/proc/show_verbs)
to_chat(src, "Almost all of your adminverbs have been hidden.")
feedback_add_details("admin_verb","TAVVH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -482,7 +482,7 @@ var/list/admin_verbs_event_manager = list(
set name = "Adminverbs - Show"
set category = "Admin"
- verbs -= /client/proc/show_verbs
+ remove_verb(src, /client/proc/show_verbs)
add_admin_verbs()
to_chat(src, "All of your adminverbs are now visible.")
@@ -833,7 +833,7 @@ var/list/admin_verbs_event_manager = list(
log_admin("[src] re-admined themself.")
message_admins("[src] re-admined themself.", 1)
to_chat(src, "You now have the keys to control the planet, or atleast a small space station")
- verbs -= /client/proc/readmin_self
+ remove_verb(src, /client/proc/readmin_self)
/client/proc/deadmin_self()
set name = "De-admin self"
@@ -844,7 +844,7 @@ var/list/admin_verbs_event_manager = list(
message_admins("[src] deadmined themself.", 1)
deadmin()
to_chat(src, "You are now a normal player.")
- verbs |= /client/proc/readmin_self
+ add_verb(src, /client/proc/readmin_self)
feedback_add_details("admin_verb","DAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/check_ai_laws()
diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm
index de9b3d95b17..8846f40967d 100644
--- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm
+++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm
@@ -393,17 +393,15 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
return "##HALTING"
/datum/SDQL2_query/proc/generate_stat()
+ . = list()
if(!allow_admin_interact)
return
- if(!delete_click)
- delete_click = new(null, "INITIALIZING", src)
- if(!action_click)
- action_click = new(null, "INITIALIZNG", src)
- stat("[id] ", delete_click.update("DELETE QUERY | STATE : [text_state()] | ALL/ELIG/FIN \
+ STATPANEL_DATA_CLICK("[id]", "DELETE QUERY | STATE : [text_state()] | ALL/ELIG/FIN \
[islist(obj_count_all)? length(obj_count_all) : (isnull(obj_count_all)? "0" : obj_count_all)]/\
[islist(obj_count_eligible)? length(obj_count_eligible) : (isnull(obj_count_eligible)? "0" : obj_count_eligible)]/\
- [islist(obj_count_finished)? length(obj_count_finished) : (isnull(obj_count_finished)? "0" : obj_count_finished)] - [get_query_text()]"))
- stat(" ", action_click.update("[SDQL2_IS_RUNNING? "HALT" : "RUN"]"))
+ [islist(obj_count_finished)? length(obj_count_finished) : (isnull(obj_count_finished)? "0" : obj_count_finished)] - [get_query_text()]", \
+ "\ref[delete_click]")
+ STATPANEL_DATA_CLICK("", "[SDQL2_IS_RUNNING? "HALT" : "RUN"]", "\ref[action_click]")
/datum/SDQL2_query/proc/delete_click()
admin_del(usr)
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index 2893b1dda31..edf9456989e 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -88,19 +88,20 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
usr << browse(dat.Join(), "window=ahelp_list[state];size=600x480")
//Tickets statpanel
-/datum/admin_help_tickets/proc/stat_entry()
+/datum/admin_help_tickets/proc/stat_data()
+ . = list()
var/num_disconnected = 0
- stat("Active Tickets:", astatclick.update("[active_tickets.len]"))
+ STATPANEL_DATA_CLICK("Active Tickets:", "[active_tickets.len]", "\ref[astatclick]")
for(var/I in active_tickets)
var/datum/admin_help/AH = I
if(AH.initiator)
- stat("#[AH.id]. [AH.initiator_key_name]:", AH.statclick.update())
+ STATPANEL_DATA_CLICK("#[AH.id]. [AH.initiator_key_name]:", "[AH.statclick.update()]", "\ref[AH.statclick]")
else
++num_disconnected
if(num_disconnected)
- stat("Disconnected:", astatclick.update("[num_disconnected]"))
- stat("Closed Tickets:", cstatclick.update("[closed_tickets.len]"))
- stat("Resolved Tickets:", rstatclick.update("[resolved_tickets.len]"))
+ STATPANEL_DATA_CLICK("Disconnected:", "[num_disconnected]", "\ref[astatclick]")
+ STATPANEL_DATA_CLICK("Closed Tickets:", "[closed_tickets.len]", "\ref[cstatclick]")
+ STATPANEL_DATA_CLICK("Resolved Tickets:", "[resolved_tickets.len]", "\ref[rstatclick]")
//Reassociate still open ticket if one exists
/datum/admin_help_tickets/proc/ClientLogin(client/C)
@@ -479,7 +480,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/statclick/ahelp)
//
/client/proc/giveadminhelpverb()
- src.verbs |= /client/verb/adminhelp
+ add_verb(src, /client/verb/adminhelp)
deltimer(adminhelptimerid)
adminhelptimerid = 0
@@ -505,7 +506,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/statclick/ahelp)
msg = sanitize(msg)
//remove out adminhelp verb temporarily to prevent spamming of admins.
- src.verbs -= /client/verb/adminhelp
+ remove_verb(src, /client/verb/adminhelp)
adminhelptimerid = addtimer(CALLBACK(src, .proc/giveadminhelpverb), 2 MINUTES, flags = TIMER_STOPPABLE)
feedback_add_details("admin_verb","Adminhelp") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm
index 2c48594cc94..0e4a167d931 100644
--- a/code/modules/admin/verbs/mapping.dm
+++ b/code/modules/admin/verbs/mapping.dm
@@ -177,9 +177,10 @@ var/list/debug_verbs = list (
set category = "Debug"
set name = "Debug verbs"
- if(!check_rights(R_DEBUG)) return
+ if(!check_rights(R_DEBUG))
+ return
- verbs += debug_verbs
+ add_verb(src, debug_verbs)
feedback_add_details("admin_verb","mDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -187,9 +188,10 @@ var/list/debug_verbs = list (
set category = "Debug"
set name = "Hide Debug verbs"
- if(!check_rights(R_DEBUG)) return
+ if(!check_rights(R_DEBUG))
+ return
- verbs -= debug_verbs
+ remove_verb(src, debug_verbs)
feedback_add_details("admin_verb","hDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm
index 8ef3ee1198e..d2ca5b8a1d0 100644
--- a/code/modules/admin/verbs/possess.dm
+++ b/code/modules/admin/verbs/possess.dm
@@ -47,6 +47,6 @@
set desc = "Give this guy possess/release verbs"
set category = "Debug"
set name = "Give Possessing Verbs"
- M.verbs += /proc/possess
- M.verbs += /proc/release
+ add_verb(M, /proc/possess)
+ add_verb(M, /proc/release)
feedback_add_details("admin_verb","GPV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 56570203516..68aa57e2ab9 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -326,7 +326,7 @@ Ccomp's first proc.
if(config_legacy.antag_hud_allowed)
for(var/mob/observer/dead/g in get_ghosts())
if(!g.client.holder) //Remove the verb from non-admin ghosts
- g.verbs -= /mob/observer/dead/verb/toggle_antagHUD
+ remove_verb(g, /mob/observer/dead/verb/toggle_antagHUD)
if(g.antagHUD)
g.antagHUD = 0 // Disable it on those that have it enabled
g.has_enabled_antagHUD = 2 // We'll allow them to respawn
@@ -337,7 +337,7 @@ Ccomp's first proc.
else
for(var/mob/observer/dead/g in get_ghosts())
if(!g.client.holder) // Add the verb back for all non-admin ghosts
- g.verbs += /mob/observer/dead/verb/toggle_antagHUD
+ add_verb(g, /mob/observer/dead/verb/toggle_antagHUD)
to_chat(g, "The Administrator has enabled AntagHUD ") // Notify all observers they can now use AntagHUD
config_legacy.antag_hud_allowed = 1
action = "enabled"
diff --git a/code/modules/admin/view_variables/topic.dm b/code/modules/admin/view_variables/topic.dm
index 8d666c88028..54b9d537d8b 100644
--- a/code/modules/admin/view_variables/topic.dm
+++ b/code/modules/admin/view_variables/topic.dm
@@ -529,7 +529,7 @@
if(!verb || verb == "Cancel")
return
else
- H.verbs += verb
+ add_verb(H, verb)
else if(href_list["remverb"])
if(!check_rights(R_DEBUG)) return
@@ -546,7 +546,7 @@
if(!verb)
return
else
- H.verbs -= verb
+ remove_verb(H, verb)
else if(href_list["addorgan"])
if(!check_rights(R_SPAWN)) return
diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm
index 5df1586f5f2..83adb3449c2 100644
--- a/code/modules/assembly/holder.dm
+++ b/code/modules/assembly/holder.dm
@@ -178,10 +178,10 @@
update_icon()
name = initial(name) + " ([tmr.time] secs)"
- loc.verbs += /obj/item/assembly_holder/timer_igniter/verb/configure
+ add_obj_verb(src, /obj/item/assembly_holder/timer_igniter/verb/configure)
/obj/item/assembly_holder/timer_igniter/detached()
- loc.verbs -= /obj/item/assembly_holder/timer_igniter/verb/configure
+ remove_obj_verb(src, /obj/item/assembly_holder/timer_igniter/verb/configure)
..()
/obj/item/assembly_holder/timer_igniter/verb/configure()
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
index 0f58e5a70e1..fb06be8d25c 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
@@ -133,7 +133,7 @@
/obj/machinery/atmospherics/component/binary/circulator/verb/rotate_clockwise()
set name = "Rotate Circulator Clockwise"
set category = "Object"
- set src in view(1)
+ set src in oview(1)
if (usr.stat || usr.restrained() || anchored)
return
@@ -145,7 +145,7 @@
/obj/machinery/atmospherics/component/binary/circulator/verb/rotate_counterclockwise()
set name = "Rotate Circulator Counterclockwise"
set category = "Object"
- set src in view(1)
+ set src in oview(1)
if (usr.stat || usr.restrained() || anchored)
return
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pipeturbine.dm b/code/modules/atmospherics/machinery/components/binary_devices/pipeturbine.dm
index 8eb3f247940..25745efec59 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/pipeturbine.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/pipeturbine.dm
@@ -123,7 +123,7 @@
/obj/machinery/atmospherics/pipeturbine/verb/rotate_clockwise()
set name = "Rotate Turbine Clockwise"
set category = "Object"
- set src in view(1)
+ set src in oview(1)
if (usr.stat || usr.restrained() || anchored)
return
@@ -134,7 +134,7 @@
/obj/machinery/atmospherics/pipeturbine/verb/rotate_counterclockwise()
set name = "Rotate Turbine Counterclockwise"
set category = "Object"
- set src in view(1)
+ set src in oview(1)
if (usr.stat || usr.restrained() || anchored)
return
diff --git a/code/modules/blob2/overmind/overmind.dm b/code/modules/blob2/overmind/overmind.dm
index 89fec169eee..12f4b176302 100644
--- a/code/modules/blob2/overmind/overmind.dm
+++ b/code/modules/blob2/overmind/overmind.dm
@@ -61,13 +61,14 @@ var/list/overminds = list()
overminds -= src
return ..()
-/mob/observer/blob/Stat()
- ..()
- if(statpanel("Status"))
+/mob/observer/blob/statpanel_data(client/C)
+ . = ..()
+ if(C.statpanel_tab("Status"))
+ STATPANEL_DATA_LINE("")
if(blob_core)
- stat(null, "Core Health: [blob_core.integrity]")
- stat(null, "Power Stored: [blob_points]/[max_blob_points]")
- stat(null, "Total Blobs: [blobs.len]")
+ STATPANEL_DATA_LINE("Core Health: [blob_core.integrity]")
+ STATPANEL_DATA_LINE("Power Stored: [blob_points]/[max_blob_points]")
+ STATPANEL_DATA_LINE("Total Blobs: [blobs.len]")
/mob/observer/blob/Move(NewLoc, Dir = 0)
if(placed)
diff --git a/code/modules/catalogue/cataloguer_vr.dm b/code/modules/catalogue/cataloguer_vr.dm
index d04cf312a30..355c0d8630d 100644
--- a/code/modules/catalogue/cataloguer_vr.dm
+++ b/code/modules/catalogue/cataloguer_vr.dm
@@ -19,6 +19,7 @@
/obj/item/cataloguer/compact/verb/toggle()
set name = "Toggle Cataloguer"
set category = "Object"
+ set src in usr
if(busy)
to_chat(usr, SPAN_WARNING( "\The [src] is currently scanning something."))
diff --git a/code/modules/client/client.dm b/code/modules/client/client.dm
index 0a468a2f627..ceb710ef588 100644
--- a/code/modules/client/client.dm
+++ b/code/modules/client/client.dm
@@ -34,6 +34,7 @@
* is the way it is, please do update this comment
*/
parent_type = /datum
+ show_verb_panel = FALSE
//! Intrinsics
/// did New() finish?
@@ -77,11 +78,28 @@
/// temporary view active?
var/using_temporary_viewsize = FALSE
- //! menu button statuses
+ //! Datum Menus
+ /// menu button statuses
var/list/menu_buttons_checked = list()
- //! menu group statuses
+ /// menu group statuses
var/list/menu_group_status = list()
+ //! Statpanel
+ /// statpanel tab ; can be null (e.g. we're looking at verb tabs)
+ var/statpanel_tab
+ /// statpanel initialized
+ var/statpanel_ready = FALSE
+ /// turf being listed
+ var/turf/statpanel_turf
+ /// tabs the panel has
+ var/list/statpanel_tabs
+ /// statpanel variable tabs: spells / other "simple" action button frameworks
+ var/list/statpanel_spell_last
+ /// are we on byond stat? if so we can just skip the js one in data transmit (and vice versa)
+ var/statpanel_on_byond = FALSE
+ /// did we get autoswitched to byond stat for turf? if so we'll switch back when we un-list
+ var/statpanel_for_turf = FALSE
+
//! throttling
/// block re-execution of expensive verbs
var/verb_throttle = 0
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 59d392b00e8..fdb5272ee46 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -85,9 +85,16 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
log_href("[src] (usr:[usr]\[[COORD(usr)]\]) : [hsrc ? "[hsrc] " : ""][href]")
return
- //Logs all hrefs
+ //? Normal HREF handling go below
+
+ // Log
log_href("[src] (usr:[usr]\[[COORD(usr)]\]) : [hsrc ? "[hsrc] " : ""][href]")
+ // Route statpanel
+ if(href_list["statpanel"])
+ _statpanel_act(href_list["statpanel"], href_list)
+ return
+
//byond bug ID:2256651
if (asset_cache_job && (asset_cache_job in completed_asset_jobs))
to_chat(src, "An error has been detected in how your client is receiving resources. Attempting to correct.... (If you keep seeing these messages you might want to close byond and reconnect)")
@@ -126,6 +133,8 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
return prefs.process_link(usr,href_list)
if("vars")
return view_var_Topic(href,href_list,hsrc)
+ if("stat")
+ return _statpanel_act(href_list["act"], href_list)
switch(href_list["action"])
if("openLink")
@@ -178,6 +187,8 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
//! Setup user interface
// todo: move top level menu here, for now it has to be under prefs.
+ // Instantiate statpanel
+ statpanel_boot()
// Instantiate tgui panel
tgui_panel = new(src, "browseroutput")
@@ -196,7 +207,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
debug_tools_allowed = TRUE
/*
else if(GLOB.deadmins[ckey])
- verbs += /client/proc/readmin
+ add_verb(src, /client/proc/readmin)
connecting_admin = TRUE
if(CONFIG_GET(flag/autoadmin))
if(!GLOB.admin_datums[ckey])
@@ -324,6 +335,9 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
// inline_css = file2text('html/statbrowser.css'),
// )
+ //! Initialize UI
+ // initialize statbrowser
+ // (we don't, the JS does it for us. by signalling statpanel_ready().)
// Initialize tgui panel
tgui_panel.initialize()
@@ -450,6 +464,10 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
active_mousedown_item = null
SSping.currentrun -= src
+ //! cleanup UI
+ /// cleanup statbrowser
+ statpanel_dispose()
+
. = ..() //Even though we're going to be hard deleted there are still some things that want to know the destroy is happening
return QDEL_HINT_HARDDEL_NOW
diff --git a/code/modules/client/movement.dm b/code/modules/client/movement.dm
deleted file mode 100644
index efcf51c02ee..00000000000
--- a/code/modules/client/movement.dm
+++ /dev/null
@@ -1,15 +0,0 @@
-
-/client/New()
- ..()
- dir = NORTH
-
-/client/verb/spinleft()
- set name = "Spin View CCW"
- set category = "OOC"
- dir = turn(dir, 90)
-
-/client/verb/spinright()
- set name = "Spin View CW"
- set category = "OOC"
- dir = turn(dir, -90)
-
diff --git a/code/modules/client/statpanel.dm b/code/modules/client/statpanel.dm
new file mode 100644
index 00000000000..89d658d674a
--- /dev/null
+++ b/code/modules/client/statpanel.dm
@@ -0,0 +1,366 @@
+// todo: either tgui window
+// or make it an inhouse lightweight datum
+// probably the latter for minimal points of failure
+// we need to send all init & reload/reset-on-mob-login data in one
+// go, because byond does not ensure function call order
+// race conditions can cause problems where verbs get removed
+// after they get added by a remove-add turning into an add-remove.
+
+/**
+ * citadel RP stat system
+ *
+ * we use a hybrid approach
+ * most stat goes to the statpanel, which is default for users;
+ * this is a browser system that uses .js and is relatively fast for serialization/whatnot
+ * the listed turf, however, gets sent to native Stat() so it supports native mouse
+ * handling among other things.
+ */
+
+//! external - state
+
+/client/proc/statpanel_init()
+ src << output(null, "statbrowser:byond_init")
+ init_verbs()
+
+/client/proc/statpanel_check()
+ if(statpanel_ready)
+ return
+ to_chat(src, SPAN_USERDANGER("Statpanel failed to load, click here to reload the panel "))
+
+/**
+ * boots statpanel up during connect
+ */
+/client/proc/statpanel_boot()
+ // loads statbrowser if it isn't there
+ src << browse(file('html/statbrowser.html'), "window=statbrowser")
+ // if it is there and we can't tell because byond is byond, send it a signal to reload
+ src << output(null, "statbrowser:byond_reconnect")
+ // check for it incase it breaks
+ addtimer(CALLBACK(src, /client/proc/statpanel_check), 30 SECONDS)
+
+/**
+ * cleans up statpanel stuff during disconnect
+ */
+/client/proc/statpanel_dispose()
+ statpanel_ready = FALSE
+ statpanel_tab = null
+ statpanel_tabs = null
+ statpanel_spell_last = null
+ unlist_turf()
+ src << output(null, "statbrowser:byond_cleanup")
+
+/**
+ * instructs statpanel to reload
+ */
+/client/proc/statpanel_reload()
+ // this is janky as shit tbh - init_verbs shouldn't be our reset call too.
+ init_verbs(TRUE)
+
+/**
+ * only called for debug; fully reset statbrowser.
+ */
+/client/proc/statpanel_reset()
+ statpanel_dispose()
+ sleep(1)
+ src << browse("RELOADING", "window=statbrowser")
+ src << browse(file('html/statbrowser.html'), "window=statbrowser")
+ sleep(1)
+ statpanel_boot()
+
+/**
+ * called by statbrowser when it's ready
+ */
+/client/proc/statpanel_ready()
+ statpanel_tabs = list()
+ statpanel_init()
+ statpanel_ready = TRUE
+
+/**
+ * called to set/dispose admin token
+ */
+/client/proc/statpanel_token(token)
+ if(!token)
+ src << output(null, "statbrowser:byond_dispose_token")
+ return
+ src << output(token, "statbrowser:byond_grant_token")
+
+/**
+ * returns TRUE if the tab should exist and we are on the tab
+ *
+ * @params
+ * - status: use to set if the panel should exist
+ */
+/client/proc/statpanel_tab(tab, status)
+ . = (statpanel_tab == tab)
+ if(isnull(status))
+ return
+ if(tab in statpanel_tabs)
+ if(!status)
+ src << output(url_encode(tab), "statbrowser:byond_remove_tab")
+ return FALSE // removing
+ else
+ if(status)
+ src << output(url_encode(tab), "statbrowser:byond_add_tab")
+ return FALSE // don't add yet, this is unfortunate but we'll add one tick of update delay to let it add first
+
+/client/proc/list_turf(turf/T)
+ if(statpanel_turf)
+ unlist_turf()
+ if(!T || !list_turf_check(T))
+ return
+ statpanel_turf = T
+ // using byond atm
+ if(!statpanel_on_byond)
+ statpanel_for_turf = TRUE
+ statpanel_on_byond = TRUE
+ winset(src, SKIN_TAB_ID_STAT, "current-tab=[SKIN_PANE_ID_BYONDSTAT]")
+/* not using js
+ var/list/data = list()
+ for(var/atom/movable/AM as anything in T)
+ var/list/got = statpanel_encode_atom(AM)
+ if(!got)
+ continue
+ data[++data.len] = got
+ src << output("[url_encode(T.name)];[url_encode(REF(T))];[icon2html(T, src, sourceonly = TRUE)];[url_encode(json_encode(data))]", "statbrowser:byond_turf_set")
+*/
+
+/client/proc/unlist_turf()
+ // using byond atm
+ if(statpanel_for_turf)
+ statpanel_for_turf = FALSE
+ statpanel_on_byond = FALSE
+ winset(src, SKIN_TAB_ID_STAT, "current-tab=[SKIN_PANE_ID_BROWSERSTAT]")
+/* not using js
+ src << output(null, "statbrowser:byond_turf_unset")
+ UnregisterSignal(statpanel_turf, list(
+ COMSIG_ATOM_ENTERED,
+ COMSIG_ATOM_EXITED,
+ ))
+*/
+ statpanel_turf = null
+
+/client/proc/list_turf_check(turf/T)
+ return mob.TurfAdjacent(T)
+
+/**
+ * must return list(name, icon, ref).
+ */
+/client/proc/statpanel_encode_atom(atom/movable/AM)
+ RETURN_TYPE(/list)
+ if(AM.mouse_opacity == MOUSE_OPACITY_TRANSPARENT)
+ return
+ if(AM.invisibility > mob.see_invisible)
+ return
+ // not gonna bother for now - this is to prevent alt clicking to see past override image
+ // if(AM in overrides)
+ // return
+ // meanwhile this is just a shit check in a proc because it's N^2, need proper turf obscure flags.
+ // if(AM.IsObscued())
+ // return
+ return list(
+ "[AM.name]",
+ REF(AM),
+ ismob(AM) ||(length(AM.overlays) > 2)? costly_icon2html(AM, src, sourceonly = TRUE) : icon2html(AM, src, sourceonly = TRUE)
+ )
+
+/client/proc/__stat_hook_turf_enter(datum/source, atom/movable/AM)
+ var/list/got = statpanel_encode_atom(AM)
+ if(!got)
+ return
+ src << output("[url_encode(json_encode(got))]", "statbrowser:byond_turf_add")
+
+/client/proc/__stat_hook_turf_exit(datum/source, atom/movable/AM)
+ src << output("[url_encode(REF(AM))]", "statbrowser:byond_turf_del")
+
+//! external - load
+/// for legacy shit like rigsuits that didn't get the hint about not using verbs
+/client/proc/queue_legacy_verb_update()
+ if(HAS_TRAIT(src, "VERB_UPDATE_QUEUED"))
+ return
+ ADD_TRAIT(src, "VERB_UPDATE_QUEUED", "FUCK")
+ addtimer(CALLBACK(src, .proc/legacy_verb_update), 1 SECONDS)
+
+/// -_-
+/client/proc/legacy_verb_update()
+ REMOVE_TRAIT(src, "VERB_UPDATE_QUEUED", "FUCK")
+ init_verbs(FALSE)
+
+/// compiles a full list of verbs and sends it to the browser
+/client/proc/init_verbs(reset = FALSE)
+ var/list/verblist = list()
+ var/list/verbstoprocess = verbs.Copy()
+ if(mob)
+ verbstoprocess += mob.verbs
+ for(var/atom/movable/AM as anything in mob)
+ verbstoprocess += AM.verbs
+ for(var/thing in verbstoprocess)
+ var/procpath/verb_to_init = thing
+ if(verb_to_init.hidden)
+ continue
+ if(!istext(verb_to_init.category) || !verb_to_init.name)
+ continue
+ if(verb_to_init.name[1] == ".")
+ continue
+ LAZYINITLIST(verblist[verb_to_init.category])
+ verblist[verb_to_init.category] |= verb_to_init.name
+ pass()
+ src << output("[url_encode(json_encode(verblist))];[reset]", "statbrowser:byond_init_verbs")
+
+//! native
+
+/client/Stat()
+ if(!statpanel_on_byond)
+ return
+ ..() // hit mob.Stat()
+ if(!statpanel("Turf"))
+ return
+ if(!statpanel_turf)
+ stat("No turf listed ; Alt click on an adjacent turf to view contents.")
+ return
+ stat(statpanel_turf.name, statpanel_turf)
+/*
+ var/list/overrides = list()
+ for(var/image/I in client.images)
+ if(I.loc && I.loc.loc == listed_turf && I.override)
+ overrides += I.loc
+*/
+ for(var/atom/movable/AM as anything in statpanel_turf)
+ if(!AM.mouse_opacity)
+ continue
+ if(AM.invisibility > using_perspective.see_invisible)
+ continue
+// too expensive rn
+/*
+ if(overrides.len && (A in overrides))
+ continue
+*/
+// not needed rn
+/*
+ if(A.IsObscured())
+ continue
+*/
+ stat(null, AM)
+
+//! data
+
+/**
+ * the big, bad, Citadel Station in house stat proc.
+ * returns a list of "panel name" : list(entry, ...)
+ * where entry is either:
+ * 1. a text string
+ * 2. a text string associated to a value
+ */
+/datum/proc/statpanel_data(client/C)
+ return list()
+
+/client/statpanel_data(client/C)
+ var/datum/D = statobj
+ return istype(D)? D.statpanel_data(C) : list()
+
+/**
+ * acts on a statpanel action / press
+ *
+ * @params
+ * * C - who pressed us
+ * * action - (optional) action; in some cases there is none.
+ * * auth - successful admin authentication. obviously, non admins will always fail this.
+ */
+/datum/proc/statpanel_click(client/C, action, auth)
+ return
+
+/**
+ * routes actions from statpanel
+ *
+ * todo: do we move this to /datum/statpanel?
+ */
+/client/proc/_statpanel_act(action, list/params)
+ switch(action)
+ if("reload")
+ statpanel_reload()
+ return
+ if("ready")
+ statpanel_ready()
+ return
+ if("stat_click")
+ var/datum/D = locate(params["ref"])
+ if(!istype(D))
+ return
+ // todo: admin token implementation
+ D.statpanel_click(src, null, FALSE)
+ return
+ if("atom_click")
+ var/atom/A = locate(params["ref"])
+ if(!istype(A))
+ return
+ // assert: it's within a *VERY* generous range
+ if(get_dist(A, mob) > 5)
+ return
+ // todo: admin token implementation
+ var/clickparams = params["params"]
+ mob.ClickOn(A, clickparams, CLICKCHAIN_FROM_HREF)
+ return
+ // todo: mousedrag event
+
+/**
+ * grabs statpanel data to send on tick
+ */
+/client/proc/_statpanel_data()
+ . = statpanel_data(src)
+ if(!islist(.))
+ CRASH("[.] was not list.")
+
+//! verb hooks - js stat
+
+/client/verb/hook_statpanel_ready()
+ set name = ".statpanel_ready"
+ set hidden = TRUE
+ set instant = TRUE
+
+ statpanel_ready()
+
+/client/verb/hook_statpanel_add_tab(tab as text)
+ set name = ".statpanel_tab_add"
+ set hidden = TRUE
+ set instant = TRUE
+
+ statpanel_tabs |= tab
+
+/client/verb/hook_statpanel_remove_tab(tab as text)
+ set name = ".statpanel_tab_remove"
+ set hidden = TRUE
+ set instant = TRUE
+
+ statpanel_tabs -= tab
+
+/client/verb/hook_statpanel_wipe_tabs()
+ set name = ".statpanel_tab_reset"
+ set hidden = TRUE
+ set instant = TRUE
+
+ statpanel_tabs = list()
+
+/client/verb/hook_statpanel_set_tab(tab as text)
+ set name = ".statpanel_tab"
+ set hidden = TRUE
+ set instant = TRUE
+
+ statpanel_tab = tab
+
+//! verb hooks - byond stat
+
+//! verb hooks - tab switcher
+
+/client/verb/hook_statswitcher_set_tab(tab as text)
+ set name = ".statswitcher"
+ set hidden = TRUE
+ set instant = TRUE
+
+ statpanel_on_byond = (tab == "stat_pane_byond")
+
+//? Verbs - For Players
+
+/client/verb/fix_stat_panel()
+ set name = "Fix Stat Panel"
+ set category = "OOC"
+
+ statpanel_reset()
diff --git a/code/modules/client/viewport.dm b/code/modules/client/viewport.dm
index f2e49f035ab..86c41a479ed 100644
--- a/code/modules/client/viewport.dm
+++ b/code/modules/client/viewport.dm
@@ -353,13 +353,14 @@ GLOBAL_VAR(lock_client_view_y)
set name = "Fit Viewport"
set category = "OOC"
set desc = "Fit the width of the map window to match the viewport"
+
request_viewport_fit()
/client/verb/force_map_zoom(n as num)
set name = ".viewport_zoom"
set hidden = TRUE
- set src = usr
set category = "Debug"
+
if(!isnum(n) || n < 0)
to_chat(usr, SPAN_WARNING("invalid number"))
return
@@ -373,8 +374,8 @@ GLOBAL_VAR(lock_client_view_y)
/client/verb/force_map_box(n as num)
set name = ".viewport_box"
set hidden = TRUE
- set src = usr
set category = "Debug"
+
if(viewport_rwlock)
to_chat(usr, SPAN_WARNING("Viewport is rwlocked; try again later."))
return
@@ -386,8 +387,8 @@ GLOBAL_VAR(lock_client_view_y)
/client/verb/force_onresize_view_update()
set name = ".viewport_update"
set hidden = TRUE
- set src = usr
set category = "Debug"
+
if(viewport_rwlock)
to_chat(usr, SPAN_WARNING("Viewport is rwlocked; try again later."))
return
@@ -396,7 +397,6 @@ GLOBAL_VAR(lock_client_view_y)
/client/verb/show_winset_debug_values()
set name = ".viewport_debug"
set hidden = TRUE
- set src = usr
set category = "Debug"
var/divisor = text2num(winget(src, "mapwindow.map", "icon-size")) || world.icon_size
diff --git a/code/modules/client/winset_wrappers.dm b/code/modules/client/winset_wrappers.dm
index 4c467629174..1fa1a1aee21 100644
--- a/code/modules/client/winset_wrappers.dm
+++ b/code/modules/client/winset_wrappers.dm
@@ -15,3 +15,6 @@
/client/proc/_command(str)
winset(src, null, "command=[str]")
+
+/client/proc/_browse(data, window)
+ src << browse(data, window)
diff --git a/code/modules/clothing/clothing_accessories.dm b/code/modules/clothing/clothing_accessories.dm
index 16483942a03..578e814e8b5 100644
--- a/code/modules/clothing/clothing_accessories.dm
+++ b/code/modules/clothing/clothing_accessories.dm
@@ -122,7 +122,7 @@
/obj/item/clothing/proc/attach_accessory(mob/user, obj/item/clothing/accessory/A)
LAZYADD(accessories,A)
A.on_attached(src, user)
- src.verbs |= /obj/item/clothing/proc/removetie_verb
+ add_obj_verb(src, /obj/item/clothing/proc/removetie_verb)
update_accessory_slowdown()
update_worn_icon()
@@ -160,7 +160,7 @@
if(A)
remove_accessory(usr,A)
if(!LAZYLEN(accessories))
- src.verbs -= /obj/item/clothing/proc/removetie_verb
+ remove_verb(src, /obj/item/clothing/proc/removetie_verb)
accessories = null
/obj/item/clothing/emp_act(severity)
diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm
index b8d1ec06b85..ad99e348974 100644
--- a/code/modules/clothing/shoes/_shoes.dm
+++ b/code/modules/clothing/shoes/_shoes.dm
@@ -63,7 +63,7 @@
else
to_chat(usr, "Your need an empty, unbroken hand to do that.")
if(!holding)
- verbs -= /obj/item/clothing/shoes/proc/draw_knife
+ remove_obj_verb(src, /obj/item/clothing/shoes/proc/draw_knife)
update_icon()
@@ -87,7 +87,7 @@
return
holding = I
user.visible_message("\The [user] shoves \the [I] into \the [src].")
- verbs |= /obj/item/clothing/shoes/proc/draw_knife
+ add_obj_verb(src, /obj/item/clothing/shoes/proc/draw_knife)
update_icon()
else if(istype(I,/obj/item/holder/micro)) //MICROS IN MY SHOES
var/full = 0
diff --git a/code/modules/clothing/suits/eventclothing.dm b/code/modules/clothing/suits/eventclothing.dm
index 39ce6b2de67..5ecf657319a 100644
--- a/code/modules/clothing/suits/eventclothing.dm
+++ b/code/modules/clothing/suits/eventclothing.dm
@@ -106,5 +106,5 @@
if(A) //If a selection is made, call the other proc
hide_accessory(usr,A)
if(!LAZYLEN(accessories)) //But if there are no accessories, list will be empty, meaning we ought to remove access to verb
- src.verbs -= /obj/item/clothing/under/event_reward/foxmiko/verb/hidetie //Removes access to verb
+ remove_verb(src, /obj/item/clothing/under/event_reward/foxmiko/verb/hidetie) //Removes access to verb
accessories = null
diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm
index e6e097c4ce7..3ec65c94208 100644
--- a/code/modules/clothing/under/_under.dm
+++ b/code/modules/clothing/under/_under.dm
@@ -132,10 +132,10 @@
has_roll = autodetect_rolldown(detected_bodytype)
if(!has_roll)
- verbs -= /obj/item/clothing/under/verb/rollsuit
+ remove_obj_verb(src, /obj/item/clothing/under/verb/rollsuit)
worn_rolled_down = UNIFORM_ROLL_NULLED
else
- verbs |= /obj/item/clothing/under/verb/rollsuit
+ add_obj_verb(src, /obj/item/clothing/under/verb/rollsuit)
if(worn_rolled_down == UNIFORM_ROLL_NULLED)
worn_rolled_down = UNIFORM_ROLL_FALSE
if(!updating)
@@ -156,10 +156,10 @@
has_sleeves = autodetect_rollsleeve(detected_bodytype)
if(!has_sleeves)
- verbs -= /obj/item/clothing/under/verb/rollsleeves
+ remove_obj_verb(src, /obj/item/clothing/under/verb/rollsleeves)
worn_rolled_sleeves = UNIFORM_ROLL_NULLED
else
- verbs |= /obj/item/clothing/under/verb/rollsleeves
+ add_obj_verb(src, /obj/item/clothing/under/verb/rollsleeves)
if(worn_rolled_sleeves == UNIFORM_ROLL_NULLED)
worn_rolled_sleeves = UNIFORM_ROLL_FALSE
if(!updating)
diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm
index 8fafab7b1b7..caa8431cbb0 100644
--- a/code/modules/clothing/under/accessories/holster.dm
+++ b/code/modules/clothing/under/accessories/holster.dm
@@ -90,11 +90,11 @@
/obj/item/clothing/accessory/holster/on_attached(obj/item/clothing/under/S, mob/user as mob)
..()
if(has_suit)
- has_suit.verbs += /obj/item/clothing/accessory/holster/verb/holster_verb
+ add_obj_verb(has_suit, /obj/item/clothing/accessory/holster/verb/holster_verb)
/obj/item/clothing/accessory/holster/on_removed(mob/user as mob)
if(has_suit)
- has_suit.verbs -= /obj/item/clothing/accessory/holster/verb/holster_verb
+ remove_verb(has_suit, /obj/item/clothing/accessory/holster/verb/holster_verb)
..()
//For the holster hotkey
diff --git a/code/modules/detectivework/tools/evidencebag.dm b/code/modules/detectivework/tools/evidencebag.dm
index 0cf76334e8d..4c66ba858e9 100644
--- a/code/modules/detectivework/tools/evidencebag.dm
+++ b/code/modules/detectivework/tools/evidencebag.dm
@@ -92,4 +92,4 @@
/obj/item/evidencebag/examine(mob/user)
. = ..()
if(stored_item)
- stored_item.examine(user)
+ . += stored_item.examine(user)
diff --git a/code/modules/examine/descriptions/engineering.dm b/code/modules/examine/descriptions/engineering.dm
index 4e70403b1a3..c7aa2f162aa 100644
--- a/code/modules/examine/descriptions/engineering.dm
+++ b/code/modules/examine/descriptions/engineering.dm
@@ -35,44 +35,44 @@
description_info = "Click the door to open or close it. It only stops air while closed.
\
To remove these safely, use the 'deflate' verb. Hitting these with any objects will probably puncture and break it forever."
-/obj/machinery/door/get_description_interaction()
+/obj/machinery/door/get_description_interaction(mob/user)
var/list/results = list()
if(!repairing && (health < maxhealth) && !(machine_stat & BROKEN))
results += "[desc_panel_image("metal sheet")]to start repairing damage (May require different material type)."
if(repairing && density)
- results += "[desc_panel_image("welder")]to finish repairs."
- results += "[desc_panel_image("crowbar")]to undo adding sheets for repairs."
+ results += "[desc_panel_image("welder", user)]to finish repairs."
+ results += "[desc_panel_image("crowbar", user)]to undo adding sheets for repairs."
return results
-/obj/machinery/door/airlock/get_description_interaction()
+/obj/machinery/door/airlock/get_description_interaction(mob/user)
var/list/results = list()
if(can_remove_electronics())
- results += "[desc_panel_image("crowbar")]to remove the airlock electronics."
+ results += "[desc_panel_image("crowbar", user)]to remove the airlock electronics."
else
- results += "[desc_panel_image("crowbar")]to open or close if unpowered/broken, and unbolted."
+ results += "[desc_panel_image("crowbar", user)]to open or close if unpowered/broken, and unbolted."
if(welded)
- results += "[desc_panel_image("welder")]to unweld, allowing it to open again."
+ results += "[desc_panel_image("welder", user)]to unweld, allowing it to open again."
else
- results += "[desc_panel_image("welder")]to weld, preventing it from opening."
+ results += "[desc_panel_image("welder", user)]to weld, preventing it from opening."
if(p_open)
- results += "[desc_panel_image("screwdriver")]to close the wire panel."
- results += "[desc_panel_image("wirecutters")]to cut an internal wire while hacking."
- results += "[desc_panel_image("multitool")]to pulse an internal wire while hacking."
+ results += "[desc_panel_image("screwdriver", user)]to close the wire panel."
+ results += "[desc_panel_image("wirecutters", user)]to cut an internal wire while hacking."
+ results += "[desc_panel_image("multitool", user)]to pulse an internal wire while hacking."
else
- results += "[desc_panel_image("screwdriver")]to open the wire panel, enabling the ability to hack."
+ results += "[desc_panel_image("screwdriver", user)]to open the wire panel, enabling the ability to hack."
results += ..()
return results
-/obj/machinery/portable_atmospherics/canister/get_description_interaction()
+/obj/machinery/portable_atmospherics/canister/get_description_interaction(mob/user)
var/list/results = list()
- results += "[desc_panel_image("wrench")]to connect or disconnect from a connector port below."
+ results += "[desc_panel_image("wrench", user)]to connect or disconnect from a connector port below."
results += "[desc_panel_image("air tank")]to fill the air tank from this canister."
return results
diff --git a/code/modules/examine/descriptions/turfs.dm b/code/modules/examine/descriptions/turfs.dm
index feb9cb0819b..86c34a47c2c 100644
--- a/code/modules/examine/descriptions/turfs.dm
+++ b/code/modules/examine/descriptions/turfs.dm
@@ -1,33 +1,33 @@
/turf/simulated/wall
description_info = "You can build a wall by using metal sheets and making a girder, then adding more metal or plasteel."
-/turf/simulated/wall/get_description_interaction()
+/turf/simulated/wall/get_description_interaction(mob/user)
var/list/results = list()
if(damage)
- results += "[desc_panel_image("welder")]to repair."
+ results += "[desc_panel_image("welder", user)]to repair."
if(isnull(construction_stage) || !reinf_material)
- results += "[desc_panel_image("welder")]to deconstruct if undamaged."
+ results += "[desc_panel_image("welder", user)]to deconstruct if undamaged."
else
switch(construction_stage)
if(6)
- results += "[desc_panel_image("wirecutters")]to begin deconstruction."
+ results += "[desc_panel_image("wirecutters", user)]to begin deconstruction."
if(5)
results += list(
- "[desc_panel_image("screwdriver")]to continue deconstruction.",
- "[desc_panel_image("wirecutters")]to reverse deconstruction."
+ "[desc_panel_image("screwdriver", user)]to continue deconstruction.",
+ "[desc_panel_image("wirecutters", user)]to reverse deconstruction."
)
if(4)
results += list(
- "[desc_panel_image("welder")]to continue deconstruction.",
- "[desc_panel_image("screwdriver")]to reverse deconstruction."
+ "[desc_panel_image("welder", user)]to continue deconstruction.",
+ "[desc_panel_image("screwdriver", user)]to reverse deconstruction."
)
if(3)
- results += "[desc_panel_image("crowbar")]to continue deconstruction."
+ results += "[desc_panel_image("crowbar", user)]to continue deconstruction."
if(2)
- results += "[desc_panel_image("wrench")]to continue deconstruction."
+ results += "[desc_panel_image("wrench", user)]to continue deconstruction."
if(1)
- results += "[desc_panel_image("welder")]to continue deconstruction."
+ results += "[desc_panel_image("welder", user)]to continue deconstruction."
if(0)
- results += "[desc_panel_image("crowbar")]to finish deconstruction."
+ results += "[desc_panel_image("crowbar", user)]to finish deconstruction."
return results
diff --git a/code/modules/examine/examine.dm b/code/modules/examine/examine.dm
index 7abdd7f04a6..1b85b08014f 100644
--- a/code/modules/examine/examine.dm
+++ b/code/modules/examine/examine.dm
@@ -29,12 +29,12 @@
return
// This one is slightly different, in that it must return a list.
-/atom/proc/get_description_interaction()
+/atom/proc/get_description_interaction(mob/user)
return list()
// Quickly adds the boilerplate code to add an image and padding for the image.
-/proc/desc_panel_image(var/icon_state)
- return "\icon[description_icons[icon_state]][EXAMINE_PANEL_PADDING]"
+/proc/desc_panel_image(var/icon_state, mob/user)
+ return "[icon2html(description_icons[icon_state], user)][EXAMINE_PANEL_PADDING]"
/mob/living/get_description_fluff()
if(flavor_text) //Get flavor text for the green text.
@@ -53,27 +53,29 @@
description_holders["info"] = A.get_description_info()
description_holders["fluff"] = A.get_description_fluff()
description_holders["antag"] = (update_antag_info)? A.get_description_antag() : ""
- description_holders["interactions"] = A.get_description_interaction()
+ description_holders["interactions"] = A.get_description_interaction(mob)
description_holders["name"] = "[A.name]"
- description_holders["icon"] = "\icon[A]" //this is icon not icon2html
+ description_holders["icon"] = "[icon2html(A, src)]" //this is icon not icon2html
description_holders["desc"] = A.desc
-/mob/Stat()
+/mob/statpanel_data(client/C)
. = ..()
- if(client && statpanel("Examine"))
- var/description_holders = client.description_holders
- stat(null,"[description_holders["icon"]] [description_holders["name"]]") //The name, written in big letters.
- stat(null,"[description_holders["desc"]]") //the default examine text.
+ if(C.statpanel_tab("Examine", TRUE))
+ var/description_holders = C.description_holders
+ if(!description_holders)
+ return // piece of shit don't update when it's not there
+ STATPANEL_DATA_LINE("[description_holders["icon"]] [description_holders["name"]]") //The name, written in big letters.
+ STATPANEL_DATA_LINE("[description_holders["desc"]]") //the default examine text.
if(description_holders["info"])
- stat(null,"[description_holders["info"]]") //Blue, informative text.
+ STATPANEL_DATA_LINE("[description_holders["info"]]") //Blue, informative text.
if(description_holders["interactions"])
for(var/line in description_holders["interactions"])
- stat(null, "[line]")
+ STATPANEL_DATA_LINE("[line]")
if(description_holders["fluff"])
- stat(null,"[description_holders["fluff"]]") //Yellow, fluff-related text.
+ STATPANEL_DATA_LINE("[description_holders["fluff"]]") //Yellow, fluff-related text.
if(description_holders["antag"])
- stat(null,"[description_holders["antag"]]") //Red, malicious antag-related text
+ STATPANEL_DATA_LINE("[description_holders["antag"]]") //Red, malicious antag-related text
//override examinate verb to update description holders when things are examined
/mob/examinate(atom/A as mob|obj|turf in view())
diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm
index 604f69e1b45..4ed8972f785 100644
--- a/code/modules/fishing/fishing_rod.dm
+++ b/code/modules/fishing/fishing_rod.dm
@@ -37,7 +37,7 @@
. = ..()
if(Bait)
. += "\The [src] has \the [Bait] hanging on its hook."
- Bait.examine(user)
+ . += Bait.examine(user)
/obj/item/material/fishing_rod/CtrlClick(mob/user)
if((src.loc == user || Adjacent(user)) && Bait)
diff --git a/code/modules/food/kitchen/cooking_machines/_appliance.dm b/code/modules/food/kitchen/cooking_machines/_appliance.dm
index 259f34987b0..0b02b550462 100644
--- a/code/modules/food/kitchen/cooking_machines/_appliance.dm
+++ b/code/modules/food/kitchen/cooking_machines/_appliance.dm
@@ -53,7 +53,7 @@
component_parts += /obj/item/stock_parts/matter_bin
component_parts += /obj/item/stock_parts/matter_bin
if(output_options.len)
- verbs += /obj/machinery/appliance/proc/choose_output
+ add_obj_verb(src, /obj/machinery/appliance/proc/choose_output)
if (!available_recipes)
available_recipes = new
diff --git a/code/modules/hydroponics/trays/tray_soil.dm b/code/modules/hydroponics/trays/tray_soil.dm
index dd39be4f76f..77d9069caed 100644
--- a/code/modules/hydroponics/trays/tray_soil.dm
+++ b/code/modules/hydroponics/trays/tray_soil.dm
@@ -15,9 +15,9 @@
/obj/machinery/portable_atmospherics/hydroponics/soil/Initialize(mapload)
. = ..()
- verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/close_lid_verb
- verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/remove_label
- verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/setlight
+ remove_obj_verb(src, /obj/machinery/portable_atmospherics/hydroponics/verb/close_lid_verb)
+ remove_obj_verb(src, /obj/machinery/portable_atmospherics/hydroponics/verb/remove_label)
+ remove_obj_verb(src, /obj/machinery/portable_atmospherics/hydroponics/verb/setlight)
// Holder for vine plants.
// Icons for plants are generated as overlays, so setting it to invisible wouldn't work.
diff --git a/code/modules/icon generation/Bluespaced.dm b/code/modules/icon generation/Bluespaced.dm
deleted file mode 100644
index 697b9e97196..00000000000
--- a/code/modules/icon generation/Bluespaced.dm
+++ /dev/null
@@ -1,243 +0,0 @@
-/proc/bsi_cast_ray(icon/I, list/start, list/end)
-
- if(abs(start[1] - end[1]) > abs(start[2] - end[2]))
- var/dist = abs(start[1] - end[1]) * 2
-
- for(var/i = 1, i <= dist, i++)
- var/x = round((start[1] * i / dist) + (end[1] * (1 - i / dist)))
- var/y = round((start[2] * i / dist) + (end[2] * (1 - i / dist)))
-
- if(I.GetPixel(x, y) != null)
- return list(x, y)
-
- else
- var/dist = abs(start[2] - end[2]) * 2
-
- for(var/i = 1, i <= dist, i++)
- var/x = round((start[1] * i / dist) + (end[1] * (1 - i / dist)))
- var/y = round((start[2] * i / dist) + (end[2] * (1 - i / dist)))
-
- if(I.GetPixel(x, y) != null)
- return list(x, y)
-
- return null
-
-/proc/bsi_split_colors(color)
- if(color == null)
- return list(0, 0, 0, 0)
-
- var/list/colors = list(0, 0, 0, 0)
- colors[1] = hex2num(copytext(color, 2, 4))
- colors[2] = hex2num(copytext(color, 4, 6))
- colors[3] = hex2num(copytext(color, 6, 8))
- colors[4] = (length(color) > 7)? hex2num(copytext(color, 8, 10)) : 255
-
- return colors
-
-/proc/bsi_spread(icon/I, list/start_point)
- var/list/queue = list()
- queue[++queue.len] = start_point
-
- var/i = 0
-
- while(i++ < length(queue))
- var/x = queue[i][1]
- var/y = queue[i][2]
-
- var/list/pixel = bsi_split_colors(I.GetPixel(x, y))
- if(pixel[4] == 0)
- continue
-
- var/list/n = (y < I.Height())? bsi_split_colors(I.GetPixel(x, y + 1)) : list(0, 0, 0, 0)
- var/list/s = (y > 1)? bsi_split_colors(I.GetPixel(x, y - 1)) : list(0, 0, 0, 0)
- var/list/e = (x < I.Width())? bsi_split_colors(I.GetPixel(x + 1, y)) : list(0, 0, 0, 0)
- var/list/w = (x > 1)? bsi_split_colors(I.GetPixel(x - 1, y)) : list(0, 0, 0, 0)
-
- var/value = (i == 1)? 16 : max(n[1] - 1, e[1] - 1, s[1] - 1, w[1] - 1)
-
- if(prob(50))
- value = max(0, value - 1)
-
- if(prob(50))
- value = max(0, value - 1)
-
- if(prob(50))
- value = max(0, value - 1)
-
- if(value <= pixel[1])
- continue
-
- var/v2 = 256 - ((16 - value) * (16 - value))
-
- I.DrawBox(rgb(value, v2, pixel[4] - v2, pixel[4]), x, y)
-
- if(n[4] != 0 && n[1] < value - 1)
- queue[++queue.len] = list(x, y + 1)
-
- if(s[4] != 0 && s[1] < value - 1)
- queue[++queue.len] = list(x, y - 1)
-
- if(e[4] != 0 && e[1] < value - 1)
- queue[++queue.len] = list(x + 1, y)
-
- if(w[4] != 0 && w[1] < value - 1)
- queue[++queue.len] = list(x - 1, y)
-
-
-
-
-
-/proc/bsi_generate_mask(icon/source, state)
- var/icon/mask = icon(source, state)
-
- mask.MapColors(
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 1, 1,
- 0, 0, 0, 0)
-
- var/hits = 0
-
- for(var/i = 1, i <= 10, i++)
- var/point1
- var/point2
-
- if(prob(50))
- if(prob(50))
- point1 = list(rand(1, mask.Width()), mask.Height())
- point2 = list(rand(1, mask.Width()), 1)
-
- else
- point2 = list(rand(1, mask.Width()), mask.Height())
- point1 = list(rand(1, mask.Width()), 1)
-
- else
- if(prob(50))
- point1 = list(mask.Width(), rand(1, mask.Height()))
- point2 = list(1, rand(1, mask.Height()))
-
- else
- point2 = list(mask.Width(), rand(1, mask.Height()))
- point1 = list(1, rand(1, mask.Height()))
-
- var/hit = bsi_cast_ray(mask, point1, point2)
-
- if(hit == null)
- continue
-
- hits++
-
- bsi_spread(mask, hit)
-
- if(prob(20 + hits * 20))
- break
-
- if(hits == 0)
- return null
-
- else
- return mask
-
-/proc/generate_bluespace_icon(icon/source, state)
-
- var/icon/mask = bsi_generate_mask(source, state)
-
- if(mask == null)
- return source
-
- var/icon/unaffected = icon(mask)
- unaffected.MapColors(
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 1,
- 0, 0, 0, 0,
- 255, 255, 255, 0)
-
- var/icon/temp = icon(source, state) //Mask already contains the original alpha values, avoid squaring them
- temp.MapColors(
- 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 255)
-
- unaffected.Blend(temp, ICON_MULTIPLY)
-
- var/icon/bluespaced = icon(mask)
- bluespaced.MapColors(
- 0, 0, 0, 0,
- 0, 0, 0, 1,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 1, 1, 1, 0)
-
- bluespaced.Blend(icon(source, state), ICON_MULTIPLY)
-
- var/list/frames = list(
- list(0.000,20),
- list(0.020, 5),
- list(0.050, 4),
- list(0.080, 5),
- list(0.100,10),
- list(0.080, 5),
- list(0.050, 4),
- list(0.020, 5),
-
- list(0.000,20),
- list(0.020, 5),
- list(0.050, 4),
- list(0.080, 5),
- list(0.100,10),
- list(0.080, 5),
- list(0.050, 4),
- list(0.020, 5),
-
- list(0.000,20),
- list(0.020, 5),
- list(0.050, 4),
- list(0.080, 5),
- list(0.100,10),
- list(0.080, 5),
- list(0.050, 4),
- list(0.020, 5),
- )
-
- var/list/colors = list(
- list( 75, 75, 75, 0),
- list( 25, 25, 25, 0),
- list( 75, 75, 75, 0),
- list( 25, 25, 75, 0),
- list( 75, 75, 300, 0),
- list( 25, 25, 300, 0),
- list(255, 255, 255, 0),
- list( 0, 0, 0, 255),
- list( 0, 0, 0, 0),
- list( 0, 0, 0, 0),
- )
-
- for(var/i = 1, i <= rand(1, 5), i++)
- var/f = rand(1, length(frames))
-
- if(frames[f][2] > 1)
- frames[f][2]--
- frames.Insert(f, 0)
-
- frames[f] = list(0.8, 1)
-
- var/icon/result = generate_color_animation(bluespaced, colors, frames)
- result.Blend(unaffected, ICON_UNDERLAY)
-
- return result
-
-
-
-/atom/verb/test()
- set src in view()
- src.icon = generate_bluespace_icon(src.icon, src.icon_state)
-
-/mob/verb/bluespam()
- for(var/turf/t in view(5))
- var/obj/s = new /obj/square(t)
- s.icon = generate_bluespace_icon(s.icon, s.icon_state)
-
diff --git a/code/modules/icon generation/Icon_color_animation.dm b/code/modules/icon generation/Icon_color_animation.dm
deleted file mode 100644
index 1be1bfa28a9..00000000000
--- a/code/modules/icon generation/Icon_color_animation.dm
+++ /dev/null
@@ -1,96 +0,0 @@
-//----------------------------------------
-//
-// Return a copy of the provided icon,
-// after calling MapColors on it. The
-// color values are linearily interpolated
-// between the pairs provided, based on
-// the ratio argument.
-//
-//----------------------------------------
-
-/proc/MapColors_interpolate(icon/input, ratio,
- rr1, rg1, rb1, ra1, rr2, rg2, rb2, ra2,
- gr1, gg1, gb1, ga1, gr2, gg2, gb2, ga2,
- br1, bg1, bb1, ba1, br2, bg2, bb2, ba2,
- ar1, ag1, ab1, aa1, ar2, ag2, ab2, aa2,
- zr1, zg1, zb1, za1, zr2, zg2, zb2, za2)
- var/r = ratio
- var/i = 1 - ratio
- var/icon/I = icon(input)
-
- I.MapColors(
- (rr1 * r + rr2 * i) / 255.0, (rg1 * r + rg2 * i) / 255.0, (rb1 * r + rb2 * i) / 255.0, (ra1 * r + ra2 * i) / 255.0,
- (gr1 * r + gr2 * i) / 255.0, (gg1 * r + gg2 * i) / 255.0, (gb1 * r + gb2 * i) / 255.0, (ga1 * r + ga2 * i) / 255.0,
- (br1 * r + br2 * i) / 255.0, (bg1 * r + bg2 * i) / 255.0, (bb1 * r + bb2 * i) / 255.0, (ba1 * r + ba2 * i) / 255.0,
- (ar1 * r + ar2 * i) / 255.0, (ag1 * r + ag2 * i) / 255.0, (ab1 * r + ab2 * i) / 255.0, (aa1 * r + aa2 * i) / 255.0,
- (zr1 * r + zr2 * i) / 255.0, (zg1 * r + zg2 * i) / 255.0, (zb1 * r + zb2 * i) / 255.0, (za1 * r + za2 * i) / 255.0)
-
- return I
-
-
-
-
-//----------------------------------------
-//
-// Extension of the above that takes a
-// list of lists of color values, rather
-// than a large number of arguments.
-//
-//----------------------------------------
-
-/proc/MapColors_interpolate_list(icon/I, ratio, list/colors)
- var/list/c[10]
-
- //Provide default values for any missing colors (without altering the original list
- for(var/i = 1, i <= 10, i++)
- c[i] = list(0, 0, 0, (i == 7 || i == 8)? 255 : 0)
-
- if(istype(colors[i], /list))
- for(var/j = 1, j <= 4, j++)
- if(j <= length(colors[i]) && isnum(colors[i][j]))
- c[i][j] = colors[i][j]
-
- return MapColors_interpolate(I, ratio,
- colors[ 1][1], colors[ 1][2], colors[ 1][3], colors[ 1][4], // Red 1
- colors[ 2][1], colors[ 2][2], colors[ 2][3], colors[ 2][4], // Red 2
- colors[ 3][1], colors[ 3][2], colors[ 3][3], colors[ 3][4], // Green 1
- colors[ 4][1], colors[ 4][2], colors[ 4][3], colors[ 4][4], // Green 2
- colors[ 5][1], colors[ 5][2], colors[ 5][3], colors[ 5][4], // Blue 1
- colors[ 6][1], colors[ 6][2], colors[ 6][3], colors[ 6][4], // Blue 2
- colors[ 7][1], colors[ 7][2], colors[ 7][3], colors[ 7][4], // Alpha 1
- colors[ 8][1], colors[ 8][2], colors[ 8][3], colors[ 8][4], // Alpha 2
- colors[ 9][1], colors[ 9][2], colors[ 9][3], colors[ 9][4], // Added 1
- colors[10][1], colors[10][2], colors[10][3], colors[10][4]) // Added 2
-
-
-
-
-
-//----------------------------------------
-//
-// Take the source image, and return an animated
-// version, that transitions between the provided
-// color mappings, according to the provided
-// pattern.
-//
-// Colors should be in a format suitable for
-// MapColors_interpolate_list, and frames should
-// be a list of 'frames', where each frame is itself
-// a list, element 1 being the ratio of the first
-// color to the second, and element 2 being how
-// long the frame lasts, in tenths of a second.
-//
-//----------------------------------------
-
-/proc/generate_color_animation(icon/icon, list/colors, list/frames)
- var/icon/out = icon('icons/effects/uristrunes.dmi', "")
- var/frame_num = 1
-
- for(var/frame in frames)
- var/icon/I = MapColors_interpolate_list(icon, frame[1], colors)
- out.Insert(I, "", 2, frame_num++, 0, frame[2])
-
- return out
-
-
-
diff --git a/code/modules/icon generation/Uristrunes.dm b/code/modules/icon generation/Uristrunes.dm
deleted file mode 100644
index 8dfe135a72f..00000000000
--- a/code/modules/icon generation/Uristrunes.dm
+++ /dev/null
@@ -1,268 +0,0 @@
-//----------------------------------------
-//
-// Take a source icon, convert into a mask,
-// then create a border around it.
-//
-// The output then uses the colors and
-// alpha values provided.
-//
-//----------------------------------------
-
-/proc/create_border_image(icon/input, border_color = "#000000", fill_color = "#000000", border_alpha = 255, fill_alpha = 255)
- var/icon/I = icon('icons/effects/uristrunes.dmi', "blank")
- I.Blend(input, ICON_OVERLAY)
-
- //Discard the image
- I.MapColors(0, 0, 0, 0, //-\ Ignore
- 0, 0, 0, 0, //--> The
- 0, 0, 0, 0, //-/ Colors
- 0,255, 0, 1, //Keep alpha channel, any pixel with non-zero alpha gets max green channel
- 0, 0, 0, 0)
-
- //Loop over the image, calculating the border value, and storing it in the red channel
- //Store border's alpha in the blue channel
- for(var/x = 1, x <= 32, x++)
- for(var/y = 1, y <= 32, y++)
- var/p = I.GetPixel(x, y)
-
- if(p == null)
- var/n = I.GetPixel(x, y + 1)
- var/s = I.GetPixel(x, y - 1)
- var/e = I.GetPixel(x + 1, y)
- var/w = I.GetPixel(x - 1, y)
- var/ne = I.GetPixel(x + 1, y + 1)
- var/se = I.GetPixel(x + 1, y - 1)
- var/nw = I.GetPixel(x - 1, y + 1)
- var/sw = I.GetPixel(x - 1, y - 1)
-
- var/sum_adj = ((n == "#00ff00"? 1 : 0) \
- + (s == "#00ff00"? 1 : 0) \
- + (e == "#00ff00"? 1 : 0) \
- + (w == "#00ff00"? 1 : 0))
-
- var/sum_diag = ((ne == "#00ff00"? 1 : 0) \
- + (se == "#00ff00"? 1 : 0) \
- + (nw == "#00ff00"? 1 : 0) \
- + (sw == "#00ff00"? 1 : 0))
-
-
- if(sum_adj)
- I.DrawBox(rgb(255, 0, 200, 0), x, y)
-
- else if(sum_diag)
- I.DrawBox(rgb(255, 0, 100, 0), x, y)
-
- else
- I.DrawBox(rgb(0, 0, 0, 0), x, y)
-
- else if(p != "#00ff00")
- var/a = 255
-
- if(length(p) == 9) // "#rrggbbaa", we want the aa
- a = hex2num(copytext(p, 8))
-
- I.DrawBox(rgb(255 - a, a, 255 - a, a), x, y)
-
- //Map the red and green channels to the desired output colors
- I.MapColors(border_color, fill_color, rgb(0, 0, 0, border_alpha), rgb(0, 0, 0, fill_alpha), "#00000000")
-
- return I
-
-
-
-
-//----------------------------------------
-//
-// Take a source icon, convert into a mask,
-// and border. Color them according to args,
-// and animate.
-//
-//----------------------------------------
-
-/proc/animate_rune_full(icon/input, rr1, rg1, rb1, ra1, rr2, rg2, rb2, ra2, br1, bg1, bb1, ba1, br2, bg2, bb2, ba2, ar1, ag1, ab1, aa1, ar2, ag2, ab2, aa2, or1, og1, ob1, oa1, or2, og2, ob2, oa2, frames)
-
- var/list/colors[10]
- colors[ 1] = list(rr1, rg1, rb1, ra1) //Rune color 1
- colors[ 2] = list(rr2, rg2, rb2, ra2) //Rune color 2
- colors[ 3] = list(br1, bg1, bb1, ba1) //Border color 1
- colors[ 4] = list(br2, bg2, bb2, ba2) //Border color 2
- colors[ 5] = list( 0, 0, 0, 0) //Unused
- colors[ 6] = list( 0, 0, 0, 0) //Unused
- colors[ 7] = list(ar1, ag1, ab1, aa1) //Alpha color 1
- colors[ 8] = list(ar2, ag2, ab2, aa2) //Alpha color 2
- colors[ 9] = list(or1, og1, ob1, oa1) //Added color 1
- colors[10] = list(or2, og2, ob2, oa2) //Added color 2
-
- var/icon/base = create_border_image(input, "#00ff0000", "#ff000000")
-
- return generate_color_animation(base, colors, frames)
-
-
-
-
-//----------------------------------------
-//
-// Calls the above, but accepts colors in
-// the form of "#RRGGBBAA", and provides
-// default values.
-//
-// Main limit is that it doesn't accept
-// negative values, which you probably
-// don't need anyway. Also missing a few
-// color inputs, which would also be rarely
-// used.
-//
-//----------------------------------------
-
-
-/proc/animate_rune(icon/input, rune_color = "#00000000", border_color = "#c8000000", rune_color2 = "#00000000", border_color2 = "#d8380000", alpha = 255, alpha2 = 255, frames = rune_animation)
- var/rr1 = hex2num(copytext(rune_color, 2, 4))
- var/rg1 = hex2num(copytext(rune_color, 4, 6))
- var/rb1 = hex2num(copytext(rune_color, 6, 8))
- var/ra1 = hex2num(copytext(rune_color, 8, 10))
- var/rr2 = hex2num(copytext(rune_color2, 2, 4))
- var/rg2 = hex2num(copytext(rune_color2, 4, 6))
- var/rb2 = hex2num(copytext(rune_color2, 6, 8))
- var/ra2 = hex2num(copytext(rune_color2, 8, 10))
- var/br1 = hex2num(copytext(border_color, 2, 4))
- var/bg1 = hex2num(copytext(border_color, 4, 6))
- var/bb1 = hex2num(copytext(border_color, 6, 8))
- var/ba1 = hex2num(copytext(border_color, 8, 10))
- var/br2 = hex2num(copytext(border_color2, 2, 4))
- var/bg2 = hex2num(copytext(border_color2, 4, 6))
- var/bb2 = hex2num(copytext(border_color2, 6, 8))
- var/ba2 = hex2num(copytext(border_color2, 8, 10))
-
- return animate_rune_full(input, rr1, rg1, rb1, ra1, rr2, rg2, rb2, ra2, br1, bg1, bb1, ba1, br2, bg2, bb2, ba2, 0, 0, 0, alpha, 0, 0, 0, alpha2, 0, 0, 0, 0, 0, 0, 0, 0, frames)
-
-
-/proc/inanimate_rune(icon/input, rune_color = "#00000000", border_color = "#c8000000")
- var/icon/base = create_border_image(input, "#00ff0000", "#ff000000")
-
- base.MapColors(rune_color, border_color, "#00000000", "#000000ff", "#00000000")
-
- return base
-
-var/list/rune_animation = list(
- list(0.000, 5),
- list(0.020, 1),
- list(0.050, 1),
- list(0.090, 1),
- list(0.140, 1),
- list(0.200, 1),
- list(0.270, 1),
- list(0.340, 1),
- list(0.420, 1),
- list(0.500, 1),
- list(0.590, 1),
- list(0.675, 1),
- list(0.750, 1),
- list(0.900, 1),
- list(1.000, 6),
- list(0.875, 1),
- list(0.750, 1),
- list(0.625, 1),
- list(0.500, 1),
- list(0.375, 1),
- list(0.250, 1),
- list(0.125, 1),
- )
-
-/var/list/rune_cache = list()
-
-/proc/get_rune(rune_bits, animated = 0)
- var/lookup = "[rune_bits]-[animated]"
-
- if(lookup in rune_cache)
- return rune_cache[lookup]
-
- var/icon/base = icon('icons/effects/uristrunes.dmi', "")
-
- for(var/i = 0, i < 10, i++)
- if(BITTEST(rune_bits, i))
- base.Blend(icon('icons/effects/uristrunes.dmi', "rune-[1 << i]"), ICON_OVERLAY)
-
- var/icon/result
-
- if(animated == 1)
- result = animate_rune(base)
-
- else
- result = inanimate_rune(base)
-
- rune_cache[lookup] = result
- return result
-
-
-
-
-
-// Testing procs and Fun procs
-
-
-
-
-/mob/verb/create_rune()
- var/obj/o = new(locate(x, y, z))
- o.icon = get_rune(rand(1, 1023), 1)
-
-/mob/verb/runes_15x15()
- for(var/turf/t in range(7))
- var/obj/o = new /obj(t)
- o.icon = get_rune(rand(1, 1023), 1)
-
-
-/*
-/mob/verb/create_rune_custom(rune as num, color1 as color, border1 as color, color2 as color, border2 as color, alpha1 as num, alpha2 as num)
- var/icon/I = icon('icons/effects/uristrunes.dmi', "blank")
-
- for(var/i = 0, i < 10, i++)
- if(BITTEST(rune, i))
- I.Blend(icon('icons/effects/uristrunes.dmi', "rune-[1 << i]"), ICON_OVERLAY)
-
- var/obj/o = new(locate(x, y, z))
- o.icon = animate_rune(I, color1, border1, color2, border2, alpha1, alpha2)
-
-/mob/verb/spam()
- for(var/turf/t in range(4))
- var/icon/I = icon('icons/effects/uristrunes.dmi', "blank")
-
- var/rune = rand(1, 1023)
- for(var/i = 0, i < 10, i++)
- if(BITTEST(rune, i))
- I.Blend(icon('icons/effects/uristrunes.dmi', "rune-[1 << i]"), ICON_OVERLAY)
-
- var/obj/o = new(t)
- o.icon = animate_rune_full(I, rand(0, 255), rand(0, 255), rand(0, 255), rand(-255, 255),
- rand(0, 255), rand(0, 255), rand(0, 255), rand(-255, 255),
- rand(0, 255), rand(0, 255), rand(0, 255), rand(-255, 255),
- rand(0, 255), rand(0, 255), rand(0, 255), rand(-255, 255),
- 0, 0, 0, rand(0, 255),
- 0, 0, 0, rand(0, 255),
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- list(
- list(0.000, 5),
- list(0.020, 1),
- list(0.050, 1),
- list(0.090, 1),
- list(0.140, 1),
- list(0.200, 1),
- list(0.270, 1),
- list(0.340, 1),
- list(0.420, 1),
- list(0.500, 1),
- list(0.590, 1),
- list(0.675, 1),
- list(0.750, 1),
- list(0.900, 1),
- list(1.000, 6),
- list(0.875, 1),
- list(0.750, 1),
- list(0.625, 1),
- list(0.500, 1),
- list(0.375, 1),
- list(0.250, 1),
- list(0.125, 1),
- ))
-*/
diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm
index 30be49f9375..60ea98e9650 100644
--- a/code/modules/integrated_electronics/core/assemblies.dm
+++ b/code/modules/integrated_electronics/core/assemblies.dm
@@ -309,6 +309,7 @@
set name = "Rename Circuit"
set category = "Object"
set desc = "Rename your circuit, useful to stay organized."
+ set src in usr
var/mob/M = usr
var/input = tgui_input_text(usr, "What do you want to name this?", "Rename", src.name, MAX_NAME_LEN)
diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm
index 462cca116b0..ee121804748 100644
--- a/code/modules/integrated_electronics/core/integrated_circuit.dm
+++ b/code/modules/integrated_electronics/core/integrated_circuit.dm
@@ -117,6 +117,7 @@ a creative player the means to solve many problems. Circuits are held inside an
set name = "Rename Circuit"
set category = "Object"
set desc = "Rename your circuit, useful to stay organized."
+ set src in usr
var/mob/M = usr
var/input = tgui_input_text(usr, "What do you want to name this circuit?", "Rename", src.name, MAX_NAME_LEN)
diff --git a/code/modules/maps/away_missions/archive/wildwest.dm b/code/modules/maps/away_missions/archive/wildwest.dm
index 05adea48cfd..393fb5ab77c 100644
--- a/code/modules/maps/away_missions/archive/wildwest.dm
+++ b/code/modules/maps/away_missions/archive/wildwest.dm
@@ -69,7 +69,7 @@
if("Immortality")
to_chat(user, "Your wish is granted, but at a terrible cost...")
to_chat(user, "The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart.")
- user.verbs += /mob/living/carbon/proc/immortality
+ add_verb(user, /mob/living/carbon/proc/immortality)
user.dna.mutantrace = "shadow"
user.update_mutantrace()
if("To Kill")
diff --git a/code/modules/mining/shelter_atoms.dm b/code/modules/mining/shelter_atoms.dm
index b47bc835dc3..d77756aae00 100644
--- a/code/modules/mining/shelter_atoms.dm
+++ b/code/modules/mining/shelter_atoms.dm
@@ -167,8 +167,8 @@
/obj/structure/table/survival_pod/Initialize(mapload)
material = get_material_by_name(MAT_STEEL)
- verbs -= /obj/structure/table/verb/do_flip
- verbs -= /obj/structure/table/proc/do_put
+ remove_obj_verb(src, /obj/structure/table/verb/do_flip)
+ remove_obj_verb(src, /obj/structure/table/proc/do_put)
return ..()
/obj/structure/table/survival_pod/dismantle(obj/item/tool/wrench/W, mob/user)
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 3dfe8403be0..a9c937ddafc 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -100,7 +100,7 @@
see_invisible = SEE_INVISIBLE_OBSERVER
see_in_dark = world.view //I mean. I don't even know if byond has occlusion culling... but...
plane = PLANE_GHOSTS //Why doesn't the var above work...???
- verbs += /mob/observer/dead/proc/dead_tele
+ add_verb(src, /mob/observer/dead/proc/dead_tele)
var/turf/T
if(ismob(body))
@@ -215,7 +215,7 @@ Works together with spawning an observer, noted above.
if(ghost.client)
ghost.client.time_died_as_mouse = ghost.timeofdeath
if(ghost.client && !ghost.client.holder && !config_legacy.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
- ghost.verbs -= /mob/observer/dead/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
+ remove_verb(ghost, /mob/observer/dead/verb/toggle_antagHUD) // Poor guys, don't know what they are missing!
ghost.client?.holder?.update_stealth_ghost()
return ghost
@@ -254,16 +254,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
ghost.set_respawn_timer()
announce_ghost_joinleave(ghost)
-/mob/observer/dead/can_use_hands() return 0
-/mob/observer/dead/is_active() return 0
+/mob/observer/dead/can_use_hands()
+ return 0
-/mob/observer/dead/Stat()
- ..()
- if(statpanel("Status"))
- if(SSemergencyshuttle)
- var/eta_status = SSemergencyshuttle.get_status_panel_eta()
- if(eta_status)
- stat(null, eta_status)
+/mob/observer/dead/is_active()
+ return 0
/mob/observer/dead/verb/reenter_corpse()
set category = "Ghost"
@@ -621,8 +616,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/observer/dead/proc/manifest(mob/user)
is_manifest = TRUE
- verbs |= /mob/observer/dead/proc/toggle_visibility
- verbs |= /mob/observer/dead/proc/ghost_whisper
+ add_verb(src, /mob/observer/dead/proc/toggle_visibility)
+ add_verb(src, /mob/observer/dead/proc/ghost_whisper)
to_chat(src,"As you are now in the realm of the living, you can whisper to the living with the Spectral Whisper verb, inside the IC tab.")
if(plane != PLANE_WORLD)
user.visible_message( \
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index b4af682b10e..16769961281 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -53,8 +53,8 @@
/mob/living/carbon/alien/Initialize(mapload)
time_of_birth = world.time
- verbs += /mob/living/proc/ventcrawl
- verbs += /mob/living/proc/hide
+ add_verb(src, /mob/living/proc/ventcrawl)
+ add_verb(src, /mob/living/proc/hide)
instance_num = rand(1, 1000)
name = "[initial(name)] ([instance_num])"
@@ -68,9 +68,10 @@
return ..()
-/mob/living/carbon/alien/Stat()
- ..()
- stat(null, "Progress: [amount_grown]/[max_grown]")
+/mob/living/carbon/alien/statpanel_data(client/C)
+ . = ..()
+ STATPANEL_DATA_LINE("")
+ STATPANEL_DATA_LINE("Progress: [amount_grown]/[max_grown]")
/mob/living/carbon/alien/restrained()
return 0
diff --git a/code/modules/mob/living/carbon/alien/diona/diona.dm b/code/modules/mob/living/carbon/alien/diona/diona.dm
index a97e68e0371..029c669f9cb 100644
--- a/code/modules/mob/living/carbon/alien/diona/diona.dm
+++ b/code/modules/mob/living/carbon/alien/diona/diona.dm
@@ -25,7 +25,7 @@
species = SScharacters.resolve_species_path(/datum/species/diona)
add_language(LANGUAGE_ROOTGLOBAL)
add_language(LANGUAGE_GALCOM)
- verbs += /mob/living/carbon/alien/diona/proc/merge
+ add_verb(src, /mob/living/carbon/alien/diona/proc/merge)
/mob/living/carbon/alien/diona/proc/wear_hat(var/obj/item/new_hat)
if(hat)
diff --git a/code/modules/mob/living/carbon/alien/diona/diona_powers.dm b/code/modules/mob/living/carbon/alien/diona/diona_powers.dm
index f0bcdeb5816..46cd347dac7 100644
--- a/code/modules/mob/living/carbon/alien/diona/diona_powers.dm
+++ b/code/modules/mob/living/carbon/alien/diona/diona_powers.dm
@@ -9,7 +9,7 @@
return
if(istype(src.loc,/mob/living/carbon))
- src.verbs -= /mob/living/carbon/alien/diona/proc/merge
+ remove_verb(src, /mob/living/carbon/alien/diona/proc/merge)
return
var/list/choices = list()
@@ -35,8 +35,8 @@
to_chat(H, "You feel your being twine with that of \the [src] as it merges with your biomass.")
to_chat(src, "You feel your being twine with that of \the [H] as you merge with its biomass.")
loc = H
- verbs += /mob/living/carbon/alien/diona/proc/split
- verbs -= /mob/living/carbon/alien/diona/proc/merge
+ add_verb(src, /mob/living/carbon/alien/diona/proc/split)
+ remove_verb(src, /mob/living/carbon/alien/diona/proc/merge)
return 1
/mob/living/carbon/alien/diona/proc/split()
@@ -49,7 +49,7 @@
return
if(!(istype(src.loc,/mob/living/carbon)))
- src.verbs -= /mob/living/carbon/alien/diona/proc/split
+ remove_verb(src, /mob/living/carbon/alien/diona/proc/split)
return
to_chat(src.loc, "You feel a pang of loss as [src] splits away from your biomass.")
@@ -58,8 +58,8 @@
var/mob/living/M = src.loc
src.loc = get_turf(src)
- src.verbs -= /mob/living/carbon/alien/diona/proc/split
- src.verbs += /mob/living/carbon/alien/diona/proc/merge
+ remove_verb(src, /mob/living/carbon/alien/diona/proc/split)
+ add_verb(src, /mob/living/carbon/alien/diona/proc/merge)
if(istype(M))
for(var/atom/A in M.contents)
diff --git a/code/modules/mob/living/carbon/alien/progression.dm b/code/modules/mob/living/carbon/alien/progression.dm
index 655210db527..1ac3e86c05d 100644
--- a/code/modules/mob/living/carbon/alien/progression.dm
+++ b/code/modules/mob/living/carbon/alien/progression.dm
@@ -8,7 +8,7 @@
return
if(!adult_form)
- verbs -= /mob/living/carbon/alien/verb/evolve
+ remove_verb(src, /mob/living/carbon/alien/verb/evolve)
return
if(handcuffed || legcuffed)
diff --git a/code/modules/mob/living/carbon/carbon_powers.dm b/code/modules/mob/living/carbon/carbon_powers.dm
index db301dac701..8555b4cd961 100644
--- a/code/modules/mob/living/carbon/carbon_powers.dm
+++ b/code/modules/mob/living/carbon/carbon_powers.dm
@@ -12,9 +12,9 @@
B.detatch()
- verbs -= /mob/living/carbon/proc/release_control
- verbs -= /mob/living/carbon/proc/punish_host
- verbs -= /mob/living/carbon/proc/spawn_larvae
+ remove_verb(src, /mob/living/carbon/proc/release_control)
+ remove_verb(src, /mob/living/carbon/proc/punish_host)
+ remove_verb(src, /mob/living/carbon/proc/spawn_larvae)
else
to_chat(src, "ERROR NO BORER OR BRAINMOB DETECTED IN THIS MOB, THIS IS A BUG !")
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index c408097a70d..d54672e61d3 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -99,7 +99,7 @@
B.host_brain.name = "host brain"
B.host_brain.real_name = "host brain"
- verbs -= /mob/living/carbon/proc/release_control
+ remove_verb(src, /mob/living/carbon/proc/release_control)
callHook("death", list(src, gibbed))
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 1d72392074a..635e248b898 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -74,42 +74,43 @@
//...and display them.
add_to_all_human_data_huds()
-/mob/living/carbon/human/Stat()
- ..()
- if(statpanel("Status"))
- stat("Intent:", "[a_intent]")
- stat("Move Mode:", "[m_intent]")
+/mob/living/carbon/human/statpanel_data(client/C)
+ . = ..()
+ if(C.statpanel_tab("Status"))
+ STATPANEL_DATA_ENTRY("Intent:", "[a_intent]")
+ STATPANEL_DATA_ENTRY("Move Mode:", "[m_intent]")
if(SSemergencyshuttle)
var/eta_status = SSemergencyshuttle.get_status_panel_eta()
if(eta_status)
- stat(null, eta_status)
+ STATPANEL_DATA_LINE(eta_status)
if (internal)
if (!internal.air_contents)
qdel(internal)
else
- stat("Internal Atmosphere Info", internal.name)
- stat("Tank Pressure", internal.air_contents.return_pressure())
- stat("Distribution Pressure", internal.distribute_pressure)
+ STATPANEL_DATA_ENTRY("Internal Atmosphere Info", internal.name)
+ STATPANEL_DATA_ENTRY("Tank Pressure", internal.air_contents.return_pressure())
+ STATPANEL_DATA_ENTRY("Distribution Pressure", internal.distribute_pressure)
var/obj/item/organ/internal/xenos/plasmavessel/P = internal_organs_by_name[O_PLASMA] //Xenomorphs. Mech.
if(P)
- stat(null, "Phoron Stored: [P.stored_plasma]/[P.max_plasma]")
+ STATPANEL_DATA_LINE("Phoron Stored: [P.stored_plasma]/[P.max_plasma]")
if(back && istype(back,/obj/item/rig))
var/obj/item/rig/suit = back
var/cell_status = "ERROR"
- if(suit.cell) cell_status = "[suit.cell.charge]/[suit.cell.maxcharge]"
- stat(null, "Suit charge: [cell_status]")
+ if(suit.cell)
+ cell_status = "[suit.cell.charge]/[suit.cell.maxcharge]"
+ STATPANEL_DATA_ENTRY("Suit charge", "[cell_status]")
if(mind)
if(mind.changeling)
- stat("Chemical Storage", mind.changeling.chem_charges)
- stat("Genetic Damage Time", mind.changeling.geneticdamage)
- stat("Re-Adaptations", "[mind.changeling.readapts]/[mind.changeling.max_readapts]")
- if(species)
- species.Stat(src)
+ STATPANEL_DATA_ENTRY("Chemical Storage", mind.changeling.chem_charges)
+ STATPANEL_DATA_ENTRY("Genetic Damage Time", mind.changeling.geneticdamage)
+ STATPANEL_DATA_ENTRY("Re-Adaptations", "[mind.changeling.readapts]/[mind.changeling.max_readapts]")
+ if(C.statpanel_tab("Species", species?.species_statpanel))
+ . += species.statpanel_status(C, src, C.statpanel_tab("Species"))
/mob/living/carbon/human/legacy_ex_act(severity)
if(!blinded)
@@ -719,7 +720,7 @@
set category = "Superpower"
if(!(MUTATION_MORPH in mutations))
- src.verbs -= /mob/living/carbon/human/proc/morph
+ remove_verb(src, /mob/living/carbon/human/proc/morph)
return
var/new_facial = input("Please select facial hair color.", "Character Generation",rgb(r_facial,g_facial,b_facial)) as color
@@ -789,7 +790,7 @@
set category = "Superpower"
if(!(MUTATION_REMOTE_TALK in src.mutations))
- src.verbs -= /mob/living/carbon/human/proc/remotesay
+ remove_verb(src, /mob/living/carbon/human/proc/remotesay)
return
var/list/creatures = list()
@@ -821,7 +822,7 @@
if(!(MUTATION_REMOTE_VIEW in src.mutations))
remoteview_target = null
reset_perspective()
- src.verbs -= /mob/living/carbon/human/proc/remoteobserve
+ remove_verb(src, /mob/living/carbon/human/proc/remoteobserve)
return
if(IsRemoteViewing())
@@ -944,7 +945,7 @@
blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
hand_blood_color = blood_color
update_bloodied()
- verbs += /mob/living/carbon/human/proc/bloody_doodle
+ add_verb(src, /mob/living/carbon/human/proc/bloody_doodle)
return 1 //we applied blood to the item
/mob/living/carbon/human/proc/get_full_print()
@@ -1186,7 +1187,7 @@
return 0 //something is terribly wrong
if (!bloody_hands)
- verbs -= /mob/living/carbon/human/proc/bloody_doodle
+ remove_verb(src, /mob/living/carbon/human/proc/bloody_doodle)
if (src.gloves)
to_chat(src, "Your [src.gloves] are getting in the way.")
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index e8e85ff98e0..14337700a6c 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -109,8 +109,8 @@
var/obj/item/organ/external/T = organs_by_name[BP_TORSO]
if(T && T.robotic >= ORGAN_ROBOT)
- T.owner.verbs |= /mob/living/carbon/human/proc/self_diagnostics
- T.owner.verbs |= /mob/living/carbon/human/proc/setmonitor_state
+ add_verb(T.owner, /mob/living/carbon/human/proc/self_diagnostics)
+ add_verb(T.owner, /mob/living/carbon/human/proc/setmonitor_state)
var/datum/robolimb/R = GLOB.all_robolimbs[T.model]
synthetic = R
return synthetic
diff --git a/code/modules/mob/living/carbon/human/human_modular_limbs.dm b/code/modules/mob/living/carbon/human/human_modular_limbs.dm
index a7e92f05979..768f1594100 100644
--- a/code/modules/mob/living/carbon/human/human_modular_limbs.dm
+++ b/code/modules/mob/living/carbon/human/human_modular_limbs.dm
@@ -75,13 +75,13 @@
// Called in robotize(), replaced() and removed() to update our modular limb verbs.
/mob/living/carbon/human/proc/refresh_modular_limb_verbs()
if(length(get_modular_limbs(return_first_found = TRUE, validate_proc = /obj/item/organ/external/proc/can_attach_modular_limb_here)))
- verbs |= .proc/attach_limb_verb
+ add_verb(src, .proc/attach_limb_verb)
else
- verbs -= .proc/attach_limb_verb
+ remove_verb(src, .proc/attach_limb_verb)
if(length(get_modular_limbs(return_first_found = TRUE, validate_proc = /obj/item/organ/external/proc/can_remove_modular_limb)))
- verbs |= .proc/detach_limb_verb
+ add_verb(src, .proc/detach_limb_verb)
else
- verbs -= .proc/detach_limb_verb
+ remove_verb(src, .proc/detach_limb_verb)
// Proc helper for attachment verb.
/mob/living/carbon/human/proc/check_can_attach_modular_limb(var/obj/item/organ/external/E)
diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm
index be7397e1be9..f03b1db0432 100644
--- a/code/modules/mob/living/carbon/human/human_powers.dm
+++ b/code/modules/mob/living/carbon/human/human_powers.dm
@@ -222,8 +222,8 @@
qdel(Org)
// Purge the diona verbs.
- verbs -= /mob/living/carbon/human/proc/diona_split_nymph
- verbs -= /mob/living/carbon/human/proc/regenerate
+ remove_verb(src, /mob/living/carbon/human/proc/diona_split_nymph)
+ remove_verb(src, /mob/living/carbon/human/proc/regenerate)
for(var/obj/item/organ/external/E in organs) // Just fall apart.
E.droplimb(TRUE)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 28431b743a3..2e9727e3e6e 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -1074,10 +1074,6 @@
fake_attack(src)
if(!handling_hal)
spawn handle_hallucinations() //The not boring kind!
- if(client && prob(5))
- client.dir = pick(2,4,8)
- spawn(rand(20,50))
- client.dir = 1
hallucination = max(0, hallucination - 2)
else
diff --git a/code/modules/mob/living/carbon/human/traits/neutral.dm b/code/modules/mob/living/carbon/human/traits/neutral.dm
index 289e1c4019e..a109ba49493 100644
--- a/code/modules/mob/living/carbon/human/traits/neutral.dm
+++ b/code/modules/mob/living/carbon/human/traits/neutral.dm
@@ -70,7 +70,7 @@
/datum/trait/neutral/bloodsucker/apply(datum/species/S, mob/living/carbon/human/H)
..(S,H)
- H.verbs |= /mob/living/carbon/human/proc/bloodsuck
+ add_verb(H, /mob/living/carbon/human/proc/bloodsuck)
/datum/trait/neutral/succubus_drain
name = "Succubus Drain"
@@ -79,9 +79,9 @@
/datum/trait/neutral/succubus_drain/apply(datum/species/S, mob/living/carbon/human/H)
..(S,H)
- H.verbs |= /mob/living/carbon/human/proc/succubus_drain
- H.verbs |= /mob/living/carbon/human/proc/succubus_drain_finalize
- H.verbs |= /mob/living/carbon/human/proc/succubus_drain_lethal
+ add_verb(H, /mob/living/carbon/human/proc/succubus_drain)
+ add_verb(H, /mob/living/carbon/human/proc/succubus_drain_finalize)
+ add_verb(H, /mob/living/carbon/human/proc/succubus_drain_lethal)
/datum/trait/neutral/vampire
name = "Vetalan / Vampiric"
@@ -98,8 +98,8 @@
/datum/trait/neutral/vampire/apply(datum/species/S, mob/living/carbon/human/H)
..(S,H)
- H.verbs |= /mob/living/carbon/human/proc/bloodsuck
- H.verbs |= /mob/living/carbon/human/proc/lick_wounds
+ add_verb(H, /mob/living/carbon/human/proc/bloodsuck)
+ add_verb(H, /mob/living/carbon/human/proc/lick_wounds)
/datum/trait/neutral/hard_vore
name = "Brutal Predation"
@@ -109,7 +109,7 @@
/datum/trait/neutral/hard_vore/apply(datum/species/S, mob/living/carbon/human/H)
..(S,H)
- H.verbs |= /mob/living/proc/shred_limb
+ add_verb(H, /mob/living/proc/shred_limb)
/datum/trait/neutral/trashcan
name = "Trash Can"
@@ -120,7 +120,7 @@
/datum/trait/neutral/trashcan/apply(datum/species/S, mob/living/carbon/human/H)
..(S,H)
- H.verbs |= /mob/living/proc/eat_trash
+ add_verb(H, /mob/living/proc/eat_trash)
/datum/trait/neutral/glowing_eyes
name = "Glowing Eyes"
@@ -137,8 +137,8 @@
/datum/trait/neutral/glowing_body/apply(datum/species/S, mob/living/carbon/human/H)
..(S,H)
- H.verbs |= /mob/living/proc/glow_toggle
- H.verbs |= /mob/living/proc/glow_color
+ add_verb(H, /mob/living/proc/glow_toggle)
+ add_verb(H, /mob/living/proc/glow_color)
//! ## Body shape traits
/datum/trait/neutral/taller
@@ -245,7 +245,7 @@
/datum/trait/neutral/antiseptic_saliva/apply(datum/species/S, mob/living/carbon/human/H)
..(S,H)
- H.verbs |= /mob/living/carbon/human/proc/lick_wounds
+ add_verb(H, /mob/living/carbon/human/proc/lick_wounds)
/datum/trait/neutral/size_change
name = "Sizeshift"
@@ -254,7 +254,7 @@
/datum/trait/neutral/size_change/apply(datum/species/S, mob/living/carbon/human/H)
..(S,H)
- H.verbs |= /mob/living/proc/set_size
+ add_verb(H, /mob/living/proc/set_size)
/datum/trait/neutral/cyberpsycho
name = "Cybernetic Rejection Syndrome"
diff --git a/code/modules/mob/living/carbon/human/traits/positive.dm b/code/modules/mob/living/carbon/human/traits/positive.dm
index fe7bb3dbb4c..db1a7ddaa04 100644
--- a/code/modules/mob/living/carbon/human/traits/positive.dm
+++ b/code/modules/mob/living/carbon/human/traits/positive.dm
@@ -158,8 +158,8 @@
/datum/trait/positive/winged_flight/apply(var/datum/species/S,var/mob/living/carbon/human/H)
..(S,H)
- H.verbs |= /mob/living/proc/flying_toggle
- H.verbs |= /mob/living/proc/start_wings_hovering
+ add_verb(H, /mob/living/proc/flying_toggle)
+ add_verb(H, /mob/living/proc/start_wings_hovering)
/datum/trait/positive/hardfeet
name = "Hard Feet"
@@ -177,7 +177,7 @@
/datum/trait/positive/antiseptic_saliva/apply(var/datum/species/S,var/mob/living/carbon/human/H)
..()
- H.verbs |= /mob/living/carbon/human/proc/lick_wounds
+ add_verb(H, /mob/living/carbon/human/proc/lick_wounds)
/datum/trait/positive/thick_blood
name = "Thick Blood"
@@ -193,8 +193,8 @@
/datum/trait/positive/positive/weaver/apply(var/datum/species/S,var/mob/living/carbon/human/H)
..()
- H.verbs |= /mob/living/carbon/human/proc/check_silk_amount
- H.verbs |= /mob/living/carbon/human/proc/toggle_silk_production
- H.verbs |= /mob/living/carbon/human/proc/weave_structure
- H.verbs |= /mob/living/carbon/human/proc/weave_item
- H.verbs |= /mob/living/carbon/human/proc/set_silk_color
+ add_verb(H, /mob/living/carbon/human/proc/check_silk_amount)
+ add_verb(H, /mob/living/carbon/human/proc/toggle_silk_production)
+ add_verb(H, /mob/living/carbon/human/proc/weave_structure)
+ add_verb(H, /mob/living/carbon/human/proc/weave_item)
+ add_verb(H, /mob/living/carbon/human/proc/set_silk_color)
diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm
index 608adb69b1c..4b95c0fe64f 100644
--- a/code/modules/mob/living/carbon/metroid/metroid.dm
+++ b/code/modules/mob/living/carbon/metroid/metroid.dm
@@ -74,7 +74,7 @@
var/core_removal_stage = 0 //For removing cores.
/mob/living/carbon/slime/Initialize(mapload, colour = "grey")
- verbs += /mob/living/proc/ventcrawl
+ add_verb(src, /mob/living/proc/ventcrawl)
src.colour = colour
number = rand(1, 1000)
@@ -155,22 +155,19 @@
/mob/living/carbon/slime/Process_Spacemove()
return 2
-/mob/living/carbon/slime/Stat()
- ..()
-
- statpanel("Status")
- stat(null, "Health: [round((health / getMaxHealth()) * 100)]%")
- stat(null, "Intent: [a_intent]")
-
- if (client.statpanel == "Status")
- stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]")
+/mob/living/carbon/slime/statpanel_data(client/C)
+ . = ..()
+ if(C.statpanel_tab("Status"))
+ STATPANEL_DATA_LINE("")
+ STATPANEL_DATA_LINE("Health: [round((health / getMaxHealth()) * 100)]%")
+ STATPANEL_DATA_LINE("Intent: [a_intent]")
+ STATPANEL_DATA_LINE("Nutrition: [nutrition]/[get_max_nutrition()]")
if(amount_grown >= 10)
if(is_adult)
- stat(null, "You can reproduce!")
+ STATPANEL_DATA_LINE("You can reproduce!")
else
- stat(null, "You can evolve!")
-
- stat(null,"Power Level: [powerlevel]")
+ STATPANEL_DATA_LINE("You can evolve!")
+ STATPANEL_DATA_LINE("Power Level: [powerlevel]")
/mob/living/carbon/slime/adjustFireLoss(var/amount,var/include_robo)
..(-abs(amount)) // Heals them
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 77fc20b7f11..7c4cca78f0e 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -327,7 +327,7 @@
/mob/living/proc/embed(var/obj/O, var/def_zone=null)
O.loc = src
src.embedded += O
- src.verbs += /mob/proc/yank_out_object
+ add_verb(src, /mob/proc/yank_out_object)
//This is called when the mob is thrown into a dense turf
/mob/living/proc/turf_collision(var/turf/T, var/speed)
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 250b3b94970..5cbcabea97b 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -126,12 +126,12 @@ var/list/ai_verbs_default = list(
var/carded
/mob/living/silicon/ai/proc/add_ai_verbs()
- src.verbs |= ai_verbs_default
- src.verbs |= silicon_subsystems
+ add_verb(src, ai_verbs_default)
+ add_verb(src, silicon_subsystems)
/mob/living/silicon/ai/proc/remove_ai_verbs()
- src.verbs -= ai_verbs_default
- src.verbs -= silicon_subsystems
+ remove_verb(src, ai_verbs_default)
+ remove_verb(src, silicon_subsystems)
/mob/living/silicon/ai/Initialize(mapload, datum/ai_laws/L, obj/item/mmi/B, safety = TRUE)
announcement = new()
@@ -194,7 +194,7 @@ var/list/ai_verbs_default = list(
on_mob_init()
if(config_legacy.allow_ai_shells)
- verbs += /mob/living/silicon/ai/proc/deploy_to_shell_act
+ add_verb(src, /mob/living/silicon/ai/proc/deploy_to_shell_act)
spawn(5)
new /obj/machinery/ai_powersupply(src)
@@ -248,12 +248,13 @@ var/list/ai_verbs_default = list(
return ..()
-/mob/living/silicon/ai/Stat()
- ..()
- if(statpanel("Status"))
+/mob/living/silicon/ai/statpanel_data(client/C)
+ . = ..()
+ if(C.statpanel_tab("Status"))
+ STATPANEL_DATA_LINE("")
if(!stat) // Make sure we're not unconscious/dead.
- stat(null, text("System integrity: [(health+100)/2]%"))
- stat(null, text("Connected synthetics: [connected_robots.len]"))
+ STATPANEL_DATA_LINE(text("System integrity: [(health+100)/2]%"))
+ STATPANEL_DATA_LINE(text("Connected synthetics: [connected_robots.len]"))
for(var/mob/living/silicon/robot/R in connected_robots)
var/robot_status = "Nominal"
if(R.shell)
@@ -263,11 +264,11 @@ var/list/ai_verbs_default = list(
else if(!R.cell || R.cell.charge <= 0)
robot_status = "DEPOWERED"
//Name, Health, Battery, Module, Area, and Status! Everything an AI wants to know about its borgies!
- stat(null, text("[R.name] | S.Integrity: [R.health]% | Cell: [R.cell ? "[R.cell.charge]/[R.cell.maxcharge]" : "Empty"] | \
+ STATPANEL_DATA_LINE(text("[R.name] | S.Integrity: [R.health]% | Cell: [R.cell ? "[R.cell.charge]/[R.cell.maxcharge]" : "Empty"] | \
Module: [R.modtype] | Loc: [get_area_name(R, TRUE)] | Status: [robot_status]"))
- stat(null, text("AI shell beacons detected: [LAZYLEN(GLOB.available_ai_shells)]")) //Count of total AI shells
+ STATPANEL_DATA_LINE(text("AI shell beacons detected: [LAZYLEN(GLOB.available_ai_shells)]")) //Count of total AI shells
else
- stat(null, text("Systems nonfunctional"))
+ STATPANEL_DATA_LINE(text("Systems nonfunctional"))
/mob/living/silicon/ai/proc/setup_icon()
diff --git a/code/modules/mob/living/silicon/ai/malf.dm b/code/modules/mob/living/silicon/ai/malf.dm
index 8290302c179..ee08b3001af 100644
--- a/code/modules/mob/living/silicon/ai/malf.dm
+++ b/code/modules/mob/living/silicon/ai/malf.dm
@@ -10,9 +10,9 @@
hacked_apcs = list()
recalc_cpu()
- verbs += new/datum/game_mode/malfunction/verb/ai_select_hardware()
- verbs += new/datum/game_mode/malfunction/verb/ai_select_research()
- verbs += new/datum/game_mode/malfunction/verb/ai_help()
+ add_verb(src, /datum/game_mode/malfunction/verb/ai_select_hardware)
+ add_verb(src, /datum/game_mode/malfunction/verb/ai_select_research)
+ add_verb(src, /datum/game_mode/malfunction/verb/ai_help)
// And greet user with some OOC info.
to_chat(user, "You are malfunctioning, you do not have to follow any laws.")
@@ -109,29 +109,31 @@
// Shows capacitor charge and hardware integrity information to the AI in Status tab.
/mob/living/silicon/ai/show_system_integrity()
+ . = list()
if(!src.stat)
- stat(null, text("Hardware integrity: [hardware_integrity()]%"))
- stat(null, text("Internal capacitor: [backup_capacitor()]%"))
+ STATPANEL_DATA_LINE("Hardware integrity: [hardware_integrity()]%")
+ STATPANEL_DATA_LINE("Internal capacitor: [backup_capacitor()]%")
else
- stat(null, text("Systems nonfunctional"))
+ STATPANEL_DATA_LINE("Systems nonfunctional")
// Shows AI Malfunction related information to the AI.
/mob/living/silicon/ai/show_malf_ai()
+ . = list()
if(src.is_malf())
if(src.hacked_apcs)
- stat(null, "Hacked APCs: [src.hacked_apcs.len]")
- stat(null, "System Status: [src.hacking ? "Busy" : "Stand-By"]")
+ STATPANEL_DATA_LINE("Hacked APCs: [src.hacked_apcs.len]")
+ STATPANEL_DATA_LINE("System Status: [src.hacking ? "Busy" : "Stand-By"]")
if(src.research)
- stat(null, "Available CPU: [src.research.stored_cpu] TFlops")
- stat(null, "Maximal CPU: [src.research.max_cpu] TFlops")
- stat(null, "CPU generation rate: [src.research.cpu_increase_per_tick * 10] TFlops/s")
- stat(null, "Current research focus: [src.research.focus ? src.research.focus.name : "None"]")
+ STATPANEL_DATA_LINE("Available CPU: [src.research.stored_cpu] TFlops")
+ STATPANEL_DATA_LINE("Maximal CPU: [src.research.max_cpu] TFlops")
+ STATPANEL_DATA_LINE("CPU generation rate: [src.research.cpu_increase_per_tick * 10] TFlops/s")
+ STATPANEL_DATA_LINE("Current research focus: [src.research.focus ? src.research.focus.name : "None"]")
if(src.research.focus)
- stat(null, "Research completed: [round(src.research.focus.invested, 0.1)]/[round(src.research.focus.price)]")
+ STATPANEL_DATA_LINE("Research completed: [round(src.research.focus.invested, 0.1)]/[round(src.research.focus.price)]")
if(system_override == 1)
- stat(null, "SYSTEM OVERRIDE INITIATED")
+ STATPANEL_DATA_LINE("SYSTEM OVERRIDE INITIATED")
else if(system_override == 2)
- stat(null, "SYSTEM OVERRIDE COMPLETED")
+ STATPANEL_DATA_LINE("SYSTEM OVERRIDE COMPLETED")
// Cleaner proc for creating powersupply for an AI.
/mob/living/silicon/ai/proc/create_powersupply()
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 2d2eb43c1bb..cc4332bb303 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -111,8 +111,8 @@
card.radio = new /obj/item/radio(src.card)
radio = card.radio
- verbs += /mob/living/silicon/pai/proc/choose_chassis
- verbs += /mob/living/silicon/pai/proc/choose_verbs
+ add_verb(src, /mob/living/silicon/pai/proc/choose_chassis)
+ add_verb(src, /mob/living/silicon/pai/proc/choose_verbs)
//PDA
pda = new(src)
@@ -128,19 +128,17 @@
if(client.prefs)
ooc_notes = client.prefs.metadata
-
// this function shows the information about being silenced as a pAI in the Status panel
/mob/living/silicon/pai/proc/show_silenced()
+ . = list()
if(src.silence_time)
var/timeleft = round((silence_time - world.timeofday)/10 ,1)
- stat(null, "Communications system reboot in -[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
+ STATPANEL_DATA_LINE("Communications system reboot in -[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
-
-/mob/living/silicon/pai/Stat()
- ..()
- statpanel("Status")
- if (src.client.statpanel == "Status")
- show_silenced()
+/mob/living/silicon/pai/statpanel_data(client/C)
+ . = ..()
+ if(C.statpanel_tab("Status"))
+ . += show_silenced()
/mob/living/silicon/pai/check_eye(var/mob/user as mob)
if (!src.current)
@@ -304,9 +302,9 @@
if(istype(T))
T.visible_message("[src] folds outwards, expanding into a mobile form.")
- verbs += /mob/living/silicon/pai/proc/pai_nom
- verbs += /mob/living/proc/set_size
- verbs += /mob/living/proc/shred_limb
+ add_verb(src, /mob/living/silicon/pai/proc/pai_nom)
+ add_verb(src, /mob/living/proc/set_size)
+ add_verb(src, /mob/living/proc/shred_limb)
/mob/living/silicon/pai/verb/fold_up()
set category = "pAI Commands"
@@ -338,7 +336,7 @@
finalized = alert("Look at your sprite. Is this what you wish to use?",,"No","Yes")
chassis = possible_chassis[choice]
- verbs |= /mob/living/proc/hide
+ add_verb(src, /mob/living/proc/hide)
/mob/living/silicon/pai/proc/choose_verbs()
set category = "pAI Commands"
@@ -421,7 +419,7 @@
canmove = TRUE
resting = FALSE
icon_state = "[chassis]"
- verbs -= /mob/living/silicon/pai/proc/pai_nom
+ remove_verb(src, /mob/living/silicon/pai/proc/pai_nom)
// No binary for pAIs.
/mob/living/silicon/pai/binarycheck()
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index 0f882d1ce53..c58d2c0ad21 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -91,8 +91,8 @@
/mob/living/silicon/robot/drone/Initialize(mapload)
. = ..()
- verbs += /mob/living/proc/ventcrawl
- verbs += /mob/living/proc/hide
+ add_verb(src, /mob/living/proc/ventcrawl)
+ add_verb(src, /mob/living/proc/hide)
remove_language("Robot Talk")
add_language("Robot Talk", 0)
add_language("Drone Talk", 1)
@@ -110,7 +110,7 @@
var/datum/robot_component/C = components[V]
C.max_damage = 10
- verbs -= /mob/living/silicon/robot/verb/Namepick
+ remove_verb(src, /mob/living/silicon/robot/verb/Namepick)
updateicon()
updatename()
@@ -359,10 +359,10 @@
to_chat(src, "Use say ;Hello to talk to other drones and say Hello to speak silently to your nearby fellows.")
/mob/living/silicon/robot/drone/add_robot_verbs()
- src.verbs |= silicon_subsystems
+ add_verb(src, silicon_subsystems)
/mob/living/silicon/robot/drone/remove_robot_verbs()
- src.verbs -= silicon_subsystems
+ remove_verb(src, silicon_subsystems)
/mob/living/silicon/robot/drone/construction/welcome_drone()
to_chat(src, "You are a construction drone, an autonomous engineering and fabrication system..")
@@ -380,7 +380,7 @@
/mob/living/silicon/robot/drone/construction/matriarch/init()
..()
- verbs += /mob/living/silicon/robot/verb/Namepick
+ add_verb(src, /mob/living/silicon/robot/verb/Namepick)
flavor_text = "It's a small matriarch drone. The casing is stamped with an corporate logo and the subscript: '[GLOB.using_map.company_name] Recursive Repair Systems: Heart Of The Swarm!'"
/mob/living/silicon/robot/drone/construction/matriarch/welcome_drone()
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm b/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm
index a62d55d4db9..bd2b5739672 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm
@@ -21,7 +21,7 @@
user.teleop = src
radio.channels = user.aiRadio.keyslot2.channels
controlling_ai = user
- verbs += /mob/living/silicon/robot/drone/proc/release_ai_control_verb
+ add_verb(src, /mob/living/silicon/robot/drone/proc/release_ai_control_verb)
local_transmit = FALSE
languages = controlling_ai.languages.Copy()
speech_synthesizer_langs = controlling_ai.speech_synthesizer_langs.Copy()
@@ -59,7 +59,7 @@
user.teleop = new_drone
new_drone.radio.channels = user.aiRadio.keyslot2.channels
new_drone.controlling_ai = user
- new_drone.verbs += /mob/living/silicon/robot/drone/proc/release_ai_control_verb
+ add_verb(new_drone, /mob/living/silicon/robot/drone/proc/release_ai_control_verb)
new_drone.local_transmit = FALSE
new_drone.languages = new_drone.controlling_ai.languages.Copy()
new_drone.speech_synthesizer_langs = new_drone.controlling_ai.speech_synthesizer_langs.Copy()
@@ -92,7 +92,7 @@
controlling_ai = null
radio.channels = module.channels
- verbs -= /mob/living/silicon/robot/drone/proc/release_ai_control_verb
+ remove_verb(src, /mob/living/silicon/robot/drone/proc/release_ai_control_verb)
module.remove_languages(src) //Removes excess, adds 'default'.
remove_language("Robot Talk")
add_language("Robot Talk", 0)
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index f93ffc155e1..d72d41f3844 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -484,42 +484,33 @@
set name = "Emit Sparks"
spark_system.start()
-// this function displays jetpack pressure in the stat panel
-/mob/living/silicon/robot/proc/show_jetpack_pressure()
- // if you have a jetpack, show the internal tank pressure
- var/obj/item/tank/jetpack/current_jetpack = installed_jetpack()
- if (current_jetpack)
- stat("Internal Atmosphere Info", current_jetpack.name)
- stat("Tank Pressure", current_jetpack.air_contents.return_pressure())
-
-
// this function returns the robots jetpack, if one is installed
/mob/living/silicon/robot/proc/installed_jetpack()
if(module)
return (locate(/obj/item/tank/jetpack) in module.modules)
return 0
-
-// this function displays the cyborgs current cell charge in the stat panel
-/mob/living/silicon/robot/proc/show_cell_power()
- if(cell)
- stat(null, text("Charge Left: [round(cell.percent())]%"))
- stat(null, text("Cell Rating: [round(cell.maxcharge)]")) // Round just in case we somehow get crazy values
- stat(null, text("Power Cell Load: [round(used_power_this_tick)]W"))
- else
- stat(null, text("No Cell Inserted!"))
-
-
// update the status screen display
-/mob/living/silicon/robot/Stat()
- ..()
- if (statpanel("Status"))
- show_cell_power()
- show_jetpack_pressure()
- stat(null, text("Lights: [lights_on ? "ON" : "OFF"]"))
+/mob/living/silicon/robot/statpanel_data(client/C)
+ . = ..()
+ if(C.statpanel_tab("Status"))
+ STATPANEL_DATA_LINE("")
+ if(cell)
+ STATPANEL_DATA_LINE( text("Charge Left: [round(cell.percent())]%"))
+ STATPANEL_DATA_LINE( text("Cell Rating: [round(cell.maxcharge)]")) // Round just in case we somehow get crazy values
+ STATPANEL_DATA_LINE( text("Power Cell Load: [round(used_power_this_tick)]W"))
+ else
+ STATPANEL_DATA_LINE( text("No Cell Inserted!"))
+ STATPANEL_DATA_LINE( text("Lights: [lights_on ? "ON" : "OFF"]"))
+ STATPANEL_DATA_LINE("")
+ // if you have a jetpack, show the internal tank pressure
+ var/obj/item/tank/jetpack/current_jetpack = installed_jetpack()
+ if (current_jetpack)
+ STATPANEL_DATA_ENTRY("Internal Atmosphere Info", current_jetpack.name)
+ STATPANEL_DATA_ENTRY("Tank Pressure", current_jetpack.air_contents.return_pressure())
if(module)
for(var/datum/matter_synth/ms in module.synths)
- stat("[ms.name]: [ms.energy]/[ms.max_energy]")
+ STATPANEL_DATA_LINE("[ms.name]: [ms.energy]/[ms.max_energy]")
/mob/living/silicon/robot/restrained()
return 0
@@ -1163,7 +1154,7 @@
if(R)
R.UnlinkSelf()
to_chat(R, "Buffers flushed and reset. Camera system shutdown. All systems operational.")
- src.verbs -= /mob/living/silicon/robot/proc/ResetSecurityCodes
+ remove_verb(src, /mob/living/silicon/robot/proc/ResetSecurityCodes)
/mob/living/silicon/robot/proc/SetLockdown(var/state = 1)
// They stay locked down if their wire is cut.
@@ -1232,12 +1223,12 @@
toggle_sensor_mode()
/mob/living/silicon/robot/proc/add_robot_verbs()
- src.verbs |= robot_verbs_default
- src.verbs |= silicon_subsystems
+ add_verb(src, robot_verbs_default)
+ add_verb(src, silicon_subsystems)
/mob/living/silicon/robot/proc/remove_robot_verbs()
- src.verbs -= robot_verbs_default
- src.verbs -= silicon_subsystems
+ remove_verb(src, robot_verbs_default)
+ remove_verb(src, silicon_subsystems)
// Uses power from cyborg's cell. Returns 1 on success or 0 on failure.
// Properly converts using CELLRATE now! Amount is in Joules.
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/event_vr.dm b/code/modules/mob/living/silicon/robot/robot_modules/event_vr.dm
index 0e807349fd6..794b25c6ba7 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/event_vr.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/event_vr.dm
@@ -55,6 +55,6 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.icon_dimension_x = 64
- R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
- R.verbs |= /mob/living/proc/shred_limb
- R.verbs |= /mob/living/silicon/robot/proc/rest_style
+ add_verb(R, /mob/living/silicon/robot/proc/ex_reserve_refill)
+ add_verb(R, /mob/living/proc/shred_limb)
+ add_verb(R, /mob/living/silicon/robot/proc/rest_style)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station.dm b/code/modules/mob/living/silicon/robot/robot_modules/station.dm
index bd1b532000f..0ee37c2b826 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/station.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/station.dm
@@ -168,10 +168,10 @@ GLOBAL_LIST_INIT(robot_modules, list(
added_networks.Cut()
/obj/item/robot_module/proc/add_subsystems(var/mob/living/silicon/robot/R)
- R.verbs |= subsystems
+ add_verb(R, subsystems)
/obj/item/robot_module/proc/remove_subsystems(var/mob/living/silicon/robot/R)
- R.verbs -= subsystems
+ remove_verb(R, subsystems)
/obj/item/robot_module/proc/apply_status_flags(var/mob/living/silicon/robot/R)
if(!can_be_pushed)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station/cargo.dm b/code/modules/mob/living/silicon/robot/robot_modules/station/cargo.dm
index 8c806b56ccc..b6b66fda38d 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/station/cargo.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/station/cargo.dm
@@ -85,5 +85,5 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.icon_dimension_x = 64
- R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
- R.verbs |= /mob/living/silicon/robot/proc/rest_style
+ add_verb(R, /mob/living/silicon/robot/proc/ex_reserve_refill)
+ add_verb(R, /mob/living/silicon/robot/proc/rest_style)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station/engineering.dm b/code/modules/mob/living/silicon/robot/robot_modules/station/engineering.dm
index 768ddad7c3c..bdc942c3716 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/station/engineering.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/station/engineering.dm
@@ -294,9 +294,9 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.icon_dimension_x = 64
- R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
- R.verbs |= /mob/living/proc/shred_limb
- R.verbs |= /mob/living/silicon/robot/proc/rest_style
+ add_verb(R, /mob/living/silicon/robot/proc/ex_reserve_refill)
+ add_verb(R, /mob/living/proc/shred_limb)
+ add_verb(R, /mob/living/silicon/robot/proc/rest_style)
if(R.client && (R.client.ckey in list("nezuli")))
sprites += "Alina"
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station/medical.dm b/code/modules/mob/living/silicon/robot/robot_modules/station/medical.dm
index 7b9e3d1b7b4..b29d4f39ece 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/station/medical.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/station/medical.dm
@@ -183,9 +183,9 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.icon_dimension_x = 64
- R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
- R.verbs |= /mob/living/proc/shred_limb
- R.verbs |= /mob/living/silicon/robot/proc/rest_style
+ add_verb(R, /mob/living/silicon/robot/proc/ex_reserve_refill)
+ add_verb(R, /mob/living/proc/shred_limb)
+ add_verb(R, /mob/living/silicon/robot/proc/rest_style)
if(R.client && (R.client.ckey in list("nezuli")))
sprites += "Alina"
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station/misc.dm b/code/modules/mob/living/silicon/robot/robot_modules/station/misc.dm
index 0eba95b4b21..6fa71a3c5ac 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/station/misc.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/station/misc.dm
@@ -68,5 +68,5 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.icon_dimension_x = 64
- R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
- R.verbs |= /mob/living/silicon/robot/proc/rest_style
+ add_verb(R, /mob/living/silicon/robot/proc/ex_reserve_refill)
+ add_verb(R, /mob/living/silicon/robot/proc/rest_style)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station/science.dm b/code/modules/mob/living/silicon/robot/robot_modules/station/science.dm
index 52385019174..7f876d6fe74 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/station/science.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/station/science.dm
@@ -145,7 +145,7 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.icon_dimension_x = 64
- R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
- R.verbs |= /mob/living/proc/shred_limb
- R.verbs |= /mob/living/silicon/robot/proc/rest_style
+ add_verb(R, /mob/living/silicon/robot/proc/ex_reserve_refill)
+ add_verb(R, /mob/living/proc/shred_limb)
+ add_verb(R, /mob/living/silicon/robot/proc/rest_style)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station/security.dm b/code/modules/mob/living/silicon/robot/robot_modules/station/security.dm
index b6907bdeee7..85d9d21644d 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/station/security.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/station/security.dm
@@ -128,9 +128,9 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.icon_dimension_x = 64
- R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
- R.verbs |= /mob/living/proc/shred_limb
- R.verbs |= /mob/living/silicon/robot/proc/rest_style
+ add_verb(R, /mob/living/silicon/robot/proc/ex_reserve_refill)
+ add_verb(R, /mob/living/proc/shred_limb)
+ add_verb(R, /mob/living/silicon/robot/proc/rest_style)
if(R.client && (R.client.ckey in list("nezuli")))
sprites += "Alina"
@@ -196,6 +196,6 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.icon_dimension_x = 64
- R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
- R.verbs |= /mob/living/proc/shred_limb
- R.verbs |= /mob/living/silicon/robot/proc/rest_style
+ add_verb(R, /mob/living/silicon/robot/proc/ex_reserve_refill)
+ add_verb(R, /mob/living/proc/shred_limb)
+ add_verb(R, /mob/living/silicon/robot/proc/rest_style)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station/service.dm b/code/modules/mob/living/silicon/robot/robot_modules/station/service.dm
index c8c0e33977e..64f2adebc80 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/station/service.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/station/service.dm
@@ -253,9 +253,9 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.icon_dimension_x = 64
- R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
- R.verbs |= /mob/living/proc/shred_limb
- R.verbs |= /mob/living/silicon/robot/proc/rest_style
+ add_verb(R, /mob/living/silicon/robot/proc/ex_reserve_refill)
+ add_verb(R, /mob/living/proc/shred_limb)
+ add_verb(R, /mob/living/silicon/robot/proc/rest_style)
// Uses modified K9 sprites.
/obj/item/robot_module/robot/clerical/quad_serv
@@ -325,8 +325,8 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.icon_dimension_x = 64
- R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
- R.verbs |= /mob/living/silicon/robot/proc/rest_style
+ add_verb(R, /mob/living/silicon/robot/proc/ex_reserve_refill)
+ add_verb(R, /mob/living/silicon/robot/proc/rest_style)
/obj/item/robot_module/Reset(var/mob/living/silicon/robot/R)
@@ -337,6 +337,6 @@
R.wideborg = FALSE
R.base_pixel_x = initial(pixel_x)
R.scrubbing = FALSE
- R.verbs -= /mob/living/silicon/robot/proc/ex_reserve_refill
- R.verbs -= /mob/living/proc/shred_limb
- R.verbs -= /mob/living/silicon/robot/proc/rest_style
+ remove_verb(R, /mob/living/silicon/robot/proc/ex_reserve_refill)
+ remove_verb(R, /mob/living/proc/shred_limb)
+ remove_verb(R, /mob/living/silicon/robot/proc/rest_style)
diff --git a/code/modules/mob/living/silicon/robot/robot_remote_control.dm b/code/modules/mob/living/silicon/robot/robot_remote_control.dm
index 20014b4252c..39bb68d6fc0 100644
--- a/code/modules/mob/living/silicon/robot/robot_remote_control.dm
+++ b/code/modules/mob/living/silicon/robot/robot_remote_control.dm
@@ -62,7 +62,7 @@ GLOBAL_LIST_EMPTY(available_ai_shells)
lawsync()
// Give button to leave.
- verbs += /mob/living/silicon/robot/proc/undeploy_act
+ add_verb(src, /mob/living/silicon/robot/proc/undeploy_act)
to_chat(AI, SPAN_NOTICE("You have connected to an AI Shell remotely, and are now in control of it.
\
To return to your core, use the Release Control verb."))
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 68a6eea8ab2..a5dca9e07c6 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -141,7 +141,6 @@
/mob/living/silicon/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0, var/check_protection = 1)
return 0//The only effect that can hit them atm is flashes and they still directly edit so this works for now
-
/proc/islinked(var/mob/living/silicon/robot/bot, var/mob/living/silicon/ai/ai)
if(!istype(bot) || !istype(ai))
return 0
@@ -149,34 +148,25 @@
return 1
return 0
-
// this function shows the health of the AI in the Status panel
/mob/living/silicon/proc/show_system_integrity()
+ . = list()
if(!src.stat)
- stat(null, text("System integrity: [round((health/getMaxHealth())*100)]%"))
+ STATPANEL_DATA_LINE("System integrity: [round((health/getMaxHealth())*100)]%")
else
- stat(null, text("Systems nonfunctional"))
-
+ STATPANEL_DATA_LINE("Systems nonfunctional")
// This is a pure virtual function, it should be overwritten by all subclasses
/mob/living/silicon/proc/show_malf_ai()
- return 0
-
-// this function displays the shuttles ETA in the status panel if the shuttle has been called
-/mob/living/silicon/proc/show_emergency_shuttle_eta()
- if(SSemergencyshuttle)
- var/eta_status = SSemergencyshuttle.get_status_panel_eta()
- if(eta_status)
- stat(null, eta_status)
-
+ return list()
// This adds the basic clock, shuttle recall timer, and malf_ai info to all silicon lifeforms
-/mob/living/silicon/Stat()
- if(statpanel("Status"))
- show_emergency_shuttle_eta()
- show_system_integrity()
- show_malf_ai()
- ..()
+/mob/living/silicon/statpanel_data(client/C)
+ . = ..()
+ if(C.statpanel_tab("Status"))
+ STATPANEL_DATA_LINE("")
+ . += show_system_integrity()
+ . += show_malf_ai()
// this function displays the stations manifest in a separate window
/mob/living/silicon/proc/show_station_manifest()
diff --git a/code/modules/mob/living/simple_animal/animals/mouse.dm b/code/modules/mob/living/simple_animal/animals/mouse.dm
index ec1ed79d68c..a89313aac41 100644
--- a/code/modules/mob/living/simple_animal/animals/mouse.dm
+++ b/code/modules/mob/living/simple_animal/animals/mouse.dm
@@ -69,8 +69,8 @@
/mob/living/simple_mob/mouse/Initialize(mapload)
. = ..()
- verbs += /mob/living/proc/ventcrawl
- verbs += /mob/living/proc/hide
+ add_verb(src, /mob/living/proc/ventcrawl)
+ add_verb(src, /mob/living/proc/hide)
if(name == initial(name))
name = "[name] ([rand(1, 1000)])"
diff --git a/code/modules/mob/living/simple_animal/animals/spiderbot.dm b/code/modules/mob/living/simple_animal/animals/spiderbot.dm
index 96f1e24e284..a1f4aaf50e9 100644
--- a/code/modules/mob/living/simple_animal/animals/spiderbot.dm
+++ b/code/modules/mob/living/simple_animal/animals/spiderbot.dm
@@ -65,8 +65,8 @@
. = ..()
add_language(LANGUAGE_GALCOM)
default_language = SScharacters.resolve_language_name(LANGUAGE_GALCOM)
- verbs |= /mob/living/proc/ventcrawl
- verbs |= /mob/living/proc/hide
+ add_verb(src, /mob/living/proc/ventcrawl)
+ add_verb(src, /mob/living/proc/hide)
/mob/living/simple_mob/spiderbot/attackby(var/obj/item/O as obj, var/mob/user as mob)
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index b6817ef7bec..46c40907e50 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -125,7 +125,7 @@
/mob/living/simple_animal/slime/Initialize(mapload, start_as_adult = FALSE)
. = ..()
- verbs += /mob/living/proc/ventcrawl
+ add_verb(src, /mob/living/proc/ventcrawl)
if(start_as_adult)
make_adult()
health = maxHealth
@@ -469,11 +469,11 @@
return FALSE
-/mob/living/simple_animal/slime/get_description_interaction()
+/mob/living/simple_animal/slime/get_description_interaction(mob/user)
var/list/results = list()
if(!stat)
- results += "[desc_panel_image("slimebaton")]to stun the slime, if it's being bad."
+ results += "[desc_panel_image("slimebaton", user)]to stun the slime, if it's being bad."
results += ..()
diff --git a/code/modules/mob/living/simple_mob/simple_mob.dm b/code/modules/mob/living/simple_mob/simple_mob.dm
index ebaf728db14..7f7f837fea4 100644
--- a/code/modules/mob/living/simple_mob/simple_mob.dm
+++ b/code/modules/mob/living/simple_mob/simple_mob.dm
@@ -265,7 +265,7 @@
update_icons()
/mob/living/simple_mob/Initialize(mapload)
- verbs -= /mob/verb/observe
+ remove_verb(src, /mob/verb/observe)
health = maxHealth
randomize()
@@ -358,10 +358,10 @@
return . + tally + config_legacy.animal_delay
-/mob/living/simple_mob/Stat()
- ..()
- if(statpanel("Status") && show_stat_health)
- stat(null, "Health: [round((health / getMaxHealth()) * 100)]%")
+/mob/living/simple_mob/statpanel_data(client/C)
+ . = ..()
+ if(C.statpanel_tab("Status") && show_stat_health)
+ STATPANEL_DATA_LINE("Health: [round((health / getMaxHealth()) * 100)]%")
/mob/living/simple_mob/lay_down()
..()
diff --git a/code/modules/mob/living/simple_mob/simple_mob_vr.dm b/code/modules/mob/living/simple_mob/simple_mob_vr.dm
index 23f07bdf9b0..9a0c63b306b 100644
--- a/code/modules/mob/living/simple_mob/simple_mob_vr.dm
+++ b/code/modules/mob/living/simple_mob/simple_mob_vr.dm
@@ -177,15 +177,15 @@
return
if(!IsAdvancedToolUser())
- verbs |= /mob/living/simple_mob/proc/animal_nom
- verbs |= /mob/living/proc/shred_limb
+ add_verb(src, /mob/living/simple_mob/proc/animal_nom)
+ add_verb(src, /mob/living/proc/shred_limb)
if(LAZYLEN(vore_organs))
return
// Since they have bellies, add verbs to toggle settings on them.
- verbs |= /mob/living/simple_mob/proc/toggle_digestion
- verbs |= /mob/living/simple_mob/proc/toggle_fancygurgle
+ add_verb(src, /mob/living/simple_mob/proc/toggle_digestion)
+ add_verb(src, /mob/living/simple_mob/proc/toggle_fancygurgle)
//A much more detailed version of the default /living implementation
var/obj/belly/B = new /obj/belly(src)
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer.dm b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer.dm
index 59b357283fb..ec5ad764f8d 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer.dm
@@ -63,8 +63,8 @@
/mob/living/simple_mob/animal/borer/Initialize(mapload)
add_language("Cortical Link")
- verbs += /mob/living/proc/ventcrawl
- verbs += /mob/living/proc/hide
+ add_verb(src, /mob/living/proc/ventcrawl)
+ add_verb(src, /mob/living/proc/hide)
true_name = "[pick("Primary","Secondary","Tertiary","Quaternary")] [rand(1000,9999)]"
@@ -105,15 +105,10 @@
if(prob(host.brainloss/20))
host.say("*[pick(list("blink","blink_r","choke","aflap","drool","twitch","twitch_v","gasp"))]")
-/mob/living/simple_mob/animal/borer/Stat()
- ..()
- if(client.statpanel == "Status")
- statpanel("Status")
- if(SSemergencyshuttle)
- var/eta_status = SSemergencyshuttle.get_status_panel_eta()
- if(eta_status)
- stat(null, eta_status)
- stat("Chemicals", chemicals)
+/mob/living/simple_mob/animal/borer/statpanel_data(client/C)
+ . = ..()
+ if(C.statpanel_tab("Status"))
+ STATPANEL_DATA_ENTRY("Chemicals", "[chemicals]")
/mob/living/simple_mob/animal/borer/proc/detatch()
if(!host || !controlling)
@@ -128,9 +123,9 @@
controlling = FALSE
host.remove_language("Cortical Link")
- host.verbs -= /mob/living/carbon/proc/release_control
- host.verbs -= /mob/living/carbon/proc/punish_host
- host.verbs -= /mob/living/carbon/proc/spawn_larvae
+ remove_verb(host, /mob/living/carbon/proc/release_control)
+ remove_verb(host, /mob/living/carbon/proc/punish_host)
+ remove_verb(host, /mob/living/carbon/proc/spawn_larvae)
if(host_brain)
// these are here so bans and multikey warnings are not triggered on the wrong people when ckey is changed.
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_captive.dm b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_captive.dm
index 1037aa5abc6..231850e73b2 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_captive.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_captive.dm
@@ -50,9 +50,9 @@
to_chat(H, "With an immense exertion of will, you regain control of your body!")
to_chat(B.host, "You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you.")
B.detatch()
- verbs -= /mob/living/carbon/proc/release_control
- verbs -= /mob/living/carbon/proc/punish_host
- verbs -= /mob/living/carbon/proc/spawn_larvae
+ remove_verb(src, /mob/living/carbon/proc/release_control)
+ remove_verb(src, /mob/living/carbon/proc/punish_host)
+ remove_verb(src, /mob/living/carbon/proc/spawn_larvae)
return
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_powers.dm b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_powers.dm
index 4fd65623e2a..b9e3aef02d4 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_powers.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_powers.dm
@@ -165,11 +165,11 @@
H.add_language("Cortical Link")
if(host.stat == 2)
- H.verbs |= /mob/living/carbon/human/proc/jumpstart
+ add_verb(H, /mob/living/carbon/human/proc/jumpstart)
- H.verbs |= /mob/living/carbon/human/proc/psychic_whisper
- H.verbs |= /mob/living/carbon/human/proc/tackle
- H.verbs |= /mob/living/carbon/proc/spawn_larvae
+ add_verb(H, /mob/living/carbon/human/proc/psychic_whisper)
+ add_verb(H, /mob/living/carbon/human/proc/tackle)
+ add_verb(H, /mob/living/carbon/proc/spawn_larvae)
if(H.client)
H.ghostize(0)
@@ -330,9 +330,9 @@
controlling = 1
- host.verbs += /mob/living/carbon/proc/release_control
- host.verbs += /mob/living/carbon/proc/punish_host
- host.verbs += /mob/living/carbon/proc/spawn_larvae
+ add_verb(host, /mob/living/carbon/proc/release_control)
+ add_verb(host, /mob/living/carbon/proc/punish_host)
+ add_verb(host, /mob/living/carbon/proc/spawn_larvae)
return
@@ -345,7 +345,7 @@
to_chat(usr, "Your host is already alive.")
return
- verbs -= /mob/living/carbon/human/proc/jumpstart
+ remove_verb(src, /mob/living/carbon/human/proc/jumpstart)
visible_message("With a hideous, rattling moan, [src] shudders back to life!")
rejuvenate()
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm
index 0df8c834769..46605505341 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm
@@ -56,8 +56,8 @@
/mob/living/simple_mob/animal/passive/mouse/Initialize(mapload)
. = ..()
- verbs += /mob/living/proc/ventcrawl
- verbs += /mob/living/proc/hide
+ add_verb(src, /mob/living/proc/ventcrawl)
+ add_verb(src, /mob/living/proc/hide)
if(name == initial(name))
name = "[name] ([rand(1, 1000)])"
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/roach/roach.dm b/code/modules/mob/living/simple_mob/subtypes/animal/roach/roach.dm
index dc02bea92b0..e9cdd4242fd 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/roach/roach.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/roach/roach.dm
@@ -92,8 +92,8 @@
/mob/living/simple_mob/animal/roach/Initialize(mapload)
. = ..()
- verbs += /mob/living/proc/ventcrawl
- verbs += /mob/living/proc/hide
+ add_verb(src, /mob/living/proc/ventcrawl)
+ add_verb(src, /mob/living/proc/hide)
if(name == initial(name))
name = "[name] ([rand(1, 1000)])"
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/frostfly.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/frostfly.dm
index fd9a1d636c8..9711c03e964 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/frostfly.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/frostfly.dm
@@ -84,8 +84,8 @@
/mob/living/simple_mob/animal/sif/frostfly/Initialize(mapload)
. = ..()
smoke_special = new
- verbs += /mob/living/proc/ventcrawl
- verbs += /mob/living/proc/hide
+ add_verb(src, /mob/living/proc/ventcrawl)
+ add_verb(src, /mob/living/proc/hide)
/datum/say_list/frostfly
speak = list("Zzzz.", "Kss.", "Zzt?")
@@ -109,15 +109,11 @@
if(energy < max_energy)
energy++
-/mob/living/simple_mob/animal/sif/frostfly/Stat()
- ..()
- if(client.statpanel == "Status")
- statpanel("Status")
- if(SSemergencyshuttle)
- var/eta_status = SSemergencyshuttle.get_status_panel_eta()
- if(eta_status)
- stat(null, eta_status)
- stat("Energy", energy)
+/mob/living/simple_mob/animal/sif/frostfly/statpanel_data(client/C)
+ . = ..()
+ if(C.statpanel_tab("Status"))
+ STATPANEL_DATA_LINE("")
+ STATPANEL_DATA_ENTRY("Energy", energy)
/mob/living/simple_mob/animal/sif/frostfly/should_special_attack(atom/A)
if(energy >= 20)
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/leech.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/leech.dm
index 3cf9eb8524c..04e08ee8256 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/leech.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/leech.dm
@@ -118,18 +118,14 @@
/mob/living/simple_mob/animal/sif/leech/Initialize(mapload)
. = ..()
- verbs += /mob/living/proc/ventcrawl
- verbs += /mob/living/proc/hide
+ add_verb(src, /mob/living/proc/ventcrawl)
+ add_verb(src, /mob/living/proc/hide)
-/mob/living/simple_mob/animal/sif/leech/Stat()
- ..()
- if(client.statpanel == "Status")
- statpanel("Status")
- if(SSemergencyshuttle)
- var/eta_status = SSemergencyshuttle.get_status_panel_eta()
- if(eta_status)
- stat(null, eta_status)
- stat("Chemicals", chemicals)
+/mob/living/simple_mob/animal/sif/leech/statpanel_data(client/C)
+ . = ..()
+ if(C.statpanel_tab("Status"))
+ STATPANEL_DATA_LINE("")
+ STATPANEL_DATA_ENTRY("Chemicals", chemicals)
/mob/living/simple_mob/animal/sif/leech/do_special_attack(atom/A)
. = TRUE
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/racoon.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/racoon.dm
index ebb1799fc27..9de640fbd88 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/racoon.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/racoon.dm
@@ -154,8 +154,8 @@
/mob/living/simple_mob/animal/sif/sakimm/Initialize(mapload)
. = ..()
- verbs += /mob/living/proc/ventcrawl
- verbs += /mob/living/proc/hide
+ add_verb(src, /mob/living/proc/ventcrawl)
+ add_verb(src, /mob/living/proc/hide)
if(randomize_size)
adjust_scale(rand(8, 11) / 10)
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/mouse_army.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/mouse_army.dm
index e283e1f32db..4f84bbce2bd 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/space/mouse_army.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/mouse_army.dm
@@ -98,8 +98,8 @@
/mob/living/simple_mob/animal/space/mouse_army/Initialize(mapload)
. = ..()
- verbs += /mob/living/proc/ventcrawl
- verbs += /mob/living/proc/hide
+ add_verb(src, /mob/living/proc/ventcrawl)
+ add_verb(src, /mob/living/proc/hide)
if(name == initial(name))
name = "[name] ([rand(1, 1000)])"
diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm b/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm
index 1f14e0ad39c..c2b4e4fcf8d 100644
--- a/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm
@@ -79,7 +79,7 @@
emote_hear = list("squishes")
/mob/living/simple_mob/slime/Initialize(mapload)
- verbs += /mob/living/proc/ventcrawl
+ add_verb(src, /mob/living/proc/ventcrawl)
update_mood()
glow_color = color
handle_light()
diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/subtypes.dm b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/subtypes.dm
index eb53fb8a4b6..062f9c10deb 100644
--- a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/subtypes.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/subtypes.dm
@@ -606,7 +606,7 @@
/mob/living/simple_mob/slime/xenobio/gold/slimebatoned(mob/living/user, amount)
power_charge = between(0, power_charge + amount, 10)
-/mob/living/simple_mob/slime/xenobio/gold/get_description_interaction() // So it doesn't say to use a baton on them.
+/mob/living/simple_mob/slime/xenobio/gold/get_description_interaction(mob/user) // So it doesn't say to use a baton on them.
return list()
diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/xenobio.dm b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/xenobio.dm
index b32f02f3bf7..3ed39cfad9b 100644
--- a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/xenobio.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/xenobio.dm
@@ -252,11 +252,11 @@
step_away(baby, src)
return baby
-/mob/living/simple_mob/slime/xenobio/get_description_interaction()
+/mob/living/simple_mob/slime/xenobio/get_description_interaction(mob/user)
var/list/results = list()
if(!stat)
- results += "[desc_panel_image("slimebaton")]to stun the slime, if it's being bad."
+ results += "[desc_panel_image("slimebaton", user)]to stun the slime, if it's being bad."
results += ..()
diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm b/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm
index 6d6da467b68..c706b628850 100644
--- a/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm
@@ -56,7 +56,7 @@
/obj/effect))
/mob/living/simple_mob/vore/hostile/morph/Initialize(mapload)
- verbs += /mob/living/proc/ventcrawl
+ add_verb(src, /mob/living/proc/ventcrawl)
return ..()
/mob/living/simple_mob/vore/hostile/morph/proc/allowed(atom/movable/A)
diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm
index 3fb1ae6d9ab..e43841315fe 100644
--- a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm
@@ -214,15 +214,14 @@
add_overlay(tailimage)
add_overlay(eye_icon_state)
-/mob/living/simple_mob/shadekin/Stat()
+/mob/living/simple_mob/shadekin/statpanel_data(client/C)
. = ..()
- if(statpanel("Shadekin"))
- abilities_stat()
-
-/mob/living/simple_mob/shadekin/proc/abilities_stat()
- for(var/A in shadekin_abilities)
- var/obj/effect/shadekin_ability/ability = A
- stat("[ability.ability_name]",ability.atom_button_text())
+ if(C.statpanel_tab("Shadekin"))
+ STATPANEL_DATA_LINE("")
+ for(var/A in shadekin_abilities)
+ var/obj/effect/shadekin_ability/ability = A
+ ability.atom_button_text()
+ STATPANEL_DATA_CLICK("[ability.ability_name]", "[ability.name]", "\ref[ability]")
//They phase back to the dark when killed
/mob/living/simple_mob/shadekin/death(gibbed, deathmessage = "phases to somewhere far away!")
diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm b/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm
index cc90ec97958..6d625e24b8c 100644
--- a/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm
@@ -62,7 +62,7 @@ var/global/list/grub_machine_overlays = list()
sparks = new(src)
sparks.set_up()
sparks.attach(src)
- verbs += /mob/living/proc/ventcrawl
+ add_verb(src, /mob/living/proc/ventcrawl)
/mob/living/simple_mob/animal/solargrub_larva/death()
powermachine.draining = 0
diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm
index 2a51275e2e0..fe675507308 100644
--- a/code/modules/mob/login.dm
+++ b/code/modules/mob/login.dm
@@ -56,7 +56,6 @@
*/
client.statobj = src
- reload_fullscreen() // Reload any fullscreen overlays this mob has.
update_client_color()
//Reload alternate appearances
@@ -98,6 +97,8 @@
reset_perspective(no_optimizations = TRUE)
// load rendering onto client's screen
reload_rendering()
+ // reset statpanel of any verbs/whatnot
+ client.statpanel_reload()
/// Handles setting lastKnownIP and computer_id for use by the ban systems as well as checking for multikeying
/mob/proc/update_Login_details()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 9cfd2a92f8b..86930e71fa7 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -139,6 +139,11 @@
spell_masters = null
zone_sel = null
+/mob/statpanel_data(client/C)
+ . = ..()
+ if(C.statpanel_tab("Status"))
+ STATPANEL_DATA_ENTRY("Ping", "[round(client.lastping,1)]ms (Avg: [round(client.avgping,1)]ms)")
+
/// Message, type of message (1 or 2), alternative message, alt message type (1 or 2)
/mob/show_message(msg, type, alt, alt_type)
@@ -284,6 +289,13 @@
if(M.client && M.client.is_preference_enabled(/datum/client_preference/examine_look))
to_chat(M, SPAN_TINYNOTICE("\The [src] looks at \the [A]."))
+ do_examinate(A)
+
+/**
+ * examines something & sends results
+ * no pre-checks for dist/view/whatnot
+ */
+/mob/proc/do_examinate(atom/A)
var/list/result
if(client)
result = A.examine(src) // if a tree is examined but no client is there to see it, did the tree ever really exist?
@@ -725,87 +737,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
for(var/mob/M in viewers())
M.see(message)
-/**
- * Output an update to the stat panel for the client
- *
- * calculates client ping, round id, server time, time dilation and other data about the round
- * and puts it in the mob status panel on a regular loop
- */
-/mob/Stat()
- ..()
-
- //This is only called from client/Stat(), let's assume client exists.
-
- if(statpanel("Status"))
- //var/list/L = list()
- stat("Ping", "[round(client.lastping,1)]ms (Avg: [round(client.avgping,1)]ms)")
- //L += SSmapping.stat_map_name
- stat("Round ID", "[GLOB.round_id || "ERROR"]")
- // VIRGO START
- stat("Station Time", stationtime2text())
- stat("Station Date", stationdate2text())
- stat("Round Duration", roundduration2text())
- // VIRGO END
- stat("Time dilation", SStime_track.stat_time_text)
- //L += SSshuttle.emergency_shuttle_stat_text
- //stat(null, "[L.Join("\n\n")]")
-
- if(listed_turf && client)
- if(!TurfAdjacent(listed_turf))
- listed_turf = null
- else
- statpanel(listed_turf.name, null, listed_turf)
- var/list/overrides = list()
- for(var/image/I in client.images)
- if(I.loc && I.loc.loc == listed_turf && I.override)
- overrides += I.loc
- for(var/atom/A in listed_turf)
- if(!A.mouse_opacity)
- continue
- if(A.invisibility > see_invisible)
- continue
- if(overrides.len && (A in overrides))
- continue
-/*
- if(A.IsObscured())
- continue
-*/
- statpanel(listed_turf.name, null, A)
-
- if(client.holder)
- if(statpanel("MC"))
- var/turf/T = get_turf(client.eye)
- stat("Location:", COORD(T))
- stat("CPU:", "[world.cpu]")
- stat("Instances:", "[num2text(world.contents.len, 10)]")
- stat("World Time:", "[world.time]")
- stat("Real time of day:", REALTIMEOFDAY)
- GLOB.stat_entry()
- config.stat_entry()
- stat(null)
- if(Master)
- Master.stat_entry()
- else
- stat("Master Controller:", "ERROR")
- if(Failsafe)
- Failsafe.stat_entry()
- else
- stat("Failsafe Controller:", "ERROR")
- if(Master)
- stat(null)
- for(var/datum/controller/subsystem/SS in Master.subsystems)
- SS.stat_entry()
- //GLOB.GLOB.cameranet.stat_entry()
- if(statpanel("Tickets"))
- GLOB.ahelp_tickets.stat_entry()
- if(length(GLOB.sdql2_queries))
- if(statpanel("SDQL2"))
- stat("Access Global SDQL2 List", GLOB.sdql2_vv_statobj)
- for(var/i in GLOB.sdql2_queries)
- var/datum/SDQL2_query/Q = i
- Q.generate_stat()
-
-
/// Not sure what to call this. Used to check if humans are wearing an AI-controlled exosuit and hence don't need to fall over yet.
/mob/proc/can_stand_overridden()
return 0
@@ -814,8 +745,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
/mob/proc/IsAdvancedToolUser()
return 0
-
-
/mob/proc/AdjustLosebreath(amount)
losebreath = clamp(0, losebreath + amount, 25)
@@ -902,7 +831,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
visible_message("[usr] rips [selection] out of [src]'s body.","[usr] rips [selection] out of your body.")
valid_objects = get_visible_implants(0)
if(valid_objects.len == 1) //Yanking out last object - removing verb.
- src.verbs -= /mob/proc/yank_out_object
+ remove_verb(src, /mob/proc/yank_out_object)
if(ishuman(src))
var/mob/living/carbon/human/H = src
@@ -996,18 +925,22 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
/mob/verb/northfaceperm()
set hidden = 1
+ set src = usr
set_face_dir(client.client_dir(NORTH))
/mob/verb/southfaceperm()
set hidden = 1
+ set src = usr
set_face_dir(client.client_dir(SOUTH))
/mob/verb/eastfaceperm()
set hidden = 1
+ set src = usr
set_face_dir(client.client_dir(EAST))
/mob/verb/westfaceperm()
set hidden = 1
+ set src = usr
set_face_dir(client.client_dir(WEST))
/mob/proc/adjustEarDamage()
@@ -1126,6 +1059,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
set name = "diceroll"
set category = "OOC"
set desc = "Roll a random number between 1 and a chosen number."
+ set src = usr
n = round(n) // why are you putting in floats??
if(n < 2)
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 09ad69590ab..fcec5dc84fe 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -289,9 +289,6 @@
*/
var/mob/teleop = null //? This is mainly used for adghosts to hear things from their actual body.
- /// The current turf being examined in the stat panel.
- var/turf/listed_turf = null
-
var/list/active_genes=list()
var/mob_size = MOB_MEDIUM
// Used for lings to not see deadchat, and to have ghosting behave as if they were not really dead.
diff --git a/code/modules/mob/movement.dm b/code/modules/mob/movement.dm
index f453b5ee7ec..16c65caca6f 100644
--- a/code/modules/mob/movement.dm
+++ b/code/modules/mob/movement.dm
@@ -537,6 +537,7 @@
///Hidden verb to turn east
/mob/verb/eastface()
set hidden = TRUE
+ set src = usr
if(!canface())
return FALSE
setDir(EAST)
@@ -546,6 +547,7 @@
///Hidden verb to turn west
/mob/verb/westface()
set hidden = TRUE
+ set src = usr
if(!canface())
return FALSE
setDir(WEST)
@@ -555,6 +557,7 @@
///Hidden verb to turn north
/mob/verb/northface()
set hidden = TRUE
+ set src = usr
if(!canface())
return FALSE
setDir(NORTH)
@@ -564,6 +567,7 @@
///Hidden verb to turn south
/mob/verb/southface()
set hidden = TRUE
+ set src = usr
if(!canface())
return FALSE
setDir(SOUTH)
@@ -573,6 +577,7 @@
//! Pixel Shifting
/mob/verb/eastshift()
set hidden = TRUE
+ set src = usr
if(!canface())
return FALSE
if(shift_pixel_x < 16)
@@ -580,6 +585,7 @@
/mob/verb/westshift()
set hidden = TRUE
+ set src = usr
if(!canface())
return FALSE
if(shift_pixel_x > -16)
@@ -587,6 +593,7 @@
/mob/verb/northshift()
set hidden = TRUE
+ set src = usr
if(!canface())
return FALSE
if(shift_pixel_y < 16)
@@ -594,6 +601,7 @@
/mob/verb/southshift()
set hidden = TRUE
+ set src = usr
if(!canface())
return FALSE
if(shift_pixel_y > -16)
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 75238e3276b..4e8f887ba16 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -150,28 +150,28 @@
-/mob/new_player/Stat()
- ..()
-
- if(SSticker.current_state == GAME_STATE_PREGAME)
- if(statpanel("Status"))
+/mob/new_player/statpanel_data(client/C)
+ . = ..()
+ if(C.statpanel_tab("Status"))
+ STATPANEL_DATA_LINE("")
+ if(SSticker.current_state == GAME_STATE_PREGAME)
if(SSticker.hide_mode)
- stat("Game Mode:", "Secret")
+ STATPANEL_DATA_ENTRY("Game Mode:", "Secret")
else
if(SSticker.hide_mode == 0)
- stat("Game Mode:", "[config_legacy.mode_names[master_mode]]") // Old setting for showing the game mode
+ STATPANEL_DATA_ENTRY("Game Mode:", "[config_legacy.mode_names[master_mode]]") // Old setting for showing the game mode
var/time_remaining = SSticker.GetTimeLeft()
if(time_remaining > 0)
- stat(null, "Time To Start: [round(time_remaining/10)]s")
+ STATPANEL_DATA_LINE("Time To Start: [round(time_remaining/10)]s")
else if(time_remaining == -10)
- stat(null, "Time To Start: DELAYED")
+ STATPANEL_DATA_LINE("Time To Start: DELAYED")
else
- stat(null, "Time To Start: SOON")
- stat("Players: [totalPlayers]", "Players Ready: [totalPlayersReady]")
+ STATPANEL_DATA_LINE("Time To Start: SOON")
+ STATPANEL_DATA_ENTRY("Players: [totalPlayers]", "Players Ready: [totalPlayersReady]")
totalPlayers = 0
totalPlayersReady = 0
for(var/mob/new_player/player in GLOB.player_list)
- stat("[player.key]", (player.ready)?("(Playing)"):(null))
+ STATPANEL_DATA_ENTRY("[player.key]", (player.ready)?("(Playing)"):(""))
totalPlayers++
if(player.ready)totalPlayersReady++
@@ -275,7 +275,7 @@
observer.real_name = client.prefs.real_name
observer.name = observer.real_name
if(!client.holder && !config_legacy.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
- observer.verbs -= /mob/observer/dead/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
+ remove_verb(observer, /mob/observer/dead/verb/toggle_antagHUD) // Poor guys, don't know what they are missing!
observer.key = key
observer.client?.holder?.update_stealth_ghost()
observer.set_respawn_timer(time_till_respawn()) // Will keep their existing time if any, or return 0 and pass 0 into set_respawn_timer which will use the defaults
diff --git a/code/modules/modular_computers/computers/modular_computer/interaction.dm b/code/modules/modular_computers/computers/modular_computer/interaction.dm
index 02de13d17e3..4c5b4d7adb7 100644
--- a/code/modules/modular_computers/computers/modular_computer/interaction.dm
+++ b/code/modules/modular_computers/computers/modular_computer/interaction.dm
@@ -1,10 +1,10 @@
/obj/item/modular_computer/proc/update_verbs()
verbs.Cut()
if(portable_drive)
- verbs |= /obj/item/modular_computer/verb/eject_usb
+ add_obj_verb(src, /obj/item/modular_computer/verb/eject_usb)
if(card_slot)
- verbs |= /obj/item/modular_computer/verb/eject_id
- verbs |= /obj/item/modular_computer/verb/emergency_shutdown
+ add_obj_verb(src, /obj/item/modular_computer/verb/eject_id)
+ add_obj_verb(src, /obj/item/modular_computer/verb/emergency_shutdown)
// Forcibly shut down the device. To be used when something bugs out and the UI is nonfunctional.
/obj/item/modular_computer/verb/emergency_shutdown()
diff --git a/code/modules/nifsoft/nif.dm b/code/modules/nifsoft/nif.dm
index 5eba838b339..8c9ba0999d7 100644
--- a/code/modules/nifsoft/nif.dm
+++ b/code/modules/nifsoft/nif.dm
@@ -144,7 +144,7 @@ GLOBAL_LIST_INIT(nif_id_lookup, init_nif_id_lookup())
human = H
human.nif = src
stat = NIF_INSTALLING
- H.verbs |= /mob/living/carbon/human/proc/set_nif_examine
+ add_verb(H, /mob/living/carbon/human/proc/set_nif_examine)
menu = H.AddComponent(/datum/component/nif_menu)
if(starting_software)
for(var/path in starting_software)
@@ -187,7 +187,7 @@ GLOBAL_LIST_INIT(nif_id_lookup, init_nif_id_lookup())
SC.brainmobs = list()
stat = NIF_PREINSTALL
vis_update()
- H.verbs -= /mob/living/carbon/human/proc/set_nif_examine
+ remove_verb(H, /mob/living/carbon/human/proc/set_nif_examine)
QDEL_NULL(menu)
H.nif = null
human = null
@@ -678,7 +678,7 @@ GLOBAL_LIST_INIT(nif_id_lookup, init_nif_id_lookup())
set category = "OOC"
if(!nif)
- verbs -= /mob/living/carbon/human/proc/set_nif_examine
+ remove_verb(src, /mob/living/carbon/human/proc/set_nif_examine)
to_chat(src,"You don't have a NIF, not sure why this was here.")
return
diff --git a/code/modules/nifsoft/nif_tgui.dm b/code/modules/nifsoft/nif_tgui.dm
index adf7bf31354..d051fa2e6c6 100644
--- a/code/modules/nifsoft/nif_tgui.dm
+++ b/code/modules/nifsoft/nif_tgui.dm
@@ -46,7 +46,7 @@
UnregisterSignal(screen_icon, COMSIG_CLICK)
QDEL_NULL(screen_icon)
if(ishuman(parent))
- owner.verbs -= /mob/living/carbon/human/proc/nif_menu
+ remove_verb(owner, /mob/living/carbon/human/proc/nif_menu)
/datum/component/nif_menu/proc/create_mob_button(mob/user)
@@ -60,7 +60,7 @@
LAZYADD(HUD.other_important, screen_icon)
user.client?.screen += screen_icon
- user.verbs |= /mob/living/carbon/human/proc/nif_menu
+ add_verb(user, /mob/living/carbon/human/proc/nif_menu)
/datum/component/nif_menu/proc/nif_menu_click(source, location, control, params, user)
var/mob/living/carbon/human/H = user
diff --git a/code/modules/nifsoft/software/13_soulcatcher.dm b/code/modules/nifsoft/software/13_soulcatcher.dm
index e579cedf300..b1a144c47ed 100644
--- a/code/modules/nifsoft/software/13_soulcatcher.dm
+++ b/code/modules/nifsoft/software/13_soulcatcher.dm
@@ -47,14 +47,14 @@
if((. = ..()))
//nif.set_flag(NIF_O_SCOTHERS,NIF_FLAGS_OTHER) //Only required on install if the flag is in the default setting_flags list defined few lines above.
if(nif?.human)
- nif.human.verbs |= /mob/living/carbon/human/proc/nsay
- nif.human.verbs |= /mob/living/carbon/human/proc/nme
+ add_verb(nif.human, /mob/living/carbon/human/proc/nsay)
+ add_verb(nif.human, /mob/living/carbon/human/proc/nme)
/datum/nifsoft/soulcatcher/uninstall()
QDEL_LIST_NULL(brainmobs)
if((. = ..()) && nif?.human) //Sometimes NIFs are deleted outside of a human
- nif.human.verbs -= /mob/living/carbon/human/proc/nsay
- nif.human.verbs -= /mob/living/carbon/human/proc/nme
+ remove_verb(nif.human, /mob/living/carbon/human/proc/nsay)
+ remove_verb(nif.human, /mob/living/carbon/human/proc/nme)
/datum/nifsoft/soulcatcher/proc/save_settings()
if(!nif)
diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm
index 9844572c3a1..4b0f7a597d7 100644
--- a/code/modules/organs/external/_external.dm
+++ b/code/modules/organs/external/_external.dm
@@ -122,7 +122,7 @@
dislocated = 1
if(istype(owner))
- owner.verbs |= /mob/living/carbon/human/proc/relocate
+ add_verb(owner, /mob/living/carbon/human/proc/relocate)
/obj/item/organ/external/proc/relocate()
if(dislocated == -1)
@@ -136,7 +136,7 @@
for(var/obj/item/organ/external/limb in owner.organs)
if(limb.dislocated == 1)
return
- owner.verbs -= /mob/living/carbon/human/proc/relocate
+ remove_verb(owner, /mob/living/carbon/human/proc/relocate)
/obj/item/organ/external/update_health()
damage = min(max_damage, (brute_dam + burn_dam))
@@ -1147,7 +1147,7 @@ Note that amputating the affected organ does in fact remove the infection from t
owner.visible_message("\The [W] sticks in the wound!")
implants += W
owner.embedded_flag = 1
- owner.verbs += /mob/proc/yank_out_object
+ add_verb(owner, /mob/proc/yank_out_object)
W.add_blood(owner)
W.forceMove(owner)
diff --git a/code/modules/organs/internal/eyes.dm b/code/modules/organs/internal/eyes.dm
index 2a742f75dfe..72605dd4d2e 100644
--- a/code/modules/organs/internal/eyes.dm
+++ b/code/modules/organs/internal/eyes.dm
@@ -11,7 +11,7 @@
/obj/item/organ/internal/eyes/robotize()
..()
name = "optical sensor"
- verbs |= /obj/item/organ/internal/eyes/proc/change_eye_color
+ add_obj_verb(src, /obj/item/organ/internal/eyes/proc/change_eye_color)
/obj/item/organ/internal/eyes/robot
name = "optical sensor"
diff --git a/code/modules/organs/internal/species/adherent.dm b/code/modules/organs/internal/species/adherent.dm
index b2815743433..5f61836a279 100644
--- a/code/modules/organs/internal/species/adherent.dm
+++ b/code/modules/organs/internal/species/adherent.dm
@@ -63,7 +63,7 @@
/obj/item/organ/internal/powered/jets/Initialize(mapload)
. = ..()
- //verbs |= /obj/item/organ/internal/powered/jets/proc/activatej
+ //add_obj_verb(src, /obj/item/organ/internal/powered/jets/proc/activatej)
/obj/item/organ/internal/powered/jets/ui_action_click()
activatej()
@@ -104,8 +104,8 @@
/obj/item/organ/internal/powered/float/Initialize(mapload)
. = ..()
- //verbs |= /obj/item/organ/internal/powered/float/proc/flying_toggle
- verbs |= /obj/item/organ/internal/powered/float/proc/hover
+ //add_obj_verb(src, /obj/item/organ/internal/powered/float/proc/flying_toggle)
+ add_obj_verb(src, /obj/item/organ/internal/powered/float/proc/hover)
/obj/item/organ/internal/powered/float/ui_action_click()
hover()
@@ -121,7 +121,7 @@
/obj/item/organ/internal/eyes/adherent/Initialize(mapload)
. = ..()
- verbs |= /obj/item/organ/internal/eyes/proc/change_eye_color
+ add_obj_verb(src, /obj/item/organ/internal/eyes/proc/change_eye_color)
/obj/item/organ/internal/cell/adherent
@@ -151,7 +151,7 @@
/obj/item/organ/internal/powered/cooling_fins/Initialize(mapload)
. = ..()
- verbs |= /obj/item/organ/internal/powered/cooling_fins/proc/activatecf
+ add_obj_verb(src, /obj/item/organ/internal/powered/cooling_fins/proc/activatecf)
/obj/item/organ/internal/powered/cooling_fins/ui_action_click()
activatecf()
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index 536860eb125..ffbba2721b8 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -631,11 +631,11 @@
if(!removed && organ_verbs && check_verb_compatability())
for(var/verb_path in organ_verbs)
- owner.verbs |= verb_path
+ add_verb(owner, verb_path)
else if(organ_verbs)
for(var/verb_path in organ_verbs)
if(!(verb_path in save_verbs))
- owner.verbs -= verb_path
+ remove_verb(owner, verb_path)
return
/// Called when processed.
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index b63e3c0e5a0..d0f055cbb7b 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -977,7 +977,7 @@ GLOBAL_LIST_INIT(possible_cable_coil_colours, list(
else
embed_chance = force/(w_class*3)
update_icon()
- verbs -= /obj/item/stack/cable_coil/verb/make_restraint
+ remove_obj_verb(src, /obj/item/stack/cable_coil/verb/make_restraint)
/obj/item/stack/cable_coil/alien/update_icon()
icon_state = initial(icon_state)
diff --git a/code/modules/power/lighting/lightswitch.dm b/code/modules/power/lighting/lightswitch.dm
index c2d1372639b..9bdfaaad158 100644
--- a/code/modules/power/lighting/lightswitch.dm
+++ b/code/modules/power/lighting/lightswitch.dm
@@ -155,18 +155,18 @@
return
. = ..()
-/obj/structure/construction/get_description_interaction()
+/obj/structure/construction/get_description_interaction(mob/user)
. = list()
switch(stage)
if(FRAME_UNFASTENED)
. += list(
- "[desc_panel_image("screwdriver")]to continue construction.",
- "[desc_panel_image("welder")]to deconstruct.")
+ "[desc_panel_image("screwdriver", user)]to continue construction.",
+ "[desc_panel_image("welder", user)]to deconstruct.")
if(FRAME_FASTENED)
. += list(
"[desc_panel_image("cable coil")]to continue construction.",
- "[desc_panel_image("screwdriver")]to reverse construction.")
+ "[desc_panel_image("screwdriver", user)]to reverse construction.")
if(FRAME_WIRED)
. += list(
- "[desc_panel_image("screwdriver")]to finish construction.",
- "[desc_panel_image("wirecutters")]to reverse construction.")
+ "[desc_panel_image("screwdriver", user)]to finish construction.",
+ "[desc_panel_image("wirecutters", user)]to reverse construction.")
diff --git a/code/modules/preferences/_preferences.dm b/code/modules/preferences/_preferences.dm
index 813088567ac..aa4eb38d11b 100644
--- a/code/modules/preferences/_preferences.dm
+++ b/code/modules/preferences/_preferences.dm
@@ -251,15 +251,15 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(client)
if(!IsGuestKey(client.key))
- load_path(client.ckey)
- if(load_preferences())
- if(load_character())
- load_skin()
- sanitize_everything()
- player_setup.sanitize_setup()
- client.update_movement_keys()
- initialized = TRUE
- return
+ if(load_path(client.ckey))
+ if(load_preferences())
+ if(load_character())
+ load_skin()
+ sanitize_everything()
+ player_setup.sanitize_setup()
+ client.update_movement_keys()
+ initialized = TRUE
+ return
key_bindings = deep_copy_list(GLOB.hotkey_keybinding_list_by_key) // give them default keybinds and update their movement keys
client?.update_movement_keys(src)
diff --git a/code/modules/preferences/preferences_savefile.dm b/code/modules/preferences/preferences_savefile.dm
index 0febd60a965..e9d5c75822f 100644
--- a/code/modules/preferences/preferences_savefile.dm
+++ b/code/modules/preferences/preferences_savefile.dm
@@ -1,7 +1,11 @@
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
- if(!ckey) return
+ if(!ckey)
+ return FALSE
path = "data/player_saves/[copytext(ckey,1,2)]/[ckey]/[filename]"
savefile_version = SAVEFILE_VERSION_MAX
+ if(!fexists(path))
+ return FALSE
+ return TRUE
/datum/preferences/proc/load_preferences()
// todo: storage handler datums...
diff --git a/code/modules/preferences/preferences_toggle_procs.dm b/code/modules/preferences/preferences_toggle_procs.dm
index 58ffab9c8ab..383e3388df8 100644
--- a/code/modules/preferences/preferences_toggle_procs.dm
+++ b/code/modules/preferences/preferences_toggle_procs.dm
@@ -371,6 +371,7 @@
set name = "Toggle Pain Messages"
set category = "Preferences"
set desc = "Toggles pain messages."
+ set src = usr
if(painmsg)
src.painmsg = 0
@@ -383,6 +384,7 @@
set name = "Feign Impairment"
set category = "IC"
set desc = "Allows user to manually enable drunkenness, stutter, jitter, etc."
+ set src = usr
var/list/choices = list("Drunkenness", "Stuttering", "Jittering")
if(src.slurring >= 10 || src.stuttering >= 10 || src.jitteriness >= 100)
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 7e6c435c250..f3067f57007 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -140,9 +140,9 @@
if(dna_lock)
attached_lock = new /obj/item/dnalockingchip(src)
if(!dna_lock)
- verbs -= /obj/item/gun/verb/remove_dna
- verbs -= /obj/item/gun/verb/give_dna
- verbs -= /obj/item/gun/verb/allow_dna
+ remove_obj_verb(src, /obj/item/gun/verb/remove_dna)
+ remove_obj_verb(src, /obj/item/gun/verb/give_dna)
+ remove_obj_verb(src, /obj/item/gun/verb/allow_dna)
if(pin)
pin = new pin(src)
@@ -276,9 +276,9 @@
to_chat(user, "You insert \the [A] into \the [src].")
attached_lock = A
dna_lock = 1
- verbs += /obj/item/gun/verb/remove_dna
- verbs += /obj/item/gun/verb/give_dna
- verbs += /obj/item/gun/verb/allow_dna
+ add_obj_verb(src, /obj/item/gun/verb/remove_dna)
+ add_obj_verb(src, /obj/item/gun/verb/give_dna)
+ add_obj_verb(src, /obj/item/gun/verb/allow_dna)
return
if(A.is_screwdriver())
@@ -290,9 +290,9 @@
user.put_in_hands(attached_lock)
dna_lock = 0
attached_lock = null
- verbs -= /obj/item/gun/verb/remove_dna
- verbs -= /obj/item/gun/verb/give_dna
- verbs -= /obj/item/gun/verb/allow_dna
+ remove_obj_verb(src, /obj/item/gun/verb/remove_dna)
+ remove_obj_verb(src, /obj/item/gun/verb/give_dna)
+ remove_obj_verb(src, /obj/item/gun/verb/allow_dna)
else
to_chat(user, "\The [src] is not accepting modifications at this time.")
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index dd2ecbe74ad..41a532e85ba 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -225,12 +225,12 @@
START_PROCESSING(SSobj, src)
update_icon()
-/obj/item/gun/energy/get_description_interaction()
+/obj/item/gun/energy/get_description_interaction(mob/user)
var/list/results = list()
if(!battery_lock && !self_recharge)
if(power_supply)
- results += "[desc_panel_image("offhand")]to remove the weapon cell."
+ results += "[desc_panel_image("offhand", user)]to remove the weapon cell."
else
results += "[desc_panel_image("weapon cell")]to add a new weapon cell."
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index dc5352844b5..02974075ec2 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -186,6 +186,7 @@
set category = "Object"
set name = "Use Scope"
set popup_menu = 1
+ set src in usr
toggle_scope(2.0)
@@ -221,6 +222,7 @@
set category = "Object"
set name = "Aim Down Sights"
set popup_menu = 1
+ set src in usr
toggle_scope(scope_multiplier)
diff --git a/code/modules/projectiles/guns/energy/sizegun_vr.dm b/code/modules/projectiles/guns/energy/sizegun_vr.dm
index d9b108fb513..d398e8b6c33 100644
--- a/code/modules/projectiles/guns/energy/sizegun_vr.dm
+++ b/code/modules/projectiles/guns/energy/sizegun_vr.dm
@@ -25,7 +25,7 @@
/obj/item/gun/energy/sizegun/Initialize(mapload)
. = ..()
- verbs += /obj/item/gun/energy/sizegun/proc/select_size
+ add_obj_verb(src, /obj/item/gun/energy/sizegun/proc/select_size)
/obj/item/gun/energy/sizegun/attack_self(mob/user)
. = ..()
diff --git a/code/modules/reagents/machinery/dispenser/reagent_tank.dm b/code/modules/reagents/machinery/dispenser/reagent_tank.dm
index 68e7a0e8161..523d686777b 100644
--- a/code/modules/reagents/machinery/dispenser/reagent_tank.dm
+++ b/code/modules/reagents/machinery/dispenser/reagent_tank.dm
@@ -28,7 +28,7 @@
reagents = R
R.my_atom = src
if (!possible_transfer_amounts)
- src.verbs -= /obj/structure/reagent_dispensers/verb/set_APTFT
+ remove_obj_verb(src, /obj/structure/reagent_dispensers/verb/set_APTFT)
// InputSocket = new(src)
// InputSocket.carrier = src
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index b8971318244..29e87cce499 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -19,7 +19,7 @@
/obj/item/reagent_containers/Initialize(mapload)
. = ..()
if(!possible_transfer_amounts)
- src.verbs -= /obj/item/reagent_containers/verb/set_APTFT
+ remove_obj_verb(src, /obj/item/reagent_containers/verb/set_APTFT)
create_reagents(volume)
/obj/item/reagent_containers/attack_self(mob/user as mob)
diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm
index a6aee8507c2..4af208415e9 100644
--- a/code/modules/reagents/reagent_containers/spray.dm
+++ b/code/modules/reagents/reagent_containers/spray.dm
@@ -20,7 +20,7 @@
/obj/item/reagent_containers/spray/Initialize(mapload)
. = ..()
- src.verbs -= /obj/item/reagent_containers/verb/set_APTFT
+ remove_obj_verb(src, /obj/item/reagent_containers/verb/set_APTFT)
/obj/item/reagent_containers/spray/afterattack(atom/A as mob|obj, mob/user as mob, proximity)
if(istype(A, /obj/item/storage) || istype(A, /obj/structure/table) || istype(A, /obj/structure/closet) || istype(A, /obj/item/reagent_containers) || istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart))
diff --git a/code/modules/resleeving/infomorph.dm b/code/modules/resleeving/infomorph.dm
index b3e99da0254..f65daebd29f 100644
--- a/code/modules/resleeving/infomorph.dm
+++ b/code/modules/resleeving/infomorph.dm
@@ -99,10 +99,10 @@ var/list/infomorph_emotions = list(
add_language(LANGUAGE_EAL, 1)
add_language(LANGUAGE_SIGN, 0)
- verbs += /mob/living/silicon/infomorph/proc/choose_verbs
- verbs += /mob/living/proc/hide
- verbs += /mob/living/silicon/infomorph/proc/fold_out
- verbs += /mob/living/silicon/infomorph/proc/fold_in
+ add_verb(src, /mob/living/silicon/infomorph/proc/choose_verbs)
+ add_verb(src, /mob/living/proc/hide)
+ add_verb(src, /mob/living/silicon/infomorph/proc/fold_out)
+ add_verb(src, /mob/living/silicon/infomorph/proc/fold_in)
software = default_infomorph_software.Copy()
@@ -117,18 +117,13 @@ var/list/infomorph_emotions = list(
return ..()
/////////// STAT PANEL
-/mob/living/silicon/infomorph/Stat()
- ..()
- statpanel("Status")
- if (src.client.statpanel == "Status")
- show_silenced()
-
-// this function shows the information about being silenced as a pAI in the Status panel
-/mob/living/silicon/infomorph/proc/show_silenced()
- if(src.silence_time)
- var/timeleft = round((silence_time - world.timeofday)/10 ,1)
- stat(null, "Communications system reboot in -[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
-
+/mob/living/silicon/infomorph/statpanel_data(client/C)
+ . = ..()
+ if(C.statpanel_tab("Status"))
+ STATPANEL_DATA_LINE("")
+ if(src.silence_time)
+ var/timeleft = round((silence_time - world.timeofday)/10 ,1)
+ STATPANEL_DATA_LINE("Communications system reboot in -[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
/////////// CHECKERS
/mob/living/silicon/infomorph/check_eye(var/mob/user as mob)
@@ -320,7 +315,7 @@ var/list/infomorph_emotions = list(
speak_exclamation = sayverbs[(sayverbs.len>1 ? 2 : sayverbs.len)]
speak_query = sayverbs[(sayverbs.len>2 ? 3 : sayverbs.len)]
- verbs -= /mob/living/silicon/infomorph/proc/choose_verbs
+ remove_verb(src, /mob/living/silicon/infomorph/proc/choose_verbs)
/mob/living/silicon/infomorph/lay_down()
set name = "Rest"
diff --git a/code/modules/rigsuits/_rig.dm b/code/modules/rigsuits/_rig.dm
index 7f29aa931f3..7cb32f66fae 100644
--- a/code/modules/rigsuits/_rig.dm
+++ b/code/modules/rigsuits/_rig.dm
@@ -156,18 +156,18 @@
air_supply = new air_type(src)
if(glove_type)
gloves = new glove_type(src)
- verbs |= /obj/item/rig/proc/toggle_gauntlets
+ add_obj_verb(src, /obj/item/rig/proc/toggle_gauntlets)
if(helm_type)
helmet = new helm_type(src)
- verbs |= /obj/item/rig/proc/toggle_helmet
+ add_obj_verb(src, /obj/item/rig/proc/toggle_helmet)
if(boot_type)
boots = new boot_type(src)
- verbs |= /obj/item/rig/proc/toggle_boots
+ add_obj_verb(src, /obj/item/rig/proc/toggle_boots)
if(chest_type)
chest = new chest_type(src)
if(allowed)
chest.allowed = allowed
- verbs |= /obj/item/rig/proc/toggle_chest
+ add_obj_verb(src, /obj/item/rig/proc/toggle_chest)
for(var/obj/item/piece in list(gloves,helmet,boots,chest))
if(!istype(piece))
@@ -622,14 +622,6 @@
cell.use(cost*10)
return 1
-// this function displays the current cell charge in the stat panel
-/obj/item/rig/proc/show_cell_power()
- if(cell)
- stat(null, text("Charge Left: [round(cell.percent())]%"))
- stat(null, text("Cell Rating: [round(cell.maxcharge)]")) // Round just in case we somehow get crazy values
- else
- stat(null, text("No Cell Inserted!"))
-
/obj/item/rig/nano_ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/nano_state = inventory_state)
if(!user)
return
@@ -1159,13 +1151,6 @@
var/atom/movable/screen/cells = null
-// update the status screen display
-/obj/item/rig/Stat()
- ..()
- if (statpanel("Status"))
- show_cell_power()
-
-
#undef ONLY_DEPLOY
#undef ONLY_RETRACT
#undef SEAL_DELAY
diff --git a/code/modules/rigsuits/modules/computer.dm b/code/modules/rigsuits/modules/computer.dm
index 9bf6d68df43..a40f74e7807 100644
--- a/code/modules/rigsuits/modules/computer.dm
+++ b/code/modules/rigsuits/modules/computer.dm
@@ -54,12 +54,12 @@
else
integrated_ai.get_rig_stats = 0
-/mob/living/Stat()
+/mob/living/statpanel_data(client/C)
. = ..()
if(get_rig_stats)
var/obj/item/rig/rig = get_rig()
if(rig)
- SetupStat(rig)
+ . += legacy_rig_stat(rig, C)
/obj/item/rig_module/ai_container/proc/update_verb_holder()
if(!verb_holder)
diff --git a/code/modules/rigsuits/modules/modules.dm b/code/modules/rigsuits/modules/modules.dm
index 3b464bca698..f8e83f05307 100644
--- a/code/modules/rigsuits/modules/modules.dm
+++ b/code/modules/rigsuits/modules/modules.dm
@@ -227,26 +227,28 @@
/obj/item/rig_module/proc/accepts_item(var/obj/item/input_device)
return 0
-/mob/living/carbon/human/Stat()
+/mob/living/carbon/human/statpanel_data(client/C)
. = ..()
if(istype(back,/obj/item/rig))
var/obj/item/rig/R = back
- SetupStat(R)
-
+ . += legacy_rig_stat(R, C)
else if(istype(belt,/obj/item/rig))
var/obj/item/rig/R = belt
- SetupStat(R)
+ . += legacy_rig_stat(R, C)
+ else
+ C.statpanel_tab("Hardsuit Modules", FALSE)
-/mob/proc/SetupStat(var/obj/item/rig/R)
- if(R?.is_activated() && 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)
- }
+/mob/proc/legacy_rig_stat(obj/item/rig/R, client/C)
+ var/needed = R.is_activated() && length(R.installed_modules)
+ . = list()
+ if(!C.statpanel_tab("Hardsuit Modules", needed))
+ return
+ var/cell_status = R.cell ? "[R.cell.charge]/[R.cell.maxcharge]" : "ERROR"
+ STATPANEL_DATA_ENTRY("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())
+ STATPANEL_DATA_CLICK(SRM.module.interface_name, SRM.name, REF(SRM))
/stat_rig_module
parent_type = /atom/movable
@@ -263,6 +265,9 @@
/stat_rig_module/proc/CanUse()
return 0
+/stat_rig_module/statpanel_click(client/C, action, auth)
+ Click()
+
/stat_rig_module/Click()
if(CanUse())
var/list/href_list = list(
diff --git a/code/modules/rigsuits/rig_verbs.dm b/code/modules/rigsuits/rig_verbs.dm
index 533febedf2d..4cbd3c4ec23 100644
--- a/code/modules/rigsuits/rig_verbs.dm
+++ b/code/modules/rigsuits/rig_verbs.dm
@@ -1,3 +1,11 @@
+/obj/item/rig/pickup(mob/user, flags, atom/oldLoc)
+ . = ..()
+ user?.client?.queue_legacy_verb_update()
+
+/obj/item/rig/dropped(mob/user, flags, atom/newLoc)
+ . = ..()
+ user?.client?.queue_legacy_verb_update()
+
// Interface for humans.
/obj/item/rig/verb/hardsuit_interface()
diff --git a/code/modules/species/promethean/promethean_blob.dm b/code/modules/species/promethean/promethean_blob.dm
index 08e90387688..1d829cf22cd 100644
--- a/code/modules/species/promethean/promethean_blob.dm
+++ b/code/modules/species/promethean/promethean_blob.dm
@@ -31,14 +31,14 @@
var/rad_glow = 0
/mob/living/simple_mob/slime/promethean/Initialize(mapload, null)
- verbs += /mob/living/simple_mob/slime/promethean/proc/prommie_blobform
- verbs += /mob/living/proc/set_size
- verbs += /mob/living/proc/hide
- verbs += /mob/living/simple_mob/proc/animal_nom
- verbs += /mob/living/proc/shred_limb
- verbs += /mob/living/simple_mob/slime/promethean/proc/toggle_expand
- verbs += /mob/living/simple_mob/slime/promethean/proc/prommie_select_colour
- verbs += /mob/living/simple_mob/slime/promethean/proc/toggle_shine
+ add_verb(src, /mob/living/simple_mob/slime/promethean/proc/prommie_blobform)
+ add_verb(src, /mob/living/proc/set_size)
+ add_verb(src, /mob/living/proc/hide)
+ add_verb(src, /mob/living/simple_mob/proc/animal_nom)
+ add_verb(src, /mob/living/proc/shred_limb)
+ add_verb(src, /mob/living/simple_mob/slime/promethean/proc/toggle_expand)
+ add_verb(src, /mob/living/simple_mob/slime/promethean/proc/prommie_select_colour)
+ add_verb(src, /mob/living/simple_mob/slime/promethean/proc/toggle_shine)
update_mood()
if(rad_glow)
rad_glow = clamp(rad_glow,0,250)
@@ -62,10 +62,10 @@
qdel(stored_blob)
return ..()
-/mob/living/simple_mob/slime/promethean/Stat()
- ..()
+/mob/living/simple_mob/slime/promethean/statpanel_data(client/C)
+ . = ..()
if(humanform)
- humanform.species.Stat(humanform)
+ . += humanform.species.statpanel_status(C, humanform)
/mob/living/simple_mob/slime/promethean/handle_special() // Should disable default slime healing, we'll use nutrition based heals instead.
if(rad_glow)
@@ -291,7 +291,7 @@
color = new_skin
update_icon()
-/mob/living/simple_mob/slime/promethean/get_description_interaction()
+/mob/living/simple_mob/slime/promethean/get_description_interaction(mob/user)
return
@@ -392,8 +392,8 @@
new_hat.forceMove(src)
blob.update_icon()
- blob.verbs -= /mob/living/proc/ventcrawl // Absolutely not.
- //blob.verbs -= /mob/living/simple_mob/proc/set_name // We already have a name.
+ remove_verb(blob, /mob/living/proc/ventcrawl) // Absolutely not.
+ //remove_verb(blob, /mob/living/simple_mob/proc/set_name) // We already have a name.
temporary_form = blob
//Mail them to nullspace
moveToNullspace()
diff --git a/code/modules/species/protean/protean_blob.dm b/code/modules/species/protean/protean_blob.dm
index 72599f6542c..555a21e442a 100644
--- a/code/modules/species/protean/protean_blob.dm
+++ b/code/modules/species/protean/protean_blob.dm
@@ -67,11 +67,11 @@
if(H)
humanform = H
refactory = locate() in humanform.internal_organs
- verbs |= /mob/living/proc/hide
- verbs |= /mob/living/simple_mob/protean_blob/proc/useradio
- verbs |= /mob/living/simple_mob/protean_blob/proc/appearanceswitch
- verbs |= /mob/living/simple_mob/protean_blob/proc/rig_transform
- verbs |= /mob/living/proc/usehardsuit
+ add_verb(src, /mob/living/proc/hide)
+ add_verb(src, /mob/living/simple_mob/protean_blob/proc/useradio)
+ add_verb(src, /mob/living/simple_mob/protean_blob/proc/appearanceswitch)
+ add_verb(src, /mob/living/simple_mob/protean_blob/proc/rig_transform)
+ add_verb(src, /mob/living/proc/usehardsuit)
INVOKE_ASYNC(src, /mob/living/proc/updatehealth)
else
update_icon()
@@ -88,11 +88,10 @@
/mob/living/simple_mob/protean_blob/init_vore()
return //Don't make a random belly, don't waste your time
-/mob/living/simple_mob/protean_blob/Stat()
- ..()
- if(humanform)
- humanform.species.Stat(humanform)
-
+/mob/living/simple_mob/protean_blob/statpanel_data(client/C)
+ . = ..()
+ if(humanform && C.statpanel_tab("Species", TRUE))
+ . += humanform.species.statpanel_status(C, humanform)
/mob/living/simple_mob/protean_blob/updatehealth()
if(humanform)
diff --git a/code/modules/species/protean/protean_powers.dm b/code/modules/species/protean/protean_powers.dm
index a4da7d29086..b0a8b2c24cb 100644
--- a/code/modules/species/protean/protean_powers.dm
+++ b/code/modules/species/protean/protean_powers.dm
@@ -372,6 +372,9 @@
/obj/effect/protean_ability/proc/atom_button_text()
return src
+/obj/effect/protean_ability/statpanel_click(client/C, action, auth)
+ Click()
+
/obj/effect/protean_ability/Click(var/location, var/control, var/params)
var/list/clickprops = params2list(params)
var/opts = clickprops["shift"]
diff --git a/code/modules/species/protean/protean_species.dm b/code/modules/species/protean/protean_species.dm
index 7d7c691977d..32545372887 100644
--- a/code/modules/species/protean/protean_species.dm
+++ b/code/modules/species/protean/protean_species.dm
@@ -146,6 +146,7 @@ I redid the calculations, as the burn weakness has been changed. This should be
/mob/living/carbon/human/proc/lick_wounds,
/mob/living/carbon/human/proc/rig_transform,
/mob/living/proc/usehardsuit) //prots get all the special verbs since they can't select traits.
+ species_statpanel = TRUE
var/global/list/abilities = list()
var/monochromatic = FALSE //IGNORE ME
@@ -262,23 +263,23 @@ I redid the calculations, as the burn weakness has been changed. This should be
/datum/species/protean/get_additional_examine_text(var/mob/living/carbon/human/H)
return ..() //Hmm, what could be done here?
-/datum/species/protean/Stat(var/mob/living/carbon/human/H)
- ..()
- if(statpanel(SPECIES_PROTEAN))
- var/obj/item/organ/internal/nano/refactory/refactory = H.nano_get_refactory()
- if(refactory && !(refactory.status & ORGAN_DEAD))
- stat(null, "- -- --- Refactory Metal Storage --- -- -")
- var/max = refactory.max_storage
- for(var/material in refactory.materials)
- var/amount = refactory.get_stored_material(material)
- stat("[capitalize(material)]", "[amount]/[max]")
- else
- stat(null, "- -- --- REFACTORY ERROR! --- -- -")
+/datum/species/protean/statpanel_status(client/C, mob/living/carbon/human/H)
+ . = ..()
+ var/obj/item/organ/internal/nano/refactory/refactory = H.nano_get_refactory()
+ if(refactory && !(refactory.status & ORGAN_DEAD))
+ STATPANEL_DATA_LINE("- -- --- Refactory Metal Storage --- -- -")
+ var/max = refactory.max_storage
+ for(var/material in refactory.materials)
+ var/amount = refactory.get_stored_material(material)
+ STATPANEL_DATA_ENTRY("[capitalize(material)]", "[amount]/[max]")
+ else
+ STATPANEL_DATA_LINE("- -- --- REFACTORY ERROR! --- -- -")
- stat(null, "- -- --- Abilities (Shift+LMB Examines) --- -- -")
- for(var/ability in abilities)
- var/obj/effect/protean_ability/A = ability
- stat("[A.ability_name]",A.atom_button_text())
+ STATPANEL_DATA_LINE("- -- --- Abilities (Shift+LMB Examines) --- -- -")
+ for(var/ability in abilities)
+ var/obj/effect/protean_ability/A = ability
+ A.atom_button_text()
+ STATPANEL_DATA_CLICK("[icon2html(A, C)] [A.ability_name]", "[A.name]", "\ref[A]")
// Various modifiers
/datum/modifier/protean
diff --git a/code/modules/species/shadekin/shadekin.dm b/code/modules/species/shadekin/shadekin.dm
index fc82fba4a23..88bfedc4ede 100644
--- a/code/modules/species/shadekin/shadekin.dm
+++ b/code/modules/species/shadekin/shadekin.dm
@@ -159,7 +159,7 @@
H.ability_master = new /atom/movable/screen/movable/ability_master/shadekin(H)
for(var/datum/power/shadekin/P in shadekin_ability_datums)
if(!(P.verbpath in H.verbs))
- H.verbs += P.verbpath
+ add_verb(H, P.verbpath)
H.ability_master.add_shadekin_ability(
object_given = H,
verb_given = P.verbpath,
diff --git a/code/modules/species/shadekin/shadekin_blackeyed.dm b/code/modules/species/shadekin/shadekin_blackeyed.dm
index 90054e7ebb2..a98b21f9d9b 100644
--- a/code/modules/species/shadekin/shadekin_blackeyed.dm
+++ b/code/modules/species/shadekin/shadekin_blackeyed.dm
@@ -149,7 +149,7 @@
H.ability_master = new /atom/movable/screen/movable/ability_master/crew_shadekin(H)
for(var/datum/power/crew_shadekin/P in crew_shadekin_ability_datums)
if(!(P.verbpath in H.verbs))
- H.verbs += P.verbpath
+ add_verb(H, P.verbpath)
H.ability_master.add_crew_shadekin_ability(
object_given = H,
verb_given = P.verbpath,
diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm
index f878b2692df..e299ccc9943 100644
--- a/code/modules/species/species.dm
+++ b/code/modules/species/species.dm
@@ -451,6 +451,8 @@
var/wing_animation
var/icobase_wing
var/wikilink = null //link to wiki page for species
+ /// do we have a species statpanel?
+ var/species_statpanel = FALSE
//!Weaver abilities
var/is_weaver = FALSE
@@ -708,16 +710,12 @@ GLOBAL_LIST_INIT(species_oxygen_tank_by_gas, list(
"You hug [target] to make [t_him] feel better!")
/datum/species/proc/remove_inherent_verbs(var/mob/living/carbon/human/H)
- if(inherent_verbs)
- for(var/verb_path in inherent_verbs)
- H.verbs -= verb_path
- return
+ if(!inherent_verbs)
+ return
+ remove_verb(H, inherent_verbs)
/datum/species/proc/add_inherent_verbs(var/mob/living/carbon/human/H)
- if(inherent_verbs)
- for(var/verb_path in inherent_verbs)
- H.verbs |= verb_path
- return
+ add_verb(H, inherent_verbs)
/datum/species/proc/add_inherent_spells(var/mob/living/carbon/human/H)
if(inherent_spells)
@@ -818,8 +816,8 @@ GLOBAL_LIST_INIT(species_oxygen_tank_by_gas, list(
return FALSE
// Allow species to display interesting information in the human stat panels
-/datum/species/proc/Stat(var/mob/living/carbon/human/H)
- return
+/datum/species/proc/statpanel_status(client/C, mob/living/carbon/human/H)
+ return list()
/datum/species/proc/update_attack_types()
unarmed_attacks = list()
diff --git a/code/modules/species/station/alraune.dm b/code/modules/species/station/alraune.dm
index cc9d8161a93..405c55c9291 100644
--- a/code/modules/species/station/alraune.dm
+++ b/code/modules/species/station/alraune.dm
@@ -342,6 +342,7 @@
set name = "Select Fruit"
set desc = "Select what fruit/vegetable you wish to grow."
set category = "Abilities"
+
var/obj/item/organ/internal/fruitgland/fruit_gland
for(var/F in contents)
if(istype(F, /obj/item/organ/internal/fruitgland))
@@ -352,13 +353,11 @@
var/selection = input(src, "Choose your character's fruit type. Choosing nothing will result in a default of apples.", "Fruit Type", fruit_gland.fruit_type) as null|anything in acceptable_fruit_types
if(selection)
fruit_gland.fruit_type = selection
- verbs |= /mob/living/carbon/human/proc/alraune_fruit_pick
- verbs -= /mob/living/carbon/human/proc/alraune_fruit_select
+ add_verb(src, /mob/living/carbon/human/proc/alraune_fruit_pick)
+ remove_verb(src, /mob/living/carbon/human/proc/alraune_fruit_select)
fruit_gland.emote_descriptor = list("fruit right off of [fruit_gland.owner]!", "a fruit from [fruit_gland.owner]!")
-
else
to_chat(src, SPAN_NOTICE("You lack the organ required to produce fruit."))
- return
/mob/living/carbon/human/proc/alraune_fruit_pick()
set name = "Pick Fruit"
diff --git a/code/modules/species/station/apidaen.dm b/code/modules/species/station/apidaen.dm
index 1948c0f8405..0d74a3ed8e9 100644
--- a/code/modules/species/station/apidaen.dm
+++ b/code/modules/species/station/apidaen.dm
@@ -140,8 +140,8 @@
var/selection = input(src, "Choose your character's nectar. Choosing nothing will result in a default of honey.", "Nectar Type", honey_stomach.nectar_type) as null|anything in acceptable_nectar_types
if(selection)
honey_stomach.nectar_type = selection
- verbs |= /mob/living/carbon/human/proc/nectar_pick
- verbs -= /mob/living/carbon/human/proc/nectar_select
+ add_verb(src, /mob/living/carbon/human/proc/nectar_pick)
+ remove_verb(src, /mob/living/carbon/human/proc/nectar_select)
honey_stomach.emote_descriptor = list("nectar fresh from [honey_stomach.owner]!", "nectar from [honey_stomach.owner]!")
else
diff --git a/code/modules/species/station/diona.dm b/code/modules/species/station/diona.dm
index cb41401f4a5..db19b89b619 100644
--- a/code/modules/species/station/diona.dm
+++ b/code/modules/species/station/diona.dm
@@ -133,8 +133,8 @@
qdel(Org)
// Purge the diona verbs.
- H.verbs -= /mob/living/carbon/human/proc/diona_split_nymph
- H.verbs -= /mob/living/carbon/human/proc/regenerate
+ remove_verb(H, /mob/living/carbon/human/proc/diona_split_nymph)
+ remove_verb(H, /mob/living/carbon/human/proc/regenerate)
return
diff --git a/code/modules/species/station/station_special_abilities.dm b/code/modules/species/station/station_special_abilities.dm
index c7999d61734..5f68eca08fb 100644
--- a/code/modules/species/station/station_special_abilities.dm
+++ b/code/modules/species/station/station_special_abilities.dm
@@ -42,7 +42,7 @@
// Was dead, still dead.
else
to_chat(src, "Consciousness begins to stir as your new body awakens, ready to hatch.")
- verbs |= /mob/living/carbon/human/proc/hatch
+ add_verb(src, /mob/living/carbon/human/proc/hatch)
revive_ready = REVIVING_DONE
//Dead until nutrition injected.
@@ -60,13 +60,13 @@
//If they're still alive after regenning.
if(stat != DEAD)
to_chat(src, "Consciousness begins to stir as your new body awakens, ready to hatch..")
- verbs |= /mob/living/carbon/human/proc/hatch
+ add_verb(src, /mob/living/carbon/human/proc/hatch)
revive_ready = REVIVING_DONE
//Was alive, now dead
else if(hasnutriment())
to_chat(src, "Consciousness begins to stir as your new body awakens, ready to hatch..")
- verbs |= /mob/living/carbon/human/proc/hatch
+ add_verb(src, /mob/living/carbon/human/proc/hatch)
revive_ready = REVIVING_DONE
//Dead until nutrition injected.
@@ -84,7 +84,7 @@
if(revive_ready != REVIVING_DONE)
//Hwhat?
- verbs -= /mob/living/carbon/human/proc/hatch
+ remove_verb(src, /mob/living/carbon/human/proc/hatch)
return
var/confirm = alert(usr, "Are you sure you want to hatch right now? This will be very obvious to anyone in view.", "Confirm Regeneration", "Yes", "No")
@@ -103,7 +103,7 @@
visible_message("