Merge pull request #11476 from kevinz000/shield_refactor

Completely overhauls how blocking, shields, reflecting, and anything in between is handled. Has some small gameplay effects.
This commit is contained in:
Lin
2020-04-07 20:47:15 +00:00
committed by GitHub
50 changed files with 542 additions and 389 deletions
@@ -63,13 +63,13 @@
if(hit_atom)
if(isliving(hit_atom))
var/mob/living/L = hit_atom
if(!L.check_shields(src, 0, "the [name]", attack_type = LEAP_ATTACK))
if(L.run_block(src, 0, "the [name]", ATTACK_TYPE_TACKLE, 0, src) & BLOCK_SUCCESS)
DefaultCombatKnockdown(40, 1, 1)
else
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
L.DefaultCombatKnockdown(100)
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
step_towards(src,L)
else
DefaultCombatKnockdown(40, 1, 1)
toggle_leap(0)
else if(hit_atom.density && !hit_atom.CanPass(src))
@@ -86,13 +86,10 @@
if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
totitemdamage *= 1.5
//CIT CHANGES END HERE
if(user != src && check_shields(I, totitemdamage, "the [I.name]", MELEE_ATTACK, I.armour_penetration))
var/impacting_zone = (user == src)? check_zone(user.zone_selected) : ran_zone(user.zone_selected)
if((user != src) && (run_block(I, totitemdamage, "the [I]", ATTACK_TYPE_MELEE, I.armour_penetration, user, impacting_zone) & BLOCK_SUCCESS))
return FALSE
var/obj/item/bodypart/affecting
if(user == src)
affecting = get_bodypart(check_zone(user.zone_selected)) //we're self-mutilating! yay!
else
affecting = get_bodypart(ran_zone(user.zone_selected))
var/obj/item/bodypart/affecting = get_bodypart(impacting_zone)
if(!affecting) //missing limb? we select the first bodypart (you can never have zero, because of chest)
affecting = bodyparts[1]
SEND_SIGNAL(I, COMSIG_ITEM_ATTACK_ZONE, src, user, affecting)
@@ -0,0 +1,8 @@
/mob/living/carbon/human/get_blocking_items()
. = ..()
if(wear_suit)
. += wear_suit
if(w_uniform)
. += w_uniform
if(wear_neck)
. += wear_neck
@@ -52,36 +52,12 @@
return martial_art_result
return ..()
/mob/living/carbon/human/check_reflect(def_zone)
if(wear_suit?.IsReflect(def_zone))
return TRUE
return ..()
/mob/living/carbon/human/check_shields(atom/AM, damage, attack_text = "the attack", attack_type = MELEE_ATTACK, armour_penetration = 0)
. = ..()
if(.)
return
var/block_chance_modifier = round(damage / -3)
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))
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))
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))
return TRUE
return FALSE
/mob/living/carbon/human/can_embed(obj/item/I)
if(I.get_sharpness() || is_pointed(I) || is_type_in_typecache(I, GLOB.can_embed_types))
return TRUE
return FALSE
/mob/living/carbon/human/proc/check_block()
/mob/living/carbon/human/proc/check_martial_melee_block()
if(mind)
if(mind.martial_art && prob(mind.martial_art.block_chance) && mind.martial_art.can_use(src) && in_throw_mode && !incapacitated(FALSE, TRUE))
return TRUE
@@ -1437,7 +1437,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
to_chat(user, "<span class='notice'>You do not breathe, so you cannot perform CPR.</span>")
/datum/species/proc/grab(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
if(target.check_block())
if(target.check_martial_melee_block())
target.visible_message("<span class='warning'>[target] blocks [user]'s grab attempt!</span>")
return 0
if(attacker_style && attacker_style.grab_act(user,target))
@@ -1453,7 +1453,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(IS_STAMCRIT(user)) //CITADEL CHANGE - makes it impossible to punch while in stamina softcrit
to_chat(user, "<span class='warning'>You're too exhausted.</span>") //CITADEL CHANGE - ditto
return FALSE //CITADEL CHANGE - ditto
if(target.check_block())
if(target.check_martial_melee_block())
target.visible_message("<span class='warning'>[target] blocks [user]'s attack!</span>")
return FALSE
if(attacker_style && attacker_style.harm_act(user,target))
@@ -1557,6 +1557,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/aim_for_groin = user.zone_selected == "groin"
var/target_aiming_for_groin = target.zone_selected == "groin"
if(target.check_martial_melee_block()) //END EDIT
target.visible_message("<span class='warning'>[target] blocks [user]'s disarm attempt!</span>")
return FALSE
if(IS_STAMCRIT(user))
to_chat(user, "<span class='warning'>You're too exhausted!</span>")
return FALSE
@@ -1685,9 +1688,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
/datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
// Allows you to put in item-specific reactions based on species
if(user != H)
if(H.check_shields(I, I.force, "the [I.name]", MELEE_ATTACK, I.armour_penetration))
if(H.run_block(I, I.force, "the [I.name]", ATTACK_TYPE_MELEE, I.armour_penetration, user, affecting.body_zone) & BLOCK_SUCCESS)
return 0
if(H.check_block())
if(H.check_martial_melee_block())
H.visible_message("<span class='warning'>[H] blocks [I]!</span>")
return 0
@@ -1803,7 +1806,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
return TRUE
if(M.mind)
attacker_style = M.mind.martial_art
if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK))
if((M != H) && M.a_intent != INTENT_HELP && (H.run_block(M, 0, "[M]", ATTACK_TYPE_UNARMED, 0, M, M.zone_selected) & BLOCK_SUCCESS))
log_combat(M, H, "attempted to touch")
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>")
return TRUE
@@ -1841,7 +1844,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(IS_STAMCRIT(user))
to_chat(user, "<span class='warning'>You're too exhausted.</span>")
return FALSE
if(target.check_block())
if(target.check_martial_melee_block())
target.visible_message("<span class='warning'>[target] blocks [user]'s shoving attempt!</span>")
return FALSE
if(attacker_style && attacker_style.disarm_act(user,target))