From c4487459766d3f883d190e336fa68062d91f1829 Mon Sep 17 00:00:00 2001
From: Jeremiah <42397676+jlsnow301@users.noreply.github.com>
Date: Thu, 4 Apr 2024 19:02:14 -0700
Subject: [PATCH] Creates a "busy" animation for players (#82416)
## About The Pull Request
Little indicator above a player when they're currently doing something.
vids
Perspective: You are the moth

Hides under runechat

Todo:
- [x] Feedback?
- [x] Sneaky params so it doesn't spoil your stealth run
- [x] Possible refactor
- [x] Probably missed some "sneaky" actions
- [x] coggers
## Why It's Good For The Game
sound on:
https://github.com/tgstation/tgstation/assets/42397676/ad71c567-0202-4158-ba50-c2946375f988
## Changelog
:cl: jlsnow301, infraredbaron
add: Added a new UI element over players that are interacting, building,
etc.
/:cl:
---------
Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com>
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: san7890
---
code/__HELPERS/mobs.dm | 11 ++-
code/datums/cogbar.dm | 87 ++++++++++++++++++
code/game/machinery/fat_sucker.dm | 2 +-
code/game/objects/items/syndie_spraycan.dm | 2 +-
.../structures/syndicate_uplink_beacon.dm | 4 +-
.../antagonists/changeling/powers/absorb.dm | 2 +-
.../antagonists/heretic/heretic_antag.dm | 2 +-
.../modules/antagonists/heretic/influences.dm | 2 +-
.../antagonists/heretic/magic/manse_link.dm | 2 +-
.../antagonists/heretic/magic/mirror_walk.dm | 4 +-
.../antagonists/ninja/ninjaDrainAct.dm | 30 +++---
.../nukeop/equipment/borgchameleon.dm | 2 +-
.../equipment/nuclear_bomb/_nuclear_bomb.dm | 2 +-
code/modules/antagonists/spy/spy_uplink.dm | 2 +-
.../antagonists/traitor/objectives/infect.dm | 2 +-
.../traitor/objectives/locate_weakpoint.dm | 2 +-
.../traitor/objectives/sabotage_machinery.dm | 2 +-
.../antagonists/traitor/objectives/steal.dm | 2 +-
.../components/unary_devices/cryo.dm | 2 +-
.../clothing/chameleon/chameleon_scanner.dm | 2 +-
.../carbon/human/species_types/vampire.dm | 2 +-
icons/effects/progressbar.dmi | Bin 1013 -> 1246 bytes
tgstation.dme | 1 +
23 files changed, 133 insertions(+), 36 deletions(-)
create mode 100644 code/datums/cogbar.dm
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index ff218afe1e1..126a565bd35 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -217,8 +217,10 @@ GLOBAL_LIST_EMPTY(species_list)
* @param {string} interaction_key - The assoc key under which the do_after is capped, with max_interact_count being the cap. Interaction key will default to target if not set.
*
* @param {number} max_interact_count - The maximum amount of interactions allowed.
+ *
+ * @param {boolean} hidden - By default, any action 1 second or longer shows a cog over the user while it is in progress. If hidden is set to TRUE, the cog will not be shown.
*/
-/proc/do_after(mob/user, delay, atom/target, timed_action_flags = NONE, progress = TRUE, datum/callback/extra_checks, interaction_key, max_interact_count = 1)
+/proc/do_after(mob/user, delay, atom/target, timed_action_flags = NONE, progress = TRUE, datum/callback/extra_checks, interaction_key, max_interact_count = 1, hidden = FALSE)
if(!user)
return FALSE
if(!isnum(delay))
@@ -245,10 +247,15 @@ GLOBAL_LIST_EMPTY(species_list)
delay *= user.cached_multiplicative_actions_slowdown
var/datum/progressbar/progbar
+ var/datum/cogbar/cog
+
if(progress)
if(user.client)
progbar = new(user, delay, target || user)
+ if(!hidden && delay >= 1 SECONDS)
+ cog = new(user)
+
SEND_SIGNAL(user, COMSIG_DO_AFTER_BEGAN)
var/endtime = world.time + delay
@@ -280,6 +287,8 @@ GLOBAL_LIST_EMPTY(species_list)
if(!QDELETED(progbar))
progbar.end_progress()
+
+ cog?.remove()
if(interaction_key)
var/reduced_interaction_count = (LAZYACCESS(user.do_afters, interaction_key) || 0) - 1
diff --git a/code/datums/cogbar.dm b/code/datums/cogbar.dm
new file mode 100644
index 00000000000..c52092e5bd1
--- /dev/null
+++ b/code/datums/cogbar.dm
@@ -0,0 +1,87 @@
+#define COGBAR_ANIMATION_TIME 5 DECISECONDS
+
+/**
+ * ### Cogbar
+ * Represents that the user is busy doing something.
+ */
+/datum/cogbar
+ /// Who's doing the thing
+ var/mob/user
+ /// The user client
+ var/client/user_client
+ /// The visible element to other players
+ var/obj/effect/overlay/vis/cog
+ /// The blank image that overlaps the cog - hides it from the source user
+ var/image/blank
+ /// The offset of the icon
+ var/offset_y
+
+
+/datum/cogbar/New(mob/user)
+ src.user = user
+ src.user_client = user.client
+
+ var/list/icon_offsets = user.get_oversized_icon_offsets()
+ offset_y = icon_offsets["y"]
+
+ add_cog_to_user()
+
+ RegisterSignal(user, COMSIG_QDELETING, PROC_REF(on_user_delete))
+
+
+/datum/cogbar/Destroy()
+ if(user)
+ SSvis_overlays.remove_vis_overlay(user, user.managed_vis_overlays)
+ user_client?.images -= blank
+
+ user = null
+ user_client = null
+ cog = null
+ QDEL_NULL(blank)
+
+ return ..()
+
+
+/// Adds the cog to the user, visible by other players
+/datum/cogbar/proc/add_cog_to_user()
+ cog = SSvis_overlays.add_vis_overlay(user,
+ icon = 'icons/effects/progressbar.dmi',
+ iconstate = "cog",
+ plane = HIGH_GAME_PLANE,
+ add_appearance_flags = APPEARANCE_UI_IGNORE_ALPHA,
+ unique = TRUE,
+ alpha = 0,
+ )
+ cog.pixel_y = world.icon_size + offset_y
+ animate(cog, alpha = 255, time = COGBAR_ANIMATION_TIME)
+
+ if(isnull(user_client))
+ return
+
+ blank = image('icons/blanks/32x32.dmi', cog, "nothing")
+ SET_PLANE_EXPLICIT(blank, HIGH_GAME_PLANE, user)
+ blank.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
+ blank.override = TRUE
+
+ user_client.images += blank
+
+
+/// Removes the cog from the user
+/datum/cogbar/proc/remove()
+ if(isnull(cog))
+ qdel(src)
+ return
+
+ animate(cog, alpha = 0, time = COGBAR_ANIMATION_TIME)
+
+ QDEL_IN(src, COGBAR_ANIMATION_TIME)
+
+
+/// When the user is deleted, remove the cog
+/datum/cogbar/proc/on_user_delete(datum/source)
+ SIGNAL_HANDLER
+
+ qdel(src)
+
+
+#undef COGBAR_ANIMATION_TIME
diff --git a/code/game/machinery/fat_sucker.dm b/code/game/machinery/fat_sucker.dm
index 279e83ecbe9..4567959b844 100644
--- a/code/game/machinery/fat_sucker.dm
+++ b/code/game/machinery/fat_sucker.dm
@@ -80,7 +80,7 @@
user.visible_message(span_notice("You see [user] kicking against the door of [src]!"), \
span_notice("You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)"), \
span_hear("You hear a metallic creaking from [src]."))
- if(do_after(user, breakout_time, target = src))
+ if(do_after(user, breakout_time, target = src, hidden = TRUE))
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open)
return
free_exit = TRUE
diff --git a/code/game/objects/items/syndie_spraycan.dm b/code/game/objects/items/syndie_spraycan.dm
index 02a576a2cb9..774219fa122 100644
--- a/code/game/objects/items/syndie_spraycan.dm
+++ b/code/game/objects/items/syndie_spraycan.dm
@@ -86,7 +86,7 @@
if(HAS_TRAIT(user, TRAIT_TAGGER))
wait_time *= 0.5
- if(!do_after(user, wait_time, target))
+ if(!do_after(user, wait_time, target, hidden = TRUE))
user.balloon_alert(user, "interrupted!")
drawing_rune = FALSE
return FALSE
diff --git a/code/game/objects/structures/syndicate_uplink_beacon.dm b/code/game/objects/structures/syndicate_uplink_beacon.dm
index f4d4ea6fe64..2106fade55a 100644
--- a/code/game/objects/structures/syndicate_uplink_beacon.dm
+++ b/code/game/objects/structures/syndicate_uplink_beacon.dm
@@ -43,7 +43,7 @@
return
var/datum/looping_sound/typing/typing_sounds = new(src, start_immediately = TRUE)
balloon_alert(user, "synchronizing...")
- if(!do_after(user = user, delay = 3 SECONDS, target = src, interaction_key = REF(src)))
+ if(!do_after(user = user, delay = 3 SECONDS, target = src, interaction_key = REF(src), hidden = TRUE))
typing_sounds.stop()
return
typing_sounds.stop()
@@ -52,7 +52,7 @@
/obj/structure/syndicate_uplink_beacon/screwdriver_act_secondary(mob/living/user, obj/item/tool)
tool.play_tool_sound(src)
balloon_alert(user, "deconstructing...")
- if (!do_after(user, 5 SECONDS, target = src))
+ if (!do_after(user, 5 SECONDS, target = src, hidden = TRUE))
return FALSE
var/turf/beacon_tile = get_turf(src)
new /obj/item/stack/sheet/iron/five(beacon_tile)
diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm
index 5bd0f390cb8..7e13612153b 100644
--- a/code/modules/antagonists/changeling/powers/absorb.dm
+++ b/code/modules/antagonists/changeling/powers/absorb.dm
@@ -145,7 +145,7 @@
target.take_overall_damage(40)
SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("Absorb DNA", "[absorbing_iteration]"))
- if(!do_after(owner, 15 SECONDS, target))
+ if(!do_after(owner, 15 SECONDS, target, hidden = TRUE))
owner.balloon_alert(owner, "interrupted!")
is_absorbing = FALSE
return FALSE
diff --git a/code/modules/antagonists/heretic/heretic_antag.dm b/code/modules/antagonists/heretic/heretic_antag.dm
index 01ca69fa734..b95b608d535 100644
--- a/code/modules/antagonists/heretic/heretic_antag.dm
+++ b/code/modules/antagonists/heretic/heretic_antag.dm
@@ -350,7 +350,7 @@
else
drawing_effect = new(target_turf, rune_colour)
- if(!do_after(user, drawing_time, target_turf, extra_checks = additional_checks))
+ if(!do_after(user, drawing_time, target_turf, extra_checks = additional_checks, hidden = TRUE))
target_turf.balloon_alert(user, "interrupted!")
new /obj/effect/temp_visual/drawing_heretic_rune/fail(target_turf, rune_colour)
qdel(drawing_effect)
diff --git a/code/modules/antagonists/heretic/influences.dm b/code/modules/antagonists/heretic/influences.dm
index 5123f7ec4bf..662af81249a 100644
--- a/code/modules/antagonists/heretic/influences.dm
+++ b/code/modules/antagonists/heretic/influences.dm
@@ -282,7 +282,7 @@
being_drained = TRUE
balloon_alert(user, "draining influence...")
- if(!do_after(user, 10 SECONDS, src))
+ if(!do_after(user, 10 SECONDS, src, hidden = TRUE))
being_drained = FALSE
balloon_alert(user, "interrupted!")
return
diff --git a/code/modules/antagonists/heretic/magic/manse_link.dm b/code/modules/antagonists/heretic/magic/manse_link.dm
index 565e7e683eb..06fd4dd9863 100644
--- a/code/modules/antagonists/heretic/magic/manse_link.dm
+++ b/code/modules/antagonists/heretic/magic/manse_link.dm
@@ -55,7 +55,7 @@
to_chat(owner, span_notice("You begin linking [linkee]'s mind to yours..."))
to_chat(linkee, span_warning("You feel your mind being pulled somewhere... connected... intertwined with the very fabric of reality..."))
- if(!do_after(owner, link_time, linkee))
+ if(!do_after(owner, link_time, linkee, hidden = TRUE))
to_chat(owner, span_warning("You fail to link to [linkee]'s mind."))
to_chat(linkee, span_warning("The foreign presence leaves your mind."))
return FALSE
diff --git a/code/modules/antagonists/heretic/magic/mirror_walk.dm b/code/modules/antagonists/heretic/magic/mirror_walk.dm
index 0bc9b059020..b9029e1ab07 100644
--- a/code/modules/antagonists/heretic/magic/mirror_walk.dm
+++ b/code/modules/antagonists/heretic/magic/mirror_walk.dm
@@ -64,7 +64,7 @@
jaunter.Beam(nearby_reflection, icon_state = "light_beam", time = phase_out_time)
nearby_reflection.visible_message(span_warning("[nearby_reflection] begins to shimmer and shake slightly!"))
- if(!do_after(jaunter, phase_out_time, nearby_reflection, IGNORE_USER_LOC_CHANGE|IGNORE_INCAPACITATED))
+ if(!do_after(jaunter, phase_out_time, nearby_reflection, IGNORE_USER_LOC_CHANGE|IGNORE_INCAPACITATED, hidden = TRUE))
return
playsound(jaunter, 'sound/magic/ethereal_enter.ogg', 50, TRUE, -1)
@@ -96,7 +96,7 @@
nearby_reflection.Beam(phase_turf, icon_state = "light_beam", time = phase_in_time)
nearby_reflection.visible_message(span_warning("[nearby_reflection] begins to shimmer and shake slightly!"))
- if(!do_after(unjaunter, phase_in_time, nearby_reflection))
+ if(!do_after(unjaunter, phase_in_time, nearby_reflection, hidden = TRUE))
return FALSE
// We can move around while phasing in, but we'll always end up where we started it.
diff --git a/code/modules/antagonists/ninja/ninjaDrainAct.dm b/code/modules/antagonists/ninja/ninjaDrainAct.dm
index 7f11d934cc6..af77a184178 100644
--- a/code/modules/antagonists/ninja/ninjaDrainAct.dm
+++ b/code/modules/antagonists/ninja/ninjaDrainAct.dm
@@ -32,7 +32,7 @@
if(hacking_module.mod.get_charge() + drain > hacking_module.mod.get_max_charge())
drain = hacking_module.mod.get_max_charge() - hacking_module.mod.get_charge()
maxcapacity = TRUE//Reached maximum battery capacity.
- if (do_after(ninja, 1 SECONDS, target = src))
+ if (do_after(ninja, 1 SECONDS, target = src, hidden = TRUE))
spark_system.start()
playsound(loc, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
cell.use(drain)
@@ -68,7 +68,7 @@
if(hacking_module.mod.get_charge() + drain > hacking_module.mod.get_max_charge())
drain = hacking_module.mod.get_max_charge() - hacking_module.mod.get_charge()
maxcapacity = TRUE
- if (do_after(ninja, 1 SECONDS, target = src))
+ if (do_after(ninja, 1 SECONDS, target = src, hidden = TRUE))
spark_system.start()
playsound(loc, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
charge -= drain
@@ -88,7 +88,7 @@
/obj/item/stock_parts/cell/proc/ninjadrain_charge(mob/living/carbon/human/ninja, obj/item/mod/module/hacker/hacking_module)
var/drain_total = 0
- if(charge && !do_after(ninja, 3 SECONDS, target = src))
+ if(charge && !do_after(ninja, 3 SECONDS, target = src, hidden = TRUE))
drain_total = charge
if(hacking_module.mod.get_charge() + charge > hacking_module.mod.get_max_charge())
drain_total = hacking_module.mod.get_max_charge() - hacking_module.mod.get_charge()
@@ -112,7 +112,7 @@
return COMPONENT_CANCEL_ATTACK_CHAIN
/obj/machinery/rnd/server/master/ninjadrain_charge(mob/living/carbon/human/ninja, obj/item/mod/module/hacker/hacking_module)
- if(!do_after(ninja, 30 SECONDS, target = src))
+ if(!do_after(ninja, 30 SECONDS, target = src, hidden = TRUE))
return
overload_source_code_hdd()
to_chat(ninja, span_notice("Sabotage complete. Storage device overloaded."))
@@ -131,7 +131,7 @@
return COMPONENT_CANCEL_ATTACK_CHAIN
/obj/machinery/rnd/server/proc/ninjadrain_charge(mob/living/carbon/human/ninja, obj/item/mod/module/hacker/hacking_module)
- if(!do_after(ninja, 30 SECONDS, target = src))
+ if(!do_after(ninja, 30 SECONDS, target = src, hidden = TRUE))
return
stored_research.modify_points_all(0)
to_chat(ninja, span_notice("Sabotage complete. Research notes corrupted."))
@@ -154,7 +154,7 @@
return COMPONENT_CANCEL_ATTACK_CHAIN
/obj/machinery/computer/records/security/proc/ninjadrain_charge(mob/living/carbon/human/ninja, obj/item/mod/module/hacker/hacking_module)
- if(!do_after(ninja, 20 SECONDS, src, extra_checks = CALLBACK(src, PROC_REF(can_hack), ninja)))
+ if(!do_after(ninja, 20 SECONDS, src, extra_checks = CALLBACK(src, PROC_REF(can_hack), ninja), hidden = TRUE))
return
for(var/datum/record/crew/target in GLOB.manifest.general)
target.wanted_status = WANTED_ARREST
@@ -230,7 +230,7 @@
while(!maxcapacity && src)
drain = (round((rand(hacking_module.mindrain, hacking_module.maxdrain))/2))
var/drained = 0
- if(wire_powernet && do_after(ninja, 1 SECONDS, target = src))
+ if(wire_powernet && do_after(ninja, 1 SECONDS, target = src, hidden = TRUE))
drained = min(drain, delayed_surplus())
add_delayedload(drained)
if(drained < drain)//if no power on net, drain apcs
@@ -270,7 +270,7 @@
if(hacking_module.mod.get_charge() + drain > hacking_module.mod.get_max_charge())
drain = hacking_module.mod.get_max_charge() - hacking_module.mod.get_charge()
maxcapacity = TRUE
- if (do_after(ninja, 1 SECONDS, target = src))
+ if (do_after(ninja, 1 SECONDS, target = src, hidden = TRUE))
spark_system.start()
playsound(loc, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
cell.use(drain)
@@ -290,7 +290,7 @@
return COMPONENT_CANCEL_ATTACK_CHAIN
/mob/living/silicon/robot/proc/ninjadrain_charge(mob/living/carbon/human/ninja, obj/item/mod/module/hacker/hacking_module)
- if(!do_after(ninja, 6 SECONDS, target = src))
+ if(!do_after(ninja, 6 SECONDS, target = src, hidden = TRUE))
return
spark_system.start()
playsound(loc, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
@@ -342,7 +342,7 @@
//BOTS//
/mob/living/simple_animal/bot/ninjadrain_act(mob/living/carbon/human/ninja, obj/item/mod/module/hacker/hacking_module)
to_chat(src, span_boldwarning("Your circutry suddenly begins heating up!"))
- if(!do_after(ninja, 1.5 SECONDS, target = src))
+ if(!do_after(ninja, 1.5 SECONDS, target = src, hidden = TRUE))
return COMPONENT_CANCEL_ATTACK_CHAIN
if(!hacking_module.mod.subtract_charge(DEFAULT_CHARGE_DRAIN * 7))
@@ -368,7 +368,7 @@
balloon_alert(ninja, "no energy!")
return COMPONENT_CANCEL_ATTACK_CHAIN
- if(!do_after(ninja, 1.5 SECONDS, target = src))
+ if(!do_after(ninja, 1.5 SECONDS, target = src, hidden = TRUE))
return COMPONENT_CANCEL_ATTACK_CHAIN
hacking_module.mod.add_charge(cell.charge)
@@ -385,7 +385,7 @@
balloon_alert(ninja, "already hacked!")
return COMPONENT_CANCEL_ATTACK_CHAIN
- if(!do_after(ninja, 2 SECONDS, target = src))
+ if(!do_after(ninja, 2 SECONDS, target = src, hidden = TRUE))
return COMPONENT_CANCEL_ATTACK_CHAIN
if(!hacking_module.mod.subtract_charge(DEFAULT_CHARGE_DRAIN * 5))
@@ -403,7 +403,7 @@
return COMPONENT_CANCEL_ATTACK_CHAIN
AI_notify_hack()
- if(!do_after(ninja, 30 SECONDS, target = src))
+ if(!do_after(ninja, 30 SECONDS, target = src, hidden = TRUE))
return COMPONENT_CANCEL_ATTACK_CHAIN
do_sparks(3, cardinal_only = FALSE, source = src)
@@ -417,7 +417,7 @@
balloon_alert(ninja, "already hacked!")
return COMPONENT_CANCEL_ATTACK_CHAIN
- if(!do_after(ninja, 2 SECONDS, target = src))
+ if(!do_after(ninja, 2 SECONDS, target = src, hidden = TRUE))
return COMPONENT_CANCEL_ATTACK_CHAIN
do_sparks(3, cardinal_only = FALSE, source = src)
@@ -438,7 +438,7 @@
AI_notify_hack()
- if(!do_after(ninja, 20 SECONDS, target = src)) //Shorter due to how incredibly easy it is for someone to (even accidentally) interrupt.
+ if(!do_after(ninja, 20 SECONDS, target = src, hidden = TRUE)) //Shorter due to how incredibly easy it is for someone to (even accidentally) interrupt.
return COMPONENT_CANCEL_ATTACK_CHAIN
force_event(/datum/round_event_control/tram_malfunction, "ninja interference")
diff --git a/code/modules/antagonists/nukeop/equipment/borgchameleon.dm b/code/modules/antagonists/nukeop/equipment/borgchameleon.dm
index 68e62a1044c..a2a072f02e2 100644
--- a/code/modules/antagonists/nukeop/equipment/borgchameleon.dm
+++ b/code/modules/antagonists/nukeop/equipment/borgchameleon.dm
@@ -66,7 +66,7 @@
to_chat(user, span_notice("You activate \the [src]."))
playsound(src, 'sound/effects/seedling_chargeup.ogg', 100, TRUE, -6)
apply_wibbly_filters(user)
- if (do_after(user, 5 SECONDS, target=user) && user.cell.use(ACTIVATION_COST))
+ if (do_after(user, 5 SECONDS, target = user, hidden = TRUE) && user.cell.use(ACTIVATION_COST))
playsound(src, 'sound/effects/bamf.ogg', 100, TRUE, -6)
to_chat(user, span_notice("You are now disguised as the Nanotrasen engineering borg \"[friendlyName]\"."))
activate(user)
diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm b/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm
index 6082567129c..8d2e746f0a2 100644
--- a/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm
+++ b/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm
@@ -124,7 +124,7 @@ GLOBAL_VAR(station_nuke_source)
if(istype(weapon, /obj/item/nuke_core_container))
var/obj/item/nuke_core_container/core_box = weapon
to_chat(user, span_notice("You start loading the plutonium core into [core_box]..."))
- if(do_after(user, 5 SECONDS, target=src))
+ if(do_after(user, 5 SECONDS, target = src, hidden = TRUE))
if(core_box.load(core, user))
to_chat(user, span_notice("You load the plutonium core into [core_box]."))
deconstruction_state = NUKESTATE_CORE_REMOVED
diff --git a/code/modules/antagonists/spy/spy_uplink.dm b/code/modules/antagonists/spy/spy_uplink.dm
index 2a9d9b9b14e..88e091310ca 100644
--- a/code/modules/antagonists/spy/spy_uplink.dm
+++ b/code/modules/antagonists/spy/spy_uplink.dm
@@ -136,7 +136,7 @@
span_notice("You start scanning [stealing], preparing it for extraction."),
)
- if(!do_after(spy, bounty.theft_time, stealing, interaction_key = REF(src)))
+ if(!do_after(spy, bounty.theft_time, stealing, interaction_key = REF(src), hidden = TRUE))
return FALSE
if(bounty.claimed)
to_chat(spy, span_warning("Your uplinks blinks red: The bounty for [stealing] has been claimed by another spy!"))
diff --git a/code/modules/antagonists/traitor/objectives/infect.dm b/code/modules/antagonists/traitor/objectives/infect.dm
index 5f761a273fc..459e8f54a0d 100644
--- a/code/modules/antagonists/traitor/objectives/infect.dm
+++ b/code/modules/antagonists/traitor/objectives/infect.dm
@@ -166,7 +166,7 @@
to_chat(affected_mob, span_warning("You feel someone try to inject you with something."))
balloon_alert(user, "injecting...")
log_combat(user, affected_mob, "attempted to inject", src)
- if(!do_after(user, 1.5 SECONDS))
+ if(!do_after(user, 1.5 SECONDS, hidden = TRUE))
balloon_alert(user, "interrupted!")
return
var/datum/disease/chronic_illness/hms = new /datum/disease/chronic_illness()
diff --git a/code/modules/antagonists/traitor/objectives/locate_weakpoint.dm b/code/modules/antagonists/traitor/objectives/locate_weakpoint.dm
index b3e211d2867..1976fd38fc8 100644
--- a/code/modules/antagonists/traitor/objectives/locate_weakpoint.dm
+++ b/code/modules/antagonists/traitor/objectives/locate_weakpoint.dm
@@ -192,7 +192,7 @@
for(var/mob/living/silicon/ai/ai_player in GLOB.player_list)
to_chat(ai_player, alertstr)
- if(!do_after(user, 30 SECONDS, src, IGNORE_USER_LOC_CHANGE | IGNORE_TARGET_LOC_CHANGE | IGNORE_HELD_ITEM | IGNORE_INCAPACITATED | IGNORE_SLOWDOWNS, extra_checks = CALLBACK(src, PROC_REF(scan_checks), user, user_area, objective)))
+ if(!do_after(user, 30 SECONDS, src, IGNORE_USER_LOC_CHANGE | IGNORE_TARGET_LOC_CHANGE | IGNORE_HELD_ITEM | IGNORE_INCAPACITATED | IGNORE_SLOWDOWNS, extra_checks = CALLBACK(src, PROC_REF(scan_checks), user, user_area, objective), hidden = TRUE))
playsound(user, 'sound/machines/buzz-sigh.ogg', 30, TRUE)
return
diff --git a/code/modules/antagonists/traitor/objectives/sabotage_machinery.dm b/code/modules/antagonists/traitor/objectives/sabotage_machinery.dm
index 48a29598981..9723d2b653e 100644
--- a/code/modules/antagonists/traitor/objectives/sabotage_machinery.dm
+++ b/code/modules/antagonists/traitor/objectives/sabotage_machinery.dm
@@ -165,7 +165,7 @@ GLOBAL_DATUM_INIT(objective_machine_handler, /datum/objective_target_machine_han
if (. || !istype(target, target_machine_path))
return
balloon_alert(user, "planting device...")
- if(!do_after(user, delay = deploy_time, target = src, interaction_key = DOAFTER_SOURCE_PLANTING_DEVICE))
+ if(!do_after(user, delay = deploy_time, target = src, interaction_key = DOAFTER_SOURCE_PLANTING_DEVICE, hidden = TRUE))
return TRUE
target.AddComponent(\
/datum/component/interaction_booby_trap,\
diff --git a/code/modules/antagonists/traitor/objectives/steal.dm b/code/modules/antagonists/traitor/objectives/steal.dm
index 61d4796d66f..22d8ed7d39c 100644
--- a/code/modules/antagonists/traitor/objectives/steal.dm
+++ b/code/modules/antagonists/traitor/objectives/steal.dm
@@ -285,7 +285,7 @@ GLOBAL_DATUM_INIT(steal_item_handler, /datum/objective_item_handler, new())
if(result & COMPONENT_FORCE_FAIL_PLACEMENT || !istype(target, target_object_type))
balloon_alert(user, "you can't attach this onto here!")
return
- if(!do_after(user, deploy_time, src))
+ if(!do_after(user, deploy_time, src, hidden = TRUE))
return
if(planted_on)
return
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
index beded509497..4d35875f1d7 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
@@ -429,7 +429,7 @@
user.visible_message(span_notice("You see [user] kicking against the glass of [src]!"), \
span_notice("You struggle inside [src], kicking the release with your foot... (this will take about [DisplayTimeText(CRYO_BREAKOUT_TIME)].)"), \
span_hear("You hear a thump from [src]."))
- if(do_after(user, CRYO_BREAKOUT_TIME, target = src))
+ if(do_after(user, CRYO_BREAKOUT_TIME, target = src, hidden = TRUE))
if(!user || user.stat != CONSCIOUS || user.loc != src )
return
user.visible_message(span_warning("[user] successfully broke out of [src]!"), \
diff --git a/code/modules/clothing/chameleon/chameleon_scanner.dm b/code/modules/clothing/chameleon/chameleon_scanner.dm
index 343ceb5c001..5023997cefe 100644
--- a/code/modules/clothing/chameleon/chameleon_scanner.dm
+++ b/code/modules/clothing/chameleon/chameleon_scanner.dm
@@ -89,7 +89,7 @@
balloon_alert(scanner, "too far away!")
return
// Very short scan timer, keep you on your toes
- if(!do_after(scanner, 0.5 SECONDS, scanned))
+ if(!do_after(scanner, 0.5 SECONDS, scanned, hidden = TRUE))
return
var/list/all_scanned_items = list()
diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm
index fbd56846ecb..111b35cb7f7 100644
--- a/code/modules/mob/living/carbon/human/species_types/vampire.dm
+++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm
@@ -186,7 +186,7 @@
victim.show_message(span_warning("[H] tries to bite you, but recoils in disgust!"))
to_chat(H, span_warning("[victim] reeks of garlic! you can't bring yourself to drain such tainted blood."))
return
- if(!do_after(H, 3 SECONDS, target = victim))
+ if(!do_after(H, 3 SECONDS, target = victim, hidden = TRUE))
return
var/blood_volume_difference = BLOOD_VOLUME_MAXIMUM - H.blood_volume //How much capacity we have left to absorb blood
var/drained_blood = min(victim.blood_volume, VAMP_DRAIN_AMOUNT, blood_volume_difference)
diff --git a/icons/effects/progressbar.dmi b/icons/effects/progressbar.dmi
index f055a07ba1492a36912ed6b9fdbf1b8e278e4864..3eed14db704a76ab77d9ea02c39e290c85e428c1 100644
GIT binary patch
delta 1184
zcmY+=eNd7I90zb7xa6FvyQY)0!@SMZUVPuQ(xD0SH8pYBsl`)G!$xL`@Ay1enYA@d
zV@*?}^fGNJz0fg_22@HXQ_)^M8Pbc2q`V|4;v+EI&fD$x*YCc6eD3@E&11)HFMJ7X
zuk-YU?>~~&vpU?}HoxoJYn?uyc|zQZLZJY9N+KB*F*TaKvSZ3p_tA-21&8x<^5{9o
zb5W?0=4&th{PCf`lg+C_gHt3wkQZB)@%wtG6IZ#(Z-S3uj#l#qUdb~GJ;^u-y0hJ@
zIa5gTjW_iuG`0B!qd&R3*eEHJ>6dHw5n+)KFYpK2*)~$j+B?vxl=Y?;+Fb`blZ)dtXN
zgf-x1Z?bJeoHP~PUe747Mpw*h7(bUbnMZn4a%-DZvIz(9YFP={V&8{CVTiHB$kdW%
zjY3n?#c?Cq`q98^^jYF>(>V*pJ6MzCM$UFIG8BVzKfoGR}QSa^q-+gf2GEk
zdg1tsYLoUi#B&;!0PLW-9%SdiQ>`Y6C2{l$0s)Yn&{6;GH^s0YEjd^@s#??8usD
zLhKK!ZDCb2Q>)B>y}I-;B;M0OdA{&`kXEe24yy!jOez-%!#L(ZFzUS8U}F$sMt~0{
zVTon3DnOYu?l`*i33VAiX=Yw4SOuAy4#mJTnOv)NU4$xMF3i(-+}vz|+qa(Xgv1x|9H_H~edf4|Ts};OE>FLK
zN2BREX$Fn+y3mT7SKc}S1ii>PaHimCnm#XgX{78B|y{pR-{O_ly0TTLPTQPt1djBr`&JFoEus
z+mBh}Nyu`5LLA`QlMh9;_~xrk+`H%}+`Q|}<}cEQEO^!21rETWsQ`*zr9C8E~(rtN>tUH$}?(|{#a^0n8eU_sOT%JnH&uzbA%e*=GC2joh=_WB$wXqsQS
zJ_idHPr&I04E~Nj{TndASGaEu0000005Ff<%}oD%?Cx%a^8q*8)nk6Opsn4#eSHcR
zw9YSIe^>v0t6x9nR}0$u{oB{)U_tBr^7Wp8-tS=Ve1xxX-y8q{0001B9=)5H{`uJ5
z-8Y;M*c?^b)l`4ZYwheN*x-78D&}|2-<0wcY;abOZ;vYddM@X+etsKla6La4^E>Bn
zOL-19SUdrz8!-4g>U_Yna{vGU004k_^loPQ=VNzw1N{GhO;Eo^?Q1IJchBF%c?vdY
znZG*;+u^(W_iZ81K>`0rzyEcEaDI;S+Wh@Vd_G|ICt!c@chvcSXXgL_00000^XT2o
z^v}oc?!MuCKnm*D2iwz~{tMdV~KLLZkqs|9BI|l#&0001(NAG5)e?E41H^A=;
zT(+-=O8c5tw!0r2+?=1*&OfyMzQASw{#NPV^U8kzV}qOX^V<1uZND$@+n<2J-%;lS
zo}B{#00000%wzWE<@w#);G*_5HMOt*0?SXj0oN)0dv5CA{|A254Ve82nEe|t^Iw5?
XZsBHuRElq(00000NkvXXu0mjf90JxT
diff --git a/tgstation.dme b/tgstation.dme
index 3a67046d8ac..105655cbaa3 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -764,6 +764,7 @@
#include "code\datums\candidate_poll.dm"
#include "code\datums\chat_payload.dm"
#include "code\datums\chatmessage.dm"
+#include "code\datums\cogbar.dm"
#include "code\datums\dash_weapon.dm"
#include "code\datums\datum.dm"
#include "code\datums\datumvars.dm"