diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm
index 2fdd6a98bc..33fc0c543d 100644
--- a/code/__DEFINES/combat.dm
+++ b/code/__DEFINES/combat.dm
@@ -243,9 +243,11 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
/// These keys are generally only applied to the list if real_attack is FALSE. Used incase we want to make "smarter" mob AI in the future or something.
/// Tells the caller how likely from 0 (none) to 100 (always) we are to reflect energy projectiles
-#define BLOCK_RETURN_REFLECT_PROJECTILE_CHANCE
+#define BLOCK_RETURN_REFLECT_PROJECTILE_CHANCE "reflect_projectile_chance"
/// Tells the caller how likely we are to block attacks from 0 to 100 in general
-#define BLOCK_RETURN_NORMAL_BLOCK_CHANCE
+#define BLOCK_RETURN_NORMAL_BLOCK_CHANCE "normal_block_chance"
+/// Tells the caller about how many hits we can soak on average before our blocking fails.
+#define BLOCK_RETURN_BLOCK_CAPACITY "block_capacity"
/// Default if the above isn't set in the list.
#define DEFAULT_REDIRECT_METHOD_PROJECTILE REDIRECT_METHOD_DEFLECT
diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 364ed65415..f844f4d4b2 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -186,6 +186,7 @@
#define COMSIG_LIVING_REVIVE "living_revive" //from base of mob/living/revive() (full_heal, admin_revive)
#define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login" //sent when a mob/login() finishes: (client)
#define COMSIG_LIVING_GUN_PROCESS_FIRE "living_gun_process_fire" //from base of /obj/item/gun/proc/process_fire(): (atom/target, params, zone_override)
+// This returns flags as defined for block in __DEFINES/combat.dm!
#define COMSIG_LIVING_RUN_BLOCK "living_do_run_block" //from base of mob/living/do_run_block(): (real_attack, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone)
//ALL OF THESE DO NOT TAKE INTO ACCOUNT WHETHER AMOUNT IS 0 OR LOWER AND ARE SENT REGARDLESS!
@@ -232,6 +233,9 @@
#define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul" //return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/targeted/lichdom/cast(): (mob/user)
#define COMSIG_ITEM_HIT_REACT "item_hit_react" //from base of obj/item/hit_reaction(): (list/args)
#define COMSIG_ITEM_WEARERCROSSED "wearer_crossed" //called on item when crossed by something (): (/atom/movable)
+// THE FOLLOWING TWO BLOCKS SHOULD RETURN BLOCK FLAGS AS DEFINED IN __DEFINES/combat.dm!
+#define COMSIG_ITEM_CHECK_BLOCK "check_block" //from base of obj/item/check_block(): (mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
+#define COMSIG_ITEM_RUN_BLOCK "run_block" //from base of obj/item/run_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/clothing signals
#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): ()
diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm
index b36ad385d6..0c144ff1d6 100644
--- a/code/game/objects/items/flamethrower.dm
+++ b/code/game/objects/items/flamethrower.dm
@@ -236,13 +236,13 @@
/obj/item/flamethrower/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(real_attack && (attack_type & ATTACK_TYPE_PROJECTILE))
- var/obj/item/projectile/P = hitby
+ var/obj/item/projectile/P = object
if(istype(P) && (P.damage_type != STAMINA) && damage && !P.nodamage && prob(15))
owner.visible_message("\The [attack_text] hits the fueltank on [owner]'s [name], rupturing it! What a shot!")
var/target_turf = get_turf(owner)
igniter.ignite_turf(src,target_turf, release_amount = 100)
qdel(ptank)
- return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL | BLOCK_INTERRUPT_CHAIN
+ return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
return ..()
/obj/item/assembly/igniter/proc/flamethrower_process(turf/open/location)
diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm
index b759c09212..e0cba34e09 100644
--- a/code/game/objects/items/shields.dm
+++ b/code/game/objects/items/shields.dm
@@ -35,7 +35,7 @@
final_block_chance = 100
. = ..()
if(. & BLOCK_SUCCESS)
- on_shield_block(owner, real_attack, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
+ on_shield_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
/obj/item/shield/riot/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/melee/baton))
diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm
index c689a01177..584767eedd 100644
--- a/code/game/objects/items/twohanded.dm
+++ b/code/game/objects/items/twohanded.dm
@@ -751,8 +751,12 @@
armour_penetration = 100
force_on = 30
+/obj/item/twohanded/required/chainsaw/doomslayer/check_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
+ block_return[BLOCK_RETURN_REFLECT_PROJECTILE_CHANCE] = 100
+ return ..()
+
/obj/item/twohanded/required/chainsaw/doomslayer/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
- if(real_attack && (attack_type & ATTACK_TYPE_PROJECTILE))
+ if(attack_type & ATTACK_TYPE_PROJECTILE)
owner.visible_message("Ranged attacks just make [owner] angrier!")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
@@ -1056,7 +1060,7 @@
. = R.get_cell()
/obj/item/twohanded/electrostaff/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
- if(!on || (!can_block_projectiles && (attack_type & PROJECTILE_ATTACK)))
+ if(!on || (!can_block_projectiles && (attack_type & ATTACK_TYPE_PROJECTILE)))
return BLOCK_NONE
return ..()
diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm
index c84076f44a..261888c3bc 100644
--- a/code/modules/antagonists/cult/cult_items.dm
+++ b/code/modules/antagonists/cult/cult_items.dm
@@ -174,7 +174,7 @@
if(attack_type & ATTACK_TYPE_PROJECTILE)
owner.visible_message("[owner] deflects [attack_text] with [src]!")
playsound(src, pick('sound/weapons/effects/ric1.ogg', 'sound/weapons/effects/ric2.ogg', 'sound/weapons/effects/ric3.ogg', 'sound/weapons/effects/ric4.ogg', 'sound/weapons/effects/ric5.ogg'), 100, 1)
- return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL | BLOCK_REDIRECT | BLOCK_SHOULD_REDIRECT
+ return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT
else
playsound(src, 'sound/weapons/parry.ogg', 75, 1)
owner.visible_message("[owner] parries [attack_text] with [src]!")
@@ -414,7 +414,13 @@
user.adjustBruteLoss(25)
user.dropItemToGround(src, TRUE)
-/obj/item/clothing/suit/hooded/cultrobes/cult_shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+/obj/item/clothing/suit/hooded/cultrobes/cult_shield/check_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
+ if(current_charges)
+ block_return[BLOCK_RETURN_GENERAL_BLOCK_CHANCE] = 100
+ block_return[BLOCK_RETURN_BLOCK_CAPACITY] = block_return[BLOCK_RETURN_BLOCK_CAPACITY] || 0) + current_charges
+ return ..()
+
+/obj/item/clothing/suit/hooded/cultrobes/cult_shield/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(current_charges)
owner.visible_message("\The [attack_text] is deflected in a burst of blood-red sparks!")
current_charges--
@@ -422,8 +428,8 @@
if(!current_charges)
owner.visible_message("The runed shield around [owner] suddenly disappears!")
owner.update_inv_wear_suit()
- return 1
- return 0
+ return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
+ return BLOCK_NONE
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/worn_overlays(isinhands, icon_file, style_flags = NONE)
. = list()
@@ -936,10 +942,11 @@
hitsound = 'sound/weapons/smash.ogg'
var/illusions = 2
+/obj/item/shield/mirror/check_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
+ block_return[BLOCK_RETURN_REFLECT_PROJECTILE_CHANCE] = max(block_return[BLOCK_RETURN_REFLECT_PROJECTILE_CHANCE] || null, final_block_chance)
+ return ..()
+
/obj/item/shield/mirror/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
- if(!real_attack)
- block_return[BLOCK_RETURN_REFLECT_PROJECTILE_CHANCE] = final_block_chance
- return ..()
if(iscultist(owner))
if(istype(object, /obj/item/projectile) && (attack_type == ATTACK_TYPE_PROJECTILE))
var/obj/item/projectile/P = object
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index 9857cfad94..e9d4ee34dc 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -757,6 +757,12 @@
if(!allowed)
allowed = GLOB.advanced_hardsuit_allowed
+/obj/item/clothing/suit/space/hardsuit/shielded/check_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
+ if(current_charges > 0)
+ block_return[BLOCK_RETURN_GENERAL_BLOCK_CHANCE] = 100
+ block_return[BLOCK_RETURN_BLOCK_CAPACITY] = (block_return[BLOCK_RETURN_BLOCK_CAPACITY] || 0) + current_charges
+ return ..()
+
/obj/item/clothing/suit/space/hardsuit/shielded/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(!real_attack)
if(current_charges > 0)
diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm
index 6d52f46d30..969d98602a 100644
--- a/code/modules/clothing/suits/reactive_armour.dm
+++ b/code/modules/clothing/suits/reactive_armour.dm
@@ -36,7 +36,6 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
actions_types = list(/datum/action/item_action/toggle)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
- hit_reaction_chance = 50 // Only on the chest yet blocks all attacks?
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
var/hit_reaction_chance = 50
diff --git a/code/modules/mob/living/living_block.dm b/code/modules/mob/living/living_block.dm
index 47d4aa4899..d9e3309e47 100644
--- a/code/modules/mob/living/living_block.dm
+++ b/code/modules/mob/living/living_block.dm
@@ -85,7 +85,7 @@
/// Runs block and returns flag for do_run_block to process.
/obj/item/proc/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
- SEND_SIGNAL(src, COMSIG_ITEM_RUN_BLOCK, args)
+ SEND_SIGNAL(src, COMSIG_ITEM_RUN_BLOCK, owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
if(prob(final_block_chance))
owner.visible_message("[owner] blocks [attack_text] with [src]!")
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
@@ -93,6 +93,6 @@
/// Returns block information using list/block_return. Used for check_block() on mobs.
/obj/item/proc/check_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
- SEND_SIGNAL(src, COMSIG_ITEM_CHECK_BLOCK, args)
+ SEND_SIGNAL(src, COMSIG_ITEM_CHECK_BLOCK, owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
var/existing = block_return[BLOCK_RETURN_NORMAL_BLOCK_CHANCE]
block_return[BLOCK_RETURN_NORMAL_BLOCK_CHANCE] = max(existing || 0, final_block_chance)