Projectile piercing fix (#22157)

Fixes the fact that no projectiles could pierce.
Uses the bitflags introduced in the projectile refactor.
Only some heavy rifle bullets and most ship weapons will pierce.
This also indirectly fixes how anemic all the non-explosive ship weapons
were.

This should probably also check armour piercing, the armor on a mob and
have some values tweaked for some weapons, but I wanted to keep this a
pure bugfix, so the numbers are exactly as they were before this was
broken.

Lore people might want to check their weapons to decide what they should
pierce, how much and how often.



https://github.com/user-attachments/assets/538a3a21-a796-4a81-ba53-6f91addd6785
This commit is contained in:
FenodyreeAv
2026-04-07 14:52:10 +00:00
committed by GitHub
parent 5b2394ecae
commit 5f06d51da3
5 changed files with 85 additions and 20 deletions
@@ -224,6 +224,7 @@
anti_materiel_potential = 3
impact_sounds = list(BULLET_IMPACT_MEAT = SOUNDS_BULLET_MEAT, BULLET_IMPACT_METAL = SOUNDS_BULLET_METAL)
accuracy = 100
projectile_piercing = PASSMOB|PASSDOORS|PASSGLASS|PASSCLOSEDTURF|PASSWINDOW|PASSMACHINE|PASSBLOB|PASSFLAPS|PASSVEHICLE //It's a ship weapon let it try to penetrate everything.
var/obj/item/ship_ammunition/ammo
var/primed = FALSE
var/hit_target = FALSE //First target we hit. Used to report if a hit was successful.
+15 -3
View File
@@ -74,7 +74,10 @@
var/projectile_piercing = NONE
/// Number of times we've pierced something. Incremented BEFORE bullet_act and on_hit proc!
var/pierces = 0
///The base chance that a projectile capable of piercing will actually pierce.
var/pierce_chance = 0
///Used to determine whether or not to apply embed chances on hit.
var/last_hit_pierced = FALSE
/// If objects are below this layer, we pass through them.
var/hit_threshhold = PROJECTILE_HIT_THRESHHOLD_LAYER
@@ -234,7 +237,7 @@
var/reflected = FALSE
/// If greater than zero, the projectile will pass through dense objects as specified by on_penetrate()
/// If greater than zero, the projectile will pass through dense objects as specified by prehit_pierce()
var/penetrating = 0
/// For KAs, really.
@@ -647,11 +650,17 @@
if((projectile_phasing & A.pass_flags_self) && (phasing_ignore_direct_target || original != A))
return PROJECTILE_PIERCE_PHASE
if(projectile_piercing & A.pass_flags_self)
return PROJECTILE_PIERCE_HIT
if (penetrating > pierces)
if(damage > 20 && prob(pierce_chance + damage))
penetrating--
last_hit_pierced = TRUE
return PROJECTILE_PIERCE_HIT
if(ismovable(A))
var/atom/movable/AM = A
if(AM.throwing)
return (projectile_phasing & LETPASSTHROW) ? PROJECTILE_PIERCE_PHASE : ((projectile_piercing & LETPASSTHROW)? PROJECTILE_PIERCE_HIT : PROJECTILE_PIERCE_NONE)
last_hit_pierced = FALSE
return PROJECTILE_PIERCE_NONE
/obj/projectile/proc/check_ricochet(atom/A)
@@ -1137,6 +1146,9 @@
/// Checks if the projectile is eligible for embedding. Not that it necessarily will.
/obj/projectile/proc/can_embed()
//embed must be enabled and damage type must be brute
if (projectile_piercing & PASSMOB) //If the shot passes through you it can't embed.
if (last_hit_pierced)
return FALSE
if(!embed || damage_type != DAMAGE_BRUTE)
return FALSE
return TRUE
+10 -17
View File
@@ -8,7 +8,7 @@
embed = TRUE
sharp = TRUE
shrapnel_type = /obj/item/material/shard/shrapnel
var/mob_passthrough_check = 0
projectile_piercing = PASSMOB|PASSFLAPS|PASSGRILLE //These are the things it can piece, a number of times up to 'penetrating', if it actually does pierce is decided by projectile/prehit_pierce()
muzzle_type = /obj/effect/projectile/muzzle/bullet
@@ -16,17 +16,6 @@
if(isliving(target) && (..(target, blocked, def_zone) == BULLET_ACT_HIT))
var/mob/living/L = target
shake_camera(L, 3, 2)
if(penetrating > 0 && damage > 20 && prob(damage))
mob_passthrough_check = 1
else
mob_passthrough_check = 0
return ..()
/obj/projectile/bullet/can_embed()
//prevent embedding if the projectile is passing through the mob
if(mob_passthrough_check)
return 0
return ..()
/**
@@ -276,11 +265,12 @@
damage = 40
armor_penetration = 15
penetrating = FALSE
projectile_piercing = PASSMOB|PASSFLAPS|PASSGRILLE|PASSDOORS|PASSDOORHATCH|PASSCLOSEDTURF|PASSWINDOW|PASSGLASS|PASSMACHINE
/obj/projectile/bullet/rifle/a762
damage = 35
armor_penetration = 22
penetrating = TRUE
penetrating = 1
/obj/projectile/bullet/rifle/a556
damage = 30
@@ -290,7 +280,7 @@
/obj/projectile/bullet/rifle/a556/ap
damage = 25
armor_penetration = 45
penetrating = TRUE
penetrating = 1
/obj/projectile/bullet/rifle/a556/polymer
damage = 25
@@ -312,7 +302,7 @@
name = "Z33s Tamparii bullet"
damage = 30
armor_penetration = 30
penetrating = TRUE
penetrating = 1
/obj/projectile/bullet/rifle/a145
damage = 80
@@ -327,13 +317,13 @@
/obj/projectile/bullet/rifle/kumar_super
damage = 40
armor_penetration = 30
penetrating = TRUE
penetrating = 1
/obj/projectile/bullet/rifle/vintage
name = ".30-06 Govt. bullet"
damage = 50
weaken = 1
penetrating = TRUE
penetrating = 1
/obj/projectile/bullet/rifle/govt
name = ".40-70 Govt. bullet"
@@ -459,6 +449,8 @@
embed = 1
sharp = 1
penetrating = 1
projectile_piercing = PASSMOB|PASSFLAPS|PASSGRILLE|PASSDOORS|PASSDOORHATCH|PASSCLOSEDTURF|PASSWINDOW|PASSGLASS|PASSMACHINE
muzzle_type = /obj/effect/projectile/muzzle/pulse
@@ -559,6 +551,7 @@
anti_materiel_potential = 6
embed = FALSE
penetrating = 1
projectile_piercing = PASSMOB|PASSDOORS|PASSGLASS|PASSCLOSEDTURF|PASSWINDOW|PASSMACHINE|PASSBLOB|PASSFLAPS|PASSVEHICLE //It's designed to penetrate mechs.
var/devastation_range = -1
var/heavy_impact_range = -1