@@ -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)) {
0 commit comments