diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 89a4570e8d..2e8641b43e 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -14,6 +14,7 @@ blocks_emissive = EMISSIVE_BLOCK_UNIQUE block_parry_data = /datum/block_parry_data/unarmed/human + default_block_parry_data = /datum/block_parry_data/unarmed/pugilist //Hair colour and style var/hair_color = "000" @@ -98,20 +99,54 @@ parry_failed_clickcd_duration = 0.4 parry_data = list( // yeah it's snowflake - "HUMAN_PARRY_STAGGER" = 3 SECONDS, - "HUMAN_PARRY_PUNCH" = TRUE, - "HUMAN_PARRY_MININUM_EFFICIENCY" = 0.9 + "UNARMED_PARRY_STAGGER" = 3 SECONDS, + "UNARMED_PARRY_PUNCH" = TRUE, + "UNARMED_PARRY_MININUM_EFFICIENCY" = 90 ) -/mob/living/carbon/human/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time) +/mob/living/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time) var/datum/block_parry_data/D = return_block_parry_datum(block_parry_data) + . = ..() if(!owner.Adjacent(attacker)) - return ..() - if(parry_efficiency < D.parry_data["HUMAN_PARRY_MINIMUM_EFFICIENCY"]) - return ..() + return + if(parry_efficiency < D.parry_data["UNARMED_PARRY_MINIMUM_EFFICIENCY"]) + return visible_message("[src] strikes back perfectly at [attacker], staggering them!") - if(D.parry_data["HUMAN_PARRY_PUNCH"]) + if(D.parry_data["UNARMED_PARRY_PUNCH"]) UnarmedAttack(attacker, TRUE, INTENT_HARM, ATTACK_IS_PARRY_COUNTERATTACK | ATTACK_IGNORE_ACTION | ATTACK_IGNORE_CLICKDELAY | NO_AUTO_CLICKDELAY_HANDLING) var/mob/living/L = attacker if(istype(L)) - L.Stagger(D.parry_data["HUMAN_PARRY_STAGGER"]) + L.Stagger(D.parry_data["UNARMED_PARRY_STAGGER"]) + +/// Unarmed parry data for pugilists +/datum/block_parry_data/unarmed/pugilist + parry_respect_clickdelay = FALSE + parry_stamina_cost = 4 + parry_attack_types = ATTACK_TYPE_UNARMED | ATTACK_TYPE_PROJECTILE | ATTACK_TYPE_TACKLE | ATTACK_TYPE_THROWN | ATTACK_TYPE_MELEE + parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK | PARRY_LOCK_ATTACKING + + parry_time_windup = 0 + parry_time_spindown = 0 + parry_time_active = 5 + + parry_time_perfect = 1.5 + parry_time_perfect_leeway = 1.5 + parry_imperfect_falloff_percent = 20 + parry_efficiency_perfect = 100 + parry_efficiency_perfect_override = list( + ATTACK_TYPE_PROJECTILE_TEXT = 60, + ) + + parry_efficiency_considered_successful = 0.01 + parry_efficiency_to_counterattack = 0.01 + parry_max_attacks = INFINITY + parry_failed_cooldown_duration = 1.5 SECONDS + parry_failed_stagger_duration = 0 + parry_cooldown = 0 + parry_failed_clickcd_duration = 0.8 + + parry_data = list( // yeah it's snowflake + "UNARMED_PARRY_STAGGER" = 3 SECONDS, + "UNARMED_PARRY_PUNCH" = TRUE, + "UNARMED_PARRY_MININUM_EFFICIENCY" = 90 + ) diff --git a/code/modules/mob/living/living_active_parry.dm b/code/modules/mob/living/living_active_parry.dm index 7353add745..16855d6f22 100644 --- a/code/modules/mob/living/living_active_parry.dm +++ b/code/modules/mob/living/living_active_parry.dm @@ -127,7 +127,7 @@ handle_parry_ending_effects(data, effect_text) parrying = NOT_PARRYING parry_start_time = 0 - parry_end_time_last = world.time + parry_end_time_last = world.time + (successful? 0 : data.parry_failed_cooldown_duration) successful_parries = null /** diff --git a/code/modules/mob/living/living_blocking_parrying.dm b/code/modules/mob/living/living_blocking_parrying.dm index 08ef674b33..e290956873 100644 --- a/code/modules/mob/living/living_blocking_parrying.dm +++ b/code/modules/mob/living/living_blocking_parrying.dm @@ -154,6 +154,8 @@ GLOBAL_LIST_EMPTY(block_parry_data) var/parry_failed_stagger_duration = 3.5 SECONDS /// Clickdelay duration post-parry if you fail to parry an attack var/parry_failed_clickcd_duration = 2 SECONDS + /// Parry cooldown post-parry if failed. This is ADDED to parry_cooldown!!! + var/parry_failed_cooldown_duration = 0 SECONDS /** * Quirky proc to get average of flags in list that are in attack_type because why is attack_type a flag. diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 5621fab9c1..d4ccc63b34 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -32,6 +32,10 @@ // 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 = /datum/block_parry_data // defaults to *something* because [combat_flags] dictates whether or not we can unarmed block/parry. + /// Default + var/datum/block_parry_data/default_block_parry_data = /datum/block_parry_data + /// If we're a pugilist + var/datum/block_parry_data/pugilist_block_parry_data = /datum/block_parry_data/unarmed/pugilist // Blocking /// The item the user is actively blocking with if any. var/obj/item/active_block_item diff --git a/code/modules/mob/living/living_mobility.dm b/code/modules/mob/living/living_mobility.dm index 62c23cca9b..2256a93fa1 100644 --- a/code/modules/mob/living/living_mobility.dm +++ b/code/modules/mob/living/living_mobility.dm @@ -1,12 +1,3 @@ -/// IN THE FUTURE, WE WILL PROBABLY REFACTOR TO LESSEN THE NEED FOR UPDATE_MOBILITY, BUT FOR NOW.. WE CAN START DOING THIS. -/// FOR BLOCKING MOVEMENT, USE TRAIT_MOBILITY_NOMOVE AS MUCH AS POSSIBLE. IT WILL MAKE REFACTORS IN THE FUTURE EASIER. -/mob/living/ComponentInitialize() - . = ..() - RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOMOVE), .proc/update_mobility) - RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOPICKUP), .proc/update_mobility) - RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOUSE), .proc/update_mobility) - RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOREST), .proc/update_mobility) - RegisterSignal(src, SIGNAL_TRAIT(TRAIT_LIVING_NO_DENSITY), .proc/update_density) //Stuff like mobility flag updates, resting updates, etc. diff --git a/code/modules/mob/living/living_signals.dm b/code/modules/mob/living/living_signals.dm new file mode 100644 index 0000000000..0eb83658d7 --- /dev/null +++ b/code/modules/mob/living/living_signals.dm @@ -0,0 +1,20 @@ +/// IN THE FUTURE, WE WILL PROBABLY REFACTOR TO LESSEN THE NEED FOR UPDATE_MOBILITY, BUT FOR NOW.. WE CAN START DOING THIS. +/// FOR BLOCKING MOVEMENT, USE TRAIT_MOBILITY_NOMOVE AS MUCH AS POSSIBLE. IT WILL MAKE REFACTORS IN THE FUTURE EASIER. +/mob/living/ComponentInitialize() + . = ..() + RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOMOVE), .proc/update_mobility) + RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOPICKUP), .proc/update_mobility) + RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOUSE), .proc/update_mobility) + RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOREST), .proc/update_mobility) + RegisterSignal(src, SIGNAL_TRAIT(TRAIT_LIVING_NO_DENSITY), .proc/update_density) + RegisterSignal(src, SIGNAL_TRAIT(TRAIT_PUGILIST), .proc/update_pugilism) + +/mob/living/proc/update_pugilism() + if(HAS_TRAIT(src, TRAIT_PUGILIST)) + combat_flags |= COMBAT_FLAG_UNARMED_PARRY + block_parry_data = pugilist_block_parry_data + else + var/initial_combat_flags = initial(combat_flags) + if(!(initial_combat_flags & COMBAT_FLAG_UNARMED_PARRY)) + combat_flags &= ~COMBAT_FLAG_UNARMED_PARRY + block_parry_data = default_block_parry_data diff --git a/tgstation.dme b/tgstation.dme index adca1ef2ae..07eefc79ef 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2473,6 +2473,7 @@ #include "code\modules\mob\living\living_defines.dm" #include "code\modules\mob\living\living_mobility.dm" #include "code\modules\mob\living\living_movement.dm" +#include "code\modules\mob\living\living_signals.dm" #include "code\modules\mob\living\living_sprint.dm" #include "code\modules\mob\living\login.dm" #include "code\modules\mob\living\logout.dm"