Skip to content

Refactor bullet mechanics: add HEAT/SUBCALIBER/FRAG enum types, penetration loss, and fragmentation damage#3

Closed
dldev32 wants to merge 5 commits into
masterfrom
claude/refactor-bullet-mechanics-86QY4
Closed

Refactor bullet mechanics: add HEAT/SUBCALIBER/FRAG enum types, penetration loss, and fragmentation damage#3
dldev32 wants to merge 5 commits into
masterfrom
claude/refactor-bullet-mechanics-86QY4

Conversation

@dldev32
Copy link
Copy Markdown
Owner

@dldev32 dldev32 commented Apr 9, 2026

  • 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

claude added 5 commits April 2, 2026 09:31
…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
@dldev32 dldev32 closed this Apr 9, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +413 to +416
InterfaceManager.packetInterface.sendToServer(new PacketEntityBulletHitEntity(bullet.gun, part, fragDamage));
} else {
EntityBullet.performEntityHitLogic(part, fragDamage);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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.01.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 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants