adds more support to stuff
This commit is contained in:
@@ -29,10 +29,11 @@
|
||||
#define EFFECT_DROWSY "drowsy"
|
||||
#define EFFECT_JITTER "jitter"
|
||||
|
||||
// mob/living/var/combat_flags variable.
|
||||
/// Default combat flags for those affected by sprinting (combat mode has been made into its own component)
|
||||
#define COMBAT_FLAGS_DEFAULT NONE
|
||||
#define COMBAT_FLAGS_DEFAULT (COMBAT_FLAG_PARRY_CAPABLE | COMBAT_FLAG_BLOCK_CAPABLE)
|
||||
/// Default combat flags for everyone else (so literally everyone but humans).
|
||||
#define COMBAT_FLAGS_SPRINT_EXEMPT (COMBAT_FLAG_SPRINT_ACTIVE | COMBAT_FLAG_SPRINT_TOGGLED | COMBAT_FLAG_SPRINT_FORCED)
|
||||
#define COMBAT_FLAGS_SPRINT_EXEMPT (COMBAT_FLAG_SPRINT_ACTIVE | COMBAT_FLAG_SPRINT_TOGGLED | COMBAT_FLAG_SPRINT_FORCED | COMBAT_FLAG_PARRY_CAPABLE | COMBAT_FLAG_BLOCK_CAPABLE)
|
||||
|
||||
/// The user wants sprint mode on
|
||||
#define COMBAT_FLAG_SPRINT_TOGGLED (1<<0)
|
||||
@@ -50,6 +51,16 @@
|
||||
#define COMBAT_FLAG_SOFT_STAMCRIT (1<<6)
|
||||
/// Force sprint mode on at all times, overrides everything including sprint disable traits.
|
||||
#define COMBAT_FLAG_SPRINT_FORCED (1<<7)
|
||||
/// This mob is capable of using the active parrying system.
|
||||
#define COMBAT_FLAG_PARRY_CAPABLE (1<<8)
|
||||
/// This mob is capable of using the active blocking system.
|
||||
#define COMBAT_FLAG_BLOCK_CAPABLE (1<<9)
|
||||
/// This mob is capable of unarmed parrying
|
||||
#define COMBAT_FLAG_UNARMED_PARRY (1<<10)
|
||||
/// This mob is currently actively blocking
|
||||
#define COMBAT_FLAG_ACTIVE_BLOCKING (1<<11)
|
||||
/// This mob is currently starting an active block
|
||||
#define COMBAT_FLAG_ACTIVE_BLOCK_STARTING (1<<12)
|
||||
|
||||
// Helpers for getting someone's stamcrit state. Cast to living.
|
||||
#define NOT_STAMCRIT 0
|
||||
|
||||
@@ -37,6 +37,14 @@ GLOBAL_LIST_INIT(dir2blockdir, list(
|
||||
#define PARRY_ACTIVE 2
|
||||
#define PARRY_SPINDOWN 3
|
||||
|
||||
// /datum/block_parry_data/var/parry_flags
|
||||
/// Default handling for audio/visual feedback
|
||||
#define PARRY_DEFAULT_HANDLE_FEEDBACK (1<<0)
|
||||
/// Lock sprinting while parrying
|
||||
#define PARRY_LOCK_SPRINTING (1<<1)
|
||||
/// Lock attacking while parrying
|
||||
#define PARRY_LOCK_ATTACKING (1<<2)
|
||||
|
||||
/// Parry effects.
|
||||
/// List association must be one of the things underneath
|
||||
#define PARRY_REFLEX_COUNTERATTACK "reflex_counter"
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
med_hud_set_status()
|
||||
|
||||
/mob/living/Destroy()
|
||||
end_parry_sequence()
|
||||
stop_active_blocking()
|
||||
if(LAZYLEN(status_effects))
|
||||
for(var/s in status_effects)
|
||||
var/datum/status_effect/S = s
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
var/full_parry_duration = data.parry_time_windup + data.parry_time_active + data.parry_time_spindown
|
||||
// no system in place to "fallback" if out of the 3 the top priority one can't parry due to constraints but something else can.
|
||||
// can always implement it later, whatever.
|
||||
if(data.parry_respect_clickdelay && (next_move > world.time))
|
||||
if((data.parry_respect_clickdelay && (next_move > world.time)) || ((parry_end_time_last + data.parry_cooldown) > world.time))
|
||||
to_chat(src, "<span class='warning'>You are not ready to parry (again)!</span>")
|
||||
return
|
||||
// Point of no return, make sure everything is set.
|
||||
@@ -50,6 +50,10 @@
|
||||
parry_start_time = world.time
|
||||
successful_parries = list()
|
||||
addtimer(CALLBACK(src, .proc/end_parry_sequence), full_parry_duration)
|
||||
if(data.parry_flags & PARRY_LOCK_ATTACKING)
|
||||
ADD_TRAIT(src, TRAIT_MOBILITY_NOUSE, ACTIVE_PARRY_TRAIT)
|
||||
if(data.parry_flags & PARRY_LOCK_SPRINTING)
|
||||
ADD_TRAIT(src, TRAIT_SPRINT_LOCKED, ACTIVE_PARRY_TRAIT)
|
||||
handle_parry_starting_effects(data)
|
||||
return TRUE
|
||||
|
||||
@@ -59,9 +63,16 @@
|
||||
/mob/living/proc/end_parry_sequence()
|
||||
if(!parrying)
|
||||
return
|
||||
if(parry_visual_effect)
|
||||
QDEL_NULL(parry_visual_effect)
|
||||
var/datum/block_parry_data/data = get_parry_data()
|
||||
var/list/effect_text = list()
|
||||
if(!length(successful_parries)) // didn't parry anything successfully
|
||||
var/successful = FALSE
|
||||
for(var/efficiency in successful_parries)
|
||||
if(efficiency >= data.parry_efficiency_considered_successful)
|
||||
successful = TRUE
|
||||
break
|
||||
if(!successful) // didn't parry anything successfully
|
||||
if(data.parry_failed_stagger_duration)
|
||||
Stagger(data.parry_failed_stagger_duration)
|
||||
effect_text += "staggering themselves"
|
||||
@@ -78,7 +89,7 @@
|
||||
*/
|
||||
/mob/living/proc/handle_parry_starting_effects(datum/block_parry_data/data)
|
||||
playsound(src, data.parry_start_sound, 75, 1)
|
||||
new /obj/effect/abstract/parry/main(null, data, src)
|
||||
parry_visual_effect = new /obj/effect/abstract/parry/main(null, data, src, data.parry_effect_icon_state)
|
||||
switch(parrying)
|
||||
if(ITEM_PARRY)
|
||||
visible_message("<span class='warning'>[src] swings [active_parry_item]!</span>")
|
||||
@@ -185,7 +196,7 @@
|
||||
/// same return values as normal blocking, called with absolute highest priority in the block "chain".
|
||||
/mob/living/proc/run_parry(atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list = list())
|
||||
var/stage = get_parry_stage()
|
||||
if(stage == NOT_PARRYING)
|
||||
if(stage != PARRY_ACTIVE)
|
||||
return BLOCK_NONE
|
||||
if(!CHECK_MOBILITY(src, MOBILITY_USE))
|
||||
to_chat(src, "<span class='warning'>Your parry is interrupted!</span>")
|
||||
@@ -208,10 +219,14 @@
|
||||
. |= BLOCK_SHOULD_PARTIAL_MITIGATE
|
||||
if(isnull(return_list[BLOCK_RETURN_MITIGATION_PERCENT])) // if one of the on_active_parry procs overrode. We don't have to worry about interference since parries are the first thing checked in the [do_run_block()] sequence.
|
||||
return_list[BLOCK_RETURN_MITIGATION_PERCENT] = clamp(efficiency, 0, 100) // do not allow > 100% or < 0% for now.
|
||||
var/list/effect_text = run_parry_countereffects(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency)
|
||||
if(data.parry_default_handle_feedback)
|
||||
var/list/effect_text
|
||||
if(efficiency >= data.parry_efficiency_to_counterattack)
|
||||
run_parry_countereffects(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency)
|
||||
if(data.parry_flags & PARRY_DEFAULT_HANDLE_FEEDBACK)
|
||||
handle_parry_feedback(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency, effect_text)
|
||||
successful_parries += efficiency
|
||||
if(length(successful_parries) >= data.parry_max_attacks)
|
||||
end_parry_sequence()
|
||||
|
||||
/mob/living/proc/handle_parry_feedback(atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list = list(), parry_efficiency, list/effect_text)
|
||||
var/datum/block_parry_data/data = get_parry_data()
|
||||
@@ -283,10 +298,10 @@
|
||||
|
||||
/obj/effect/abstract/parry/main
|
||||
name = null
|
||||
icon_state = "parry_bm_hold"
|
||||
|
||||
/obj/effect/abstract/parry/main/Initialize(mapload, datum/block_parry_data/data, mob/living/owner)
|
||||
/obj/effect/abstract/parry/main/Initialize(mapload, datum/block_parry_data/data, mob/living/owner, icon_state)
|
||||
. = ..()
|
||||
src.icon_state = icon_state
|
||||
if(owner)
|
||||
attach_to(owner)
|
||||
if(data)
|
||||
|
||||
@@ -93,6 +93,8 @@ GLOBAL_LIST_EMPTY(block_parry_data)
|
||||
var/parry_stamina_cost = 5
|
||||
/// Attack types we can block
|
||||
var/parry_attack_types = ALL
|
||||
/// Parry flags
|
||||
var/parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK | PARRY_LOCK_ATTACKING
|
||||
|
||||
/// Parry windup duration in deciseconds. 0 to this is windup, afterwards is main stage.
|
||||
var/parry_time_windup = 2
|
||||
@@ -116,8 +118,16 @@ GLOBAL_LIST_EMPTY(block_parry_data)
|
||||
var/list/parry_data = list(
|
||||
PARRY_REFLEX_COUNTERATTACK = PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN
|
||||
)
|
||||
/// Enable default handling of audio/visual feedback
|
||||
var/parry_default_handle_feedback = TRUE
|
||||
/// Efficiency must be at least this to be considered successful
|
||||
var/parry_efficiency_considered_successful = 0.1
|
||||
/// Efficiency must be at least this to run automatic counterattack
|
||||
var/parry_efficiency_to_counterattack = 0.1
|
||||
/// Maximum attacks to parry successfully or unsuccessfully during active period, hitting this immediately ends the sequence.
|
||||
var/parry_max_attacks = INFINITY
|
||||
/// Visual icon state override for parrying
|
||||
var/parry_effect_icon_state = "parry_bm_hold"
|
||||
/// Parrying cooldown, separate of clickdelay. It must be this much deciseconds since their last parry for them to parry with this object.
|
||||
var/parry_cooldown = 0
|
||||
/// Parry start sound
|
||||
var/parry_start_sound = 'sound/block_parry/sfx-parry.ogg'
|
||||
/// Sounds for parrying
|
||||
|
||||
@@ -29,14 +29,8 @@
|
||||
|
||||
// Combat - Blocking/Parrying system
|
||||
/// Our block_parry_data for unarmed blocks/parries. Currently only used for parrying, as unarmed block isn't implemented yet. YOU MUST RUN [get_block_parry_data(this)] INSTEAD OF DIRECTLY ACCESSING!
|
||||
var/datum/block_parry_data/block_parry_data
|
||||
var/datum/block_parry_data/block_parry_data = /datum/block_parry_data // defaults to *something* because [combat_flags] dictates whether or not we can unarmed block/parry.
|
||||
// Blocking
|
||||
/// Whether or not the user is actively blocking.
|
||||
var/active_blocking = FALSE
|
||||
/// Whether or not we can actively block. Disabled by default since a lot of mobs do not support stamina damage. Imagine a dextrous guardian with a shield..
|
||||
var/active_block_enabled = FALSE
|
||||
/// Whether or not we are in the process of raising our shield/whatever.
|
||||
var/active_block_starting = FALSE
|
||||
/// The item the user is actively blocking with if any.
|
||||
var/obj/item/active_block_item
|
||||
// Parrying
|
||||
@@ -46,8 +40,11 @@
|
||||
var/obj/item/active_parry_item
|
||||
/// world.time of parry action start
|
||||
var/parry_start_time = 0
|
||||
/// Whether or not we can unarmed parry
|
||||
var/parry_while_unarmed = FALSE
|
||||
/// Current parry effect.
|
||||
var/obj/effect/abstract/parry/parry_visual_effect
|
||||
/// world.time of last parry end
|
||||
var/parry_end_time_last = 0
|
||||
#warn implement above
|
||||
/// Successful parries within the current parry cycle. It's a list of efficiency percentages.
|
||||
var/list/successful_parries
|
||||
|
||||
|
||||
Reference in New Issue
Block a user