From e1f42f4673a0368e411ea107bd0186058dd39d7f Mon Sep 17 00:00:00 2001
From: Contrabang <91113370+Contrabang@users.noreply.github.com>
Date: Mon, 1 Sep 2025 17:10:58 -0400
Subject: [PATCH] pre_attack change (#30305)
---
code/__DEFINES/dcs/attack_chain_signals.dm | 5 +++--
code/_onclick/item_attack.dm | 5 ++++-
code/game/objects/items/cigs.dm | 7 +++----
code/game/objects/items/robot/cyborg_gripper.dm | 6 ++----
code/game/objects/items/weapons/stunbaton.dm | 7 +++----
code/game/objects/items/weapons/teleprod.dm | 9 +++++----
code/modules/mod/mod_paint.dm | 6 +++---
.../modules/projectiles/guns/energy/special_eguns.dm | 2 +-
code/modules/recycling/sortingmachinery.dm | 12 ++++++------
9 files changed, 30 insertions(+), 29 deletions(-)
diff --git a/code/__DEFINES/dcs/attack_chain_signals.dm b/code/__DEFINES/dcs/attack_chain_signals.dm
index 51210b9074d..8d1bf2325ec 100644
--- a/code/__DEFINES/dcs/attack_chain_signals.dm
+++ b/code/__DEFINES/dcs/attack_chain_signals.dm
@@ -60,8 +60,9 @@
// signal interceptors because they're not meant to be combined, and to mesh better with
// historical use of return values in attack chain procs.
-#define CONTINUE_ATTACK 0 //! Continue the attack chain, i.e. allow other signals to respond.
-#define FINISH_ATTACK 1 //! Do not continue the attack chain.
+#define CONTINUE_ATTACK 0 //! Continue the attack chain, i.e. allow other signals to respond.
+#define FINISH_ATTACK (1<<0) //! Do not continue the attack chain.
+#define MELEE_COOLDOWN_PREATTACK (1<<1) //! Apply a CLICK_CD_MELEE cooldown.
// Legacy-only, do not use in new code
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 984d2ac148b..7bf344bac1b 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -23,7 +23,10 @@
return
// Attack phase
- if(pre_attack(target, user, params))
+ var/pre_attack_result = pre_attack(target, user, params)
+ if(pre_attack_result & MELEE_COOLDOWN_PREATTACK)
+ user.changeNext_move(CLICK_CD_MELEE)
+ if(pre_attack_result & FINISH_ATTACK)
return
var/resolved = target.new_attack_chain \
diff --git a/code/game/objects/items/cigs.dm b/code/game/objects/items/cigs.dm
index 253614f9fd7..0f4aba42224 100644
--- a/code/game/objects/items/cigs.dm
+++ b/code/game/objects/items/cigs.dm
@@ -124,7 +124,6 @@ LIGHTERS ARE IN LIGHTERS.DM
var/mob/living/target = A
if(target.on_fire)
- user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(target)
if(target != user)
user.visible_message(
@@ -138,7 +137,7 @@ LIGHTERS ARE IN LIGHTERS.DM
"You quickly whip out [src] and nonchalantly light it with your own burning body. Clearly, you have your priorities straight."
)
light(user, user)
- return FINISH_ATTACK
+ return FINISH_ATTACK | MELEE_COOLDOWN_PREATTACK
// The above section doesn't check for carbons to allow ALL burning bodies to be used.
if(!iscarbon(A))
@@ -361,10 +360,10 @@ LIGHTERS ARE IN LIGHTERS.DM
)
if(!do_after(user, 5 SECONDS, target = target))
return ITEM_INTERACT_COMPLETE
-
+
else
to_chat(user, "You eat [src].")
-
+
playsound(user.loc, 'sound/items/eatfood.ogg', 50, 0)
// A SPICY candy!
diff --git a/code/game/objects/items/robot/cyborg_gripper.dm b/code/game/objects/items/robot/cyborg_gripper.dm
index 393c8d8e112..2081ca1edb9 100644
--- a/code/game/objects/items/robot/cyborg_gripper.dm
+++ b/code/game/objects/items/robot/cyborg_gripper.dm
@@ -169,16 +169,14 @@
return TRUE
/obj/item/gripper/pre_attack(atom/A, mob/living/user, params)
- // This is required to avoid hypersonic interaction speed.
- user.changeNext_move(CLICK_CD_MELEE)
+ . = FINISH_ATTACK | MELEE_COOLDOWN_PREATTACK
if(gripped_item)
gripped_item.attack(A, user)
- return TRUE
+ return
if(!ismob(A))
return ..()
- . = TRUE
var/mob/living/target = A
// If a human target is horizonal, try to help them up. Unless you're trying to kill them.
if(ishuman(target) && user.a_intent == INTENT_HELP && can_help_up)
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index 2074cb9d531..9af9e5342f1 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -212,7 +212,6 @@
if(!ismob(A))
return
- user.changeNext_move(CLICK_CD_MELEE)
var/mob/living/target = A
if(user.a_intent == INTENT_HARM)
@@ -225,7 +224,7 @@
"[target == user ? "You prod yourself" : "[user] has prodded you"] with [src]. Luckily it was off."
)
playsound(loc, 'sound/weapons/tap.ogg', 50, TRUE, -1)
- return FINISH_ATTACK
+ return FINISH_ATTACK | MELEE_COOLDOWN_PREATTACK
// Only human mobs can be stunned.
if(!ishuman(target))
@@ -235,11 +234,11 @@
"[target == user ? "You prod yourself" : "[user] has prodded you"] with [src]. It doesn't seem to have an effect."
)
playsound(loc, 'sound/weapons/tap.ogg', 50, TRUE, -1)
- return FINISH_ATTACK
+ return FINISH_ATTACK | MELEE_COOLDOWN_PREATTACK
if(baton_stun(target, user))
user.do_attack_animation(target)
- return FINISH_ATTACK
+ return FINISH_ATTACK | MELEE_COOLDOWN_PREATTACK
/obj/item/melee/baton/after_attack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
diff --git a/code/game/objects/items/weapons/teleprod.dm b/code/game/objects/items/weapons/teleprod.dm
index 81ab40bfd6b..900ba9c0eb0 100644
--- a/code/game/objects/items/weapons/teleprod.dm
+++ b/code/game/objects/items/weapons/teleprod.dm
@@ -6,15 +6,16 @@
origin_tech = "combat=2;bluespace=4;materials=3"
/obj/item/melee/baton/cattleprod/teleprod/pre_attack(atom/A, mob/living/user, params)
- if(..())
- return FINISH_ATTACK
+ . = ..()
+ if(.)
+ return
if(!turned_on)
- return FINISH_ATTACK
+ return FINISH_ATTACK | MELEE_COOLDOWN_PREATTACK
if(!ismob(A))
return
-
+
var/mob/living/carbon/M
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
user.visible_message(
diff --git a/code/modules/mod/mod_paint.dm b/code/modules/mod/mod_paint.dm
index 09f473faf88..785af97ca77 100644
--- a/code/modules/mod/mod_paint.dm
+++ b/code/modules/mod/mod_paint.dm
@@ -16,14 +16,14 @@
var/obj/item/mod/control/mod = attacked_atom
if(mod.active || mod.activating)
to_chat(user, "Deactivate the suit!")
- return TRUE
+ return FINISH_ATTACK
if(!istype(mod.theme, compatible_theme))
to_chat(user, "Theme is not compatible!")
- return TRUE
+ return FINISH_ATTACK
mod.set_mod_skin(skin)
to_chat(user, "You apply the theme to [mod].")
qdel(src)
- return TRUE
+ return FINISH_ATTACK
/obj/item/mod/skin_applier/asteroid
skin = "asteroid"
diff --git a/code/modules/projectiles/guns/energy/special_eguns.dm b/code/modules/projectiles/guns/energy/special_eguns.dm
index 7bbb16bb4cf..02581a9c5b3 100644
--- a/code/modules/projectiles/guns/energy/special_eguns.dm
+++ b/code/modules/projectiles/guns/energy/special_eguns.dm
@@ -138,7 +138,7 @@
if(istype(A, /obj/machinery/hydroponics))
// Calling afterattack from pre_attack looks stupid, but afterattack with proximity FALSE is what makes the gun fire, and we're returning FALSE to cancel the melee attack.
afterattack__legacy__attackchain(A, user, FALSE, params)
- return FALSE
+ return CONTINUE_ATTACK
return ..()
//////////////////////////////
diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm
index 61a3d521535..10050cb5767 100644
--- a/code/modules/recycling/sortingmachinery.dm
+++ b/code/modules/recycling/sortingmachinery.dm
@@ -177,7 +177,7 @@
if(isitem(target) && !(isstorage(target) && !istype(target,/obj/item/storage/box) && !istype(target, /obj/item/shipping_package)))
var/obj/item/O = target
if(!use(1))
- return FALSE
+ return CONTINUE_ATTACK
var/obj/item/small_delivery/P = new /obj/item/small_delivery(get_turf(O.loc)) //Aaannd wrap it up!
if(!isturf(O.loc))
@@ -196,24 +196,24 @@
else if(istype(target, /obj/structure/closet/crate))
var/obj/structure/big_delivery/D = wrap_closet(target, user)
if(!D)
- return FALSE
+ return CONTINUE_ATTACK
D.icon_state = "deliverycrate"
else if(istype(target, /obj/structure/closet))
var/obj/structure/closet/C = target
var/obj/structure/big_delivery/D = wrap_closet(target, user)
if(!D)
- return FALSE
+ return CONTINUE_ATTACK
D.init_welded = C.welded
C.welded = TRUE
else if(target.GetComponent(/datum/component/two_handed))
to_chat(user, "[target] is too unwieldy to wrap effectively.")
- return FALSE
+ return CONTINUE_ATTACK
else
to_chat(user, "The object you are trying to wrap is unsuitable for the sorting machinery.")
- return FALSE
+ return CONTINUE_ATTACK
user.visible_message("[user] wraps [target].")
user.create_attack_log("Has used [name] on [target]")
@@ -222,7 +222,7 @@
if(amount <= 0 && QDELETED(src)) //if we used our last wrapping paper, drop a cardboard tube
var/obj/item/c_tube/T = new(get_turf(user))
user.put_in_active_hand(T)
- return FALSE
+ return CONTINUE_ATTACK
// Separate proc to avoid copy pasting the code twice
/obj/item/stack/package_wrap/proc/wrap_closet(obj/structure/closet/C, mob/user)