Skip to content

Commit b8c3c56

Browse files
Implementation for an AI order to chase ship types -Second Attempt- (#6828)
* Back in business hopefully * Refactor * Resolve CI issue in aigoals.cpp * Updating order.cpp * Whoops * Updated objecttypes.tbl to incorporate attack ship type * Fix clang-tidy issue * Forgot one other instance --------- Co-authored-by: wookieejedi <azthepaleo@gmail.com>
1 parent 94744e9 commit b8c3c56

19 files changed

Lines changed: 216 additions & 46 deletions

File tree

code/ai/ai.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ const char *ai_get_goal_target_name(const char *name, int *index);
527527
void ai_clear_goal_target_names();
528528

529529
extern void init_ai_system(void);
530-
extern void ai_attack_object(object *attacker, object *attacked, int ship_info_index = -1);
530+
extern void ai_attack_object(object *attacker, object *attacked, int ship_info_index = -1, int class_type = -1);
531531
extern void ai_evade_object(object *evader, object *evaded);
532532
extern void ai_ignore_object(object *ignorer, object *ignored, int ignore_new);
533533
extern void ai_ignore_wing(object *ignorer, int wingnum);
@@ -559,7 +559,7 @@ extern void ai_set_guard_wing(object *objp, int wingnum);
559559
extern void ai_warp_out(object *objp, vec3d *vp);
560560
extern void ai_attack_wing(object *attacker, int wingnum);
561561
extern void ai_deathroll_start(object *ship_obj);
562-
extern int set_target_objnum(ai_info *aip, int objnum);
562+
extern int set_target_objnum(ai_info* aip, int objnum);
563563
extern void ai_form_on_wing(object *objp, object *goal_objp);
564564
extern void ai_do_stay_near(object *objp, object *other_obj, float dist, int additional_data);
565565
extern ship_subsys *set_targeted_subsys(ai_info *aip, ship_subsys *new_subsys, int parent_objnum);
@@ -596,7 +596,7 @@ extern int ai_maybe_fire_afterburner(object *objp, ai_info *aip);
596596
extern void set_predicted_enemy_pos(vec3d *predicted_enemy_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, ai_info *aip);
597597

598598
extern int is_instructor(object *objp);
599-
extern int find_enemy(int objnum, float range, int max_attackers, int ship_info_index = -1);
599+
extern int find_enemy(int objnum, float range, int max_attackers, int ship_info_index = -1, int class_type = -1);
600600

601601
float ai_get_weapon_speed(const ship_weapon *swp);
602602
void set_predicted_enemy_pos_turret(vec3d *predicted_enemy_pos, const vec3d *gun_pos, const object *pobjp, const vec3d *enemy_pos, const vec3d *enemy_vel, float weapon_speed, float time_enemy_in_range);
@@ -617,7 +617,7 @@ extern float dock_orient_and_approach(object *docker_objp, int docker_index, obj
617617
void ai_set_mode_warp_out(object *objp, ai_info *aip);
618618

619619
// prototyped by Goober5000
620-
int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers, int ship_info_index);
620+
int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers, int ship_info_index, int class_type = -1);
621621

622622
// moved to header file by Goober5000
623623
void ai_announce_ship_dying(object *dying_objp);

code/ai/aicode.cpp

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2229,6 +2229,7 @@ typedef struct eval_nearest_objnum {
22292229
object *trial_objp;
22302230
int enemy_team_mask;
22312231
int enemy_ship_info_index;
2232+
int enemy_class_type;
22322233
int enemy_wing;
22332234
float range;
22342235
int max_attackers;
@@ -2262,6 +2263,10 @@ void evaluate_object_as_nearest_objnum(eval_nearest_objnum *eno)
22622263
if ((eno->enemy_ship_info_index >= 0) && (shipp->ship_info_index != eno->enemy_ship_info_index))
22632264
return;
22642265

2266+
// If only supposed to attack ships of a certain ship type, don't attack other ships.
2267+
if ((eno->enemy_class_type >= 0) && (Ship_info[shipp->ship_info_index].class_type != eno->enemy_class_type))
2268+
return;
2269+
22652270
// Don't keep firing at a ship that is in its death throes.
22662271
if (shipp->flags[Ship::Ship_Flags::Dying])
22672272
return;
@@ -2350,8 +2355,9 @@ void evaluate_object_as_nearest_objnum(eval_nearest_objnum *eno)
23502355
* @param range Ship must be within range "range".
23512356
* @param max_attackers Don't attack a ship that already has at least max_attackers attacking it.
23522357
* @param ship_info_index If >=0, the enemy object must be of the specified ship class
2358+
* @param class_type If >=0, the enemy object must be of the specified ship type
23532359
*/
2354-
int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers, int ship_info_index)
2360+
int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers, int ship_info_index, int class_type)
23552361
{
23562362
object *danger_weapon_objp;
23572363
ai_info *aip;
@@ -2361,6 +2367,7 @@ int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float ra
23612367
eval_nearest_objnum eno;
23622368
eno.enemy_team_mask = enemy_team_mask;
23632369
eno.enemy_ship_info_index = ship_info_index;
2370+
eno.enemy_class_type = class_type;
23642371
eno.enemy_wing = enemy_wing;
23652372
eno.max_attackers = max_attackers;
23662373
eno.objnum = objnum;
@@ -2406,7 +2413,7 @@ int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float ra
24062413
// If only looking for target in certain wing and couldn't find anything in
24072414
// that wing, look for any object.
24082415
if ((eno.nearest_objnum == -1) && (enemy_wing != -1)) {
2409-
return get_nearest_objnum(objnum, enemy_team_mask, -1, range, max_attackers, ship_info_index);
2416+
return get_nearest_objnum(objnum, enemy_team_mask, -1, range, max_attackers, ship_info_index, class_type);
24102417
}
24112418

24122419
return eno.nearest_objnum;
@@ -2510,33 +2517,41 @@ int get_enemy_timestamp()
25102517
/**
25112518
* Return objnum if enemy found, else return -1;
25122519
*
2513-
* @param objnum Object number
2514-
* @param range Range within which to look
2515-
* @param max_attackers Don't attack a ship that already has at least max_attackers attacking it.
2520+
* @param objnum Object number
2521+
* @param range Range within which to look
2522+
* @param max_attackers Don't attack a ship that already has at least max_attackers attacking it.
2523+
* @param ship_info_index If specified, restrict the search to enemies with this ship class
2524+
* @param class_type If specified, restrict the search to enemies with this ship type
25162525
*/
2517-
int find_enemy(int objnum, float range, int max_attackers, int ship_info_index)
2526+
int find_enemy(int objnum, float range, int max_attackers, int ship_info_index, int class_type)
25182527
{
2519-
int enemy_team_mask;
2528+
int enemy_team_mask;
25202529

25212530
if (objnum < 0)
25222531
return -1;
25232532

25242533
enemy_team_mask = iff_get_attackee_mask(obj_team(&Objects[objnum]));
25252534

25262535
// if target_objnum != -1, use that as goal.
2527-
ai_info *aip = &Ai_info[Ships[Objects[objnum].instance].ai_index];
2536+
ai_info* aip = &Ai_info[Ships[Objects[objnum].instance].ai_index];
25282537
if (timestamp_elapsed(aip->choose_enemy_timestamp)) {
25292538
aip->choose_enemy_timestamp = timestamp(get_enemy_timestamp());
2539+
25302540
if (aip->target_objnum != -1) {
2531-
int target_objnum = aip->target_objnum;
2541+
int target_objnum = aip->target_objnum;
25322542

25332543
// DKA don't undo object as target in nebula missions.
2534-
// This could cause attack on ship on fringe on nebula to stop if attackee moves our of nebula range. (BAD)
2535-
if ( Objects[target_objnum].signature == aip->target_signature ) {
2536-
if (iff_matches_mask(Ships[Objects[target_objnum].instance].team, enemy_team_mask)) {
2537-
if (ship_info_index < 0 || ship_info_index == Ships[Objects[target_objnum].instance].ship_info_index) {
2538-
if (!(Objects[target_objnum].flags[Object::Object_Flags::Protected])) {
2539-
return target_objnum;
2544+
// This could cause attack on ship on fringe on nebula to stop if attackee moves out of nebula range. (BAD)
2545+
if (Objects[target_objnum].signature == aip->target_signature) {
2546+
ship* target_shipp = (Objects[target_objnum].type == OBJ_SHIP) ? &Ships[Objects[target_objnum].instance] : nullptr;
2547+
2548+
if (target_shipp && iff_matches_mask(target_shipp->team, enemy_team_mask)) {
2549+
if (ship_info_index < 0 || ship_info_index == target_shipp->ship_info_index) {
2550+
if (class_type < 0 || (target_shipp->ship_info_index >= 0 &&
2551+
class_type == Ship_info[target_shipp->ship_info_index].class_type)) {
2552+
if (!(Objects[target_objnum].flags[Object::Object_Flags::Protected])) {
2553+
return target_objnum;
2554+
}
25402555
}
25412556
}
25422557
}
@@ -2545,9 +2560,8 @@ int find_enemy(int objnum, float range, int max_attackers, int ship_info_index)
25452560
aip->target_signature = -1;
25462561
}
25472562
}
2548-
2549-
return get_nearest_objnum(objnum, enemy_team_mask, aip->enemy_wing, range, max_attackers, ship_info_index);
2550-
2563+
2564+
return get_nearest_objnum(objnum, enemy_team_mask, aip->enemy_wing, range, max_attackers, ship_info_index, class_type);
25512565
} else {
25522566
aip->target_objnum = -1;
25532567
aip->target_signature = -1;
@@ -2588,7 +2602,7 @@ void force_avoid_player_check(object *objp, ai_info *aip)
25882602
* If attacked == NULL, then attack any enemy object.
25892603
* Attack point *rel_pos on object. This is for supporting attacking subsystems.
25902604
*/
2591-
void ai_attack_object(object* attacker, object* attacked, int ship_info_index)
2605+
void ai_attack_object(object* attacker, object* attacked, int ship_info_index, int class_type)
25922606
{
25932607
int temp;
25942608
ai_info* aip;
@@ -2621,7 +2635,7 @@ void ai_attack_object(object* attacker, object* attacked, int ship_info_index)
26212635
if (attacked == nullptr) {
26222636
aip->choose_enemy_timestamp = timestamp(0);
26232637
// nebula safe
2624-
set_target_objnum(aip, find_enemy(OBJ_INDEX(attacker), 99999.9f, 4, ship_info_index));
2638+
set_target_objnum(aip, find_enemy(OBJ_INDEX(attacker), 99999.9f, 4, ship_info_index, class_type));
26252639
} else {
26262640
// check if we can see attacked in nebula
26272641
if (aip->target_objnum != OBJ_INDEX(attacked)) {

code/ai/aigoals.cpp

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ ai_goal_list Ai_goal_names[] =
100100
{ "Attack weapon", AI_GOAL_CHASE_WEAPON, 0 },
101101
{ "Fly to ship", AI_GOAL_FLY_TO_SHIP, 0 },
102102
{ "Attack ship class", AI_GOAL_CHASE_SHIP_CLASS, 0 },
103+
{ "Attack ship type", AI_GOAL_CHASE_SHIP_TYPE, 0 },
103104
};
104105

105106
int Num_ai_goals = sizeof(Ai_goal_names) / sizeof(ai_goal_list);
@@ -114,6 +115,7 @@ const char *Ai_goal_text(ai_goal_mode goal, int submode)
114115
case AI_GOAL_CHASE:
115116
case AI_GOAL_CHASE_WING:
116117
case AI_GOAL_CHASE_SHIP_CLASS:
118+
case AI_GOAL_CHASE_SHIP_TYPE:
117119
return XSTR( "attack ", 474);
118120
case AI_GOAL_DOCK:
119121
return XSTR( "dock ", 475);
@@ -513,13 +515,25 @@ void ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list, ai_info *ai
513515
if ( purge_goal->target_name == NULL )
514516
continue;
515517

516-
// goals operating on ship classes are handled slightly differently
518+
// goals operating on ship classes and ship types are handled slightly differently
517519
if ( purge_ai_mode == AI_GOAL_CHASE_SHIP_CLASS ) {
518520
// if the target of the purge goal is the same class of ship we are concerned about, then we have a match;
519521
// if it is not, then we can continue (see standard ship check below)
520522
if ( stricmp(purge_goal->target_name, Ship_info[Ships[ship_index].ship_info_index].name) != 0 )
521523
continue;
522524
}
525+
else if (purge_ai_mode == AI_GOAL_CHASE_SHIP_TYPE) {
526+
// Get the ship type of the ship we're concerned about
527+
int ship_type = Ship_info[Ships[ship_index].ship_info_index].class_type;
528+
529+
// If the ship type is invalid, we can't match it, so continue
530+
if (ship_type < 0)
531+
continue;
532+
533+
// Check if the target name of the purge goal matches the ship type name
534+
if (stricmp(purge_goal->target_name, Ship_types[ship_type].name) != 0)
535+
continue;
536+
}
523537
// standard goals operating on either wings or ships
524538
else {
525539
// determine if the purge goal is acting either on the ship or the ship's wing.
@@ -1094,6 +1108,7 @@ void ai_add_goal_sub_sexp( int sexp, ai_goal_type type, ai_info *aip, ai_goal *a
10941108
case OP_AI_CHASE:
10951109
case OP_AI_CHASE_WING:
10961110
case OP_AI_CHASE_SHIP_CLASS:
1111+
case OP_AI_CHASE_SHIP_TYPE:
10971112
case OP_AI_GUARD:
10981113
case OP_AI_GUARD_WING:
10991114
case OP_AI_EVADE_SHIP:
@@ -1125,6 +1140,8 @@ void ai_add_goal_sub_sexp( int sexp, ai_goal_type type, ai_info *aip, ai_goal *a
11251140
aigp->ai_mode = AI_GOAL_CHASE_WING;
11261141
} else if (op == OP_AI_CHASE_SHIP_CLASS) {
11271142
aigp->ai_mode = AI_GOAL_CHASE_SHIP_CLASS;
1143+
} else if (op == OP_AI_CHASE_SHIP_TYPE) {
1144+
aigp->ai_mode = AI_GOAL_CHASE_SHIP_TYPE;
11281145
} else if ( op == OP_AI_IGNORE ) {
11291146
aigp->ai_mode = AI_GOAL_IGNORE;
11301147
} else if ( op == OP_AI_IGNORE_NEW ) {
@@ -1169,7 +1186,7 @@ void ai_add_goal_sub_sexp( int sexp, ai_goal_type type, ai_info *aip, ai_goal *a
11691186
}
11701187

11711188
// Goober5000 - we now have an extra optional chase argument to allow chasing our own team
1172-
if ( op == OP_AI_CHASE || op == OP_AI_CHASE_WING || op == OP_AI_CHASE_SHIP_CLASS
1189+
if (op == OP_AI_CHASE || op == OP_AI_CHASE_WING || op == OP_AI_CHASE_SHIP_CLASS || op == OP_AI_CHASE_SHIP_TYPE
11731190
|| op == OP_AI_DISABLE_SHIP || op == OP_AI_DISABLE_SHIP_TACTICAL || op == OP_AI_DISARM_SHIP || op == OP_AI_DISARM_SHIP_TACTICAL ) {
11741191
if (is_sexp_true(CDDDR(node)))
11751192
aigp->flags.set(AI::Goal_Flags::Target_own_team);
@@ -1194,6 +1211,7 @@ void ai_add_goal_sub_sexp( int sexp, ai_goal_type type, ai_info *aip, ai_goal *a
11941211
if (op == OP_AI_CHASE ||
11951212
op == OP_AI_CHASE_WING ||
11961213
op == OP_AI_CHASE_SHIP_CLASS ||
1214+
op == OP_AI_CHASE_SHIP_TYPE ||
11971215
op == OP_AI_DISABLE_SHIP ||
11981216
op == OP_AI_DISABLE_SHIP_TACTICAL ||
11991217
op == OP_AI_DISARM_SHIP ||
@@ -1380,6 +1398,10 @@ int ai_remove_goal_sexp_sub( int sexp, ai_goal* aigp, bool &remove_more )
13801398
priority = eval_priority_et_seq(CDDR(node));
13811399
goalmode = AI_GOAL_CHASE_SHIP_CLASS;
13821400
break;
1401+
case OP_AI_CHASE_SHIP_TYPE:
1402+
priority = eval_priority_et_seq(CDDR(node));
1403+
goalmode = AI_GOAL_CHASE_SHIP_TYPE;
1404+
break;
13831405
case OP_AI_EVADE_SHIP:
13841406
priority = eval_priority_et_seq(CDDR(node));
13851407
goalmode = AI_GOAL_EVADE_SHIP;
@@ -1689,7 +1711,20 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
16891711
}
16901712
return ai_achievability::NOT_KNOWN;
16911713
}
1692-
1714+
// and similarly for chasing all ships of a certain ship type
1715+
if (aigp->ai_mode == AI_GOAL_CHASE_SHIP_TYPE) {
1716+
for (auto so : list_range(&Ship_obj_list)) {
1717+
auto type_objp = &Objects[so->objnum];
1718+
if (type_objp->type != OBJ_SHIP || type_objp->flags[Object::Object_Flags::Should_be_dead])
1719+
continue;
1720+
int ship_info_idx = Ships[type_objp->instance].ship_info_index;
1721+
int class_type = Ship_info[ship_info_idx].class_type;
1722+
if (class_type >= 0 && !strcmp(aigp->target_name, Ship_types[class_type].name)) {
1723+
return ai_achievability::ACHIEVABLE;
1724+
}
1725+
}
1726+
return ai_achievability::NOT_KNOWN;
1727+
}
16931728

16941729
return_val = ai_achievability::SATISFIED;
16951730

@@ -2523,10 +2558,20 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
25232558

25242559
// chase-ship-class is chase-any but restricted to a subset of ships
25252560
case AI_GOAL_CHASE_SHIP_CLASS:
2526-
shipnum = ship_info_lookup( current_goal->target_name );
2527-
Assertion( shipnum >= 0, "The target of AI_GOAL_CHASE_SHIP_CLASS must refer to a valid ship class!" );
2528-
ai_attack_object( objp, nullptr, shipnum );
2561+
{
2562+
int ship_info_index = ship_info_lookup(current_goal->target_name);
2563+
Assertion(ship_info_index >= 0, "The target of AI_GOAL_CHASE_SHIP_CLASS must refer to a valid ship class!");
2564+
ai_attack_object(objp, nullptr, ship_info_index);
25292565
break;
2566+
}
2567+
// similarly for chase-ship-type
2568+
case AI_GOAL_CHASE_SHIP_TYPE:
2569+
{
2570+
int class_type = ship_type_name_lookup(current_goal->target_name);
2571+
Assertion(class_type >= 0, "The target of AI_GOAL_CHASE_SHIP_TYPE must refer to a valid ship type!");
2572+
ai_attack_object(objp, nullptr, -1, class_type);
2573+
break;
2574+
}
25302575

25312576
case AI_GOAL_WARP: {
25322577
mission_do_departure( objp, true );

code/ai/aigoals.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ enum ai_goal_mode : uint8_t
8080
AI_GOAL_FLY_TO_SHIP,
8181
AI_GOAL_IGNORE_NEW,
8282
AI_GOAL_CHASE_SHIP_CLASS,
83+
AI_GOAL_CHASE_SHIP_TYPE,
8384
AI_GOAL_PLAY_DEAD_PERSISTENT, // Disables subsystem rotation/translation among other things but there is a carveout for that in the lab in ship_move_subsystems() and ai_process_subobjects()
8485
AI_GOAL_LUA,
8586
AI_GOAL_DISARM_SHIP_TACTICAL,
@@ -103,7 +104,7 @@ inline bool ai_goal_is_disable_or_disarm(ai_goal_mode ai_mode)
103104
}
104105
inline bool ai_goal_is_specific_chase(ai_goal_mode ai_mode)
105106
{
106-
return ai_mode == AI_GOAL_CHASE || ai_mode == AI_GOAL_CHASE_WING || ai_mode == AI_GOAL_CHASE_SHIP_CLASS;
107+
return ai_mode == AI_GOAL_CHASE || ai_mode == AI_GOAL_CHASE_WING || ai_mode == AI_GOAL_CHASE_SHIP_CLASS || ai_mode == AI_GOAL_CHASE_SHIP_TYPE;
107108
}
108109

109110
enum class ai_achievability { ACHIEVABLE, NOT_ACHIEVABLE, NOT_KNOWN, SATISFIED };

code/ai/aiturret.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,9 +1089,11 @@ int find_turret_enemy(const ship_subsys *turret_subsys, int objnum, const vec3d
10891089
int target_objnum = aip->target_objnum;
10901090

10911091
if (Objects[target_objnum].signature == aip->target_signature) {
1092-
if (iff_matches_mask(Ships[Objects[target_objnum].instance].team, enemy_team_mask)) {
1093-
if ( !(Objects[target_objnum].flags[Object::Object_Flags::Protected]) ) { // check this flag as well
1094-
// nprintf(("AI", "Frame %i: Object %i resuming goal of object %i\n", AI_FrameCount, objnum, target_objnum));
1092+
ship* target_shipp = &Ships[Objects[target_objnum].instance];
1093+
if (target_shipp && iff_matches_mask(target_shipp->team, enemy_team_mask)) {
1094+
if (!(Objects[target_objnum].flags[Object::Object_Flags::Protected])) { // check this flag as well
1095+
// nprintf(("AI", "Frame %i: Object %i resuming goal of object %i\n", AI_FrameCount, objnum,
1096+
// target_objnum));
10951097
return target_objnum;
10961098
}
10971099
}

code/def_files/data/tables/objecttypes.tbl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ $Fog:
110110
+Start dist: 10.0
111111
+Compl dist: 500.0
112112
$AI:
113-
+Valid goals: ( "fly to ship" "attack ship" "waypoints" "waypoints once" "depart" "attack subsys" "attack wing" "guard ship" "disable ship" "disable ship (tactical)" "disarm ship" "disarm ship (tactical)" "attack any" "attack ship class" "ignore ship" "ignore ship (new)" "guard wing" "evade ship" "stay still" "play dead" "play dead (persistent)" "stay near ship" "keep safe dist" "form on wing")
113+
+Valid goals: ( "fly to ship" "attack ship" "waypoints" "waypoints once" "depart" "attack subsys" "attack wing" "guard ship" "disable ship" "disable ship (tactical)" "disarm ship" "disarm ship (tactical)" "attack any" "attack ship class" "attack ship type" "ignore ship" "ignore ship (new)" "guard wing" "evade ship" "stay still" "play dead" "play dead (persistent)" "stay near ship" "keep safe dist" "form on wing")
114114
+Accept Player Orders: YES
115-
+Player Orders: ( "attack ship" "disable ship" "disable ship (tactical)" "disarm ship" "disarm ship (tactical)" "guard ship" "ignore ship" "ignore ship (new)" "form on wing" "cover me" "attack any" "attack ship class" "depart" "disable subsys" )
115+
+Player Orders: ( "attack ship" "disable ship" "disable ship (tactical)" "disarm ship" "disarm ship (tactical)" "guard ship" "ignore ship" "ignore ship (new)" "form on wing" "cover me" "attack any" "attack ship class" "attack ship type" "depart" "disable subsys" )
116116
+Auto attacks: YES
117117
+Actively Pursues: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "fighter" "bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
118118
+Guards attack this: YES
@@ -138,9 +138,9 @@ $Fog:
138138
+Start dist: 10.0
139139
+Compl dist: 500.0
140140
$AI:
141-
+Valid goals: ( "fly to ship" "attack ship" "waypoints" "waypoints once" "depart" "attack subsys" "attack wing" "guard ship" "disable ship" "disable ship (tactical)" "disarm ship" "disarm ship (tactical)" "attack any" "attack ship class" "ignore ship" "ignore ship (new)" "guard wing" "evade ship" "stay still" "play dead" "play dead (persistent)" "stay near ship" "keep safe dist" "form on wing" )
141+
+Valid goals: ( "fly to ship" "attack ship" "waypoints" "waypoints once" "depart" "attack subsys" "attack wing" "guard ship" "disable ship" "disable ship (tactical)" "disarm ship" "disarm ship (tactical)" "attack any" "attack ship class" "attack ship type" "ignore ship" "ignore ship (new)" "guard wing" "evade ship" "stay still" "play dead" "play dead (persistent)" "stay near ship" "keep safe dist" "form on wing" )
142142
+Accept Player Orders: YES
143-
+Player Orders: ( "attack ship" "disable ship" "disable ship (tactical)" "disarm ship" "disarm ship (tactical)" "guard ship" "ignore ship" "ignore ship (new)" "form on wing" "cover me" "attack any" "attack ship class" "depart" "disable subsys" )
143+
+Player Orders: ( "attack ship" "disable ship" "disable ship (tactical)" "disarm ship" "disarm ship (tactical)" "guard ship" "ignore ship" "ignore ship (new)" "form on wing" "cover me" "attack any" "attack ship class" "attack ship type" "depart" "disable subsys" )
144144
+Auto attacks: YES
145145
+Actively Pursues: ( "navbuoy" "sentry gun" "escape pod" "cargo" "support" "fighter" "bomber" "transport" "freighter" "awacs" "gas miner" "cruiser" "corvette" "capital" "super cap" "drydock" "knossos device" )
146146
+Guards attack this: YES

0 commit comments

Comments
 (0)