mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-27 06:00:23 +01:00
Port tg statpanel (#16463)
* Port tg statpanel * Add verb descriptions using the title attribute * Fix a dreamchecker error * Remove chomp edits * Add mentor tickets to ticket panel --------- Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
co-authored by
Kashargul
parent
ed5fc193f7
commit
c07027136e
@@ -63,6 +63,10 @@
|
||||
#define SS_PAUSED 3 /// paused by mc_tick_check
|
||||
#define SS_SLEEPING 4 /// fire() slept.
|
||||
#define SS_PAUSING 5 /// in the middle of pausing
|
||||
// Subsystem init stages
|
||||
#define INITSTAGE_EARLY 1 //! Early init stuff that doesn't need to wait for mapload
|
||||
#define INITSTAGE_MAIN 2 //! Main init stage
|
||||
#define INITSTAGE_MAX 2 //! Highest initstage.
|
||||
|
||||
#define SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/##X);\
|
||||
/datum/controller/subsystem/##X/New(){\
|
||||
|
||||
+13
-1
@@ -1,15 +1,27 @@
|
||||
/// Percentage of tick to leave for master controller to run
|
||||
#define MAPTICK_MC_MIN_RESERVE 70
|
||||
#define MAPTICK_LAST_INTERNAL_TICK_USAGE (world.map_cpu)
|
||||
|
||||
#define TICK_LIMIT_RUNNING 80
|
||||
/// Tick limit used to resume things in stoplag
|
||||
#define TICK_LIMIT_TO_RUN 70
|
||||
/// Tick limit for MC while running
|
||||
#define TICK_LIMIT_MC 70
|
||||
#define TICK_LIMIT_MC_INIT_DEFAULT 98
|
||||
|
||||
/// for general usage of tick_usage
|
||||
#define TICK_USAGE world.tick_usage
|
||||
/// to be used where the result isn't checked
|
||||
#define TICK_USAGE_REAL world.tick_usage
|
||||
|
||||
/// Returns true if tick_usage is above the limit
|
||||
#define TICK_CHECK ( TICK_USAGE > Master.current_ticklimit )
|
||||
/// runs stoplag if tick_usage is above the limit
|
||||
#define CHECK_TICK ( TICK_CHECK ? stoplag() : 0 )
|
||||
|
||||
/// Returns true if tick usage is above 95, for high priority usage
|
||||
#define TICK_CHECK_HIGH_PRIORITY ( TICK_USAGE > 95 )
|
||||
/// runs stoplag if tick_usage is above 95, for high priority usage
|
||||
#define CHECK_TICK_HIGH_PRIORITY ( TICK_CHECK_HIGH_PRIORITY? stoplag() : 0 )
|
||||
|
||||
#define UNTIL(X) while(!(X)) stoplag()
|
||||
#define UNTIL(X) while(!(X)) stoplag()
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#define TURFLIST_UPDATED (1 << 0)
|
||||
#define TURFLIST_UPDATE_QUEUED (1 << 1)
|
||||
@@ -109,6 +109,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
||||
#define INIT_ORDER_SKYBOX -30 //Visual only, irrelevant to gameplay, but needs to be late enough to have overmap populated fully
|
||||
#define INIT_ORDER_TICKER -50
|
||||
#define INIT_ORDER_MAPRENAME -60 //Initiating after Ticker to ensure everything is loaded and everything we rely on us working
|
||||
#define INIT_ORDER_STATPANELS -98
|
||||
#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
|
||||
|
||||
|
||||
@@ -140,6 +141,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
||||
#define FIRE_PRIORITY_MACHINES 100
|
||||
#define FIRE_PRIORITY_TGUI 110
|
||||
#define FIRE_PRIORITY_PROJECTILES 150
|
||||
#define FIRE_PRIORITY_STATPANEL 390
|
||||
#define FIRE_PRIORITY_CHAT 400
|
||||
#define FIRE_PRIORITY_OVERLAYS 500
|
||||
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
///displays the current time into the round, with a lot of extra code just there for ensuring it looks okay after an entire day passes
|
||||
#define ROUND_TIME(...) ( "[world.time - SSticker.round_start_time > MIDNIGHT_ROLLOVER ? "[round((world.time - SSticker.round_start_time)/MIDNIGHT_ROLLOVER)]:[worldtime2text()]" : worldtime2text()]" )
|
||||
|
||||
/// Define that just has the current in-universe year for use in whatever context you might want to display that in. (For example, 2022 -> 2562 given a 540 year offset)
|
||||
#define CURRENT_STATION_YEAR (GLOB.year_integer + STATION_YEAR_OFFSET)
|
||||
|
||||
|
||||
+148
-146
@@ -97,203 +97,205 @@
|
||||
|
||||
// Ported from /tg/station
|
||||
// Creates a single icon from a given /atom or /image. Only the first argument is required.
|
||||
/proc/getFlatIcon(image/A, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE)
|
||||
//Define... defines.
|
||||
// appearance_flags indicates whether appearance_flags should be respected (at the cost of about 10-20% perf)
|
||||
/proc/getFlatIcon(image/appearance, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE, force_south = FALSE, appearance_flags = FALSE)
|
||||
// Loop through the underlays, then overlays, sorting them into the layers list
|
||||
#define PROCESS_OVERLAYS_OR_UNDERLAYS(flat, process, base_layer) \
|
||||
for (var/i in 1 to process.len) { \
|
||||
var/image/current = process[i]; \
|
||||
if (!current) { \
|
||||
continue; \
|
||||
} \
|
||||
if (current.plane != FLOAT_PLANE && current.plane != appearance.plane) { \
|
||||
continue; \
|
||||
} \
|
||||
var/current_layer = current.layer; \
|
||||
if (current_layer < 0) { \
|
||||
if (current_layer <= -1000) { \
|
||||
return flat; \
|
||||
} \
|
||||
current_layer = base_layer + appearance.layer + current_layer / 1000; \
|
||||
} \
|
||||
for (var/index_to_compare_to in 1 to layers.len) { \
|
||||
var/compare_to = layers[index_to_compare_to]; \
|
||||
if (current_layer < layers[compare_to]) { \
|
||||
layers.Insert(index_to_compare_to, current); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
layers[current] = current_layer; \
|
||||
}
|
||||
|
||||
var/static/icon/flat_template = icon('icons/effects/effects.dmi', "nothing")
|
||||
|
||||
#define BLANK icon(flat_template)
|
||||
#define SET_SELF(SETVAR) do { \
|
||||
var/icon/SELF_ICON=icon(icon(curicon, curstate, base_icon_dir),"",SOUTH,no_anim?1:null); \
|
||||
if(A.alpha<255) { \
|
||||
SELF_ICON.Blend(rgb(255,255,255,A.alpha),ICON_MULTIPLY);\
|
||||
} \
|
||||
if(A.color) { \
|
||||
if(islist(A.color)){ \
|
||||
SELF_ICON.MapColors(arglist(A.color))} \
|
||||
else{ \
|
||||
SELF_ICON.Blend(A.color,ICON_MULTIPLY)} \
|
||||
} \
|
||||
##SETVAR=SELF_ICON;\
|
||||
} while (0)
|
||||
#define INDEX_X_LOW 1
|
||||
#define INDEX_X_HIGH 2
|
||||
#define INDEX_Y_LOW 3
|
||||
#define INDEX_Y_HIGH 4
|
||||
|
||||
#define flatX1 flat_size[INDEX_X_LOW]
|
||||
#define flatX2 flat_size[INDEX_X_HIGH]
|
||||
#define flatY1 flat_size[INDEX_Y_LOW]
|
||||
#define flatY2 flat_size[INDEX_Y_HIGH]
|
||||
#define addX1 add_size[INDEX_X_LOW]
|
||||
#define addX2 add_size[INDEX_X_HIGH]
|
||||
#define addY1 add_size[INDEX_Y_LOW]
|
||||
#define addY2 add_size[INDEX_Y_HIGH]
|
||||
|
||||
if(!A || A.alpha <= 0)
|
||||
return BLANK
|
||||
|
||||
var/noIcon = FALSE
|
||||
if(!appearance || appearance.alpha <= 0)
|
||||
return icon(flat_template)
|
||||
if(start)
|
||||
if(!defdir)
|
||||
defdir = A.dir
|
||||
defdir = appearance.dir
|
||||
if(!deficon)
|
||||
deficon = A.icon
|
||||
deficon = appearance.icon
|
||||
if(!defstate)
|
||||
defstate = A.icon_state
|
||||
defstate = appearance.icon_state
|
||||
if(!defblend)
|
||||
defblend = A.blend_mode
|
||||
defblend = appearance.blend_mode
|
||||
|
||||
var/curicon = A.icon || deficon
|
||||
var/curstate = A.icon_state || defstate
|
||||
var/curicon = appearance.icon || deficon
|
||||
var/curstate = appearance.icon_state || defstate
|
||||
var/curdir = (!appearance.dir || appearance.dir == SOUTH) ? defdir : appearance.dir
|
||||
|
||||
if(!((noIcon = (!curicon))))
|
||||
var/curstates = cached_icon_states(curicon)
|
||||
if(force_south)
|
||||
curdir = SOUTH
|
||||
|
||||
var/render_icon = curicon
|
||||
|
||||
if (render_icon)
|
||||
var/curstates = icon_states(curicon)
|
||||
if(!(curstate in curstates))
|
||||
if("" in curstates)
|
||||
if ("" in curstates)
|
||||
curstate = ""
|
||||
else
|
||||
noIcon = TRUE // Do not render this object.
|
||||
render_icon = FALSE
|
||||
|
||||
var/curdir
|
||||
var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have
|
||||
var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have
|
||||
|
||||
// Use the requested dir or the atom's current dir
|
||||
curdir = defdir || A.dir
|
||||
|
||||
//Try to remove/optimize this section ASAP, CPU hog. //Slightly mitigated by implementing caching using cached_icon_states
|
||||
//Try to remove/optimize this section ASAP, CPU hog.
|
||||
//Determines if there's directionals.
|
||||
if(!noIcon && curdir != SOUTH)
|
||||
var/exist = FALSE
|
||||
var/static/list/checkdirs = list(NORTH, EAST, WEST)
|
||||
for(var/i in checkdirs) //Not using GLOB for a reason.
|
||||
if(length(cached_icon_states(icon(curicon, curstate, i))))
|
||||
exist = TRUE
|
||||
break
|
||||
if(!exist)
|
||||
if(render_icon && curdir != SOUTH)
|
||||
if (
|
||||
!length(icon_states(icon(curicon, curstate, NORTH))) \
|
||||
&& !length(icon_states(icon(curicon, curstate, EAST))) \
|
||||
&& !length(icon_states(icon(curicon, curstate, WEST))) \
|
||||
)
|
||||
base_icon_dir = SOUTH
|
||||
//
|
||||
|
||||
if(!base_icon_dir)
|
||||
base_icon_dir = curdir
|
||||
|
||||
ASSERT(!BLEND_DEFAULT) //I might just be stupid but lets make sure this define is 0.
|
||||
var/curblend = appearance.blend_mode || defblend
|
||||
|
||||
var/curblend = A.blend_mode || defblend
|
||||
|
||||
if(A.overlays.len || A.underlays.len)
|
||||
var/icon/flat = BLANK
|
||||
if(appearance.overlays.len || appearance.underlays.len)
|
||||
var/icon/flat = icon(flat_template)
|
||||
// Layers will be a sorted list of icons/overlays, based on the order in which they are displayed
|
||||
var/list/layers = list()
|
||||
var/image/copy
|
||||
// Add the atom's icon itself, without pixel_x/y offsets.
|
||||
if(!noIcon)
|
||||
copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=base_icon_dir)
|
||||
copy.color = A.color
|
||||
copy.alpha = A.alpha
|
||||
if(render_icon)
|
||||
copy = image(icon=curicon, icon_state=curstate, layer=appearance.layer, dir=base_icon_dir)
|
||||
copy.color = appearance.color
|
||||
copy.alpha = appearance.alpha
|
||||
copy.blend_mode = curblend
|
||||
layers[copy] = A.layer
|
||||
layers[copy] = appearance.layer
|
||||
|
||||
// Loop through the underlays, then overlays, sorting them into the layers list
|
||||
for(var/process_set in 0 to 1)
|
||||
var/list/process = process_set? A.overlays : A.underlays
|
||||
for(var/i in 1 to process.len)
|
||||
var/image/current = process[i]
|
||||
if(!current)
|
||||
continue
|
||||
if(current.plane != FLOAT_PLANE && current.plane != A.plane)
|
||||
continue
|
||||
var/current_layer = current.layer
|
||||
if(current_layer < 0)
|
||||
//if(current_layer <= -1000)
|
||||
//return flat
|
||||
current_layer = process_set + A.layer + current_layer / 1000
|
||||
|
||||
for(var/p in 1 to layers.len)
|
||||
var/image/cmp = layers[p]
|
||||
if(current_layer < layers[cmp])
|
||||
layers.Insert(p, current)
|
||||
break
|
||||
layers[current] = current_layer
|
||||
|
||||
//sortTim(layers, GLOBAL_PROC_REF(cmp_image_layer_asc))
|
||||
PROCESS_OVERLAYS_OR_UNDERLAYS(flat, appearance.underlays, 0)
|
||||
PROCESS_OVERLAYS_OR_UNDERLAYS(flat, appearance.overlays, 1)
|
||||
|
||||
var/icon/add // Icon of overlay being added
|
||||
|
||||
// Current dimensions of flattened icon
|
||||
var/list/flat_size = list(1, flat.Width(), 1, flat.Height())
|
||||
// Dimensions of overlay being added
|
||||
var/list/add_size[4]
|
||||
var/flatX1 = 1
|
||||
var/flatX2 = flat.Width()
|
||||
var/flatY1 = 1
|
||||
var/flatY2 = flat.Height()
|
||||
|
||||
for(var/V in layers)
|
||||
var/image/I = V
|
||||
if(I.alpha == 0)
|
||||
var/addX1 = 0
|
||||
var/addX2 = 0
|
||||
var/addY1 = 0
|
||||
var/addY2 = 0
|
||||
|
||||
for(var/image/layer_image as anything in layers)
|
||||
if(layer_image.alpha == 0)
|
||||
continue
|
||||
|
||||
if(I == copy) // 'I' is an /image based on the object being flattened.
|
||||
// variables only relevant when accounting for appearance_flags:
|
||||
var/apply_color = TRUE
|
||||
var/apply_alpha = TRUE
|
||||
|
||||
if(layer_image == copy) // 'layer_image' is an /image based on the object being flattened.
|
||||
curblend = BLEND_OVERLAY
|
||||
add = icon(I.icon, I.icon_state, base_icon_dir)
|
||||
add = icon(layer_image.icon, layer_image.icon_state, base_icon_dir)
|
||||
else // 'I' is an appearance object.
|
||||
add = getFlatIcon(image(I), curdir, curicon, curstate, curblend, FALSE, no_anim)
|
||||
var/image/layer_as_image = image(layer_image)
|
||||
if(appearance_flags)
|
||||
if(layer_as_image.appearance_flags & RESET_COLOR)
|
||||
apply_color = FALSE
|
||||
if(layer_as_image.appearance_flags & RESET_ALPHA)
|
||||
apply_alpha = FALSE
|
||||
add = getFlatIcon(layer_as_image, curdir, curicon, curstate, curblend, FALSE, no_anim, force_south, appearance_flags)
|
||||
if(!add)
|
||||
continue
|
||||
// Find the new dimensions of the flat icon to fit the added overlay
|
||||
add_size = list(
|
||||
min(flatX1, I.pixel_x+1),
|
||||
max(flatX2, I.pixel_x+add.Width()),
|
||||
min(flatY1, I.pixel_y+1),
|
||||
max(flatY2, I.pixel_y+add.Height())
|
||||
)
|
||||
|
||||
if(flat_size ~! add_size)
|
||||
// Find the new dimensions of the flat icon to fit the added overlay
|
||||
addX1 = min(flatX1, layer_image.pixel_x + 1)
|
||||
addX2 = max(flatX2, layer_image.pixel_x + add.Width())
|
||||
addY1 = min(flatY1, layer_image.pixel_y + 1)
|
||||
addY2 = max(flatY2, layer_image.pixel_y + add.Height())
|
||||
|
||||
if (
|
||||
addX1 != flatX1 \
|
||||
|| addX2 != flatX2 \
|
||||
|| addY1 != flatY1 \
|
||||
|| addY2 != flatY2 \
|
||||
)
|
||||
// Resize the flattened icon so the new icon fits
|
||||
flat.Crop(
|
||||
addX1 - flatX1 + 1,
|
||||
addY1 - flatY1 + 1,
|
||||
addX2 - flatX1 + 1,
|
||||
addY2 - flatY1 + 1
|
||||
addX1 - flatX1 + 1,
|
||||
addY1 - flatY1 + 1,
|
||||
addX2 - flatX1 + 1,
|
||||
addY2 - flatY1 + 1
|
||||
)
|
||||
flat_size = add_size.Copy()
|
||||
|
||||
flatX1 = addX1
|
||||
flatX2 = addX2
|
||||
flatY1 = addY1
|
||||
flatY2 = addY2
|
||||
|
||||
if(appearance_flags)
|
||||
// apply parent's color/alpha to the added layers if the layer didn't opt
|
||||
if(apply_color && appearance.color)
|
||||
if(islist(appearance.color))
|
||||
add.MapColors(arglist(appearance.color))
|
||||
else
|
||||
add.Blend(appearance.color, ICON_MULTIPLY)
|
||||
|
||||
if(apply_alpha && appearance.alpha < 255)
|
||||
add.Blend(rgb(255, 255, 255, appearance.alpha), ICON_MULTIPLY)
|
||||
|
||||
// Blend the overlay into the flattened icon
|
||||
flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1)
|
||||
flat.Blend(add, blendMode2iconMode(curblend), layer_image.pixel_x + 2 - flatX1, layer_image.pixel_y + 2 - flatY1)
|
||||
|
||||
if(A.color)
|
||||
if(islist(A.color))
|
||||
flat.MapColors(arglist(A.color))
|
||||
else
|
||||
flat.Blend(A.color, ICON_MULTIPLY)
|
||||
if(!appearance_flags)
|
||||
// If we didn't apply parent colors individually per layer respecting appearance_flags, then do it just the one time now
|
||||
if(appearance.color)
|
||||
if(islist(appearance.color))
|
||||
flat.MapColors(arglist(appearance.color))
|
||||
else
|
||||
flat.Blend(appearance.color, ICON_MULTIPLY)
|
||||
|
||||
if(A.alpha < 255)
|
||||
flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY)
|
||||
if(appearance.alpha < 255)
|
||||
flat.Blend(rgb(255, 255, 255, appearance.alpha), ICON_MULTIPLY)
|
||||
|
||||
if(no_anim)
|
||||
//Clean up repeated frames
|
||||
var/icon/cleaned = new /icon()
|
||||
cleaned.Insert(flat, "", SOUTH, 1, 0)
|
||||
. = cleaned
|
||||
return cleaned
|
||||
else
|
||||
. = icon(flat, "", SOUTH)
|
||||
else //There's no overlays.
|
||||
if(!noIcon)
|
||||
SET_SELF(.)
|
||||
return icon(flat, "", SOUTH)
|
||||
else if (render_icon) // There's no overlays.
|
||||
var/icon/final_icon = icon(icon(curicon, curstate, base_icon_dir), "", SOUTH, no_anim ? TRUE : null)
|
||||
|
||||
//Clear defines
|
||||
#undef flatX1
|
||||
#undef flatX2
|
||||
#undef flatY1
|
||||
#undef flatY2
|
||||
#undef addX1
|
||||
#undef addX2
|
||||
#undef addY1
|
||||
#undef addY2
|
||||
if (appearance.alpha < 255)
|
||||
final_icon.Blend(rgb(255,255,255, appearance.alpha), ICON_MULTIPLY)
|
||||
|
||||
#undef INDEX_X_LOW
|
||||
#undef INDEX_X_HIGH
|
||||
#undef INDEX_Y_LOW
|
||||
#undef INDEX_Y_HIGH
|
||||
if (appearance.color)
|
||||
if (islist(appearance.color))
|
||||
final_icon.MapColors(arglist(appearance.color))
|
||||
else
|
||||
final_icon.Blend(appearance.color, ICON_MULTIPLY)
|
||||
|
||||
#undef BLANK
|
||||
#undef SET_SELF
|
||||
return final_icon
|
||||
|
||||
#undef PROCESS_OVERLAYS_OR_UNDERLAYS
|
||||
|
||||
/proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N
|
||||
var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A.
|
||||
@@ -676,7 +678,7 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
|
||||
icon_state = thing.icon_state
|
||||
//Despite casting to atom, this code path supports mutable appearances, so let's be nice to them
|
||||
//if(isnull(icon_state) || (isatom(thing) && thing.flags_1 & HTML_USE_INITAL_ICON_1))
|
||||
if(isnull(icon_state) || isatom(thing))
|
||||
if(isnull(icon_state) && isatom(thing))
|
||||
icon_state = initial(thing.icon_state)
|
||||
if (isnull(dir))
|
||||
dir = initial(thing.dir)
|
||||
@@ -745,7 +747,7 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
|
||||
return "<img class='icon icon-[target_atom.icon_state] [custom_classes]' src='data:image/png;base64,[bicon_cache[key]]'>"
|
||||
|
||||
//Costlier version of icon2html() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs.
|
||||
/proc/costly_icon2html(thing, target, sourceonly = FALSE)
|
||||
/proc/costly_icon2html(thing, target, sourceonly = FALSE, force_south = FALSE)
|
||||
if (!thing)
|
||||
return
|
||||
//if(SSlag_switch.measures[DISABLE_USR_ICON2HTML] && usr && !HAS_TRAIT(usr, TRAIT_BYPASS_MEASURES))
|
||||
@@ -754,5 +756,5 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
|
||||
if (isicon(thing))
|
||||
return icon2html(thing, target)
|
||||
|
||||
var/icon/I = getFlatIcon(thing)
|
||||
var/icon/I = getFlatIcon(thing, force_south = force_south)
|
||||
return icon2html(I, target, sourceonly = sourceonly)
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
//Returns the world time in english
|
||||
/proc/worldtime2text()
|
||||
return gameTimestamp("hh:mm:ss", world.time)
|
||||
|
||||
#define TimeOfGame (get_game_time())
|
||||
#define TimeOfTick (TICK_USAGE*0.01*world.tick_lag)
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* handles adding verbs and updating the stat panel browser
|
||||
*
|
||||
* pass the verb type path to this instead of adding it directly to verbs so the statpanel can update
|
||||
* Arguments:
|
||||
* * target - Who the verb is being added to, client or mob typepath
|
||||
* * verb - typepath to a verb, or a list of verbs, supports lists of lists
|
||||
*/
|
||||
/proc/add_verb(client/target, verb_or_list_to_add)
|
||||
if(!target)
|
||||
CRASH("add_verb called without a target")
|
||||
if(IsAdminAdvancedProcCall())
|
||||
return
|
||||
var/mob/mob_target = null
|
||||
|
||||
if(ismob(target))
|
||||
mob_target = target
|
||||
target = mob_target.client
|
||||
else if(!istype(target, /client))
|
||||
CRASH("add_verb called on a non-mob and non-client")
|
||||
var/list/verbs_list = list()
|
||||
if(!islist(verb_or_list_to_add))
|
||||
verbs_list += verb_or_list_to_add
|
||||
else
|
||||
var/list/verb_listref = verb_or_list_to_add
|
||||
var/list/elements_to_process = verb_listref.Copy()
|
||||
while(length(elements_to_process))
|
||||
var/element_or_list = elements_to_process[length(elements_to_process)] //Last element
|
||||
elements_to_process.len--
|
||||
if(islist(element_or_list))
|
||||
elements_to_process += element_or_list //list/a += list/b adds the contents of b into a, not the reference to the list itself
|
||||
else
|
||||
verbs_list += element_or_list
|
||||
|
||||
if(mob_target)
|
||||
mob_target.verbs += verbs_list
|
||||
if(!target)
|
||||
return //Our work is done.
|
||||
else
|
||||
target.verbs += verbs_list
|
||||
|
||||
var/list/output_list = list()
|
||||
for(var/thing in verbs_list)
|
||||
var/procpath/verb_to_add = thing
|
||||
output_list[++output_list.len] = list(verb_to_add.category, verb_to_add.name, verb_to_add.desc)
|
||||
|
||||
target.stat_panel.send_message("add_verb_list", output_list)
|
||||
|
||||
/**
|
||||
* handles removing verb and sending it to browser to update, use this for removing verbs
|
||||
*
|
||||
* pass the verb type path to this instead of removing it from verbs so the statpanel can update
|
||||
* Arguments:
|
||||
* * target - Who the verb is being removed from, client or mob typepath
|
||||
* * verb - typepath to a verb, or a list of verbs, supports lists of lists
|
||||
*/
|
||||
/proc/remove_verb(client/target, verb_or_list_to_remove)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
return
|
||||
|
||||
var/mob/mob_target = null
|
||||
if(ismob(target))
|
||||
mob_target = target
|
||||
target = mob_target.client
|
||||
else if(!istype(target, /client))
|
||||
CRASH("remove_verb called on a non-mob and non-client")
|
||||
|
||||
var/list/verbs_list = list()
|
||||
if(!islist(verb_or_list_to_remove))
|
||||
verbs_list += verb_or_list_to_remove
|
||||
else
|
||||
var/list/verb_listref = verb_or_list_to_remove
|
||||
var/list/elements_to_process = verb_listref.Copy()
|
||||
while(length(elements_to_process))
|
||||
var/element_or_list = elements_to_process[length(elements_to_process)] //Last element
|
||||
elements_to_process.len--
|
||||
if(islist(element_or_list))
|
||||
elements_to_process += element_or_list //list/a += list/b adds the contents of b into a, not the reference to the list itself
|
||||
else
|
||||
verbs_list += element_or_list
|
||||
|
||||
if(mob_target)
|
||||
mob_target.verbs -= verbs_list
|
||||
if(!target)
|
||||
return //Our work is done.
|
||||
else
|
||||
target.verbs -= verbs_list
|
||||
|
||||
var/list/output_list = list()
|
||||
for(var/thing in verbs_list)
|
||||
var/procpath/verb_to_remove = thing
|
||||
output_list[++output_list.len] = list(verb_to_remove.category, verb_to_remove.name)
|
||||
|
||||
target.stat_panel.send_message("remove_verb_list", output_list)
|
||||
@@ -286,16 +286,9 @@
|
||||
/atom/proc/AltClick(var/mob/user)
|
||||
var/turf/T = get_turf(src)
|
||||
if(T && user.TurfAdjacent(T))
|
||||
user.ToggleTurfTab(T)
|
||||
user.set_listed_turf(T)
|
||||
return 1
|
||||
|
||||
/mob/proc/ToggleTurfTab(var/turf/T)
|
||||
if(listed_turf == T)
|
||||
listed_turf = null
|
||||
else
|
||||
listed_turf = T
|
||||
client.statpanel = "Turf"
|
||||
|
||||
/mob/proc/TurfAdjacent(var/turf/T)
|
||||
return T.AdjacentQuick(src)
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
if(modifiers["alt"]) // alt and alt-gr (rightalt)
|
||||
var/turf/T = get_turf(A)
|
||||
if(T && TurfAdjacent(T))
|
||||
ToggleTurfTab(T)
|
||||
set_listed_turf(T)
|
||||
return
|
||||
// You are responsible for checking config.ghost_interaction when you override this function
|
||||
// Not all of them require checking, see below
|
||||
|
||||
@@ -16,4 +16,4 @@
|
||||
|
||||
/datum/controller/proc/Recover()
|
||||
|
||||
/datum/controller/proc/stat_entry()
|
||||
/datum/controller/proc/stat_entry(msg)
|
||||
|
||||
@@ -96,8 +96,9 @@ var/datum/controller/failsafe/Failsafe
|
||||
/datum/controller/failsafe/proc/defcon_pretty()
|
||||
return defcon
|
||||
|
||||
/datum/controller/failsafe/stat_entry()
|
||||
/datum/controller/failsafe/stat_entry(msg)
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"))
|
||||
msg = "Failsafe Controller: [statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])")]"
|
||||
return msg
|
||||
|
||||
@@ -32,11 +32,12 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/controller/global_vars/stat_entry()
|
||||
/datum/controller/global_vars/stat_entry(msg)
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
stat("GLOB:", statclick.update("Edit"))
|
||||
msg = "GLOB: [statclick.update("Edit")]"
|
||||
return msg
|
||||
|
||||
/datum/controller/global_vars/vv_edit_var(var_name, var_value)
|
||||
if(gvars_datum_protected_varlist[var_name])
|
||||
|
||||
@@ -582,12 +582,14 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
|
||||
|
||||
|
||||
/datum/controller/master/stat_entry()
|
||||
/datum/controller/master/stat_entry(msg)
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
stat("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%))")
|
||||
stat("Master Controller:", statclick.update("(TickRate:[Master.processing]) (Iteration:[Master.iteration])"))
|
||||
msg = "Byond: (FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%))"
|
||||
msg += "Master Controller: [statclick.update("(TickRate:[Master.processing]) (Iteration:[Master.iteration])")]"
|
||||
|
||||
return msg
|
||||
|
||||
/datum/controller/master/StartLoadingMap(var/quiet = TRUE)
|
||||
if(map_loading)
|
||||
|
||||
@@ -164,22 +164,11 @@
|
||||
|
||||
//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc.
|
||||
/datum/controller/subsystem/stat_entry(msg)
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
|
||||
if(SS_NO_FIRE & flags)
|
||||
msg = "NO FIRE\t[msg]"
|
||||
else if(can_fire <= 0)
|
||||
msg = "OFFLINE\t[msg]"
|
||||
else
|
||||
if(can_fire && !(SS_NO_FIRE & flags))
|
||||
msg = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)]\t[msg]"
|
||||
|
||||
var/title = name
|
||||
if (can_fire)
|
||||
title = "\[[state_letter()]][title]"
|
||||
|
||||
stat(title, statclick.update(msg))
|
||||
else
|
||||
msg = "OFFLINE\t[msg]"
|
||||
return msg
|
||||
|
||||
/datum/controller/subsystem/proc/state_letter()
|
||||
switch (state)
|
||||
|
||||
@@ -12,8 +12,9 @@ SUBSYSTEM_DEF(ai)
|
||||
var/slept_mobs = 0
|
||||
var/list/process_z = list()
|
||||
|
||||
/datum/controller/subsystem/ai/stat_entry(msg_prefix)
|
||||
..("P: [processing.len] | S: [slept_mobs]")
|
||||
/datum/controller/subsystem/ai/stat_entry(msg)
|
||||
msg = "P: [processing.len] | S: [slept_mobs]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/ai/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
|
||||
@@ -9,10 +9,9 @@ SUBSYSTEM_DEF(aifast)
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
|
||||
/datum/controller/subsystem/aifast/stat_entry(msg_prefix)
|
||||
var/list/msg = list(msg_prefix)
|
||||
msg += "P:[processing.len]"
|
||||
..(msg.Join())
|
||||
/datum/controller/subsystem/aifast/stat_entry(msg)
|
||||
msg = "P:[processing.len]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/aifast/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
|
||||
@@ -244,9 +244,8 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/air/stat_entry(msg_prefix)
|
||||
var/list/msg = list(msg_prefix)
|
||||
msg += "S:[current_step ? part_names[current_step] : ""] "
|
||||
/datum/controller/subsystem/air/stat_entry(msg)
|
||||
msg = "S:[current_step ? part_names[current_step] : ""] "
|
||||
msg += "C:{"
|
||||
msg += "T [round(cost_turfs, 1)] | "
|
||||
msg += "E [round(cost_edges, 1)] | "
|
||||
@@ -263,7 +262,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
msg += "H [active_hotspots.len] | "
|
||||
msg += "Z [zones_to_update.len] "
|
||||
msg += "}"
|
||||
..(msg.Join())
|
||||
return ..()
|
||||
|
||||
// ZAS might displace objects as the map loads if an air tick is processed mid-load.
|
||||
/datum/controller/subsystem/air/StartLoadingMap(var/quiet = TRUE)
|
||||
|
||||
@@ -41,5 +41,6 @@ SUBSYSTEM_DEF(alarm)
|
||||
/datum/controller/subsystem/alarm/proc/number_of_active_alarms()
|
||||
return active_alarm_cache.len
|
||||
|
||||
/datum/controller/subsystem/alarm/stat_entry()
|
||||
..("[number_of_active_alarms()] alarm\s")
|
||||
/datum/controller/subsystem/alarm/stat_entry(msg)
|
||||
msg = "[number_of_active_alarms()] alarm\s"
|
||||
return ..()
|
||||
|
||||
@@ -20,8 +20,9 @@ SUBSYSTEM_DEF(chemistry)
|
||||
initialize_chemical_reactions()
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/chemistry/stat_entry()
|
||||
..("C: [chemical_reagents.len] | R: [chemical_reactions.len]")
|
||||
/datum/controller/subsystem/chemistry/stat_entry(msg)
|
||||
msg = "C: [chemical_reagents.len] | R: [chemical_reactions.len]"
|
||||
return ..()
|
||||
|
||||
//Chemical Reactions - Initialises all /decl/chemical_reaction into a list
|
||||
// It is filtered into multiple lists within a list.
|
||||
@@ -43,7 +44,7 @@ SUBSYSTEM_DEF(chemistry)
|
||||
// add_to = fusion_reactions_by_reagent
|
||||
if(istype(D, /decl/chemical_reaction/distilling))
|
||||
add_to = distilled_reactions_by_reagent
|
||||
|
||||
|
||||
LAZYINITLIST(add_to[reagent_id])
|
||||
add_to[reagent_id] += D
|
||||
|
||||
|
||||
@@ -41,8 +41,9 @@ SUBSYSTEM_DEF(events)
|
||||
var/datum/event_container/EC = event_containers[i]
|
||||
EC.process()
|
||||
|
||||
/datum/controller/subsystem/events/stat_entry()
|
||||
..("E:[active_events.len]")
|
||||
/datum/controller/subsystem/events/stat_entry(msg)
|
||||
msg = "E:[active_events.len]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/events/Recover()
|
||||
if(SSevents.active_events)
|
||||
|
||||
@@ -56,8 +56,9 @@ SUBSYSTEM_DEF(inactivity)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/inactivity/stat_entry()
|
||||
..("Kicked: [number_kicked]")
|
||||
/datum/controller/subsystem/inactivity/stat_entry(msg)
|
||||
msg = "Kicked: [number_kicked]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/inactivity/proc/can_kick(var/client/C)
|
||||
if(C.holder) return FALSE //VOREStation Add - Don't kick admins.
|
||||
|
||||
@@ -82,9 +82,8 @@ SUBSYSTEM_DEF(machines)
|
||||
T.broadcast_status()
|
||||
CHECK_TICK
|
||||
|
||||
/datum/controller/subsystem/machines/stat_entry()
|
||||
var/msg = list()
|
||||
msg += "C:{"
|
||||
/datum/controller/subsystem/machines/stat_entry(msg)
|
||||
msg = "C:{"
|
||||
msg += "PI:[round(cost_pipenets,1)]|"
|
||||
msg += "MC:[round(cost_machinery,1)]|"
|
||||
msg += "PN:[round(cost_powernets,1)]|"
|
||||
@@ -95,7 +94,7 @@ SUBSYSTEM_DEF(machines)
|
||||
msg += "PN:[SSmachines.powernets.len]|"
|
||||
msg += "PO:[SSmachines.powerobjs.len]|"
|
||||
msg += "MC/MS:[round((cost ? SSmachines.processing_machines.len/cost_machinery : 0),0.1)]"
|
||||
..(jointext(msg, null))
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/machines/proc/process_pipenets(resumed = 0)
|
||||
if (!resumed)
|
||||
|
||||
@@ -19,8 +19,9 @@ SUBSYSTEM_DEF(mobs)
|
||||
var/slept_mobs = 0
|
||||
var/list/process_z = list()
|
||||
|
||||
/datum/controller/subsystem/mobs/stat_entry()
|
||||
..("P: [global.mob_list.len] | S: [slept_mobs]")
|
||||
/datum/controller/subsystem/mobs/stat_entry(msg)
|
||||
msg = "P: [global.mob_list.len] | S: [slept_mobs]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/mobs/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
@@ -90,4 +91,4 @@ SUBSYSTEM_DEF(mobs)
|
||||
|
||||
/datum/controller/subsystem/mobs/critfail()
|
||||
..()
|
||||
log_recent()
|
||||
log_recent()
|
||||
|
||||
@@ -7,8 +7,9 @@ SUBSYSTEM_DEF(orbit)
|
||||
var/list/currentrun = list()
|
||||
var/list/processing = list()
|
||||
|
||||
/datum/controller/subsystem/orbit/stat_entry()
|
||||
..("P:[processing.len]")
|
||||
/datum/controller/subsystem/orbit/stat_entry(msg)
|
||||
msg = "P:[processing.len]"
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/orbit/fire(resumed = 0)
|
||||
@@ -40,5 +41,3 @@ SUBSYSTEM_DEF(orbit)
|
||||
O.Check(targetloc)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -32,8 +32,9 @@ SUBSYSTEM_DEF(overlays)
|
||||
fire(FALSE, TRUE)
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/overlays/stat_entry()
|
||||
..("Queued Atoms: [queue.len], Cache Size: [cache_size]")
|
||||
/datum/controller/subsystem/overlays/stat_entry(msg)
|
||||
msg = "Queued Atoms: [queue.len], Cache Size: [cache_size]"
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/overlays/fire(resumed, no_mc_tick)
|
||||
|
||||
@@ -12,8 +12,9 @@ SUBSYSTEM_DEF(ping)
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
var/list/currentrun = list()
|
||||
|
||||
/datum/controller/subsystem/ping/stat_entry()
|
||||
..("P:[GLOB.clients.len]")
|
||||
/datum/controller/subsystem/ping/stat_entry(msg)
|
||||
msg = "P:[GLOB.clients.len]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/ping/fire(resumed = FALSE)
|
||||
// Prepare the new batch of clients
|
||||
|
||||
@@ -22,8 +22,9 @@ SUBSYSTEM_DEF(plants)
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
|
||||
/datum/controller/subsystem/plants/stat_entry()
|
||||
..("P:[processing.len]|S:[seeds.len]")
|
||||
/datum/controller/subsystem/plants/stat_entry(msg)
|
||||
msg = "P:[processing.len]|S:[seeds.len]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/plants/Initialize(timeofday)
|
||||
setup()
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(obj_tab_items)
|
||||
name = "Obj Tab Items"
|
||||
flags = SS_NO_INIT
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
wait = 0.1 SECONDS
|
||||
|
||||
// I know this is mostly copypasta, but I want to change the processing logic
|
||||
// Sorry bestie :(
|
||||
/datum/controller/subsystem/processing/obj_tab_items/fire(resumed = FALSE)
|
||||
if (!resumed)
|
||||
currentrun = processing.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/current_run = currentrun
|
||||
|
||||
while(current_run.len)
|
||||
var/datum/thing = current_run[current_run.len]
|
||||
if(QDELETED(thing))
|
||||
processing -= thing
|
||||
else if(thing.process(wait * 0.1) == PROCESS_KILL)
|
||||
// fully stop so that a future START_PROCESSING will work
|
||||
STOP_PROCESSING(src, thing)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
current_run.len--
|
||||
@@ -24,8 +24,9 @@ SUBSYSTEM_DEF(processing)
|
||||
if(CHECK_BITFIELD(D.datum_flags, DF_ISPROCESSING))
|
||||
processing |= D
|
||||
|
||||
/datum/controller/subsystem/processing/stat_entry()
|
||||
..("[stat_tag]:[processing.len]")
|
||||
/datum/controller/subsystem/processing/stat_entry(msg)
|
||||
msg = "[stat_tag]:[processing.len]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/processing/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
@@ -69,14 +70,14 @@ SUBSYSTEM_DEF(processing)
|
||||
log_world(msg)
|
||||
return
|
||||
msg += "Lists: current_run: [currentrun.len], processing: [processing.len]\n"
|
||||
|
||||
|
||||
if(!currentrun.len)
|
||||
msg += "!!The subsystem just finished the processing list, and currentrun is empty (or has never run).\n"
|
||||
msg += "!!The info below is the tail of processing instead of currentrun.\n"
|
||||
|
||||
|
||||
var/datum/D = currentrun.len ? currentrun[currentrun.len] : processing[processing.len]
|
||||
msg += "Tail entry: [describeThis(D)] (this is likely the item AFTER the problem item)\n"
|
||||
|
||||
|
||||
var/position = processing.Find(D)
|
||||
if(!position)
|
||||
msg += "Unable to find context of tail entry in processing list.\n"
|
||||
|
||||
@@ -54,8 +54,9 @@ SUBSYSTEM_DEF(radiation)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/radiation/stat_entry()
|
||||
..("S:[sources.len], RC:[resistance_cache.len]")
|
||||
/datum/controller/subsystem/radiation/stat_entry(msg)
|
||||
msg = "S:[sources.len], RC:[resistance_cache.len]"
|
||||
return ..()
|
||||
|
||||
// Ray trace from all active radiation sources to T and return the strongest effect.
|
||||
/datum/controller/subsystem/radiation/proc/get_rads_at_turf(var/turf/T)
|
||||
@@ -144,4 +145,4 @@ SUBSYSTEM_DEF(radiation)
|
||||
if(!(power && source))
|
||||
return
|
||||
var/turf/epicentre = locate(round(world.maxx / 2), round(world.maxy / 2), source.z)
|
||||
flat_radiate(epicentre, power, world.maxx, respect_maint)
|
||||
flat_radiate(epicentre, power, world.maxx, respect_maint)
|
||||
|
||||
@@ -172,5 +172,6 @@ SUBSYSTEM_DEF(shuttles)
|
||||
for(var/obj/effect/overmap/visitable/ship/ship_effect as anything in ships)
|
||||
overmap_halted ? ship_effect.halt() : ship_effect.unhalt()
|
||||
|
||||
/datum/controller/subsystem/shuttles/stat_entry()
|
||||
..("Shuttles:[process_shuttles.len]/[shuttles.len], Ships:[ships.len], L:[registered_shuttle_landmarks.len][overmap_halted ? ", HALT" : ""]")
|
||||
/datum/controller/subsystem/shuttles/stat_entry(msg)
|
||||
msg = "Shuttles:[process_shuttles.len]/[shuttles.len], Ships:[ships.len], L:[registered_shuttle_landmarks.len][overmap_halted ? ", HALT" : ""]"
|
||||
return ..()
|
||||
|
||||
@@ -0,0 +1,481 @@
|
||||
SUBSYSTEM_DEF(statpanels)
|
||||
name = "Stat Panels"
|
||||
wait = 4
|
||||
init_order = INIT_ORDER_STATPANELS
|
||||
//init_stage = INITSTAGE_EARLY
|
||||
priority = FIRE_PRIORITY_STATPANEL
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
||||
flags = SS_NO_INIT
|
||||
var/list/currentrun = list()
|
||||
var/list/global_data
|
||||
var/list/mc_data
|
||||
var/list/cached_images = list()
|
||||
|
||||
///how many subsystem fires between most tab updates
|
||||
var/default_wait = 10
|
||||
///how many subsystem fires between updates of misc tabs
|
||||
var/misc_wait = 3
|
||||
///how many subsystem fires between updates of the status tab
|
||||
var/status_wait = 2
|
||||
///how many subsystem fires between updates of the MC tab
|
||||
var/mc_wait = 5
|
||||
///how many full runs this subsystem has completed. used for variable rate refreshes.
|
||||
var/num_fires = 0
|
||||
|
||||
/datum/controller/subsystem/statpanels/fire(resumed = FALSE)
|
||||
if (!resumed)
|
||||
num_fires++
|
||||
//var/datum/map_config/cached = SSmapping.next_map_config
|
||||
global_data = list(
|
||||
//"Map: [SSmapping.config?.map_name || "Loading..."]",
|
||||
"Map: [using_map.name]",
|
||||
//cached ? "Next Map: [cached.map_name]" : null,
|
||||
//"Next Map: -- Not Available --",
|
||||
// "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]",
|
||||
"Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]",
|
||||
"Round Time: [ROUND_TIME()]",
|
||||
"Station Date: [stationdate2text()]", // [capitalize(GLOB.world_time_season)]",
|
||||
"Station Time: [stationtime2text()]",
|
||||
"Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)"
|
||||
)
|
||||
|
||||
if(emergency_shuttle.evac)
|
||||
var/ETA = emergency_shuttle.get_status_panel_eta()
|
||||
if(ETA)
|
||||
global_data += "[ETA]"
|
||||
src.currentrun = GLOB.clients.Copy()
|
||||
mc_data = null
|
||||
|
||||
var/list/currentrun = src.currentrun
|
||||
while(length(currentrun))
|
||||
var/client/target = currentrun[length(currentrun)]
|
||||
currentrun.len--
|
||||
|
||||
if(!target?.stat_panel?.is_ready()) // Null target client, client has null stat panel, or stat panel isn't ready
|
||||
continue
|
||||
|
||||
if(target.stat_tab == "Status" && num_fires % status_wait == 0)
|
||||
set_status_tab(target)
|
||||
|
||||
if(!target.holder)
|
||||
target.stat_panel.send_message("remove_admin_tabs")
|
||||
else
|
||||
//target.stat_panel.send_message("update_split_admin_tabs", !!(target.prefs.toggles & SPLIT_ADMIN_TABS))
|
||||
target.stat_panel.send_message("update_split_admin_tabs", FALSE)
|
||||
|
||||
if(!("MC" in target.panel_tabs) || !("Tickets" in target.panel_tabs))
|
||||
target.stat_panel.send_message("add_admin_tabs", target.holder.href_token)
|
||||
|
||||
//if(target.stat_tab == "MC" && ((num_fires % mc_wait == 0) || target?.prefs.read_preference(/datum/preference/toggle/fast_mc_refresh)))
|
||||
//set_MC_tab(target)
|
||||
if(target.stat_tab == "MC" && ((num_fires % mc_wait == 0)))
|
||||
set_MC_tab(target)
|
||||
|
||||
if(target.stat_tab == "Tickets" && num_fires % default_wait == 0)
|
||||
set_tickets_tab(target)
|
||||
|
||||
if(!length(GLOB.sdql2_queries) && ("SDQL2" in target.panel_tabs))
|
||||
target.stat_panel.send_message("remove_sdql2")
|
||||
|
||||
else if(length(GLOB.sdql2_queries) && (target.stat_tab == "SDQL2" || !("SDQL2" in target.panel_tabs)) && num_fires % default_wait == 0)
|
||||
set_SDQL2_tab(target)
|
||||
|
||||
if(target.mob)
|
||||
var/mob/target_mob = target.mob
|
||||
|
||||
// Handle the action panels of the stat panel
|
||||
|
||||
var/update_actions = FALSE
|
||||
// We're on a spell tab, update the tab so we can see cooldowns progressing and such
|
||||
if(target.stat_tab in target.spell_tabs)
|
||||
update_actions = TRUE
|
||||
// We're not on a spell tab per se, but we have cooldown actions, and we've yet to
|
||||
// set up our spell tabs at all
|
||||
//if(!length(target.spell_tabs) && locate(/datum/action/cooldown) in target_mob.actions)
|
||||
//update_actions = TRUE
|
||||
|
||||
if(update_actions && num_fires % default_wait == 0)
|
||||
set_action_tabs(target, target_mob)
|
||||
//Update every fire if tab is open, otherwise update every 7 fires
|
||||
if((num_fires % misc_wait == 0))
|
||||
update_misc_tabs(target,target_mob)
|
||||
|
||||
var/datum/object_window_info/obj_window = target.obj_window
|
||||
if(obj_window)
|
||||
if(obj_window.flags & TURFLIST_UPDATE_QUEUED)
|
||||
immediate_send_stat_data(target)
|
||||
obj_window.flags = 0
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/statpanels/proc/update_misc_tabs(var/client/target,var/mob/target_mob)
|
||||
target_mob.update_misc_tabs()
|
||||
for(var/tab in target_mob.misc_tabs)
|
||||
if(target_mob.misc_tabs[tab].len == 0 && (tab in target.misc_tabs))
|
||||
target.misc_tabs -= tab
|
||||
target.stat_panel.send_message("remove_misc",tab)
|
||||
|
||||
if(target_mob.misc_tabs[tab].len > 0)
|
||||
if(!(tab in target.misc_tabs))
|
||||
target.misc_tabs += tab
|
||||
target.stat_panel.send_message("create_misc",tab)
|
||||
target.stat_panel.send_message("update_misc",list(
|
||||
TN = tab, \
|
||||
TC = target_mob.misc_tabs[tab], \
|
||||
))
|
||||
|
||||
for(var/tab in target.misc_tabs)
|
||||
if(!(tab in target_mob.misc_tabs))
|
||||
target.misc_tabs -= tab
|
||||
target.stat_panel.send_message("remove_misc",tab)
|
||||
|
||||
/datum/controller/subsystem/statpanels/proc/set_status_tab(client/target)
|
||||
if(!global_data)//statbrowser hasnt fired yet and we were called from immediate_send_stat_data()
|
||||
return
|
||||
|
||||
target.stat_panel.send_message("update_stat", list(
|
||||
global_data = global_data,
|
||||
ping_str = "Ping: -- Not Available --", // [round(target.lastping, 1)]ms (Average: [round(target.avgping, 1)]ms)",
|
||||
other_str = target.mob?.get_status_tab_items(),
|
||||
))
|
||||
|
||||
/datum/controller/subsystem/statpanels/proc/set_MC_tab(client/target)
|
||||
var/turf/eye_turf = get_turf(target.eye)
|
||||
var/coord_entry = COORD(eye_turf)
|
||||
if(!mc_data)
|
||||
generate_mc_data()
|
||||
target.stat_panel.send_message("update_mc", list(mc_data = mc_data, coord_entry = coord_entry))
|
||||
|
||||
/datum/controller/subsystem/statpanels/proc/set_examine_tab(client/target)
|
||||
var/description_holders = target.description_holders
|
||||
var/list/examine_update = list()
|
||||
|
||||
if(!target.obj_window)
|
||||
target.obj_window = new(target)
|
||||
if(!target.examine_icon && !target.obj_window.examine_target && target.stat_tab == "Examine")
|
||||
target.obj_window.examine_target = description_holders["icon"]
|
||||
target.obj_window.atoms_to_show += target.obj_window.examine_target
|
||||
START_PROCESSING(SSobj_tab_items, target.obj_window)
|
||||
refresh_client_obj_view(target)
|
||||
examine_update += "[target.examine_icon] <font size='5'>[description_holders["name"]]</font>" //The name, written in big letters.
|
||||
examine_update += "[description_holders["desc"]]" //the default examine text.
|
||||
if(description_holders["info"])
|
||||
examine_update += "<font color='#084B8A'>" + span_bold("[replacetext(description_holders["info"], "\n", "<BR>")]") + "</font><br />" //Blue, informative text.
|
||||
if(description_holders["interactions"])
|
||||
for(var/line in description_holders["interactions"])
|
||||
examine_update += "<font color='#084B8A'>" + span_bold("[line]") + "</font><br />"
|
||||
if(description_holders["fluff"])
|
||||
examine_update += "<font color='#298A08'>" + span_bold("[replacetext(description_holders["fluff"], "\n", "<BR>")]") + "</font><br />" //Green, fluff-related text.
|
||||
if(description_holders["antag"])
|
||||
examine_update += "<font color='#8A0808'>" + span_bold("[description_holders["antag"]]") + "</font><br />" //Red, malicious antag-related text
|
||||
|
||||
target.stat_panel.send_message("update_examine", examine_update)
|
||||
|
||||
/datum/controller/subsystem/statpanels/proc/set_tickets_tab(client/target)
|
||||
var/list/tickets = GLOB.ahelp_tickets.stat_entry(target)
|
||||
tickets += GLOB.mhelp_tickets.stat_entry(target)
|
||||
target.stat_panel.send_message("update_tickets", tickets)
|
||||
|
||||
/datum/controller/subsystem/statpanels/proc/set_SDQL2_tab(client/target)
|
||||
var/list/sdql2A = list()
|
||||
sdql2A[++sdql2A.len] = list("", "Access Global SDQL2 List", REF(GLOB.sdql2_vv_statobj))
|
||||
var/list/sdql2B = list()
|
||||
for(var/datum/SDQL2_query/query as anything in GLOB.sdql2_queries)
|
||||
sdql2B = query.generate_stat()
|
||||
|
||||
sdql2A += sdql2B
|
||||
target.stat_panel.send_message("update_sdql2", sdql2A)
|
||||
|
||||
/// Set up the various action tabs.
|
||||
/datum/controller/subsystem/statpanels/proc/set_action_tabs(client/target, mob/target_mob)
|
||||
return
|
||||
//var/list/actions = target_mob.get_actions_for_statpanel()
|
||||
//target.spell_tabs.Cut()
|
||||
|
||||
//for(var/action_data in actions)
|
||||
// target.spell_tabs |= action_data[1]
|
||||
|
||||
//target.stat_panel.send_message("update_spells", list(spell_tabs = target.spell_tabs, actions = actions))
|
||||
|
||||
/datum/controller/subsystem/statpanels/proc/set_turf_examine_tab(client/target, mob/target_mob)
|
||||
if(!target)//statbrowser hasnt fired yet and we were called from immediate_send_stat_data()
|
||||
return
|
||||
var/list/overrides = list()
|
||||
for(var/image/target_image as anything in target.images)
|
||||
if(!target_image.loc || target_image.loc.loc != target_mob.listed_turf || !target_image.override)
|
||||
continue
|
||||
overrides += target_image.loc
|
||||
|
||||
var/list/atoms_to_display = list(target_mob.listed_turf)
|
||||
for(var/atom/movable/turf_content as anything in target_mob.listed_turf)
|
||||
if(turf_content.mouse_opacity == MOUSE_OPACITY_TRANSPARENT)
|
||||
continue
|
||||
if(turf_content.invisibility > target_mob.see_invisible)
|
||||
continue
|
||||
if(turf_content in overrides)
|
||||
continue
|
||||
//if(turf_content.IsObscured())
|
||||
//continue
|
||||
atoms_to_display += turf_content
|
||||
|
||||
/// Set the atoms we're meant to display
|
||||
var/datum/object_window_info/obj_window = target.obj_window
|
||||
if(!obj_window)
|
||||
return // previous one no longer exists
|
||||
obj_window.atoms_to_show = atoms_to_display
|
||||
START_PROCESSING(SSobj_tab_items, obj_window)
|
||||
refresh_client_obj_view(target)
|
||||
|
||||
/datum/controller/subsystem/statpanels/proc/refresh_client_obj_view(client/refresh)
|
||||
var/list/turf_items = return_object_images(refresh)
|
||||
if(!length(turf_items)/* || !refresh.mob?.listed_turf*/)
|
||||
return
|
||||
refresh.stat_panel.send_message("update_listedturf", turf_items)
|
||||
|
||||
#define OBJ_IMAGE_LOADING "statpanels obj loading temporary"
|
||||
/// Returns all our ready object tab images
|
||||
/// Returns a list in the form list(list(object_name, object_ref, loaded_image), ...)
|
||||
/datum/controller/subsystem/statpanels/proc/return_object_images(client/load_from)
|
||||
// You might be inclined to think that this is a waste of cpu time, since we
|
||||
// A: Double iterate over atoms in the build case, or
|
||||
// B: Generate these lists over and over in the refresh case
|
||||
// It's really not very hot. The hot portion of this code is genuinely mostly in the image generation
|
||||
// So it's ok to pay a performance cost for cleanliness here
|
||||
|
||||
// No turf? go away
|
||||
/*if(!load_from.mob?.listed_turf)
|
||||
return list()*/
|
||||
var/datum/object_window_info/obj_window = load_from.obj_window
|
||||
var/list/already_seen = obj_window.atoms_to_images
|
||||
var/list/to_make = obj_window.atoms_to_imagify
|
||||
var/list/turf_items = list()
|
||||
for(var/atom/turf_item as anything in obj_window.atoms_to_show)
|
||||
// First, we fill up the list of refs to display
|
||||
// If we already have one, just use that
|
||||
var/existing_image = already_seen[turf_item]
|
||||
if(existing_image == OBJ_IMAGE_LOADING)
|
||||
continue
|
||||
// We already have it. Success!
|
||||
if(existing_image)
|
||||
if(turf_item == obj_window.examine_target) //not actually a turf item get trolled
|
||||
load_from.examine_icon = "<img src=\"[existing_image]\" />"
|
||||
obj_window.examine_target = null
|
||||
set_examine_tab(load_from)
|
||||
continue
|
||||
turf_items[++turf_items.len] = list("[turf_item.name]", REF(turf_item), existing_image)
|
||||
continue
|
||||
// Now, we're gonna queue image generation out of those refs
|
||||
to_make += turf_item
|
||||
already_seen[turf_item] = OBJ_IMAGE_LOADING
|
||||
obj_window.RegisterSignal(turf_item, COMSIG_PARENT_QDELETING, TYPE_PROC_REF(/datum/object_window_info,viewing_atom_deleted)) // we reset cache if anything in it gets deleted
|
||||
return turf_items
|
||||
|
||||
#undef OBJ_IMAGE_LOADING
|
||||
|
||||
/datum/controller/subsystem/statpanels/proc/generate_mc_data()
|
||||
mc_data = list(
|
||||
list("CPU:", world.cpu),
|
||||
list("Instances:", "[num2text(world.contents.len, 10)]"),
|
||||
list("World Time:", "[world.time]"),
|
||||
list("Globals:", GLOB.stat_entry(), "\ref[GLOB]"),
|
||||
// list("[config]:", config.stat_entry(), "\ref[config]"),
|
||||
list("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%)) (Internal Tick Usage: [round(MAPTICK_LAST_INTERNAL_TICK_USAGE,0.1)]%)"),
|
||||
list("Master Controller:", Master.stat_entry(), "\ref[Master]"),
|
||||
list("Failsafe Controller:", Failsafe.stat_entry(), "\ref[Failsafe]"),
|
||||
list("","")
|
||||
)
|
||||
for(var/datum/controller/subsystem/sub_system as anything in Master.subsystems)
|
||||
mc_data[++mc_data.len] = list("\[[sub_system.state_letter()]][sub_system.name]", sub_system.stat_entry(), "\ref[sub_system]")
|
||||
mc_data[++mc_data.len] = list("Camera Net", "Cameras: [global.cameranet.cameras.len] | Chunks: [global.cameranet.chunks.len]", "\ref[global.cameranet]")
|
||||
|
||||
///immediately update the active statpanel tab of the target client
|
||||
/datum/controller/subsystem/statpanels/proc/immediate_send_stat_data(client/target)
|
||||
if(!target.stat_panel.is_ready())
|
||||
return FALSE
|
||||
|
||||
if(target.stat_tab == "Examine")
|
||||
set_examine_tab(target)
|
||||
return TRUE
|
||||
|
||||
if(target.stat_tab == "Status")
|
||||
set_status_tab(target)
|
||||
return TRUE
|
||||
|
||||
var/mob/target_mob = target.mob
|
||||
|
||||
// Handle actions
|
||||
|
||||
var/update_actions = FALSE
|
||||
if(target.stat_tab in target.spell_tabs)
|
||||
update_actions = TRUE
|
||||
|
||||
//if(!length(target.spell_tabs) && locate(/datum/action/cooldown) in target_mob.actions)
|
||||
//update_actions = TRUE
|
||||
|
||||
if(update_actions)
|
||||
set_action_tabs(target, target_mob)
|
||||
return TRUE
|
||||
|
||||
// Handle turfs
|
||||
|
||||
if(target_mob?.listed_turf)
|
||||
if(!target_mob.TurfAdjacent(target_mob.listed_turf))
|
||||
target.stat_panel.send_message("removed_listedturf")
|
||||
target_mob.listed_turf = null
|
||||
|
||||
else if(target.stat_tab == target_mob?.listed_turf.name || !(target_mob?.listed_turf.name in target.panel_tabs))
|
||||
set_turf_examine_tab(target, target_mob)
|
||||
return TRUE
|
||||
|
||||
if(!target.holder)
|
||||
return FALSE
|
||||
|
||||
if(target.stat_tab == "MC")
|
||||
set_MC_tab(target)
|
||||
return TRUE
|
||||
|
||||
if(target.stat_tab == "Tickets")
|
||||
set_tickets_tab(target)
|
||||
return TRUE
|
||||
|
||||
if(!length(GLOB.sdql2_queries) && ("SDQL2" in target.panel_tabs))
|
||||
target.stat_panel.send_message("remove_sdql2")
|
||||
|
||||
else if(length(GLOB.sdql2_queries) && target.stat_tab == "SDQL2")
|
||||
set_SDQL2_tab(target)
|
||||
|
||||
/atom/proc/remove_from_cache()
|
||||
SIGNAL_HANDLER
|
||||
SSstatpanels.cached_images -= REF(src)
|
||||
|
||||
/// Stat panel window declaration
|
||||
/client/var/datum/tgui_window/stat_panel
|
||||
|
||||
/// Datum that holds and tracks info about a client's object window
|
||||
/// Really only exists because I want to be able to do logic with signals
|
||||
/// And need a safe place to do the registration
|
||||
/datum/object_window_info
|
||||
/// list of atoms to show to our client via the object tab, at least currently
|
||||
var/list/atoms_to_show = list()
|
||||
/// list of atom -> image string for objects we have had in the right click tab
|
||||
/// this is our caching
|
||||
var/list/atoms_to_images = list()
|
||||
/// list of atoms to turn into images for the object tab
|
||||
var/list/atoms_to_imagify = list()
|
||||
/// Our owner client
|
||||
var/client/parent
|
||||
/// Are we currently tracking a turf?
|
||||
var/actively_tracking = FALSE
|
||||
///For reusing this logic for examines
|
||||
var/atom/examine_target
|
||||
var/flags = 0
|
||||
|
||||
/datum/object_window_info/New(client/parent)
|
||||
. = ..()
|
||||
src.parent = parent
|
||||
|
||||
/datum/object_window_info/Destroy(force, ...)
|
||||
atoms_to_show = null
|
||||
atoms_to_images = null
|
||||
atoms_to_imagify = null
|
||||
parent.obj_window = null
|
||||
parent = null
|
||||
STOP_PROCESSING(SSobj_tab_items, src)
|
||||
return ..()
|
||||
|
||||
/// Takes a client, attempts to generate object images for it
|
||||
/// We will update the client with any improvements we make when we're done
|
||||
/datum/object_window_info/process(seconds_per_tick)
|
||||
// Cache the datum access for sonic speed
|
||||
var/list/to_make = atoms_to_imagify
|
||||
var/list/newly_seen = atoms_to_images
|
||||
var/index = 0
|
||||
for(index in 1 to length(to_make))
|
||||
var/atom/thing = to_make[index]
|
||||
|
||||
if(!thing) // A null thing snuck in somehow
|
||||
continue
|
||||
|
||||
var/generated_string
|
||||
if(ismob(thing) || length(thing.overlays) > 0)
|
||||
var/force_south = FALSE
|
||||
if(isliving(thing))
|
||||
force_south = TRUE
|
||||
generated_string = costly_icon2html(thing, parent, sourceonly=TRUE, force_south = force_south)
|
||||
else
|
||||
generated_string = icon2html(thing, parent, sourceonly=TRUE)
|
||||
|
||||
newly_seen[thing] = generated_string
|
||||
if(TICK_CHECK)
|
||||
to_make.Cut(1, index + 1)
|
||||
index = 0
|
||||
break
|
||||
// If we've not cut yet, do it now
|
||||
if(index)
|
||||
to_make.Cut(1, index + 1)
|
||||
SSstatpanels.refresh_client_obj_view(parent)
|
||||
if(!length(to_make))
|
||||
return PROCESS_KILL
|
||||
|
||||
/datum/object_window_info/proc/start_turf_tracking()
|
||||
if(actively_tracking)
|
||||
stop_turf_tracking()
|
||||
var/static/list/connections = list(
|
||||
COMSIG_MOVABLE_MOVED = PROC_REF(on_mob_move),
|
||||
COMSIG_MOB_LOGOUT = PROC_REF(on_mob_logout),
|
||||
)
|
||||
AddComponent(/datum/component/connect_mob_behalf, parent, connections)
|
||||
RegisterSignal(parent.mob.listed_turf, COMSIG_ATOM_ENTERED, PROC_REF(turflist_changed))
|
||||
RegisterSignal(parent.mob.listed_turf, COMSIG_ATOM_EXITED, PROC_REF(turflist_changed))
|
||||
actively_tracking = TRUE
|
||||
|
||||
/datum/object_window_info/proc/stop_turf_tracking()
|
||||
qdel(GetComponent(/datum/component/connect_mob_behalf))
|
||||
UnregisterSignal(parent.mob.listed_turf, COMSIG_ATOM_ENTERED)
|
||||
UnregisterSignal(parent.mob.listed_turf, COMSIG_ATOM_EXITED)
|
||||
actively_tracking = FALSE
|
||||
|
||||
/datum/object_window_info/proc/on_mob_move(mob/source)
|
||||
SIGNAL_HANDLER
|
||||
var/turf/listed = source.listed_turf
|
||||
if(!listed || !source.TurfAdjacent(listed))
|
||||
source.set_listed_turf(null)
|
||||
|
||||
/datum/object_window_info/proc/on_mob_logout(mob/source)
|
||||
SIGNAL_HANDLER
|
||||
on_mob_move(parent.mob)
|
||||
|
||||
/datum/object_window_info/proc/turflist_changed(mob/source)
|
||||
if(!parent)//statbrowser hasnt fired yet and we still have a pending action
|
||||
return
|
||||
SIGNAL_HANDLER
|
||||
if(!(flags & TURFLIST_UPDATED)) //Limit updates to 1 per tick
|
||||
SSstatpanels.immediate_send_stat_data(parent)
|
||||
flags |= TURFLIST_UPDATED
|
||||
else if(!(flags & TURFLIST_UPDATE_QUEUED))
|
||||
flags |= TURFLIST_UPDATE_QUEUED
|
||||
|
||||
/// Clears any cached object window stuff
|
||||
/// We use hard refs cause we'd need a signal for this anyway. Cleaner this way
|
||||
/datum/object_window_info/proc/viewing_atom_deleted(atom/deleted)
|
||||
SIGNAL_HANDLER
|
||||
atoms_to_show -= deleted
|
||||
atoms_to_imagify -= deleted
|
||||
atoms_to_images -= deleted
|
||||
|
||||
/mob/proc/set_listed_turf(turf/new_turf)
|
||||
if(!client)
|
||||
listed_turf = new_turf
|
||||
return
|
||||
if(!client.obj_window)
|
||||
client.obj_window = new(client)
|
||||
if(!new_turf)
|
||||
client.obj_window.stop_turf_tracking() //Needs to go before listed_turf is set to null so signals can be removed
|
||||
listed_turf = new_turf
|
||||
|
||||
if(listed_turf)
|
||||
client.stat_panel.send_message("create_listedturf", listed_turf.name)
|
||||
client.obj_window.start_turf_tracking()
|
||||
else
|
||||
client.stat_panel.send_message("remove_listedturf")
|
||||
@@ -39,8 +39,9 @@ SUBSYSTEM_DEF(supply)
|
||||
/datum/controller/subsystem/supply/fire()
|
||||
points += points_per_process
|
||||
|
||||
/datum/controller/subsystem/supply/stat_entry()
|
||||
..("Points: [points]")
|
||||
/datum/controller/subsystem/supply/stat_entry(msg)
|
||||
msg = "Points: [points]"
|
||||
return ..()
|
||||
|
||||
//To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types.
|
||||
/datum/controller/subsystem/supply/proc/forbidden_atoms_check(atom/A)
|
||||
|
||||
@@ -35,8 +35,9 @@ SUBSYSTEM_DEF(tgui)
|
||||
/datum/controller/subsystem/tgui/Shutdown()
|
||||
close_all_uis()
|
||||
|
||||
/datum/controller/subsystem/tgui/stat_entry()
|
||||
..("P:[all_uis.len]")
|
||||
/datum/controller/subsystem/tgui/stat_entry(msg)
|
||||
msg = "P:[all_uis.len]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/tgui/fire(resumed = FALSE)
|
||||
if(!resumed)
|
||||
|
||||
@@ -9,8 +9,9 @@ SUBSYSTEM_DEF(throwing)
|
||||
var/list/currentrun
|
||||
var/list/processing = list()
|
||||
|
||||
/datum/controller/subsystem/throwing/stat_entry()
|
||||
..("P:[processing.len]")
|
||||
/datum/controller/subsystem/throwing/stat_entry(msg)
|
||||
msg = "P:[processing.len]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/throwing/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
|
||||
@@ -41,6 +41,10 @@ SUBSYSTEM_DEF(ticker)
|
||||
//Now we have a general cinematic centrally held within the gameticker....far more efficient!
|
||||
var/obj/screen/cinematic = null
|
||||
|
||||
var/round_start_time = 0
|
||||
|
||||
|
||||
|
||||
// This global variable exists for legacy support so we don't have to rename every 'ticker' to 'SSticker' yet.
|
||||
var/global/datum/controller/subsystem/ticker/ticker
|
||||
/datum/controller/subsystem/ticker/PreInit()
|
||||
@@ -101,6 +105,7 @@ var/global/datum/controller/subsystem/ticker/ticker
|
||||
|
||||
// Called during GAME_STATE_SETTING_UP (RUNLEVEL_SETUP)
|
||||
/datum/controller/subsystem/ticker/proc/setup_tick(resumed = FALSE)
|
||||
round_start_time = world.time // otherwise round_start_time would be 0 for the signals
|
||||
if(!setup_choose_gamemode())
|
||||
// It failed, go back to lobby state and re-send the welcome message
|
||||
pregame_timeleft = config.pregame_time
|
||||
@@ -418,6 +423,7 @@ var/global/datum/controller/subsystem/ticker/ticker
|
||||
if(new_char.client)
|
||||
var/obj/screen/splash/S = new(new_char.client, TRUE)
|
||||
S.Fade(TRUE)
|
||||
new_char.client.init_verbs()
|
||||
|
||||
// If they're a carbon, they can get manifested
|
||||
if(J?.mob_type & JOB_CARBON)
|
||||
@@ -542,28 +548,29 @@ var/global/datum/controller/subsystem/ticker/ticker
|
||||
|
||||
return 1
|
||||
|
||||
/datum/controller/subsystem/ticker/stat_entry()
|
||||
/datum/controller/subsystem/ticker/stat_entry(msg)
|
||||
switch(current_state)
|
||||
if(GAME_STATE_INIT)
|
||||
..()
|
||||
if(GAME_STATE_PREGAME) // RUNLEVEL_LOBBY
|
||||
..("START [round_progressing ? "[round(pregame_timeleft)]s" : "(PAUSED)"]")
|
||||
msg = "START [round_progressing ? "[round(pregame_timeleft)]s" : "(PAUSED)"]"
|
||||
if(GAME_STATE_SETTING_UP) // RUNLEVEL_SETUP
|
||||
..("SETUP")
|
||||
msg = "SETUP"
|
||||
if(GAME_STATE_PLAYING) // RUNLEVEL_GAME
|
||||
..("GAME")
|
||||
msg = "GAME"
|
||||
if(GAME_STATE_FINISHED) // RUNLEVEL_POSTGAME
|
||||
switch(end_game_state)
|
||||
if(END_GAME_MODE_FINISHED)
|
||||
..("MODE OVER, WAITING")
|
||||
msg = "MODE OVER, WAITING"
|
||||
if(END_GAME_READY_TO_END)
|
||||
..("ENDGAME PROCESSING")
|
||||
msg = "ENDGAME PROCESSING"
|
||||
if(END_GAME_ENDING)
|
||||
..("END IN [round(restart_timeleft/10)]s")
|
||||
msg = "END IN [round(restart_timeleft/10)]s"
|
||||
if(END_GAME_DELAYED)
|
||||
..("END PAUSED")
|
||||
msg = "END PAUSED"
|
||||
else
|
||||
..("ENDGAME ERROR:[end_game_state]")
|
||||
msg = "ENDGAME ERROR:[end_game_state]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/ticker/Recover()
|
||||
flags |= SS_NO_INIT // Don't initialize again
|
||||
@@ -579,3 +586,5 @@ var/global/datum/controller/subsystem/ticker/ticker
|
||||
minds = SSticker.minds
|
||||
|
||||
random_players = SSticker.random_players
|
||||
|
||||
round_start_time = SSticker.round_start_time
|
||||
|
||||
@@ -34,7 +34,8 @@ SUBSYSTEM_DEF(timer)
|
||||
bucket_resolution = world.tick_lag
|
||||
|
||||
/datum/controller/subsystem/timer/stat_entry(msg)
|
||||
..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]")
|
||||
msg = "B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/timer/fire(resumed = FALSE)
|
||||
var/lit = last_invoke_tick
|
||||
|
||||
@@ -122,9 +122,8 @@ SUBSYSTEM_DEF(transcore)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/transcore/stat_entry()
|
||||
var/msg = list()
|
||||
msg += "$:{"
|
||||
/datum/controller/subsystem/transcore/stat_entry(msg)
|
||||
msg = "$:{"
|
||||
msg += "IM:[round(cost_implants,1)]|"
|
||||
msg += "BK:[round(cost_backups,1)]"
|
||||
msg += "} "
|
||||
@@ -137,7 +136,7 @@ SUBSYSTEM_DEF(transcore)
|
||||
msg += "DFB:[default_db.body_scans.len]|"
|
||||
msg += "DFI:[default_db.implants.len]"
|
||||
msg += "} "
|
||||
..(jointext(msg, null))
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/transcore/Recover()
|
||||
for(var/key in SStranscore.databases)
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/// This component behaves similar to connect_loc_behalf, but working off clients and mobs instead of loc
|
||||
/// To be clear, we hook into a signal on a tracked client's mob
|
||||
/// We retain the ability to react to that signal on a seperate listener, which makes this quite powerful
|
||||
/datum/component/connect_mob_behalf
|
||||
dupe_mode = COMPONENT_DUPE_UNIQUE
|
||||
|
||||
/// An assoc list of signal -> procpath to register to the mob our client "owns"
|
||||
var/list/connections
|
||||
/// The master client we're working with
|
||||
var/client/tracked
|
||||
/// The mob we're currently tracking
|
||||
var/mob/tracked_mob
|
||||
|
||||
/datum/component/connect_mob_behalf/Initialize(client/tracked, list/connections)
|
||||
. = ..()
|
||||
if (!istype(tracked))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
src.connections = connections
|
||||
src.tracked = tracked
|
||||
|
||||
/datum/component/connect_mob_behalf/RegisterWithParent()
|
||||
RegisterSignal(tracked, COMSIG_PARENT_QDELETING, PROC_REF(handle_tracked_qdel))
|
||||
update_signals()
|
||||
|
||||
/datum/component/connect_mob_behalf/UnregisterFromParent()
|
||||
unregister_signals()
|
||||
UnregisterSignal(tracked, COMSIG_PARENT_QDELETING)
|
||||
|
||||
tracked = null
|
||||
tracked_mob = null
|
||||
|
||||
/datum/component/connect_mob_behalf/proc/handle_tracked_qdel()
|
||||
SIGNAL_HANDLER
|
||||
qdel(src)
|
||||
|
||||
/datum/component/connect_mob_behalf/proc/update_signals()
|
||||
unregister_signals()
|
||||
// Yes this is a runtime silencer
|
||||
// We could be in a position where logout is sent to two things, one thing intercepts it, then deletes the client's new mob
|
||||
// It's rare, and the same check in connect_loc_behalf is more fruitful, but it's still worth doing
|
||||
if(QDELETED(tracked?.mob))
|
||||
return
|
||||
tracked_mob = tracked.mob
|
||||
RegisterSignal(tracked_mob, COMSIG_MOB_LOGOUT, PROC_REF(on_logout))
|
||||
for (var/signal in connections)
|
||||
parent.RegisterSignal(tracked_mob, signal, connections[signal])
|
||||
|
||||
/datum/component/connect_mob_behalf/proc/unregister_signals()
|
||||
if(isnull(tracked_mob))
|
||||
return
|
||||
|
||||
parent.UnregisterSignal(tracked_mob, connections)
|
||||
UnregisterSignal(tracked_mob, COMSIG_MOB_LOGOUT)
|
||||
|
||||
tracked_mob = null
|
||||
|
||||
/datum/component/connect_mob_behalf/proc/on_logout(mob/source)
|
||||
SIGNAL_HANDLER
|
||||
update_signals()
|
||||
+5
-2
@@ -88,7 +88,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
|
||||
|
||||
if(new_character.mind) //remove any mind currently in our new body's mind variable
|
||||
@@ -103,6 +103,9 @@
|
||||
if(active)
|
||||
new_character.key = key //now transfer the key to link the client to our new body
|
||||
|
||||
if(new_character.client)
|
||||
new_character.client.init_verbs() // re-initialize character specific verbs
|
||||
|
||||
/datum/mind/proc/store_memory(new_text)
|
||||
memory += "[new_text]<BR>"
|
||||
|
||||
@@ -516,7 +519,7 @@
|
||||
if(!mind.name) mind.name = real_name
|
||||
mind.current = src
|
||||
if(player_is_antag(mind))
|
||||
src.client.verbs += /client/proc/aooc
|
||||
add_verb(src.client, /client/proc/aooc)
|
||||
|
||||
//HUMAN
|
||||
/mob/living/carbon/human/mind_initialize()
|
||||
|
||||
@@ -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, span_notice("Once you decide on a goal to pursue, you can optionally display it to \
|
||||
everyone at the end of the shift with the " + span_bold("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, span_danger(span_large("You are no longer a [role_text]!")))
|
||||
current_antagonists -= player
|
||||
@@ -60,8 +60,8 @@
|
||||
update_icons_removed(player)
|
||||
BITSET(player.current.hud_updateflag, SPECIALROLE_HUD)
|
||||
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
|
||||
|
||||
+31
-1
@@ -247,7 +247,7 @@
|
||||
|
||||
// Don't make these call bicon or anything, these are what bicon uses. They need to return an icon.
|
||||
/atom/proc/examine_icon()
|
||||
return icon(icon=src.icon, icon_state=src.icon_state, dir=SOUTH, frame=1, moving=0)
|
||||
return src // 99% of the time just returning src will be sufficient. More complex examine icon things are available where they are needed
|
||||
|
||||
// called by mobs when e.g. having the atom as their machine, pulledby, loc (AKA mob being inside the atom) or buckled var set.
|
||||
// see code/modules/mob/mob_movement.dm for more.
|
||||
@@ -786,3 +786,33 @@
|
||||
else if(C)
|
||||
color = C
|
||||
return
|
||||
|
||||
///Passes Stat Browser Panel clicks to the game and calls client click on an atom
|
||||
/atom/Topic(href, list/href_list)
|
||||
. = ..()
|
||||
if(!usr?.client)
|
||||
return
|
||||
var/client/usr_client = usr.client
|
||||
var/list/paramslist = list()
|
||||
|
||||
if(href_list["statpanel_item_click"])
|
||||
switch(href_list["statpanel_item_click"])
|
||||
if("left")
|
||||
paramslist["left"] = "1"
|
||||
if("right")
|
||||
paramslist["right"] = "1"
|
||||
if("middle")
|
||||
paramslist["middle"] = "1"
|
||||
else
|
||||
return
|
||||
|
||||
if(href_list["statpanel_item_shiftclick"])
|
||||
paramslist["shift"] = "1"
|
||||
if(href_list["statpanel_item_ctrlclick"])
|
||||
paramslist["ctrl"] = "1"
|
||||
if(href_list["statpanel_item_altclick"])
|
||||
paramslist["alt"] = "1"
|
||||
|
||||
var/mouseparams = list2params(paramslist)
|
||||
usr_client.Click(src, loc, null, mouseparams)
|
||||
return TRUE
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
/datum/dna/gene/basic/remoteview/activate(var/mob/M, var/connected, var/flags)
|
||||
..(M,connected,flags)
|
||||
M.verbs += /mob/living/carbon/human/proc/remoteobserve
|
||||
add_verb(M, /mob/living/carbon/human/proc/remoteobserve)
|
||||
|
||||
/datum/dna/gene/basic/regenerate
|
||||
name="Regenerate"
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
/datum/dna/gene/basic/remotetalk/activate(var/mob/M, var/connected, var/flags)
|
||||
..(M,connected,flags)
|
||||
M.verbs += /mob/living/carbon/human/proc/remotesay
|
||||
add_verb(M, /mob/living/carbon/human/proc/remotesay)
|
||||
|
||||
/datum/dna/gene/basic/morph
|
||||
name="Morph"
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
/datum/dna/gene/basic/morph/activate(var/mob/M)
|
||||
..(M)
|
||||
M.verbs += /mob/living/carbon/human/proc/morph
|
||||
add_verb(M, /mob/living/carbon/human/proc/morph)
|
||||
|
||||
/datum/dna/gene/basic/cold_resist
|
||||
name="Cold Resistance"
|
||||
|
||||
@@ -65,8 +65,8 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
|
||||
if(!mind) return
|
||||
if(!mind.changeling) mind.changeling = new /datum/changeling(gender)
|
||||
|
||||
verbs.Add(/datum/changeling/proc/EvolutionMenu)
|
||||
verbs.Add(/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)
|
||||
@@ -85,7 +85,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))
|
||||
verbs.Add(P.verbpath)
|
||||
add_verb(src, P.verbpath)
|
||||
if(P.make_hud_button)
|
||||
if(!src.ability_master)
|
||||
src.ability_master = new /obj/screen/movable/ability_master(src)
|
||||
@@ -113,7 +113,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
|
||||
if(!mind || !mind.changeling) return
|
||||
for(var/datum/power/changeling/P in mind.changeling.purchased_powers)
|
||||
if(P.isVerb)
|
||||
verbs.Remove(P.verbpath)
|
||||
remove_verb(src, P.verbpath)
|
||||
var/obj/screen/ability/verb_based/changeling/C = ability_master.get_ability_by_proc_ref(P.verbpath)
|
||||
if(C)
|
||||
ability_master.remove_ability(C)
|
||||
@@ -235,8 +235,8 @@ 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
|
||||
spawn(10) src.verbs += verb_path
|
||||
remove_verb(src, verb_path)
|
||||
spawn(10) add_verb(src, verb_path)
|
||||
|
||||
to_chat(src, span_notice("We stealthily sting [T]."))
|
||||
if(!T.mind || !T.mind.changeling) return T //T will be affected by the sting
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
range = range + 3
|
||||
to_chat(src, span_notice("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
|
||||
|
||||
@@ -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, span_notice("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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
spawn(rand(2 MINUTES, 4 MINUTES))
|
||||
//The ling will now be able to choose when to revive
|
||||
verbs.Add(/mob/proc/changeling_revive)
|
||||
add_verb(src, /mob/proc/changeling_revive)
|
||||
|
||||
new /obj/changeling_revive_holder(src)
|
||||
|
||||
|
||||
@@ -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, span_notice("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
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
C.set_stat(CONSCIOUS)
|
||||
C.forbid_seeing_deadchat = FALSE
|
||||
C.timeofdeath = null
|
||||
verbs.Remove(/mob/proc/changeling_revive)
|
||||
remove_verb(src, /mob/proc/changeling_revive)
|
||||
// re-add our changeling powers
|
||||
C.make_changeling()
|
||||
|
||||
|
||||
@@ -56,9 +56,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")
|
||||
|
||||
@@ -238,7 +238,7 @@ var/global/list/Holiday = list() //Holidays are lists now, so we can have more t
|
||||
|
||||
//Allows GA and GM to set the Holiday variable
|
||||
/client/proc/Set_Holiday()
|
||||
set name = ".Set Holiday"
|
||||
set name = "Set Holiday"
|
||||
set category = "Fun"
|
||||
set desc = "Force-set the Holiday variable to make the game think it's a certain day."
|
||||
if(!check_rights(R_SERVER)) return
|
||||
|
||||
@@ -8,7 +8,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"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
if(!focus)
|
||||
return
|
||||
to_chat(owner, "<b>Research Completed</b>: [focus.name]")
|
||||
owner.verbs.Add(focus.ability)
|
||||
add_verb(owner, focus.ability)
|
||||
available_abilities -= focus
|
||||
if(focus.next)
|
||||
available_abilities += focus.next
|
||||
@@ -62,8 +62,3 @@
|
||||
focus.process(cpu_gained)
|
||||
if(focus.unlocked)
|
||||
finish_research()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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, new /datum/game_mode/malfunction/verb/ai_destroy_station())
|
||||
|
||||
|
||||
// END ABILITY VERBS
|
||||
|
||||
@@ -24,7 +24,7 @@ mob
|
||||
sandbox.owner = src.ckey
|
||||
if(src.client.holder)
|
||||
sandbox.admin = 1
|
||||
verbs += new/mob/proc/sandbox_panel
|
||||
add_verb(src, /mob/proc/sandbox_panel)
|
||||
sandbox_panel()
|
||||
if(sandbox)
|
||||
sandbox.update()
|
||||
|
||||
@@ -160,23 +160,24 @@
|
||||
/obj/spellbutton/DblClick()
|
||||
return Click()
|
||||
|
||||
/mob/living/carbon/human/Stat()
|
||||
/mob/living/carbon/human/get_status_tab_items()
|
||||
. = ..()
|
||||
|
||||
if(. && istype(back,/obj/item/technomancer_core))
|
||||
var/obj/item/technomancer_core/core = back
|
||||
setup_technomancer_stat(core)
|
||||
. += setup_technomancer_stat(core)
|
||||
|
||||
/mob/living/carbon/human/proc/setup_technomancer_stat(var/obj/item/technomancer_core/core)
|
||||
if(core && statpanel("Spell Core"))
|
||||
. = list()
|
||||
if(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)
|
||||
. += "Core charge: [charge_status]"
|
||||
. += "User instability: [instability_status]"
|
||||
for(var/obj/spellbutton/button in core.spells)
|
||||
stat(button)
|
||||
. += button
|
||||
|
||||
/obj/item/technomancer_core/proc/add_spell(var/path, var/new_name, var/ability_icon_state)
|
||||
if(!path || !ispath(path))
|
||||
|
||||
@@ -49,12 +49,12 @@
|
||||
return
|
||||
if (prob(50))
|
||||
for(var/x in verbs)
|
||||
verbs -= x
|
||||
src.verbs -= x
|
||||
set_broken()
|
||||
if(3.0)
|
||||
if (prob(25))
|
||||
for(var/x in verbs)
|
||||
verbs -= x
|
||||
src.verbs -= x
|
||||
set_broken()
|
||||
else
|
||||
return
|
||||
|
||||
@@ -257,7 +257,7 @@
|
||||
//Yes, I am using a aheal just so your markings transfer over, I could not get .prefs.copy_to working. This is very stupid, and I can't be assed to rewrite this. Too bad!
|
||||
avatar.revive()
|
||||
avatar.revive()
|
||||
avatar.verbs += /mob/living/carbon/human/proc/exit_vr //ahealing removes the prommie verbs and the VR verbs, giving it back
|
||||
add_verb(avatar, /mob/living/carbon/human/proc/exit_vr) //ahealing removes the prommie verbs and the VR verbs, giving it back
|
||||
avatar.Sleeping(1)
|
||||
|
||||
// Prompt for username after they've enterred the body.
|
||||
|
||||
@@ -423,10 +423,10 @@
|
||||
////////////////////////
|
||||
|
||||
/obj/mecha/proc/removeVerb(verb_path)
|
||||
verbs -= verb_path
|
||||
src.verbs -= verb_path
|
||||
|
||||
/obj/mecha/proc/addVerb(verb_path)
|
||||
verbs += verb_path
|
||||
src.verbs += verb_path
|
||||
|
||||
/obj/mecha/proc/add_airtank()
|
||||
internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src)
|
||||
|
||||
@@ -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/decal/cleanable/blood/splatter
|
||||
random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5")
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
// Parameters: None
|
||||
// Description: Lets synths use their communicators without hands.
|
||||
/obj/item/communicator/integrated/verb/activate()
|
||||
set category = "AI IM"
|
||||
set category = "Abilities.AI_IM"
|
||||
set name = "Use Communicator"
|
||||
set desc = "Utilizes your built-in communicator."
|
||||
set src in usr
|
||||
@@ -29,4 +29,4 @@
|
||||
to_chat(usr, "You can't do that because you are dead!")
|
||||
return
|
||||
|
||||
src.attack_self(usr)
|
||||
src.attack_self(usr)
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
to_chat(usr, "It'd be unwise to plug another vtec module in!")
|
||||
return 0
|
||||
|
||||
R.verbs += /mob/living/silicon/robot/proc/toggle_vtec
|
||||
add_verb(R, /mob/living/silicon/robot/proc/toggle_vtec)
|
||||
R.vtec_active = TRUE
|
||||
R.hud_used.toggle_vtec_control()
|
||||
return 1
|
||||
@@ -139,7 +139,7 @@
|
||||
to_chat(usr, "There's no space for another size alteration module!")
|
||||
return 0
|
||||
|
||||
R.verbs += /mob/living/proc/set_size
|
||||
add_verb(R, /mob/living/proc/set_size)
|
||||
return 1
|
||||
|
||||
/obj/item/borg/upgrade/basic/syndicate
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
else
|
||||
return
|
||||
else
|
||||
imp_in.verbs -= assigned_proc
|
||||
remove_verb(imp_in, assigned_proc)
|
||||
return
|
||||
|
||||
if(reagents)
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
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(var/mob/user)
|
||||
user.verbs -= /mob/living/proc/shred_limb_temp
|
||||
..()
|
||||
remove_verb(user, /mob/living/proc/shred_limb_temp)
|
||||
..()
|
||||
|
||||
@@ -23,5 +23,5 @@
|
||||
new_voice.real_name = "[new_voice.real_name]" //We still know their real name though!
|
||||
possessed_voice.Add(new_voice)
|
||||
listening_objects |= src
|
||||
new_voice.verbs -= /mob/living/voice/verb/change_name //No changing your name! Bad!
|
||||
new_voice.verbs -= /mob/living/voice/verb/hang_up //Also you can't hang up. You are the item!
|
||||
remove_verb(new_voice, /mob/living/voice/verb/change_name) //No changing your name! Bad!
|
||||
remove_verb(new_voice, /mob/living/voice/verb/hang_up) //Also you can't hang up. You are the item!
|
||||
|
||||
@@ -69,10 +69,10 @@
|
||||
|
||||
|
||||
/obj/vehicle/proc/removeVerb(verb_path)
|
||||
verbs -= verb_path
|
||||
src.verbs -= verb_path
|
||||
|
||||
/obj/vehicle/proc/addVerb(verb_path)
|
||||
verbs += verb_path
|
||||
src.verbs += verb_path
|
||||
|
||||
/obj/vehicle/proc/add_cell(var/obj/item/cell/C=null)
|
||||
if(C)
|
||||
|
||||
@@ -13,6 +13,7 @@ var/list/admin_verbs_default = list(
|
||||
// /client/proc/cmd_mod_say,
|
||||
// /client/proc/deadchat //toggles deadchat on/off,
|
||||
// /client/proc/toggle_ahelp_sound,
|
||||
/client/proc/debugstatpanel,
|
||||
)
|
||||
|
||||
var/list/admin_verbs_admin = list(
|
||||
@@ -507,27 +508,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.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,
|
||||
@@ -542,4 +543,4 @@ var/list/admin_verbs_event_manager = list(
|
||||
admin_verbs_sounds,
|
||||
admin_verbs_spawn,
|
||||
debug_verbs
|
||||
)
|
||||
))
|
||||
|
||||
@@ -18,6 +18,7 @@ var/list/admin_verbs_default = list(
|
||||
// /client/proc/cmd_mod_say,
|
||||
// /client/proc/deadchat //toggles deadchat on/off,
|
||||
// /client/proc/toggle_ahelp_sound,
|
||||
/client/proc/debugstatpanel,
|
||||
)
|
||||
|
||||
var/list/admin_verbs_admin = list(
|
||||
@@ -568,27 +569,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.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,
|
||||
@@ -603,4 +604,4 @@ var/list/admin_verbs_event_manager = list(
|
||||
admin_verbs_sounds,
|
||||
admin_verbs_spawn,
|
||||
debug_verbs
|
||||
)
|
||||
))
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
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, span_filter_system(span_interface("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!
|
||||
@@ -14,7 +14,7 @@
|
||||
set category = "Admin"
|
||||
|
||||
remove_admin_verbs()
|
||||
verbs += /client/proc/show_verbs
|
||||
add_verb(src, /client/proc/show_verbs)
|
||||
|
||||
to_chat(src, span_filter_system(span_interface("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!
|
||||
@@ -24,7 +24,7 @@
|
||||
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, span_filter_adminlog(span_interface("All of your adminverbs are now visible.")))
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
|
||||
/client/proc/admin_ghost()
|
||||
set category = "Admin"
|
||||
set category = "Admin.Game"
|
||||
set name = "Aghost"
|
||||
if(!holder) return
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
else
|
||||
ghost = body.ghostize(1)
|
||||
ghost.admin_ghosted = 1
|
||||
init_verbs()
|
||||
if(body)
|
||||
body.teleop = ghost
|
||||
if(!body.key)
|
||||
@@ -82,7 +83,7 @@
|
||||
|
||||
/client/proc/invisimin()
|
||||
set name = "Invisimin"
|
||||
set category = "Admin"
|
||||
set category = "Admin.Game"
|
||||
set desc = "Toggles ghost-like invisibility (Don't abuse this)"
|
||||
if(holder && mob)
|
||||
if(mob.invisibility == INVISIBILITY_OBSERVER)
|
||||
@@ -144,7 +145,7 @@
|
||||
|
||||
/client/proc/game_panel()
|
||||
set name = "Game Panel"
|
||||
set category = "Admin"
|
||||
set category = "Admin.Game"
|
||||
if(holder)
|
||||
holder.Game()
|
||||
feedback_add_details("admin_verb","GP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
@@ -255,7 +256,7 @@
|
||||
#undef AUTOBANTIME
|
||||
|
||||
/client/proc/drop_bomb() // Some admin dickery that can probably be done better -- TLE
|
||||
set category = "Special Verbs"
|
||||
set category = "Special Verbs.Fun"
|
||||
set name = "Drop Bomb"
|
||||
set desc = "Cause an explosion of varying strength at your location."
|
||||
|
||||
@@ -338,7 +339,7 @@
|
||||
log_and_message_admins("has given [key_name(L)] the modifer [new_modifier_type], with a duration of [duration ? "[duration / 600] minutes" : "forever"].")
|
||||
|
||||
/client/proc/make_sound(var/obj/O in world) // -- TLE
|
||||
set category = "Special Verbs"
|
||||
set category = "Special Verbs.Events"
|
||||
set name = "Make Sound"
|
||||
set desc = "Display a message to everyone who can hear the target"
|
||||
if(O)
|
||||
@@ -353,13 +354,13 @@
|
||||
|
||||
/client/proc/togglebuildmodeself()
|
||||
set name = "Toggle Build Mode Self"
|
||||
set category = "Special Verbs"
|
||||
set category = "Special Verbs.Events"
|
||||
if(src.mob)
|
||||
togglebuildmode(src.mob)
|
||||
feedback_add_details("admin_verb","TBMS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/object_talk(var/msg as text) // -- TLE
|
||||
set category = "Special Verbs"
|
||||
set category = "Special Verbs.Events"
|
||||
set name = "oSay"
|
||||
set desc = "Display a message to everyone who can hear the target"
|
||||
if(mob.control_object)
|
||||
@@ -388,7 +389,7 @@
|
||||
log_admin("[src] re-admined themself.")
|
||||
message_admins("[src] re-admined themself.", 1)
|
||||
to_chat(src, span_filter_system(span_interface("You now have the keys to control the planet, or at least 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"
|
||||
@@ -400,7 +401,7 @@
|
||||
message_admins("[src] deadmined themself.", 1)
|
||||
deadmin()
|
||||
to_chat(src, span_filter_system(span_interface("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/toggle_log_hrefs()
|
||||
@@ -413,7 +414,7 @@
|
||||
|
||||
/client/proc/check_ai_laws()
|
||||
set name = "Check AI Laws"
|
||||
set category = "Admin"
|
||||
set category = "Admin.Game"
|
||||
if(holder)
|
||||
src.holder.output_ai_laws()
|
||||
|
||||
@@ -449,7 +450,7 @@
|
||||
/client/proc/change_security_level()
|
||||
set name = "Set security level"
|
||||
set desc = "Sets the station security level"
|
||||
set category = "Admin"
|
||||
set category = "Admin.Events"
|
||||
|
||||
if(!check_rights(R_ADMIN|R_EVENT)) return
|
||||
var/sec_level = tgui_input_list(usr, "It's currently code [get_security_level()].", "Select Security Level", (list("green","yellow","violet","orange","blue","red","delta")-get_security_level()))
|
||||
@@ -559,3 +560,9 @@
|
||||
feedback_add_details("admin_verb","GS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] gave [key_name(T)] the spell [S].")
|
||||
message_admins(span_blue("[key_name_admin(usr)] gave [key_name(T)] the spell [S]."), 1)
|
||||
|
||||
/client/proc/debugstatpanel()
|
||||
set name = "Debug Stat Panel"
|
||||
set category = "Debug"
|
||||
|
||||
src.stat_panel.send_message("create_debug")
|
||||
|
||||
@@ -37,12 +37,14 @@ var/list/admin_datums = list()
|
||||
owner = C
|
||||
owner.holder = src
|
||||
owner.add_admin_verbs() //TODO
|
||||
owner.init_verbs() //re-initialize the verb list
|
||||
GLOB.admins |= C
|
||||
|
||||
/datum/admins/proc/disassociate()
|
||||
if(owner)
|
||||
GLOB.admins -= owner
|
||||
owner.remove_admin_verbs()
|
||||
owner.init_verbs() //re-initialize the verb list
|
||||
owner.deadmin_holder = owner.holder
|
||||
owner.holder = null
|
||||
|
||||
|
||||
@@ -494,7 +494,7 @@
|
||||
var/mob/living/Tar = target
|
||||
if(!istype(Tar))
|
||||
return
|
||||
Tar.verbs |= /mob/living/proc/ventcrawl
|
||||
add_verb(Tar, /mob/living/proc/ventcrawl)
|
||||
|
||||
if("darksight")
|
||||
var/mob/living/carbon/human/Tar = target
|
||||
@@ -509,26 +509,26 @@
|
||||
var/mob/living/carbon/human/Tar = target
|
||||
if(!istype(Tar))
|
||||
return
|
||||
Tar.verbs |= /mob/living/carbon/human/proc/enter_cocoon
|
||||
add_verb(Tar, /mob/living/carbon/human/proc/enter_cocoon)
|
||||
|
||||
if("transformation")
|
||||
var/mob/living/carbon/human/Tar = target
|
||||
if(!istype(Tar))
|
||||
return
|
||||
Tar.verbs |= /mob/living/carbon/human/proc/shapeshifter_select_hair
|
||||
Tar.verbs |= /mob/living/carbon/human/proc/shapeshifter_select_hair_colors
|
||||
Tar.verbs |= /mob/living/carbon/human/proc/shapeshifter_select_gender
|
||||
Tar.verbs |= /mob/living/carbon/human/proc/shapeshifter_select_wings
|
||||
Tar.verbs |= /mob/living/carbon/human/proc/shapeshifter_select_tail
|
||||
Tar.verbs |= /mob/living/carbon/human/proc/shapeshifter_select_ears
|
||||
Tar.verbs |= /mob/living/carbon/human/proc/lleill_select_shape //designed for non-shapeshifter mobs
|
||||
Tar.verbs |= /mob/living/carbon/human/proc/lleill_select_colour
|
||||
add_verb(Tar, /mob/living/carbon/human/proc/shapeshifter_select_hair)
|
||||
add_verb(Tar, /mob/living/carbon/human/proc/shapeshifter_select_hair_colors)
|
||||
add_verb(Tar, /mob/living/carbon/human/proc/shapeshifter_select_gender)
|
||||
add_verb(Tar, /mob/living/carbon/human/proc/shapeshifter_select_wings)
|
||||
add_verb(Tar, /mob/living/carbon/human/proc/shapeshifter_select_tail)
|
||||
add_verb(Tar, /mob/living/carbon/human/proc/shapeshifter_select_ears)
|
||||
add_verb(Tar, /mob/living/carbon/human/proc/lleill_select_shape) //designed for non-shapeshifter mobs
|
||||
add_verb(Tar, /mob/living/carbon/human/proc/lleill_select_colour)
|
||||
|
||||
if("set_size")
|
||||
var/mob/living/Tar = target
|
||||
if(!istype(Tar))
|
||||
return
|
||||
Tar.verbs |= /mob/living/proc/set_size
|
||||
add_verb(Tar, /mob/living/proc/set_size)
|
||||
|
||||
if("lleill_energy")
|
||||
var/mob/living/carbon/human/Tar = target
|
||||
@@ -543,44 +543,44 @@
|
||||
var/mob/living/carbon/human/Tar = target
|
||||
if(!istype(Tar))
|
||||
return
|
||||
Tar.verbs |= /mob/living/carbon/human/proc/lleill_invisibility
|
||||
add_verb(Tar, /mob/living/carbon/human/proc/lleill_invisibility)
|
||||
|
||||
if("beast_form")
|
||||
var/mob/living/carbon/human/Tar = target
|
||||
if(!istype(Tar))
|
||||
return
|
||||
Tar.verbs |= /mob/living/carbon/human/proc/lleill_beast_form
|
||||
add_verb(Tar, /mob/living/carbon/human/proc/lleill_beast_form)
|
||||
|
||||
if("lleill_transmute")
|
||||
var/mob/living/carbon/human/Tar = target
|
||||
if(!istype(Tar))
|
||||
return
|
||||
Tar.verbs |= /mob/living/carbon/human/proc/lleill_transmute
|
||||
add_verb(Tar, /mob/living/carbon/human/proc/lleill_transmute)
|
||||
|
||||
if("lleill_alchemy")
|
||||
var/mob/living/carbon/human/Tar = target
|
||||
if(!istype(Tar))
|
||||
return
|
||||
Tar.verbs |= /mob/living/carbon/human/proc/lleill_alchemy
|
||||
add_verb(Tar, /mob/living/carbon/human/proc/lleill_alchemy)
|
||||
|
||||
if("lleill_drain")
|
||||
var/mob/living/carbon/human/Tar = target
|
||||
if(!istype(Tar))
|
||||
return
|
||||
Tar.verbs |= /mob/living/carbon/human/proc/lleill_contact
|
||||
add_verb(Tar, /mob/living/carbon/human/proc/lleill_contact)
|
||||
|
||||
if("brutal_pred")
|
||||
var/mob/living/Tar = target
|
||||
if(!istype(Tar))
|
||||
return
|
||||
Tar.verbs |= /mob/living/proc/shred_limb
|
||||
add_verb(Tar, /mob/living/proc/shred_limb)
|
||||
|
||||
if("trash_eater")
|
||||
var/mob/living/carbon/human/Tar = target
|
||||
if(!istype(Tar))
|
||||
return
|
||||
Tar.verbs |= /mob/living/proc/eat_trash
|
||||
Tar.verbs |= /mob/living/proc/toggle_trash_catching
|
||||
add_verb(Tar, /mob/living/proc/eat_trash)
|
||||
add_verb(Tar, /mob/living/proc/toggle_trash_catching)
|
||||
|
||||
|
||||
////////INVENTORY//////////////
|
||||
|
||||
@@ -384,11 +384,13 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
|
||||
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 \
|
||||
var/list/L = list()
|
||||
L[++L.len] = list("[id] ", "[delete_click.update("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))
|
||||
L[++L.len] = list(" ", "[action_click.update("[SDQL2_IS_RUNNING? "HALT" : "RUN"]")]", REF(action_click))
|
||||
return L
|
||||
|
||||
/datum/SDQL2_query/proc/delete_click()
|
||||
admin_del(usr)
|
||||
|
||||
@@ -72,18 +72,23 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
|
||||
//Tickets statpanel
|
||||
/datum/admin_help_tickets/proc/stat_entry()
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
var/list/L = list()
|
||||
var/num_disconnected = 0
|
||||
stat("== Admin Tickets ==")
|
||||
stat("Active Tickets:", astatclick.update("[active_tickets.len]"))
|
||||
L[++L.len] = list("== Admin Tickets ==", "", null, null)
|
||||
L[++L.len] = list("Active Tickets:", "[astatclick.update("[active_tickets.len]")]", null, REF(astatclick))
|
||||
astatclick.update("[active_tickets.len]")
|
||||
for(var/datum/admin_help/AH as anything in active_tickets)
|
||||
if(AH.initiator)
|
||||
stat("#[AH.id]. [AH.initiator_key_name]:", AH.statclick.update())
|
||||
L[++L.len] = list("#[AH.id]. [AH.initiator_key_name]:", "[AH.statclick.update()]", REF(AH))
|
||||
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]"))
|
||||
L[++L.len] = list("Disconnected:", "[astatclick.update("[num_disconnected]")]", null, REF(astatclick))
|
||||
L[++L.len] = list("Closed Tickets:", "[cstatclick.update("[closed_tickets.len]")]", null, REF(cstatclick))
|
||||
L[++L.len] = list("Resolved Tickets:", "[rstatclick.update("[resolved_tickets.len]")]", null, REF(rstatclick))
|
||||
return L
|
||||
|
||||
//Reassociate still open ticket if one exists
|
||||
/datum/admin_help_tickets/proc/ClientLogin(client/C)
|
||||
@@ -119,6 +124,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
/obj/effect/statclick/ticket_list/Click()
|
||||
GLOB.ahelp_tickets.BrowseTickets(current_state)
|
||||
|
||||
//called by admin topic
|
||||
/obj/effect/statclick/ticket_list/proc/Action()
|
||||
Click()
|
||||
//
|
||||
//TICKET DATUM
|
||||
//
|
||||
@@ -606,9 +614,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
return
|
||||
|
||||
//remove out adminhelp verb temporarily to prevent spamming of admins.
|
||||
src.verbs -= /client/verb/adminhelp
|
||||
remove_verb(src, /client/verb/adminhelp)
|
||||
spawn(1200)
|
||||
src.verbs += /client/verb/adminhelp // 2 minute cool-down for adminhelps
|
||||
add_verb(src, /client/verb/adminhelp) // 2 minute cool-down for adminhelps
|
||||
|
||||
feedback_add_details("admin_verb","Adminhelp") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
if(current_ticket)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
return
|
||||
|
||||
//if they requested spice, then remove spice verb temporarily to prevent spamming
|
||||
usr.verbs -= /client/verb/adminspice
|
||||
remove_verb(usr, /client/verb/adminspice)
|
||||
spawn(10 MINUTES)
|
||||
if(usr) // In case we left in the 10 minute cooldown
|
||||
usr.verbs += /client/verb/adminspice // 10 minute cool-down for spice request
|
||||
add_verb(usr, /client/verb/adminspice) // 10 minute cool-down for spice request
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
to_chat(src, span_red("Error: giveruntimelog(): Client not found."))
|
||||
return
|
||||
|
||||
target.verbs |= /client/proc/getruntimelog
|
||||
add_verb(target, /client/proc/getruntimelog)
|
||||
to_chat(target, span_red("You have been granted access to runtime logs. Please use them responsibly or risk being banned."))
|
||||
return
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ var/list/debug_verbs = list (
|
||||
|
||||
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!
|
||||
|
||||
@@ -182,7 +182,7 @@ var/list/debug_verbs = list (
|
||||
|
||||
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!
|
||||
|
||||
|
||||
@@ -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
|
||||
feedback_add_details("admin_verb","GPV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
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!
|
||||
|
||||
@@ -324,7 +324,7 @@ Ccomp's first proc.
|
||||
if(config.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
|
||||
@@ -335,7 +335,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, span_blue("<B>The Administrator has enabled AntagHUD </B>")) // Notify all observers they can now use AntagHUD
|
||||
config.antag_hud_allowed = 1
|
||||
action = "enabled"
|
||||
|
||||
@@ -449,7 +449,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
|
||||
@@ -466,7 +466,7 @@
|
||||
if(!verb)
|
||||
return
|
||||
else
|
||||
H.verbs -= verb
|
||||
remove_verb(H, verb)
|
||||
|
||||
else if(href_list["addorgan"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
@@ -70,13 +70,14 @@ var/list/overminds = list()
|
||||
overminds -= src
|
||||
return ..()
|
||||
|
||||
/mob/observer/blob/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
if(blob_core)
|
||||
stat(null, "Core Health: [blob_core.integrity]")
|
||||
stat(null, "Power Stored: [blob_points]/[max_blob_points]")
|
||||
stat(null, "Total Blobs: [GLOB.all_blobs.len]")
|
||||
/mob/observer/blob/get_status_tab_items()
|
||||
. = ..()
|
||||
. += ""
|
||||
. += "BLOB STATUS"
|
||||
if(blob_core)
|
||||
. += "Core Health: [blob_core.integrity]"
|
||||
. += "Power Stored: [blob_points]/[max_blob_points]"
|
||||
. += "Total Blobs: [GLOB.all_blobs.len]"
|
||||
|
||||
/mob/observer/blob/Move(var/atom/NewLoc, Dir = 0)
|
||||
if(placed)
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
////////////////
|
||||
//ADMIN THINGS//
|
||||
////////////////
|
||||
/// hides the byond verb panel as we use our own custom version
|
||||
show_verb_panel = FALSE
|
||||
///Contains admin info. Null if client is not an admin.
|
||||
var/datum/admins/holder = null
|
||||
var/datum/admins/deadmin_holder = null
|
||||
@@ -113,6 +115,23 @@
|
||||
|
||||
// Runechat messages
|
||||
var/list/seen_messages
|
||||
/// our current tab
|
||||
var/stat_tab
|
||||
|
||||
/// list of all tabs
|
||||
var/list/panel_tabs = list()
|
||||
/// list of tabs containing spells and abilities
|
||||
var/list/spell_tabs = list()
|
||||
/// list of misc tabs from mob
|
||||
var/list/misc_tabs = list()
|
||||
///A lazy list of atoms we've examined in the last RECENT_EXAMINE_MAX_WINDOW (default 2) seconds, so that we will call [/atom/proc/examine_more] instead of [/atom/proc/examine] on them when examining
|
||||
var/list/recent_examines
|
||||
///Our object window datum. It stores info about and handles behavior for the object tab
|
||||
var/datum/object_window_info/obj_window
|
||||
|
||||
var/list/misc_cache = list()
|
||||
|
||||
var/atom/examine_icon //Holder for examine icon, useful for statpanel
|
||||
|
||||
//Hide top bars
|
||||
var/fullscreen = FALSE
|
||||
|
||||
@@ -113,6 +113,8 @@
|
||||
log_and_message_admins("[ckey] failed to register their Discord ID. Their Discord snowflake ID is: [their_id]. Is the database connected?")
|
||||
return
|
||||
//VOREStation Add End
|
||||
if(href_list["reload_statbrowser"])
|
||||
stat_panel.reinitialize()
|
||||
|
||||
//Logs all hrefs
|
||||
if(config && config.log_hrefs && href_logfile)
|
||||
@@ -181,6 +183,10 @@
|
||||
GLOB.clients += src
|
||||
GLOB.directory[ckey] = src
|
||||
|
||||
// Instantiate stat panel
|
||||
stat_panel = new(src, "statbrowser")
|
||||
stat_panel.subscribe(src, .proc/on_stat_panel_message)
|
||||
|
||||
// Instantiate tgui panel
|
||||
tgui_say = new(src, "tgui_say")
|
||||
initialize_commandbar_spy()
|
||||
@@ -218,6 +224,14 @@
|
||||
if(prefs)
|
||||
prefs.selecting_slots = FALSE
|
||||
|
||||
// Initialize stat panel
|
||||
stat_panel.initialize(
|
||||
inline_html = file2text('html/statbrowser.html'),
|
||||
inline_js = file2text('html/statbrowser.js'),
|
||||
inline_css = file2text('html/statbrowser.css'),
|
||||
)
|
||||
addtimer(CALLBACK(src, PROC_REF(check_panel_loaded)), 30 SECONDS)
|
||||
|
||||
// Initialize tgui panel
|
||||
tgui_say.initialize()
|
||||
tgui_panel.initialize()
|
||||
@@ -652,3 +666,43 @@
|
||||
to_chat(src, span_warning("No recorded playtime found!"))
|
||||
return
|
||||
to_chat(src, span_info("Your department hours:" + department_hours))
|
||||
|
||||
/// compiles a full list of verbs and sends it to the browser
|
||||
/client/proc/init_verbs()
|
||||
if(IsAdminAdvancedProcCall())
|
||||
return
|
||||
var/list/verblist = list()
|
||||
panel_tabs.Cut()
|
||||
for(var/thing in (verbs + mob?.verbs))
|
||||
var/procpath/verb_to_init = thing
|
||||
if(!verb_to_init)
|
||||
continue
|
||||
if(verb_to_init.hidden)
|
||||
continue
|
||||
if(!istext(verb_to_init.category))
|
||||
continue
|
||||
panel_tabs |= verb_to_init.category
|
||||
verblist[++verblist.len] = list(verb_to_init.category, verb_to_init.name, verb_to_init.desc)
|
||||
src.stat_panel.send_message("init_verbs", list(panel_tabs = panel_tabs, verblist = verblist))
|
||||
|
||||
/client/proc/check_panel_loaded()
|
||||
if(stat_panel && stat_panel.is_ready())
|
||||
return
|
||||
to_chat(src, "<span class='danger'>Statpanel failed to load, click <a href='?src=[REF(src)];reload_statbrowser=1'>here</a> to reload the panel. If this does not work, reconnecting will reassign a new panel.</span>")
|
||||
|
||||
/**
|
||||
* Handles incoming messages from the stat-panel TGUI.
|
||||
*/
|
||||
/client/proc/on_stat_panel_message(type, payload)
|
||||
switch(type)
|
||||
if("Update-Verbs")
|
||||
init_verbs()
|
||||
if("Remove-Tabs")
|
||||
panel_tabs -= payload["tab"]
|
||||
if("Send-Tabs")
|
||||
panel_tabs |= payload["tab"]
|
||||
if("Reset-Tabs")
|
||||
panel_tabs = list()
|
||||
if("Set-Tab")
|
||||
stat_tab = payload["tab"]
|
||||
SSstatpanels.immediate_send_stat_data(src)
|
||||
|
||||
@@ -275,3 +275,9 @@
|
||||
INVOKE_ASYNC(src, VERB_REF(fit_viewport))
|
||||
else //Delayed to avoid wingets from Login calls.
|
||||
addtimer(CALLBACK(src, VERB_REF(fit_viewport), 1 SECONDS))
|
||||
|
||||
/client/verb/fix_stat_panel()
|
||||
set name = "Fix Stat Panel"
|
||||
set hidden = TRUE
|
||||
|
||||
init_verbs()
|
||||
|
||||
@@ -234,28 +234,6 @@
|
||||
/obj/item/rig_module/proc/accepts_item(var/obj/item/input_device)
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/Stat()
|
||||
. = ..()
|
||||
|
||||
if(. && istype(back,/obj/item/rig))
|
||||
var/obj/item/rig/R = back
|
||||
SetupStat(R)
|
||||
|
||||
else if(. && istype(belt,/obj/item/rig))
|
||||
var/obj/item/rig/R = belt
|
||||
SetupStat(R)
|
||||
|
||||
/mob/proc/SetupStat(var/obj/item/rig/R)
|
||||
if(R && !R.canremove && R.installed_modules.len && statpanel("Hardsuit Modules"))
|
||||
var/cell_status = R.cell ? "[R.cell.charge]/[R.cell.maxcharge]" : "ERROR"
|
||||
stat("Suit charge", cell_status)
|
||||
for(var/obj/item/rig_module/module in R.installed_modules)
|
||||
{
|
||||
for(var/stat_rig_module/SRM in module.stat_modules)
|
||||
if(SRM.CanUse())
|
||||
stat(SRM.module.interface_name,SRM)
|
||||
}
|
||||
|
||||
/stat_rig_module
|
||||
parent_type = /atom/movable
|
||||
var/module_mode = ""
|
||||
|
||||
@@ -46,13 +46,6 @@
|
||||
else
|
||||
integrated_ai.get_rig_stats = 0
|
||||
|
||||
/mob/living/Stat()
|
||||
. = ..()
|
||||
if(. && get_rig_stats)
|
||||
var/obj/item/rig/rig = get_rig()
|
||||
if(rig)
|
||||
SetupStat(rig)
|
||||
|
||||
/obj/item/rig_module/ai_container/proc/update_verb_holder()
|
||||
if(!verb_holder)
|
||||
verb_holder = new(src)
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
This means that this file can be unchecked, along with the other examine files, and can be removed entirely with no effort.
|
||||
*/
|
||||
|
||||
#define EXAMINE_PANEL_PADDING " "
|
||||
|
||||
/atom/
|
||||
var/description_info = null //Helpful blue text.
|
||||
@@ -34,7 +33,7 @@
|
||||
|
||||
// Quickly adds the boilerplate code to add an image and padding for the image.
|
||||
/proc/desc_panel_image(var/icon_state)
|
||||
return "[bicon(description_icons[icon_state])][EXAMINE_PANEL_PADDING]"
|
||||
return "[icon2html(description_icons[icon_state], usr)] "
|
||||
|
||||
/mob/living/get_description_fluff()
|
||||
if(flavor_text) //Get flavor text for the green text.
|
||||
@@ -50,50 +49,16 @@
|
||||
/client/var/description_holders[0]
|
||||
|
||||
/client/proc/update_description_holders(atom/A, update_antag_info=0)
|
||||
examine_icon = null
|
||||
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["name"] = "[A.name]"
|
||||
description_holders["icon"] = "[icon2html(A.examine_icon(),src)]"
|
||||
description_holders["icon"] = A
|
||||
description_holders["desc"] = A.desc
|
||||
|
||||
/mob/Stat()
|
||||
. = ..()
|
||||
if(client && statpanel("Examine"))
|
||||
var/description_holders = client.description_holders
|
||||
stat(null,"[description_holders["icon"]] <font size='5'>[description_holders["name"]]</font>") //The name, written in big letters.
|
||||
stat(null,"[description_holders["desc"]]") //the default examine text.
|
||||
|
||||
|
||||
var/color_i = "#084B8A"
|
||||
var/color_f = "#298A08"
|
||||
var/color_a = "#8A0808"
|
||||
/*
|
||||
The infowindow colours are set in code\modules\vchat\js\vchat.js file
|
||||
Unfortunately, I cannot think of a way to do this elegantly where there's this central define that we can easily track.
|
||||
As of 2023/08/05 13:10, the lightmode colour for vchat tabBackgroundColor is "none", this is also defined in interface\skin.dmf .
|
||||
The darkmode colour for vchat tabBackgroundColor is "#272727".
|
||||
Since it's possible that one day we'll have option to modify the user's preferred tabBackgroundColor
|
||||
I will assume the lightmode colour will be left untouched - therefore, we are checking for none.
|
||||
*/
|
||||
if(!(winget(src, "infowindow", "background-color") == "none"))
|
||||
color_i = "#709ec9d8"
|
||||
color_f = "#76d357"
|
||||
color_a = "#c94d4d"
|
||||
|
||||
|
||||
if(description_holders["info"])
|
||||
stat(null,"<font color=[color_i]><b>[description_holders["info"]]</b></font>") //Blue, informative text.
|
||||
if(description_holders["interactions"])
|
||||
for(var/line in description_holders["interactions"])
|
||||
stat(null, "<font color=[color_i]><b>[line]</b></font>")
|
||||
if(description_holders["fluff"])
|
||||
stat(null,"<font color=[color_f]><b>[description_holders["fluff"]]</b></font>") //Yellow, fluff-related text.
|
||||
if(description_holders["antag"])
|
||||
stat(null,"<font color=[color_a]><b>[description_holders["antag"]]</b></font>") //Red, malicious antag-related text
|
||||
|
||||
//override examinate verb to update description holders when things are examined
|
||||
//mob verbs are faster than object verbs. See http://www.byond.com/forum/?post=1326139&page=2#comment8198716 for why this isn't atom/verb/examine()
|
||||
/mob/verb/examinate(atom/A as mob|obj|turf in _validate_atom(A))
|
||||
@@ -122,6 +87,7 @@
|
||||
if(client)
|
||||
var/is_antag = ((mind && mind.special_role) || isobserver(src)) //ghosts don't have minds
|
||||
client.update_description_holders(A, is_antag)
|
||||
SSstatpanels.set_examine_tab(client)
|
||||
|
||||
|
||||
/mob/verb/mob_examine()
|
||||
@@ -198,5 +164,3 @@
|
||||
results = list("You were unable to examine that. Tell a developer!")
|
||||
to_chat(src, jointext(results, "<br>"))
|
||||
update_examine_panel(B)
|
||||
|
||||
#undef EXAMINE_PANEL_PADDING
|
||||
|
||||
@@ -36,11 +36,11 @@ var/list/mentor_verbs_default = list(
|
||||
|
||||
/client/proc/add_mentor_verbs()
|
||||
if(mentorholder)
|
||||
verbs += mentor_verbs_default
|
||||
add_verb(src, mentor_verbs_default)
|
||||
|
||||
/client/proc/remove_mentor_verbs()
|
||||
if(mentorholder)
|
||||
verbs -= mentor_verbs_default
|
||||
remove_verb(src, mentor_verbs_default)
|
||||
|
||||
/client/proc/make_mentor()
|
||||
set category = "Special Verbs"
|
||||
|
||||
@@ -61,17 +61,22 @@ GLOBAL_DATUM_INIT(mhelp_tickets, /datum/mentor_help_tickets, new)
|
||||
|
||||
//Tickets statpanel
|
||||
/datum/mentor_help_tickets/proc/stat_entry()
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
var/list/L = list()
|
||||
var/num_disconnected = 0
|
||||
stat("== Mentor Tickets ==")
|
||||
stat("Active Tickets:", astatclick.update("[active_tickets.len]"))
|
||||
L[++L.len] = list("== Mentor Tickets ==", "", null, null)
|
||||
L[++L.len] = list("Active Tickets:", "[astatclick.update("[active_tickets.len]")]", null, REF(astatclick))
|
||||
astatclick.update("[active_tickets.len]")
|
||||
for(var/datum/mentor_help/MH as anything in active_tickets)
|
||||
if(MH.initiator)
|
||||
stat("#[MH.id]. [MH.initiator_ckey]:", MH.statclick.update())
|
||||
L[++L.len] = list("#[MH.id]. [MH.initiator_ckey]:", "[MH.statclick.update()]", REF(MH))
|
||||
else
|
||||
++num_disconnected
|
||||
if(num_disconnected)
|
||||
stat("Disconnected:", astatclick.update("[num_disconnected]"))
|
||||
stat("Resolved Tickets:", rstatclick.update("[resolved_tickets.len]"))
|
||||
L[++L.len] = list("Disconnected:", "[astatclick.update("[num_disconnected]")]", null, REF(astatclick))
|
||||
L[++L.len] = list("Resolved Tickets:", "[rstatclick.update("[resolved_tickets.len]")]", null, REF(rstatclick))
|
||||
return L
|
||||
|
||||
//Reassociate still open ticket if one exists
|
||||
/datum/mentor_help_tickets/proc/ClientLogin(client/C)
|
||||
@@ -439,9 +444,9 @@ GLOBAL_DATUM_INIT(mhelp_tickets, /datum/mentor_help_tickets, new)
|
||||
"Send to discord?", list("Admin-help!", "Still mentorhelp!", "Cancel"))
|
||||
if(choice == "Admin-help!")
|
||||
usr.client.adminhelp(msg)
|
||||
src.verbs -= /client/verb/mentorhelp
|
||||
remove_verb(src, /client/verb/mentorhelp)
|
||||
spawn(1200)
|
||||
src.verbs += /client/verb/mentorhelp // 2 minute cd to prevent abusing this to spam admins.
|
||||
add_verb(src, /client/verb/mentorhelp) // 2 minute cd to prevent abusing this to spam admins.
|
||||
return
|
||||
else if(!choice || choice == "Cancel")
|
||||
return
|
||||
@@ -449,9 +454,9 @@ GLOBAL_DATUM_INIT(mhelp_tickets, /datum/mentor_help_tickets, new)
|
||||
|
||||
|
||||
//remove out adminhelp verb temporarily to prevent spamming of admins.
|
||||
src.verbs -= /client/verb/mentorhelp
|
||||
remove_verb(src, /client/verb/mentorhelp)
|
||||
spawn(600)
|
||||
src.verbs += /client/verb/mentorhelp // 1 minute cool-down for mentorhelps
|
||||
add_verb(src, /client/verb/mentorhelp) // 1 minute cool-down for mentorhelps
|
||||
|
||||
feedback_add_details("admin_verb","Mentorhelp") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
if(current_mentorhelp)
|
||||
|
||||
@@ -208,7 +208,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.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!
|
||||
return ghost
|
||||
|
||||
/*
|
||||
@@ -249,13 +249,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
/mob/observer/dead/can_use_hands() return 0
|
||||
/mob/observer/dead/is_active() return 0
|
||||
|
||||
/mob/observer/dead/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
if(emergency_shuttle)
|
||||
var/eta_status = emergency_shuttle.get_status_panel_eta()
|
||||
if(eta_status)
|
||||
stat(null, eta_status)
|
||||
/mob/observer/dead/get_status_tab_items()
|
||||
. = ..()
|
||||
if(emergency_shuttle)
|
||||
var/eta_status = emergency_shuttle.get_status_panel_eta()
|
||||
if(eta_status)
|
||||
. += ""
|
||||
. += "[eta_status]"
|
||||
|
||||
/mob/observer/dead/verb/reenter_corpse()
|
||||
set category = "Ghost"
|
||||
@@ -798,8 +798,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, span_filter_notice("[span_purple("As you are now in the realm of the living, you can whisper to the living with the <b>Spectral Whisper</b> verb, inside the IC tab.")]"))
|
||||
if(plane != PLANE_WORLD)
|
||||
user.visible_message( \
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
/datum/language/proc/broadcast(var/mob/living/speaker,var/message,var/speaker_mask)
|
||||
log_say("(HIVE) [message]", speaker)
|
||||
|
||||
speaker.verbs |= /mob/proc/adjust_hive_range
|
||||
add_verb(speaker, /mob/proc/adjust_hive_range)
|
||||
|
||||
if(!speaker_mask) speaker_mask = speaker.real_name
|
||||
message = "[get_spoken_verb(message)], \"[format_message(message, get_spoken_verb(message))]\""
|
||||
@@ -205,7 +205,7 @@
|
||||
languages.Add(new_language)
|
||||
//VOREStation Addition Start
|
||||
if(new_language.flags & HIVEMIND)
|
||||
verbs |= /mob/proc/adjust_hive_range
|
||||
add_verb(src, /mob/proc/adjust_hive_range)
|
||||
//VOREStation Addition End
|
||||
|
||||
return 1
|
||||
|
||||
@@ -562,13 +562,13 @@
|
||||
/mob/living/bot/Login()
|
||||
no_vore = FALSE // ROBOT VORE
|
||||
init_vore() // ROBOT VORE
|
||||
verbs |= /mob/proc/insidePanel
|
||||
add_verb(src, /mob/proc/insidePanel)
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/bot/Logout()
|
||||
release_vore_contents()
|
||||
verbs -= /mob/proc/insidePanel
|
||||
remove_verb(src, /mob/proc/insidePanel)
|
||||
no_vore = TRUE
|
||||
devourable = FALSE
|
||||
feeding = FALSE
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
|
||||
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])"
|
||||
@@ -66,4 +66,3 @@
|
||||
else if(ending == "?")
|
||||
verb = "hisses curiously"
|
||||
return verb
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ var/list/_nymph_default_emotes = list(
|
||||
species = GLOB.all_species[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/put_in_hands(var/obj/item/W) // No hands.
|
||||
W.loc = get_turf(src)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/mob/living/carbon/alien/diona/Stat() //Specified where progression is at, doesn't work right for some things in carbon/alien
|
||||
/mob/living/carbon/alien/diona/get_status_tab_items() //Specified where progression is at, doesn't work right for some things in carbon/alien
|
||||
. = ..()
|
||||
if(. && statpanel("Status"))
|
||||
stat("Growth", "[round(amount_grown)]/[max_grown]")
|
||||
if(.)
|
||||
. += ""
|
||||
. += "Diona Growth: [round(amount_grown)]/[max_grown]"
|
||||
|
||||
/mob/living/carbon/alien/diona/confirm_evolution()
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/mob/living/carbon/alien/larva/Stat() //Specified where progression stats come from, because for some reason it doesn't work right in carbon/alien
|
||||
/mob/living/carbon/alien/larva/get_status_tab_items() //Specified where progression stats come from, because for some reason it doesn't work right in carbon/alien
|
||||
. = ..()
|
||||
if(. && statpanel("Status"))
|
||||
stat("Growth", "[round(amount_grown)]/[max_grown]")
|
||||
if(.)
|
||||
. += ""
|
||||
. += "Larva Growth: [round(amount_grown)]/[max_grown]"
|
||||
|
||||
/mob/living/carbon/alien/larva/confirm_evolution()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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, span_danger("ERROR NO BORER OR BRAINMOB DETECTED IN THIS MOB, THIS IS A BUG !"))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user