Skip to content

Commit 78d2e66

Browse files
authored
One fix and one enhancement to AI shield behavior (#6737)
* One fix and one enhancement to AI shield behavior This PR adds one fix and one enhancement to AI shield behavior. 1) Fix: Testing, especially in FotG, revealed an edge-case bug with shield management where the AI will not direct shield energy to a quadrant if it was hit when that quadrant was down. In other words, if a shield quadrant is knocked down to 0 and continues to be shot the AI will not realize it needs to direct energy to that quadrant. This is because `quadrant` is set to -1 if a shield segment is down. This ensures that the resulting effects and damage calculations properly ignore that quadrant downstream, but it also results in `aip->last_hit_quadrant` being set to -1. This PR adds a fix to properly record which shield was actually hit, so that the AI knows to direct energy to that quadrant. 2) Enhancement: In combat situations with fire coming from many directions, it is good practice to keep shields equalized, so this PR adds a flag for the AI to always attempt to balance shields, even if it is being fired upon (instead of the current behavior to always direct energy to the hit shield quadrant). Both flags are tested and work as expected. * fix copy paste * rename to avoid previous confusion * also make as ai class flag
1 parent 106afbe commit 78d2e66

6 files changed

Lines changed: 19 additions & 5 deletions

File tree

code/ai/ai.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ typedef struct ai_info {
330330
float time_enemy_near; // SUSHI: amount of time enemy continuously "near" the player
331331
fix last_attack_time; // Missiontime of last time this ship attacked its enemy.
332332
fix last_hit_time; // Missiontime of last time this ship was hit by anyone.
333-
int last_hit_quadrant; // Shield section of last hit.
333+
int danger_shield_quadrant; // Shield section AI will prefer to prioritize for recharging, it if possible.
334334
fix last_hit_target_time; // Missiontime of last time this ship successfully hit target.
335335
int hitter_objnum; // Object index of ship that hit this ship last time.
336336
int hitter_signature; // Signature of hitter. Prevents stupidity if hitter gets killed.

code/ai/ai_flags.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ namespace AI {
172172
Guards_ignore_protected_attackers,
173173
Standard_strafe_used_more,
174174
Unify_usage_ai_shield_manage_delay,
175+
Fix_AI_shield_management_bug,
176+
AI_balances_shields_when_attacked,
175177
Disable_ai_transferring_energy,
176178
Freespace_1_missile_behavior,
177179
ETS_uses_power_output,

code/ai/ai_profiles.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,10 @@ void parse_ai_profiles_tbl(const char *filename)
699699

700700
set_flag(profile, "$unify usage of AI Shield Manage Delay:", AI::Profile_Flags::Unify_usage_ai_shield_manage_delay);
701701

702+
set_flag(profile, "$fix AI shield management bug:", AI::Profile_Flags::Fix_AI_shield_management_bug);
703+
704+
set_flag(profile, "$AI balances shields instead of directs when attacked:", AI::Profile_Flags::AI_balances_shields_when_attacked);
705+
702706
set_flag(profile, "$disable AI transferring energy:", AI::Profile_Flags::Disable_ai_transferring_energy);
703707

704708
set_flag(profile, "$enable freespace 1 style missile behavior:", AI::Profile_Flags::Freespace_1_missile_behavior);

code/ai/aicode.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,8 @@ void parse_ai_class()
924924
set_aic_flag(aicp, "$use actual primary range:", AI::Profile_Flags::Use_actual_primary_range);
925925

926926
set_aic_flag(aicp, "$firing requires exact los:", AI::Profile_Flags::Require_exact_los);
927+
928+
set_aic_flag(aicp, "$AI balances shields instead of directs when attacked:", AI::Profile_Flags::AI_balances_shields_when_attacked);
927929
}
928930

929931
void reset_ai_class_names()
@@ -13320,8 +13322,8 @@ void ai_manage_shield(object *objp, ai_info *aip)
1332013322
aip->shield_manage_timestamp = timestamp((int) (delay * 1000.0f));
1332113323

1332213324
if (sip->is_small_ship() || (aip->ai_profile_flags[AI::Profile_Flags::All_ships_manage_shields])) {
13323-
if (Missiontime - aip->last_hit_time < F1_0*10)
13324-
ai_transfer_shield(objp, aip->last_hit_quadrant);
13325+
if ((Missiontime - aip->last_hit_time < F1_0 * 10) && !((aip->ai_profile_flags[AI::Profile_Flags::AI_balances_shields_when_attacked])))
13326+
ai_transfer_shield(objp, aip->danger_shield_quadrant);
1332513327
else
1332613328
ai_balance_shield(objp);
1332713329
}
@@ -15559,7 +15561,7 @@ void init_ai_object(int objnum)
1555915561
aip->time_enemy_near = 0.0f;
1556015562
aip->last_attack_time = 0;
1556115563
aip->last_hit_time = 0;
15562-
aip->last_hit_quadrant = 0;
15564+
aip->danger_shield_quadrant = 0;
1556315565
aip->hitter_objnum = -1;
1556415566
aip->hitter_signature = -1;
1556515567
aip->resume_goal_time = -1;

code/object/collideshipweapon.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,12 @@ static int ship_weapon_check_collision(object *ship_objp, object *weapon_objp, f
446446

447447
// make sure that the shield is active in that quadrant
448448
if (shipp->flags[Ship::Ship_Flags::Dying] || !ship_is_shield_up(ship_objp, quadrant_num)) {
449+
// if the shield is down in the quadrant we still want the AI to record that the shield was hit here
450+
// so that the AI can put energy torwards repairing that shield segement (but put behind a flag)
451+
// --wookieejedi
452+
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_AI_shield_management_bug] && SCP_vector_inbounds(ship_objp->shield_quadrant, quadrant_num)) {
453+
Ai_info[Ships[ship_objp->instance].ai_index].danger_shield_quadrant = quadrant_num;
454+
}
449455
quadrant_num = -1;
450456
shield_collision = 0;
451457
}

code/object/objectshield.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ float shield_apply_damage(object *objp, int quadrant_num, float damage)
204204

205205
if (objp->type != OBJ_SHIP && objp->type != OBJ_START)
206206
return damage;
207-
Ai_info[Ships[objp->instance].ai_index].last_hit_quadrant = quadrant_num;
207+
Ai_info[Ships[objp->instance].ai_index].danger_shield_quadrant = quadrant_num;
208208

209209
remaining_damage = damage - objp->shield_quadrant[quadrant_num];
210210
if (remaining_damage > 0.0f) {

0 commit comments

Comments
 (0)