Fixes armour checks, rubbers checking siemens and pain interrupting t… (#23023)

**_- bugfix: "Fixes all rubber bullets dealing damage twice."_**
Rubber bullets were dealing their pain damage twice, while checking if
they should shake your screen or not.

_**- bugfix: "Fixes all attacks that dealt pain damage checking siemens
coefficient. This makes everything but hardsuits and voidsuits stronger
against rubber bullets. Insulated gloves are also no longer immune to
rubber bullets."**_

Hardsuits has siemens 0.1, meaning they took 10% damage from all stuns.
Now rubber bullets check their melee armor. Hardsuits are now weaker, or
the same against stuns.

Regular armor all has siemens 0.5, they took a flat 50% reduction.
Security armour is slightly weaker to rubbers, ablative and ballistic
are much weaker. Combat armour is roughly the same, or slightly better.
Riot armour is a lot better.

Voidsuits all had better siemens than armour, all voidsuits are now
weaker against stuns.

Finally, all jumpsuits had 0.75 siemens, but no (or nearly no) armor.
Combined with the fix of them hitting twice this means that rubber
bullets previously dealt 50% more damage against people in jumpsuits
than they do now.

**_- bugfix: "Fixes pain failing to make your blurt out whatever you
were typing. Now getting shot will cause you to say whatever was in the
typing window when you were hit and close the window immediately,
allowing you to move."_**

No more getting stuck in the typing window when you're getting sprayed
down by an STS!
 

_**- bugfix: "Fixes all attacks that had manually set armour checks,
previously they ignored the armour they were meant to check and decided
what armour affected them based only on their damage type."**_

Weapons that were set to specifically target armour types, such as
explosive projectiles (rockets, etc) were instead defaulting to the
damage type they dealt. So a rocket to the head was checking your melee
armour, not your bomb armour.

---------

Signed-off-by: FenodyreeAv <fenodyree.av@gmail.com>
This commit is contained in:
FenodyreeAv
2026-08-16 16:13:03 +00:00
committed by GitHub
parent 5f78469fce
commit be17521156
18 changed files with 66 additions and 38 deletions
+7 -4
View File
@@ -35,7 +35,7 @@
* Applies state changes to self, holder, and whatever else caused by damage mitigation
* Returns modified damage, a list to allow for flag modification or damage conversion, in the same format as the arguments.
*/
/datum/component/armor/proc/apply_damage_modifications(damage, damage_type, damage_flags, mob/living/victim, armor_pen, silent = FALSE)
/datum/component/armor/proc/apply_damage_modifications(damage, damage_type, damage_flags, mob/living/victim, armor_pen, silent = FALSE, check_armor)
if(armor_flags & ARMOR_TYPE_EXOSUIT)
if(prob(get_blocked(damage_type, damage_flags, armor_pen) * 100)) //extra removal of sharp and edge on account of us being big robots
damage_flags &= ~(DAMAGE_FLAG_SHARP | DAMAGE_FLAG_EDGE)
@@ -43,7 +43,8 @@
if(damage <= 0)
return args.Copy()
var/blocked = get_blocked(damage_type, damage_flags, armor_pen, damage)
var/blocked = get_blocked(damage_type, damage_flags, armor_pen, damage, check_armor)
on_blocking(damage, damage_type, damage_flags, armor_pen, blocked)
// Blocking values that mean the damage was under armor, so all dangerous flags are removed (edge/sharp)
@@ -74,8 +75,10 @@
* under_armor_mult is used to determine how much damage is mitigated when the incoming damage is less than or equal to the armor value
* over_armor_mult is used to determine how much damage is mitigated when the incoming damage is greater than the armor value
*/
/datum/component/armor/proc/get_blocked(damage_type, damage_flags, armor_pen = 0, damage = 5)
var/key = get_armor_key(damage_type, damage_flags)
/datum/component/armor/proc/get_blocked(damage_type, damage_flags, armor_pen = 0, damage = 5, check_armor)
var/key = check_armor
if(!key)
key = get_armor_key(damage_type, damage_flags)
if(!key)
return 0
+1 -1
View File
@@ -472,7 +472,7 @@
playsound(loc, 'sound/weapons/Egloves.ogg', 100, 1, -1)
set_cooldown(cooldowntime)
H.stun_effect_act(2, 120, target_zone)
H.stun_effect_act(2, 120, DAMAGE_PAIN, target_zone, check_armor = ENERGY)
var/burn_damage = H.electrocute_act(burn_damage_amt*2, src, def_zone = target_zone)
if(burn_damage > 15 && H.can_feel_pain())
H.emote("scream")
+1 -1
View File
@@ -200,7 +200,7 @@
target_mob.visible_message(SPAN_DANGER("[target_mob] has been prodded with \the [src] by [user]!"))
//stun effects
target_mob.stun_effect_act(stun, agony, target_zone, src)
target_mob.stun_effect_act(stun, agony, DAMAGE_PAIN, target_zone, src)
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
+1 -1
View File
@@ -104,7 +104,7 @@
else
return body
/mob/living/heavy_vehicle/apply_damage(damage = 0, damagetype = DAMAGE_BRUTE, def_zone, used_weapon, damage_flags = 0, armor_pen, silent = FALSE)
/mob/living/heavy_vehicle/apply_damage(damage = 0, damagetype = DAMAGE_BRUTE, def_zone, used_weapon, damage_flags = 0, armor_pen, silent = FALSE, check_armor)
if(!damage)
return 0
@@ -424,7 +424,7 @@
msg_admin_attack("An integrated circuit with a shocker circuit was used to shock [M.name] ([M.ckey]) (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
to_chat(M, SPAN_DANGER("You feel a sharp shock from the [src]!"))
spark(get_turf(M), 3, 1)
M.stun_effect_act(0, clamp(get_pin_data(IC_INPUT, 2), 0, 30), null)
M.stun_effect_act(0, clamp(get_pin_data(IC_INPUT, 2), 0, 30), DAMAGE_PAIN, null)
shocktime = world.time
@@ -453,7 +453,7 @@ This function restores all organs.
if(zone_to_get in organs_by_name)
return organs_by_name[zone_to_get]
/mob/living/carbon/human/apply_damage(damage = 0, damagetype = DAMAGE_BRUTE, def_zone, used_weapon, damage_flags = 0, armor_pen, silent = FALSE)
/mob/living/carbon/human/apply_damage(damage = 0, damagetype = DAMAGE_BRUTE, def_zone, used_weapon, damage_flags = 0, armor_pen, silent = FALSE, check_armor)
if (invisibility == INVISIBILITY_LEVEL_TWO && back && (istype(back, /obj/item/rig)))
if(damage > 0)
to_chat(src, SPAN_DANGER("You are now visible."))
@@ -492,13 +492,14 @@ This function restores all organs.
//Handle other types of damage
if(!(damagetype in list(DAMAGE_BRUTE, DAMAGE_BURN, DAMAGE_PAIN, DAMAGE_CLONE)))
if(!stat && damagetype == DAMAGE_PAIN)
if((damage > 25) || (damage > 50))
force_say()
if((damage > 25 && prob(20) || (damage > 50 && prob(60))))
emote("scream")
return ..()
if(!stat && damagetype == DAMAGE_PAIN)
if((damage > 25))
force_say()
if((damage > 25 && prob(20) || (damage > 50 && prob(60))))
emote("scream")
if(!organ)
return FALSE
@@ -41,11 +41,23 @@ emp_act
if(prob(20 + max(hitting_projectile.damage + hitting_projectile.embed_chance - armor, -10)))
hitting_projectile.do_embed(organ)
/mob/living/carbon/human/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone, var/used_weapon, var/damage_flags)
/mob/living/carbon/human/stun_effect_act(var/stun_amount, var/agony_amount, var/damage_type, var/def_zone, var/used_weapon, var/damage_flags, var/check_armor)
var/obj/item/organ/external/affected = get_organ(check_zone(def_zone))
var/siemens_coeff = get_siemens_coefficient_organ(affected)
stun_amount *= siemens_coeff
agony_amount *= siemens_coeff
var/obj/attack_source = used_weapon
var/stun_after_armor = stun_amount
var/agony_after_armor = agony_amount
if(damage_type)
if (check_armor != ENERGY && check_armor != LASER)
if(agony_amount)
agony_after_armor *= (1 - get_blocked_ratio(def_zone, damage_type, damage_flags, attack_source.armor_penetration, agony_amount, check_armor))
if(stun_amount)
stun_after_armor *= (1 - get_blocked_ratio(def_zone, damage_type, damage_flags, attack_source.armor_penetration, stun_amount, check_armor))
if (!check_armor || check_armor == ENERGY || check_armor == LASER)
stun_after_armor *= siemens_coeff
agony_after_armor *= siemens_coeff
switch (def_zone)
if(BP_HEAD)
@@ -68,9 +80,9 @@ emp_act
var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ")
visible_message("<b>[src]</b> [(!can_feel_pain()) ? "" : emote_scream ]drops what they were holding in their [affected.name]!")
..(stun_amount, agony_amount, def_zone, used_weapon, damage_flags)
..(stun_after_armor, agony_after_armor, damage_type, def_zone, used_weapon, damage_flags)
/mob/living/carbon/human/get_blocked_ratio(def_zone, damage_type, damage_flags, armor_pen, damage)
/mob/living/carbon/human/get_blocked_ratio(def_zone, damage_type, damage_flags, armor_pen, damage, check_armor)
if(!def_zone && (damage_flags & DAMAGE_FLAG_DISPERSED))
var/tally
for(var/zone in GLOB.organ_rel_size)
+2 -2
View File
@@ -8,13 +8,13 @@
standard 0 if fail
*/
/mob/living/proc/apply_damage(damage = 0, damagetype = DAMAGE_BRUTE, def_zone, used_weapon, damage_flags = 0, armor_pen, silent = FALSE)
/mob/living/proc/apply_damage(damage = 0, damagetype = DAMAGE_BRUTE, def_zone, used_weapon, damage_flags = 0, armor_pen, silent = FALSE, check_armor = null)
SHOULD_NOT_SLEEP(TRUE)
if(!damage)
return FALSE
var/list/after_armor = modify_damage_by_armor(def_zone, damage, damagetype, damage_flags, src, armor_pen, silent)
var/list/after_armor = modify_damage_by_armor(def_zone, damage, damagetype, damage_flags, src, armor_pen, silent, check_armor)
damage = after_armor[1]
damagetype = after_armor[2]
damage_flags = after_armor[3] // args modifications in case of parent calls
+8 -8
View File
@@ -1,5 +1,5 @@
/mob/living/proc/modify_damage_by_armor(def_zone, damage, damage_type, damage_flags, mob/living/victim, armor_pen, silent = FALSE)
var/list/armors = get_armors_by_zone(def_zone, damage_type, damage_flags)
/mob/living/proc/modify_damage_by_armor(def_zone, damage, damage_type, damage_flags, mob/living/victim, armor_pen, silent = FALSE, check_armor)
var/list/armors = get_armors_by_zone(def_zone, damage_type, damage_flags, check_armor)
. = args.Copy(2)
for(var/armor in armors)
var/datum/component/armor/armor_datum = armor
@@ -8,18 +8,18 @@
/mob/living/check_projectile_armor(def_zone, obj/projectile/impacting_projectile, is_silent)
if(impacting_projectile.damage > 0) // Run the block computation if we did damage or if we only use armor for effects (nodamage)
//Since we get a ratio from this and we need a percentage, we multiply by 100 to get the percentage
return (get_blocked_ratio(def_zone, impacting_projectile.damage_type, impacting_projectile.damage_flags(), impacting_projectile.armor_penetration, impacting_projectile.damage) * 100)
return (get_blocked_ratio(def_zone, impacting_projectile.damage_type, impacting_projectile.damage_flags(), impacting_projectile.armor_penetration, impacting_projectile.damage, impacting_projectile.check_armor) * 100)
return 0
/mob/living/proc/get_blocked_ratio(def_zone, damage_type, damage_flags, armor_pen, damage)
var/list/armors = get_armors_by_zone(def_zone, damage_type, damage_flags)
/mob/living/proc/get_blocked_ratio(def_zone, damage_type, damage_flags, armor_pen, damage, check_armor)
var/list/armors = get_armors_by_zone(def_zone, damage_type, damage_flags, check_armor)
. = 0
for(var/armor in armors)
var/datum/component/armor/armor_datum = armor
. = 1 - (1 - .) * (1 - armor_datum.get_blocked(damage_type, damage_flags, armor_pen, damage)) // multiply the amount we let through
. = 1 - (1 - .) * (1 - armor_datum.get_blocked(damage_type, damage_flags, armor_pen, damage, check_armor)) // multiply the amount we let through
. = min(1, .)
/mob/living/proc/get_armors_by_zone(def_zone, damage_type, damage_flags)
/mob/living/proc/get_armors_by_zone(def_zone, damage_type, damage_flags, check_armor)
. = list()
var/natural_armor = GetComponent(/datum/component/armor)
if(natural_armor)
@@ -185,7 +185,7 @@
return BULLET_IMPACT_MEAT
//Handles the effects of "stun" weapons
/mob/living/proc/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone, var/used_weapon, var/damage_flags)
/mob/living/proc/stun_effect_act(var/stun_amount, var/agony_amount, var/damage_type, var/def_zone, var/used_weapon, var/damage_flags, var/check_armor)
flash_pain(stun_amount)
if(stun_amount)
@@ -15,6 +15,6 @@
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
M.apply_effect(5, STUTTER)
M.stun_effect_act(0, 70, check_zone(hit_zone), src)
M.stun_effect_act(0, 70, DAMAGE_PAIN, check_zone(hit_zone), src)
return FALSE
+1 -1
View File
@@ -117,7 +117,7 @@
to_chat(src, SPAN_DANGER("BZZZT"))
to_chat(src, SPAN_WARNING("Warning: Electromagnetic pulse detected."))
/mob/living/silicon/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone, var/used_weapon, var/damage_flags)
/mob/living/silicon/stun_effect_act(var/stun_amount, var/agony_amount, var/damage_type, var/def_zone, var/used_weapon, var/damage_flags)
return //immune
/mob/living/silicon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1.0, var/def_zone = null, tesla_shock = FALSE, ground_zero)
@@ -104,7 +104,7 @@
var/datum/weakref/original_body
var/datum/weakref/possessed_body
/mob/living/simple_animal/shade/bluespace/apply_damage(damage = 0, damagetype = DAMAGE_BRUTE, def_zone, used_weapon, damage_flags = 0, armor_pen, silent = FALSE)
/mob/living/simple_animal/shade/bluespace/apply_damage(damage = 0, damagetype = DAMAGE_BRUTE, def_zone, used_weapon, damage_flags = 0, armor_pen, silent = FALSE, check_armor)
return 0
/mob/living/simple_animal/shade/bluespace/adjustBruteLoss()
@@ -718,7 +718,7 @@
if(ismob(hitting_projectile.firer))
handle_attack_by(hitting_projectile.firer)
/mob/living/simple_animal/apply_damage(damage = 0, damagetype = DAMAGE_BRUTE, def_zone, used_weapon, damage_flags = 0, armor_pen, silent = FALSE)
/mob/living/simple_animal/apply_damage(damage = 0, damagetype = DAMAGE_BRUTE, def_zone, used_weapon, damage_flags = 0, armor_pen, silent = FALSE, check_armor)
. = ..()
handle_bleeding_timer(damage)
handle_blood()
+1 -1
View File
@@ -661,7 +661,7 @@
if(owner.a_intent == I_HURT)
H.electrocute_act(10, owner, def_zone = target_zone)
else
H.stun_effect_act(0, 50, target_zone, owner)
H.stun_effect_act(0, 50, DAMAGE_PAIN, target_zone, owner, check_armor = ENERGY)
owner.visible_message(SPAN_DANGER("[H] has been prodded with [src] by [owner]!"))
playsound(get_turf(owner), 'sound/weapons/Egloves.ogg', 50, 1, -1)
+4 -2
View File
@@ -331,8 +331,10 @@
var/mob/living/living_target = target
living_target.apply_effects(0, weaken, paralyze, 0, stutter, eyeblur, drowsy, 0, incinerate, blocked)
living_target.stun_effect_act(stun, agony, def_zone, src, damage_flags)
living_target.apply_damage(irradiate, DAMAGE_RADIATION, damage_flags = DAMAGE_FLAG_DISPERSED) //radiation protection is handled separately from other armor types.
if(stun || agony)
living_target.stun_effect_act(stun, agony, DAMAGE_PAIN, def_zone, src, damage_flags, check_armor)
if(irradiate)
living_target.apply_damage(irradiate, DAMAGE_RADIATION, def_zone, check_armor = check_armor) //radiation protection is handled separately from other armor types.
if(!do_not_log)
log_combat(firer, living_target, "shot", src)
@@ -14,7 +14,7 @@
muzzle_type = /obj/effect/projectile/muzzle/bullet
/obj/projectile/bullet/on_hit(atom/target, blocked, def_zone)
if(isliving(target) && (..(target, blocked, def_zone) == BULLET_ACT_HIT))
if(isliving(target) && blocked < 100)
var/mob/living/L = target
shake_camera(L, 3, 2)
return ..()
@@ -112,6 +112,7 @@
name = "rubber ball"
icon_state = "pellets"
damage = 2
check_armor = MELEE
agony = 50
embed = FALSE
var/balls = 4
@@ -0,0 +1,9 @@
author: Fenodyree
delete-after: True
changes:
- bugfix: "Fixes all rubber bullets dealing damage twice."
- bugfix: "Fixes all attacks that dealt pain damage checking siemens coefficient. This makes everything but hardsuits and voidsuits stronger against rubber bullets. Insulated gloves are also no longer immune to rubber bullets."
- bugfix: "Fixes pain failing to make you blurt out whatever you were typing. Now getting shot will cause you to say whatever was in the typing window when you were hit and close the window immediately, allowing you to move."
- bugfix: "Fixes all attacks that had manually set armour checks, previously they ignored the armour they were meant to check and decided what armour affected them based only on their damage type."
@@ -261,7 +261,7 @@ GLOBAL_LIST_EMPTY(trackables_pool)
if(mob_in_disguise && isliving(hit_mob)) // we hit a mob? Disguise is gone
disregard_the_disguise()
/mob/living/simple_animal/hostile/revivable/abomination/apply_damage(damage = 0, damagetype = DAMAGE_BRUTE, def_zone, blocked, used_weapon, damage_flags = 0, armor_pen, silent = FALSE)
/mob/living/simple_animal/hostile/revivable/abomination/apply_damage(damage = 0, damagetype = DAMAGE_BRUTE, def_zone, blocked, used_weapon, damage_flags = 0, armor_pen, silent = FALSE, check_armor)
. = ..()
if(mob_in_disguise && damage) // we were hit? Disguise is gone
disregard_the_disguise()