diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 72ab4f9bdf3..cd321db03dd 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -139,4 +139,84 @@ Proc for attack log creation, because really why not
user.attack_log += text("\[[time_stamp()]\] Has [what_done] [target ? "[target.name][(ismob(target) && target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][newhealthtxt][coordinates]")
if(target && ismob(target))
target.attack_log += text("\[[time_stamp()]\] Has been [what_done] by [user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][newhealthtxt][coordinates]")
- log_attack("[user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] [what_done] [target ? "[target.name][(ismob(target) && target.ckey)? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][newhealthtxt][coordinates]")
\ No newline at end of file
+ log_attack("[user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] [what_done] [target ? "[target.name][(ismob(target) && target.ckey)? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][newhealthtxt][coordinates]")
+
+
+
+/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1)
+ if(!user || !target)
+ return 0
+ var/user_loc = user.loc
+
+ var/target_loc = target.loc
+
+ var/holding = user.get_active_hand()
+ var/datum/progressbar/progbar
+ if (progress)
+ progbar = new(user, time, target)
+
+ var/endtime = world.time+time
+ . = 1
+ while (world.time < endtime)
+ if (progress)
+ progbar.update(endtime - world.time)
+ if(!user || !target)
+ . = 0
+ break
+ if(uninterruptible)
+ continue
+ if(user.loc != user_loc || target.loc != target_loc || user.get_active_hand() != holding || user.incapacitated() || user.lying )
+ . = 0
+ break
+ sleep(1)
+ if (progress)
+ qdel(progbar)
+
+
+/proc/do_after(mob/user, delay, needhand = 1, atom/target = null, progress = 1)
+ if(!user)
+ return 0
+ var/atom/Tloc = null
+ if(target)
+ Tloc = target.loc
+
+ var/atom/Uloc = user.loc
+
+ var/holding = user.get_active_hand()
+
+ var/holdingnull = 1 //User's hand started out empty, check for an empty hand
+ if(holding)
+ holdingnull = 0 //Users hand started holding something, check to see if it's still holding that
+
+ var/datum/progressbar/progbar
+ if (progress)
+ progbar = new(user, delay, target)
+
+ var/endtime = world.time + delay
+ var/starttime = world.time
+ . = 1
+ while (world.time < endtime)
+ if (progress)
+ progbar.update(world.time - starttime)
+
+ if(!user || user.stat || user.weakened || user.stunned || user.loc != Uloc)
+ . = 0
+ break
+
+ if(Tloc && (!target || Tloc != target.loc))
+ . = 0
+ break
+
+ if(needhand)
+ //This might seem like an odd check, but you can still need a hand even when it's empty
+ //i.e the hand is used to pull some item/tool out of the construction
+ if(!holdingnull)
+ if(!holding)
+ . = 0
+ break
+ if(user.get_active_hand() != holding)
+ . = 0
+ break
+ sleep(1)
+ if (progress)
+ qdel(progbar)
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index a1b0b22f1dc..c0e0fe3a893 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -666,108 +666,6 @@ Turf and target are seperate in case you want to teleport some distance from a t
else return get_step(ref, base_dir)
-/proc/do_mob(mob/user , mob/target, time = 30, numticks = 5, uninterruptible = 0, progress = 1)
- //This is quite an ugly solution but i refuse to use the old request system.
- if(!user || !target)
- return 0
- if(numticks == 0)
- return 0
- var/user_loc = user.loc
- user.last_move = null
- var/target_loc = target.loc
- target.last_move = null
- var/holding = user.get_active_hand()
- var/timefraction = round(time/numticks)
- var/image/progbar
- var/continue_looping = 1
- for(var/i = 1 to numticks)
- if(user.client && progress)
- progbar = make_progress_bar(i, numticks, target)
- assign_progress_bar(user, progbar)
- sleep(timefraction)
- if(!user || !target)
- continue_looping = 0
-
- if (continue_looping && !uninterruptible && (user.loc != user_loc || user.last_move != null || target.loc != target_loc || target.last_move != null || user.get_active_hand() != holding || user.incapacitated() || user.lying ))
- continue_looping = 0
-
- cancel_progress_bar(user, progbar)//Clear the way for the next progbar image
- if(!continue_looping)
- return 0
-
- cancel_progress_bar(user, progbar)
- return 1
-
-/proc/make_progress_bar(current_number, goal_number, atom/target)
- if(current_number && goal_number && target)
- var/image/progbar
- progbar = image("icon" = 'icons/effects/doafter_icon.dmi', "loc" = target, "icon_state" = "prog_bar_0")
- progbar.icon_state = "prog_bar_[round(((current_number / goal_number) * 100), 10)]"
- progbar.pixel_y = 32
- return progbar
-
-/proc/cancel_progress_bar(mob/user, image/progbar)
- if(user && user.client && progbar)
- user.client.images -= progbar
-
-/proc/assign_progress_bar(mob/user, image/progbar)
- if(user && user.client && progbar)
- user.client.images |= progbar
-
-/proc/do_after(mob/user, delay, numticks = 5, needhand = 1, atom/target = null, progress = 1)
- if(!user)
- return 0
-
- if(numticks == 0)
- return 0
-
- var/atom/Tloc = null
- if(target)
- Tloc = target.loc
- var/atom/movable/AMtarget
- if(istype(target,/atom/movable))
- AMtarget = target
- AMtarget.last_move = null
- var/delayfraction = round(delay/numticks)
-
- var/atom/Uloc = user.loc
- user.last_move = null
- var/holding = user.get_active_hand()
- var/holdingnull = 1 //User is not holding anything
- if(holding)
- holdingnull = 0 //User is holding a tool of some kind
-
- var/image/progbar
-
- var/continue_looping = 1
- for (var/i = 1 to numticks)
- if(user.client && progress)
- progbar = make_progress_bar(i, numticks, target)
- assign_progress_bar(user, progbar)
-
- sleep(delayfraction)
- if(!user || user.stat || user.weakened || user.stunned || !(user.loc == Uloc) || (user.last_move != null))
- continue_looping = 0
-
- if(continue_looping && Tloc && (!target || Tloc != target.loc || (AMtarget && AMtarget.last_move != null))) //Tloc not set when we don't want to track target
- continue_looping = 0
-
- if(continue_looping && needhand)
- //This might seem like an odd check, but you can still need a hand even when it's empty
- //i.e the hand is used to insert some item/tool into the construction
- if(!holdingnull)
- if(!holding)
- continue_looping = 0
- if(continue_looping && user.get_active_hand() != holding)
- continue_looping = 0
-
- cancel_progress_bar(user, progbar)//Clear the way for the next progbar image
- if(!continue_looping)
- return 0
-
- cancel_progress_bar(user,progbar)
- return 1
-
//Takes: Anything that could possibly have variables and a varname to check.
//Returns: 1 if found, 0 if not.
/proc/hasvar(datum/A, varname)
@@ -1217,7 +1115,7 @@ B --><-- A
transform = shift
SpinAnimation(rotation_speed, -1, clockwise, rotation_segments)
-
+
//we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit
transform = initial_transform
while(orbiting && orbiting == A && A.loc)
@@ -1227,7 +1125,7 @@ B --><-- A
loc = targetloc
lastloc = loc
sleep(0.6)
-
+
if (orbiting == A) //make sure we haven't started orbiting something else.
orbiting = null
SpinAnimation(0,0)
diff --git a/code/datums/progressbar.dm b/code/datums/progressbar.dm
new file mode 100644
index 00000000000..5a4fd485527
--- /dev/null
+++ b/code/datums/progressbar.dm
@@ -0,0 +1,41 @@
+/datum/progressbar
+ var/goal = 1
+ var/image/bar
+ var/shown = 0
+ var/mob/user
+ var/client/client
+
+/datum/progressbar/New(mob/User, goal_number, atom/target)
+ . = ..()
+ if (!istype(target))
+ EXCEPTION("Invalid target given")
+ if (goal_number)
+ goal = goal_number
+ bar = image('icons/effects/progessbar.dmi', target, "prog_bar_0")
+ bar.pixel_y = 32
+ user = User
+ if (user)
+ client = user.client
+
+/datum/progressbar/proc/update(progress)
+ //world << "Update [progress] - [goal] - [(progress / goal)] - [((progress / goal) * 100)] - [round(((progress / goal) * 100), 5)]"
+ if (!user || !user.client)
+ shown = 0
+ return
+ if (user.client != client)
+ if (client)
+ client.images -= bar
+ if (user.client)
+ user.client.images += bar
+
+ progress = Clamp(progress, 0, goal)
+ bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]"
+ if (!shown)
+ user.client.images += bar
+ shown = 1
+
+/datum/progressbar/Destroy()
+ if (client)
+ client.images -= bar
+ qdel(bar)
+ . = ..()
diff --git a/code/datums/spells/lightning.dm b/code/datums/spells/lightning.dm
index 233016531cc..1bc6b2429f8 100644
--- a/code/datums/spells/lightning.dm
+++ b/code/datums/spells/lightning.dm
@@ -28,7 +28,7 @@
halo = image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = EFFECTS_LAYER)
user.overlays.Add(halo)
playsound(get_turf(user), Snd, 50, 0)
- if(do_mob(user,user,100,uninterruptible=1))
+ if(do_mob(user,user,100,1))
if(ready && cast_check(skipcharge=1))
choose_targets()
else
diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm
index 3ee6cdb9bd5..ed153281399 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant.dm
@@ -169,7 +169,7 @@
draining = 1
essence_drained += rand(15, 20)
src << "You search for the soul of [target]."
- if(do_after(src, 10, 3, 0, target)) //did they get deleted in that second?
+ if(do_after(src, 10, 0, target)) //did they get deleted in that second?
if(target.ckey)
src << "Their soul burns with intelligence."
essence_drained += rand(20, 30)
@@ -178,7 +178,7 @@
essence_drained += rand(40, 50)
else
src << "Their soul is weak and faltering."
- if(do_after(src, 20, 6, 0, target)) //did they get deleted NOW?
+ if(do_after(src, 20, 0, target)) //did they get deleted NOW?
switch(essence_drained)
if(1 to 30)
src << "[target] will not yield much essence. Still, every bit counts."
@@ -188,7 +188,7 @@
src << "Such a feast! [target] will yield much essence to you."
if(90 to INFINITY)
src << "Ah, the perfect soul. [target] will yield massive amounts of essence to you."
- if(do_after(src, 20, 6, 0, target)) //how about now
+ if(do_after(src, 20, 0, target)) //how about now
if(!target.stat)
src << "They are now powerful enough to fight off your draining."
target << "You feel something tugging across your body before subsiding."
@@ -202,7 +202,7 @@
stun(46)
target.visible_message("[target] suddenly rises slightly into the air, their skin turning an ashy gray.")
Beam(target,icon_state="drain_life",icon='icons/effects/effects.dmi',time=44)
- if(do_after(src, 50, 15, 0, target)) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining.
+ if(do_after(src, 50, 0, target)) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining.
change_essence_amount(essence_drained, 0, target)
if(essence_drained <= 90 && target.stat != DEAD)
essence_regen_cap += 5
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 25e30d87906..74869fafb76 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -818,7 +818,7 @@ About the new airlock wires panel:
"You begin [welded ? "unwelding":"welding"] the airlock...", \
"You hear welding.")
playsound(loc, 'sound/items/Welder.ogg', 40, 1)
- if(do_after(user,40/C.toolspeed,5,1, target = src))
+ if(do_after(user,40/C.toolspeed, 1, target = src))
if(density && !operating)//Door must be closed to weld.
if( !istype(src, /obj/machinery/door/airlock) || !user || !W || !W.isOn() || !user.loc )
return
diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm
index a69655548ca..2fe704d5760 100644
--- a/code/game/objects/items/weapons/cosmetics.dm
+++ b/code/game/objects/items/weapons/cosmetics.dm
@@ -89,7 +89,7 @@
else
user.visible_message("[user] begins to wipe [H]'s lipstick off with \the [src].", \
"You begin to wipe off [H]'s lipstick...")
- if(do_after(user, 10, target = H) && do_after(H, 10, 5, 0)) //user needs to keep their active hand, H does not.
+ if(do_after(user, 10, target = H))
user.visible_message("[user] wipes [H]'s lipstick off with \the [src].", \
"You wipe off [H]'s lipstick.")
H.lip_style = null
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 1ab5437d9db..38a348bbfcb 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -214,7 +214,7 @@
return
user << "You begin cutting \the [src] apart..."
playsound(loc, cutting_sound, 40, 1)
- if(do_after(user,40/W.toolspeed,5,1, target = src))
+ if(do_after(user,40/W.toolspeed,1, target = src))
if( !opened || !istype(src, /obj/structure/closet) || !user || !WT || !WT.isOn() || !user.loc )
return
playsound(loc, cutting_sound, 50, 1)
@@ -234,7 +234,7 @@
if(WT.remove_fuel(0,user))
user << "You begin [welded ? "unwelding":"welding"] \the [src]..."
playsound(loc, 'sound/items/Welder2.ogg', 40, 1)
- if(do_after(user,40,5,1, target = src))
+ if(do_after(user,40,1, target = src))
if(opened || !istype(src, /obj/structure/closet) || !user || !WT || !WT.isOn() || !user.loc )
return
playsound(loc, 'sound/items/welder.ogg', 50, 1)
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 365acba4a54..431057335d7 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -79,7 +79,7 @@
if(open)
GM.visible_message("[user] starts to give [GM] a swirlie!", "[user] starts to give [GM] a swirlie...")
swirlie = GM
- if(do_after(user, 30, 5, 0, target = src))
+ if(do_after(user, 30, 0, target = src))
GM.visible_message("[user] gives [GM] a swirlie!", "[user] gives [GM] a swirlie!", "You hear a toilet flushing.")
if(iscarbon(GM))
var/mob/living/carbon/C = GM
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index d1f2c2c10b2..5aa20340d43 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -388,7 +388,7 @@ var/const/GALOSHES_DONT_HELP = 4
last_special = world.time + CLICK_CD_BREAKOUT
visible_message("[src] attempts to unbuckle themself!", \
"You attempt to unbuckle yourself... (This will take around one minute and you need to stay still.)")
- if(do_after(src, 600, needhand = 0, target = src))
+ if(do_after(src, 600, 0, target = src))
if(!buckled)
return
buckled.user_unbuckle_mob(src,src)
@@ -431,7 +431,7 @@ var/const/GALOSHES_DONT_HELP = 4
if(!cuff_break)
visible_message("[src] attempts to remove [I]!")
src << "You attempt to remove [I]... (This will take around [displaytime] minutes and you need to stand still.)"
- if(do_after(src, breakouttime, 10, 0, target = src))
+ if(do_after(src, breakouttime, 0, target = src))
if(I.loc != src || buckled)
return
visible_message("[src] manages to remove [I]!")
@@ -457,7 +457,7 @@ var/const/GALOSHES_DONT_HELP = 4
breakouttime = 50
visible_message("[src] is trying to break [I]!")
src << "You attempt to break [I]... (This will take around 5 seconds and you need to stand still.)"
- if(do_after(src, breakouttime, needhand = 0, target = src))
+ if(do_after(src, breakouttime, 0, target = src))
if(!I.loc || buckled)
return
visible_message("[src] manages to break [I]!")
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
index 9e4eac0075c..f863d12faa1 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
@@ -33,7 +33,7 @@
D << "You can't seem to find the [pick(faux_gadgets)]! Without it, [src] [pick(faux_problems)]."
return
D.visible_message("[D] begins to reactivate [src].", "You begin to reactivate [src]...")
- if(do_after(user,30,needhand = 1, target = src))
+ if(do_after(user,30, 1, target = src))
adjustBruteLoss(-getBruteLoss()) //Heal all brute damage
stat = CONSCIOUS
icon_state = icon_living
@@ -49,7 +49,7 @@
if("Cannibalize")
if(D.health < D.maxHealth)
D.visible_message("[D] begins to cannibalize parts from [src].", "You begin to cannibalize parts from [src]...")
- if(do_after(D, 60,5,0, target = src))
+ if(do_after(D, 60, 0, target = src))
D.visible_message("[D] repairs itself using [src]'s remains!", "You repair yourself using [src]'s remains.")
D.adjustBruteLoss(-src.maxHealth)
new /obj/effect/decal/cleanable/oil/streak(get_turf(src))
diff --git a/icons/effects/doafter_icon.dmi b/icons/effects/doafter_icon.dmi
deleted file mode 100644
index 0add263e976..00000000000
Binary files a/icons/effects/doafter_icon.dmi and /dev/null differ
diff --git a/icons/effects/progessbar.dmi b/icons/effects/progessbar.dmi
new file mode 100644
index 00000000000..99284060aa6
Binary files /dev/null and b/icons/effects/progessbar.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 3822e2fec1f..aada13d7165 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -183,6 +183,7 @@
#include "code\datums\modules.dm"
#include "code\datums\mutations.dm"
#include "code\datums\outfit.dm"
+#include "code\datums\progressbar.dm"
#include "code\datums\recipe.dm"
#include "code\datums\spell.dm"
#include "code\datums\supplypacks.dm"