mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-26 06:29:23 +01:00
Add alternate attack procs (#56663)
Adds alternate attack procs for right-clicking. Updates the gunpoint code to use this new proc as an example (though I suspect this is being changed soon, so oops). This makes it easier to add new behavior to right click, which we should be doing.
This commit is contained in:
@@ -278,3 +278,14 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
|
||||
|
||||
/// If a carbon is thrown at a speed faster than normal and impacts something solid, they take extra damage for every extra speed up to this number (see [/mob/living/carbon/proc/throw_impact])
|
||||
#define CARBON_MAX_IMPACT_SPEED_BONUS 5
|
||||
|
||||
/// Alternate attack defines. Return these at the end of procs like afterattack_alt.
|
||||
/// Calls the normal attack proc. For example, if returned in afterattack_alt, will call afterattack.
|
||||
/// Will continue the chain depending on the return value of the non-alternate proc, like with normal attacks.
|
||||
#define ALT_ATTACK_CALL_NORMAL 1
|
||||
|
||||
/// Cancels the attack chain entirely.
|
||||
#define ALT_ATTACK_CANCEL_ATTACK_CHAIN 2
|
||||
|
||||
/// Proceed with the attack chain, but don't call the normal methods.
|
||||
#define ALT_ATTACK_CONTINUE_CHAIN 3
|
||||
|
||||
@@ -8,15 +8,41 @@
|
||||
* * [/obj/item/proc/afterattack]. The return value does not matter.
|
||||
*/
|
||||
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params)
|
||||
var/is_right_clicking = params2list(params)["right"]
|
||||
|
||||
if(tool_behaviour && target.tool_act(user, src, tool_behaviour))
|
||||
return TRUE
|
||||
|
||||
if(pre_attack(target, user, params))
|
||||
return TRUE
|
||||
if(target.attackby(src,user, params))
|
||||
|
||||
var/attackby_result
|
||||
|
||||
if (is_right_clicking)
|
||||
switch (target.attackby_alt(src, user, params))
|
||||
if (ALT_ATTACK_CALL_NORMAL)
|
||||
attackby_result = target.attackby(src, user, params)
|
||||
if (ALT_ATTACK_CANCEL_ATTACK_CHAIN)
|
||||
return TRUE
|
||||
if (null)
|
||||
CRASH("attackby_alt must return an ALT_ATTACK_* define, please consult code/__DEFINES/combat.dm")
|
||||
else
|
||||
attackby_result = target.attackby(src, user, params)
|
||||
|
||||
if (attackby_result)
|
||||
return TRUE
|
||||
|
||||
if(QDELETED(src) || QDELETED(target))
|
||||
attack_qdeleted(target, user, TRUE, params)
|
||||
return TRUE
|
||||
|
||||
if (is_right_clicking)
|
||||
var/after_attack_alt_result = afterattack_alt(target, user, TRUE, params)
|
||||
|
||||
// There's no chain left to continue at this point, so CANCEL_ATTACK_CHAIN and CONTINUE_CHAIN are functionally the same.
|
||||
if (after_attack_alt_result == ALT_ATTACK_CANCEL_ATTACK_CHAIN || after_attack_alt_result == ALT_ATTACK_CONTINUE_CHAIN)
|
||||
return TRUE
|
||||
|
||||
return afterattack(target, user, TRUE, params)
|
||||
|
||||
/// Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown.
|
||||
@@ -55,6 +81,19 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Called on an object being right-clicked on by an item
|
||||
*
|
||||
* Arguments:
|
||||
* * obj/item/weapon - The item hitting this atom
|
||||
* * mob/user - The wielder of this item
|
||||
* * params - click params such as alt/shift etc
|
||||
*
|
||||
* See: [/obj/item/proc/melee_attack_chain]
|
||||
*/
|
||||
/atom/proc/attackby_alt(obj/item/weapon, mob/user, params)
|
||||
return ALT_ATTACK_CALL_NORMAL
|
||||
|
||||
/obj/attackby(obj/item/I, mob/living/user, params)
|
||||
return ..() || ((obj_flags & CAN_BE_HIT) && I.attack_obj(src, user))
|
||||
|
||||
@@ -64,6 +103,15 @@
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
return I.attack(src, user, params)
|
||||
|
||||
/mob/living/attackby_alt(obj/item/weapon, mob/living/user, params)
|
||||
var/result = weapon.attack_alt(src, user, params)
|
||||
|
||||
// Normal attackby updates click cooldown, so we have to make up for it
|
||||
if (result != ALT_ATTACK_CALL_NORMAL)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
|
||||
return result
|
||||
|
||||
/**
|
||||
* Called from [/mob/living/proc/attackby]
|
||||
*
|
||||
@@ -110,6 +158,9 @@
|
||||
log_combat(user, M, "attacked", src.name, "(COMBAT MODE: [uppertext(user.combat_mode)]) (DAMTYPE: [uppertext(damtype)])")
|
||||
add_fingerprint(user)
|
||||
|
||||
/// The equivalent of [/obj/item/proc/attack] but for alternate attacks, AKA right clicking
|
||||
/obj/item/proc/attack_alt(mob/living/victim, mob/living/user, params)
|
||||
return ALT_ATTACK_CALL_NORMAL
|
||||
|
||||
/// The equivalent of the standard version of [/obj/item/proc/attack] but for object targets.
|
||||
/obj/item/proc/attack_obj(obj/O, mob/living/user)
|
||||
@@ -165,6 +216,18 @@
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters)
|
||||
SEND_SIGNAL(user, COMSIG_MOB_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters)
|
||||
|
||||
/**
|
||||
* Called at the end of the attack chain if the user right-clicked.
|
||||
*
|
||||
* Arguments:
|
||||
* * atom/target - The thing that was hit
|
||||
* * mob/user - The mob doing the hitting
|
||||
* * proximity_flag - is 1 if this afterattack was called on something adjacent, in your square, or on your person.
|
||||
* * click_parameters - is the params string from byond [/atom/proc/Click] code, see that documentation.
|
||||
*/
|
||||
/obj/item/proc/afterattack_alt(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
return ALT_ATTACK_CALL_NORMAL
|
||||
|
||||
/// Called if the target gets deleted by our attack
|
||||
/obj/item/proc/attack_qdeleted(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_QDELETED, target, user, proximity_flag, click_parameters)
|
||||
|
||||
@@ -193,15 +193,13 @@
|
||||
for(var/obj/O in contents)
|
||||
O.emp_act(severity)
|
||||
|
||||
/obj/item/gun/attack(mob/M, mob/living/user, params)
|
||||
var/list/modifiers = params2list(params)
|
||||
if(ismob(M) && modifiers && modifiers["right"]) //Right click to hold someone up
|
||||
if(user.GetComponent(/datum/component/gunpoint))
|
||||
to_chat(user, "<span class='warning'>You are already holding someone up!</span>")
|
||||
return
|
||||
user.AddComponent(/datum/component/gunpoint, M, src)
|
||||
return TRUE
|
||||
return ..()
|
||||
/obj/item/gun/attack_alt(mob/living/victim, mob/living/user, params)
|
||||
if (user.GetComponent(/datum/component/gunpoint))
|
||||
to_chat(user, "<span class='warning'>You are already holding someone up!</span>")
|
||||
return ALT_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
|
||||
user.AddComponent(/datum/component/gunpoint, victim, src)
|
||||
return ALT_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
|
||||
/obj/item/gun/afterattack(atom/target, mob/living/user, flag, params)
|
||||
. = ..()
|
||||
|
||||
Reference in New Issue
Block a user