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:
ShadowLarkens
2024-10-16 19:39:06 +02:00
committed by GitHub
co-authored by Kashargul
parent ed5fc193f7
commit c07027136e
211 changed files with 3233 additions and 1170 deletions
+4
View File
@@ -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
View File
@@ -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()
+2
View File
@@ -0,0 +1,2 @@
#define TURFLIST_UPDATED (1 << 0)
#define TURFLIST_UPDATE_QUEUED (1 << 1)
+2
View File
@@ -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.
+3
View File
@@ -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
View File
@@ -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)
+4
View File
@@ -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)
+94
View File
@@ -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)
+1 -8
View File
@@ -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)
+1 -1
View File
@@ -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
+1 -1
View File
@@ -16,4 +16,4 @@
/datum/controller/proc/Recover()
/datum/controller/proc/stat_entry()
/datum/controller/proc/stat_entry(msg)
+3 -2
View File
@@ -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
+3 -2
View File
@@ -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])
+5 -3
View File
@@ -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)
+4 -15
View File
@@ -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)
+3 -2
View File
@@ -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)
+3 -4
View File
@@ -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)
+3 -4
View File
@@ -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)
+3 -2
View File
@@ -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 ..()
+4 -3
View File
@@ -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
+3 -2
View File
@@ -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)
+3 -2
View File
@@ -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.
+3 -4
View File
@@ -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)
+4 -3
View File
@@ -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()
+3 -4
View File
@@ -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
+3 -2
View File
@@ -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)
+3 -2
View File
@@ -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
+3 -2
View File
@@ -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"
+4 -3
View File
@@ -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)
+3 -2
View File
@@ -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 ..()
+481
View File
@@ -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]&emsp;<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")
+3 -2
View File
@@ -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)
+3 -2
View File
@@ -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)
+3 -2
View File
@@ -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)
+18 -9
View File
@@ -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
+2 -1
View File
@@ -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
+3 -4
View File
@@ -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
View File
@@ -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()
+6 -6
View File
@@ -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
View File
@@ -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
+3 -3
View File
@@ -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
+1 -1
View File
@@ -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()
+7 -6
View File
@@ -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))
+2 -2
View File
@@ -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.
+2 -2
View File
@@ -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)
+4 -4
View File
@@ -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)
..()
+2 -2
View File
@@ -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!
+2 -2
View File
@@ -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)
+19 -18
View File
@@ -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
)
))
+19 -18
View File
@@ -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
)
))
+22 -15
View File
@@ -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")
+2
View File
@@ -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
+19 -19
View File
@@ -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//////////////
+5 -3
View File
@@ -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)
+16 -8
View File
@@ -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)
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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!
+3 -3
View File
@@ -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!
+2 -2
View File
@@ -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"
+2 -2
View File
@@ -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
+8 -7
View File
@@ -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)
+19
View File
@@ -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
+54
View File
@@ -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)
+6
View File
@@ -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)
+4 -40
View File
@@ -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)]&emsp;"
/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
+2 -2
View File
@@ -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"
+14 -9
View File
@@ -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)
+10 -10
View File
@@ -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( \
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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