diff --git a/Hyperbot/ahelp.txt b/Hyperbot/ahelp.txt new file mode 100644 index 00000000..3f9bacc7 --- /dev/null +++ b/Hyperbot/ahelp.txt @@ -0,0 +1 @@ +**QuoteFox/(Test Character)** *()*```cum``` diff --git a/code/__DEFINES/procpath.dm b/code/__DEFINES/procpath.dm new file mode 100644 index 00000000..642ca3ea --- /dev/null +++ b/code/__DEFINES/procpath.dm @@ -0,0 +1,26 @@ +/// Represents a proc or verb path. +/// +/// Despite having no DM-defined static type, proc paths have some variables, +/// listed below. These are not modifiable, but for a given procpath P, +/// `new P(null, "Name", "Desc")` can be used to create a new procpath with the +/// same code but new `name` and `desc` values. The other variables cannot be +/// changed in this way. +/// +/// This type exists only to act as an annotation, providing reasonable static +/// typing for procpaths. Previously, types like `/atom/verb` were used, with +/// the `name` and `desc` vars of `/atom` thus being accessible. Proc and verb +/// paths will fail `istype` and `ispath` checks against `/procpath`. +/procpath + // Although these variables are effectively const, if they are marked const + // below, their accesses are optimized away. + + /// A text string of the verb's name. + var/name as text + /// The verb's help text or description. + var/desc as text + /// The category or tab the verb will appear in. + var/category as text + /// Only clients/mobs with `see_invisibility` higher can use the verb. + var/invisibility as num + /// Whether or not the verb appears in statpanel and commandbar when you press space + var/hidden as num diff --git a/code/__DEFINES/spaceman_dmm.dm b/code/__DEFINES/spaceman_dmm.dm index b9c0544b..10d586dc 100644 --- a/code/__DEFINES/spaceman_dmm.dm +++ b/code/__DEFINES/spaceman_dmm.dm @@ -6,10 +6,14 @@ #define RETURN_TYPE(X) set SpacemanDMM_return_type = X #define SHOULD_CALL_PARENT(X) set SpacemanDMM_should_call_parent = X #define UNLINT(X) SpacemanDMM_unlint(X) + #define SHOULD_NOT_OVERRIDE(X) set SpacemanDMM_should_not_override = X + #define SHOULD_NOT_SLEEP(X) set SpacemanDMM_should_not_sleep = X #else #define RETURN_TYPE(X) #define SHOULD_CALL_PARENT(X) #define UNLINT(X) X + #define SHOULD_NOT_OVERRIDE(X) + #define SHOULD_NOT_SLEEP(X) #endif /world/proc/enable_debugger() diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index f4e0c316..f2ef5638 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -84,6 +84,7 @@ #define INIT_ORDER_MINOR_MAPPING -40 #define INIT_ORDER_PATH -50 #define INIT_ORDER_PERSISTENCE -95 +#define INIT_ORDER_STATPANELS -98 #define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init. // Subsystem fire priority, from lowest to highest priority diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 05c93878..ec1abadd 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -337,7 +337,7 @@ if(!previous) var/list/report_parts = list(personal_report(C), GLOB.common_report) content = report_parts.Join() - C.verbs -= /client/proc/show_previous_roundend_report + remove_verb(C, /client/proc/show_previous_roundend_report) fdel(filename) text2file(content, filename) else diff --git a/code/__HELPERS/verbs.dm b/code/__HELPERS/verbs.dm new file mode 100644 index 00000000..60dcaeda --- /dev/null +++ b/code/__HELPERS/verbs.dm @@ -0,0 +1,96 @@ +/** + * 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) + output_list = url_encode(json_encode(output_list)) + + target << output("[output_list];", "statbrowser:add_verb_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) + output_list = url_encode(json_encode(output_list)) + + target << output("[output_list];", "statbrowser:remove_verb_list") \ No newline at end of file diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 46ae8e39..e1e6c0b6 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -374,6 +374,10 @@ /atom/proc/AltClick(mob/user) . = SEND_SIGNAL(src, COMSIG_CLICK_ALT, user) + var/turf/T = get_turf(src) + if(T && (isturf(loc) || isturf(src)) && user.TurfAdjacent(T)) + user.listed_turf = T + user.client << output("[url_encode(json_encode(T.name))];", "statbrowser:create_listedturf") /mob/proc/TurfAdjacent(turf/T) return T.Adjacent(src) diff --git a/code/_onclick/hud/credits.dm b/code/_onclick/hud/credits.dm index 2cd0dded..31ea453d 100644 --- a/code/_onclick/hud/credits.dm +++ b/code/_onclick/hud/credits.dm @@ -11,7 +11,7 @@ var/icon/credits_icon = new(CREDITS_PATH) LAZYINITLIST(credits) var/list/_credits = credits - verbs += /client/proc/ClearCredits + add_verb(src, /client/proc/ClearCredits) var/static/list/credit_order_for_this_round if(isnull(credit_order_for_this_round)) credit_order_for_this_round = list("Thanks for playing!") + (shuffle(icon_states(credits_icon)) - "Thanks for playing!") @@ -21,13 +21,13 @@ _credits += new /obj/screen/credit(null, I, src, credits_icon) sleep(CREDIT_SPAWN_SPEED) sleep(CREDIT_ROLL_SPEED - CREDIT_SPAWN_SPEED) - verbs -= /client/proc/ClearCredits + remove_verb(src, /client/proc/ClearCredits) qdel(credits_icon) /client/proc/ClearCredits() set name = "Hide Credits" set category = "OOC" - verbs -= /client/proc/ClearCredits + remove_verb(src, /client/proc/ClearCredits) QDEL_LIST(credits) credits = null diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index 4fe0812c..d9d818ac 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -165,10 +165,9 @@ log_world(msg) return time -//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc. + /datum/controller/subsystem/stat_entry(msg) - if(!statclick) - statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) + @@ -177,11 +176,7 @@ else msg = "OFFLINE\t[msg]" - var/title = name - if (can_fire) - title = "\[[state_letter()]][title]" - - stat(title, statclick.update(msg)) + return msg /datum/controller/subsystem/proc/state_letter() switch (state) diff --git a/code/controllers/subsystem/acid.dm b/code/controllers/subsystem/acid.dm index e3c41596..21fb4349 100644 --- a/code/controllers/subsystem/acid.dm +++ b/code/controllers/subsystem/acid.dm @@ -7,9 +7,9 @@ SUBSYSTEM_DEF(acid) var/list/currentrun = list() var/list/processing = list() -/datum/controller/subsystem/acid/stat_entry() - ..("P:[processing.len]") - +/datum/controller/subsystem/acid/stat_entry(msg) + msg = "P:[length(processing)]" + return ..() /datum/controller/subsystem/acid/fire(resumed = 0) if (!resumed) diff --git a/code/controllers/subsystem/adjacent_air.dm b/code/controllers/subsystem/adjacent_air.dm index 8395eda7..ccbf8ffc 100644 --- a/code/controllers/subsystem/adjacent_air.dm +++ b/code/controllers/subsystem/adjacent_air.dm @@ -6,12 +6,13 @@ SUBSYSTEM_DEF(adjacent_air) priority = FIRE_PRIORITY_ATMOS_ADJACENCY var/list/queue = list() -/datum/controller/subsystem/adjacent_air/stat_entry() +/datum/controller/subsystem/adjacent_air/stat_entry(msg) #ifdef TESTING - ..("P:[length(queue)], S:[GLOB.atmos_adjacent_savings[1]], T:[GLOB.atmos_adjacent_savings[2]]") + msg = "P:[length(queue)], S:[GLOB.atmos_adjacent_savings[1]], T:[GLOB.atmos_adjacent_savings[2]]" #else - ..("P:[length(queue)]") + msg = "P:[length(queue)]" #endif + return ..() /datum/controller/subsystem/adjacent_air/Initialize() while(length(queue)) diff --git a/code/controllers/subsystem/augury.dm b/code/controllers/subsystem/augury.dm index 1b1c7bc3..53c86004 100644 --- a/code/controllers/subsystem/augury.dm +++ b/code/controllers/subsystem/augury.dm @@ -9,7 +9,8 @@ SUBSYSTEM_DEF(augury) var/list/observers_given_action = list() /datum/controller/subsystem/augury/stat_entry(msg) - ..("W:[watchers.len]|D:[doombringers.len]") + msg = "W:[watchers.len]|D:[length(doombringers)]" + return ..() /datum/controller/subsystem/augury/proc/register_doom(atom/A, severity) doombringers[A] = severity diff --git a/code/controllers/subsystem/disease.dm b/code/controllers/subsystem/disease.dm index 9be1d8d9..4fe5533e 100644 --- a/code/controllers/subsystem/disease.dm +++ b/code/controllers/subsystem/disease.dm @@ -20,7 +20,8 @@ SUBSYSTEM_DEF(disease) return ..() /datum/controller/subsystem/disease/stat_entry(msg) - ..("P:[active_diseases.len]") + msg = "P:[length(active_diseases)]" + return ..() /datum/controller/subsystem/disease/proc/get_disease_name(id) var/datum/disease/advance/A = archive_diseases[id] diff --git a/code/controllers/subsystem/fire_burning.dm b/code/controllers/subsystem/fire_burning.dm index db6dc651..6ac42f8c 100644 --- a/code/controllers/subsystem/fire_burning.dm +++ b/code/controllers/subsystem/fire_burning.dm @@ -7,9 +7,9 @@ SUBSYSTEM_DEF(fire_burning) var/list/currentrun = list() var/list/processing = list() -/datum/controller/subsystem/fire_burning/stat_entry() - ..("P:[processing.len]") - +/datum/controller/subsystem/fire_burning/stat_entry(msg) + msg = "P:[length(processing)]" + return ..() /datum/controller/subsystem/fire_burning/fire(resumed = 0) if (!resumed) diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm index f8ca1e7e..328818fd 100644 --- a/code/controllers/subsystem/garbage.dm +++ b/code/controllers/subsystem/garbage.dm @@ -57,7 +57,7 @@ SUBSYSTEM_DEF(garbage) msg += "TGR:[round((totalgcs/(totaldels+totalgcs))*100, 0.01)]%" msg += " P:[pass_counts.Join(",")]" msg += "|F:[fail_counts.Join(",")]" - ..(msg) + return ..() /datum/controller/subsystem/garbage/Shutdown() //Adds the del() log to the qdel log file diff --git a/code/controllers/subsystem/idlenpcpool.dm b/code/controllers/subsystem/idlenpcpool.dm index 8992fa7b..03b7931d 100644 --- a/code/controllers/subsystem/idlenpcpool.dm +++ b/code/controllers/subsystem/idlenpcpool.dm @@ -8,10 +8,11 @@ SUBSYSTEM_DEF(idlenpcpool) var/list/currentrun = list() var/static/list/idle_mobs_by_zlevel[][] -/datum/controller/subsystem/idlenpcpool/stat_entry() +/datum/controller/subsystem/idlenpcpool/stat_entry(msg) var/list/idlelist = GLOB.simple_animals[AI_IDLE] var/list/zlist = GLOB.simple_animals[AI_Z_OFF] - ..("IdleNPCS:[idlelist.len]|Z:[zlist.len]") + msg = "IdleNPCS:[length(idlelist)]|Z:[length(zlist)]" + return ..() /datum/controller/subsystem/idlenpcpool/proc/MaxZChanged() if (!islist(idle_mobs_by_zlevel)) diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm index 12b467b6..7eff66eb 100644 --- a/code/controllers/subsystem/lighting.dm +++ b/code/controllers/subsystem/lighting.dm @@ -7,10 +7,13 @@ SUBSYSTEM_DEF(lighting) wait = 2 init_order = INIT_ORDER_LIGHTING flags = SS_TICKER + var/static/list/sources_queue = list() // List of lighting sources queued for update. + var/static/list/corners_queue = list() // List of lighting corners queued for update. + var/static/list/objects_queue = list() // List of lighting objects queued for update. -/datum/controller/subsystem/lighting/stat_entry() - ..("L:[GLOB.lighting_update_lights.len]|C:[GLOB.lighting_update_corners.len]|O:[GLOB.lighting_update_objects.len]") - +/datum/controller/subsystem/lighting/stat_entry(msg) + msg = "L:[length(sources_queue)]|C:[length(corners_queue)]|O:[length(objects_queue)]" + return ..() /datum/controller/subsystem/lighting/Initialize(timeofday) if(!initialized) diff --git a/code/controllers/subsystem/machines.dm b/code/controllers/subsystem/machines.dm index c4b09d1b..04b65410 100644 --- a/code/controllers/subsystem/machines.dm +++ b/code/controllers/subsystem/machines.dm @@ -22,9 +22,10 @@ SUBSYSTEM_DEF(machines) NewPN.add_cable(PC) propagate_network(PC,PC.powernet) -/datum/controller/subsystem/machines/stat_entry() - ..("M:[processing.len]|PN:[powernets.len]") +/datum/controller/subsystem/machines/stat_entry(msg) + msg = "M:[length(processing)]|PN:[length(powernets)]" + return ..() /datum/controller/subsystem/machines/fire(resumed = 0) if (!resumed) diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm index aac9f9d3..1e8efff0 100644 --- a/code/controllers/subsystem/mobs.dm +++ b/code/controllers/subsystem/mobs.dm @@ -10,8 +10,9 @@ SUBSYSTEM_DEF(mobs) var/static/list/cubemonkeys = list() var/static/list/cheeserats = list() -/datum/controller/subsystem/mobs/stat_entry() - ..("P:[GLOB.mob_living_list.len]") +/datum/controller/subsystem/mobs/stat_entry(msg) + msg = "P:[length(GLOB.mob_living_list)]" + return ..() /datum/controller/subsystem/mobs/proc/MaxZChanged() if (!islist(clients_by_zlevel)) diff --git a/code/controllers/subsystem/npcpool.dm b/code/controllers/subsystem/npcpool.dm index 7fd35124..5e8fc1f5 100644 --- a/code/controllers/subsystem/npcpool.dm +++ b/code/controllers/subsystem/npcpool.dm @@ -6,9 +6,10 @@ SUBSYSTEM_DEF(npcpool) var/list/currentrun = list() -/datum/controller/subsystem/npcpool/stat_entry() +/datum/controller/subsystem/npcpool/stat_entry(msg) var/list/activelist = GLOB.simple_animals[AI_ON] - ..("NPCS:[activelist.len]") + msg = "NPCS:[length(activelist)]" + return ..() /datum/controller/subsystem/npcpool/fire(resumed = FALSE) diff --git a/code/controllers/subsystem/overlays.dm b/code/controllers/subsystem/overlays.dm index 20eb2af0..f8f7a16b 100644 --- a/code/controllers/subsystem/overlays.dm +++ b/code/controllers/subsystem/overlays.dm @@ -21,10 +21,9 @@ SUBSYSTEM_DEF(overlays) fire(mc_check = FALSE) return ..() - -/datum/controller/subsystem/overlays/stat_entry() - ..("Ov:[length(queue)]") - +/datum/controller/subsystem/overlays/stat_entry(msg) + msg = "Ov:[length(queue)]" + return ..() /datum/controller/subsystem/overlays/Shutdown() text2file(render_stats(stats), "[GLOB.log_directory]/overlay.log") diff --git a/code/controllers/subsystem/processing/processing.dm b/code/controllers/subsystem/processing/processing.dm index c5d6dfa1..637b0499 100644 --- a/code/controllers/subsystem/processing/processing.dm +++ b/code/controllers/subsystem/processing/processing.dm @@ -10,8 +10,9 @@ SUBSYSTEM_DEF(processing) var/list/processing = list() var/list/currentrun = list() -/datum/controller/subsystem/processing/stat_entry() - ..("[stat_tag]:[processing.len]") +/datum/controller/subsystem/processing/stat_entry(msg) + msg = "[stat_tag]:[length(processing)]" + return ..() /datum/controller/subsystem/processing/fire(resumed = 0) if (!resumed) diff --git a/code/controllers/subsystem/spacedrift.dm b/code/controllers/subsystem/spacedrift.dm index f23f41b7..b6cec58b 100644 --- a/code/controllers/subsystem/spacedrift.dm +++ b/code/controllers/subsystem/spacedrift.dm @@ -8,9 +8,9 @@ SUBSYSTEM_DEF(spacedrift) var/list/currentrun = list() var/list/processing = list() -/datum/controller/subsystem/spacedrift/stat_entry() - ..("P:[processing.len]") - +/datum/controller/subsystem/spacedrift/stat_entry(msg) + msg = "P:[length(processing)]" + return ..() /datum/controller/subsystem/spacedrift/fire(resumed = 0) if (!resumed) diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm new file mode 100644 index 00000000..7c9510fa --- /dev/null +++ b/code/controllers/subsystem/statpanel.dm @@ -0,0 +1,114 @@ +SUBSYSTEM_DEF(statpanels) + name = "Stat Panels" + wait = 4 + init_order = INIT_ORDER_STATPANELS + runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY + var/list/currentrun = list() + var/encoded_global_data + var/mc_data_encoded + var/list/cached_images = list() + +/datum/controller/subsystem/statpanels/fire(resumed = FALSE) + if (!resumed) + var/datum/map_config/cached = SSmapping.next_map_config + var/round_time = world.time - SSticker.round_start_time + var/list/global_data = list( + "Map: [SSmapping.config?.map_name || "Loading..."]", + cached ? "Next Map: [cached.map_name]" : null, + "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]", + "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]", + "Round Time: [round_time > MIDNIGHT_ROLLOVER ? "[round(round_time/MIDNIGHT_ROLLOVER)]:[worldtime2text()]" : worldtime2text()]", + "Station Time: [station_time_timestamp()]", + "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(SSshuttle.emergency) + var/ETA = SSshuttle.emergency.getModeStr() + if(ETA) + global_data += "[ETA] [SSshuttle.emergency.getTimerStr()]" + encoded_global_data = url_encode(json_encode(global_data)) + + var/list/mc_data = list( + list("CPU:", world.cpu), + list("Instances:", "[num2text(world.contents.len, 10)]"), + list("World Time:", "[world.time]"), + list("Globals:", "Edit", "\ref[GLOB]"), + list("[config]:", "Edit", "\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)]%))"), + list("Master Controller:", Master ? "(TickRate:[Master.processing]) (Iteration:[Master.iteration])" : "ERROR", "\ref[Master]"), + list("Failsafe Controller:", Failsafe ? "Defcon: [Failsafe.defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])" : "ERROR", "\ref[Failsafe]"), + list("","") + ) + for(var/ss in Master.subsystems) + var/datum/controller/subsystem/sub_system = ss + 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: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]", "\ref[GLOB.cameranet]") + mc_data_encoded = url_encode(json_encode(mc_data)) + src.currentrun = GLOB.clients.Copy() + + var/list/currentrun = src.currentrun + while(length(currentrun)) + var/client/target = currentrun[length(currentrun)] + currentrun.len-- + var/ping_str = url_encode("Ping: [round(target.lastping, 1)]ms (Average: [round(target.avgping, 1)]ms)") + var/other_str = url_encode(json_encode(target.mob.get_status_tab_items())) + target << output("[encoded_global_data];[ping_str];[other_str]", "statbrowser:update") + if(!target.holder) + target << output("", "statbrowser:remove_admin_tabs") + else + var/turf/eye_turf = get_turf(target.eye) + var/coord_entry = url_encode(COORD(eye_turf)) + target << output("[mc_data_encoded];[coord_entry];[url_encode(target.holder.href_token)]", "statbrowser:update_mc") + var/list/ahelp_tickets = GLOB.ahelp_tickets.stat_entry() + target << output("[url_encode(json_encode(ahelp_tickets))];", "statbrowser:update_tickets") + if(!length(GLOB.sdql2_queries)) + target << output("", "statbrowser:remove_sqdl2") + else + var/list/sqdl2A = list() + sqdl2A[++sqdl2A.len] = list("", "Access Global SDQL2 List", REF(GLOB.sdql2_vv_statobj)) + var/list/sqdl2B = list() + sqdl2A += sqdl2B + target << output(url_encode(json_encode(sqdl2A)), "statbrowser:update_sqdl2") + var/list/proc_holders = target.mob.get_proc_holders() + target.spell_tabs.Cut() + for(var/phl in proc_holders) + var/list/proc_holder_list = phl + target.spell_tabs |= proc_holder_list[1] + var/proc_holders_encoded = "" + if(length(proc_holders)) + proc_holders_encoded = url_encode(json_encode(proc_holders)) + target << output("[url_encode(json_encode(target.spell_tabs))];[proc_holders_encoded]", "statbrowser:update_spells") + if(target.mob?.listed_turf) + var/mob/target_mob = target.mob + if(!target_mob.TurfAdjacent(target_mob.listed_turf)) + target << output("", "statbrowser:remove_listedturf") + target_mob.listed_turf = null + else + var/list/overrides = list() + var/list/turfitems = list() + for(var/img in target.images) + var/image/target_image = img + if(!target_image.loc || target_image.loc.loc != target_mob.listed_turf || !target_image.override) + continue + overrides += target_image.loc + for(var/tc in target_mob.listed_turf) + var/atom/movable/turf_content = tc + 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 + if(length(turfitems) < 30) // only create images for the first 30 items on the turf, for performance reasons + if(!(REF(turf_content) in cached_images)) + target << browse_rsc(getFlatIcon(turf_content, no_anim = TRUE), "[REF(turf_content)].png") + cached_images += REF(turf_content) + turfitems[++turfitems.len] = list("[turf_content.name]", REF(turf_content), "[REF(turf_content)].png") + else + turfitems[++turfitems.len] = list("[turf_content.name]", REF(turf_content)) + turfitems = url_encode(json_encode(turfitems)) + target << output("[turfitems];", "statbrowser:update_listedturf") + if(MC_TICK_CHECK) + return \ No newline at end of file diff --git a/code/controllers/subsystem/tgui.dm b/code/controllers/subsystem/tgui.dm index dacbac40..9fc689ff 100644 --- a/code/controllers/subsystem/tgui.dm +++ b/code/controllers/subsystem/tgui.dm @@ -16,8 +16,9 @@ SUBSYSTEM_DEF(tgui) /datum/controller/subsystem/tgui/Shutdown() close_all_uis() -/datum/controller/subsystem/tgui/stat_entry() - ..("P:[processing_uis.len]") +/datum/controller/subsystem/tgui/stat_entry(msg) + msg = "P:[length(open_uis)]" + return ..() /datum/controller/subsystem/tgui/fire(resumed = 0) if (!resumed) diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm index 908b8944..b491cc3c 100644 --- a/code/controllers/subsystem/throwing.dm +++ b/code/controllers/subsystem/throwing.dm @@ -11,9 +11,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:[length(processing)]" + return ..() /datum/controller/subsystem/throwing/fire(resumed = 0) if (!resumed) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 810882ff..0f4b34f4 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -402,6 +402,7 @@ SUBSYSTEM_DEF(ticker) if(living.client) var/obj/screen/splash/S = new(living.client, TRUE) S.Fade(TRUE) + living.client.init_verbs() livings += living if(livings.len) addtimer(CALLBACK(src, .proc/release_characters, livings), 30, TIMER_CLIENT_TIME) @@ -677,7 +678,7 @@ SUBSYSTEM_DEF(ticker) if(!round_end_sound) round_end_sound = pick(\ 'sound/roundend/iwishtherewassomethingmore.ogg', - 'sound/roundend/likeisaid.ogg', + 'sound/roundend/likeisaid.ogg', 'sound/roundend/whatarottenwaytodie.ogg', 'sound/roundend/whatashame.ogg', 'sound/roundend/newroundsexy.ogg', diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm index d0eb0b9c..90ee4b48 100644 --- a/code/controllers/subsystem/timer.dm +++ b/code/controllers/subsystem/timer.dm @@ -34,7 +34,8 @@ SUBSYSTEM_DEF(timer) bucket_resolution = world.tick_lag /datum/controller/subsystem/timer/stat_entry(msg) - ..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]") + msg = "B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]" + return ..() /datum/controller/subsystem/timer/fire(resumed = FALSE) var/lit = last_invoke_tick diff --git a/code/datums/components/rotation.dm b/code/datums/components/rotation.dm index c4ed0031..84a56ace 100644 --- a/code/datums/components/rotation.dm +++ b/code/datums/components/rotation.dm @@ -12,6 +12,48 @@ var/rotation_flags = NONE var/default_rotation_direction = ROTATION_CLOCKWISE +/* +/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) + output_list = url_encode(json_encode(output_list)) + + target << output("[output_list];", "statbrowser:add_verb_list") +*/ /datum/component/simple_rotation/Initialize(rotation_flags = NONE ,can_user_rotate,can_be_rotated,after_rotation) if(!ismovableatom(parent)) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 0e4e9319..8712851a 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -128,6 +128,9 @@ transfer_martial_arts(new_character) if(active || force_key_move) new_character.key = key //now transfer the key to link the client to our new body + if(new_character.client) + //LAZYCLEARLIST(new_character.client.recent_examines) + new_character.client.init_verbs() // re-initialize character specific verbs //CIT CHANGE - makes arousal update when transfering bodies if(isliving(new_character)) //New humans and such are by default enabled arousal. Let's always use the new mind's prefs. @@ -771,6 +774,7 @@ if(istype(S, spell)) spell_list -= S qdel(S) + current?.client << output(null, "statbrowser:check_spells") /datum/mind/proc/RemoveAllSpells() for(var/obj/effect/proc_holder/S in spell_list) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index d3c530cb..04314dd7 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -873,3 +873,20 @@ Proc for attack log creation, because really why not /atom/proc/intercept_zImpact(atom/movable/AM, levels = 1) . |= SEND_SIGNAL(src, COMSIG_ATOM_INTERCEPT_Z_FALL, AM, levels) +///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_shiftclick"]) + paramslist["shift"] = "1" + if(href_list["statpanel_item_ctrlclick"]) + paramslist["ctrl"] = "1" + if(href_list["statpanel_item_altclick"]) + paramslist["alt"] = "1" + if(href_list["statpanel_item_click"]) + // first of all make sure we valid + var/mouseparams = list2params(paramslist) + usr_client.Click(src, loc, null, mouseparams) \ No newline at end of file diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm index c5946719..bcdee791 100644 --- a/code/game/gamemodes/sandbox/h_sandbox.dm +++ b/code/game/gamemodes/sandbox/h_sandbox.dm @@ -9,7 +9,8 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) sandbox.owner = src.ckey if(src.client.holder) sandbox.admin = 1 - verbs += new/mob/proc/sandbox_panel + add_verb(src, /mob/proc/sandbox_panel) + /mob/proc/sandbox_panel() set name = "Sandbox Panel" if(sandbox) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 0ab823e2..3a24d7aa 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -74,6 +74,7 @@ GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin()) /client/proc/addbunkerbypass, /client/proc/revokebunkerbypass, /client/proc/stop_sounds, + /client/proc/debugstatpanel, /client/proc/hide_verbs, /*hides all our adminverbs*/ /client/proc/hide_most_verbs, /*hides all our hideable adminverbs*/ /datum/admins/proc/open_borgopanel @@ -256,36 +257,36 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( control_freak = CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS var/rights = holder.rank.rights - verbs += GLOB.admin_verbs_default + add_verb(src, GLOB.admin_verbs_default) if(rights & R_BUILDMODE) - verbs += /client/proc/togglebuildmodeself + add_verb(src, /client/proc/togglebuildmodeself) if(rights & R_ADMIN) - verbs += GLOB.admin_verbs_admin + add_verb(src, GLOB.admin_verbs_admin) if(rights & R_BAN) - verbs += GLOB.admin_verbs_ban + add_verb(src, GLOB.admin_verbs_ban) if(rights & R_FUN) - verbs += GLOB.admin_verbs_fun + add_verb(src, GLOB.admin_verbs_fun) if(rights & R_SERVER) - verbs += GLOB.admin_verbs_server + add_verb(src, GLOB.admin_verbs_server) if(rights & R_DEBUG) - verbs += GLOB.admin_verbs_debug + add_verb(src, GLOB.admin_verbs_debug) if(rights & R_POSSESS) - verbs += GLOB.admin_verbs_possess + add_verb(src, GLOB.admin_verbs_possess) if(rights & R_PERMISSIONS) - verbs += GLOB.admin_verbs_permissions + add_verb(src, GLOB.admin_verbs_permissions) if(rights & R_STEALTH) - verbs += /client/proc/stealth + add_verb(src, /client/proc/stealth) if(rights & R_ADMIN) - verbs += GLOB.admin_verbs_poll + add_verb(src, GLOB.admin_verbs_poll) if(rights & R_SOUNDS) - verbs += GLOB.admin_verbs_sounds + add_verb(src, GLOB.admin_verbs_sounds) if(CONFIG_GET(string/invoke_youtubedl)) - verbs += /client/proc/play_web_sound + add_verb(src, /client/proc/play_web_sound) if(rights & R_SPAWN) - verbs += GLOB.admin_verbs_spawn + add_verb(src, GLOB.admin_verbs_spawn) /client/proc/remove_admin_verbs() - verbs.Remove( + remove_verb(src, list( GLOB.admin_verbs_default, /client/proc/togglebuildmodeself, GLOB.admin_verbs_admin, @@ -304,14 +305,14 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( GLOB.admin_verbs_debug_mapping, /client/proc/disable_debug_verbs, /client/proc/readmin - ) + )) /client/proc/hide_most_verbs()//Allows you to keep some functionality while hiding some verbs set name = "Adminverbs - Hide Most" set category = "Admin" verbs.Remove(/client/proc/hide_most_verbs, GLOB.admin_verbs_hideable) - verbs += /client/proc/show_verbs + add_verb(src, /client/proc/show_verbs) to_chat(src, "Most of your adminverbs have been hidden.") SSblackbox.record_feedback("tally", "admin_verb", 1, "Hide Most Adminverbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -322,7 +323,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( set category = "Admin" remove_admin_verbs() - verbs += /client/proc/show_verbs + add_verb(src, /client/proc/show_verbs) to_chat(src, "Almost all of your adminverbs have been hidden.") SSblackbox.record_feedback("tally", "admin_verb", 1, "Hide All Adminverbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -332,7 +333,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( set name = "Adminverbs - Show" set category = "Admin" - verbs -= /client/proc/show_verbs + remove_verb(src, /client/proc/show_verbs) add_admin_verbs() to_chat(src, "All of your adminverbs are now visible.") @@ -365,6 +366,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( message_admins("[key_name_admin(usr)] admin ghosted.") var/mob/body = mob body.ghostize(1) + init_verbs() if(body && !body.key) body.key = "@[key]" //Haaaaaaaack. But the people have spoken. If it breaks; blame adminbus SSblackbox.record_feedback("tally", "admin_verb", 1, "Admin Ghost") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -717,3 +719,10 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( log_admin("[key_name(usr)] has [AI_Interact ? "activated" : "deactivated"] Admin AI Interact") message_admins("[key_name_admin(usr)] has [AI_Interact ? "activated" : "deactivated"] their AI interaction") + + +/client/proc/debugstatpanel() + set name = "Debug Stat Panel" + set category = "Debug" + + src << output("", "statbrowser:create_debug") \ No newline at end of file diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index f9bed188..04c1909c 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -93,7 +93,7 @@ GLOBAL_PROTECT(href_token) var/client/C if ((C = owner) || (C = GLOB.directory[target])) disassociate() - C.verbs += /client/proc/readmin + add_verb(C, /client/proc/readmin) /datum/admins/proc/associate(client/C) if(IsAdminAdvancedProcCall()) @@ -113,7 +113,8 @@ GLOBAL_PROTECT(href_token) owner = C owner.holder = src owner.add_admin_verbs() //TODO <--- todo what? the proc clearly exists and works since its the backbone to our entire admin system - owner.verbs -= /client/proc/readmin + remove_verb(owner, /client/proc/readmin) + owner.init_verbs() //re-initialize the verb list GLOB.admins |= C /datum/admins/proc/disassociate() @@ -125,6 +126,7 @@ GLOBAL_PROTECT(href_token) if(owner) GLOB.admins -= owner owner.remove_admin_verbs() + owner.init_verbs() owner.holder = null owner = null diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index 41496b35..3e83974d 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -393,11 +393,14 @@ 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) @@ -1161,10 +1164,18 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null return istype(thing, /datum) || istype(thing, /client) /obj/effect/statclick/SDQL2_delete/Click() + if(!usr.client?.holder) + message_admins("[key_name_admin(usr)] non-holder clicked on a statclick! ([src])") + log_game("[key_name(usr)] non-holder clicked on a statclick! ([src])") + return var/datum/SDQL2_query/Q = target Q.delete_click() /obj/effect/statclick/SDQL2_action/Click() + if(!usr.client?.holder) + message_admins("[key_name_admin(usr)] non-holder clicked on a statclick! ([src])") + log_game("[key_name(usr)] non-holder clicked on a statclick! ([src])") + return var/datum/SDQL2_query/Q = target Q.action_click() @@ -1172,4 +1183,13 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null name = "VIEW VARIABLES" /obj/effect/statclick/SDQL2_VV_all/Click() + if(!usr.client?.holder) + message_admins("[key_name_admin(usr)] non-holder clicked on a statclick! ([src])") + log_game("[key_name(usr)] non-holder clicked on a statclick! ([src])") + return usr.client.debug_variables(GLOB.sdql2_queries) + + if(!usr.client?.holder) + message_admins("[key_name_admin(usr)] non-holder clicked on a statclick! ([src])") + log_game("[key_name(usr)] non-holder clicked on a statclick! ([src])") + return \ No newline at end of file diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index b24ce6d1..256bdaf0 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -89,18 +89,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("Active Tickets:", astatclick.update("[active_tickets.len]")) + L[++L.len] = list("Active Tickets:", "[astatclick.update("[active_tickets.len]")]", null, REF(astatclick)) + astatclick.update("[active_tickets.len]") for(var/I in active_tickets) var/datum/admin_help/AH = I if(AH.initiator) - stat("#[AH.id]. [AH.initiator_key_name]:", AH.statclick.update()) + 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) @@ -137,6 +142,13 @@ 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 // @@ -221,7 +233,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) //Removes the ahelp verb and returns it after 30 seconds /datum/admin_help/proc/TimeoutVerb() - initiator.verbs -= /client/verb/adminhelp + remove_verb(initiator, /client/verb/adminhelp) initiator.adminhelptimerid = addtimer(CALLBACK(initiator, /client/proc/giveadminhelpverb), 300, TIMER_STOPPABLE) //30 seconds cooldown of admin helps //private @@ -492,7 +504,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) // /client/proc/giveadminhelpverb() - src.verbs |= /client/verb/adminhelp + add_verb(src, /client/verb/adminhelp) deltimer(adminhelptimerid) adminhelptimerid = 0 diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index 3a0b1e97..bb005a6b 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -205,15 +205,15 @@ GLOBAL_LIST_EMPTY(dirty_vars) set name = "Debug verbs - Enable" if(!check_rights(R_DEBUG)) return - verbs -= /client/proc/enable_debug_verbs - verbs.Add(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping) + remove_verb(src, /client/proc/enable_debug_verbs) + add_verb(src, list(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping)) SSblackbox.record_feedback("tally", "admin_verb", 1, "Enable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/disable_debug_verbs() set category = "Debug" set name = "Debug verbs - Disable" - verbs.Remove(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping) - verbs += /client/proc/enable_debug_verbs + remove_verb(src, list(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping)) + add_verb(src, /client/proc/enable_debug_verbs) SSblackbox.record_feedback("tally", "admin_verb", 1, "Disable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/count_objects_on_z_level() diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm index 445de4c4..ee4d1265 100644 --- a/code/modules/admin/verbs/possess.dm +++ b/code/modules/admin/verbs/possess.dm @@ -48,6 +48,6 @@ set desc = "Give this guy possess/release verbs" set category = "Debug" set name = "Give Possessing Verbs" - M.verbs += /proc/possess - M.verbs += /proc/release + add_verb(M, /proc/possess) + add_verb(M, /proc/release) SSblackbox.record_feedback("tally", "admin_verb", 1, "Give Possessing Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/antagonists/blob/blob/overmind.dm b/code/modules/antagonists/blob/blob/overmind.dm index 01882821..57ae1d4c 100644 --- a/code/modules/antagonists/blob/blob/overmind.dm +++ b/code/modules/antagonists/blob/blob/overmind.dm @@ -223,19 +223,16 @@ GLOBAL_LIST_EMPTY(blob_nodes) /mob/camera/blob/blob_act(obj/structure/blob/B) return -/mob/camera/blob/Stat() - ..() - if(statpanel("Status")) - if(blob_core) - stat(null, "Core Health: [blob_core.obj_integrity]") - stat(null, "Power Stored: [blob_points]/[max_blob_points]") - stat(null, "Blobs to Win: [blobs_legit.len]/[blobwincount]") - if(free_chem_rerolls) - stat(null, "You have [free_chem_rerolls] Free Chemical Reroll\s Remaining") - if(!placed) - if(manualplace_min_time) - stat(null, "Time Before Manual Placement: [max(round((manualplace_min_time - world.time)*0.1, 0.1), 0)]") - stat(null, "Time Before Automatic Placement: [max(round((autoplace_max_time - world.time)*0.1, 0.1), 0)]") +/mob/camera/blob/get_status_tab_items() + . = ..() + if(blob_core) + . += "Core Health: [blob_core.obj_integrity]" + . += "Power Stored: [blob_points]/[max_blob_points]" + . += "Blobs to Win: [blobs_legit.len]/[blobwincount]" + if(!placed) + if(manualplace_min_time) + . += "Time Before Manual Placement: [max(round((manualplace_min_time - world.time)*0.1, 0.1), 0)]" + . += "Time Before Automatic Placement: [max(round((autoplace_max_time - world.time)*0.1, 0.1), 0)]" /mob/camera/blob/Move(NewLoc, Dir = 0) if(placed) diff --git a/code/modules/antagonists/disease/disease_mob.dm b/code/modules/antagonists/disease/disease_mob.dm index e824c5c9..ff935f32 100644 --- a/code/modules/antagonists/disease/disease_mob.dm +++ b/code/modules/antagonists/disease/disease_mob.dm @@ -84,17 +84,16 @@ the new instance inside the host to be updated to the template's stats. to_chat(src, "You have [DisplayTimeText(freemove_end - world.time)] to select your first host. Click on a human to select your host.") -/mob/camera/disease/Stat() - ..() - if(statpanel("Status")) - if(freemove) - stat("Host Selection Time: [round((freemove_end - world.time)/10)]s") - else - stat("Adaptation Points: [points]/[total_points]") - stat("Hosts: [disease_instances.len]") - var/adapt_ready = next_adaptation_time - world.time - if(adapt_ready > 0) - stat("Adaptation Ready: [round(adapt_ready/10, 0.1)]s") +/mob/camera/disease/get_status_tab_items() + + if(freemove) + . += "Host Selection Time: [round((freemove_end - world.time)/10)]s" + else + . += "Adaptation Points: [points]/[total_points]" + . += "Hosts: [disease_instances.len]" + var/adapt_ready = next_adaptation_time - world.time + if(adapt_ready > 0) + . += "Adaptation Ready: [round(adapt_ready/10, 0.1)]s" /mob/camera/disease/examine(mob/user) diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm index f4418a62..2fa4952a 100644 --- a/code/modules/antagonists/revenant/revenant.dm +++ b/code/modules/antagonists/revenant/revenant.dm @@ -124,12 +124,12 @@ update_health_hud() ..() -/mob/living/simple_animal/revenant/Stat() - ..() - if(statpanel("Status")) - stat(null, "Current essence: [essence]/[essence_regen_cap]E") - stat(null, "Stolen essence: [essence_accumulated]E") - stat(null, "Stolen perfect souls: [perfectsouls]") + +/mob/living/simple_animal/revenant/get_status_tab_items() + . = ..() + . += "Current essence: [essence]/[essence_regen_cap]E" + . += "Stolen essence: [essence_accumulated]E" + . += "Stolen perfect souls: [perfectsouls]" /mob/living/simple_animal/revenant/update_health_hud() if(hud_used) diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm index 9f663fc5..02ddf315 100644 --- a/code/modules/antagonists/swarmer/swarmer.dm +++ b/code/modules/antagonists/swarmer/swarmer.dm @@ -107,7 +107,7 @@ /mob/living/simple_animal/hostile/swarmer/Initialize() . = ..() - verbs -= /mob/living/verb/pulled + remove_verb(src, /mob/living/verb/pulled) for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) diag_hud.add_to_hud(src) @@ -123,10 +123,9 @@ holder.pixel_y = I.Height() - world.icon_size holder.icon_state = "hudstat" -/mob/living/simple_animal/hostile/swarmer/Stat() - ..() - if(statpanel("Status")) - stat("Resources:",resources) +/mob/living/simple_animal/hostile/swarmer/get_status_tab_items() + . = ..() + . += "Resources: [resources]" /mob/living/simple_animal/hostile/swarmer/emp_act() . = ..() diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm index 505b9a1e..f13341fa 100644 --- a/code/modules/awaymissions/mission_code/wildwest.dm +++ b/code/modules/awaymissions/mission_code/wildwest.dm @@ -105,7 +105,7 @@ if("Immortality") to_chat(user, "Your wish is granted, but at a terrible cost...") to_chat(user, "The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart.") - user.verbs += /mob/living/carbon/proc/immortality + add_verb(user, /mob/living/carbon/proc/immortality) user.set_species(/datum/species/shadow) if("To Kill") to_chat(user, "Your wish is granted, but at a terrible cost...") diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 53170805..792e40ad 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -4,6 +4,10 @@ //BLACK MAGIC THINGS// ////////////////////// parent_type = /datum + + + /// hides the byond verb panel as we use our own custom version + show_verb_panel = FALSE //////////////// //ADMIN THINGS// //////////////// @@ -24,6 +28,12 @@ var/move_delay = 0 var/area = null + + + /// list of tabs containing spells and abilities + var/list/spell_tabs = list() + /// list of tabs containing verbs + var/list/verb_tabs = list() /////////////// //SOUND STUFF// /////////////// diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 23bfebb2..84856302 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -197,7 +197,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) debug_tools_allowed = TRUE //END CITADEL EDIT else if(GLOB.deadmins[ckey]) - verbs += /client/proc/readmin + add_verb(src, /client/proc/readmin) connecting_admin = TRUE if(CONFIG_GET(flag/autoadmin)) if(!GLOB.admin_datums[ckey]) @@ -243,7 +243,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) fps = 40 if(fexists(roundend_report_file())) - verbs += /client/proc/show_previous_roundend_report + add_verb(src, /client/proc/show_previous_roundend_report) var/full_version = "[byond_version].[byond_build ? byond_build : "xxx"]" log_access("Login: [key_name(src)] from [address ? address : "localhost"]-[computer_id] || BYOND v[full_version]") @@ -304,6 +304,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) set_macros() chatOutput.start() // Starts the chat + src << browse(file('html/statbrowser.html'), "window=statbrowser") //starts stats tab if(alert_mob_dupe_login) spawn() @@ -798,9 +799,9 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) /client/proc/add_verbs_from_config() if(CONFIG_GET(flag/see_own_notes)) - verbs += /client/proc/self_notes + add_verb(src, /client/proc/self_notes) if(CONFIG_GET(flag/use_exp_tracking)) - verbs += /client/proc/self_playtime + add_verb(src, /client/proc/self_playtime) #undef UPLOAD_LIMIT @@ -865,6 +866,24 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) y = CLAMP(y+change, min,max) change_view("[x]x[y]") +/// compiles a full list of verbs and sends it to the browser +/client/proc/init_verbs() + if(IsAdminAdvancedProcCall()) + return + var/list/verblist = list() + verb_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 + verb_tabs |= verb_to_init.category + verblist[++verblist.len] = list(verb_to_init.category, verb_to_init.name) + src << output("[url_encode(json_encode(verb_tabs))];[url_encode(json_encode(verblist))]", "statbrowser:init_verbs") + /client/proc/change_view(new_size) if (isnull(new_size)) CRASH("change_view called without argument.") diff --git a/code/modules/client/darkmode.dm b/code/modules/client/darkmode.dm index f806e5c9..ad8e5ef0 100644 --- a/code/modules/client/darkmode.dm +++ b/code/modules/client/darkmode.dm @@ -37,6 +37,7 @@ Thanks to spacemaniac and mcdonald for help with the JS side of this. winset(src, "say", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]") winset(src, "asset_cache_browser", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]") winset(src, "tooltip", "background-color = [COLOR_WHITEMODE_BACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]") + src << output(null, "statbrowser:set_light_theme") /client/proc/force_dark_theme() //Inversely, if theyre using white theme and want to swap to the superior dark theme, let's get WINSET() ing //Main windows @@ -62,4 +63,5 @@ Thanks to spacemaniac and mcdonald for help with the JS side of this. //Etc. winset(src, "say", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]") winset(src, "asset_cache_browser", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]") - winset(src, "tooltip", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]") \ No newline at end of file + winset(src, "tooltip", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]") + src << output(null, "statbrowser:set_dark_theme") \ No newline at end of file diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index 1465a0c9..087c434b 100644 --- a/code/modules/client/verbs/ooc.dm +++ b/code/modules/client/verbs/ooc.dm @@ -366,3 +366,10 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8") pct += delta winset(src, "mainwindow.split", "splitter=[pct]") + + +/client/verb/fix_stat_panel() + set name = "Fix Stat Panel" + set hidden = TRUE + + init_verbs() \ No newline at end of file diff --git a/code/modules/events/wizard/ghost.dm b/code/modules/events/wizard/ghost.dm index d5366c57..c288953e 100644 --- a/code/modules/events/wizard/ghost.dm +++ b/code/modules/events/wizard/ghost.dm @@ -21,6 +21,6 @@ /datum/round_event/wizard/possession/start() for(var/mob/dead/observer/G in GLOB.player_list) - G.verbs += /mob/dead/observer/verb/boo - G.verbs += /mob/dead/observer/verb/possess + add_verb(G, /mob/dead/observer/verb/boo) + add_verb(G, /mob/dead/observer/verb/possess) to_chat(G, "You suddenly feel a welling of new spooky powers...") diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index 0c50cb04..ad65bf8e 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -17,7 +17,7 @@ INITIALIZE_IMMEDIATE(/mob/dead) prepare_huds() if(length(CONFIG_GET(keyed_list/cross_server))) - verbs += /mob/dead/proc/server_hop + add_verb(src, /mob/dead/proc/server_hop) set_focus(src) return INITIALIZE_HINT_NORMAL @@ -42,27 +42,26 @@ INITIALIZE_IMMEDIATE(/mob/dead) loc = destination Moved(oldloc, NONE, TRUE) -/mob/dead/Stat() - ..() - if(!statpanel("Status")) - return - //stat(null, "Game Mode: [SSticker.hide_mode ? "Secret" : "[GLOB.master_mode]"]") +/mob/dead/get_status_tab_items() + . = ..() + . += "" + //. += "Game Mode: [SSticker.hide_mode ? "Secret" : "[GLOB.master_mode]"]" if(SSticker.HasRoundStarted()) return var/time_remaining = SSticker.GetTimeLeft() if(time_remaining > 0) - stat(null, "Time To Start: [round(time_remaining/10)]s") + . += "Time To Start: [round(time_remaining/10)]s" else if(time_remaining == -10) - stat(null, "Time To Start: DELAYED") + . += "Time To Start: DELAYED" else - stat(null, "Time To Start: SOON") + . += "Time To Start: SOON" - stat(null, "Players: [SSticker.totalPlayers]") + . += "Players: [SSticker.totalPlayers]" if(client.holder) - stat(null, "Players Ready: [SSticker.totalPlayersReady]") + . += "Players Ready: [SSticker.totalPlayersReady]" /mob/dead/proc/server_hop() set category = "OOC" @@ -74,7 +73,7 @@ INITIALIZE_IMMEDIATE(/mob/dead) var/pick switch(csa.len) if(0) - verbs -= /mob/dead/proc/server_hop + remove_verb(src, /mob/dead/proc/server_hop) to_chat(src, "Server Hop has been disabled.") if(1) pick = csa[0] diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index ca660860..59347e77 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -303,6 +303,7 @@ if(observer.client && observer.client.prefs) observer.real_name = observer.client.prefs.real_name observer.name = observer.real_name + observer.client.init_verbs() observer.update_icon() observer.stop_sound_channel(CHANNEL_LOBBYMUSIC) QDEL_NULL(mind) @@ -397,6 +398,7 @@ character.update_parallax_teleport() SSticker.minds += character.mind + character.client.init_verbs() // init verbs for the late join var/mob/living/carbon/human/humanc if(ishuman(character)) @@ -590,6 +592,7 @@ mind.transfer_to(H) //won't transfer key since the mind is not active H.name = real_name + client.init_verbs() //h13 assign your characters custom height. if (H.custom_body_size) //Do they have it set? H.resize(H.custom_body_size * 0.01) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 541fb5e1..7548d194 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -59,10 +59,10 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) /mob/dead/observer/Initialize() set_invisibility(GLOB.observer_default_invisibility) - verbs += list( + add_verb(src, list( /mob/dead/observer/proc/dead_tele, /mob/dead/observer/proc/open_spawners_menu, - /mob/dead/observer/proc/view_gas) + /mob/dead/observer/proc/view_gas)) if(icon_state in GLOB.ghost_forms_with_directions_list) ghostimage_default = image(src.icon,src,src.icon_state + "_nodir") @@ -120,8 +120,8 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) real_name = name if(!fun_verbs) - verbs -= /mob/dead/observer/verb/boo - verbs -= /mob/dead/observer/verb/possess + remove_verb(src, /mob/dead/observer/verb/boo) + remove_verb(src, /mob/dead/observer/verb/possess) animate(src, pixel_y = 2, time = 10, loop = -1) @@ -270,6 +270,7 @@ Works together with spawning an observer, noted above. var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc. SStgui.on_transfer(src, ghost) // Transfer NanoUIs. ghost.can_reenter_corpse = can_reenter_corpse + ghost.client.init_verbs() if (client && client.prefs && client.prefs.auto_ooc) if (!(client.prefs.chat_toggles & CHAT_OOC)) client.prefs.chat_toggles ^= CHAT_OOC @@ -367,6 +368,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp client.change_view(CONFIG_GET(string/default_view)) SStgui.on_transfer(src, mind.current) // Transfer NanoUIs. mind.current.key = key + mind.current.client.init_verbs() return 1 /mob/dead/observer/proc/notify_cloning(var/message, var/sound, var/atom/source, flashwindow = TRUE) @@ -777,11 +779,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp ghostimage_simple.icon_state = icon_state if("fun_verbs") if(fun_verbs) - verbs += /mob/dead/observer/verb/boo - verbs += /mob/dead/observer/verb/possess + add_verb(src, /mob/dead/observer/verb/boo) + add_verb(src, /mob/dead/observer/verb/possess) else - verbs -= /mob/dead/observer/verb/boo - verbs -= /mob/dead/observer/verb/possess + remove_verb(src, /mob/dead/observer/verb/boo) + remove_verb(src, /mob/dead/observer/verb/possess) /mob/dead/observer/reset_perspective(atom/A) if(client) diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index bd24a4b4..c9a504e2 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -26,8 +26,8 @@ var/static/regex/alien_name_regex = new("alien (larva|sentinel|drone|hunter|praetorian|queen)( \\(\\d+\\))?") /mob/living/carbon/alien/Initialize() - verbs += /mob/living/proc/mob_sleep - verbs += /mob/living/proc/lay_down + add_verb(src, /mob/living/proc/mob_sleep) + add_verb(src, /mob/living/proc/lay_down) create_bodyparts() //initialize bodyparts @@ -86,11 +86,10 @@ /mob/living/carbon/alien/IsAdvancedToolUser() return has_fine_manipulation -/mob/living/carbon/alien/Stat() - ..() - if(statpanel("Status")) - stat(null, "Intent: [a_intent]") +/mob/living/carbon/alien/get_status_tab_items() + . = ..() + . += "Intent: [a_intent]" /mob/living/carbon/alien/getTrail() if(getBruteLoss() < 200) diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index 323bd408..509caf81 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -143,10 +143,10 @@ Doesn't work on other aliens/AI.*/ action_icon_state = "alien_acid" /obj/effect/proc_holder/alien/acid/on_gain(mob/living/carbon/user) - user.verbs.Add(/mob/living/carbon/proc/corrosive_acid) + add_verb(user, /mob/living/carbon/proc/corrosive_acid) /obj/effect/proc_holder/alien/acid/on_lose(mob/living/carbon/user) - user.verbs.Remove(/mob/living/carbon/proc/corrosive_acid) + remove_verb(user, /mob/living/carbon/proc/corrosive_acid) /obj/effect/proc_holder/alien/acid/proc/corrode(atom/target,mob/living/carbon/user = usr) if(target in oview(1,user)) diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 3b150a22..9fdf7ab8 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -29,11 +29,9 @@ internal_organs += new /obj/item/organ/alien/plasmavessel/small/tiny ..() -//This needs to be fixed -/mob/living/carbon/alien/larva/Stat() - ..() - if(statpanel("Status")) - stat(null, "Progress: [amount_grown]/[max_grown]") +/mob/living/carbon/alien/larva/get_status_tab_items() + . = ..() + . += "Progress: [amount_grown]/[max_grown]" /mob/living/carbon/alien/larva/adjustPlasma(amount) if(stat != DEAD && amount > 0) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 33214a0f..38d9b377 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -465,16 +465,18 @@ var/turf/target = get_turf(loc) I.safe_throw_at(target,I.throw_range,I.throw_speed,src, force = move_force) -/mob/living/carbon/Stat() - ..() - if(statpanel("Status")) - var/obj/item/organ/alien/plasmavessel/vessel = getorgan(/obj/item/organ/alien/plasmavessel) - if(vessel) - stat(null, "Plasma Stored: [vessel.storedPlasma]/[vessel.max_plasma]") - if(locate(/obj/item/assembly/health) in src) - stat(null, "Health: [health]") - add_abilities_to_panel() +/mob/living/carbon/get_status_tab_items() + . = ..() + var/obj/item/organ/alien/plasmavessel/vessel = getorgan(/obj/item/organ/alien/plasmavessel) + if(vessel) + . += "Plasma Stored: [vessel.storedPlasma]/[vessel.max_plasma]" + if(locate(/obj/item/assembly/health) in src) + . += "Health: [health]" + +/mob/living/carbon/get_proc_holders() + . = ..() + . += add_abilities_to_panel() /mob/living/carbon/attack_ui(slot) if(!has_hand_for_held_index(active_hand_index)) @@ -995,4 +997,4 @@ /mob/living/carbon/transfer_ckey(mob/new_mob, send_signal = TRUE) if(combatmode) toggle_combat_mode(TRUE, TRUE) - return ..() + return ..() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 343cf07c..58264160 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -6,9 +6,8 @@ appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE|LONG_GLIDE /mob/living/carbon/human/Initialize() - verbs += /mob/living/proc/mob_sleep - verbs += /mob/living/proc/lay_down - verbs += /mob/living/carbon/human/proc/underwear_toggle //fwee + add_verb(src, /mob/living/proc/mob_sleep) + add_verb(src, /mob/living/proc/lay_down) time_initialized = world.time //initialize limbs first @@ -62,70 +61,52 @@ add_to_all_human_data_huds() -/mob/living/carbon/human/Stat() - ..() - //Same thing from mob - if(statpanel("Status")) - if(tickrefresh == 1) - sList2 = list() - sList2 += "Intent: [a_intent]" - sList2 += "Move Mode: [m_intent]" - if (internal) - if (!internal.air_contents) - qdel(internal) - else - sList2 += "Internal Atmosphere Info: "+ "[internal.name]" - sList2 += "Tank Pressure: "+ "[internal.air_contents.return_pressure()]" - sList2 += "Distribution Pressure: "+ "[internal.distribute_pressure]" - if(mind) - var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling) - if(changeling) - sList2 += "Chemical Storage: " + "[changeling.chem_charges]/[changeling.chem_storage]" - sList2 += "Absorbed DNA: "+ "[changeling.absorbedcount]" - var/datum/antagonist/nightmare/nightmare = mind.has_antag_datum(/datum/antagonist/nightmare) - if(nightmare) - for(var/datum/objective/O in mind.objectives) - if(istype(O, /datum/objective/break_lights)) - var/datum/objective/break_lights/BL = O - if(BL.mode) //Keeping lights out of areas - var/T = "Target Area(s): " - for(var/area/I in BL.area_targets) - T += "[initial(I.name)], " - sList2 += T - else //Break number of lights - sList2 += "Lights Broken: " + "[BL.lightsbroken]/[BL.target_amount]" - if (sList2 != null) - stat(null, "[sList2.Join("\n\n")]") +/mob/living/carbon/human/get_status_tab_items() + . = ..() + . += "Intent: [a_intent]" + . += "Move Mode: [m_intent]" + if (internal) + if (!internal.air_contents) + qdel(internal) + else + . += "" + . += "Internal Atmosphere Info: [internal.name]" + . += "Tank Pressure: [internal.air_contents.return_pressure()]" + . += "Distribution Pressure: [internal.distribute_pressure]" + if(mind) + var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling) + if(changeling) + . += "" + . += "Chemical Storage: [changeling.chem_charges]/[changeling.chem_storage]" + . += "Absorbed DNA: [changeling.absorbedcount]" //NINJACODE if(istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)) //Only display if actually a ninja. var/obj/item/clothing/suit/space/space_ninja/SN = wear_suit - if(statpanel("SpiderOS")) - stat("SpiderOS Status:","[SN.s_initialized ? "Initialized" : "Disabled"]") - stat("Current Time:", "[STATION_TIME_TIMESTAMP("hh:mm:ss")]") - if(SN.s_initialized) - //Suit gear - stat("Energy Charge:", "[round(SN.cell.charge/100)]%") - stat("Smoke Bombs:", "\Roman [SN.s_bombs]") - //Ninja status - stat("Fingerprints:", "[md5(dna.uni_identity)]") - stat("Unique Identity:", "[dna.unique_enzymes]") - stat("Overall Status:", "[stat > 1 ? "dead" : "[health]% healthy"]") - stat("Nutrition Status:", "[nutrition]") - stat("Hydration Status:", "[thirst]") - stat("Oxygen Loss:", "[getOxyLoss()]") - stat("Toxin Levels:", "[getToxLoss()]") - stat("Burn Severity:", "[getFireLoss()]") - stat("Brute Trauma:", "[getBruteLoss()]") - stat("Radiation Levels:","[radiation] rad") - stat("Body Temperature:","[bodytemperature-T0C] degrees C ([bodytemperature*1.8-459.67] degrees F)") + . += "SpiderOS Status: [SN.s_initialized ? "Initialized" : "Disabled"]" + . += "Current Time: [station_time_timestamp()]" + if(SN.s_initialized) + //Suit gear + . += "Energy Charge: [round(SN.cell.charge/100)]%" + . += "Smoke Bombs: \Roman [SN.s_bombs]" + //Ninja status + . += "Fingerprints: [md5(dna.uni_identity)]" + . += "Unique Identity: [dna.unique_enzymes]" + . += "Overall Status: [stat > 1 ? "dead" : "[health]% healthy"]" + . += "Nutrition Status: [nutrition]" + . += "Oxygen Loss: [getOxyLoss()]" + . += "Toxin Levels: [getToxLoss()]" + . += "Burn Severity: [getFireLoss()]" + . += "Brute Trauma: [getBruteLoss()]" + . += "Radiation Levels: [radiation] rad" + . += "Body Temperature: [bodytemperature-T0C] degrees C ([bodytemperature*1.8-459.67] degrees F)" - //Diseases - if(diseases.len) - stat("Viruses:", null) - for(var/thing in diseases) - var/datum/disease/D = thing - stat("*", "[D.name], Type: [D.spread_text], Stage: [D.stage]/[D.max_stages], Possible Cure: [D.cure_text]") + //Diseases + if(length(diseases)) + . += "Viruses:" + for(var/thing in diseases) + var/datum/disease/D = thing + . += "* [D.name], Type: [D.spread_text], Stage: [D.stage]/[D.max_stages], Possible Cure: [D.cure_text]" /mob/living/carbon/human/show_inv(mob/user) diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index a287c569..7aa89392 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -17,8 +17,8 @@ hud_type = /datum/hud/monkey /mob/living/carbon/monkey/Initialize(mapload, cubespawned=FALSE, mob/spawner) - verbs += /mob/living/proc/mob_sleep - verbs += /mob/living/proc/lay_down + add_verb(src, /mob/living/proc/mob_sleep) + add_verb(src, /mob/living/proc/lay_down) if(unique_name) //used to exclude pun pun gender = pick(MALE, FEMALE) @@ -89,16 +89,16 @@ return add_movespeed_modifier(MOVESPEED_ID_MONKEY_TEMPERATURE_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount) -/mob/living/carbon/monkey/Stat() - ..() - if(statpanel("Status")) - stat(null, "Intent: [a_intent]") - stat(null, "Move Mode: [m_intent]") - if(client && mind) - var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling) - if(changeling) - stat("Chemical Storage", "[changeling.chem_charges]/[changeling.chem_storage]") - stat("Absorbed DNA", changeling.absorbedcount) +/mob/living/carbon/monkey/get_status_tab_items() + . = ..() + . += "Intent: [a_intent]" + . += "Move Mode: [m_intent]" + if(client && mind) + var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling) + if(changeling) + . += "" + . += "Chemical Storage: [changeling.chem_charges]/[changeling.chem_storage]" + . += "Absorbed DNA: [changeling.absorbedcount]" return diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 9832e3b2..80420051 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1104,8 +1104,10 @@ A.action.Remove(src) /mob/living/proc/add_abilities_to_panel() + var/list/L = list() for(var/obj/effect/proc_holder/A in abilities) - statpanel("[A.panel]",A.get_panel_text(),A) + L[++L.len] = list("[A.panel]",A.get_panel_text(),A.name,"[REF(A)]") + return L /mob/living/lingcheck() if(mind) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index efc714f2..04d241d2 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -137,7 +137,7 @@ spark_system.set_up(5, 0, src) spark_system.attach(src) - verbs += /mob/living/silicon/ai/proc/show_laws_verb + add_verb(src, /mob/living/silicon/ai/proc/show_laws_verb) aiPDA = new/obj/item/pda/ai(src) aiPDA.owner = name @@ -151,10 +151,10 @@ deploy_action.Grant(src) if(isturf(loc)) - verbs.Add(/mob/living/silicon/ai/proc/ai_network_change, \ + add_verb(src, list(/mob/living/silicon/ai/proc/ai_network_change, \ /mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \ /mob/living/silicon/ai/proc/botcall, /mob/living/silicon/ai/proc/control_integrated_radio, \ - /mob/living/silicon/ai/proc/set_automatic_say_channel) + /mob/living/silicon/ai/proc/set_automatic_say_channel)) GLOB.ai_list += src GLOB.shuttle_caller_list += src @@ -205,26 +205,26 @@ display_icon_override = ai_core_icon set_core_display_icon(ai_core_icon) -/mob/living/silicon/ai/Stat() - ..() - if(statpanel("Status")) - if(!stat) - stat(null, text("System integrity: [(health+100)/2]%")) - stat(null, text("Connected cyborgs: [connected_robots.len]")) - for(var/mob/living/silicon/robot/R in connected_robots) - var/robot_status = "Nominal" - if(R.shell) - robot_status = "AI SHELL" - else if(R.stat || !R.client) - robot_status = "OFFLINE" - else if(!R.cell || R.cell.charge <= 0) - robot_status = "DEPOWERED" - //Name, Health, Battery, Module, Area, and Status! Everything an AI wants to know about its borgies! - stat(null, text("[R.name] | S.Integrity: [R.health]% | Cell: [R.cell ? "[R.cell.charge]/[R.cell.maxcharge]" : "Empty"] | \ - Module: [R.designation] | Loc: [get_area_name(R, TRUE)] | Status: [robot_status]")) - stat(null, text("AI shell beacons detected: [LAZYLEN(GLOB.available_ai_shells)]")) //Count of total AI shells - else - stat(null, text("Systems nonfunctional")) +/mob/living/silicon/ai/get_status_tab_items() + . = ..() + if(stat != CONSCIOUS) + . += text("Systems nonfunctional") + return + . += text("System integrity: [(health + 100) * 0.5]%") + . += text("Connected cyborgs: [length(connected_robots)]") + for(var/r in connected_robots) + var/mob/living/silicon/robot/connected_robot = r + var/robot_status = "Nominal" + if(connected_robot.shell) + robot_status = "AI SHELL" + else if(connected_robot.stat != CONSCIOUS || !connected_robot.client) + robot_status = "OFFLINE" + else if(!connected_robot.cell || connected_robot.cell.charge <= 0) + robot_status = "DEPOWERED" + //Name, Health, Battery, Module, Area, and Status! Everything an AI wants to know about its borgies! + . += text("[connected_robot.name] | S.Integrity: [connected_robot.health]% | Cell: [connected_robot.cell ? "[connected_robot.cell.charge]/[connected_robot.cell.maxcharge]" : "Empty"] | \ + Module: [connected_robot.designation] | Loc: [get_area_name(connected_robot, TRUE)] | Status: [robot_status]") + . += text("AI shell beacons detected: [LAZYLEN(GLOB.available_ai_shells)]") //Count of total AI shells /mob/living/silicon/ai/proc/ai_alerts() var/dat = "Current Station Alerts\n" diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index f4859ab2..05b0fc5e 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -172,13 +172,12 @@ else client.eye = card -/mob/living/silicon/pai/Stat() - ..() - if(statpanel("Status")) - if(!stat) - stat(null, text("Emitter Integrity: [emitterhealth * (100/emittermaxhealth)]")) - else - stat(null, text("Systems nonfunctional")) +/mob/living/silicon/pai/get_status_tab_items() + . += ..() + if(!stat) + . += text("Emitter Integrity: [emitterhealth * (100/emittermaxhealth)]") + else + . += text("Systems nonfunctional") /mob/living/silicon/pai/restrained(ignore_grab) . = FALSE diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 8d8444a6..51eed8ff 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -321,19 +321,20 @@ if(thruster_button) thruster_button.icon_state = "ionpulse[ionpulse_on]" -/mob/living/silicon/robot/Stat() - ..() - if(statpanel("Status")) - if(cell) - stat("Charge Left:", "[cell.charge]/[cell.maxcharge]") - else - stat(null, text("No Cell Inserted!")) - if(module) - for(var/datum/robot_energy_storage/st in module.storages) - stat("[st.name]:", "[st.energy]/[st.max_energy]") - if(connected_ai) - stat("Master AI:", connected_ai.name) +/mob/living/silicon/robot/get_status_tab_items() + . = ..() + . += "" + if(cell) + . += "Charge Left: [cell.charge]/[cell.maxcharge]" + else + . += text("No Cell Inserted!") + + if(module) + for(var/datum/robot_energy_storage/st in module.storages) + . += "[st.name]: [st.energy]/[st.max_energy]" + if(connected_ai) + . += "Master AI: [connected_ai.name]" /mob/living/silicon/robot/restrained(ignore_grab) . = 0 diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 2380db56..c204508a 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -38,7 +38,7 @@ /mob/living/simple_animal/pet/cat/Initialize() . = ..() - verbs += /mob/living/proc/lay_down + add_verb(src, /mob/living/proc/lay_down) /mob/living/simple_animal/pet/cat/ComponentInitialize() . = ..() diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index 903c3ea3..50fbc9d1 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -154,18 +154,17 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians REMOVE_TRAIT(summoner, TRAIT_NODEATH, "memento_mori") to_chat(summoner,"You feel incredibly vulnerable as the memento mori pulls your life force in one too many directions!") -/mob/living/simple_animal/hostile/guardian/Stat() - ..() - if(statpanel("Status")) - if(summoner) - var/resulthealth - if(iscarbon(summoner)) - resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - summoner.health) / abs(HEALTH_THRESHOLD_DEAD - summoner.maxHealth)) * 100) - else - resulthealth = round((summoner.health / summoner.maxHealth) * 100, 0.5) - stat(null, "Summoner Health: [resulthealth]%") - if(cooldown >= world.time) - stat(null, "Manifest/Recall Cooldown Remaining: [DisplayTimeText(cooldown - world.time)]") +/mob/living/simple_animal/hostile/guardian/get_status_tab_items() + . += ..() + if(summoner) + var/resulthealth + if(iscarbon(summoner)) + resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - summoner.health) / abs(HEALTH_THRESHOLD_DEAD - summoner.maxHealth)) * 100) + else + resulthealth = round((summoner.health / summoner.maxHealth) * 100, 0.5) + . += "Summoner Health: [resulthealth]%" + if(cooldown >= world.time) + . += "Manifest/Recall Cooldown Remaining: [DisplayTimeText(cooldown - world.time)]" /mob/living/simple_animal/hostile/guardian/Move() //Returns to summoner if they move out of range . = ..() @@ -441,13 +440,13 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians to_chat(src, "[G.real_name] has been summoned!") guardians -= G if(!guardians.len) - verbs -= /mob/living/proc/guardian_reset + remove_verb(src, /mob/living/proc/guardian_reset) else to_chat(src, "There were no ghosts willing to take control of [G.real_name]. Looks like you're stuck with it for now.") else to_chat(src, "You decide not to reset [guardians.len > 1 ? "any of your guardians":"your guardian"].") else - verbs -= /mob/living/proc/guardian_reset + remove_verb(src, /mob/living/proc/guardian_reset) ////////parasite tracking/finding procs @@ -571,9 +570,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians if("carp") to_chat(user, "[G.carp_fluff_string]") to_chat(user, "[G.real_name] has been caught!") - user.verbs += /mob/living/proc/guardian_comm - user.verbs += /mob/living/proc/guardian_recall - user.verbs += /mob/living/proc/guardian_reset + add_verb(user, list(/mob/living/proc/guardian_comm, \ + /mob/living/proc/guardian_recall, \ + /mob/living/proc/guardian_reset)) /obj/item/guardiancreator/choose random = FALSE diff --git a/code/modules/mob/living/simple_animal/guardian/types/assassin.dm b/code/modules/mob/living/simple_animal/guardian/types/assassin.dm index e507a4c8..1b4758b9 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/assassin.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/assassin.dm @@ -24,11 +24,10 @@ if(loc == summoner && toggle) ToggleMode(0) -/mob/living/simple_animal/hostile/guardian/assassin/Stat() - ..() - if(statpanel("Status")) - if(stealthcooldown >= world.time) - stat(null, "Stealth Cooldown Remaining: [DisplayTimeText(stealthcooldown - world.time)]") +/mob/living/simple_animal/hostile/guardian/assassin/get_status_tab_items() + . = ..() + if(stealthcooldown >= world.time) + . += "Stealth Cooldown Remaining: [DisplayTimeText(stealthcooldown - world.time)]" /mob/living/simple_animal/hostile/guardian/assassin/AttackingTarget() . = ..() diff --git a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm index e9f76737..a480ce0f 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm @@ -7,11 +7,10 @@ carp_fluff_string = "CARP CARP CARP! Caught one! It's an explosive carp! Boom goes the fishy." var/bomb_cooldown = 0 -/mob/living/simple_animal/hostile/guardian/bomb/Stat() - ..() - if(statpanel("Status")) - if(bomb_cooldown >= world.time) - stat(null, "Bomb Cooldown Remaining: [DisplayTimeText(bomb_cooldown - world.time)]") +/mob/living/simple_animal/hostile/guardian/bomb/get_status_tab_items() + . = ..() + if(bomb_cooldown >= world.time) + . += "Bomb Cooldown Remaining: [DisplayTimeText(bomb_cooldown - world.time)]" /mob/living/simple_animal/hostile/guardian/bomb/AttackingTarget() . = ..() diff --git a/code/modules/mob/living/simple_animal/guardian/types/support.dm b/code/modules/mob/living/simple_animal/guardian/types/support.dm index 2b1b330d..78ad55be 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/support.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/support.dm @@ -17,11 +17,11 @@ var/datum/atom_hud/medsensor = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] medsensor.add_hud_to(src) -/mob/living/simple_animal/hostile/guardian/healer/Stat() - ..() - if(statpanel("Status")) - if(beacon_cooldown >= world.time) - stat(null, "Beacon Cooldown Remaining: [DisplayTimeText(beacon_cooldown - world.time)]") + +/mob/living/simple_animal/hostile/guardian/healer/get_status_tab_items() + . = ..() + if(beacon_cooldown >= world.time) + . += "Beacon Cooldown Remaining: [DisplayTimeText(beacon_cooldown - world.time)]" /mob/living/simple_animal/hostile/guardian/healer/AttackingTarget() . = ..() diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm index deb88d67..9634c7fe 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm @@ -128,7 +128,7 @@ /mob/living/simple_animal/hostile/jungle/leaper/Initialize() . = ..() - verbs -= /mob/living/verb/pulled + remove_verb(src, /mob/living/verb/pulled) /mob/living/simple_animal/hostile/jungle/leaper/CtrlClickOn(atom/A) face_atom(A) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 0308443d..573a9ef8 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -638,8 +638,8 @@ Difficulty: Very Hard /mob/living/simple_animal/hostile/lightgeist/Initialize() . = ..() - verbs -= /mob/living/verb/pulled - verbs -= /mob/verb/me_verb + remove_verb(src, /mob/living/verb/pulled) + remove_verb(src, /mob/verb/me_verb) var/datum/atom_hud/medsensor = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] medsensor.add_hud_to(src) @@ -728,7 +728,7 @@ Difficulty: Very Hard L.mind.transfer_to(holder_animal) var/obj/effect/proc_holder/spell/targeted/exit_possession/P = new /obj/effect/proc_holder/spell/targeted/exit_possession holder_animal.mind.AddSpell(P) - holder_animal.verbs -= /mob/living/verb/pulled + remove_verb(holder_animal, /mob/living/verb/pulled) /obj/structure/closet/stasis/dump_contents(var/kill = 1) STOP_PROCESSING(SSobj, src) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index acf695a7..286831aa 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -110,12 +110,12 @@ parrot_sleep_dur = parrot_sleep_max //In case someone decides to change the max without changing the duration var - verbs.Add(/mob/living/simple_animal/parrot/proc/steal_from_ground, \ + add_verb(src, list(/mob/living/simple_animal/parrot/proc/steal_from_ground, \ /mob/living/simple_animal/parrot/proc/steal_from_mob, \ /mob/living/simple_animal/parrot/verb/drop_held_item_player, \ /mob/living/simple_animal/parrot/proc/perch_player, \ /mob/living/simple_animal/parrot/proc/toggle_mode, - /mob/living/simple_animal/parrot/proc/perch_mob_player) + /mob/living/simple_animal/parrot/proc/perch_mob_player)) /mob/living/simple_animal/parrot/examine(mob/user) @@ -137,11 +137,12 @@ ..(gibbed) -/mob/living/simple_animal/parrot/Stat() - ..() - if(statpanel("Status")) - stat("Held Item", held_item) - stat("Mode",a_intent) + +/mob/living/simple_animal/parrot/get_status_tab_items() + . = ..() + . += "" + . += "Held Item: [held_item]" + . += "Mode: [a_intent]" /mob/living/simple_animal/parrot/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, message_mode, atom/movable/source) . = ..() diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index f8e799e5..e482f72a 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -5,7 +5,7 @@ maxHealth = 20 gender = PLURAL //placeholder blood_volume = 550 //How much blud it has for bloodsucking - + status_flags = CANPUSH var/icon_living = "" @@ -294,11 +294,11 @@ remove_movespeed_modifier(MOVESPEED_ID_SIMPLEMOB_VARSPEED, TRUE) add_movespeed_modifier(MOVESPEED_ID_SIMPLEMOB_VARSPEED, TRUE, 100, multiplicative_slowdown = speed, override = TRUE) -/mob/living/simple_animal/Stat() - ..() - if(statpanel("Status")) - stat(null, "Health: [round((health / maxHealth) * 100)]%") - return 1 + +/mob/living/simple_animal/get_status_tab_items() + . = ..() + . += "" + . += "Health: [round((health / maxHealth) * 100)]%" /mob/living/simple_animal/proc/drop_loot() if(loot.len) diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 67b3cb53..593ea1fa 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -197,21 +197,21 @@ /mob/living/simple_animal/slime/Process_Spacemove(movement_dir = 0) return 2 -/mob/living/simple_animal/slime/Stat() +/mob/living/simple_animal/slime/get_status_tab_items() if(..()) if(!docile) - stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]") + . += "Nutrition: [nutrition]/[get_max_nutrition()]" if(amount_grown >= SLIME_EVOLUTION_THRESHOLD) if(is_adult) - stat(null, "You can reproduce!") + . += "You can reproduce!" else - stat(null, "You can evolve!") + . += "You can evolve!" if(stat == UNCONSCIOUS) - stat(null,"You are knocked out by high levels of BZ!") + . += "You are knocked out by high levels of BZ!" else - stat(null,"Power Level: [powerlevel]") + . += "Power Level: [powerlevel]" /mob/living/simple_animal/slime/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 4f1afd3d..98209303 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -572,7 +572,7 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA /mob/proc/is_muzzled() return 0 - +/* /mob/Stat() ..() //This is where I try and add a temporary solution to the issue of the status tab. This solution is bad and I should feel bad, but it should mitigate some of the client lag. @@ -646,25 +646,31 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA if(A.IsObscured()) continue statpanel(listed_turf.name, null, A) +*/ +/// Adds this list to the output to the stat browser +/mob/proc/get_status_tab_items() + . = list() +/// Gets all relevant proc holders for the browser statpenl +/mob/proc/get_proc_holders() + . = list() if(mind) - add_spells_to_statpanel(mind.spell_list) - var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling) - if(changeling) - add_stings_to_statpanel(changeling.purchasedpowers) - add_spells_to_statpanel(mob_spell_list) + . += get_spells_for_statpanel(mind.spell_list) + . += get_spells_for_statpanel(mob_spell_list) -/mob/proc/add_spells_to_statpanel(list/spells) +/mob/proc/get_spells_for_statpanel(list/spells) + var/list/L = list() for(var/obj/effect/proc_holder/spell/S in spells) if(S.can_be_cast_by(src)) switch(S.charge_type) if("recharge") - statpanel("[S.panel]","[S.charge_counter/10.0]/[S.charge_max/10]",S) + L[++L.len] = list("[S.panel]", "[S.charge_counter/10.0]/[S.charge_max/10]", S.name, REF(S)) if("charges") - statpanel("[S.panel]","[S.charge_counter]/[S.charge_max]",S) + L[++L.len] = list("[S.panel]", "[S.charge_counter]/[S.charge_max]", S.name, REF(S)) if("holdervar") - statpanel("[S.panel]","[S.holder_var_type] [S.holder_var_amount]",S) + L[++L.len] = list("[S.panel]", "[S.holder_var_type] [S.holder_var_amount]", S.name, REF(S)) + return L /mob/proc/add_stings_to_statpanel(list/stings) for(var/obj/effect/proc_holder/changeling/S in stings) @@ -794,6 +800,8 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA if(istype(S, spell)) mob_spell_list -= S qdel(S) + if(client) + client << output(null, "statbrowser:check_spells") /mob/proc/anti_magic_check(magic = TRUE, holy = FALSE) if(!magic && !holy) diff --git a/html/statbrowser.html b/html/statbrowser.html new file mode 100644 index 00000000..bca72f91 --- /dev/null +++ b/html/statbrowser.html @@ -0,0 +1,896 @@ + + + +Stat Browser + + + + + + + +
+ + + diff --git a/modular_citadel/interface/skin.dmf b/modular_citadel/interface/skin.dmf index dc2da9a2..ed242d4a 100644 --- a/modular_citadel/interface/skin.dmf +++ b/modular_citadel/interface/skin.dmf @@ -110,9 +110,8 @@ window "mapwindow" font-size = 7 is-default = true saved-params = "icon-size" - zoom-mode = distort + saved-params = "zoom;letterbox;zoom-mode" style = ".center { text-align: center; } .maptext { font-family: 'Small Fonts'; font-size: 7px; -dm-text-outline: 1px black; color: white; line-height: 1.1; } .command_headset { font-weight: bold;\tfont-size: 8px; } .small { font-size: 6px; } .big { font-size: 8px; } .reallybig { font-size: 8px; } .extremelybig { font-size: 8px; } .greentext { color: #00FF00; font-size: 7px; } .redtext { color: #FF0000; font-size: 7px; } .clown { color: #FF69Bf; font-size: 7px; font-weight: bold; } .his_grace { color: #15D512; } .hypnophrase { color: #0d0d0d; font-weight: bold; } .yell { font-weight: bold; } .italics { font-size: 6px; }" - window "infowindow" elem "infowindow" type = MAIN @@ -264,15 +263,15 @@ window "outputwindow" window "statwindow" elem "statwindow" type = MAIN - pos = 281,0 + pos = 372,0 size = 640x480 anchor1 = none anchor2 = none background-color = #242424 saved-params = "pos;size;is-minimized;is-maximized" is-pane = true - elem "stat" - type = INFO + elem "statbrowser" + type = BROWSER pos = 0,0 size = 640x480 anchor1 = 0,0 @@ -285,7 +284,18 @@ window "statwindow" tab-background-color = #242424 prefix-color = #e0e0e0 suffix-color = #e0e0e0 - + is-visible = false + on-tab = ".output statbrowser:tab_change [[*]]" + elem "statbrowser" + type = BROWSER + pos = 6,44 + size = 628x430 + anchor1 = 0,0 + anchor2 = 100,100 + background-color = none + saved-params = "" + is-visible = false + window "preferences_window" elem "preferences_window" type = MAIN diff --git a/tgstation.dme b/tgstation.dme index 9562ec48..7352bfc8 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -79,6 +79,7 @@ #include "code\__DEFINES\pipe_construction.dm" #include "code\__DEFINES\pool.dm" #include "code\__DEFINES\preferences.dm" +#include "code\__DEFINES\procpath.dm" #include "code\__DEFINES\profile.dm" #include "code\__DEFINES\qdel.dm" #include "code\__DEFINES\radiation.dm" @@ -151,6 +152,7 @@ #include "code\__HELPERS\type2type_vr.dm" #include "code\__HELPERS\typelists.dm" #include "code\__HELPERS\unsorted.dm" +#include "code\__HELPERS\verbs.dm" #include "code\__HELPERS\view.dm" #include "code\__HELPERS\sorts\__main.dm" #include "code\__HELPERS\sorts\InsertSort.dm" @@ -275,6 +277,7 @@ #include "code\controllers\subsystem\server_maint.dm" #include "code\controllers\subsystem\shuttle.dm" #include "code\controllers\subsystem\spacedrift.dm" +#include "code\controllers\subsystem\statpanel.dm" #include "code\controllers\subsystem\stickyban.dm" #include "code\controllers\subsystem\sun.dm" #include "code\controllers\subsystem\tgui.dm"