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

The dormant husk of [src] bursts open, revealing a new, intact copy in the pool of viscera.

") //Bloody hell... /mob/living/carbon/human/proc/chimera_hatch() - verbs -= /mob/living/carbon/human/proc/hatch + remove_verb(src, /mob/living/carbon/human/proc/hatch) to_chat(src, "Your new body awakens, bursting free from your old skin.") //Modify and record values (half nutrition and braindamage) diff --git a/code/modules/species/xenomorphs/alien_powers.dm b/code/modules/species/xenomorphs/alien_powers.dm index 0e1d5b2d87e..6325d8876b4 100644 --- a/code/modules/species/xenomorphs/alien_powers.dm +++ b/code/modules/species/xenomorphs/alien_powers.dm @@ -85,7 +85,7 @@ if(!config_legacy.aliens_allowed) to_chat(src, "You begin to lay an egg, but hesitate. You suspect it isn't allowed.") - verbs -= /mob/living/carbon/human/proc/lay_egg + remove_verb(src, /mob/living/carbon/human/proc/lay_egg) return if(locate(/obj/effect/alien/egg) in get_turf(src)) diff --git a/code/modules/spells/spellbook.dm b/code/modules/spells/spellbook.dm index 7b81ae4a721..451f5a3d865 100644 --- a/code/modules/spells/spellbook.dm +++ b/code/modules/spells/spellbook.dm @@ -346,11 +346,11 @@ if(user.mind.special_verbs.len) for(var/V in user.mind.special_verbs) - user.verbs -= V + remove_verb(user, V) if(stored_swap.mind.special_verbs.len) for(var/V in stored_swap.mind.special_verbs) - stored_swap.verbs -= V + remove_verb(stored_swap, V) var/mob/observer/dead/ghost = stored_swap.ghostize(0) ghost.spell_list = stored_swap.spell_list @@ -360,7 +360,7 @@ if(stored_swap.mind.special_verbs.len) for(var/V in user.mind.special_verbs) - user.verbs += V + add_verb(user, V) ghost.mind.transfer_to(user) user.key = ghost.key @@ -368,7 +368,7 @@ if(user.mind.special_verbs.len) for(var/V in user.mind.special_verbs) - user.verbs += V + add_verb(user, V) to_chat(stored_swap, "You're suddenly somewhere else... and someone else?!") to_chat(user, "Suddenly you're staring at [src] again... where are you, who are you?!") diff --git a/code/modules/spells/spells.dm b/code/modules/spells/spells.dm index e4c269a16d4..3adb922981a 100644 --- a/code/modules/spells/spells.dm +++ b/code/modules/spells/spells.dm @@ -8,19 +8,43 @@ spell_master.toggle_open(1) client.screen -= spell_master -/mob/Stat() +/mob/statpanel_data(client/C) . = ..() - if(. && spell_list && spell_list.len) - for(var/spell/S in spell_list) - if((!S.connected_button) || !statpanel(S.panel)) - continue //Not showing the noclothes spell - switch(S.charge_type) - if(Sp_RECHARGE) - statpanel(S.panel,"[S.charge_counter/10.0]/[S.charge_max/10]",S.connected_button) - if(Sp_CHARGES) - statpanel(S.panel,"[S.charge_counter]/[S.charge_max]",S.connected_button) - if(Sp_HOLDVAR) - statpanel(S.panel,"[S.holder_var_type] [S.holder_var_amount]",S.connected_button) + //! WARNING + //! NO, SERIOUSLY, READ THIS + // DO NOT COPY PASTE THE FOLLOWING CODE. + // THIS IS ALREADY SNOWFLAKED CODE; YOU *WILL* BREAK EVERYTHING IF YOU DO BY OVERWRITING DATA!! + + // i'm going to trust people aren't stupid and won't put the name of a regular panel in spells. + if(!length(spell_list)) + if(C.statpanel_spell_last) + // dispose + for(var/tab in C.statpanel_spell_last) + C.statpanel_tab(tab, FALSE) + C.statpanel_spell_last = null + return + LAZYINITLIST(C.statpanel_spell_last) + var/list/collected = list() + for(var/spell/S in spell_list) + if(!S.panel || !S.connected_button) + continue + collected[S.panel] = TRUE + if(!C.statpanel_tab(S.panel)) + continue + switch(S.charge_type) + if(Sp_RECHARGE) + STATPANEL_DATA_CLICK("[S.charge_counter/10.0]/[S.charge_max/10]", "[S.connected_button]", "\ref[S.connected_button]") + if(Sp_CHARGES) + STATPANEL_DATA_CLICK("[S.charge_counter]/[S.charge_max]", "[S.connected_button]", "\ref[S.connected_button]") + if(Sp_HOLDVAR) + STATPANEL_DATA_CLICK("[S.holder_var_type] [S.holder_var_amount]", "[S.connected_button]", "\ref[S.connected_button]") + // process tabs + var/list/removing = C.statpanel_spell_last - collected + var/list/adding = collected - C.statpanel_spell_last + for(var/tab in adding) + C.statpanel_tab(adding, TRUE) + for(var/tab in removing) + C.statpanel_tab(removing, TRUE) /hook/clone/proc/restore_spells(var/mob/H) if(H.mind && H.mind.learned_spells) diff --git a/code/modules/spells/targeted/mind_transfer.dm b/code/modules/spells/targeted/mind_transfer.dm index c440157cdd9..37c6720fce4 100644 --- a/code/modules/spells/targeted/mind_transfer.dm +++ b/code/modules/spells/targeted/mind_transfer.dm @@ -41,11 +41,11 @@ //MIND TRANSFER BEGIN if(caster.mind.special_verbs.len)//If the caster had any special verbs, remove them from the mob verb list. for(var/V in caster.mind.special_verbs)//Since the caster is using an object spell system, this is mostly moot. - caster.verbs -= V//But a safety nontheless. + remove_verb(caster, V) //But a safety nontheless. if(victim.mind.special_verbs.len)//Now remove all of the victim's verbs. for(var/V in victim.mind.special_verbs) - victim.verbs -= V + remove_verb(victim, V) var/mob/observer/dead/ghost = victim.ghostize(0) ghost.spell_list += victim.spell_list//If they have spells, transfer them. Now we basically have a backup mob. @@ -60,7 +60,7 @@ if(victim.mind.special_verbs.len)//To add all the special verbs for the original caster. for(var/V in caster.mind.special_verbs)//Not too important but could come into play. - caster.verbs += V + add_verb(caster, V) ghost.mind.transfer_to(caster) caster.key = ghost.key //have to transfer the key since the mind was not active @@ -70,7 +70,7 @@ if(caster.mind.special_verbs.len)//If they had any special verbs, we add them here. for(var/V in caster.mind.special_verbs) - caster.verbs += V + add_verb(caster, V) //MIND TRANSFER END //Target is handled in ..(), so we handle the caster here diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index 48f43f942d5..f70fc768abc 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -557,8 +557,8 @@ target.set_species(/datum/species/diona) - target.verbs |= /mob/living/carbon/human/proc/diona_split_nymph - target.verbs |= /mob/living/carbon/human/proc/regenerate + add_verb(target, /mob/living/carbon/human/proc/diona_split_nymph) + add_verb(target, /mob/living/carbon/human/proc/regenerate) spawn(0) //Name yourself on your own damn time var/new_name = "" diff --git a/code/modules/tables/flipping.dm b/code/modules/tables/flipping.dm index 91c7838a6ec..e271b22d138 100644 --- a/code/modules/tables/flipping.dm +++ b/code/modules/tables/flipping.dm @@ -73,8 +73,8 @@ if( !straight_table_check(turn(direction,90)) || !straight_table_check(turn(direction,-90)) ) return 0 - verbs -=/obj/structure/table/verb/do_flip - verbs +=/obj/structure/table/proc/do_put + remove_obj_verb(src, /obj/structure/table/verb/do_flip) + add_obj_verb(src, /obj/structure/table/proc/do_put) var/list/targets = list(get_step(src,dir),get_step(src,turn(dir, 45)),get_step(src,turn(dir, -45))) for (var/atom/movable/A in get_turf(src)) @@ -100,8 +100,8 @@ return 1 /obj/structure/table/proc/unflip() - verbs -=/obj/structure/table/proc/do_put - verbs +=/obj/structure/table/verb/do_flip + remove_obj_verb(src, /obj/structure/table/proc/do_put) + add_obj_verb(src, /obj/structure/table/verb/do_flip) reset_plane_and_layer() flipped = 0 diff --git a/code/modules/tables/presets.dm b/code/modules/tables/presets.dm index acaba1d1bdc..6babae5b4b9 100644 --- a/code/modules/tables/presets.dm +++ b/code/modules/tables/presets.dm @@ -153,8 +153,8 @@ /obj/structure/table/alien/Initialize(mapload) material = SSmaterials.get_material(/datum/material/alienalloy/alium) - verbs -= /obj/structure/table/verb/do_flip - verbs -= /obj/structure/table/proc/do_put + remove_obj_verb(src, /obj/structure/table/verb/do_flip) + remove_obj_verb(src, /obj/structure/table/proc/do_put) return ..() /obj/structure/table/alien/dismantle(obj/item/tool/wrench/W, mob/user) diff --git a/code/modules/tables/presets_vr.dm b/code/modules/tables/presets_vr.dm index a898014bae4..6b0d112e836 100644 --- a/code/modules/tables/presets_vr.dm +++ b/code/modules/tables/presets_vr.dm @@ -9,8 +9,8 @@ /obj/structure/table/darkglass/New() material = get_material_by_name("darkglass") - verbs -= /obj/structure/table/verb/do_flip - verbs -= /obj/structure/table/proc/do_put + remove_obj_verb(src, /obj/structure/table/verb/do_flip) + remove_obj_verb(src, /obj/structure/table/proc/do_put) ..() @@ -32,8 +32,8 @@ /obj/structure/table/fancyblack/Initialize(mapload) material = get_material_by_name("fancyblack") - verbs -= /obj/structure/table/verb/do_flip - verbs -= /obj/structure/table/proc/do_put + remove_obj_verb(src, /obj/structure/table/verb/do_flip) + remove_obj_verb(src, /obj/structure/table/proc/do_put) . = ..() /obj/structure/table/fancyblack/dismantle(obj/item/tool/wrench/W, mob/user) diff --git a/code/modules/tables/rack.dm b/code/modules/tables/rack.dm index c3a6455f038..6c990b0bcde 100644 --- a/code/modules/tables/rack.dm +++ b/code/modules/tables/rack.dm @@ -10,8 +10,8 @@ /obj/structure/table/rack/Initialize(mapload) . = ..() - verbs -= /obj/structure/table/verb/do_flip - verbs -= /obj/structure/table/proc/do_put + remove_obj_verb(src, /obj/structure/table/verb/do_flip) + remove_obj_verb(src, /obj/structure/table/proc/do_put) /obj/structure/table/rack/update_connections() return diff --git a/code/modules/vehicles_legacy/Securitrain_vr.dm b/code/modules/vehicles_legacy/Securitrain_vr.dm index 24bb18bc94a..355cab24e4e 100644 --- a/code/modules/vehicles_legacy/Securitrain_vr.dm +++ b/code/modules/vehicles_legacy/Securitrain_vr.dm @@ -96,7 +96,7 @@ if(!user.attempt_insert_item_for_installation(W, src)) return key = W - verbs += /obj/vehicle_old/train/security/engine/verb/remove_key + add_obj_verb(src, /obj/vehicle_old/train/security/engine/verb/remove_key) return ..() @@ -148,24 +148,24 @@ ..() update_stats() - verbs -= /obj/vehicle_old/train/security/engine/verb/stop_engine - verbs -= /obj/vehicle_old/train/security/engine/verb/start_engine + remove_obj_verb(src, /obj/vehicle_old/train/security/engine/verb/stop_engine) + remove_obj_verb(src, /obj/vehicle_old/train/security/engine/verb/start_engine) if(on) - verbs += /obj/vehicle_old/train/security/engine/verb/stop_engine + add_obj_verb(src, /obj/vehicle_old/train/security/engine/verb/stop_engine) else - verbs += /obj/vehicle_old/train/security/engine/verb/start_engine + add_obj_verb(src, /obj/vehicle_old/train/security/engine/verb/start_engine) /obj/vehicle_old/train/security/engine/turn_off() ..() - verbs -= /obj/vehicle_old/train/security/engine/verb/stop_engine - verbs -= /obj/vehicle_old/train/security/engine/verb/start_engine + remove_obj_verb(src, /obj/vehicle_old/train/security/engine/verb/stop_engine) + remove_obj_verb(src, /obj/vehicle_old/train/security/engine/verb/start_engine) if(!on) - verbs += /obj/vehicle_old/train/security/engine/verb/start_engine + add_obj_verb(src, /obj/vehicle_old/train/security/engine/verb/start_engine) else - verbs += /obj/vehicle_old/train/security/engine/verb/stop_engine + add_obj_verb(src, /obj/vehicle_old/train/security/engine/verb/stop_engine) /obj/vehicle_old/train/security/RunOver(var/mob/living/M) var/list/parts = list(BP_HEAD, BP_TORSO, BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM) @@ -268,7 +268,7 @@ usr.put_in_hands(key) key = null - verbs -= /obj/vehicle_old/train/security/engine/verb/remove_key + remove_obj_verb(src, /obj/vehicle_old/train/security/engine/verb/remove_key) //------------------------------------------- // Loading/unloading procs diff --git a/code/modules/vehicles_legacy/cargo_train.dm b/code/modules/vehicles_legacy/cargo_train.dm index 1f299c2adcb..4a76d4e3572 100644 --- a/code/modules/vehicles_legacy/cargo_train.dm +++ b/code/modules/vehicles_legacy/cargo_train.dm @@ -80,7 +80,7 @@ if(!user.attempt_insert_item_for_installation(W, src)) return CLICKCHAIN_DO_NOT_PROPAGATE key = W - verbs += /obj/vehicle_old/train/engine/verb/remove_key + add_obj_verb(src, /obj/vehicle_old/train/engine/verb/remove_key) return CLICKCHAIN_DO_NOT_PROPAGATE return ..() @@ -134,24 +134,24 @@ ..() update_stats() - verbs -= /obj/vehicle_old/train/engine/verb/stop_engine - verbs -= /obj/vehicle_old/train/engine/verb/start_engine + remove_obj_verb(src, /obj/vehicle_old/train/engine/verb/stop_engine) + remove_obj_verb(src, /obj/vehicle_old/train/engine/verb/start_engine) if(on) - verbs += /obj/vehicle_old/train/engine/verb/stop_engine + add_obj_verb(src, /obj/vehicle_old/train/engine/verb/stop_engine) else - verbs += /obj/vehicle_old/train/engine/verb/start_engine + add_obj_verb(src, /obj/vehicle_old/train/engine/verb/start_engine) /obj/vehicle_old/train/engine/turn_off() ..() - verbs -= /obj/vehicle_old/train/engine/verb/stop_engine - verbs -= /obj/vehicle_old/train/engine/verb/start_engine + remove_obj_verb(src, /obj/vehicle_old/train/engine/verb/stop_engine) + remove_obj_verb(src, /obj/vehicle_old/train/engine/verb/start_engine) if(!on) - verbs += /obj/vehicle_old/train/engine/verb/start_engine + add_obj_verb(src, /obj/vehicle_old/train/engine/verb/start_engine) else - verbs += /obj/vehicle_old/train/engine/verb/stop_engine + add_obj_verb(src, /obj/vehicle_old/train/engine/verb/stop_engine) /obj/vehicle_old/train/RunOver(var/mob/living/M) var/list/parts = list(BP_HEAD, BP_TORSO, BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM) @@ -269,7 +269,7 @@ usr.put_in_hands(key) key = null - verbs -= /obj/vehicle_old/train/engine/verb/remove_key + remove_obj_verb(src, /obj/vehicle_old/train/engine/verb/remove_key) //------------------------------------------- // Loading/unloading procs diff --git a/code/modules/vehicles_legacy/rover_vr.dm b/code/modules/vehicles_legacy/rover_vr.dm index 697a5e30245..2f271cd85ac 100644 --- a/code/modules/vehicles_legacy/rover_vr.dm +++ b/code/modules/vehicles_legacy/rover_vr.dm @@ -97,7 +97,7 @@ if(!user.attempt_insert_item_for_installation(W, src)) return key = W - verbs += /obj/vehicle_old/train/rover/engine/verb/remove_key + add_obj_verb(src, /obj/vehicle_old/train/rover/engine/verb/remove_key) return ..() @@ -149,24 +149,24 @@ ..() update_stats() - verbs -= /obj/vehicle_old/train/rover/engine/verb/stop_engine - verbs -= /obj/vehicle_old/train/rover/engine/verb/start_engine + remove_obj_verb(src, /obj/vehicle_old/train/rover/engine/verb/stop_engine) + remove_obj_verb(src, /obj/vehicle_old/train/rover/engine/verb/start_engine) if(on) - verbs += /obj/vehicle_old/train/rover/engine/verb/stop_engine + add_obj_verb(src, /obj/vehicle_old/train/rover/engine/verb/stop_engine) else - verbs += /obj/vehicle_old/train/rover/engine/verb/start_engine + add_obj_verb(src, /obj/vehicle_old/train/rover/engine/verb/start_engine) /obj/vehicle_old/train/rover/engine/turn_off() ..() - verbs -= /obj/vehicle_old/train/rover/engine/verb/stop_engine - verbs -= /obj/vehicle_old/train/rover/engine/verb/start_engine + remove_obj_verb(src, /obj/vehicle_old/train/rover/engine/verb/stop_engine) + remove_obj_verb(src, /obj/vehicle_old/train/rover/engine/verb/start_engine) if(!on) - verbs += /obj/vehicle_old/train/rover/engine/verb/start_engine + add_obj_verb(src, /obj/vehicle_old/train/rover/engine/verb/start_engine) else - verbs += /obj/vehicle_old/train/rover/engine/verb/stop_engine + add_obj_verb(src, /obj/vehicle_old/train/rover/engine/verb/stop_engine) /obj/vehicle_old/train/rover/RunOver(var/mob/living/M) var/list/parts = list(BP_HEAD, BP_TORSO, BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM) @@ -269,7 +269,7 @@ usr.put_in_hands(key) key = null - verbs -= /obj/vehicle_old/train/rover/engine/verb/remove_key + remove_obj_verb(src, /obj/vehicle_old/train/rover/engine/verb/remove_key) //------------------------------------------- // Loading/unloading procs diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm index 596f81033ff..752f60ef989 100644 --- a/code/modules/vore/eating/living_vr.dm +++ b/code/modules/vore/eating/living_vr.dm @@ -45,13 +45,13 @@ // Hook for generic creation of stuff on new creatures // /hook/living_new/proc/vore_setup(mob/living/M) - M.verbs += /mob/living/proc/escapeOOC - M.verbs += /mob/living/proc/lick - M.verbs += /mob/living/proc/smell - M.verbs += /mob/living/proc/switch_scaling + add_verb(M, /mob/living/proc/escapeOOC) + add_verb(M, /mob/living/proc/lick) + add_verb(M, /mob/living/proc/smell) + add_verb(M, /mob/living/proc/switch_scaling) if(M.no_vore) //If the mob isn't supposed to have a stomach, let's not give it an insidepanel so it can make one for itself, or a stomach. return TRUE - M.verbs += /mob/living/proc/insidePanel + add_verb(M, /mob/living/proc/insidePanel) //Tries to load prefs if a client is present otherwise gives freebie stomach spawn(2 SECONDS) diff --git a/code/modules/vore/eating/silicon_vr.dm b/code/modules/vore/eating/silicon_vr.dm index 4f99133f0da..0b3682d4bf5 100644 --- a/code/modules/vore/eating/silicon_vr.dm +++ b/code/modules/vore/eating/silicon_vr.dm @@ -50,6 +50,7 @@ set name = "Hardlight Nom" set category = "AI Commands" set desc = "Wrap up a person in hardlight holograms." + set src = usr // Wrong state if (!eyeobj || !holo) diff --git a/code/modules/vore/eating/transforming_vr.dm b/code/modules/vore/eating/transforming_vr.dm index 28a92610c15..d3b8afec809 100644 --- a/code/modules/vore/eating/transforming_vr.dm +++ b/code/modules/vore/eating/transforming_vr.dm @@ -215,7 +215,7 @@ if(!istype(M) || !istype(O)) return - M.verbs -= M.species.inherent_verbs //Take away their unique stuff + remove_verb(M, M.species.inherent_verbs) //Take away their unique stuff var/list/backup_implants = list() for(var/obj/item/organ/I in M.organs) diff --git a/code/modules/vore/fluffstuff/custom_items.dm b/code/modules/vore/fluffstuff/custom_items.dm index 49b64474b46..6fd0c39c234 100644 --- a/code/modules/vore/fluffstuff/custom_items.dm +++ b/code/modules/vore/fluffstuff/custom_items.dm @@ -678,7 +678,7 @@ /obj/item/fluff/dragor_dot/attack_self(mob/user) if(user.ckey == "pontifexminimus") - user.verbs |= /mob/living/carbon/human/proc/shapeshifter_select_gender + add_verb(user, /mob/living/carbon/human/proc/shapeshifter_select_gender) else return @@ -1287,7 +1287,7 @@ /obj/item/implant/reagent_generator/evian/post_implant(mob/living/carbon/source) START_PROCESSING(SSobj, src) to_chat(source, "You implant [source] with \the [src].") - source.verbs |= assigned_proc + add_verb(source, assigned_proc) return 1 /obj/item/implanter/reagent_generator/evian diff --git a/code/modules/vore/resizing/resize_vr.dm b/code/modules/vore/resizing/resize_vr.dm index acd65a5eeb5..96a5b096d0d 100644 --- a/code/modules/vore/resizing/resize_vr.dm +++ b/code/modules/vore/resizing/resize_vr.dm @@ -116,7 +116,7 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2 /* //Add the set_size() proc to usable verbs. By commenting this out, we can leave the proc and hand it to species that need it. /hook/living_new/proc/resize_setup(mob/living/H) - H.verbs += /mob/living/proc/set_size + add_verb(H, /mob/living/proc/set_size) return 1 */ diff --git a/code/world.dm b/code/world.dm index 3d3bc39f902..8d04aa4aadc 100644 --- a/code/world.dm +++ b/code/world.dm @@ -6,7 +6,6 @@ turf = /turf/space/basic area = /area/space view = "15x15" - cache_lifespan = 7 hub = "Exadv1.spacestation13" hub_password = "kMZy3U5jJHSiBQjr" name = "Citadel Station 13 - Roleplay" diff --git a/html/statbrowser.html b/html/statbrowser.html new file mode 100644 index 00000000000..e4e0468d5ac --- /dev/null +++ b/html/statbrowser.html @@ -0,0 +1,1136 @@ + + + + + + +Stat Browser + + + + + + + + + + + + + + + + + + +
+
+ + + + + + diff --git a/interface/skin.dmf b/interface/skin.dmf index 3b8304d6e93..338b8e77c21 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -8,20 +8,16 @@ window "mainwindow" size = 640x480 anchor1 = -1,-1 anchor2 = -1,-1 - background-color = none is-default = true saved-params = "pos;size;is-minimized;is-maximized" icon = 'icons\\CS13.png' macro = "default" - outer-size = 656x538 - inner-size = 640x499 elem "split" type = CHILD pos = 0,0 size = 640x480 anchor1 = 0,0 anchor2 = 100,100 - background-color = none saved-params = "splitter" left = "mapwindow" right = "infowindow" @@ -32,7 +28,6 @@ window "mainwindow" size = 200x200 anchor1 = -1,-1 anchor2 = -1,-1 - background-color = none is-visible = false saved-params = "" elem "tooltip" @@ -41,7 +36,6 @@ window "mainwindow" size = 999x999 anchor1 = -1,-1 anchor2 = -1,-1 - background-color = none is-visible = false saved-params = "" @@ -178,7 +172,7 @@ window "infowindow" window "outputwindow" elem "outputwindow" type = MAIN - pos = 0,0 + pos = 281,0 size = 640x480 anchor1 = -1,-1 anchor2 = -1,-1 @@ -241,16 +235,35 @@ window "outputwindow" is-visible = false saved-params = "" -window "statwindow" - elem "statwindow" +window "stat_pane_browser" + elem "stat_pane_browser" type = MAIN - pos = 372,0 + pos = 281,0 size = 640x480 anchor1 = -1,-1 anchor2 = -1,-1 saved-params = "pos;size;is-minimized;is-maximized" + title = "Status Panel" is-pane = true elem "statbrowser" + type = BROWSER + pos = 0,0 + size = 640x480 + anchor1 = 0,0 + anchor2 = 100,100 + saved-params = "" + +window "stat_pane_byond" + elem "stat_pane_byond" + type = MAIN + pos = 281,0 + size = 640x480 + anchor1 = -1,-1 + anchor2 = -1,-1 + saved-params = "pos;size;is-minimized;is-maximized" + title = "Turf / Misc" + is-pane = true + elem "statpanel" type = INFO pos = 0,0 size = 640x480 @@ -258,3 +271,28 @@ window "statwindow" anchor2 = 100,100 saved-params = "" +window "statwindow" + elem "statwindow" + type = MAIN + pos = 281,0 + size = 640x480 + anchor1 = -1,-1 + anchor2 = -1,-1 + background-color = none + saved-params = "pos;size;is-minimized;is-maximized" + is-pane = true + outer-size = 656x538 + inner-size = 640x499 + elem "stat_tab" + type = TAB + pos = 0,0 + size = 640x480 + anchor1 = 0,0 + anchor2 = 100,100 + background-color = none + saved-params = "" + tabs = "stat_pane_browser,stat_pane_byond" + current-tab = "stat_pane_browser,stat_pane_byond" + multi-line = false + on-tab = ".statswitcher [[*]]" + diff --git a/tgui/packages/tgui-panel/themes.js b/tgui/packages/tgui-panel/themes.js index a972e051db5..8306ecb39a6 100644 --- a/tgui/packages/tgui-panel/themes.js +++ b/tgui/packages/tgui-panel/themes.js @@ -36,11 +36,12 @@ let setClientThemeTimer = null; export const setClientTheme = name => { // Transmit once for fast updates and again in a little while in case we won // the race against statbrowser init. - clearInterval(setClientThemeTimer); - Byond.command(`.output statbrowser:set_theme ${name}`); + let stat_theme = name === "light"? "light" : "dark"; + clearTimeout(setClientThemeTimer); + Byond.command(`.output statbrowser:set_theme ${stat_theme}`); setClientThemeTimer = setTimeout(() => { - Byond.command(`.output statbrowser:set_theme ${name}`); - }, 1500); + Byond.command(`.output statbrowser:set_theme ${stat_theme}`); + }, 5000); if (name === 'light') { return Byond.winset({ @@ -73,19 +74,21 @@ export const setClientTheme = name => { 'output.text-color': COLOR_WHITE_TEXT, 'statwindow.background-color': COLOR_WHITE_DARKBG, 'statwindow.text-color': COLOR_WHITE_TEXT, - 'statbrowser.background-color': COLOR_WHITE_BG, - 'statbrowser.tab-background-color': COLOR_WHITE_DARKBG, - 'statbrowser.text-color': COLOR_WHITE_TEXT, - 'statbrowser.tab-text-color': COLOR_WHITE_TEXT, - 'statbrowser.prefix-color': COLOR_WHITE_TEXT, - 'statbrowser.suffix-color': COLOR_WHITE_TEXT, + 'stat_tab.background-color': COLOR_WHITE_DARKBG, + 'stat_tab.text-color': COLOR_WHITE_TEXT, + 'statpanel.background-color': COLOR_WHITE_BG, + 'statpanel.tab-background-color': COLOR_WHITE_DARKBG, + 'statpanel.text-color': COLOR_WHITE_TEXT, + 'statpanel.tab-text-color': COLOR_WHITE_TEXT, + 'statpanel.prefix-color': COLOR_WHITE_TEXT, + 'statpanel.suffix-color': COLOR_WHITE_TEXT, // Say, OOC, me Buttons etc. 'saybutton.background-color': COLOR_WHITE_DARKBG, 'saybutton.text-color': COLOR_WHITE_TEXT, - 'oocbutton.background-color': COLOR_WHITE_DARKBG, - 'oocbutton.text-color': COLOR_WHITE_TEXT, - 'mebutton.background-color': COLOR_WHITE_DARKBG, - 'mebutton.text-color': COLOR_WHITE_TEXT, + // 'oocbutton.background-color': COLOR_WHITE_DARKBG, + // 'oocbutton.text-color': COLOR_WHITE_TEXT, + // 'mebutton.background-color': COLOR_WHITE_DARKBG, + // 'mebutton.text-color': COLOR_WHITE_TEXT, 'asset_cache_browser.background-color': COLOR_WHITE_DARKBG, 'asset_cache_browser.text-color': COLOR_WHITE_TEXT, 'tooltip.background-color': COLOR_WHITE_BG, @@ -123,12 +126,14 @@ export const setClientTheme = name => { 'output.text-color': COLOR_DARK_TEXT, 'statwindow.background-color': COLOR_DARK_DARKBG, 'statwindow.text-color': COLOR_DARK_TEXT, - 'statbrowser.background-color': COLOR_DARK_DARKBG, - 'statbrowser.tab-background-color': COLOR_DARK_BG, - 'statbrowser.text-color': COLOR_DARK_TEXT, - 'statbrowser.tab-text-color': COLOR_DARK_TEXT, - 'statbrowser.prefix-color': COLOR_DARK_TEXT, - 'statbrowser.suffix-color': COLOR_DARK_TEXT, + 'stat_tab.background-color': COLOR_DARK_BG, + 'stat_tab.text-color': COLOR_DARK_TEXT, + 'statpanel.background-color': COLOR_DARK_DARKBG, + 'statpanel.tab-background-color': COLOR_DARK_BG, + 'statpanel.text-color': COLOR_DARK_TEXT, + 'statpanel.tab-text-color': COLOR_DARK_TEXT, + 'statpanel.prefix-color': COLOR_DARK_TEXT, + 'statpanel.suffix-color': COLOR_DARK_TEXT, // Say, OOC, me Buttons etc. 'saybutton.background-color': COLOR_DARK_BG, 'saybutton.text-color': COLOR_DARK_TEXT, @@ -173,12 +178,14 @@ export const setClientTheme = name => { 'output.text-color': COLOR_DARK_TEXT, 'statwindow.background-color': COLOR_DARK_DARKBG, 'statwindow.text-color': COLOR_DARK_TEXT, - 'statbrowser.background-color': COLOR_DARK_DARKBG, - 'statbrowser.tab-background-color': COLOR_DARK_BG, - 'statbrowser.text-color': COLOR_DARK_TEXT, - 'statbrowser.tab-text-color': COLOR_DARK_TEXT, - 'statbrowser.prefix-color': COLOR_DARK_TEXT, - 'statbrowser.suffix-color': COLOR_DARK_TEXT, + 'stat_tab.background-color': COLOR_DARK_BG, + 'stat_tab.text-color': COLOR_DARK_TEXT, + 'statpanel.background-color': COLOR_DARK_DARKBG, + 'statpanel.tab-background-color': COLOR_DARK_BG, + 'statpanel.text-color': COLOR_DARK_TEXT, + 'statpanel.tab-text-color': COLOR_DARK_TEXT, + 'statpanel.prefix-color': COLOR_DARK_TEXT, + 'statpanel.suffix-color': COLOR_DARK_TEXT, // Say, OOC, me Buttons etc. 'saybutton.background-color': COLOR_DARK_BG, 'saybutton.text-color': COLOR_DARK_TEXT,