Stops shields getting broken by pillows and disablers. (#75759)

## About The Pull Request
See the title. Doing so by adding a new arg for damage type to
`check_shields()` and `hit_reaction()`. The other way would had involved
a couple istype checks for item or projectile damage type, but this is a
longer term solution and can tackle more than just that.

## Why It's Good For The Game
Fixes #74876.

## Changelog

🆑
fix: Stops shields getting broken by pillows and disablers.
/🆑
This commit is contained in:
Ghom
2023-06-01 16:26:10 -04:00
committed by GitHub
parent 099c804c52
commit 88b898dffd
32 changed files with 73 additions and 62 deletions
@@ -94,7 +94,7 @@
return BULLET_ACT_FORCE_PIERCE // complete projectile permutation
if(check_shields(P, P.damage, "the [P.name]", PROJECTILE_ATTACK, P.armour_penetration))
if(check_shields(P, P.damage, "the [P.name]", PROJECTILE_ATTACK, P.armour_penetration, P.damage_type))
P.on_hit(src, 100, def_zone, piercing_hit)
return BULLET_ACT_HIT
@@ -113,31 +113,31 @@
return TRUE
return FALSE
/mob/living/carbon/human/proc/check_shields(atom/AM, damage, attack_text = "the attack", attack_type = MELEE_ATTACK, armour_penetration = 0)
/mob/living/carbon/human/proc/check_shields(atom/AM, damage, attack_text = "the attack", attack_type = MELEE_ATTACK, armour_penetration = 0, damage_type = BRUTE)
var/block_chance_modifier = round(damage / -3)
for(var/obj/item/I in held_items)
if(!isclothing(I))
var/final_block_chance = I.block_chance - (clamp((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
if(I.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
if(I.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type, damage_type))
return TRUE
if(wear_suit)
var/final_block_chance = wear_suit.block_chance - (clamp((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier
if(wear_suit.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
if(wear_suit.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type, damage_type))
return TRUE
if(w_uniform)
var/final_block_chance = w_uniform.block_chance - (clamp((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier
if(w_uniform.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
if(w_uniform.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type, damage_type))
return TRUE
if(wear_neck)
var/final_block_chance = wear_neck.block_chance - (clamp((armour_penetration-wear_neck.armour_penetration)/2,0,100)) + block_chance_modifier
if(wear_neck.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
if(wear_neck.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type, damage_type))
return TRUE
if(head)
var/final_block_chance = head.block_chance - (clamp((armour_penetration-head.armour_penetration)/2,0,100)) + block_chance_modifier
if(head.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
if(head.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type, damage_type))
return TRUE
if(SEND_SIGNAL(src, COMSIG_HUMAN_CHECK_SHIELDS, AM, damage, attack_text, attack_type, armour_penetration) & SHIELD_BLOCK)
if(SEND_SIGNAL(src, COMSIG_HUMAN_CHECK_SHIELDS, AM, damage, attack_text, attack_type, armour_penetration, damage_type) & SHIELD_BLOCK)
return TRUE
return FALSE
@@ -153,13 +153,15 @@
if(spec_return)
return spec_return
var/obj/item/I
var/damage_type = BRUTE
var/throwpower = 30
if(isitem(AM))
I = AM
throwpower = I.throwforce
if(I.thrownby == WEAKREF(src)) //No throwing stuff at yourself to trigger hit reactions
return ..()
if(check_shields(AM, throwpower, "\the [AM.name]", THROWN_PROJECTILE_ATTACK))
throwpower = I.throwforce
damage_type = I.damtype
if(check_shields(AM, throwpower, "\the [AM.name]", THROWN_PROJECTILE_ATTACK, damage_type))
hitpush = FALSE
skipcatch = TRUE
blocked = TRUE
@@ -339,7 +341,7 @@
if(!.)
return
var/damage = rand(user.melee_damage_lower, user.melee_damage_upper)
if(check_shields(user, damage, "the [user.name]", MELEE_ATTACK, user.armour_penetration))
if(check_shields(user, damage, "the [user.name]", MELEE_ATTACK, user.armour_penetration, user.melee_damage_type))
return FALSE
var/dam_zone = dismembering_strike(user, pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
if(!dam_zone) //Dismemberment successful
@@ -1274,7 +1274,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
/datum/species/proc/spec_attacked_by(obj/item/weapon, mob/living/user, obj/item/bodypart/affecting, mob/living/carbon/human/human)
// Allows you to put in item-specific reactions based on species
if(user != human)
if(human.check_shields(weapon, weapon.force, "the [weapon.name]", MELEE_ATTACK, weapon.armour_penetration))
if(human.check_shields(weapon, weapon.force, "the [weapon.name]", MELEE_ATTACK, weapon.armour_penetration, weapon.damtype))
return FALSE
if(human.check_block())
human.visible_message(span_warning("[human] blocks [weapon]!"), \