Skip to content

Commit 9e73127

Browse files
authored
AI Cleanup and Flag Fixes (#6788)
* AI Cleanup and Flag Fixes This PR does 3 things. 1) Cleanup `ship_subsystem_in_sight` so it properly returns a bool, which is the return type of the function. Also update `ai_big_maybe_follow_subsys_path` to be a bool instead of int. 2) Adds `+subsystem attack pathing extra distance:` for use within `"$improved subsystem attack pathing:"`. FotG found, especially with the new strafing values we use, could really use the ability to set at what distance `ai_new_maybe_reposition_attack_subsys()` determines if it wants to pick a new point or not. By default the value was 2000. 3) In FotG we started using the `standard_strafe` mode more now thanks to #6511, but we have now discovered some inherit issues with it, namely that it will prematurely trigger `ai_big_strafe_maybe_retreat` because the distance it uses for determining if a collision is going to occur is `dist_normal_to_target`, which commonly resulted in the AI flying to a point to start a strafe, then thinking it would collide with the target and then retreating from strafe mode, only to realize it was now far enough to re-engage strafe mode, which commonly resulted in AI just flying around not accomplishing much. This PR adds a flag which instead uses the `distance_to_target` and a check to see if the ship is even facing the target. Overall all are tested and work as expected. Happy to change or tune however requested, especially regarding point 3. * clang cleanup * cleanup copy paste name * remove un-needed exposed float
1 parent 742dd07 commit 9e73127

File tree

4 files changed

+44
-28
lines changed

4 files changed

+44
-28
lines changed

code/ai/ai_flags.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ namespace AI {
170170
Debris_respects_big_damage,
171171
Dont_limit_change_in_speed_due_to_physics_whack,
172172
Guards_ignore_protected_attackers,
173+
Fix_standard_strafe,
173174
Standard_strafe_used_more,
174175
Unify_usage_ai_shield_manage_delay,
175176
Fix_AI_shield_management_bug,

code/ai/ai_profiles.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,8 @@ void parse_ai_profiles_tbl(const char *filename)
669669

670670
set_flag(profile, "$fix avoid-shockwave bugs:", AI::Profile_Flags::Fix_avoid_shockwave_bugs);
671671

672+
set_flag(profile, "$fix standard strafe:", AI::Profile_Flags::Fix_standard_strafe);
673+
672674
set_flag(profile, "$standard strafe used more:", AI::Profile_Flags::Standard_strafe_used_more);
673675

674676
if (optional_string("$standard strafe triggers under this speed:")) {

code/ai/aibig.cpp

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@
6262
void ai_big_evade_ship();
6363
void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum);
6464
void ai_big_avoid_ship();
65-
int ai_big_maybe_follow_subsys_path(int do_dot_check=1);
65+
bool ai_big_maybe_follow_subsys_path(bool do_dot_check=true);
6666
void ai_big_strafe_position();
67-
static int ai_big_strafe_maybe_retreat(const vec3d *target_pos);
67+
static bool ai_big_strafe_maybe_retreat(const vec3d *target_pos);
6868

6969
extern void compute_desired_rvec(vec3d *rvec, const vec3d *goal_pos, const vec3d *cur_pos);
7070
extern void big_ship_collide_recover_start(const object *objp, const object *big_objp, const vec3d *collision_normal);
@@ -347,10 +347,10 @@ void ai_big_subsys_path_cleanup(ai_info *aip)
347347
}
348348

