Refactor bullet mechanics: add HEAT/SUBCALIBER/FRAG enum types, penetration loss, and fragmentation damage#3
Conversation
…ration loss, and fragmentation damage - Add HEAT, SUBCALIBER, and FRAG to BulletType enum, deprecate isHeat boolean (backwards compatible) - Add fragmentation parameters: fragConeAngle, fragHitProbability, fragDamage to JSONBullet - Implement penetration loss for kinetic (non-HEAT) rounds based on armor thickness ratio - Implement fragmentation damage to internal parts and crew when FRAG bullet penetrates armor https://claude.ai/code/session_01L7GeMnAYtRwxzvzDwnTyRH
…ll-rework
- Fix frag crew damage: use PacketEntityBulletHitExternalEntity for proper
client/server handling (was using server-only rider.attack() which never
executed since bullet checks run on client)
- Adapt HEAT shell behavior from heat-shell-rework branch:
- HEAT shells always detonate on armor contact (return ARMOR, stop flying)
- On successful penetration, apply post-pen damage proportional to residual
penetration ratio to both vehicle entity and all crew members
- Add missing PacketEntityBulletHitExternalEntity import
https://claude.ai/code/session_01L7GeMnAYtRwxzvzDwnTyRH
… messages - coneRange was diameter/100 (0.75m for 75mm) — far too small to reach any internal parts. Changed to diameter/10 (7.5m for 75mm) - Removed distToPart > 0 check that filtered parts at the hit point - Added zero-length vector guard to prevent NaN from acos - Added FRAG ACTIVATED debug message at block entry to confirm code is reached - Enhanced hit debug messages with distance and angle info for diagnostics https://claude.ai/code/session_01L7GeMnAYtRwxzvzDwnTyRH
- Add MISSILE type for guided projectiles and BOMB type for unguided drops - Simplify all new debug messages to match mod's terse style https://claude.ai/code/session_01L7GeMnAYtRwxzvzDwnTyRH
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bd72b0275f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| InterfaceManager.packetInterface.sendToServer(new PacketEntityBulletHitEntity(bullet.gun, part, fragDamage)); | ||
| } else { | ||
| EntityBullet.performEntityHitLogic(part, fragDamage); | ||
| } |
There was a problem hiding this comment.
Avoid mutating allParts during FRAG iteration
This branch applies damage to part while attackProjectile is iterating allParts, and APart.attack() can call removePart(), which rebuilds allParts. In server-side bullet simulation (for isLongRange bullets or NPC-fired bullets), a FRAG hit that destroys a part will mutate the collection mid-iteration and can raise ConcurrentModificationException, aborting hit processing. Iterate over a snapshot/list copy (or pre-collect targets) before applying fragment damage.
Useful? React with 👍 / 👎.
| //If the bullet has FRAG type and penetrated armor, deal fragmentation damage to internals. | ||
| if (bullet.definition.bullet.types.contains(BulletType.FRAG) && bullet.definition.bullet.fragDamage > 0) { | ||
| float coneAngle = bullet.definition.bullet.fragConeAngle > 0 ? bullet.definition.bullet.fragConeAngle : 45.0f; | ||
| float hitProbability = bullet.definition.bullet.fragHitProbability > 0 ? bullet.definition.bullet.fragHitProbability : 0.5f; |
There was a problem hiding this comment.
Respect explicit zero frag hit probability
Using > 0 to decide whether to apply a default makes fragHitProbability: 0.0 impossible: it is treated as "unset" and replaced with 0.5, so fragments still hit 50% of the time. That breaks the documented 0.0–1.0 behavior and can cause unexpected internal/crew damage when pack authors intentionally configure zero chance. Defaulting should use a distinct sentinel (for example negative values) or clamp the provided value directly.
Useful? React with 👍 / 👎.
https://claude.ai/code/session_01L7GeMnAYtRwxzvzDwnTyRH