adds more support to stuff

This commit is contained in:
kevinz000
2020-05-30 00:35:17 -07:00
parent f8741b6a0b
commit ae9fc5789d
6 changed files with 64 additions and 21 deletions
+13 -2
View File
@@ -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
+8
View File
@@ -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"
+2
View File
@@ -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
+23 -8
View File
@@ -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
+6 -9
View File
@@ -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