Skip to content

Conversation

@mszabo-wikia
Copy link
Contributor

@mszabo-wikia mszabo-wikia commented Jan 3, 2026

Changes

  • Always compute and return the distance to the intersection point even when the current or previous position is within the bounds of the impacted Thing.
  • Ensure explosion effects spawn in the impacted cell irrespective of shooting direction.

Reasoning

When impacting a Thing, CanCollideWith() returns the distance d to the Thing from the previous position of the projectile. This is then used to derive the point of impact by getting the point on the shotline that is exactly d distance away from its origin (the previous position). The projectile's current position is then set to this point.

Since #3907 added special-casing for when the projectile's current or previous position is already within the bounding box of the impacted Thing, this doesn't work correctly, because the special casing returns a distance of 0, so the projectile's current position is set back to its previous position following the above logic. Secondary effects such as fragments and explosions then spawn a few tiles behind.

This normalization logic also means that when impacting Things whose hitbox precisely lines up with a cell,
the projectile's final position would end up sitting precisely on a cell boundary. Since a Vector3 -> IntVec3 conversion is just (int)x, 0, (int)z, this position always corresponds to the cell due east or north of the boundary, which, when shooting south or west, would be the previous cell on the shotline. Since we always want explosion effects to occur in the impacted cell, we should shift the position accordingly if it is on a cell boundary.

Testing

Check tests you have performed:

  • Compiles without warnings
  • Game runs without errors
  • Playtested a colony:
  1. On cannon.rws.zip, shoot the sandstone at 188, 0, 36 (it's the rocky outcropping near some of the starting steel, east-southeast of the cannon).
  2. Observe how the explosion will spawn behind the impact tile without this fix.

When impacting a Thing, CanCollideWith() returns the distance `d` to the
Thing from the previous position of the projectile. This is then used
to derive the point of impact by getting the point on the shotline that
is exactly `d` distance away from its origin (the previous position).
The projectile's current position is then set to this point.

Since #3907 added special-casing for when the projectile's current or
previous position is already within the bounding box of the impacted
Thing, this doesn't work correctly, because the special casing returns
a distance of 0, so the projectile's current position is set back to its
previous position following the above logic. Secondary effects such as
fragments and explosions then spawn a few tiles behind.

So, still compute and return the distance to the intersection point
even when the current or previous position is within the bounds of the
impacted Thing.
@mszabo-wikia mszabo-wikia requested review from a team as code owners January 3, 2026 19:52
@github-actions
Copy link

github-actions bot commented Jan 3, 2026

You can download the rebuilt assembly for this PR here: https://combatextended.lp-programming.com/CombatExtended-20682138632.zip

@github-actions github-actions bot added the Download in Comments This PR has a zipfile download available. label Jan 3, 2026
@github-actions
Copy link

github-actions bot commented Jan 3, 2026

You can download the rebuilt assembly for this PR here: https://combatextended.lp-programming.com/CombatExtended-20683206276.zip

@github-actions
Copy link

github-actions bot commented Jan 3, 2026

You can download the rebuilt assembly for this PR here: https://combatextended.lp-programming.com/CombatExtended-20683300480.zip

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

Labels

Download in Comments This PR has a zipfile download available.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants