mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 23:27:34 +01:00
Re-refactors batons / Refactors attack chain force modifiers (#90809)
## About The Pull Request Melee attack chain now has a list passed along with it, `attack_modifiers`, which you can stick force modifiers to change the resulting attack This is basically a soft implementation of damage packets until a more definitive pr, but one that only applies to item attack chain, and not unarmed attacks. This change was done to facilitate a baton refactor - batons no longer hack together their own attack chain, and are now integrated straight into the real attack chain. This refactor itself was done because batons don't send any attack signals, which has been annoying in the past (for swing combat). ## Changelog 🆑 Melbert refactor: Batons have been refactored again. Baton stuns now properly count as an attack, when before it was a nothing. Report any oddities, particularly in regards to harmbatonning vs normal batonning. refactor: The method of adjusting item damage mid-attack has been refactored - some affected items include the Nullblade and knives. Report any strange happenings with damage numbers. refactor: A few objects have been moved to the new interaction chain - records consoles, mawed crucible, alien weeds and space vines, hedges, restaurant portals, and some mobs - to name a few. fix: Spears only deal bonus damage against secure lockers, not all closet types (including crates) /🆑
This commit is contained in:
@@ -41,12 +41,15 @@
|
||||
var/on_stun_sound = 'sound/effects/woodhit.ogg'
|
||||
/// The volume of the above.
|
||||
var/on_stun_volume = 75
|
||||
/// Do we animate the "hit" when stunning something?
|
||||
var/stun_animation = TRUE
|
||||
/// Whether the stun attack is logged. Only relevant for abductor batons, which have different modes.
|
||||
var/log_stun_attack = TRUE
|
||||
/// Boolean on whether people with chunky fingers can use this baton.
|
||||
var/chunky_finger_usable = FALSE
|
||||
/// Boolean, if TRUE when we harmbaton someone we will also try to stun if the baton is active / not on cooldown.
|
||||
var/stun_on_harmbaton = FALSE
|
||||
|
||||
/// Text shown when trying to stun someone while the baton is on cooldown.
|
||||
var/wait_desc = ""
|
||||
|
||||
/// What term do we use to describe our baton being 'ready', or the phrase to use when var/active is TRUE.
|
||||
var/activated_word = "ready"
|
||||
@@ -96,37 +99,83 @@
|
||||
readout += "\nIt has a stun armor-piercing capability of [span_warning("[get_stun_penetration_value()]%")]."
|
||||
return readout.Join("\n")
|
||||
|
||||
/**
|
||||
* Ok, think of baton attacks like a melee attack chain:
|
||||
*
|
||||
* [/baton_attack()] comes first. It checks if the user is clumsy, if the target parried the attack and handles some messages and sounds.
|
||||
* * Depending on its return value, it'll either do a normal attack, continue to the next step or stop the attack.
|
||||
*
|
||||
* [/finalize_baton_attack()] is then called. It handles logging stuff, sound effects and calls baton_effect().
|
||||
* * The proc is also called in other situations such as stunbatons right clicking or throw impact. Basically when baton_attack()
|
||||
* * checks are either redundant or unnecessary.
|
||||
*
|
||||
* [/baton_effect()] is third in the line. It knockdowns targets, along other effects called in additional_effects_cyborg() and
|
||||
* * additional_effects_non_cyborg().
|
||||
*
|
||||
* Last but not least [/set_batoned()], which gives the target the IWASBATONED trait with REF(user) as source and then removes it
|
||||
* * after a cooldown has passed. Basically, it stops users from cheesing the cooldowns by dual wielding batons.
|
||||
*
|
||||
* TL;DR: [/baton_attack()] -> [/finalize_baton_attack()] -> [/baton_effect()] -> [/set_batoned()]
|
||||
*/
|
||||
/obj/item/melee/baton/attack(mob/living/target, mob/living/user, list/modifiers)
|
||||
add_fingerprint(user)
|
||||
switch(baton_attack(target, user, modifiers))
|
||||
if(BATON_DO_NORMAL_ATTACK)
|
||||
return ..()
|
||||
if(BATON_ATTACKING)
|
||||
finalize_baton_attack(target, user, modifiers)
|
||||
/// Checks if we can actually USE the baton. Impure
|
||||
/obj/item/melee/baton/proc/can_baton(mob/living/target, mob/living/user)
|
||||
PROTECTED_PROC(TRUE)
|
||||
if(clumsy_check(user, target))
|
||||
return FALSE
|
||||
|
||||
if(!chunky_finger_usable && ishuman(user))
|
||||
var/mob/living/carbon/human/human_user = user
|
||||
if(human_user.check_chunky_fingers() && user.is_holding(src) && !HAS_MIND_TRAIT(user, TRAIT_CHUNKYFINGERS_IGNORE_BATON))
|
||||
balloon_alert(human_user, "fingers are too big!")
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
// Stun attack
|
||||
/obj/item/melee/baton/pre_attack(atom/target, mob/living/user, list/modifiers, list/attack_modifiers)
|
||||
. = ..()
|
||||
if(. || !isliving(target))
|
||||
return .
|
||||
|
||||
if(!can_baton(target, user))
|
||||
return TRUE
|
||||
|
||||
if(!COOLDOWN_FINISHED(src, cooldown_check))
|
||||
if(wait_desc)
|
||||
balloon_alert(user, wait_desc)
|
||||
return TRUE
|
||||
|
||||
if(HAS_TRAIT_FROM(target, TRAIT_IWASBATONED, REF(user))) //no doublebaton abuse anon!
|
||||
target.balloon_alert(user, "can't stun yet!")
|
||||
return TRUE
|
||||
|
||||
if(active)
|
||||
// when we continue to attack, deal 0 (brute) damage (just stun)
|
||||
SET_ATTACK_FORCE(attack_modifiers, 0)
|
||||
MUTE_ATTACK_HITSOUND(attack_modifiers)
|
||||
HIDE_ATTACK_MESSAGES(attack_modifiers)
|
||||
return .
|
||||
|
||||
// Harm attack
|
||||
/obj/item/melee/baton/pre_attack_secondary(atom/target, mob/living/user, list/modifiers, list/attack_modifiers)
|
||||
. = ..()
|
||||
if(. != SECONDARY_ATTACK_CALL_NORMAL || !isliving(target))
|
||||
return .
|
||||
|
||||
if(!can_baton(target, user))
|
||||
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
|
||||
// call attack, NOT pre_attack
|
||||
// (so we go directly to harming)
|
||||
return SECONDARY_ATTACK_CONTINUE_CHAIN
|
||||
|
||||
// This is where stun gets applied
|
||||
/obj/item/melee/baton/afterattack(atom/target, mob/user, list/modifiers, list/attack_modifiers)
|
||||
if(!active || !COOLDOWN_FINISHED(src, cooldown_check) || HAS_TRAIT_FROM(target, TRAIT_IWASBATONED, REF(user)))
|
||||
return
|
||||
// worst check in the chain but - right click = harmbaton
|
||||
if(LAZYACCESS(modifiers, RIGHT_CLICK) && !stun_on_harmbaton)
|
||||
return
|
||||
|
||||
finalize_baton_attack(target, user, modifiers)
|
||||
|
||||
var/list/desc
|
||||
if(iscyborg(target))
|
||||
desc = get_cyborg_stun_description(target, user)
|
||||
if(!affect_cyborg)
|
||||
playsound(src, 'sound/effects/bang.ogg', 10, TRUE) //bonk
|
||||
else
|
||||
desc = get_stun_description(target, user)
|
||||
|
||||
if(desc)
|
||||
target.visible_message(desc["visible"], desc["local"], visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE)
|
||||
|
||||
/obj/item/melee/baton/apply_fantasy_bonuses(bonus)
|
||||
. = ..()
|
||||
stamina_damage = modify_fantasy_variable("stamina_damage", stamina_damage, bonus * 4)
|
||||
|
||||
|
||||
/obj/item/melee/baton/remove_fantasy_bonuses(bonus)
|
||||
stamina_damage = reset_fantasy_variable("stamina_damage", stamina_damage)
|
||||
return ..()
|
||||
@@ -155,74 +204,19 @@
|
||||
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
/obj/item/melee/baton/proc/baton_attack(mob/living/target, mob/living/user, modifiers)
|
||||
. = BATON_ATTACKING
|
||||
|
||||
if(clumsy_check(user, target))
|
||||
return BATON_ATTACK_DONE
|
||||
|
||||
if(!chunky_finger_usable && ishuman(user))
|
||||
var/mob/living/carbon/human/potential_chunky_finger_human = user
|
||||
if(potential_chunky_finger_human.check_chunky_fingers() && user.is_holding(src) && !HAS_MIND_TRAIT(user, TRAIT_CHUNKYFINGERS_IGNORE_BATON))
|
||||
balloon_alert(potential_chunky_finger_human, "fingers are too big!")
|
||||
return BATON_ATTACK_DONE
|
||||
|
||||
if(!active || LAZYACCESS(modifiers, RIGHT_CLICK))
|
||||
return BATON_DO_NORMAL_ATTACK
|
||||
|
||||
if(cooldown_check > world.time)
|
||||
var/wait_desc = get_wait_description()
|
||||
if (wait_desc)
|
||||
to_chat(user, wait_desc)
|
||||
return BATON_ATTACK_DONE
|
||||
|
||||
if(check_parried(target, user))
|
||||
return BATON_ATTACK_DONE
|
||||
|
||||
if(HAS_TRAIT_FROM(target, TRAIT_IWASBATONED, REF(user))) //no doublebaton abuse anon!
|
||||
to_chat(user, span_danger("You fumble and miss [target]!"))
|
||||
return BATON_ATTACK_DONE
|
||||
|
||||
if(stun_animation)
|
||||
user.do_attack_animation(target)
|
||||
|
||||
var/list/desc
|
||||
|
||||
if(iscyborg(target))
|
||||
if(affect_cyborg)
|
||||
desc = get_cyborg_stun_description(target, user)
|
||||
else
|
||||
desc = get_unga_dunga_cyborg_stun_description(target, user)
|
||||
playsound(get_turf(src), 'sound/effects/bang.ogg', 10, TRUE) //bonk
|
||||
. = BATON_ATTACK_DONE
|
||||
else
|
||||
desc = get_stun_description(target, user)
|
||||
|
||||
if(desc)
|
||||
target.visible_message(desc["visible"], desc["local"])
|
||||
|
||||
/obj/item/melee/baton/proc/check_parried(mob/living/carbon/human/human_target, mob/living/user)
|
||||
if (human_target.check_block(src, 0, "[user]'s [name]", MELEE_ATTACK))
|
||||
playsound(human_target, 'sound/items/weapons/genhit.ogg', 50, TRUE)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/melee/baton/proc/finalize_baton_attack(mob/living/target, mob/living/user, modifiers, in_attack_chain = TRUE)
|
||||
if(!in_attack_chain && HAS_TRAIT_FROM(target, TRAIT_IWASBATONED, REF(user)))
|
||||
return BATON_ATTACK_DONE
|
||||
|
||||
cooldown_check = world.time + cooldown
|
||||
/// Wrapper for calling "stun()" and doing relevant vfx/sfx
|
||||
/obj/item/melee/baton/proc/finalize_baton_attack(mob/living/target, mob/living/user, list/modifiers)
|
||||
PROTECTED_PROC(TRUE)
|
||||
COOLDOWN_START(src, cooldown_check, cooldown)
|
||||
if(on_stun_sound)
|
||||
playsound(get_turf(src), on_stun_sound, on_stun_volume, TRUE, -1)
|
||||
if(user)
|
||||
target.lastattacker = user.real_name
|
||||
target.lastattackerckey = user.ckey
|
||||
if(log_stun_attack)
|
||||
log_combat(user, target, "stun attacked", src)
|
||||
playsound(src, on_stun_sound, on_stun_volume, TRUE, -1)
|
||||
if(baton_effect(target, user, modifiers) && user)
|
||||
set_batoned(target, user, cooldown)
|
||||
log_combat(user, target, "stunned", src.name)
|
||||
|
||||
/obj/item/melee/baton/proc/baton_effect(mob/living/target, mob/living/user, modifiers, stun_override)
|
||||
/// The actual "stun()" of the stun baton
|
||||
/obj/item/melee/baton/proc/baton_effect(mob/living/target, mob/living/user, list/modifiers, stun_override)
|
||||
PROTECTED_PROC(TRUE)
|
||||
var/trait_check = HAS_TRAIT(target, TRAIT_BATON_RESISTANCE)
|
||||
if(iscyborg(target))
|
||||
if(!affect_cyborg)
|
||||
@@ -244,46 +238,37 @@
|
||||
SEND_SIGNAL(target, COMSIG_MOB_BATONED, user, src)
|
||||
return TRUE
|
||||
|
||||
/// Description for trying to stun when still on cooldown.
|
||||
/obj/item/melee/baton/proc/get_wait_description()
|
||||
return
|
||||
|
||||
/// Default message for stunning a living, non-cyborg mob.
|
||||
/obj/item/melee/baton/proc/get_stun_description(mob/living/target, mob/living/user)
|
||||
PROTECTED_PROC(TRUE)
|
||||
. = list()
|
||||
|
||||
.["visible"] = span_danger("[user] knocks [target] down with [src]!")
|
||||
.["local"] = span_userdanger("[user] knocks you down with [src]!")
|
||||
|
||||
return .
|
||||
|
||||
/// Default message for stunning a cyborg.
|
||||
/obj/item/melee/baton/proc/get_cyborg_stun_description(mob/living/target, mob/living/user)
|
||||
PROTECTED_PROC(TRUE)
|
||||
. = list()
|
||||
|
||||
.["visible"] = span_danger("[user] pulses [target]'s sensors with the baton!")
|
||||
.["local"] = span_danger("You pulse [target]'s sensors with the baton!")
|
||||
|
||||
return .
|
||||
|
||||
/// Default message for trying to stun a cyborg with a baton that can't stun cyborgs.
|
||||
/obj/item/melee/baton/proc/get_unga_dunga_cyborg_stun_description(mob/living/target, mob/living/user)
|
||||
. = list()
|
||||
|
||||
.["visible"] = span_danger("[user] tries to knock down [target] with [src], and predictably fails!") //look at this duuuuuude
|
||||
.["local"] = span_userdanger("[user] tries to... knock you down with [src]?") //look at the top of his head!
|
||||
|
||||
return .
|
||||
if(affect_cyborg)
|
||||
.["visible"] = span_danger("[user] pulses [target]'s sensors with the baton!")
|
||||
.["local"] = span_danger("You pulse [target]'s sensors with the baton!")
|
||||
else
|
||||
.["visible"] = span_danger("[user] tries to knock down [target] with [src], and predictably fails!") //look at this duuuuuude
|
||||
.["local"] = span_userdanger("[user] tries to... knock you down with [src]?") //look at the top of his head!
|
||||
|
||||
/// Contains any special effects that we apply to living, non-cyborg mobs we stun. Does not include applying a knockdown, dealing stamina damage, etc.
|
||||
/obj/item/melee/baton/proc/additional_effects_non_cyborg(mob/living/target, mob/living/user)
|
||||
PROTECTED_PROC(TRUE)
|
||||
return
|
||||
|
||||
/// Contains any special effects that we apply to cyborgs we stun. Does not include flashing the cyborg's screen, hardstunning them, etc.
|
||||
/obj/item/melee/baton/proc/additional_effects_cyborg(mob/living/target, mob/living/user)
|
||||
PROTECTED_PROC(TRUE)
|
||||
return
|
||||
|
||||
/// Used in marking a target as being hit by a baton
|
||||
/obj/item/melee/baton/proc/set_batoned(mob/living/target, mob/living/user, cooldown)
|
||||
PRIVATE_PROC(TRUE)
|
||||
if(!cooldown)
|
||||
return
|
||||
var/user_ref = REF(user) // avoids harddels.
|
||||
@@ -293,7 +278,7 @@
|
||||
/obj/item/melee/baton/proc/clumsy_check(mob/living/user, mob/living/intented_target)
|
||||
if(!active || !HAS_TRAIT(user, TRAIT_CLUMSY) || prob(50))
|
||||
return FALSE
|
||||
user.visible_message(span_danger("[user] accidentally hits [user.p_them()]self over the head with [src]! What a doofus!"), span_userdanger("You accidentally hit yourself over the head with [src]!"))
|
||||
user.visible_message(span_danger("[user] accidentally hits [user.p_them()]self over the head with [src]! What a doofus!"), span_userdanger("You accidentally hit yourself over the head with [src]!"), visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE)
|
||||
|
||||
if(iscyborg(user))
|
||||
if(affect_cyborg)
|
||||
@@ -301,9 +286,9 @@
|
||||
user.Paralyze(clumsy_knockdown_time)
|
||||
additional_effects_cyborg(user, user) // user is the target here
|
||||
if(on_stun_sound)
|
||||
playsound(get_turf(src), on_stun_sound, on_stun_volume, TRUE, -1)
|
||||
playsound(src, on_stun_sound, on_stun_volume, TRUE, -1)
|
||||
else
|
||||
playsound(get_turf(src), 'sound/effects/bang.ogg', 10, TRUE)
|
||||
playsound(src, 'sound/effects/bang.ogg', 10, TRUE)
|
||||
else
|
||||
//straight up always force say for clumsy humans
|
||||
if(ishuman(user))
|
||||
@@ -313,14 +298,11 @@
|
||||
user.apply_damage(stamina_damage, STAMINA)
|
||||
additional_effects_non_cyborg(user, user) // user is the target here
|
||||
if(on_stun_sound)
|
||||
playsound(get_turf(src), on_stun_sound, on_stun_volume, TRUE, -1)
|
||||
|
||||
user.apply_damage(2*force, BRUTE, BODY_ZONE_HEAD, attacking_item = src)
|
||||
playsound(src, on_stun_sound, on_stun_volume, TRUE, -1)
|
||||
|
||||
user.apply_damage(2 * force, BRUTE, BODY_ZONE_HEAD, attacking_item = src)
|
||||
log_combat(user, user, "accidentally stun attacked [user.p_them()]self due to their clumsiness", src)
|
||||
if(stun_animation)
|
||||
user.do_attack_animation(user)
|
||||
return
|
||||
user.do_attack_animation(user)
|
||||
|
||||
/// Handles the penetration value of our baton, called during baton_effect()
|
||||
/obj/item/melee/baton/proc/get_stun_penetration_value()
|
||||
@@ -461,6 +443,7 @@
|
||||
stun_armour_penetration = 40
|
||||
clumsy_knockdown_time = 24 SECONDS
|
||||
affect_cyborg = TRUE
|
||||
wait_desc = "still charging!"
|
||||
on_stun_sound = 'sound/items/weapons/contractor_baton/contractorbatonhit.ogg'
|
||||
unfolded_drop_sound = 'sound/items/baton/contractor_baton_unfolded_pickup.ogg'
|
||||
unfolded_pickup_sound = 'sound/items/baton/contractor_baton_unfolded_pickup.ogg'
|
||||
@@ -469,9 +452,6 @@
|
||||
on_sound = 'sound/items/weapons/contractorbatonextend.ogg'
|
||||
active_force = 16
|
||||
|
||||
/obj/item/melee/baton/telescopic/contractor_baton/get_wait_description()
|
||||
return span_danger("The baton is still charging!")
|
||||
|
||||
/obj/item/melee/baton/telescopic/contractor_baton/additional_effects_non_cyborg(mob/living/target, mob/living/user)
|
||||
. = ..()
|
||||
target.set_jitter_if_lower(40 SECONDS)
|
||||
@@ -504,6 +484,8 @@
|
||||
on_stun_sound = 'sound/items/weapons/egloves.ogg'
|
||||
on_stun_volume = 50
|
||||
active = FALSE
|
||||
stun_on_harmbaton = TRUE
|
||||
wait_desc = "still charging!"
|
||||
activated_word = "activated"
|
||||
context_living_rmb_active = "Harmful Stun"
|
||||
light_range = 1.5
|
||||
@@ -553,7 +535,7 @@
|
||||
/obj/item/melee/baton/security/suicide_act(mob/living/user)
|
||||
if(cell?.charge && active)
|
||||
user.visible_message(span_suicide("[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide!"))
|
||||
attack(user, user)
|
||||
finalize_baton_attack(user, user)
|
||||
return FIRELOSS
|
||||
else
|
||||
user.visible_message(span_suicide("[user] is shoving \the [src] down their throat! It looks like [user.p_theyre()] trying to commit suicide!"))
|
||||
@@ -624,7 +606,7 @@
|
||||
tool.play_tool_sound(src)
|
||||
return TRUE
|
||||
|
||||
/obj/item/melee/baton/security/attackby(obj/item/item, mob/user, list/modifiers)
|
||||
/obj/item/melee/baton/security/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
|
||||
if(istype(item, /obj/item/stock_parts/power_store/cell))
|
||||
var/obj/item/stock_parts/power_store/cell/active_cell = item
|
||||
if(cell)
|
||||
@@ -727,18 +709,20 @@
|
||||
SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
|
||||
deductcharge(cell_hit_cost)
|
||||
|
||||
/// Handles prodding targets with turned off stunbatons and right clicking stun'n'bash
|
||||
/obj/item/melee/baton/security/baton_attack(mob/living/target, mob/living/user, modifiers)
|
||||
/obj/item/melee/baton/security/pre_attack(atom/target, mob/living/user, list/modifiers, list/attack_modifiers)
|
||||
. = ..()
|
||||
if(. != BATON_DO_NORMAL_ATTACK)
|
||||
return
|
||||
if(LAZYACCESS(modifiers, RIGHT_CLICK))
|
||||
if(active && cooldown_check <= world.time && !check_parried(target, user))
|
||||
finalize_baton_attack(target, user, modifiers, in_attack_chain = FALSE)
|
||||
else if(!user.combat_mode)
|
||||
target.visible_message(span_warning("[user] prods [target] with [src]. Luckily it was off."), \
|
||||
span_warning("[user] prods you with [src]. Luckily it was off."))
|
||||
return BATON_ATTACK_DONE
|
||||
if(. || !isliving(target))
|
||||
return .
|
||||
|
||||
if(!active && !user.combat_mode)
|
||||
target.visible_message(
|
||||
span_warning("[user] prods [target] with [src]. Luckily it was off."),
|
||||
span_warning("[user] prods you with [src]. Luckily it was off."),
|
||||
visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE,
|
||||
)
|
||||
return TRUE
|
||||
|
||||
return .
|
||||
|
||||
/obj/item/melee/baton/security/baton_effect(mob/living/target, mob/living/user, modifiers, stun_override)
|
||||
if(iscyborg(loc))
|
||||
@@ -778,25 +762,22 @@
|
||||
if(!trait_check)
|
||||
target.Knockdown(knockdown_time)
|
||||
|
||||
/obj/item/melee/baton/security/get_wait_description()
|
||||
return span_danger("The baton is still charging!")
|
||||
|
||||
/obj/item/melee/baton/security/get_stun_description(mob/living/target, mob/living/user)
|
||||
. = list()
|
||||
|
||||
.["visible"] = span_danger("[user] stuns [target] with [src]!")
|
||||
.["local"] = span_userdanger("[user] stuns you with [src]!")
|
||||
|
||||
/obj/item/melee/baton/security/get_unga_dunga_cyborg_stun_description(mob/living/target, mob/living/user)
|
||||
. = list()
|
||||
|
||||
.["visible"] = span_danger("[user] tries to stun [target] with [src], and predictably fails!")
|
||||
.["local"] = span_userdanger("[user] tries to... stun you with [src]?")
|
||||
/obj/item/melee/baton/security/get_cyborg_stun_description(mob/living/target, mob/living/user)
|
||||
. = ..()
|
||||
if(!affect_cyborg)
|
||||
.["visible"] = span_danger("[user] tries to stun [target] with [src], and predictably fails!")
|
||||
.["local"] = span_userdanger("[user] tries to... stun you with [src]?")
|
||||
|
||||
/obj/item/melee/baton/security/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
. = ..()
|
||||
if(!. && active && prob(throw_stun_chance) && isliving(hit_atom))
|
||||
finalize_baton_attack(hit_atom, throwingdatum.get_thrower(), in_attack_chain = FALSE)
|
||||
finalize_baton_attack(hit_atom, throwingdatum.get_thrower())
|
||||
|
||||
/obj/item/melee/baton/security/emp_act(severity)
|
||||
. = ..()
|
||||
@@ -857,7 +838,7 @@
|
||||
. = ..()
|
||||
sparkler = new (src)
|
||||
|
||||
/obj/item/melee/baton/security/cattleprod/attackby(obj/item/item, mob/user, list/modifiers)//handles sticking a crystal onto a stunprod to make an improved cattleprod
|
||||
/obj/item/melee/baton/security/cattleprod/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)//handles sticking a crystal onto a stunprod to make an improved cattleprod
|
||||
if(!istype(item, /obj/item/stack))
|
||||
return ..()
|
||||
|
||||
@@ -889,9 +870,9 @@
|
||||
var/obj/item/melee/baton/security/cattleprod/brand_new_prod = new our_prod(user.loc)
|
||||
user.put_in_hands(brand_new_prod)
|
||||
|
||||
/obj/item/melee/baton/security/cattleprod/baton_effect()
|
||||
/obj/item/melee/baton/security/cattleprod/can_baton(mob/living/target, mob/living/user)
|
||||
if(!sparkler.activate())
|
||||
return BATON_ATTACK_DONE
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/baton/security/cattleprod/Destroy()
|
||||
@@ -919,15 +900,7 @@
|
||||
|
||||
/obj/item/melee/baton/security/boomerang/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/boomerang, throw_range+2, TRUE)
|
||||
|
||||
/obj/item/melee/baton/security/boomerang/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
if(!active)
|
||||
return ..()
|
||||
var/caught = hit_atom.hitby(src, skipcatch = FALSE, hitpush = FALSE, throwingdatum = throwingdatum)
|
||||
var/mob/thrown_by = throwingdatum.get_thrower()
|
||||
if(isliving(hit_atom) && !iscyborg(hit_atom) && !caught && prob(throw_stun_chance))//if they are a living creature and they didn't catch it
|
||||
finalize_baton_attack(hit_atom, thrown_by, in_attack_chain = FALSE)
|
||||
AddComponent(/datum/component/boomerang, throw_range + 2, TRUE)
|
||||
|
||||
/obj/item/melee/baton/security/boomerang/loaded //Same as above, comes with a cell.
|
||||
preload_cell_type = /obj/item/stock_parts/power_store/cell/high
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
final_block_chance = 0 //Don't bring a sword to a gunfight, and also you aren't going to really block someone full body tackling you with a sword
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/beesword/afterattack(atom/target, mob/user, list/modifiers)
|
||||
/obj/item/melee/beesword/afterattack(atom/target, mob/user, list/modifiers, list/attack_modifiers)
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/carbon_target = target
|
||||
carbon_target.reagents.add_reagent(/datum/reagent/toxin, 4)
|
||||
@@ -292,7 +292,7 @@
|
||||
if(!isspaceturf(turf))
|
||||
consume_turf(turf)
|
||||
|
||||
/obj/item/melee/supermatter_sword/pre_attack(atom/target, mob/living/user, list/modifiers)
|
||||
/obj/item/melee/supermatter_sword/pre_attack(atom/target, mob/living/user, list/modifiers, list/attack_modifiers)
|
||||
. = ..()
|
||||
if(.)
|
||||
return .
|
||||
@@ -386,7 +386,7 @@
|
||||
attack_verb_simple = list("flog", "whip", "lash", "discipline")
|
||||
hitsound = 'sound/items/weapons/whip.ogg'
|
||||
|
||||
/obj/item/melee/curator_whip/afterattack(atom/target, mob/user, list/modifiers)
|
||||
/obj/item/melee/curator_whip/afterattack(atom/target, mob/user, list/modifiers, list/attack_modifiers)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/human_target = target
|
||||
human_target.drop_all_held_items()
|
||||
|
||||
Reference in New Issue
Block a user