349349
// Maybe Pl_objp needs to follow a path to get in line-of-sight to a subsystem
350-
// input: do_dot_check => default value 0, flag to indicate whether check should be done to ensure
350+
// input: do_dot_check => default value true, flag to indicate whether check should be done to ensure
351351
// subsystem is within certain field of view. We don't want to check fov when
352352
// strafing, since ship is weaving to avoid turret fire
353-
int ai_big_maybe_follow_subsys_path(int do_dot_check)
353+
bool ai_big_maybe_follow_subsys_path(bool do_dot_check)
354354
{
355355
ai_info *aip;
356356
float dot = 1.0f, min_dot;
@@ -1416,33 +1416,50 @@ void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_t
14161416

14171417
// check to see if Pl_objp has gotten too close to attacking point.. if so, break off by entering
14181418
// AIS_STRAFE_RETREAT
1419-
static int ai_big_strafe_maybe_retreat(const vec3d *target_pos)
1419+
static bool ai_big_strafe_maybe_retreat(const vec3d *target_pos)
14201420
{
14211421
ai_info *aip;
14221422
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
14231423

14241424
vec3d vec_to_target;
14251425
vm_vec_sub(&vec_to_target, target_pos, &Pl_objp->pos);
14261426

1427-
float dist_to_target, dist_normal_to_target, time_to_target;
1428-
dist_to_target = vm_vec_mag_quick(&vec_to_target);
1429-
if (vm_vec_mag_quick(&aip->big_attack_surface_normal) > 0.9) {
1430-
dist_normal_to_target = -vm_vec_dot(&vec_to_target, &aip->big_attack_surface_normal);
1431-
} else {
1432-
dist_normal_to_target = 0.2f * vm_vec_mag_quick(&vec_to_target);
1433-
}
1434-
1435-
dist_normal_to_target = MAX(0.2f*dist_to_target, dist_normal_to_target);
1436-
time_to_target = dist_normal_to_target / Pl_objp->phys_info.speed;
1427+
float dist_to_target = vm_vec_mag(&vec_to_target);
14371428

14381429
// add distance penalty for going too fast
14391430
float speed_to_dist_penalty = MAX(0.0f, (Pl_objp->phys_info.speed-50));
14401431

1432+
bool collide_time;
1433+
bool collide_distance;
1434+
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_standard_strafe]) {
1435+
// check if ship facing target, as likely will only collide if facing
1436+
vec3d vec_to_tpos;
1437+
vm_vec_normalized_dir(&vec_to_tpos, target_pos, &Pl_objp->pos);
1438+
float dot = vm_vec_dot(&vec_to_tpos, &Pl_objp->orient.vec.fvec);
1439+
if (dot <= 0.0f) {
1440+
collide_time = false;
1441+
collide_distance = false;
1442+
} else {
1443+
collide_time = (dist_to_target / Pl_objp->phys_info.speed) < STRAFE_RETREAT_COLLIDE_TIME;
1444+
collide_distance = dist_to_target < (STRAFE_RETREAT_COLLIDE_DIST + speed_to_dist_penalty);
1445+
}
1446+
} else {
1447+
float dist_normal_to_target;
1448+
if (vm_vec_mag(&aip->big_attack_surface_normal) > 0.9) {
1449+
dist_normal_to_target =
1450+
MAX(0.2f * dist_to_target, -vm_vec_dot(&vec_to_target, &aip->big_attack_surface_normal));
1451+
} else {
1452+
dist_normal_to_target = 0.2f * dist_to_target;
1453+
}
1454+
collide_time = (dist_normal_to_target / Pl_objp->phys_info.speed) < STRAFE_RETREAT_COLLIDE_TIME;
1455+
collide_distance = dist_normal_to_target < (STRAFE_RETREAT_COLLIDE_DIST + speed_to_dist_penalty);
1456+
}
1457+
14411458
//if ((dot_to_enemy > 1.0f - 0.1f * En_objp->radius/(dist_to_enemy + 1.0f)) && (Pl_objp->phys_info.speed > dist_to_enemy/5.0f))
14421459

