From 427919d1479c824699985e1c31c09fea70f2ad19 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sat, 20 Mar 2021 13:57:48 -0700 Subject: [PATCH] whew --- code/game/objects/items/dualsaber.dm | 2 +- code/game/objects/items/shields.dm | 2 +- .../changeling/powers/mutations.dm | 2 +- .../modules/mob/living/living_active_block.dm | 34 +++++++++++++------ .../mob/living/living_blocking_parrying.dm | 2 +- 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/code/game/objects/items/dualsaber.dm b/code/game/objects/items/dualsaber.dm index 86522b9587..01e68a6516 100644 --- a/code/game/objects/items/dualsaber.dm +++ b/code/game/objects/items/dualsaber.dm @@ -73,7 +73,7 @@ parry_failed_stagger_duration = 3 SECONDS parry_failed_clickcd_duration = CLICK_CD_MELEE -/obj/item/dualsaber/active_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction) +/obj/item/dualsaber/directional_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction) if((attack_type & ATTACK_TYPE_PROJECTILE) && is_energy_reflectable_projectile(object)) block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_RETURN_TO_SENDER return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index 9841a29ae0..deb8a8ac7d 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -446,7 +446,7 @@ return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT return ..() -/obj/item/shield/energy/active_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction) +/obj/item/shield/energy/directional_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction) if((attack_type & ATTACK_TYPE_PROJECTILE) && is_energy_reflectable_projectile(object)) block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_DEFLECT return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index 5b6a7648c8..0d1496039a 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -466,7 +466,7 @@ block_return[BLOCK_RETURN_BLOCK_CAPACITY] = (block_return[BLOCK_RETURN_BLOCK_CAPACITY] || 0) + remaining_uses return ..() -/obj/item/shield/changeling/active_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) +/obj/item/shield/changeling/directional_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) . = ..() if(--remaining_uses < 1) if(ishuman(loc)) diff --git a/code/modules/mob/living/living_active_block.dm b/code/modules/mob/living/living_active_block.dm index 5c184313ee..719fa4bc53 100644 --- a/code/modules/mob/living/living_active_block.dm +++ b/code/modules/mob/living/living_active_block.dm @@ -140,7 +140,7 @@ /** * Calculates FINAL ATTACK DAMAGE after mitigation */ -/obj/item/proc/active_block_calculate_final_damage(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) +/obj/item/proc/active_block_calculate_final_damage(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, passive = FALSE) var/datum/block_parry_data/data = get_block_parry_data() var/absorption = data.attack_type_list_scan(data.block_damage_absorption_override, attack_type) var/efficiency = data.attack_type_list_scan(data.block_damage_multiplier_override, attack_type) @@ -149,7 +149,7 @@ if(isnull(absorption)) absorption = data.block_damage_absorption if(isnull(efficiency)) - efficiency = data.block_damage_multiplier + efficiency = data.block_damage_multiplier * (passive? data.block_automatic_mitigation_multiplier : 1) if(isnull(limit)) limit = data.block_damage_limit // now we calculate damage to reduce. @@ -165,7 +165,7 @@ return final_damage /// Amount of stamina from damage blocked. Note that the damage argument is damage_blocked. -/obj/item/proc/active_block_stamina_cost(mob/living/owner, atom/object, damage_blocked, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) +/obj/item/proc/active_block_stamina_cost(mob/living/owner, atom/object, damage_blocked, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, passive = FALSE) var/datum/block_parry_data/data = get_block_parry_data() var/efficiency = data.attack_type_list_scan(data.block_stamina_efficiency_override, attack_type) if(isnull(efficiency)) @@ -175,7 +175,7 @@ multiplier = data.attack_type_list_scan(data.block_resting_stamina_penalty_multiplier_override, attack_type) if(isnull(multiplier)) multiplier = data.block_resting_stamina_penalty_multiplier - return (damage_blocked / efficiency) * multiplier + return (damage_blocked / efficiency) * multiplier * (passive? data.block_automatic_stamina_multiplier : 1) /// Apply the stamina damage to our user, notice how damage argument is stamina_amount. /obj/item/proc/active_block_do_stamina_damage(mob/living/owner, atom/object, stamina_amount, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) @@ -207,6 +207,18 @@ return /obj/item/proc/active_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction) + return directional_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return, override_direction) + +/obj/item/proc/can_passive_block() + if(!block_parry_data || !(item_flags & ITEM_CAN_BLOCK)) + return FALSE + var/datum/block_parry_data/data = return_block_parry_datum(block_parry_data) + return data.block_automatic_enabled + +/obj/item/proc/passive_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction) + return directional_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return, override_direction, TRUE) + +/obj/item/proc/directional_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction, passive = FALSE) if(!can_active_block()) return BLOCK_NONE var/datum/block_parry_data/data = get_block_parry_data() @@ -221,12 +233,12 @@ incoming_direction = get_dir(get_turf(attacker) || get_turf(object), src) if(!CHECK_MOBILITY(owner, MOBILITY_STAND) && !(data.block_resting_attack_types_anydir & attack_type) && (!(data.block_resting_attack_types_directional & attack_type) || !can_block_direction(owner.dir, incoming_direction))) return BLOCK_NONE - else if(!can_block_direction(owner.dir, incoming_direction)) + else if(!can_block_direction(owner.dir, incoming_direction, passive)) return BLOCK_NONE block_return[BLOCK_RETURN_ACTIVE_BLOCK] = TRUE - var/final_damage = active_block_calculate_final_damage(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return) + var/final_damage = active_block_calculate_final_damage(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return, passive) var/damage_blocked = damage - final_damage - var/stamina_cost = active_block_stamina_cost(owner, object, damage_blocked, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return) + var/stamina_cost = active_block_stamina_cost(owner, object, damage_blocked, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return, passive) active_block_do_stamina_damage(owner, object, stamina_cost, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return) block_return[BLOCK_RETURN_ACTIVE_BLOCK_DAMAGE_MITIGATED] = damage - final_damage block_return[BLOCK_RETURN_SET_DAMAGE_TO] = final_damage @@ -254,9 +266,9 @@ /** * Gets the block direction bitflags of what we can block. */ -/obj/item/proc/blockable_directions() +/obj/item/proc/blockable_directions(passive = FALSE) var/datum/block_parry_data/data = get_block_parry_data() - return data.can_block_directions + return passive? data.block_automatic_directions : data.can_block_directions /** * Checks if we can block from a specific direction from our direction. @@ -265,14 +277,14 @@ * * our_dir - our direction. * * their_dir - their direction. Must be a single direction, or NONE for an attack from the same tile. This is incoming direction. */ -/obj/item/proc/can_block_direction(our_dir, their_dir) +/obj/item/proc/can_block_direction(our_dir, their_dir, passive = FALSE) their_dir = turn(their_dir, 180) if(our_dir != NORTH) var/turn_angle = dir2angle(our_dir) // dir2angle(), ss13 proc is clockwise so dir2angle(EAST) == 90 // turn(), byond proc is counterclockwise so turn(NORTH, 90) == WEST their_dir = turn(their_dir, turn_angle) - return (DIR2BLOCKDIR(their_dir) & blockable_directions()) + return (DIR2BLOCKDIR(their_dir) & blockable_directions(passive)) /** * can_block_direction but for "compound" directions to check all of them and return the number of directions that were blocked. diff --git a/code/modules/mob/living/living_blocking_parrying.dm b/code/modules/mob/living/living_blocking_parrying.dm index 1ed490b0d8..b273324028 100644 --- a/code/modules/mob/living/living_blocking_parrying.dm +++ b/code/modules/mob/living/living_blocking_parrying.dm @@ -100,7 +100,7 @@ GLOBAL_LIST_EMPTY(block_parry_data) #warn have autoblock items warn user on pickup /// Directions that you can autoblock in var/block_automatic_directions = BLOCK_DIR_NORTH | BLOCK_DIR_NORTHEAST | BLOCK_DIR_NORTHWEST - /// Effectiveness multiplier for automated block + /// Effectiveness multiplier for automated block. Only applies to efficiency, absorption and limits stay the same! var/block_automatic_mitigation_multiplier = 0.33 /// Stamina cost multiplier for automated block var/block_automatic_stamina_multiplier = 1