diff --git a/code/ZAS/Airflow.dm b/code/ZAS/Airflow.dm
index 01a84fdf5d..8dd637e58f 100644
--- a/code/ZAS/Airflow.dm
+++ b/code/ZAS/Airflow.dm
@@ -228,13 +228,16 @@ mob/living/carbon/human/airflow_hit(atom/A)
var/b_loss = airflow_speed * vsc.airflow_damage
var/blocked = run_armor_check(BP_HEAD,"melee")
- apply_damage(b_loss/3, BRUTE, BP_HEAD, blocked, 0, "Airflow")
+ var/soaked = get_armor_soak(BP_HEAD,"melee")
+ apply_damage(b_loss/3, BRUTE, BP_HEAD, blocked, soaked, 0, "Airflow")
blocked = run_armor_check(BP_TORSO,"melee")
- apply_damage(b_loss/3, BRUTE, BP_TORSO, blocked, 0, "Airflow")
+ soaked = get_armor_soak(BP_TORSO,"melee")
+ apply_damage(b_loss/3, BRUTE, BP_TORSO, blocked, soaked, 0, "Airflow")
blocked = run_armor_check(BP_GROIN,"melee")
- apply_damage(b_loss/3, BRUTE, BP_GROIN, blocked, 0, "Airflow")
+ soaked = get_armor_soak(BP_GROIN,"melee")
+ apply_damage(b_loss/3, BRUTE, BP_GROIN, blocked, soaked, 0, "Airflow")
if(airflow_speed > 10)
Paralyse(round(airflow_speed * vsc.airflow_stun))
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 0559b626e1..4316da3c49 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -44,6 +44,7 @@
var/slowdown = 0 // How much clothing is slowing you down. Negative values speeds you up
var/canremove = 1 //Mostly for Ninja code at this point but basically will not allow the item to be removed if set to 0. /N
var/list/armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
+ var/list/armorsoak = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
var/list/allowed = null //suit storage stuff.
var/obj/item/device/uplink/hidden/hidden_uplink = null // All items can have an uplink hidden inside, just remember to add the triggers.
var/zoomdevicename = null //name used for message when binoculars/scope is used
diff --git a/code/game/objects/items/weapons/traps.dm b/code/game/objects/items/weapons/traps.dm
index e5a655d7f9..cd11af3400 100644
--- a/code/game/objects/items/weapons/traps.dm
+++ b/code/game/objects/items/weapons/traps.dm
@@ -77,11 +77,15 @@
//armour
var/blocked = L.run_armor_check(target_zone, "melee")
+ var/soaked = L.get_armor_soak(target_zone, "melee")
if(blocked >= 100)
return
- if(!L.apply_damage(30, BRUTE, target_zone, blocked, used_weapon=src))
+ if(soaked >= 30)
+ return
+
+ if(!L.apply_damage(30, BRUTE, target_zone, blocked, soaked, used_weapon=src))
return 0
//trap the victim in place
diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
index ae4fe4d740..0e6064785d 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
@@ -150,20 +150,22 @@
var/def_zone = ran_zone()
var/blocked = occupant.run_armor_check(def_zone, "melee")
+ var/soaked = occupant.get_armor_soak(def_zone, "melee")
occupant.throw_at(A, 3, propelled)
occupant.apply_effect(6, STUN, blocked)
occupant.apply_effect(6, WEAKEN, blocked)
occupant.apply_effect(6, STUTTER, blocked)
- occupant.apply_damage(10, BRUTE, def_zone, blocked)
+ occupant.apply_damage(10, BRUTE, def_zone, blocked, soaked)
playsound(src.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
if(istype(A, /mob/living))
var/mob/living/victim = A
def_zone = ran_zone()
blocked = victim.run_armor_check(def_zone, "melee")
+ soaked = victim.get_armor_soak(def_zone, "melee")
victim.apply_effect(6, STUN, blocked)
victim.apply_effect(6, WEAKEN, blocked)
victim.apply_effect(6, STUTTER, blocked)
- victim.apply_damage(10, BRUTE, def_zone, blocked)
+ victim.apply_damage(10, BRUTE, def_zone, blocked, soaked)
occupant.visible_message("[occupant] crashed into \the [A]!")
/obj/structure/bed/chair/office/light
diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
index 2bcbf8aa87..9ae19769eb 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
@@ -149,20 +149,22 @@
var/def_zone = ran_zone()
var/blocked = occupant.run_armor_check(def_zone, "melee")
+ var/soaked = occupant.get_armor_soak(def_zone, "melee")
occupant.throw_at(A, 3, propelled)
occupant.apply_effect(6, STUN, blocked)
occupant.apply_effect(6, WEAKEN, blocked)
occupant.apply_effect(6, STUTTER, blocked)
- occupant.apply_damage(10, BRUTE, def_zone)
+ occupant.apply_damage(10, BRUTE, def_zone, soaked)
playsound(src.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
if(istype(A, /mob/living))
var/mob/living/victim = A
def_zone = ran_zone()
blocked = victim.run_armor_check(def_zone, "melee")
+ soaked = victim.get_armor_soak(def_zone, "melee")
victim.apply_effect(6, STUN, blocked)
victim.apply_effect(6, WEAKEN, blocked)
victim.apply_effect(6, STUTTER, blocked)
- victim.apply_damage(10, BRUTE, def_zone)
+ victim.apply_damage(10, BRUTE, def_zone, soaked)
if(pulling)
occupant.visible_message("[pulling] has thrusted \the [name] into \the [A], throwing \the [occupant] out of it!")
diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm
index 0bd14ef9d1..855aa49c7e 100644
--- a/code/modules/clothing/spacesuits/rig/rig.dm
+++ b/code/modules/clothing/spacesuits/rig/rig.dm
@@ -161,6 +161,7 @@
piece.permeability_coefficient = permeability_coefficient
piece.unacidable = unacidable
if(islist(armor)) piece.armor = armor.Copy()
+ if(islist(armorsoak)) piece.armorsoak = armorsoak.Copy()
update_icon(1)
diff --git a/code/modules/clothing/spacesuits/rig/suits/alien.dm b/code/modules/clothing/spacesuits/rig/suits/alien.dm
index 5d73e804b2..073ea5f9b1 100644
--- a/code/modules/clothing/spacesuits/rig/suits/alien.dm
+++ b/code/modules/clothing/spacesuits/rig/suits/alien.dm
@@ -8,6 +8,7 @@
suit_type = "\improper NT breacher"
icon_state = "breacher_rig_cheap"
armor = list(melee = 60, bullet = 60, laser = 60, energy = 60, bomb = 70, bio = 100, rad = 50)
+ armorsoak = list(melee = 15, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
emp_protection = -20
slowdown = 6
offline_slowdown = 10
diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm
index f6388e0190..1d92705dec 100644
--- a/code/modules/hydroponics/seed.dm
+++ b/code/modules/hydroponics/seed.dm
@@ -114,8 +114,11 @@
if(!target_limb) target_limb = pick(BP_ALL)
var/blocked = target.run_armor_check(target_limb, "melee")
+ var/soaked = target.get_armor_soak(target_limb, "melee")
+
if(blocked >= 100)
return
+
var/obj/item/organ/external/affecting = target.get_organ(target_limb)
var/damage = 0
var/has_edge = 0
@@ -125,7 +128,7 @@
if(affecting)
to_chat(target, "\The [fruit]'s thorns pierce your [affecting.name] greedily!")
- target.apply_damage(damage, BRUTE, target_limb, blocked, "Thorns", sharp=1, edge=has_edge)
+ target.apply_damage(damage, BRUTE, target_limb, blocked, soaked, "Thorns", sharp=1, edge=has_edge)
else
to_chat(target, "\The [fruit]'s thorns pierce your flesh greedily!")
target.adjustBruteLoss(damage)
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index db59f6bc83..66ba7ecd51 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -4,7 +4,7 @@
return null
..()
-/mob/living/carbon/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/hit_zone)
+/mob/living/carbon/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/soaked, var/hit_zone)
if(!effective_force || blocked >= 100)
return 0
@@ -12,6 +12,10 @@
if(HULK in user.mutations)
effective_force *= 2
+ //If the armor soaks all of the damage, it just skips the rest of the checks
+ if(effective_force <= soaked)
+ return 0
+
//Apply weapon damage
var/weapon_sharp = is_sharp(I)
var/weapon_edge = has_edge(I)
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index fccf6afbf6..01005b031b 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -43,6 +43,7 @@
return 0
var/obj/item/organ/external/affecting = get_organ(ran_zone(H.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
+ var/armor_soak = get_armor_soak(affecting, "melee")
if(HULK in H.mutations)
damage += 5
@@ -51,7 +52,10 @@
visible_message("\red [H] has punched [src]!")
- apply_damage(damage, HALLOSS, affecting, armor_block)
+ if(armor_soak >= damage)
+ return
+
+ apply_damage(damage, HALLOSS, affecting, armor_block, armor_soak)
if(damage >= 9)
visible_message("\red [H] has weakened [src]!")
apply_effect(4, WEAKEN, armor_block)
@@ -245,11 +249,12 @@
real_damage = max(1, real_damage)
var/armour = run_armor_check(affecting, "melee")
+ var/soaked = get_armor_soak(affecting, "melee")
// Apply additional unarmed effects.
attack.apply_effects(H, src, armour, rand_damage, hit_zone)
// Finally, apply damage to target
- apply_damage(real_damage, (attack.deal_halloss ? HALLOSS : BRUTE), affecting, armour, sharp=attack.sharp, edge=attack.edge)
+ apply_damage(real_damage, (attack.deal_halloss ? HALLOSS : BRUTE), affecting, armour, soaked, sharp=attack.sharp, edge=attack.edge)
if(I_DISARM)
M.attack_log += text("\[[time_stamp()]\] Disarmed [src.name] ([src.ckey])")
@@ -325,7 +330,8 @@
var/dam_zone = pick(organs_by_name)
var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone))
var/armor_block = run_armor_check(affecting, "melee")
- apply_damage(damage, BRUTE, affecting, armor_block)
+ var/armor_soak = get_armor_soak(affecting, "melee")
+ apply_damage(damage, BRUTE, affecting, armor_block, armor_soak)
updatehealth()
return 1
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index a6471c4aeb..4d8e428cc6 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -93,6 +93,29 @@ emp_act
total += weight
return (armorval/max(total, 1))
+//Like getarmor, but the value it returns will be numerical damage reduction
+/mob/living/carbon/human/getsoak(var/def_zone, var/type)
+ var/soakval = 0
+ var/total = 0
+
+ if(def_zone)
+ if(isorgan(def_zone))
+ return getsoak_organ(def_zone, type)
+ var/obj/item/organ/external/affecting = get_organ(def_zone)
+ if(affecting)
+ return getsoak_organ(affecting, type)
+ //If a specific bodypart is targetted, check how that bodypart is protected and return the value.
+
+ //If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values
+ for(var/organ_name in organs_by_name)
+ if (organ_name in organ_rel_size)
+ var/obj/item/organ/external/organ = organs_by_name[organ_name]
+ if(organ)
+ var/weight = organ_rel_size[organ_name]
+ soakval += getsoak_organ(organ, type) * weight
+ total += weight
+ return (soakval/max(total, 1))
+
//this proc returns the Siemens coefficient of electrical resistivity for a particular external organ.
/mob/living/carbon/human/proc/get_siemens_coefficient_organ(var/obj/item/organ/external/def_zone)
if (!def_zone)
@@ -119,6 +142,17 @@ emp_act
protection += C.armor[type]
return protection
+/mob/living/carbon/human/proc/getsoak_organ(var/obj/item/organ/external/def_zone, var/type)
+ if(!type || !def_zone) return 0
+ var/soaked = 0
+ var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes)
+ for(var/gear in protective_gear)
+ if(gear && istype(gear ,/obj/item/clothing))
+ var/obj/item/clothing/C = gear
+ if(istype(C) && C.body_parts_covered & def_zone.body_part)
+ soaked += C.armorsoak[type]
+ return soaked
+
/mob/living/carbon/human/proc/check_head_coverage()
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform)
@@ -195,25 +229,35 @@ emp_act
visible_message("[src] has been [I.attack_verb.len? pick(I.attack_verb) : "attacked"] in the [affecting.name] with [I.name] by [user]!")
+ var/soaked = get_armor_soak(hit_zone, "melee", I.armor_penetration)
+
+ if(soaked >= effective_force)
+ src << "Your armor absorbs the force of [I.name]!"
+ return
+
var/blocked = run_armor_check(hit_zone, "melee", I.armor_penetration, "Your armor has protected your [affecting.name].", "Your armor has softened the blow to your [affecting.name].")
- standard_weapon_hit_effects(I, user, effective_force, blocked, hit_zone)
+
+ standard_weapon_hit_effects(I, user, effective_force, blocked, soaked, hit_zone)
return blocked
-/mob/living/carbon/human/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/hit_zone)
+/mob/living/carbon/human/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/soaked, var/hit_zone)
var/obj/item/organ/external/affecting = get_organ(hit_zone)
if(!affecting)
return 0
+ if(soaked >= effective_force)
+ return 0
+
// Handle striking to cripple.
if(user.a_intent == I_DISARM)
effective_force *= 0.5 //reduced effective force...
- if(!..(I, user, effective_force, blocked, hit_zone))
+ if(!..(I, user, effective_force, blocked, soaked, hit_zone))
return 0
//set the dislocate mult less than the effective force mult so that
//dislocating limbs on disarm is a bit easier than breaking limbs on harm
- attack_joint(affecting, I, effective_force, 0.75, blocked) //...but can dislocate joints
+ attack_joint(affecting, I, effective_force, 0.75, blocked, soaked) //...but can dislocate joints
else if(!..())
return 0
@@ -243,7 +287,7 @@ emp_act
switch(hit_zone)
if("head")//Harder to score a stun but if you do it lasts a bit longer
if(prob(effective_force))
- apply_effect(20, PARALYZE, blocked)
+ apply_effect(20, PARALYZE, blocked, soaked)
visible_message("\The [src] has been knocked unconscious!")
if(bloody)//Apply blood
if(wear_mask)
@@ -257,15 +301,15 @@ emp_act
update_inv_glasses(0)
if("chest")//Easier to score a stun but lasts less time
if(prob(effective_force + 10))
- apply_effect(6, WEAKEN, blocked)
+ apply_effect(6, WEAKEN, blocked, soaked)
visible_message("\The [src] has been knocked down!")
if(bloody)
bloody_body(src)
return 1
-/mob/living/carbon/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/W, var/effective_force, var/dislocate_mult, var/blocked)
- if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1) || blocked >= 100)
+/mob/living/carbon/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/W, var/effective_force, var/dislocate_mult, var/blocked, var/soaked)
+ if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1) || blocked >= 100 || soaked > effective_force)
return 0
if(W.damtype != BRUTE)
@@ -338,10 +382,6 @@ emp_act
var/hit_area = affecting.name
src.visible_message("\red [src] has been hit in the [hit_area] by [O].")
- var/armor = run_armor_check(affecting, "melee", O.armor_penetration, "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") //I guess "melee" is the best fit here
-
- if(armor < 100)
- apply_damage(throw_damage, dtype, zone, armor, is_sharp(O), has_edge(O), O)
if(ismob(O.thrower))
var/mob/M = O.thrower
@@ -352,12 +392,25 @@ emp_act
if(!istype(src,/mob/living/simple_animal/mouse))
msg_admin_attack("[src.name] ([src.ckey]) was hit by a [O], thrown by [M.name] ([assailant.ckey]) (JMP)")
+ //If the armor absorbs all of the damage, skip the rest of the calculations
+ var/soaked = get_armor_soak(affecting, "melee", O.armor_penetration)
+ if(soaked >= throw_damage)
+ src << "Your armor absorbs the force of [O.name]!"
+ return
+
+ var/armor = run_armor_check(affecting, "melee", O.armor_penetration, "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") //I guess "melee" is the best fit here
+ if(armor < 100)
+ apply_damage(throw_damage, dtype, zone, armor, soaked, is_sharp(O), has_edge(O), O)
+
+
//thrown weapon embedded object code.
if(dtype == BRUTE && istype(O,/obj/item))
var/obj/item/I = O
if (!is_robot_module(I))
var/sharp = is_sharp(I)
var/damage = throw_damage
+ if (soaked)
+ damage -= soaked
if (armor)
damage /= armor+1
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index f09eb3741f..130ed9a283 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -8,15 +8,18 @@
Returns
standard 0 if fail
*/
-/mob/living/proc/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/used_weapon = null, var/sharp = 0, var/edge = 0)
+/mob/living/proc/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/soaked = 0, var/used_weapon = null, var/sharp = 0, var/edge = 0)
if(Debug2)
world.log << "## DEBUG: apply_damage() was called on [src], with [damage] damage, and an armor value of [blocked]."
- if(!damage || (blocked >= 100))
+ if(!damage || (blocked >= 100) || soaked >= damage)
return 0
+ if(soaked)
+ damage -= soaked
blocked = (100-blocked)/100
switch(damagetype)
if(BRUTE)
adjustBruteLoss(damage * blocked)
+ world << "Modified damage: [damage*blocked]"
if(BURN)
if(COLD_RESISTANCE in mutations)
damage = 0
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 17eff101bb..b7ab1ef793 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -40,6 +40,7 @@
src << "Your armor softens the blow!"
if(Debug2)
world.log << "## DEBUG: Armor when [src] was attacked was [armor]."
+ world << "Armor Check: [armor]"
return armor
/*
@@ -77,10 +78,21 @@
return 0
*/
+//Certain pieces of armor actually absorb flat amounts of damage from income attacks
+/mob/living/proc/get_armor_soak(var/def_zone = null, var/attack_flag = "melee", var/armour_pen = 0)
+ var/soaked = getsoak(def_zone, attack_flag)
+ //5 points of armor pen negate one point of soak
+ if(armour_pen)
+ soaked = max(soaked - (armour_pen/5), 0)
+ world << "Soaked: [soaked]"
+ return soaked
+
//if null is passed for def_zone, then this should return something appropriate for all zones (e.g. area effect damage)
/mob/living/proc/getarmor(var/def_zone, var/type)
return 0
+/mob/living/proc/getsoak(var/def_zone, var/type)
+ return 0
/mob/living/bullet_act(var/obj/item/projectile/P, var/def_zone)
@@ -93,6 +105,7 @@
signaler.signal()
//Armor
+ var/soaked = get_armor_soak(def_zone, P.check_armour, P.armor_penetration)
var/absorb = run_armor_check(def_zone, P.check_armour, P.armor_penetration)
var/proj_sharp = is_sharp(P)
var/proj_edge = has_edge(P)
@@ -105,13 +118,13 @@
stun_effect_act(0, P.agony, def_zone, P)
src <<"\red You have been hit by [P]!"
if(!P.nodamage)
- apply_damage(P.damage, P.damage_type, def_zone, absorb, 0, P, sharp=proj_sharp, edge=proj_edge)
+ apply_damage(P.damage, P.damage_type, def_zone, absorb, soaked, 0, P, sharp=proj_sharp, edge=proj_edge)
qdel(P)
return
if(!P.nodamage)
- apply_damage(P.damage, P.damage_type, def_zone, absorb, 0, P, sharp=proj_sharp, edge=proj_edge)
- P.on_hit(src, absorb, def_zone)
+ apply_damage(P.damage, P.damage_type, def_zone, absorb, soaked, 0, P, sharp=proj_sharp, edge=proj_edge)
+ P.on_hit(src, absorb, soaked, def_zone)
if(absorb == 100)
return 2
@@ -153,17 +166,21 @@
/mob/living/proc/hit_with_weapon(obj/item/I, mob/living/user, var/effective_force, var/hit_zone)
visible_message("[src] has been [I.attack_verb.len? pick(I.attack_verb) : "attacked"] with [I.name] by [user]!")
+ var/soaked = get_armor_soak(hit_zone, "melee")
var/blocked = run_armor_check(hit_zone, "melee")
- standard_weapon_hit_effects(I, user, effective_force, blocked, hit_zone)
- if(I.damtype == BRUTE && prob(33)) // Added blood for whacking non-humans too
- var/turf/simulated/location = get_turf(src)
- if(istype(location)) location.add_blood_floor(src)
+ //If the armor absorbs all of the damage, skip the damage calculation and the blood
+ if(!soaked > effective_force)
+ standard_weapon_hit_effects(I, user, effective_force, blocked, soaked, hit_zone)
+
+ if(I.damtype == BRUTE && prob(33)) // Added blood for whacking non-humans too
+ var/turf/simulated/location = get_turf(src)
+ if(istype(location)) location.add_blood_floor(src)
return blocked
//returns 0 if the effects failed to apply for some reason, 1 otherwise.
-/mob/living/proc/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/hit_zone)
+/mob/living/proc/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/soaked, var/hit_zone)
if(!effective_force || blocked >= 100)
return 0
@@ -171,6 +188,10 @@
if(HULK in user.mutations)
effective_force *= 2
+ //Armor soak
+ if(soaked >= effective_force)
+ return 0
+
//Apply weapon damage
var/weapon_sharp = is_sharp(I)
var/weapon_edge = has_edge(I)
@@ -178,7 +199,7 @@
weapon_sharp = 0
weapon_edge = 0
- apply_damage(effective_force, I.damtype, hit_zone, blocked, sharp=weapon_sharp, edge=weapon_edge, used_weapon=I)
+ apply_damage(effective_force, I.damtype, hit_zone, blocked, soaked, sharp=weapon_sharp, edge=weapon_edge, used_weapon=I)
return 1
@@ -200,8 +221,10 @@
src.visible_message("\red [src] has been hit by [O].")
var/armor = run_armor_check(null, "melee")
+ var/soaked = get_armor_soak(null, "melee")
- apply_damage(throw_damage, dtype, null, armor, is_sharp(O), has_edge(O), O)
+
+ apply_damage(throw_damage, dtype, null, armor, soaked, is_sharp(O), has_edge(O), O)
O.throwing = 0 //it hit, so stop moving
@@ -230,6 +253,9 @@
if(!O || !src) return
if(O.sharp) //Projectile is suitable for pinning.
+ if(soaked >= throw_damage) //Don't embed if it didn't actually damage
+ return
+
//Handles embedding for non-humans and simple_animals.
embed(O)
diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm
index f4de3b6054..49c82ccca2 100644
--- a/code/modules/mob/living/simple_animal/hostile/bear.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bear.dm
@@ -135,7 +135,7 @@
var/mob/living/carbon/human/H = target_mob
var/dam_zone = pick(BP_TORSO, BP_L_HAND, BP_R_HAND, BP_L_LEG, BP_R_LEG)
var/obj/item/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
- H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1, edge=1)
+ H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), H.get_armor_soak(affecting, "melee"), sharp=1, edge=1)
return H
else if(isliving(target_mob))
var/mob/living/L = target_mob
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index 36a1ac186a..593e761cba 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -477,7 +477,7 @@
var/mob/living/carbon/human/H = parrot_interest
var/obj/item/organ/external/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone)))
- H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1)
+ H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), H.get_armor_soak(affecting, "melee"), sharp=1)
visible_emote(pick("pecks [H]'s [affecting].", "cuts [H]'s [affecting] with its talons."))
else
diff --git a/code/modules/mob/mob_grab_specials.dm b/code/modules/mob/mob_grab_specials.dm
index e7b75a2e5d..e06da4eb5e 100644
--- a/code/modules/mob/mob_grab_specials.dm
+++ b/code/modules/mob/mob_grab_specials.dm
@@ -56,7 +56,8 @@
return
var/armor = target.run_armor_check(target, "melee")
- if(armor < 60)
+ var/soaked = target.get_armor_soak(target, "melee")
+ if(armor + soaked < 60)
target << "You feel extreme pain!"
var/max_halloss = round(target.species.total_health * 0.8) //up to 80% of passing out
@@ -100,8 +101,9 @@
damage += hat.force * 3
var/armor = target.run_armor_check(BP_HEAD, "melee")
- target.apply_damage(damage, BRUTE, BP_HEAD, armor)
- attacker.apply_damage(10, BRUTE, BP_HEAD, attacker.run_armor_check(BP_HEAD, "melee"))
+ var/soaked = target.get_armor_soak(BP_HEAD, "melee")
+ target.apply_damage(damage, BRUTE, BP_HEAD, armor, soaked)
+ attacker.apply_damage(10, BRUTE, BP_HEAD, attacker.run_armor_check(BP_HEAD), attacker.get_armor_soak(BP_HEAD), "melee")
if(!armor && target.headcheck(BP_HEAD) && prob(damage))
target.apply_effect(20, PARALYZE)
diff --git a/code/modules/planet/weather.dm b/code/modules/planet/weather.dm
index d4d13d7a40..21ed506664 100644
--- a/code/modules/planet/weather.dm
+++ b/code/modules/planet/weather.dm
@@ -260,9 +260,13 @@
var/target_zone = pick(BP_ALL)
var/amount_blocked = L.run_armor_check(target_zone, "melee")
+ var/amount_soaked = L.get_armor_soak(target_zone, "melee")
if(amount_blocked >= 100)
return // No need to apply damage.
- L.apply_damage(rand(5, 10), BRUTE, target_zone, amount_blocked, used_weapon = "hail")
+ if(amount_soaked >= 10)
+ return // No need to apply damage.
+
+ L.apply_damage(rand(5, 10), BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail")
to_chat(L, "The hail raining down on you [L.can_feel_pain() ? "hurts" : "damages you"]!")