diff --git a/code/__HELPERS/mob_helpers.dm b/code/__HELPERS/mob_helpers.dm index 659c379453d..cda36557525 100644 --- a/code/__HELPERS/mob_helpers.dm +++ b/code/__HELPERS/mob_helpers.dm @@ -392,7 +392,7 @@ * This will create progress bar that lasts for 5 seconds. If the user doesn't move or otherwise do something that would cause the checks to fail in those 5 seconds, do_stuff() would execute. * The Proc returns TRUE upon success (the progress bar reached the end), or FALSE upon failure (the user moved or some other check failed) */ -/proc/do_after(mob/user, delay, needhand = 1, atom/target = null, progress = 1, list/extra_checks = list(), use_default_checks = TRUE) +/proc/do_after(mob/user, delay, needhand = 1, atom/target = null, progress = 1, allow_moving = 0, must_be_held = 0, list/extra_checks = list(), use_default_checks = TRUE) if(!user) return FALSE var/atom/Tloc = null @@ -402,8 +402,9 @@ var/atom/Uloc = user.loc var/drifting = FALSE - if(!user.Process_Spacemove(0) && user.inertia_dir) - drifting = TRUE + if(!allow_moving) + if(!user.Process_Spacemove(0) && user.inertia_dir) + drifting = TRUE var/holding = user.get_active_hand() @@ -429,12 +430,15 @@ sleep(1) if(progress) progbar.update(world.time - starttime) + if(!allow_moving) + if(drifting && !user.inertia_dir) + drifting = FALSE + Uloc = user.loc + if((!drifting && user.loc != Uloc)) + . = FALSE + break - if(drifting && !user.inertia_dir) - drifting = FALSE - Uloc = user.loc - - if(!user || user.stat || (!drifting && user.loc != Uloc) || check_for_true_callbacks(extra_checks)) + if(!user || user.stat || check_for_true_callbacks(extra_checks)) . = FALSE break @@ -442,6 +446,11 @@ . = FALSE break + if(must_be_held) + if(target.loc != user) + . = FALSE + 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 @@ -456,7 +465,7 @@ qdel(progbar) /// A version of do_after that will not get cancelled by a mob moving, for situations when signals are not viable -/proc/moving_do_after(mob/user, delay, needhand = TRUE, atom/target = null, progress = TRUE, list/extra_checks = list(), use_default_checks = TRUE, must_be_held = TRUE) +/proc/moving_do_after(mob/user, delay, needhand = TRUE, atom/target = null, progress = TRUE, allow_moving = 0, list/extra_checks = list(), use_default_checks = TRUE, must_be_held = TRUE) if(!istype(user)) return FALSE var/atom/target_loc = null @@ -514,7 +523,7 @@ #define DOAFTERONCE_MAGIC "Magic~~" GLOBAL_LIST_INIT(do_after_once_tracker, list()) -/proc/do_after_once(mob/user, delay, needhand = 1, atom/target = null, progress = 1, attempt_cancel_message = "Attempt cancelled.") +/proc/do_after_once(mob/user, delay, needhand = 1, atom/target = null, progress = 1, allow_moving, must_be_held, attempt_cancel_message = "Attempt cancelled.") if(!user || !target) return @@ -524,7 +533,7 @@ GLOBAL_LIST_INIT(do_after_once_tracker, list()) to_chat(user, "[attempt_cancel_message]") return FALSE GLOB.do_after_once_tracker[cache_key] = TRUE - . = do_after(user, delay, needhand, target, progress, extra_checks = list(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(do_after_once_checks), cache_key))) + . = do_after(user, delay, needhand, target, progress, allow_moving, must_be_held, extra_checks = list(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(do_after_once_checks), cache_key))) GLOB.do_after_once_tracker[cache_key] = FALSE /proc/do_after_once_checks(cache_key) diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 85f116e7faf..a0d25ee80a1 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -50,8 +50,10 @@ return /obj/item/ammo_casing/attackby(obj/item/I as obj, mob/user as mob, params) - if(istype(I, /obj/item/ammo_box) && !istype(I, /obj/item/ammo_box/magazine/wt550m9)) + if(istype(I, /obj/item/ammo_box)) var/obj/item/ammo_box/box = I + if(box.slow_loading) + return if(isturf(loc)) var/boolets = 0 for(var/obj/item/ammo_casing/bullet in loc) @@ -127,9 +129,10 @@ var/multi_sprite_step = AMMO_MULTI_SPRITE_STEP_NONE // see update_icon_state() for details var/caliber var/multiload = 1 + var/slow_loading = 0 var/list/initial_mats //For calculating refund values. -/obj/item/ammo_box/New() +/obj/item/ammo_box/Initialize(mapload) ..() for(var/i in 1 to max_ammo) stored_ammo += new ammo_type(src) diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 334e3ddfc44..8d027d3ba42 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -154,7 +154,7 @@ max_ammo = 6 multiload = 0 -/obj/item/ammo_box/magazine/internal/rus357/New() +/obj/item/ammo_box/magazine/internal/rus357/Initialize(mapload) ..() stored_ammo.Cut() // We only want 1 bullet in there stored_ammo += new ammo_type(src) @@ -259,6 +259,7 @@ max_ammo = 20 multi_sprite_step = 4 multiload = 0 + slow_loading = 1 w_class = WEIGHT_CLASS_NORMAL ///A var to check if the mag is being loaded var/being_loaded = FALSE @@ -275,29 +276,19 @@ if(istype(A, /obj/item/ammo_box/wt550) || istype(A, /obj/item/ammo_box/magazine/wt550m9)) to_chat(user, "You begin to load the magazine with [A].") var/obj/item/ammo_box/AB = A - if(being_loaded == TRUE && double_loaded == FALSE) - double_loaded = TRUE //This will cancel ongoing reloads if made true by someone trying to do two reload processes at once - to_chat(user, "You're already loading the magazine!.") - to_chat(user, "You stop loading the magazine with [A].") - being_loaded = TRUE for(var/obj/item/ammo_casing/AC in AB.stored_ammo) - if(double_loaded == FALSE)// checks to make sure double_loaded hasn't been made true while an ongoing reload is already ongoing - to_chat(user, "You stop loading the magazine with [A].") - double_loaded = FALSE - break if(length(stored_ammo) >= max_ammo) to_chat(user, "You stop loading the magazine with [A].") break - if(!moving_do_after(user, 0.5 SECONDS, target = src, use_default_checks = TRUE)) - to_chat(user, "You stop loading the magazine with [A].") + if(do_after_once(user, 0.5 SECONDS, target = src, allow_moving = TRUE, must_be_held = TRUE, attempt_cancel_message = "You stop loading the magazine with [A].")) + src.give_round(AC) + AB.stored_ammo -= AC + update_mat_value() + update_appearance(UPDATE_DESC|UPDATE_ICON_STATE) + AB.update_appearance(UPDATE_DESC|UPDATE_ICON_STATE) + playsound(src, 'sound/weapons/gun_interactions/bulletinsert.ogg', 50, 1) + else break - src.give_round(AC) - AB.stored_ammo -= AC - update_mat_value() - update_appearance(UPDATE_DESC|UPDATE_ICON_STATE) - AB.update_appearance(UPDATE_DESC|UPDATE_ICON_STATE) - playsound(src, 'sound/weapons/gun_interactions/bulletinsert.ogg', 50, 1) - being_loaded = FALSE /obj/item/ammo_box/magazine/wt550m9/wtap name = "wt550 magazine (Armour Piercing 4.6x30mm)" @@ -319,9 +310,9 @@ icon_state = "46x30mmt" ammo_type = /obj/item/ammo_casing/c46x30mm -/obj/item/ammo_box/magazine/wt550m9/empty/New() +/obj/item/ammo_box/magazine/wt550m9/empty/Initialize(mapload) . = ..() - stored_ammo = list() + stored_ammo.Cut() update_appearance(UPDATE_DESC|UPDATE_ICON) /obj/item/ammo_box/magazine/uzim9mm