27 #pragma optimize("", off)
28 #pragma auto_inline(off)
31 #define SCAN_FIGHTERS_INTERVAL 2000 // how often an AI fighter/bomber should scan for enemy fighter/bombers
35 #define ENTER_STRAFE_THREAT_DIST_SQUARED 360000 // use squared distance, instead of 600
37 #define MIN_DOT_TO_ATTACK_SUBSYS 0.7f
38 #define MIN_DOT_TO_ATTACK_MOVING_SUBSYS 0.97f
41 #define STRAFE_RETREAT_COLLIDE_TIME 2.0 // when anticipated collision time is less than this, begin retreat
42 #define STRAFE_RETREAT_COLLIDE_DIST 100 // when perpendicular distance to *surface* is less than this, begin retreat
43 #define STRAFE_RETREAT_BOX_DIST 300 // distance beyond the bounding box to retreat
44 #define STRAFE_MAX_UNHIT_TIME 20 // Maximum amount of time to stay in strafe mode if not hit
46 #define EVADE_BOX_BASE_DISTANCE 300 // standard distance to end evade submode
47 #define EVADE_BOX_MIN_DISTANCE 200 // minimun distance to end evade submode, after long time
49 #define ATTACK_STOP_DISTANCE 150 // when distance to target is less than this, put on brakes
51 #define ATTACK_COLLIDE_BASE_DIST 300 // absolute distance at which to begin checking for possible collision
52 #define ATTACK_COLLIDE_AVOID_DIST 60 // perpendicular distance to attack surface at which begin avoiding
53 #define ATTACK_COLLIDE_AVOID_TIME 1.0 // anticipated collision time at which to begin evade
54 #define ATTACK_COLLIDE_SLOW_DIST 150 // perpendicular distance to attack surface at which begin slowing down
55 #define ATTACK_COLLIDE_SLOW_TIME 1.5 // anticipated collision time at which to begin slowing down
57 #define GLIDE_STRAFE_DISTANCE 50.0f //Distance from the ship to pass when glide strafing
58 #define GLIDE_STRAFE_MIN_TIME 2 //Minimum amount of time to stay on one glide strafe approach vector
59 #define GLIDE_STRAFE_MAX_TIME 15 //Maximum amount of time for each glide strafe pass
81 vec3d result_point, best_point;
92 best_point = objp->
pos;
93 nearest_dist = weapon_travel_dist;
102 num_tries = 4 - num_tries;
111 for (q=0; q<4; q++) {
115 if (num_tries > octp->
nverts)
118 if (num_tries > octp->
nverts)
121 for (i=0; i<num_tries; i++) {
144 if (dist < nearest_dist) {
146 best_point = result_point;
147 *local_attack_point = rel_point;
149 if (dot > (1.0
f + fov)/2.0
f)
158 *attack_point = best_point;
181 mc.
p0 = attacker_objp_pos;
191 if (surface_normal) {
196 *attack_point = objp->
pos;
197 if (surface_normal) {
215 vec3d local_attack_point;
217 ai_bpap(objp, gpos, gvec, attack_point, &local_attack_point, fov, weapon_travel_dist, NULL, ssp);
233 vec3d local_attack_point;
235 switch (attacker_objp->
type) {
269 vec3d surface_normal;
270 ai_bpap(objp, &attacker_objp->
pos, &attacker_objp->
orient.
vec.fvec, attack_point, &local_attack_point, fov, 99999.9f, &surface_normal, NULL);
272 switch (attacker_objp->
type) {
299 vec3d player_pos, enemy_pos;
303 vec3d randvec, semi_enemy_pos;
369 float dot = 1.0f, min_dot;
380 int subsys_path_num, subsys_in_sight, checked_sight;
416 vec3d subsys_normal, subsys_to_eye;
417 if ( do_dot_check ) {
420 dot =
vm_vec_dot(&subsys_normal, &subsys_to_eye);
431 if ( (checked_sight && ((!subsys_in_sight) || (dot < min_dot)) ) ) {
437 if ( subsys_path_num >= 0 ) {
447 if ( checked_sight && subsys_in_sight && (dot > min_dot) ) {
468 if ( (checked_sight && subsys_in_sight) && (dot > min_dot) ) {
473 if ( path_done || ( dist < aip->path_goal_dist ) || in_view ) {
547 float dot_to_enemy, time_to_hit;
615 float weapon_travel_dist;
619 if ((po->
n_guns) && (start_bank != -1)) {
627 vec3d rvec_vec, *rvec = &rvec_vec;
629 if (dist_to_enemy > 500.0
f)
640 if (dist_to_enemy > (weapon_travel_dist-20)) {
663 if (dot_to_enemy < 0.0
f) {
665 }
else if (dot_to_enemy < 0.75
f) {
668 if (dist_to_enemy > weapon_travel_dist/2.0
f) {
671 accel = 1.0f - dot_to_enemy;
754 if (current_bank > -1) {
775 firing_range *= 0.8f;
780 if (dist_to_enemy < firing_range*1.0
f) {
853 float dist_to_enemy, dot_to_enemy;
854 vec3d player_pos, enemy_pos, vec_to_enemy;
858 vec3d predicted_enemy_pos;
942 if ((dot_to_enemy < 0.9
f) || (dist_to_enemy > 300.0
f)) {
945 if (dot_to_enemy > 0.0
f)
1007 float dist_normal_to_enemy;
1013 dist_normal_to_enemy = 0.3f * dist_to_enemy;
1023 dist_normal_to_enemy =
MAX(0.3
f*dist_to_enemy, dist_normal_to_enemy);
1027 float time_to_enemy;
1033 time_to_enemy = 100.0f;
1040 time_to_enemy = 100.0f;
1101 if (box_dist > 300) {
1169 vec3d player_pos, vec_to_enemy, predicted_enemy_pos;
1202 predicted_enemy_pos=*enemy_pos;
1226 *enemy_pos = predicted_enemy_pos;
1236 vec3d vec_to_target;
1239 float dist_to_target, dist_normal_to_target, time_to_target;
1247 dist_normal_to_target =
MAX(0.2
f*dist_to_target, dist_normal_to_target);
1292 float target_dist, target_dot, accel,
t;
1305 if (target_dist < 1200.0
f) {
1318 if ( t > 0.0
f && t < 1.5
f ) {
1355 if ( target_dist > 1200 || last_hit <
F1_0*6) {
1360 if ( attack_time > 15 ) {
1362 }
else if ( attack_time > 10 ) {
1364 }
else if ( attack_time > 8 ) {
1366 }
else if ( attack_time > 5 ) {
1393 vec3d target_pos, vec_to_goal, predicted_enemy_pos, norm_vel_vec;
1394 float target_dist, target_dot, target_ship_dist, dot_to_goal, flight_dot_to_enemy;
1395 object *target_objp;
1408 dot_to_goal =
vm_vec_dot(&vec_to_goal, &norm_vel_vec);
1409 flight_dot_to_enemy =
vm_vec_dot(&target_objp->
pos, &norm_vel_vec);
1423 vec3d targetToAttacker;
1453 if (flight_dot_to_enemy > 0.0
f) {
1474 if (dot_to_goal > 0.99
f) {
1509 float target_dist, target_dot;
1520 if ( mode_time >
fl2f(0.5)) {
1708 object *weapon_objp, *parent_objp;
1737 weapon_objp = &Objects[weapon_objnum];
1741 parent_objp = &Objects[weapon_objp->
parent];
1781 object *parent_objp;
1813 if ( !attack_turret_on_different_ship )
void mc_info_init(mc_info *mc)
float ai_glide_strafe_percent
#define AIF_ON_SUBSYS_PATH
int model_collide(mc_info *mc_info_obj)
int timestamp(int delta_ms)
float get_world_closest_box_point_with_delta(vec3d *closest_box_point, object *box_obj, vec3d *start_point, int *is_inside, float delta)
#define AIS_STRAFE_RETREAT1
model_subsystem * system_info
weapon Weapons[MAX_WEAPONS]
int primary_bank_weapons[MAX_SHIP_PRIMARY_BANKS]
void ai_big_switch_to_chase_mode(ai_info *aip)
#define MAX_SHIP_PRIMARY_BANKS
void model_find_world_point(vec3d *outpnt, vec3d *mpnt, int model_num, int submodel_num, const matrix *objorient, const vec3d *objpos)
void ai_big_strafe_attack()
float vm_vec_mag_quick(const vec3d *v)
int ai_maybe_fire_afterburner(object *objp, ai_info *aip)
void vm_vec_scale_add(vec3d *dest, const vec3d *src1, const vec3d *src2, float k)
#define MISSION_FLAG_FULLNEB
#define GLIDE_STRAFE_MIN_TIME
polymodel * model_get(int model_num)
weapon_info Weapon_info[MAX_WEAPON_TYPES]
float vm_vec_mag(const vec3d *v)
#define SCAN_FIGHTERS_INTERVAL
int ai_fire_primary_weapon(object *objp)
int path_subsystem_next_check
int pick_big_attack_point_timestamp
#define EVADE_BOX_BASE_DISTANCE
int next_secondary_fire_stamp[MAX_SHIP_SECONDARY_BANKS]
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)
#define STRAFE_RETREAT_BOX_DIST
fix afterburner_stop_time
int ai_big_maybe_follow_subsys_path(int do_dot_check=1)
int model_which_octant_distant_many(vec3d *pnt, int model_num, matrix *model_orient, vec3d *model_pos, polymodel **pm, int *octs)
vec3d turret_big_attack_point
#define EVADE_BOX_MIN_DISTANCE
int ship_stop_fire_primary(object *obj)
void ai_big_strafe_glide_attack()
void big_ship_collide_recover_start(object *objp, object *big_objp, vec3d *collide_pos, vec3d *collision_normal)
struct vec3d::@225::@227 xyz
int ship_subsystem_in_sight(object *objp, ship_subsys *subsys, vec3d *eye_pos, vec3d *subsys_pos, int do_facing_check, float *dot_out, vec3d *vec_out)
ai_info Ai_info[MAX_AI_INFO]
vec3d * vm_vec_rotate(vec3d *dest, const vec3d *src, const matrix *m)
#define Assertion(expr, msg,...)
#define MIN_DOT_TO_ATTACK_MOVING_SUBSYS
#define END_OF_LIST(head)
void ai_select_secondary_weapon(object *objp, ship_weapon *swp, int priority1=-1, int priority2=-1)
#define AI_GOAL_DISARM_SHIP
void accelerate_ship(ai_info *aip, float accel)
ship_subsys * targeted_subsys
float set_secondary_fire_delay(ai_info *aip, ship *shipp, weapon_info *swip, bool burst)
void vm_vec_scale_add2(vec3d *dest, const vec3d *src, float k)
int current_secondary_bank
float ai_endangered_by_weapon(ai_info *aip)
void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov)
float vm_vec_mag_squared(const vec3d *v)
#define ATTACK_COLLIDE_AVOID_DIST
pnode Path_points[MAX_PATH_POINTS]
float ai_random_sidethrust_percent
#define GLIDE_STRAFE_DISTANCE
void ai_big_strafe_avoid()
void ai_big_strafe_retreat1()
int turret_pick_big_attack_point_timestamp
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
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, ship_subsys *ss)
void afterburners_stop(object *objp, int key_released)
matrix * vm_vector_2_matrix(matrix *m, const vec3d *fvec, const vec3d *uvec, const vec3d *rvec)
void vm_vec_add2(vec3d *dest, const vec3d *src)
void turn_towards_point(object *objp, vec3d *point, vec3d *slide_vec, float bank_override)
#define GLIDE_STRAFE_MAX_TIME
ship_subsys * turret_subsys
struct matrix::@228::@230 vec
float ai_get_weapon_speed(ship_weapon *swp)
void vm_vec_scale(vec3d *dest, float s)
int timestamp_until(int stamp)
void maybe_cheat_fire_synaptic(object *objp, ai_info *aip)
#define AIS_STRAFE_POSITION
void ai_big_strafe_position()
int find_enemy(int objnum, float range, int max_attackers)
void ai_big_strafe_retreat2()
#define MIN_DOT_TO_ATTACK_SUBSYS
ai_profile_t * ai_profile
void update_aspect_lock_information(ai_info *aip, vec3d *vec_to_enemy, float dist_to_enemy, float enemy_radius)
ai_goal goals[MAX_AI_GOALS]
float time_enemy_in_range
float ai_get_weapon_dist(ship_weapon *swp)
void ai_find_path(object *pl_objp, int objnum, int path_num, int exit_flag, int subsys_path=0)
void vm_vec_sub2(vec3d *dest, const vec3d *src)
#define ATTACK_COLLIDE_SLOW_DIST
void compute_desired_rvec(vec3d *rvec, vec3d *goal_pos, vec3d *cur_pos)
void ai_do_default_behavior(object *obj)
bool turret_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mod)
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
#define AIPF2_AI_AIMS_FROM_SHIP_CENTER
void ai_choose_secondary_weapon(object *objp, ai_info *aip, object *en_objp)
float vm_vec_normalized_dir(vec3d *dest, const vec3d *end, const vec3d *start)
float vm_vec_dist(const vec3d *v0, const vec3d *v1)
vec3d big_attack_surface_normal
#define AIF_FREE_AFTERBURNER_USE
int maybe_avoid_big_ship(object *objp, object *ignore_objp, ai_info *aip, vec3d *goal_point, float delta_time)
#define AIF_UNLOAD_SECONDARIES
#define AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS
void do_random_sidethrust(ai_info *aip, ship_info *sip)
int max_attackers[NUM_SKILL_LEVELS]
vec3d * vm_vec_unrotate(vec3d *dest, const vec3d *src, const matrix *m)
#define SM_CONTINUOUS_TURN
float vm_vec_dist_squared(const vec3d *v0, const vec3d *v1)
int iff_x_attacks_y(int team_x, int team_y)
int get_subsystem_pos(vec3d *pos, object *objp, ship_subsys *subsysp)
int ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
object Objects[MAX_OBJECTS]
#define STRAFE_RETREAT_COLLIDE_DIST
void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp)
void vm_vec_copy_scale(vec3d *dest, const vec3d *src, float s)
void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy)
#define AIS_STRAFE_RETREAT2
void vm_vec_random_in_circle(vec3d *out, const vec3d *in, const matrix *orient, float radius, int on_edge)
void vm_vec_rand_vec_quick(vec3d *rvec)
#define ENTER_STRAFE_THREAT_DIST_SQUARED
#define WBF_RANDOM_LENGTH
#define ATTACK_STOP_DISTANCE
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
#define STRAFE_RETREAT_COLLIDE_TIME
int pick_big_attack_point_timestamp
void ai_big_ship(object *objp)
int scan_for_enemy_timestamp
void afterburners_start(object *objp)
#define SM_ATTACK_FOREVER
GLdouble GLdouble GLdouble GLdouble q
#define STRAFE_MAX_UNHIT_TIME
float vm_vec_dist_quick(const vec3d *v0, const vec3d *v1)
float frand()
Return random value in range 0.0..1.0- (1.0- means the closest number less than 1.0)
#define AIS_STRAFE_GLIDE_ATTACK
#define AI_GOAL_DISABLE_SHIP
int set_target_objnum(ai_info *aip, int objnum)
#define ATTACK_COLLIDE_AVOID_TIME
int ship_return_subsys_path_normal(ship *shipp, ship_subsys *ss, vec3d *gsubpos, vec3d *norm)
float vm_vec_copy_normalize(vec3d *dest, const vec3d *src)
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=NULL, int sexp_flags=0)
#define MAX_ENEMY_DISTANCE
SCP_vector< ship_info > Ship_info
#define SF2_AFTERBURNER_LOCKED
int static_rand(int num)
Return a pseudo random 32 bit value given a reasonably small number.
#define timestamp_elapsed(stamp)
void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel)
float vm_vec_dot(const vec3d *v0, const vec3d *v1)
void ai_big_subsys_path_cleanup(ai_info *aip)
#define timestamp_rand(a, b)
eye view_positions[MAX_EYES]
#define PF_AFTERBURNER_ON
#define ATTACK_COLLIDE_SLOW_TIME
int ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int consider_target_only)
#define ATTACK_COLLIDE_BASE_DIST
void set_predicted_enemy_pos(vec3d *predicted_enemy_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, ai_info *aip)
void turn_away_from_point(object *objp, vec3d *point, float bank_override)
int ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
char filename[FILESPEC_LENGTH]
#define AIS_STRAFE_ATTACK
int burst_counter[MAX_SHIP_PRIMARY_BANKS+MAX_SHIP_SECONDARY_BANKS]
void vm_vec_add(vec3d *dest, const vec3d *src0, const vec3d *src1)
void ai_set_positions(object *pl_objp, object *en_objp, ai_info *aip, vec3d *player_pos, vec3d *enemy_pos)
void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum)
float static_randf(int num)
Return a random float in 0.0f .. 1.0f- (ie, it will never return 1.0f).
#define AIF_TARGET_COLLISION
ship_subsys * set_targeted_subsys(ai_info *aip, ship_subsys *new_subsys, int parent_objnum)
int ai_fire_secondary_weapon(object *objp, int priority1=-1, int priority2=-1)
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)
float vm_vec_normalize(vec3d *v)