From 5f06d51da37017301aec1b47bde158c817aed213 Mon Sep 17 00:00:00 2001 From: FenodyreeAv Date: Tue, 7 Apr 2026 15:52:10 +0100 Subject: [PATCH] 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 --- .../technomancer/spells/energy_siphon.dm | 1 + .../overmap/ship_weaponry/_ship_ammunition.dm | 1 + code/modules/projectiles/projectile.dm | 18 +++++- .../modules/projectiles/projectile/bullets.dm | 27 ++++----- .../Fenodyree-ProjectilePiercingFix.yml | 58 +++++++++++++++++++ 5 files changed, 85 insertions(+), 20 deletions(-) create mode 100644 html/changelogs/Fenodyree-ProjectilePiercingFix.yml diff --git a/code/game/gamemodes/technomancer/spells/energy_siphon.dm b/code/game/gamemodes/technomancer/spells/energy_siphon.dm index 4da9cdf1c8e..7d21991b3f7 100644 --- a/code/game/gamemodes/technomancer/spells/energy_siphon.dm +++ b/code/game/gamemodes/technomancer/spells/energy_siphon.dm @@ -177,6 +177,7 @@ icon_state = "lightning" range = 6 // Backup plan in-case the effect somehow misses the Technomancer. power = 5 // This fires really fast, so this may add up if someone keeps standing in the beam. + projectile_piercing = PASSMOB //This is the only energy projectile with penetrating. penetrating = 5 /obj/projectile/beam/lightning/energy_siphon/Bump(atom/A as mob|obj|turf|area, forced=0) diff --git a/code/modules/overmap/ship_weaponry/_ship_ammunition.dm b/code/modules/overmap/ship_weaponry/_ship_ammunition.dm index 85496c64a9e..cc3aacb1566 100644 --- a/code/modules/overmap/ship_weaponry/_ship_ammunition.dm +++ b/code/modules/overmap/ship_weaponry/_ship_ammunition.dm @@ -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. diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 6f1d2253e54..794cc6680fe 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -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 diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 2c6b206a080..eb6a3109e38 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -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 diff --git a/html/changelogs/Fenodyree-ProjectilePiercingFix.yml b/html/changelogs/Fenodyree-ProjectilePiercingFix.yml new file mode 100644 index 00000000000..23f409cd80d --- /dev/null +++ b/html/changelogs/Fenodyree-ProjectilePiercingFix.yml @@ -0,0 +1,58 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# - (fixes bugs) +# wip +# - (work in progress) +# qol +# - (quality of life) +# soundadd +# - (adds a sound) +# sounddel +# - (removes a sound) +# rscadd +# - (adds a feature) +# rscdel +# - (removes a feature) +# imageadd +# - (adds an image or sprite) +# imagedel +# - (removes an image or sprite) +# spellcheck +# - (fixes spelling or grammar) +# experiment +# - (experimental change) +# balance +# - (balance changes) +# code_imp +# - (misc internal code change) +# refactor +# - (refactors code) +# config +# - (makes a change to the config files) +# admin +# - (makes changes to administrator tools) +# server +# - (miscellaneous changes to server) +################################# + +# Your name. +author: Fenodyree + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - bugfix: "Fixes projectile piercing, some rifle bullets and most ship-weapons will now pierce through most things."