-
Notifications
You must be signed in to change notification settings - Fork 164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix ai behavior when avoiding ship and weapon shockwaves #6378
base: master
Are you sure you want to change the base?
fix ai behavior when avoiding ship and weapon shockwaves #6378
Conversation
b9beefe
to
4e0419d
Compare
4e0419d
to
73cff97
Compare
code/ai/aicode.cpp
Outdated
mc.p1 = &expected_pos; // Point 2 of ray to check | ||
mc.flags = MC_CHECK_MODEL; | ||
|
||
model_collide(&mc); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm loathe to add more collision checks unless absolutely necessary, especially since this appears to be called every frame for a thing which is in the average case unlikely to move much (and also this case doesn't need tons of accuracy, some approximation/lag should be fine), so at the very least the result should probably be cached.
Alternatively, have you considered just using the weapon's homing_pos
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a fair point, and I had the same reluctance, but I ended up adding it after seeing how many collision checks were used elsewhere in the code, and due to the difficulty of solving this problem without a collision check. I'm certainly open to suggestions though. And I could cache the result, at the cost of adding some additional fields to ai_info
.
The weapon's homing_pos
will work if the missile is homing on a subsystem, but will not work if the weapon is homing on the actual ship, since the position will be at the center of the ship.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a large ship, the homing_pos
shouldn't be the center of the ship, see the usage of ai_big_pick_attack_point
in weapon_home
. They tend to spread themselves over the hull surface on the side facing the missile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I finally had a chance to get back to this. I modified the code to print debug output every frame to show the coordinates being used. Here is the output for homing on one of the turrets:
expected_pos: [x=7417.05, y=-108.33, z=637.62] weapon homing_pos: [x=7421.30, y=-106.31, z=630.08] center of ship: [x=7862.55, y=0.00, z=581.01] expected-homing: 8.89 expected-center: 461.97 homing-center: 456.52
expected_pos: [x=7417.05, y=-108.33, z=637.62] weapon homing_pos: [x=7421.30, y=-106.31, z=630.08] center of ship: [x=7862.55, y=0.00, z=581.01] expected-homing: 8.89 expected-center: 461.97 homing-center: 456.52
expected_pos: [x=7417.05, y=-108.33, z=637.62] weapon homing_pos: [x=7421.30, y=-106.31, z=630.08] center of ship: [x=7862.55, y=0.00, z=581.01] expected-homing: 8.89 expected-center: 461.97 homing-center: 456.52
expected_pos: [x=7417.05, y=-108.33, z=637.62] weapon homing_pos: [x=7421.30, y=-106.31, z=630.08] center of ship: [x=7862.55, y=0.00, z=581.01] expected-homing: 8.89 expected-center: 461.97 homing-center: 456.52
expected_pos: [x=7417.05, y=-108.33, z=637.62] weapon homing_pos: [x=7421.30, y=-106.31, z=630.08] center of ship: [x=7862.55, y=0.00, z=581.01] expected-homing: 8.89 expected-center: 461.97 homing-center: 456.52
...
And here is the output for homing on the ship with no subsystem selected:
expected_pos: [x=7483.91, y=-133.26, z=826.83] weapon homing_pos: [x=7862.55, y=0.00, z=581.01] center of ship: [x=7862.55, y=0.00, z=581.01] expected-homing: 470.70 expected-center: 470.70 homing-center: 0.00
expected_pos: [x=7483.91, y=-133.26, z=826.83] weapon homing_pos: [x=7862.55, y=0.00, z=581.01] center of ship: [x=7862.55, y=0.00, z=581.01] expected-homing: 470.70 expected-center: 470.70 homing-center: 0.00
expected_pos: [x=7483.91, y=-133.26, z=826.83] weapon homing_pos: [x=7862.55, y=0.00, z=581.01] center of ship: [x=7862.55, y=0.00, z=581.01] expected-homing: 470.70 expected-center: 470.70 homing-center: 0.00
expected_pos: [x=7483.91, y=-133.26, z=826.83] weapon homing_pos: [x=7862.55, y=0.00, z=581.01] center of ship: [x=7862.55, y=0.00, z=581.01] expected-homing: 470.70 expected-center: 470.70 homing-center: 0.00
expected_pos: [x=7483.91, y=-133.26, z=826.83] weapon homing_pos: [x=7862.55, y=0.00, z=581.01] center of ship: [x=7862.55, y=0.00, z=581.01] expected-homing: 470.70 expected-center: 470.70 homing-center: 0.00
...
This confirms what I discovered last month -- the homing_pos
is close enough if the weapon is homing on a subsystem (or turret), but is equivalent to the center of the ship if the weapon is homing on the ship.
I took a deeper look through the code and found that the octant picking is never actually called. This is because the wp->pick_big_attack_point_timestamp
is always 0 (i.e. invalid) and never elapses. This is actually intentional:
// If player has apect lock, we don't want to find a homing point on the closest
// octant... setting the timestamp to 0 ensures this.
if (wip->is_locked_homing()) {
wp->pick_big_attack_point_timestamp = 0;
} else {
wp->pick_big_attack_point_timestamp = 1;
}
Then the "preliminary" attack point, which is used if the octant picking code fails or is bypassed, is set as follows:
if (pp && pp->locking_subsys) {
wp->big_attack_point = pp->locking_subsys->system_info->pnt;
} else {
vm_vec_zero(&wp->big_attack_point);
}
So anyway, that was a bit of a detour, but was informative. In any case, I'll figure out a way to cache the expected position so the collision check doesn't need to run every frame.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't that just for player missiles? (Not that I am trying to imply that is an irrelevant case)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, that's a good point -- that is inside a block that checks for the player ship.
73cff97
to
869596d
Compare
3b79162
to
7f788a9
Compare
7f788a9
to
0e54ccc
Compare
The FreeSpace AI includes behavior to run away from shockwaves to try to avoid explosion damage. This is implemented for both ships and missiles, although the missile implementation has been buggy ever since retail. There are several issues: 1. The AI attempts to evade a weapon immediately upon launch. Many missiles have a period of free flight before they start homing on their target. During the free flight period, the homing position is not set. Consequently, the AI will not know the position to avoid and will make assumptions. 2. The AI assumes the shockwave-producing weapon will detonate at the center of the ship it is targeting, although missiles detonate on the surface. A capital ship is likely to be significantly larger than the weapon's blast radius, leading the AI to believe the detonation will be much farther away than it actually is. 3. When avoiding ship shockwaves, the `shockwave_object` field is not cleared when avoiding is complete. This can result in stale references (though not crashes, due to object type checks), causing AI to not avoid future explosions in certain cases. 4. When avoiding ship shockwaves, the code does not check the correct ship for the amount of damage caused by the shockwave. All of these issues are now fixed. Since this is a change in AI behavior, these fixes are tied to a new AI profiles flag.
0e54ccc
to
03bf756
Compare
…add a should-be-dead check
The FreeSpace AI includes behavior to run away from shockwaves to try to avoid explosion damage. This is implemented for both ships and missiles, although the missile implementation has been buggy ever since retail. There are several issues:
shockwave_object
field is not cleared when avoiding is complete. This can result in stale references (though not crashes, due to object type checks), causing AI to not avoid future explosions in certain cases.All of these issues are now fixed. Since this is a change in AI behavior, these fixes are tied to a new AI profiles flag.
Already tested, but in draft pending additional tests.Tested with both ship and weapon shockwaves.