mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-17 19:14:15 +01:00
Adds a counterattack for sheathed weapons (#93994)
This commit is contained in:
@@ -588,10 +588,19 @@
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
interaction_flags_click = parent_type::interaction_flags_click | NEED_DEXTERITY | NEED_HANDS
|
||||
var/stored_blade
|
||||
actions_types = list(/datum/action/innate/blade_counter)
|
||||
action_slots = ITEM_SLOT_BELT
|
||||
COOLDOWN_DECLARE(resheath_cooldown)
|
||||
COOLDOWN_DECLARE(full_ability_cooldown)
|
||||
|
||||
/obj/item/storage/belt/sheath/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
RegisterSignal(src, COMSIG_ATOM_STORED_ITEM, PROC_REF(post_resheath))
|
||||
|
||||
/obj/item/storage/belt/sheath/Destroy(force)
|
||||
. = ..()
|
||||
UnregisterSignal(src, COMSIG_ATOM_STORED_ITEM)
|
||||
|
||||
/obj/item/storage/belt/sheath/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -623,6 +632,103 @@
|
||||
new stored_blade(src)
|
||||
update_appearance()
|
||||
|
||||
/obj/item/storage/belt/sheath/proc/post_resheath()
|
||||
SIGNAL_HANDLER
|
||||
COOLDOWN_START(src, resheath_cooldown, 10 SECONDS)
|
||||
|
||||
/datum/action/innate/blade_counter
|
||||
name = "Counterattack"
|
||||
desc = "Anticipate an enemy's attack and strike back with your sheathed blade."
|
||||
button_icon = 'icons/mob/actions/actions_spells.dmi'
|
||||
button_icon_state = "declaration"
|
||||
ranged_mousepointer = 'icons/effects/mouse_pointers/honorbound.dmi'
|
||||
|
||||
enable_text = "You prepare to counterattack a target..."
|
||||
disable_text = "You relax your stance."
|
||||
|
||||
click_action = TRUE
|
||||
|
||||
var/datum/weakref/eyed_fool
|
||||
|
||||
/datum/action/innate/blade_counter/IsAvailable(feedback = TRUE)
|
||||
if(!isliving(owner))
|
||||
return FALSE
|
||||
var/obj/item/storage/belt/sheath/owners_sheath = target
|
||||
if(!COOLDOWN_FINISHED(owners_sheath, full_ability_cooldown))
|
||||
if(feedback)
|
||||
to_chat(owner, span_warning("You failed a counterattack too recently!"))
|
||||
return FALSE
|
||||
if(!length(owners_sheath.contents))
|
||||
if(feedback)
|
||||
to_chat(owner, span_warning("Your sheath is empty!"))
|
||||
return FALSE
|
||||
if(!COOLDOWN_FINISHED(owners_sheath, resheath_cooldown))
|
||||
if(feedback)
|
||||
to_chat(owner, span_warning("You only just resheathed your blade!"))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/action/innate/blade_counter/proc/final_checks(atom/cast_on)
|
||||
if(!isliving(cast_on))
|
||||
return FALSE
|
||||
if(owner == cast_on)
|
||||
to_chat(owner, span_warning("You can't counterattack yourself!"))
|
||||
return FALSE
|
||||
var/mob/living/target = cast_on
|
||||
if(!target.mind)
|
||||
to_chat(owner, span_warning("They are too unpredictable to counterattack!"))
|
||||
return FALSE
|
||||
var/obj/item/storage/belt/sheath/oursheath = target
|
||||
if(!length(oursheath.contents))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/action/innate/blade_counter/do_ability(mob/living/swordsman, mob/living/cast_on)
|
||||
if(!final_checks(cast_on))
|
||||
return FALSE
|
||||
var/obj/item/storage/belt/sheath/used_sheath = target
|
||||
RegisterSignal(swordsman, COMSIG_LIVING_CHECK_BLOCK, PROC_REF(counter_attack))
|
||||
swordsman.Immobilize(1 SECONDS)
|
||||
eyed_fool = WEAKREF(cast_on)
|
||||
swordsman.visible_message(span_danger("[swordsman] widens [p_their(swordsman)] stance, [p_their(swordsman)] hand hovering over \the [used_sheath]!"), span_notice("You prepare to counterattack [cast_on]!"))
|
||||
addtimer(CALLBACK(src, PROC_REF(relax), swordsman), 1 SECONDS)
|
||||
COOLDOWN_START(used_sheath, full_ability_cooldown, 60 SECONDS)
|
||||
unset_ranged_ability(swordsman)
|
||||
|
||||
#define COUNTERMULTIPLIER 3
|
||||
|
||||
/datum/action/innate/blade_counter/proc/counter_attack(mob/living/forward_thinker, atom/attackingthing, damage, attack_text, attack_type)
|
||||
SIGNAL_HANDLER
|
||||
var/obj/item/storage/belt/sheath/used_sheath = target
|
||||
if(!used_sheath || !length(used_sheath.contents) || (attack_type != MELEE_ATTACK && attack_type != UNARMED_ATTACK))
|
||||
return FAILED_BLOCK
|
||||
|
||||
var/obj/item/justicetool = used_sheath.contents[1]
|
||||
var/mob/living/fool = isliving(attackingthing) ? attackingthing : attackingthing.loc
|
||||
if(used_sheath.loc != forward_thinker || fool != eyed_fool.resolve() || !forward_thinker.put_in_active_hand(justicetool))
|
||||
return FAILED_BLOCK
|
||||
var/obj/item/bodypart/offending_hand = fool.get_active_hand()
|
||||
fool.apply_damage(
|
||||
damage = justicetool.force * COUNTERMULTIPLIER,
|
||||
damagetype = justicetool.damtype,
|
||||
def_zone = offending_hand,
|
||||
blocked = fool.run_armor_check(offending_hand, MELEE, armour_penetration = justicetool.armour_penetration, silent = TRUE),
|
||||
wound_bonus = justicetool.wound_bonus * COUNTERMULTIPLIER,
|
||||
exposed_wound_bonus = justicetool.exposed_wound_bonus * COUNTERMULTIPLIER,
|
||||
sharpness = justicetool.sharpness,
|
||||
attack_direction = get_dir(forward_thinker, fool),
|
||||
attacking_item = justicetool,
|
||||
)
|
||||
playsound(forward_thinker, 'sound/items/unsheath.ogg', 50, TRUE)
|
||||
forward_thinker.visible_message(span_danger("[forward_thinker] swiftly draws \the [justicetool] and strikes [fool] during [p_their(fool)] attack!"), span_notice("You swiftly draw \the [justicetool] and counter-attack [fool]!"))
|
||||
COOLDOWN_RESET(used_sheath, full_ability_cooldown)
|
||||
return SUCCESSFUL_BLOCK
|
||||
|
||||
#undef COUNTERMULTIPLIER
|
||||
|
||||
/datum/action/innate/blade_counter/proc/relax(mob/living/holder)
|
||||
UnregisterSignal(holder, COMSIG_LIVING_CHECK_BLOCK)
|
||||
|
||||
/obj/item/storage/belt/sheath/sabre
|
||||
name = "sabre sheath"
|
||||
desc = "An ornate sheath designed to hold an officer's blade."
|
||||
|
||||
Reference in New Issue
Block a user