mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-08 07:28:22 -10:00
Compare commits
16
Commits
swifty
...
fs2_open-ai
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42e618e330 | ||
|
|
3e1b9c173b | ||
|
|
3e61b43b31 | ||
|
|
918a805080 | ||
|
|
75f5273c0e | ||
|
|
e130b74231 | ||
|
|
3a6f03a984 | ||
|
|
0287e166df | ||
|
|
1fb5f9cd9b | ||
|
|
92d8507c12 | ||
|
|
914ed7a2f5 | ||
|
|
9dca3f22db | ||
|
|
42ad6cba7c | ||
|
|
12b153fd73 | ||
|
|
7a7eb3b711 | ||
|
|
d18277e2ba |
No files matched your search
@@ -211,6 +211,9 @@ FS2_SOURCES = \
|
||||
ai/aiturret.cpp \
|
||||
ai/ai_profiles.cpp \
|
||||
ai/ai_profiles.h \
|
||||
ai/aimodular.h \
|
||||
ai/aimodular.cpp \
|
||||
ai/newai/newai.cpp \
|
||||
anim/animplay.cpp \
|
||||
anim/animplay.h \
|
||||
anim/packunpack.cpp \
|
||||
@@ -822,6 +825,8 @@ fs2_open_r_SOURCES = \
|
||||
|
||||
fs2_open_d_LDADD = libcode.a ../libjpeg/libjpeg.a ../lua/liblua.a
|
||||
fs2_open_r_LDADD = libcode.a ../libjpeg/libjpeg.a ../lua/liblua.a
|
||||
fs2_open_d_LDFLAGS = -rdynamic
|
||||
fs2_open_r_LDFLAGS = -rdynamic
|
||||
|
||||
##
|
||||
## End MAIN binary
|
||||
|
||||
@@ -235,6 +235,10 @@ void parse_ai_profiles_tbl(char *filename)
|
||||
// fill in any and all settings; they're all optional and can be in any order
|
||||
while (!check_for_string("$Profile Name:") && !check_for_string("#End"))
|
||||
{
|
||||
strcpy(profile->ai_module, "retail");
|
||||
if (optional_string("$AI Module:"))
|
||||
stuff_string(profile->ai_module, F_NAME, NAME_LENGTH);
|
||||
|
||||
if (optional_string("$Player Afterburner Recharge Scale:"))
|
||||
parse_float_list(profile->afterburner_recharge_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
|
||||
@@ -80,6 +80,8 @@
|
||||
typedef struct ai_profile_t {
|
||||
|
||||
char profile_name[NAME_LENGTH];
|
||||
|
||||
char ai_module[NAME_LENGTH];
|
||||
|
||||
int flags;
|
||||
|
||||
|
||||
+179
-24
@@ -482,13 +482,141 @@ extern int model_which_octant_distant_many( vec3d *pnt, int model_num,matrix *mo
|
||||
extern void compute_desired_rvec(vec3d *rvec, vec3d *goal_pos, vec3d *cur_pos);
|
||||
extern void big_ship_collide_recover_start(object *objp, object *big_objp, vec3d *collide_pos, vec3d *collision_normal);
|
||||
|
||||
// FF 14-06-07
|
||||
// AI Big Table Wrapper
|
||||
|
||||
struct aibig_call_table *aibig_table = &AIBigDefaultTable;
|
||||
|
||||
void ai_big_evade_ship ()
|
||||
{
|
||||
aibig_table->ai_big_evade_ship();
|
||||
}
|
||||
|
||||
void ai_big_chase_attack (ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum)
|
||||
{
|
||||
aibig_table->ai_big_chase_attack(aip, sip, enemy_pos, dist_to_enemy, modelnum);
|
||||
}
|
||||
|
||||
void ai_big_avoid_ship ()
|
||||
{
|
||||
aibig_table->ai_big_avoid_ship();
|
||||
}
|
||||
|
||||
int ai_big_maybe_follow_subsys_path (int do_dot_check)
|
||||
{
|
||||
return aibig_table->ai_big_maybe_follow_subsys_path(do_dot_check);
|
||||
}
|
||||
|
||||
void ai_bpap (object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal)
|
||||
{
|
||||
aibig_table->ai_bpap(objp, attacker_objp_pos, attacker_objp_fvec, attack_point, local_attack_point, fov, weapon_travel_dist, surface_normal);
|
||||
}
|
||||
|
||||
void ai_big_pick_attack_point_turret (object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
|
||||
{
|
||||
aibig_table->ai_big_pick_attack_point_turret(objp, ssp, gpos, gvec, attack_point, fov, weapon_travel_dist);
|
||||
}
|
||||
|
||||
void ai_big_pick_attack_point (object *objp, object *attacker_objp, vec3d *attack_point, float fov)
|
||||
{
|
||||
aibig_table->ai_big_pick_attack_point(objp, attacker_objp, attack_point, fov);
|
||||
}
|
||||
|
||||
void ai_big_subsys_path_cleanup (ai_info *aip)
|
||||
{
|
||||
aibig_table->ai_big_subsys_path_cleanup(aip);
|
||||
}
|
||||
|
||||
int ai_big_maybe_start_strafe (ai_info *aip, ship_info *sip)
|
||||
{
|
||||
return aibig_table->ai_big_maybe_start_strafe(aip, sip);
|
||||
}
|
||||
|
||||
void ai_big_chase_ct ()
|
||||
{
|
||||
aibig_table->ai_big_chase_ct();
|
||||
}
|
||||
|
||||
void ai_big_maybe_fire_weapons (float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel)
|
||||
{
|
||||
aibig_table->ai_big_maybe_fire_weapons(dist_to_enemy, dot_to_enemy, firing_pos, enemy_pos, enemy_vel);
|
||||
}
|
||||
|
||||
void ai_big_switch_to_chase_mode (ai_info *aip)
|
||||
{
|
||||
aibig_table->ai_big_switch_to_chase_mode(aip);
|
||||
}
|
||||
|
||||
int ai_big_strafe_maybe_retreat (float dist, vec3d *target_pos)
|
||||
{
|
||||
return aibig_table->ai_big_strafe_maybe_retreat(dist, target_pos);
|
||||
}
|
||||
|
||||
void ai_big_chase ()
|
||||
{
|
||||
aibig_table->ai_big_chase();
|
||||
}
|
||||
|
||||
void ai_big_ship (object *objp)
|
||||
{
|
||||
aibig_table->ai_big_ship(objp);
|
||||
}
|
||||
|
||||
void ai_big_attack_get_data (vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy)
|
||||
{
|
||||
aibig_table->ai_big_attack_get_data(enemy_pos, dist_to_enemy, dot_to_enemy);
|
||||
}
|
||||
|
||||
void ai_big_strafe_attack ()
|
||||
{
|
||||
aibig_table->ai_big_strafe_attack();
|
||||
}
|
||||
|
||||
void ai_big_strafe_avoid ()
|
||||
{
|
||||
aibig_table->ai_big_strafe_avoid();
|
||||
}
|
||||
|
||||
void ai_big_strafe_retreat1 ()
|
||||
{
|
||||
aibig_table->ai_big_strafe_retreat1();
|
||||
}
|
||||
|
||||
void ai_big_strafe_retreat2 ()
|
||||
{
|
||||
aibig_table->ai_big_strafe_retreat2();
|
||||
}
|
||||
|
||||
void ai_big_strafe_position ()
|
||||
{
|
||||
aibig_table->ai_big_strafe_position();
|
||||
}
|
||||
|
||||
void ai_big_strafe ()
|
||||
{
|
||||
aibig_table->ai_big_strafe();
|
||||
}
|
||||
|
||||
int ai_big_maybe_enter_strafe_mode (object *pl_objp, int weapon_objnum, int consider_target_only)
|
||||
{
|
||||
return aibig_table->ai_big_maybe_enter_strafe_mode(pl_objp, weapon_objnum, consider_target_only);
|
||||
}
|
||||
|
||||
void ai_big_strafe_maybe_attack_turret (object *ship_objp, object *weapon_objp)
|
||||
{
|
||||
aibig_table->ai_big_strafe_maybe_attack_turret(ship_objp, weapon_objp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// AI Big Default implementation
|
||||
|
||||
// Called by ai_big_pick_attack_point.
|
||||
// Generates a random attack point.
|
||||
// If truly_random flag set (haha), then generate a pretty random number. Otherwise, generate a static rand which
|
||||
// tends to not change from frame to frame.
|
||||
// Try four times and choose nearest point to increase chance of getting a good point.
|
||||
void ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal)
|
||||
void aibig_ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal)
|
||||
{
|
||||
float nearest_dist;
|
||||
vec3d result_point, best_point;
|
||||
@@ -607,7 +735,7 @@ done_1:
|
||||
//
|
||||
// Note: Default value for fov is 1.0f 1.0f means don't use fov parameter.
|
||||
// If fov != 1.0f, try up to four times to find a point that's in the field of view.
|
||||
void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
|
||||
void aibig_ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
|
||||
{
|
||||
if (!timestamp_elapsed(ssp->turret_pick_big_attack_point_timestamp)) {
|
||||
vec3d result_point;
|
||||
@@ -627,7 +755,7 @@ void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos
|
||||
// Note: Default value for fov is 1.0f 1.0f means don't use fov parameter.
|
||||
// If fov != 1.0f, try up to four times to find a point that's in the field of view.
|
||||
// Note, attacker_objp can be a ship or a weapon.
|
||||
void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov)
|
||||
void aibig_ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov)
|
||||
{
|
||||
Assert(objp->instance > -1);
|
||||
Assert(objp->type == OBJ_SHIP);
|
||||
@@ -696,7 +824,7 @@ void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack
|
||||
}
|
||||
|
||||
// Handler for SM_EVADE submode ( called from ai_big_chase() )
|
||||
void ai_big_evade_ship()
|
||||
void aibig_ai_big_evade_ship()
|
||||
{
|
||||
vec3d player_pos, enemy_pos;
|
||||
float dist;
|
||||
@@ -744,13 +872,13 @@ void ai_big_evade_ship()
|
||||
}
|
||||
|
||||
// Handler for SM_AVOID submode ( called from ai_big_chase() )
|
||||
void ai_big_avoid_ship()
|
||||
void aibig_ai_big_avoid_ship()
|
||||
{
|
||||
ai_big_evade_ship();
|
||||
}
|
||||
|
||||
// reset path following information
|
||||
void ai_big_subsys_path_cleanup(ai_info *aip)
|
||||
void aibig_ai_big_subsys_path_cleanup(ai_info *aip)
|
||||
{
|
||||
if ( aip->ai_flags & AIF_ON_SUBSYS_PATH ) {
|
||||
aip->ai_flags &= ~AIF_ON_SUBSYS_PATH;
|
||||
@@ -765,7 +893,7 @@ void ai_big_subsys_path_cleanup(ai_info *aip)
|
||||
// input: do_dot_check => default value 0, flag to indicate whether check should be done to ensure
|
||||
// subsystem is within certain field of view. We don't want to check fov when
|
||||
// strafing, since ship is weaving to avoid turret fire
|
||||
int ai_big_maybe_follow_subsys_path(int do_dot_check)
|
||||
int aibig_ai_big_maybe_follow_subsys_path(int do_dot_check)
|
||||
{
|
||||
ai_info *aip;
|
||||
float dot = 1.0f, min_dot;
|
||||
@@ -899,7 +1027,7 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
|
||||
// 0 => ship should not change ai mode, no fighter/bomber threats are near
|
||||
//
|
||||
// NOTE: uses SCAN_FIGHTERS_INTERVAL and ENTER_STRAFE_THREAT_DIST_SQUARED which are defined in AiBig.h
|
||||
int ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
|
||||
int aibig_ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
|
||||
{
|
||||
// if moving slowly (or stopped), and SIF_SMALL_SHIP, then enter STRAFE mode if enemy fighter/bombers
|
||||
// are near
|
||||
@@ -934,7 +1062,7 @@ int ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
|
||||
}
|
||||
|
||||
// ATTACK submode handler for chase mode.
|
||||
void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum)
|
||||
void aibig_ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum)
|
||||
{
|
||||
int start_bank;
|
||||
float dot_to_enemy, time_to_hit;
|
||||
@@ -1051,7 +1179,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
|
||||
}
|
||||
|
||||
// Handler for submode SM_CONTINUOUS_TURN
|
||||
void ai_big_chase_ct()
|
||||
void aibig_ai_big_chase_ct()
|
||||
{
|
||||
ai_chase_ct();
|
||||
}
|
||||
@@ -1068,7 +1196,7 @@ extern void maybe_cheat_fire_synaptic(object *objp, ai_info *aip);
|
||||
// dist_to_enemy => distance (in m) to attack point on current target
|
||||
// dot_to_enemy => dot product between fvec of Pl_objp and vector from Pl_objp to attack point
|
||||
//
|
||||
void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel)
|
||||
void aibig_ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel)
|
||||
{
|
||||
ai_info *aip;
|
||||
ship_weapon *swp;
|
||||
@@ -1173,7 +1301,7 @@ void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *f
|
||||
}
|
||||
|
||||
// switch ai ship into chase mode
|
||||
void ai_big_switch_to_chase_mode(ai_info *aip)
|
||||
void aibig_ai_big_switch_to_chase_mode(ai_info *aip)
|
||||
{
|
||||
aip->previous_mode = aip->mode;
|
||||
aip->mode = AIM_CHASE;
|
||||
@@ -1184,7 +1312,7 @@ void ai_big_switch_to_chase_mode(ai_info *aip)
|
||||
extern int ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos);
|
||||
|
||||
// Make object Pl_objp chase object En_objp, which is a big ship, not a small ship.
|
||||
void ai_big_chase()
|
||||
void aibig_ai_big_chase()
|
||||
{
|
||||
float dist_to_enemy, dot_to_enemy;
|
||||
vec3d player_pos, enemy_pos, vec_to_enemy;
|
||||
@@ -1474,7 +1602,7 @@ void ai_big_chase()
|
||||
aip->time_enemy_in_range *= (1.0f - flFrametime);
|
||||
}
|
||||
|
||||
void ai_big_ship(object *objp)
|
||||
void aibig_ai_big_ship(object *objp)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@@ -1485,7 +1613,7 @@ void ai_big_ship(object *objp)
|
||||
// dist => distance from Pl_objp front to attack point
|
||||
// dot => dot of Pl_objp fvec and vector to attack point
|
||||
// fire_pos => world pos from which firing
|
||||
void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy)
|
||||
void aibig_ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy)
|
||||
{
|
||||
vec3d player_pos, vec_to_enemy, predicted_enemy_pos;
|
||||
ship *shipp = &Ships[Pl_objp->instance];
|
||||
@@ -1544,7 +1672,7 @@ void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_t
|
||||
|
||||
// check to see if Pl_objp has gotten too close to attacking point.. if so, break off by entering
|
||||
// AIS_STRAFE_RETREAT
|
||||
int ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
|
||||
int aibig_ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
|
||||
{
|
||||
ai_info *aip;
|
||||
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
|
||||
@@ -1601,7 +1729,7 @@ int ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
|
||||
}
|
||||
|
||||
// attack directly to the turret and fire weapons
|
||||
void ai_big_strafe_attack()
|
||||
void aibig_ai_big_strafe_attack()
|
||||
{
|
||||
ai_info *aip;
|
||||
vec3d target_pos;
|
||||
@@ -1704,7 +1832,7 @@ void ai_big_strafe_attack()
|
||||
}
|
||||
|
||||
// pick a new attack point when entering this state, and keep using it
|
||||
void ai_big_strafe_avoid()
|
||||
void aibig_ai_big_strafe_avoid()
|
||||
{
|
||||
ai_info *aip;
|
||||
vec3d target_pos;
|
||||
@@ -1730,7 +1858,7 @@ void ai_big_strafe_avoid()
|
||||
}
|
||||
|
||||
// move towards aip->goal_point in an evasive manner
|
||||
void ai_big_strafe_retreat1()
|
||||
void aibig_ai_big_strafe_retreat1()
|
||||
{
|
||||
float dist;
|
||||
ai_info *aip;
|
||||
@@ -1776,7 +1904,7 @@ void ai_big_strafe_retreat1()
|
||||
accelerate_ship(aip, 1.0f);
|
||||
}
|
||||
|
||||
void ai_big_strafe_retreat2()
|
||||
void aibig_ai_big_strafe_retreat2()
|
||||
{
|
||||
float dist;
|
||||
ai_info *aip;
|
||||
@@ -1815,7 +1943,7 @@ void ai_big_strafe_retreat2()
|
||||
}
|
||||
|
||||
// reposition self to begin another strafing run
|
||||
void ai_big_strafe_position()
|
||||
void aibig_ai_big_strafe_position()
|
||||
{
|
||||
ai_info *aip;
|
||||
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
|
||||
@@ -1833,7 +1961,7 @@ void ai_big_strafe_position()
|
||||
// #define AIS_STRAFE_RETREAT1 204 // fly away from attack point (on an avoid vector)
|
||||
// #define AIS_STRAFE_POSITION 205 // re-position to resume strafing attack
|
||||
//
|
||||
void ai_big_strafe()
|
||||
void aibig_ai_big_strafe()
|
||||
{
|
||||
ai_info *aip;
|
||||
|
||||
@@ -1883,7 +2011,7 @@ void ai_big_strafe()
|
||||
//
|
||||
// Check if weapon_objnum was fired by Pl_objp's target, and whether Pl_objp's target is a big ship, if
|
||||
// so, enter AIM_STRAFE
|
||||
int ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int consider_target_only)
|
||||
int aibig_ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int consider_target_only)
|
||||
{
|
||||
ai_info *aip;
|
||||
ship_info *sip;
|
||||
@@ -1957,7 +2085,7 @@ int ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int consi
|
||||
// Consider attacking a turret, if a turret actually fired the weapon
|
||||
// input: ship_objp => ship that will attack the turret
|
||||
// weapon_objp =>
|
||||
void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp)
|
||||
void aibig_ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp)
|
||||
{
|
||||
ai_info *aip;
|
||||
object *parent_objp;
|
||||
@@ -2006,3 +2134,30 @@ void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp)
|
||||
// attack the turret
|
||||
set_targeted_subsys(aip, Weapons[weapon_objp->instance].turret_subsys, OBJ_INDEX(parent_objp));
|
||||
}
|
||||
|
||||
struct aibig_call_table AIBigDefaultTable = {
|
||||
aibig_ai_big_evade_ship,
|
||||
aibig_ai_big_chase_attack,
|
||||
aibig_ai_big_avoid_ship,
|
||||
aibig_ai_big_maybe_follow_subsys_path,
|
||||
aibig_ai_bpap,
|
||||
aibig_ai_big_pick_attack_point_turret,
|
||||
aibig_ai_big_pick_attack_point,
|
||||
aibig_ai_big_subsys_path_cleanup,
|
||||
aibig_ai_big_maybe_start_strafe,
|
||||
aibig_ai_big_chase_ct,
|
||||
aibig_ai_big_maybe_fire_weapons,
|
||||
aibig_ai_big_switch_to_chase_mode,
|
||||
aibig_ai_big_strafe_maybe_retreat,
|
||||
aibig_ai_big_chase,
|
||||
aibig_ai_big_ship,
|
||||
aibig_ai_big_attack_get_data,
|
||||
aibig_ai_big_strafe_attack,
|
||||
aibig_ai_big_strafe_avoid,
|
||||
aibig_ai_big_strafe_retreat1,
|
||||
aibig_ai_big_strafe_retreat2,
|
||||
aibig_ai_big_strafe_position,
|
||||
aibig_ai_big_strafe,
|
||||
aibig_ai_big_maybe_enter_strafe_mode,
|
||||
aibig_ai_big_strafe_maybe_attack_turret
|
||||
};
|
||||
+38
-1
@@ -102,6 +102,43 @@ void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp);
|
||||
void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov=1.0f);
|
||||
void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float weapon_travel_dist, float fov=1.0f);
|
||||
|
||||
// AI Big Table Wrapper
|
||||
|
||||
#include "ship/ship.h"
|
||||
|
||||
struct aibig_call_table
|
||||
{
|
||||
void (*ai_big_evade_ship) ();
|
||||
void (*ai_big_chase_attack) (ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum);
|
||||
void (*ai_big_avoid_ship) ();
|
||||
int (*ai_big_maybe_follow_subsys_path) (int do_dot_check=1);
|
||||
void (*ai_bpap) (object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal);
|
||||
void (*ai_big_pick_attack_point_turret) (object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist);
|
||||
void (*ai_big_pick_attack_point) (object *objp, object *attacker_objp, vec3d *attack_point, float fov);
|
||||
void (*ai_big_subsys_path_cleanup) (ai_info *aip);
|
||||
int (*ai_big_maybe_start_strafe) (ai_info *aip, ship_info *sip);
|
||||
void (*ai_big_chase_ct) ();
|
||||
void (*ai_big_maybe_fire_weapons) (float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel);
|
||||
void (*ai_big_switch_to_chase_mode) (ai_info *aip);
|
||||
int (*ai_big_strafe_maybe_retreat) (float dist, vec3d *target_pos);
|
||||
void (*ai_big_chase) ();
|
||||
void (*ai_big_ship) (object *objp);
|
||||
void (*ai_big_attack_get_data) (vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy);
|
||||
void (*ai_big_strafe_attack) ();
|
||||
void (*ai_big_strafe_avoid) ();
|
||||
void (*ai_big_strafe_retreat1) ();
|
||||
void (*ai_big_strafe_retreat2) ();
|
||||
void (*ai_big_strafe_position) ();
|
||||
void (*ai_big_strafe) ();
|
||||
int (*ai_big_maybe_enter_strafe_mode) (object *pl_objp, int weapon_objnum, int consider_target_only);
|
||||
void (*ai_big_strafe_maybe_attack_turret) (object *ship_objp, object *weapon_objp);
|
||||
};
|
||||
|
||||
// Set new pointer to override ai_big* function calls
|
||||
// possibly copying the old function calls first
|
||||
|
||||
extern struct aibig_call_table *aibig_table;
|
||||
|
||||
extern struct aibig_call_table AIBigDefaultTable;
|
||||
|
||||
#endif
|
||||
|
||||
+1414
-212
File diff suppressed because it is too large.
Load diff
+233
-32
@@ -772,11 +772,176 @@ ai_goal_list Ai_goal_names[] =
|
||||
|
||||
int Num_ai_goals = sizeof(Ai_goal_names) / sizeof(ai_goal_list);
|
||||
|
||||
// FF 04-06-07
|
||||
// AI Goal Table Wrapper
|
||||
|
||||
struct aigoal_call_table *aigoal_table = &AIGoalDefaultTable;
|
||||
|
||||
char* Ai_goal_text (int goal)
|
||||
{
|
||||
return aigoal_table->Ai_goal_text(goal);
|
||||
}
|
||||
|
||||
void ai_maybe_add_form_goal (wing *wingp)
|
||||
{
|
||||
aigoal_table->ai_maybe_add_form_goal(wingp);
|
||||
}
|
||||
|
||||
void ai_post_process_mission ()
|
||||
{
|
||||
aigoal_table->ai_post_process_mission();
|
||||
}
|
||||
|
||||
int ai_query_goal_valid (int ship, int ai_goal)
|
||||
{
|
||||
return aigoal_table->ai_query_goal_valid(ship, ai_goal);
|
||||
}
|
||||
|
||||
void ai_remove_ship_goal (ai_info *aip, int index)
|
||||
{
|
||||
aigoal_table->ai_remove_ship_goal(aip, index);
|
||||
}
|
||||
|
||||
void ai_clear_ship_goals (ai_info *aip)
|
||||
{
|
||||
aigoal_table->ai_clear_ship_goals(aip);
|
||||
}
|
||||
|
||||
void ai_clear_wing_goals (int wingnum)
|
||||
{
|
||||
aigoal_table->ai_clear_wing_goals(wingnum);
|
||||
}
|
||||
|
||||
void ai_mission_wing_goal_complete (int wingnum, ai_goal *remove_goalp)
|
||||
{
|
||||
aigoal_table->ai_mission_wing_goal_complete(wingnum, remove_goalp);
|
||||
}
|
||||
|
||||
void ai_mission_goal_complete (ai_info *aip)
|
||||
{
|
||||
aigoal_table->ai_mission_goal_complete(aip);
|
||||
}
|
||||
|
||||
int ai_get_subsystem_type (char *subsystem)
|
||||
{
|
||||
return aigoal_table->ai_get_subsystem_type(subsystem);
|
||||
}
|
||||
|
||||
void ai_goal_purge_invalid_goals (ai_goal *aigp, ai_goal *goal_list)
|
||||
{
|
||||
aigoal_table->ai_goal_purge_invalid_goals(aigp, goal_list);
|
||||
}
|
||||
|
||||
void ai_goal_purge_all_invalid_goals (ai_goal *aigp)
|
||||
{
|
||||
aigoal_table->ai_goal_purge_all_invalid_goals(aigp);
|
||||
}
|
||||
|
||||
int ai_goal_find_dockpoint (int shipnum, int dock_type)
|
||||
{
|
||||
return aigoal_table->ai_goal_find_dockpoint(shipnum, dock_type);
|
||||
}
|
||||
|
||||
void ai_goal_fixup_dockpoints (ai_info *aip, ai_goal *aigp)
|
||||
{
|
||||
aigoal_table->ai_goal_fixup_dockpoints(aip, aigp);
|
||||
}
|
||||
|
||||
void ai_add_goal_sub_player (int type, int mode, int submode, char *shipname, ai_goal *aigp)
|
||||
{
|
||||
aigoal_table->ai_add_goal_sub_player(type, mode, submode, shipname, aigp);
|
||||
}
|
||||
|
||||
int ai_goal_find_empty_slot (ai_goal *goals, int active_goal)
|
||||
{
|
||||
return aigoal_table->ai_goal_find_empty_slot(goals, active_goal);
|
||||
}
|
||||
|
||||
void ai_add_ship_goal_player (int type, int mode, int submode, char *shipname, ai_info *aip)
|
||||
{
|
||||
aigoal_table->ai_add_ship_goal_player(type, mode, submode, shipname, aip);
|
||||
}
|
||||
|
||||
void ai_add_wing_goal_player (int type, int mode, int submode, char *shipname, int wingnum)
|
||||
{
|
||||
aigoal_table->ai_add_wing_goal_player(type, mode, submode, shipname, wingnum);
|
||||
}
|
||||
|
||||
void ai_add_goal_sub_sexp (int sexp, int type, ai_goal *aigp, char *actor_name)
|
||||
{
|
||||
aigoal_table->ai_add_goal_sub_sexp(sexp, type, aigp, actor_name);
|
||||
}
|
||||
|
||||
void ai_add_ship_goal_sexp (int sexp, int type, ai_info *aip)
|
||||
{
|
||||
aigoal_table->ai_add_ship_goal_sexp(sexp, type, aip);
|
||||
}
|
||||
|
||||
void ai_add_wing_goal_sexp (int sexp, int type, int wingnum)
|
||||
{
|
||||
aigoal_table->ai_add_wing_goal_sexp(sexp, type, wingnum);
|
||||
}
|
||||
|
||||
void ai_add_goal_ship_internal (ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate)
|
||||
{
|
||||
aigoal_table->ai_add_goal_ship_internal(aip, goal_type, name, docker_point, dockee_point, immediate);
|
||||
}
|
||||
|
||||
void ai_add_goal_wing_internal (wing *wingp, int goal_type, char *name, int immediate)
|
||||
{
|
||||
aigoal_table->ai_add_goal_wing_internal(wingp, goal_type, name, immediate);
|
||||
}
|
||||
|
||||
void ai_copy_mission_wing_goal (ai_goal *aigp, ai_info *aip)
|
||||
{
|
||||
aigoal_table->ai_copy_mission_wing_goal(aigp, aip);
|
||||
}
|
||||
|
||||
int ai_mission_goal_achievable (int objnum, ai_goal *aigp)
|
||||
{
|
||||
return aigoal_table->ai_mission_goal_achievable(objnum, aigp);
|
||||
}
|
||||
|
||||
int ai_goal_priority_compare (const void *a, const void *b)
|
||||
{
|
||||
return aigoal_table->ai_goal_priority_compare(a, b);
|
||||
}
|
||||
|
||||
void prioritize_goals (int objnum, ai_info *aip)
|
||||
{
|
||||
aigoal_table->prioritize_goals(objnum, aip);
|
||||
}
|
||||
|
||||
void validate_mission_goals (int objnum, ai_info *aip)
|
||||
{
|
||||
aigoal_table->validate_mission_goals(objnum, aip);
|
||||
}
|
||||
|
||||
void ai_process_mission_orders (int objnum, ai_info *aip)
|
||||
{
|
||||
aigoal_table->ai_process_mission_orders(objnum, aip);
|
||||
}
|
||||
|
||||
void ai_update_goal_references (ai_goal *goals, int type, char *old_name, char *new_name)
|
||||
{
|
||||
aigoal_table->ai_update_goal_references(goals, type, old_name, new_name);
|
||||
}
|
||||
|
||||
int query_referenced_in_ai_goals (ai_goal *goals, int type, char *name)
|
||||
{
|
||||
return aigoal_table->query_referenced_in_ai_goals(goals, type, name);
|
||||
}
|
||||
|
||||
char* ai_add_dock_name (char *str)
|
||||
{
|
||||
return aigoal_table->ai_add_dock_name(str);
|
||||
}
|
||||
|
||||
// AL 11-17-97: A text description of the AI goals. This is used for printing out on the
|
||||
// HUD what a ship's current orders are. If the AI goal doesn't correspond to something that
|
||||
// ought to be printable, then NULL is used.
|
||||
// JAS: Converted to a function in order to externalize the strings
|
||||
char *Ai_goal_text(int goal)
|
||||
char *aigoal_Ai_goal_text(int goal)
|
||||
{
|
||||
switch(goal) {
|
||||
case 1:
|
||||
@@ -815,7 +980,7 @@ char *Ai_goal_text(int goal)
|
||||
|
||||
// function to maybe add the form on my wing goal for a player's starting wing. Called when a player wing arrives.
|
||||
// Goober5000 - made more generic
|
||||
void ai_maybe_add_form_goal( wing *wingp )
|
||||
void aigoal_ai_maybe_add_form_goal( wing *wingp )
|
||||
{
|
||||
int j;
|
||||
char *wing_leader;
|
||||
@@ -853,7 +1018,7 @@ void ai_maybe_add_form_goal( wing *wingp )
|
||||
}
|
||||
}
|
||||
|
||||
void ai_post_process_mission()
|
||||
void aigoal_ai_post_process_mission()
|
||||
{
|
||||
object *objp;
|
||||
|
||||
@@ -907,7 +1072,7 @@ void ai_post_process_mission()
|
||||
}
|
||||
|
||||
// function which determines is a goal is valid for a particular type of ship
|
||||
int ai_query_goal_valid( int ship, int ai_goal )
|
||||
int aigoal_ai_query_goal_valid( int ship, int ai_goal )
|
||||
{
|
||||
int accepted;
|
||||
|
||||
@@ -930,7 +1095,7 @@ int ai_query_goal_valid( int ship, int ai_goal )
|
||||
}
|
||||
|
||||
// remove an ai goal from it's list. Uses the active_goal member as the goal to remove
|
||||
void ai_remove_ship_goal( ai_info *aip, int index )
|
||||
void aigoal_ai_remove_ship_goal( ai_info *aip, int index )
|
||||
{
|
||||
// only need to set the ai_mode for the particular goal to AI_GOAL_NONE
|
||||
// reset ai mode to default behavior. Might get changed next time through
|
||||
@@ -950,7 +1115,7 @@ void ai_remove_ship_goal( ai_info *aip, int index )
|
||||
//ai_do_default_behavior( &Objects[Ships[aip->shipnum].objnum] );
|
||||
}
|
||||
|
||||
void ai_clear_ship_goals( ai_info *aip )
|
||||
void aigoal_ai_clear_ship_goals( ai_info *aip )
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -969,7 +1134,7 @@ void ai_clear_ship_goals( ai_info *aip )
|
||||
}
|
||||
}
|
||||
|
||||
void ai_clear_wing_goals( int wingnum )
|
||||
void aigoal_ai_clear_wing_goals( int wingnum )
|
||||
{
|
||||
int i;
|
||||
wing *wingp = &Wings[wingnum];
|
||||
@@ -999,7 +1164,7 @@ void ai_clear_wing_goals( int wingnum )
|
||||
// structure of the goal to be removed. This process is slightly tricky since some member of the wing
|
||||
// might be pursuing a different goal. We will have to compare based on mode, submode, priority,
|
||||
// and name.. This routine is only currently called from waypoint code!!!
|
||||
void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
|
||||
void aigoal_ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
|
||||
{
|
||||
int mode, submode, priority, i;
|
||||
char *name;
|
||||
@@ -1059,7 +1224,7 @@ void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
|
||||
// routine which is called with an ai object complete it's goal. Do some action
|
||||
// based on the goal what was just completed
|
||||
|
||||
void ai_mission_goal_complete( ai_info *aip )
|
||||
void aigoal_ai_mission_goal_complete( ai_info *aip )
|
||||
{
|
||||
// if the active goal is dynamic or none, just return. (AI_GOAL_NONE is probably an error, but
|
||||
// I don't think that this is a problem)
|
||||
@@ -1071,7 +1236,7 @@ void ai_mission_goal_complete( ai_info *aip )
|
||||
|
||||
}
|
||||
|
||||
int ai_get_subsystem_type( char *subsystem )
|
||||
int aigoal_ai_get_subsystem_type( char *subsystem )
|
||||
{
|
||||
if ( strstr(subsystem, "engine") ) {
|
||||
return SUBSYSTEM_ENGINE;
|
||||
@@ -1107,7 +1272,7 @@ int ai_get_subsystem_type( char *subsystem )
|
||||
// which are destroy, etc, should get removed. goal list is the list of goals to purge. It is
|
||||
// always MAX_AI_GOALS in length. This function will only get called when the goal which causes
|
||||
// purging becomes valid.
|
||||
void ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list )
|
||||
void aigoal_ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list )
|
||||
{
|
||||
int i;
|
||||
ai_goal *purge_goal;
|
||||
@@ -1173,7 +1338,7 @@ void ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list )
|
||||
}
|
||||
|
||||
// function to purge the goals of *all* ships in the game based on the incoming goal structure
|
||||
void ai_goal_purge_all_invalid_goals(ai_goal *aigp)
|
||||
void aigoal_ai_goal_purge_all_invalid_goals(ai_goal *aigp)
|
||||
{
|
||||
int i;
|
||||
ship_obj *sop;
|
||||
@@ -1196,7 +1361,7 @@ void ai_goal_purge_all_invalid_goals(ai_goal *aigp)
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
int ai_goal_find_dockpoint(int shipnum, int dock_type)
|
||||
int aigoal_ai_goal_find_dockpoint(int shipnum, int dock_type)
|
||||
{
|
||||
int dock_index = -1;
|
||||
int loop_count = 0;
|
||||
@@ -1247,7 +1412,7 @@ int ai_goal_find_dockpoint(int shipnum, int dock_type)
|
||||
// passed are the pointer to goal we are working with. aip if the ai_info pointer
|
||||
// of the ship with the order. aigp is a pointer to the goal (of aip) of which we are
|
||||
// fixing up the docking points
|
||||
void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
|
||||
void aigoal_ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
|
||||
{
|
||||
int shipnum, docker_index, dockee_index;
|
||||
|
||||
@@ -1318,7 +1483,7 @@ void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
|
||||
// from the mission goals (i.e. those goals which come from events) in that we don't
|
||||
// use sexpressions for goals from the player...so we enumerate all the parameters
|
||||
|
||||
void ai_add_goal_sub_player(int type, int mode, int submode, char *shipname, ai_goal *aigp )
|
||||
void aigoal_ai_add_goal_sub_player(int type, int mode, int submode, char *shipname, ai_goal *aigp )
|
||||
{
|
||||
Assert ( (type == AIG_TYPE_PLAYER_WING) || (type == AIG_TYPE_PLAYER_SHIP) );
|
||||
|
||||
@@ -1359,7 +1524,7 @@ void ai_add_goal_sub_player(int type, int mode, int submode, char *shipname, ai_
|
||||
// friendlies want to rearm at the same time. The support ship forgets what it's doing and flies
|
||||
// off to repair somebody while still docked. I reproduced this with retail, so it's not a bug in
|
||||
// my new docking code. :)
|
||||
int ai_goal_find_empty_slot( ai_goal *goals, int active_goal )
|
||||
int aigoal_ai_goal_find_empty_slot( ai_goal *goals, int active_goal )
|
||||
{
|
||||
int gindex, oldest_index;
|
||||
|
||||
@@ -1389,7 +1554,7 @@ int ai_goal_find_empty_slot( ai_goal *goals, int active_goal )
|
||||
// is issued to ship or wing (from player), mode is AI_GOAL_*. submode is the submode the
|
||||
// ship should go into. shipname is the object of the action. aip is the ai_info pointer
|
||||
// of the ship receiving the order
|
||||
void ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip )
|
||||
void aigoal_ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip )
|
||||
{
|
||||
int empty_index;
|
||||
ai_goal *aigp;
|
||||
@@ -1415,7 +1580,7 @@ void ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, a
|
||||
|
||||
// adds a goal from the player to the given wing (which in turn will add it to the proper
|
||||
// ships in the wing
|
||||
void ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, int wingnum )
|
||||
void aigoal_ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, int wingnum )
|
||||
{
|
||||
int i, empty_index;
|
||||
wing *wingp = &Wings[wingnum];
|
||||
@@ -1439,7 +1604,7 @@ void ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, i
|
||||
|
||||
|
||||
// common routine to add a sexpression mission goal to the appropriate goal structure.
|
||||
void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
void aigoal_ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
{
|
||||
int node, dummy, op;
|
||||
char *text;
|
||||
@@ -1630,7 +1795,7 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
|
||||
// adds an ai goal for an individual ship
|
||||
// type determines who has issues this ship a goal (i.e. the player/mission event/etc)
|
||||
void ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip )
|
||||
void aigoal_ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip )
|
||||
{
|
||||
int gindex;
|
||||
|
||||
@@ -1639,7 +1804,7 @@ void ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip )
|
||||
}
|
||||
|
||||
// code to add ai goals to wings.
|
||||
void ai_add_wing_goal_sexp(int sexp, int type, int wingnum)
|
||||
void aigoal_ai_add_wing_goal_sexp(int sexp, int type, int wingnum)
|
||||
{
|
||||
int i;
|
||||
wing *wingp = &Wings[wingnum];
|
||||
@@ -1673,7 +1838,7 @@ void ai_add_wing_goal_sexp(int sexp, int type, int wingnum)
|
||||
// this name can be a shipname or a wingname)
|
||||
// docker_point and dockee_point are used for the AI_GOAL_DOCK command to tell two ships where to dock
|
||||
// immediate means to process this order right away
|
||||
void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate )
|
||||
void aigoal_ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate )
|
||||
{
|
||||
int gindex;
|
||||
ai_goal *aigp;
|
||||
@@ -1753,7 +1918,7 @@ void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int doc
|
||||
// across waves of the wing so we merely need to add the goal to each ship in the wing. Certain
|
||||
// goal are simply not valid for wings (like dock, undock). Immediate parameter gets passed to add_ship_goal
|
||||
// to say whether or not we should process this goal right away
|
||||
void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate )
|
||||
void aigoal_ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate )
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1769,7 +1934,7 @@ void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int imme
|
||||
}
|
||||
|
||||
// this function copies goals from a wing to an ai_info * from a ship.
|
||||
void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
|
||||
void aigoal_ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
|
||||
{
|
||||
int j;
|
||||
|
||||
@@ -1790,7 +1955,7 @@ void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
|
||||
// function to determine if an ai goal is achieveable or not. Will return
|
||||
// one of the AI_GOAL_* values. Also determines is a goal was successful.
|
||||
|
||||
int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
int aigoal_ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
{
|
||||
int status;
|
||||
char *ai_shipname;
|
||||
@@ -2269,7 +2434,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
|
||||
// Compare function for sorting ai_goals based on priority.
|
||||
// Return values set to sort array in _decreasing_ order.
|
||||
int ai_goal_priority_compare(const void *a, const void *b)
|
||||
int aigoal_ai_goal_priority_compare(const void *a, const void *b)
|
||||
{
|
||||
ai_goal *ga, *gb;
|
||||
|
||||
@@ -2318,7 +2483,7 @@ int ai_goal_priority_compare(const void *a, const void *b)
|
||||
// Then sort on time for goals of equivalent priority.
|
||||
// objnum The object number to act upon. Redundant with *aip.
|
||||
// *aip The AI info to act upon. Goals are stored at aip->goals
|
||||
void prioritize_goals(int objnum, ai_info *aip)
|
||||
void aigoal_prioritize_goals(int objnum, ai_info *aip)
|
||||
{
|
||||
// First sort based on priority field.
|
||||
insertion_sort(aip->goals, MAX_AI_GOALS, sizeof(ai_goal), ai_goal_priority_compare);
|
||||
@@ -2328,7 +2493,7 @@ void prioritize_goals(int objnum, ai_info *aip)
|
||||
// Remove obsolete goals.
|
||||
// objnum Object of interest. Redundant with *aip.
|
||||
// *aip contains goals at aip->goals.
|
||||
void validate_mission_goals(int objnum, ai_info *aip)
|
||||
void aigoal_validate_mission_goals(int objnum, ai_info *aip)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -2403,7 +2568,7 @@ extern char *Mode_text[MAX_AI_BEHAVIORS];
|
||||
// code to process ai "orders". Orders include those determined from the mission file and those
|
||||
// given by the player to a ship that is under his control. This function gets called for every
|
||||
// AI object every N seconds through the ai loop.
|
||||
void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
void aigoal_ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
{
|
||||
object *objp = &Objects[objnum];
|
||||
object *other_obj;
|
||||
@@ -2724,7 +2889,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
|
||||
}
|
||||
|
||||
void ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *new_name)
|
||||
void aigoal_ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *new_name)
|
||||
{
|
||||
int i, mode, flag, dummy;
|
||||
|
||||
@@ -2791,7 +2956,7 @@ void ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *n
|
||||
}
|
||||
}
|
||||
|
||||
int query_referenced_in_ai_goals(ai_goal *goals, int type, char *name)
|
||||
int aigoal_query_referenced_in_ai_goals(ai_goal *goals, int type, char *name)
|
||||
{
|
||||
int i, mode, flag;
|
||||
|
||||
@@ -2856,7 +3021,7 @@ int query_referenced_in_ai_goals(ai_goal *goals, int type, char *name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *ai_add_dock_name(char *str)
|
||||
char *aigoal_ai_add_dock_name(char *str)
|
||||
{
|
||||
char *ptr;
|
||||
int i;
|
||||
@@ -2871,3 +3036,39 @@ char *ai_add_dock_name(char *str)
|
||||
strcpy(ptr, str);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
struct aigoal_call_table AIGoalDefaultTable = {
|
||||
aigoal_Ai_goal_text,
|
||||
aigoal_ai_maybe_add_form_goal,
|
||||
aigoal_ai_post_process_mission,
|
||||
aigoal_ai_query_goal_valid,
|
||||
aigoal_ai_remove_ship_goal,
|
||||
aigoal_ai_clear_ship_goals,
|
||||
aigoal_ai_clear_wing_goals,
|
||||
aigoal_ai_mission_wing_goal_complete,
|
||||
aigoal_ai_mission_goal_complete,
|
||||
aigoal_ai_get_subsystem_type,
|
||||
aigoal_ai_goal_purge_invalid_goals,
|
||||
aigoal_ai_goal_purge_all_invalid_goals,
|
||||
aigoal_ai_goal_find_dockpoint,
|
||||
aigoal_ai_goal_fixup_dockpoints,
|
||||
aigoal_ai_add_goal_sub_player,
|
||||
aigoal_ai_goal_find_empty_slot,
|
||||
aigoal_ai_add_ship_goal_player,
|
||||
aigoal_ai_add_wing_goal_player,
|
||||
aigoal_ai_add_goal_sub_sexp,
|
||||
aigoal_ai_add_ship_goal_sexp,
|
||||
aigoal_ai_add_wing_goal_sexp,
|
||||
aigoal_ai_add_goal_ship_internal,
|
||||
aigoal_ai_add_goal_wing_internal,
|
||||
aigoal_ai_copy_mission_wing_goal,
|
||||
aigoal_ai_mission_goal_achievable,
|
||||
aigoal_ai_goal_priority_compare,
|
||||
aigoal_prioritize_goals,
|
||||
aigoal_validate_mission_goals,
|
||||
aigoal_ai_process_mission_orders,
|
||||
aigoal_ai_update_goal_references,
|
||||
aigoal_query_referenced_in_ai_goals,
|
||||
aigoal_ai_add_dock_name
|
||||
};
|
||||
@@ -292,4 +292,48 @@ extern int ai_query_goal_valid( int ship, int ai_goal );
|
||||
extern void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate = 1 );
|
||||
extern void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate = 1 );
|
||||
|
||||
// AI Goal Table Wrapper
|
||||
struct aigoal_call_table
|
||||
{
|
||||
char* (*Ai_goal_text) (int goal);
|
||||
void (*ai_maybe_add_form_goal) (wing *wingp);
|
||||
void (*ai_post_process_mission) ();
|
||||
int (*ai_query_goal_valid) (int ship, int ai_goal);
|
||||
void (*ai_remove_ship_goal) (ai_info *aip, int index);
|
||||
void (*ai_clear_ship_goals) (ai_info *aip);
|
||||
void (*ai_clear_wing_goals) (int wingnum);
|
||||
void (*ai_mission_wing_goal_complete) (int wingnum, ai_goal *remove_goalp);
|
||||
void (*ai_mission_goal_complete) (ai_info *aip);
|
||||
int (*ai_get_subsystem_type) (char *subsystem);
|
||||
void (*ai_goal_purge_invalid_goals) (ai_goal *aigp, ai_goal *goal_list);
|
||||
void (*ai_goal_purge_all_invalid_goals) (ai_goal *aigp);
|
||||
int (*ai_goal_find_dockpoint) (int shipnum, int dock_type);
|
||||
void (*ai_goal_fixup_dockpoints) (ai_info *aip, ai_goal *aigp);
|
||||
void (*ai_add_goal_sub_player) (int type, int mode, int submode, char *shipname, ai_goal *aigp);
|
||||
int (*ai_goal_find_empty_slot) (ai_goal *goals, int active_goal);
|
||||
void (*ai_add_ship_goal_player) (int type, int mode, int submode, char *shipname, ai_info *aip);
|
||||
void (*ai_add_wing_goal_player) (int type, int mode, int submode, char *shipname, int wingnum);
|
||||
void (*ai_add_goal_sub_sexp) (int sexp, int type, ai_goal *aigp, char *actor_name);
|
||||
void (*ai_add_ship_goal_sexp) (int sexp, int type, ai_info *aip);
|
||||
void (*ai_add_wing_goal_sexp) (int sexp, int type, int wingnum);
|
||||
void (*ai_add_goal_ship_internal) (ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate);
|
||||
void (*ai_add_goal_wing_internal) (wing *wingp, int goal_type, char *name, int immediate);
|
||||
void (*ai_copy_mission_wing_goal) (ai_goal *aigp, ai_info *aip);
|
||||
int (*ai_mission_goal_achievable) (int objnum, ai_goal *aigp);
|
||||
int (*ai_goal_priority_compare) (const void *a, const void *b);
|
||||
void (*prioritize_goals) (int objnum, ai_info *aip);
|
||||
void (*validate_mission_goals) (int objnum, ai_info *aip);
|
||||
void (*ai_process_mission_orders) (int objnum, ai_info *aip);
|
||||
void (*ai_update_goal_references) (ai_goal *goals, int type, char *old_name, char *new_name);
|
||||
int (*query_referenced_in_ai_goals) (ai_goal *goals, int type, char *name);
|
||||
char* (*ai_add_dock_name) (char *str);
|
||||
};
|
||||
|
||||
// Set new pointer to override ai_goal* function calls
|
||||
// possibly copying the old function calls first
|
||||
|
||||
extern struct aigoal_call_table *aigoal_table;
|
||||
|
||||
extern struct aigoal_call_table AIGoalDefaultTable;
|
||||
|
||||
#endif
|
||||
@@ -10,6 +10,22 @@
|
||||
#ifndef _AIINTERNAL_H
|
||||
#define _AIINTERNAL_H
|
||||
|
||||
#include "weapon/weapon.h"
|
||||
#include "weapon/swarm.h"
|
||||
#include "object/objectdock.h"
|
||||
|
||||
typedef struct eval_nearest_objnum {
|
||||
int objnum;
|
||||
object *trial_objp;
|
||||
int enemy_team_mask;
|
||||
int enemy_wing;
|
||||
float range;
|
||||
int max_attackers;
|
||||
int nearest_objnum;
|
||||
float nearest_dist;
|
||||
int check_danger_weapon_objnum;
|
||||
} eval_nearest_objnum;
|
||||
|
||||
//Returns true if the specified object is a stealth ship, false if not
|
||||
bool is_object_stealth_ship(object* objp);
|
||||
|
||||
@@ -28,4 +44,243 @@ int check_ok_to_fire(int objnum, int target_objnum, weapon_info *wip);
|
||||
//Does all the stuff needed to aim and fire a turret.
|
||||
void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum);
|
||||
|
||||
// AI Turret Table Wrapper
|
||||
|
||||
struct eval_enemy_obj_struct;
|
||||
|
||||
struct aiturret_call_table
|
||||
{
|
||||
int (*turret_select_best_weapon) (ship_subsys *turret, object *target);
|
||||
int (*valid_turret_enemy) (object *objp, object *turret_parent);
|
||||
void (*evaluate_obj_as_target) (object *objp, eval_enemy_obj_struct *eeo);
|
||||
int (*get_nearest_turret_objnum) (int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag);
|
||||
int (*find_turret_enemy) (ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov);
|
||||
int (*turret_should_pick_new_target) (ship_subsys *turret);
|
||||
void (*turret_set_next_fire_timestamp) (int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip);
|
||||
int (*turret_should_fire_aspect) (ship_subsys *turret, float dot, weapon_info *wip);
|
||||
bool (*turret_fire_weapon) (int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos, float flak_range_override);
|
||||
void (*turret_swarm_fire_from_turret) (turret_swarm_info *tsi);
|
||||
void (*ai_fire_from_turret) (ship *shipp, ship_subsys *ss, int parent_objnum);
|
||||
};
|
||||
|
||||
// Set new pointer to override ai_goal* function calls
|
||||
// possibly copying the old function calls first
|
||||
|
||||
extern struct aiturret_call_table *aiturret_table;
|
||||
|
||||
extern struct aiturret_call_table AITurretDefaultTable;
|
||||
|
||||
// AI Code Table Wrapper
|
||||
struct aicode_call_table
|
||||
{
|
||||
void (*ai_set_rearm_status) (int team, int time);
|
||||
int (*ai_good_time_to_rearm) (object *objp);
|
||||
void (*ai_good_secondary_time) (int team, int weapon_index, int max_fire_count, char *shipname);
|
||||
int (*is_preferred_weapon) (int weapon_num, object *firer_objp, object *target_objp);
|
||||
void (*ai_init_secondary_info) ();
|
||||
void (*free_ai_stuff) ();
|
||||
void (*parse_ai_class) ();
|
||||
void (*reset_ai_class_names) ();
|
||||
void (*parse_aitbl) ();
|
||||
void (*ai_init) ();
|
||||
void (*ai_level_init) ();
|
||||
int (*ai_is_stealth_visible) (object *viewer_objp, object *stealth_objp);
|
||||
void (*update_ai_stealth_info_with_error) (ai_info *aip);
|
||||
void (*ai_update_danger_weapon) (int attacked_objnum, int weapon_objnum);
|
||||
void (*ai_turn_towards_vector) (vec3d *dest, object *objp, float frametime, float turn_time, vec3d *slide_vec, vec3d *rel_pos, float bank_override, int flags, vec3d *rvec, int sexp_flags);
|
||||
void (*init_ship_info) ();
|
||||
int (*set_target_objnum) (ai_info *aip, int objnum);
|
||||
ship_subsys* (*set_targeted_subsys) (ai_info *aip, ship_subsys *new_subsys, int parent_objnum);
|
||||
void (*ai_object_init) (object *obj, int ai_index);
|
||||
void (*adjust_accel_for_docking) (ai_info *aip);
|
||||
void (*accelerate_ship) (ai_info *aip, float accel);
|
||||
void (*change_acceleration) (ai_info *aip, float delta_accel);
|
||||
void (*set_accel_for_target_speed) (object *objp, float tspeed);
|
||||
void (*turn_towards_point) (object *objp, vec3d *point, vec3d *slide_vec, float bank_override);
|
||||
void (*turn_away_from_point) (object *objp, vec3d *point, float bank_override);
|
||||
float (*turn_towards_tangent) (object *objp, vec3d *point, float radius);
|
||||
float (*turn_toward_tangent_with_axis) (object *objp, object *center_objp, float radius);
|
||||
int (*object_is_targetable) (object *target, ship *viewer);
|
||||
int (*num_enemies_attacking) (int objnum);
|
||||
float (*get_wing_lowest_max_speed) (object *objp);
|
||||
int (*is_ignore_object_sub) (int *ignore_objnum, int *ignore_signature, int objnum);
|
||||
int (*find_ignore_new_object_index) (ai_info *aip, int objnum);
|
||||
int (*is_ignore_object) (ai_info *aip, int objnum, int just_the_original=0);
|
||||
int (*get_nearest_bbox_point) (object *ship_obj, vec3d *start, vec3d *box_pt);
|
||||
void (*evaluate_object_as_nearest_objnum) (eval_nearest_objnum *eno);
|
||||
int (*get_nearest_objnum) (int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers);
|
||||
int (*find_nearby_threat) (int objnum, int enemy_team_mask, float range, int *count);
|
||||
int (*num_turrets_attacking) (object *turret_parent, int target_objnum);
|
||||
int (*get_enemy_timestamp) ();
|
||||
int (*find_enemy) (int objnum, float range, int max_attackers);
|
||||
void (*ai_set_goal_maybe_abort_dock) (object *objp, ai_info *aip);
|
||||
void (*force_avoid_player_check) (object *objp, ai_info *aip);
|
||||
void (*ai_attack_object) (object *attacker, object *attacked, int priority, ship_subsys *ssp);
|
||||
void (*ai_attack_wing) (object *attacker, int wingnum, int priority);
|
||||
void (*ai_evade_object) (object *evader, object *evaded, int priority);
|
||||
int (*compact_ignore_new_objects) (ai_info *aip, int force=0);
|
||||
void (*ai_ignore_object) (object *ignorer, object *ignored, int priority, int ignore_new);
|
||||
void (*ai_ignore_wing) (object *ignorer, int wingnum, int priority);
|
||||
void (*create_model_path) (object *pl_objp, object *mobjp, int path_num, int subsys_path);
|
||||
void (*create_model_exit_path) (object *pl_objp, object *mobjp, int path_num, int count);
|
||||
void (*ai_find_path) (object *pl_objp, int objnum, int path_num, int exit_flag, int subsys_path);
|
||||
int (*maybe_avoid_player) (object *objp, vec3d *goal_pos);
|
||||
void (*ai_stay_still) (object *still_objp, vec3d *view_pos);
|
||||
void (*ai_do_objects_docked_stuff) (object *docker, int docker_point, object *dockee, int dockee_point);
|
||||
void (*ai_do_objects_undocked_stuff) (object *docker, object *dockee);
|
||||
void (*ai_dock_with_object) (object *docker, int docker_index, object *dockee, int dockee_index, int priority, int dock_type);
|
||||
void (*ai_start_fly_to_ship) (object *objp, int shipnum);
|
||||
void (*ai_start_waypoints) (object *objp, int waypoint_list_index, int wp_flags);
|
||||
void (*ai_do_stay_near) (object *objp, object *other_objp, float dist);
|
||||
void (*ai_do_safety) (object *objp);
|
||||
void (*ai_form_on_wing) (object *objp, object *goal_objp);
|
||||
int (*ai_formation_object_get_slotnum) (int objnum, object *objp);
|
||||
float (*compute_time_to_enemy) (float dist_to_enemy, object *pobjp, object *eobjp);
|
||||
void (*ai_set_positions) (object *pl_objp, object *en_objp, ai_info *aip, vec3d *player_pos, vec3d *enemy_pos);
|
||||
float (*maybe_recreate_path) (object *objp, ai_info *aip, int force_recreate_flag, int override_hash=0);
|
||||
void (*set_accel_for_docking) (object *objp, ai_info *aip, float dot, float dot_to_next, float dist_to_next, float dist_to_goal, ship_info *sip);
|
||||
float (*ai_path) ();
|
||||
void (*ai_safety_pick_spot) (object *objp);
|
||||
float (*ai_safety_goto_spot) (object *objp);
|
||||
void (*ai_safety_circle_spot) (object *objp);
|
||||
void (*ai_safety) ();
|
||||
void (*ai_fly_to_ship) ();
|
||||
void (*ai_waypoints) ();
|
||||
void (*avoid_ship) ();
|
||||
int (*maybe_resume_previous_mode) (object *objp, ai_info *aip);
|
||||
int (*ai_maybe_fire_afterburner) (object *objp, ai_info *aip);
|
||||
void (*maybe_afterburner_after_ship_hit) (object *objp, ai_info *aip, object *en_objp);
|
||||
int (*is_instructor) (object *objp);
|
||||
void (*evade_weapon) ();
|
||||
void (*slide_face_ship) ();
|
||||
void (*evade_ship) ();
|
||||
void (*ai_evade) ();
|
||||
int (*ai_select_primary_weapon_OLD) (object *objp, object *other_objp, int flags);
|
||||
int (*ai_select_primary_weapon) (object *objp, object *other_objp, int flags);
|
||||
void (*set_primary_weapon_linkage) (object *objp);
|
||||
int (*ai_fire_primary_weapon) (object *objp);
|
||||
void (*ai_select_secondary_weapon) (object *objp, ship_weapon *swp, int priority1=-1, int priority2=-1);
|
||||
void (*ai_maybe_announce_shockwave_weapon) (object *firing_objp, int weapon_index);
|
||||
int (*check_ok_to_fire) (int objnum, int target_objnum, weapon_info *wip);
|
||||
int (*ai_fire_secondary_weapon) (object *objp, int priority1, int priority2);
|
||||
void (*set_predicted_enemy_pos_turret) (vec3d *predicted_enemy_pos, vec3d *gun_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, float weapon_speed, float time_enemy_in_range);
|
||||
void (*set_predicted_enemy_pos) (vec3d *predicted_enemy_pos, object *pobjp, object *eobjp, ai_info *aip);
|
||||
void (*ai_chase_ct) ();
|
||||
void (*ai_chase_eb) (ai_info *aip, ship_info *sip, vec3d *predicted_enemy_pos, float dist_to_enemy);
|
||||
float (*ai_endangered_time) (object *ship_objp, object *weapon_objp);
|
||||
float (*ai_endangered_by_weapon) (ai_info *aip);
|
||||
int (*ai_near_full_strength) (object *objp);
|
||||
void (*attack_set_accel) (ai_info *aip, float dist_to_enemy, float dot_to_enemy, float dot_from_enemy);
|
||||
void (*get_behind_ship) (ai_info *aip, ship_info *sip, float dist_to_enemy);
|
||||
int (*avoid_player) (object *objp, vec3d *goal_pos);
|
||||
int (*maybe_avoid_big_ship) (object *objp, object *ignore_objp, ai_info *aip, vec3d *goal_point, float delta_time);
|
||||
void (*ai_stealth_find) ();
|
||||
void (*ai_stealth_sweep) ();
|
||||
void (*ai_chase_attack) (ai_info *aip, ship_info *sip, vec3d *predicted_enemy_pos, float dist_to_enemy, int modelnum);
|
||||
void (*ai_chase_es) (ai_info *aip, ship_info *sip);
|
||||
void (*ai_chase_ga) (ai_info *aip, ship_info *sip);
|
||||
int (*ai_set_attack_subsystem) (object *objp, int subnum);
|
||||
void (*ai_set_guard_vec) (object *objp, object *guard_objp);
|
||||
void (*ai_set_guard_wing) (object *objp, int wingnum);
|
||||
void (*ai_set_evade_object) (object *objp, object *other_objp);
|
||||
void (*ai_set_guard_object) (object *objp, object *other_objp);
|
||||
void (*update_aspect_lock_information) (ai_info *aip, vec3d *vec_to_enemy, float dist_to_enemy, float enemy_radius);
|
||||
void (*ai_chase_fly_away) (object *objp, ai_info *aip);
|
||||
int (*has_preferred_secondary) (object *objp, object *en_objp, ship_weapon *swp);
|
||||
void (*ai_choose_secondary_weapon) (object *objp, ai_info *aip, object *en_objp);
|
||||
float (*set_secondary_fire_delay) (ai_info *aip, ship *shipp, weapon_info *swip);
|
||||
void (*ai_chase_big_approach_set_goal) (vec3d *goal_pos, object *attack_objp, object *target_objp, float *accel);
|
||||
void (*ai_chase_big_circle_set_goal) (vec3d *goal_pos, object *attack_objp, object *target_objp, float *accel);
|
||||
void (*ai_chase_big_get_separations) (object *attack_objp, object *target_objp, vec3d *horz_vec_to_target, float *desired_separation, float *cur_separation);
|
||||
void (*ai_chase_big_parallel_set_goal) (vec3d *goal_pos, object *attack_objp, object *target_objp, float *accel);
|
||||
void (*ai_cruiser_chase_set_goal_pos) (vec3d *goal_pos, object *pl_objp, object *en_objp);
|
||||
int (*maybe_hack_cruiser_chase_abort) ();
|
||||
void (*ai_cruiser_chase) ();
|
||||
void (*ai_chase) ();
|
||||
int (*num_ships_attacking) (int target_objnum);
|
||||
void (*remove_farthest_attacker) (int objnum);
|
||||
int (*ai_maybe_limit_attackers) (int attacked_objnum);
|
||||
void (*guard_object_was_hit) (object *guard_objp, object *hitter_objp);
|
||||
void (*maybe_update_guard_object) (object *hit_objp, object *hitter_objp);
|
||||
int (*ai_guard_find_nearby_bomb) (object *guarding_objp, object *guarded_objp);
|
||||
void (*ai_guard_find_nearby_ship) (object *guarding_objp, object *guarded_objp);
|
||||
void (*ai_guard_find_nearby_asteroid) (object *guarding_objp, object *guarded_objp);
|
||||
void (*ai_guard_find_nearby_object) ();
|
||||
void (*ai_big_guard) ();
|
||||
void (*ai_guard) ();
|
||||
void (*ai_do_objects_repairing_stuff) (object *repaired_objp, object *repair_objp, int how);
|
||||
void (*ai_cleanup_dock_mode_subjective) (object *objp);
|
||||
void (*ai_cleanup_dock_mode_objective) (object *objp);
|
||||
void (*ai_cleanup_rearm_mode) (object *objp);
|
||||
void (*ai_still) ();
|
||||
void (*ai_stay_near) ();
|
||||
int (*maybe_dock_obstructed) (object *cur_objp, object *goal_objp, int big_only_flag);
|
||||
void (*ai_dock) ();
|
||||
void (*process_subobjects) (int objnum);
|
||||
void (*ai_fly_in_formation) (int wingnum);
|
||||
void (*ai_disband_formation) (int wingnum);
|
||||
int (*formation_is_leader_chaotic) (object *objp);
|
||||
void (*ai_most_massive_object_of_its_wing_of_all_docked_objects_helper) (object *objp, dock_function_info *infop);
|
||||
int (*ai_formation) ();
|
||||
void (*ai_do_repair_frame) (object *objp, ai_info *aip, float frametime);
|
||||
void (*call_doa) (object *child, object *parent);
|
||||
void (*ai_maybe_launch_cmeasure) (object *objp, ai_info *aip);
|
||||
void (*ai_preprocess_ignore_objnum) (object *objp, ai_info *aip);
|
||||
void (*ai_chase_circle) (object *objp);
|
||||
void (*ai_transfer_shield) (object *objp, int quadrant_num);
|
||||
void (*ai_balance_shield) (object *objp);
|
||||
void (*ai_manage_shield) (object *objp, ai_info *aip);
|
||||
void (*ai_maybe_evade_locked_missile) (object *objp, ai_info *aip);
|
||||
void (*maybe_evade_dumbfire_weapon) (ai_info *aip);
|
||||
int (*ai_acquire_emerge_path) (object *pl_objp, int parent_objnum, int allowed_path_mask, vec3d *pos, vec3d *fvec);
|
||||
void (*ai_emerge_bay_path_cleanup) (ai_info *aip);
|
||||
void (*ai_bay_emerge) ();
|
||||
int (*ai_find_closest_depart_path) (ai_info *aip, polymodel *pm, int allowed_path_mask);
|
||||
int (*ai_acquire_depart_path) (object *pl_objp, int parent_objnum, int allowed_path_mask);
|
||||
void (*ai_bay_depart) ();
|
||||
void (*ai_sentrygun) ();
|
||||
void (*ai_execute_behavior) (ai_info *aip);
|
||||
int (*maybe_request_support) (object *objp);
|
||||
void (*ai_set_mode_warp_out) (object *objp, ai_info *aip);
|
||||
void (*ai_maybe_depart) (object *objp);
|
||||
void (*ai_warp_out) (object *objp);
|
||||
void (*ai_announce_ship_dying) (object *dying_objp);
|
||||
int (*aas_1) (object *objp, ai_info *aip, vec3d *safe_pos);
|
||||
int (*ai_avoid_shockwave) (object *objp, ai_info *aip);
|
||||
int (*ai_await_repair_frame) (object *objp, ai_info *aip);
|
||||
void (*ai_maybe_self_destruct) (object *objp, ai_info *aip);
|
||||
int (*ai_need_new_target) (object *pl_objp, int target_objnum);
|
||||
int (*maybe_big_ship_collide_recover_frame) (object *objp, ai_info *aip);
|
||||
void (*validate_mode_submode) (ai_info *aip);
|
||||
void (*ai_frame) (int objnum);
|
||||
void (*ai_process) (object *obj, int ai_index, float frametime);
|
||||
void (*init_ai_object) (int objnum);
|
||||
void (*init_ai_objects) ();
|
||||
void (*init_ai_system) ();
|
||||
void (*ai_set_default_behavior) (object *obj, int classnum);
|
||||
void (*ai_do_default_behavior) (object *obj);
|
||||
void (*process_friendly_hit_message) (int message, object *objp);
|
||||
void (*maybe_process_friendly_hit) (object *objp_hitter, object *objp_hit, object *objp_weapon);
|
||||
void (*maybe_set_dynamic_chase) (ai_info *aip, int hitter_objnum);
|
||||
void (*big_ship_collide_recover_start) (object *objp, object *big_objp, vec3d *collide_pos, vec3d *collision_normal);
|
||||
void (*ai_update_lethality) (object *ship_obj, object *other_obj, float damage);
|
||||
void (*ai_ship_hit) (object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_quadrant, vec3d *hit_normal);
|
||||
void (*ai_ship_destroy) (int shipnum, int method);
|
||||
void (*ai_deathroll_start) (object *dying_objp);
|
||||
int (*ai_abort_rearm_request) (object *requester_objp);
|
||||
void (*ai_add_rearm_goal) (object *requester_objp, object *support_objp);
|
||||
int (*ai_issue_rearm_request) (object *requester_objp);
|
||||
void (*ai_rearm_repair) (object *objp, int docker_index, object *goal_objp, int dockee_index, int priority);
|
||||
void (*cheat_fire_synaptic) (object *objp, ship *shipp, ai_info *aip);
|
||||
void (*maybe_cheat_fire_synaptic) (object *objp, ai_info *aip);
|
||||
};
|
||||
|
||||
|
||||
// Set new pointer to override ai_code* function calls
|
||||
// possibly copying the old function calls first
|
||||
|
||||
extern struct aicode_call_table *aicode_table;
|
||||
|
||||
extern struct aicode_call_table AICodeDefaultTable;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,185 @@
|
||||
/**
|
||||
* @file aimodular.cpp
|
||||
* @brief Modular loading of new AI code based on name in AI Profile.
|
||||
*
|
||||
* The ai_module_init function should be called by ai_init.
|
||||
*
|
||||
* @author Fabian Franz <[email protected]>
|
||||
*
|
||||
*/
|
||||
#include "ai/aibig.h"
|
||||
#include "ai/aigoals.h"
|
||||
#include "ai/aiinternal.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <Windows.h>
|
||||
/** @brief Wrapper for the dlopen functions for Windows */
|
||||
#define dlopen(x,y) ((x==NULL)?GetModuleHandle(x):LoadLibrary(x))
|
||||
#define dlsym GetProcAddress
|
||||
#define dlclose FreeLibrary
|
||||
static HINSTANCE handle = NULL; /**< @brief Handle for the loaded library */
|
||||
|
||||
#else
|
||||
|
||||
#include <dlfcn.h>
|
||||
static void* handle = NULL; /**< @brief Handle for the loaded library */
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/** @brief ai_module_init_function prototype */
|
||||
typedef void (*ai_module_init_function)(void);
|
||||
|
||||
void ai_module_dlclose(void);
|
||||
|
||||
/**
|
||||
* @brief Fallback function to load new AI from same process image.
|
||||
*
|
||||
* This function is used if no dynamic library with the name can be found
|
||||
* or it does not contain the correct symbol.
|
||||
*
|
||||
* @param func_name The symbol to look for in handle
|
||||
* @return Returns 0 on success and -1,-2 on errors
|
||||
*
|
||||
*/
|
||||
int ai_module_dlopen_process(char* func_name)
|
||||
{
|
||||
ai_module_init_function ai_module_init_func;
|
||||
|
||||
// Maybe close handle first
|
||||
ai_module_dlclose();
|
||||
|
||||
handle = dlopen(NULL, RTLD_NOW);
|
||||
|
||||
if (handle == NULL)
|
||||
return -1;
|
||||
|
||||
ai_module_init_func=(ai_module_init_function)dlsym(handle, func_name);
|
||||
|
||||
#ifdef _WIN32
|
||||
// Under WIN32 GetModuleHandle is not
|
||||
// incrementing the reference counter
|
||||
// so we need to "free" the handle directly
|
||||
|
||||
handle=NULL;
|
||||
#endif
|
||||
|
||||
if (ai_module_init_func == NULL)
|
||||
return -2;
|
||||
|
||||
ai_module_init_func();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Loads new AI from dynamic library
|
||||
*
|
||||
* This function looks for dllname.dll or dllname.so
|
||||
* tries to load it into memory and if it finds the
|
||||
* dllname_ai_module_init function it starts it.
|
||||
*
|
||||
* If it does not find the library or symbol it falls
|
||||
* back to ai_module_dlopen_process.
|
||||
*
|
||||
* @param dllname The name of the library to load
|
||||
* @return Returns 0 on success and -1,-2 on errors
|
||||
*
|
||||
*/
|
||||
|
||||
int ai_module_dlopen(char* dllname)
|
||||
{
|
||||
char buf[PATH_MAX+1];
|
||||
char init_func_name[PATH_MAX+1];
|
||||
ai_module_init_function ai_module_init_func;
|
||||
|
||||
#ifdef _WIN32
|
||||
snprintf(buf, PATH_MAX, "%s.dll", dllname);
|
||||
#else
|
||||
snprintf(buf, PATH_MAX, "%s.so", dllname);
|
||||
#endif
|
||||
snprintf(init_func_name, PATH_MAX, "%s_ai_module_init", dllname);
|
||||
|
||||
handle = dlopen(buf, RTLD_NOW);
|
||||
|
||||
if (handle == NULL)
|
||||
return ai_module_dlopen_process(init_func_name);
|
||||
|
||||
ai_module_init_func=(ai_module_init_function)dlsym(handle, init_func_name);
|
||||
|
||||
if (ai_module_init_func == NULL)
|
||||
return ai_module_dlopen_process(init_func_name);
|
||||
|
||||
ai_module_init_func();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Closes the library handle
|
||||
*
|
||||
* This function closes the library handle.
|
||||
*
|
||||
*/
|
||||
void ai_module_dlclose(void)
|
||||
{
|
||||
if (handle != NULL)
|
||||
{
|
||||
dlclose(handle);
|
||||
handle=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inits or resets the AI code tables
|
||||
*
|
||||
* This function first resets the AI code tables,
|
||||
* then closes any open libraries from before.
|
||||
*
|
||||
* Then it ooks if the ai_module is not "retail"
|
||||
* and if that is the case it loads a library with this name.
|
||||
*
|
||||
*/
|
||||
void ai_module_init(void)
|
||||
{
|
||||
// First Reset values
|
||||
aibig_table = &AIBigDefaultTable;
|
||||
aicode_table = &AICodeDefaultTable;
|
||||
aigoal_table = &AIGoalDefaultTable;
|
||||
aiturret_table = &AITurretDefaultTable;
|
||||
|
||||
ai_module_dlclose();
|
||||
|
||||
if (The_mission.ai_profile == NULL)
|
||||
return;
|
||||
|
||||
if (strncmp(The_mission.ai_profile->ai_module, "retail", 6) != 0)
|
||||
{
|
||||
if (ai_module_dlopen(The_mission.ai_profile->ai_module) != 0)
|
||||
{
|
||||
char err[1024];
|
||||
|
||||
snprintf(err, sizeof(err), "AI_module_init(%s) failed: %s\n", The_mission.ai_profile->ai_module, dlerror());
|
||||
|
||||
mprintf(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void newai_ai_module_init(void);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Dummy function
|
||||
*
|
||||
* This dummy functions calls all AI implementations
|
||||
* that should be statically included.
|
||||
*
|
||||
*/
|
||||
void ai_module_dummy()
|
||||
{
|
||||
newai_ai_module_init();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef _AIMODULAR_H
|
||||
#define _AIMODULAR_H
|
||||
|
||||
void ai_module_init(void);
|
||||
|
||||
#endif
|
||||
+89
-12
@@ -233,6 +233,69 @@ typedef struct eval_enemy_obj_struct {
|
||||
int nearest_objnum;
|
||||
} eval_enemy_obj_struct;
|
||||
|
||||
// FF 17-06-07
|
||||
// AI Turret Table Wrapper
|
||||
|
||||
struct aiturret_call_table *aiturret_table = &AITurretDefaultTable;
|
||||
|
||||
int turret_select_best_weapon (ship_subsys *turret, object *target)
|
||||
{
|
||||
return aiturret_table->turret_select_best_weapon(turret, target);
|
||||
}
|
||||
|
||||
int valid_turret_enemy (object *objp, object *turret_parent)
|
||||
{
|
||||
return aiturret_table->valid_turret_enemy(objp, turret_parent);
|
||||
}
|
||||
|
||||
void evaluate_obj_as_target (object *objp, eval_enemy_obj_struct *eeo)
|
||||
{
|
||||
aiturret_table->evaluate_obj_as_target(objp, eeo);
|
||||
}
|
||||
|
||||
int get_nearest_turret_objnum (int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag)
|
||||
{
|
||||
return aiturret_table->get_nearest_turret_objnum(turret_parent_objnum, turret_subsys, enemy_team_mask, tpos, tvec, current_enemy, big_only_flag, small_only_flag, tagged_only_flag, beam_flag);
|
||||
}
|
||||
|
||||
int find_turret_enemy (ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov)
|
||||
{
|
||||
return aiturret_table->find_turret_enemy(turret_subsys, objnum, tpos, tvec, current_enemy, fov);
|
||||
}
|
||||
|
||||
int turret_should_pick_new_target (ship_subsys *turret)
|
||||
{
|
||||
return aiturret_table->turret_should_pick_new_target(turret);
|
||||
}
|
||||
|
||||
void turret_set_next_fire_timestamp (int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip)
|
||||
{
|
||||
aiturret_table->turret_set_next_fire_timestamp(weapon_num, wip, turret, aip);
|
||||
}
|
||||
|
||||
int turret_should_fire_aspect (ship_subsys *turret, float dot, weapon_info *wip)
|
||||
{
|
||||
return aiturret_table->turret_should_fire_aspect(turret, dot, wip);
|
||||
}
|
||||
|
||||
bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos = NULL, float flak_range_override = 100.0f)
|
||||
{
|
||||
return aiturret_table->turret_fire_weapon(weapon_num, turret, parent_objnum, turret_pos, turret_fvec, predicted_pos, flak_range_override);
|
||||
}
|
||||
|
||||
void turret_swarm_fire_from_turret (turret_swarm_info *tsi)
|
||||
{
|
||||
aiturret_table->turret_swarm_fire_from_turret(tsi);
|
||||
}
|
||||
|
||||
void ai_fire_from_turret (ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
{
|
||||
aiturret_table->ai_fire_from_turret(shipp, ss, parent_objnum);
|
||||
}
|
||||
|
||||
|
||||
// AI Turret default implementation
|
||||
|
||||
// return 1 if objp is in fov of the specified turret, tp. Otherwise return 0.
|
||||
// dist = distance from turret to center point of object
|
||||
int object_in_turret_fov(object *objp, model_subsystem *tp, vec3d *tvec, vec3d *tpos, float dist)
|
||||
@@ -274,7 +337,7 @@ int bomb_headed_towards_ship(object *bomb_objp, object *ship_objp)
|
||||
//Note that all non-negative return values are expressed in
|
||||
//what I like to call "widx"s.
|
||||
//Returns -1 if unable to find a weapon for the target at all.
|
||||
int turret_select_best_weapon(ship_subsys *turret, object *target)
|
||||
int aiturret_turret_select_best_weapon(ship_subsys *turret, object *target)
|
||||
{
|
||||
//TODO: Fill this out with extraodinary gun-picking algorithms
|
||||
if(turret->weapons.num_primary_banks > 0)
|
||||
@@ -441,7 +504,7 @@ float longest_turret_weapon_range(ship_weapon *swp)
|
||||
// input: objp => object that turret is considering as an enemy
|
||||
// turret_parent => object index for ship that turret sits on
|
||||
// turret => turret pointer
|
||||
int valid_turret_enemy(object *objp, object *turret_parent)
|
||||
int aiturret_valid_turret_enemy(object *objp, object *turret_parent)
|
||||
{
|
||||
if ( objp == turret_parent ) {
|
||||
return 0;
|
||||
@@ -505,7 +568,7 @@ int valid_turret_enemy(object *objp, object *turret_parent)
|
||||
}
|
||||
|
||||
extern int Player_attacking_enabled;
|
||||
void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
|
||||
void aiturret_evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
|
||||
{
|
||||
object *turret_parent_obj = &Objects[eeo->turret_parent_objnum];
|
||||
ship *shipp;
|
||||
@@ -716,7 +779,7 @@ int is_target_beam_valid(ship_weapon *swp, object *objp)
|
||||
// tpos => position of turret (world coords)
|
||||
// tvec => forward vector of turret (world coords)
|
||||
// current_enemy => objnum of current turret target
|
||||
int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag)
|
||||
int aiturret_get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag)
|
||||
{
|
||||
//float weapon_travel_dist;
|
||||
int weapon_system_ok;
|
||||
@@ -857,7 +920,7 @@ DCF_BOOL(use_parent_target, Use_parent_target)
|
||||
// tpos => position of turret (world coords)
|
||||
// tvec => forward vector of turret (world coords)
|
||||
// current_enemy => objnum of current turret target
|
||||
int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov)
|
||||
int aiturret_find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov)
|
||||
{
|
||||
int enemy_team_mask, enemy_objnum;
|
||||
model_subsystem *tp;
|
||||
@@ -1201,7 +1264,7 @@ ship_subsys *aifft_find_turret_subsys(object *objp, ship_subsys *ssp, object *en
|
||||
}
|
||||
|
||||
// return !0 if the specified target should scan for a new target, otherwise return 0
|
||||
int turret_should_pick_new_target(ship_subsys *turret)
|
||||
int aiturret_turret_should_pick_new_target(ship_subsys *turret)
|
||||
{
|
||||
// int target_type;
|
||||
|
||||
@@ -1224,7 +1287,7 @@ int turret_should_pick_new_target(ship_subsys *turret)
|
||||
}
|
||||
|
||||
// Set the next fire timestamp for a turret, based on weapon type and ai class
|
||||
void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip)
|
||||
void aiturret_turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip)
|
||||
{
|
||||
Assert(weapon_num < MAX_SHIP_WEAPONS);
|
||||
float wait = wip->fire_wait * 1000.0f;
|
||||
@@ -1280,7 +1343,7 @@ void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsy
|
||||
}
|
||||
|
||||
// Decide if a turret should launch an aspect seeking missile
|
||||
int turret_should_fire_aspect(ship_subsys *turret, float dot, weapon_info *wip)
|
||||
int aiturret_turret_should_fire_aspect(ship_subsys *turret, float dot, weapon_info *wip)
|
||||
{
|
||||
if ( (dot > AICODE_TURRET_DUMBFIRE_ANGLE) && (turret->turret_time_enemy_in_range >= MIN(wip->min_lock_time,AICODE_TURRET_MAX_TIME_IN_RANGE)) ) {
|
||||
return 1;
|
||||
@@ -1304,7 +1367,7 @@ void turret_update_enemy_in_range(ship_subsys *turret, float seconds)
|
||||
}
|
||||
|
||||
// Fire a weapon from a turret
|
||||
bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos = NULL, float flak_range_override = 100.0f)
|
||||
bool aiturret_turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos = NULL, float flak_range_override = 100.0f)
|
||||
{
|
||||
matrix turret_orient;
|
||||
int weapon_objnum;
|
||||
@@ -1439,8 +1502,8 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
return true;
|
||||
}
|
||||
|
||||
//void turret_swarm_fire_from_turret(ship_subsys *turret, int parent_objnum, int target_objnum, ship_subsys *target_subsys)
|
||||
void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
|
||||
//void aiturret_turret_swarm_fire_from_turret(ship_subsys *turret, int parent_objnum, int target_objnum, ship_subsys *target_subsys)
|
||||
void aiturret_turret_swarm_fire_from_turret(turret_swarm_info *tsi)
|
||||
{
|
||||
int weapon_objnum;
|
||||
matrix turret_orient;
|
||||
@@ -1504,7 +1567,7 @@ int Num_find_turret_enemy = 0;
|
||||
int Num_turrets_fired = 0;
|
||||
// Given a turret tp and its parent parent_objnum, fire from the turret at its enemy.
|
||||
extern int Nebula_sec_range;
|
||||
void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
void aiturret_ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
{
|
||||
float weapon_firing_range;
|
||||
|
||||
@@ -1975,3 +2038,17 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
ss->turret_time_enemy_in_range = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
struct aiturret_call_table AITurretDefaultTable = {
|
||||
aiturret_turret_select_best_weapon,
|
||||
aiturret_valid_turret_enemy,
|
||||
aiturret_evaluate_obj_as_target,
|
||||
aiturret_get_nearest_turret_objnum,
|
||||
aiturret_find_turret_enemy,
|
||||
aiturret_turret_should_pick_new_target,
|
||||
aiturret_turret_set_next_fire_timestamp,
|
||||
aiturret_turret_should_fire_aspect,
|
||||
aiturret_turret_fire_weapon,
|
||||
aiturret_turret_swarm_fire_from_turret,
|
||||
aiturret_ai_fire_from_turret
|
||||
};
|
||||
@@ -0,0 +1,122 @@
|
||||
#include "ai/aibig.h"
|
||||
#include "ai/aigoals.h"
|
||||
#include "ai/aiinternal.h"
|
||||
|
||||
struct aicode_call_table AICodeNewAITable;
|
||||
|
||||
#include "iff_defs/iff_defs.h"
|
||||
|
||||
#define DEPARTURE_HULL_PERCENT 0.3 // Departure if 15% to 30% hull strength left
|
||||
|
||||
void newai_ai_maybe_depart(object* objp_ship)
|
||||
{
|
||||
ship *shipp = &Ships[objp_ship->instance];
|
||||
|
||||
// Coward mode:
|
||||
//
|
||||
// Depart if:
|
||||
// * not player and
|
||||
// * same team as player and player not traitor and
|
||||
// * fighter or bomber
|
||||
// * hull multiplied with random value below critical
|
||||
|
||||
if (objp_ship->flags & OF_PLAYER_SHIP)
|
||||
return;
|
||||
|
||||
// make sure player is on their team and not a traitor
|
||||
if ((Player_ship->team != shipp->team) || (Player_ship->team == Iff_traitor))
|
||||
return;
|
||||
|
||||
if ((Ship_info[shipp->ship_info_index].flags & (SIF_FIGHTER|SIF_BOMBER)) == 0)
|
||||
return;
|
||||
|
||||
if (objp_ship->hull_strength*(frand()+1) < DEPARTURE_HULL_PERCENT * shipp->ship_max_hull_strength)
|
||||
mission_do_departure(objp_ship);
|
||||
}
|
||||
|
||||
// Object *objp_ship was hit by either weapon *objp_weapon or collided into by ship hit_objp at point *hitpos.
|
||||
void newai_aicode_ai_ship_hit (object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_quadrant, vec3d *hit_normal)
|
||||
{
|
||||
// Call the default implementation
|
||||
AICodeDefaultTable.ai_ship_hit(objp_ship, hit_objp, hitpos, shield_quadrant, hit_normal);
|
||||
|
||||
if (hit_objp->parent >= 0)
|
||||
{
|
||||
object *objp_hitter = &Objects[hit_objp->parent];
|
||||
|
||||
if ( objp_hitter->type == OBJ_SHIP )
|
||||
{
|
||||
ship *shipp_hitter = &Ships[objp_hitter->instance];
|
||||
ship *shipp_hit = &Ships[objp_ship->instance];
|
||||
|
||||
fprintf(stderr, "Ship %s hit %s\n", shipp_hitter->ship_name, shipp_hit->ship_name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
newai_ai_maybe_depart(objp_ship);
|
||||
}
|
||||
|
||||
|
||||
void newai_aicode_maybe_process_friendly_hit(object *objp_hitter, object *objp_hit, object *objp_weapon)
|
||||
{
|
||||
AICodeDefaultTable.maybe_process_friendly_hit(objp_hitter, objp_hit, objp_weapon);
|
||||
|
||||
if (obj_team(objp_hitter) == obj_team(objp_hit))
|
||||
{
|
||||
if ( objp_hitter->type != OBJ_SHIP )
|
||||
return;
|
||||
|
||||
ship *shipp_hitter = &Ships[objp_hitter->instance];
|
||||
ship *shipp_hit = &Ships[objp_hit->instance];
|
||||
|
||||
fprintf(stderr, "Ship %s friendly hit %s\n", shipp_hitter->ship_name, shipp_hit->ship_name);
|
||||
}
|
||||
}
|
||||
|
||||
int newai_aicode_ai_fire_primary_weapon(object *objp)
|
||||
{
|
||||
int fired = AICodeDefaultTable.ai_fire_primary_weapon(objp);
|
||||
|
||||
if (fired)
|
||||
{
|
||||
ship *shipp = &Ships[objp->instance];
|
||||
fprintf(stderr, "Ship %s fired primary weapon\n", shipp->ship_name);
|
||||
}
|
||||
}
|
||||
|
||||
void newai_aicode_init_ship_info()
|
||||
{
|
||||
static int called=0;
|
||||
if (called == 0)
|
||||
{
|
||||
fprintf(stderr, "Init ship info was called\n");
|
||||
called=1;
|
||||
}
|
||||
AICodeDefaultTable.init_ship_info();
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void newai_ai_module_init();
|
||||
}
|
||||
|
||||
void newai_ai_module_init()
|
||||
{
|
||||
|
||||
#ifdef PACKAGE_NAME
|
||||
fprintf(stderr, "ai_module_init() called\n");
|
||||
#else
|
||||
fprintf(stderr, "ai_module_init() modular called\n");
|
||||
#endif
|
||||
|
||||
// First make a copy
|
||||
memcpy(&AICodeNewAITable, &AICodeDefaultTable, sizeof(AICodeNewAITable));
|
||||
|
||||
// Now set up our overridden functions
|
||||
|
||||
aicode_table = &AICodeNewAITable;
|
||||
aicode_table->init_ship_info=newai_aicode_init_ship_info;
|
||||
aicode_table->ai_ship_hit=newai_aicode_ai_ship_hit;
|
||||
//aicode_table->ai_fire_primary_weapon=newai_aicode_ai_fire_primary_weapon;
|
||||
//aicode_table->maybe_process_friendly_hit=newai_aicode_maybe_process_friendly_hit;
|
||||
}
|
||||
@@ -217,6 +217,12 @@
|
||||
<File
|
||||
RelativePath="..\..\code\ai\ai_profiles.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\ai\aimodular.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\ai\aimodular.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\ai\AiBig.cpp">
|
||||
<FileConfiguration
|
||||
@@ -277,6 +283,9 @@
|
||||
<File
|
||||
RelativePath="..\..\code\ai\AiTurret.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\ai\newai\newai.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Anim"
|
||||
|
||||
@@ -236,6 +236,34 @@
|
||||
RelativePath="..\..\code\ai\ai_profiles.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\ai\aimodular.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
UndefinePreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
UndefinePreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\ai\aimodular.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\ai\AiBig.cpp"
|
||||
>
|
||||
@@ -351,6 +379,30 @@
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\ai\newai\newai.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
UndefinePreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
UndefinePreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Anim"
|
||||
|
||||
Reference in new issue
Block a user