Make projectile targeting code anatomy indepedent, aim for center of mass #56104
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Features "Make projectile targeting anatomy agnostic, aim for center of mass"
Purpose of change
The projectile targeting code formerly cared too much about our anatomy, and that would not do if we want to change our anatomy. Additionally, instead of sensibly aiming for the center of mass, with good shots, the target would randomly switch to the head.
Describe the solution
Replace the old "torso or arms or legs, and then head if you got a good hit" logic with an anatomy dependent projectile targeting function.
This function uses the connection relationships of the body parts in the anatomy to generate a graph. At the center of the graph is the body part with the largest hitsize, Which is treated as the center of mass.
To select a bodypart, a path to an end of the graph is first chosen, with what branch to take chosen in a random fashion, weighted by the relative hitsize of the possible next limbs.
Then, the total weight of that path is determined, and used to scale the accuracy value passed in. Based on the accuracy value (lower is closer to center of mass), we walk down the path, stopping on whatever bodypart is the last one before it is too expensive to continue.
For random shots, this results in these percentage chances to hit various bodyparts:
For actual shots, from 8 m249 turrets firing 1600 rounds from 36 tiles away.
before:
after:
See files under additional context for some data.
Describe alternatives you've considered
In practice, the effective result is that body parts other than the torso are rarely hit. It may make sense in the future to use some other value than hit_size for weighting.
Testing
See tests.
Also, get shot (by turrets or NPCs), and shoot some NPCs and zombies.
Additional context
Here's some data - the result of being fired at by an m249 turret 36 tiles away:
This is a log of ~3800 hits, with the bodypart hit on each line
hits.log
These are similar, but shows info on the accuracy values passed to the hit function:
parts1.log
parts2.log