View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0001777 | FSSCP | gameplay | public | 2008-09-26 05:32 | 2008-09-28 00:24 |
| Reporter | KeldorKatarn | Assigned To | |||
| Priority | normal | Severity | minor | Reproducibility | always |
| Status | resolved | Resolution | fixed | ||
| Product Version | 3.6.9 | ||||
| Summary | 0001777: attack_set_accel () & evade_ship() bugs prevent AI from disengaging afterburners | ||||
| Description | There is a strange setting in above aicode.cpp functions that causes the AI to virtually never disengage the afterburners after they have been engaged by one of these functions. The reason for that is in a wrong setting of the afterburner_stop_time: aip->afterburner_stop_time = Missiontime + F1_0 + static_rand(Pl_objp-Objects)/4; since static_rand returns a 32bit integer this causes the AI in the worst case to keep the afterburners engaged for 2^32 / (F1_0 * 4) = 16,384 seconds. I am pretty sure this is a retail behavior and I am also pretty sure it was not intended this way or at least it was fully intended to nearly always exhaust a ship's afterburner fuel. | ||||
| Additional Information | Since this makes usage of AI ships with limited afterburner fuel impossible it needs to be fixed but without breaking retail behavior. I have attached a proposed fix that introduces a new flag to the ai_profiles which handles the new behavior. The new behavior in short would be to make a ship evade another ship for 1.0 - 1.25 seconds and to accelerate to get to an enemy the minimum of the time to fly 75% of the distance to the enemy and the time to burn 25% of the remaining fuel. | ||||
| Tags | No tags attached. | ||||
|
2008-09-26 05:32
|
ai_afterburner_fix.patch (3,277 bytes)
Index: code/ai/ai_profiles.cpp
===================================================================
--- code/ai/ai_profiles.cpp (revision 4831)
+++ code/ai/ai_profiles.cpp (working copy)
@@ -363,6 +363,8 @@
set_flag(profile, "$allow event and goal scoring in multiplayer:", AIPF_ALLOW_MULTI_EVENT_SCORING);
+ set_flag(profile, "$new ai afterburner behavior:", AIPF_SMART_AFTERBURNER_USAGE);
+
// if we've been through once already and are at the same place, force a move
if ( saved_Mp && (saved_Mp == Mp) )
Mp++;
Index: code/ai/ai_profiles.h
===================================================================
--- code/ai/ai_profiles.h (revision 4831)
+++ code/ai/ai_profiles.h (working copy)
@@ -77,6 +77,7 @@
#define AIPF_KILL_SCORING_SCALES_WITH_DAMAGE (1 << 16)
#define AIPF_ASSIST_SCORING_SCALES_WITH_DAMAGE (1 << 17)
#define AIPF_ALLOW_MULTI_EVENT_SCORING (1 << 18)
+#define AIPF_SMART_AFTERBURNER_USAGE (1 << 19)
#define MAX_AI_PROFILES 5
Index: code/ai/aicode.cpp
===================================================================
--- code/ai/aicode.cpp (revision 4831)
+++ code/ai/aicode.cpp (working copy)
@@ -6033,7 +6033,12 @@
float percent_left = 100.0f * shipp->afterburner_fuel / sip->afterburner_fuel_capacity;
if (percent_left > 30.0f + ((Pl_objp-Objects) & 0x0f)) {
afterburners_start(Pl_objp);
- aip->afterburner_stop_time = Missiontime + F1_0 + static_rand(Pl_objp-Objects)/4;
+
+ if (The_mission.ai_profile->flags & AIPF_SMART_AFTERBURNER_USAGE) {
+ aip->afterburner_stop_time = Missiontime + F1_0 + static_randf(Pl_objp-Objects) * F1_0 / 4;
+ } else {
+ aip->afterburner_stop_time = Missiontime + F1_0 + static_rand(Pl_objp-Objects)/4;
+ }
}
}
@@ -7584,8 +7589,30 @@
if (sip->afterburner_fuel_capacity > 0.0f) {
percent_left = 100.0f * shipp->afterburner_fuel / sip->afterburner_fuel_capacity;
if (percent_left > 30.0f + ((Pl_objp-Objects) & 0x0f)) {
- afterburners_start(Pl_objp);
- aip->afterburner_stop_time = Missiontime + F1_0 + static_rand(Pl_objp-Objects)/4;
+ afterburners_start(Pl_objp);
+ if (The_mission.ai_profile->flags & AIPF_SMART_AFTERBURNER_USAGE) {
+ float max_ab_vel;
+ float time_to_exhaust_25pct_fuel;
+ float time_to_fly_75pct_of_distance;
+ float ab_time;
+
+ // Max afterburner speed - make sure we don't devide by 0 later
+ max_ab_vel = sip->afterburner_max_vel.xyz.z > 0.0f ? sip->afterburner_max_vel.xyz.z : sip->max_vel.xyz.z;
+ max_ab_vel = max_ab_vel > 0.0f ? max_ab_vel : 0.0001f;
+
+ // Time to exhaust 25% of the remaining fuel
+ time_to_exhaust_25pct_fuel = shipp->afterburner_fuel * 0.25f / sip->afterburner_burn_rate;
+
+ // Time to fly 75% of the distance to the target
+ time_to_fly_75pct_of_distance = dist_to_enemy * 0.75f / max_ab_vel;
+
+ // Get minimum
+ ab_time = min(time_to_exhaust_25pct_fuel, time_to_fly_75pct_of_distance);
+
+ aip->afterburner_stop_time = Missiontime + F1_0 * ab_time;
+ } else {
+ aip->afterburner_stop_time = Missiontime + F1_0 + static_rand(Pl_objp-Objects)/4;
+ }
}
}
}
|
|
|
Confirmed. And I approve of the patch. Change two things, and I'll commit it: 1) Make the line in ai_profiles.tbl more descriptive 2) Add the appropriate default in the ai_profiles.tbl default table in globalincs. |
|
2008-09-27 12:04
|
ai_afterburner_fix_new.patch (4,002 bytes)
Index: code/ai/ai_profiles.cpp
===================================================================
--- code/ai/ai_profiles.cpp (revision 4831)
+++ code/ai/ai_profiles.cpp (working copy)
@@ -363,6 +369,8 @@
set_flag(profile, "$allow event and goal scoring in multiplayer:", AIPF_ALLOW_MULTI_EVENT_SCORING);
+ set_flag(profile, "$AI supports limited afterburner fuel:", AIPF_AI_SUPPORTS_LIMITED_AFTERBURNER_FUEL);
+
// if we've been through once already and are at the same place, force a move
if ( saved_Mp && (saved_Mp == Mp) )
Mp++;
Index: code/ai/ai_profiles.h
===================================================================
--- code/ai/ai_profiles.h (revision 4831)
+++ code/ai/ai_profiles.h (working copy)
@@ -77,6 +77,7 @@
#define AIPF_KILL_SCORING_SCALES_WITH_DAMAGE (1 << 16)
#define AIPF_ASSIST_SCORING_SCALES_WITH_DAMAGE (1 << 17)
#define AIPF_ALLOW_MULTI_EVENT_SCORING (1 << 18)
+#define AIPF_AI_SUPPORTS_LIMITED_AFTERBURNER_FUEL (1 << 19)
#define MAX_AI_PROFILES 5
Index: code/ai/aicode.cpp
===================================================================
--- code/ai/aicode.cpp (revision 4831)
+++ code/ai/aicode.cpp (working copy)
@@ -6033,7 +6033,12 @@
float percent_left = 100.0f * shipp->afterburner_fuel / sip->afterburner_fuel_capacity;
if (percent_left > 30.0f + ((Pl_objp-Objects) & 0x0f)) {
afterburners_start(Pl_objp);
- aip->afterburner_stop_time = Missiontime + F1_0 + static_rand(Pl_objp-Objects)/4;
+
+ if (The_mission.ai_profile->flags & AIPF_AI_SUPPORTS_LIMITED_AFTERBURNER_FUEL) {
+ aip->afterburner_stop_time = Missiontime + F1_0 + static_randf(Pl_objp-Objects) * F1_0 / 4;
+ } else {
+ aip->afterburner_stop_time = Missiontime + F1_0 + static_rand(Pl_objp-Objects)/4;
+ }
}
}
@@ -7584,8 +7589,30 @@
if (sip->afterburner_fuel_capacity > 0.0f) {
percent_left = 100.0f * shipp->afterburner_fuel / sip->afterburner_fuel_capacity;
if (percent_left > 30.0f + ((Pl_objp-Objects) & 0x0f)) {
- afterburners_start(Pl_objp);
- aip->afterburner_stop_time = Missiontime + F1_0 + static_rand(Pl_objp-Objects)/4;
+ afterburners_start(Pl_objp);
+ if (The_mission.ai_profile->flags & AIPF_AI_SUPPORTS_LIMITED_AFTERBURNER_FUEL) {
+ float max_ab_vel;
+ float time_to_exhaust_25pct_fuel;
+ float time_to_fly_75pct_of_distance;
+ float ab_time;
+
+ // Max afterburner speed - make sure we don't devide by 0 later
+ max_ab_vel = sip->afterburner_max_vel.xyz.z > 0.0f ? sip->afterburner_max_vel.xyz.z : sip->max_vel.xyz.z;
+ max_ab_vel = max_ab_vel > 0.0f ? max_ab_vel : 0.0001f;
+
+ // Time to exhaust 25% of the remaining fuel
+ time_to_exhaust_25pct_fuel = shipp->afterburner_fuel * 0.25f / sip->afterburner_burn_rate;
+
+ // Time to fly 75% of the distance to the target
+ time_to_fly_75pct_of_distance = dist_to_enemy * 0.75f / max_ab_vel;
+
+ // Get minimum
+ ab_time = min(time_to_exhaust_25pct_fuel, time_to_fly_75pct_of_distance);
+
+ aip->afterburner_stop_time = Missiontime + F1_0 * ab_time;
+ } else {
+ aip->afterburner_stop_time = Missiontime + F1_0 + static_rand(Pl_objp-Objects)/4;
+ }
}
}
}
Index: code/globalincs/def_files.cpp
===================================================================
--- code/globalincs/def_files.cpp (revision 4831)
+++ code/globalincs/def_files.cpp (working copy)
@@ -864,6 +870,10 @@
;; events in multiplayer \n\
$allow event and goal scoring in multiplayer: NO \n\
\n\
+;; if set, the AI can handle limited afterburner fuel \n\
+;; and will be smarter in spending it \n\
+$AI supports limited afterburner fuel: NO \n\
\n\
+ \n\
#End \n\
";
|
|
|
Line should be more descriptive now and is set to NO in FS2 RETAIL |
|
|
That's not quite what I meant... though actually it was the comment in the sample ai_profiles.tbl that would be better served by the description. I committed a slightly tweaked version of the patch. |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2008-09-26 05:32 | KeldorKatarn | New Issue | |
| 2008-09-26 05:32 | KeldorKatarn | File Added: ai_afterburner_fix.patch | |
| 2008-09-27 05:52 | Goober5000 | Note Added: 0009710 | |
| 2008-09-27 05:52 | Goober5000 | Status | new => confirmed |
| 2008-09-27 12:04 | KeldorKatarn | File Added: ai_afterburner_fix_new.patch | |
| 2008-09-27 12:05 | KeldorKatarn | Note Added: 0009719 | |
| 2008-09-28 00:24 | Goober5000 | Note Added: 0009723 | |
| 2008-09-28 00:24 | Goober5000 | Status | confirmed => resolved |
| 2008-09-28 00:24 | Goober5000 | Resolution | open => fixed |