14431460
// Inside 2 sec retreat, setting goal point to box point + strafe_retreat_box_dist
14441461
// If collision, use std collision resolution.
1445-
if ( !(aip->ai_flags[AI::AI_Flags::Kamikaze]) && ((aip->ai_flags[AI::AI_Flags::Target_collision]) || (time_to_target < STRAFE_RETREAT_COLLIDE_TIME) || (dist_normal_to_target < STRAFE_RETREAT_COLLIDE_DIST + speed_to_dist_penalty)) ) {
1462+
if ( !(aip->ai_flags[AI::AI_Flags::Kamikaze]) && ((aip->ai_flags[AI::AI_Flags::Target_collision]) || (collide_time) || (collide_distance)) ) {
14461463
if (aip->ai_flags[AI::AI_Flags::Target_collision]) {
14471464
// use standard collision resolution
14481465
aip->ai_flags.remove(AI::AI_Flags::Target_collision);
@@ -1486,7 +1503,7 @@ void ai_big_strafe_attack()
14861503
if (aip->ai_profile_flags[AI::Profile_Flags::Improved_subsystem_attack_pathing]) {
14871504
if (ai_new_maybe_reposition_attack_subsys())
14881505
return;
1489-
} else if (ai_big_maybe_follow_subsys_path(0))
1506+
} else if (ai_big_maybe_follow_subsys_path(false))
14901507
return;
14911508

14921509
ai_big_attack_get_data(&target_pos, &target_dist, &target_dot);
@@ -1606,7 +1623,7 @@ void ai_big_strafe_glide_attack()
16061623
if (aip->ai_profile_flags[AI::Profile_Flags::Improved_subsystem_attack_pathing]) {
16071624
if (ai_new_maybe_reposition_attack_subsys())
16081625
return;
1609-
} else if (ai_big_maybe_follow_subsys_path(0))
1626+
} else if (ai_big_maybe_follow_subsys_path(false))
16101627
return;
16111628

16121629
//Gets a point on the target ship to attack, as well as distance and the angle between the nose of the attacker and that point.

code/ship/ship.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16977,7 +16977,7 @@ int ship_return_subsys_path_normal(const ship *shipp, const ship_subsys *ss, con
1697716977
// subsys => pointer to the subsystem of interest
1697816978
// eye_pos => world coord for the eye looking at the subsystem
1697916979
// subsys_pos => world coord for the center of the subsystem of interest
16980-
// do_facing_check => OPTIONAL PARAMETER (default value is 1), do a dot product check to see if subsystem fvec is facing
16980+
// do_facing_check => OPTIONAL PARAMETER (default value is true), do a dot product check to see if subsystem fvec is facing
1698116981
// towards the eye position
1698216982
// dot_out => OPTIONAL PARAMETER, output parameter, will return dot between subsys fvec and subsys_to_eye_vec
1698316983
// (only filled in if do_facing_check is true)
@@ -16988,7 +16988,7 @@ bool ship_subsystem_in_sight(const object *objp, const ship_subsys *subsys, cons
1698816988
vec3d terminus, eye_to_pos, subsys_fvec, subsys_to_eye_vec;
1698916989

1699016990
if (objp->type != OBJ_SHIP)
16991-
return 0;
16991+
return false;
1699216992

1699316993
// See if we are at least facing the subsystem
1699416994
if ( do_facing_check ) {
@@ -17008,8 +17008,8 @@ bool ship_subsystem_in_sight(const object *objp, const ship_subsys *subsys, cons
1700817008
vm_vec_negate(vec_out);
1700917009
}
1701017010

17011-
if ( dot < 0 )
17012-
return 0;
17011+
if ( dot <= 0 )
17012+
return false;
1701317013
}
1701417014

1701517015
// See if ray from eye to subsystem actually hits close enough to the subsystem position
@@ -17028,17 +17028,13 @@ bool ship_subsystem_in_sight(const object *objp, const ship_subsys *subsys, cons
1702817028
model_collide(&mc);
1702917029

1703017030
if ( !mc.num_hits ) {
17031-
return 0;
17031+
return false;
1703217032
}
1703317033

1703417034
// determine if hitpos is close enough to subsystem
1703517035
dist = vm_vec_dist(&mc.hit_point_world, subsys_pos);
1703617036

17037-
if ( dist <= subsys->system_info->radius ) {
17038-
return 1;
17039-
}
17040-
17041-
return 0;
17037+
return (dist <= subsys->system_info->radius);
1704217038
}
1704317039

1704417040
/**

0 commit comments

Comments
 (0)