75 #pragma optimize("", off)
76 #pragma auto_inline(off)
79 #define UNINITIALIZED_VALUE -99999.9f
81 #define INSTRUCTOR_SHIP_NAME NOX("instructor")
83 #define AICODE_SMALL_MAGNITUDE 0.001f // cosider a vector NULL if mag is less than this
85 #define NEXT_REARM_TIMESTAMP (60*1000) // Ships will re-request rearm, typically, after this long.
87 #define CIRCLE_STRAFE_MAX_DIST 300.0f //Maximum distance for circle strafe behavior.
92 #define SM_SF_BEHIND 1
96 #define SM_SS_SET_GOAL -1
172 #define REARM_SOUND_DELAY (3*F1_0) // Amount of time to delay rearm/repair after mode start
173 #define REARM_BREAKOFF_DELAY (3*F1_0) // Amount of time to wait after fully rearmed to breakoff.
175 #define MIN_DIST_TO_WAYPOINT_GOAL 5.0f
176 #define MAX_GUARD_DIST 250.0f
177 #define BIG_GUARD_RADIUS 500.0f
179 #define MAX_EVADE_TIME (15 * 1000) // Max time to evade a weapon.
182 #define MAX_REPAIR_SPEED 25.0f
183 #define MAX_UNDOCK_ABORT_SPEED 2.0f
186 #define MAX_EMP_INACCURACY 50.0f
189 #define MAX_STEALTH_INACCURACY 50.0f // at max view dist
190 #define STEALTH_MAX_VIEW_DIST 400 // dist at which 1) stealth no longer visible 2) firing inaccuracy is greatest
191 #define STEALTH_VIEW_CONE_DOT 0.707 // (half angle of 45 degrees)
210 const char *str = NULL;
212 #if NUM_SKILL_LEVELS != 5
213 #error Number of skill levels is wrong!
219 str =
XSTR(
"Very Easy", 469);
222 str =
XSTR(
"Easy", 470);
225 str =
XSTR(
"Medium", 471);
228 str =
XSTR(
"Hard", 472);
231 str =
XSTR(
"Insane", 473);
239 str =
NOX(
"Very Easy");
261 #define DELAY_TARGET_TIME (12*1000) // time in milliseconds until a ship can target a new enemy after an order.
338 Ai_huge_fire_info.push_back(new_info);
350 int firer_team, target_signature;
356 firer_team = firer_ship->
team;
359 target_signature = target_objp->
signature;
360 for (hfi = Ai_huge_fire_info.begin();hfi != Ai_huge_fire_info.end(); ++hfi ) {
361 int ship_index, signature;
363 if ( hfi->weapon_index == -1 )
367 if ( ship_index == -1 )
373 if ( (signature == target_signature) && (hfi->weapon_index == weapon_num) && (hfi->team == firer_team) )
378 if ( hfi == Ai_huge_fire_info.end() )
382 return hfi->max_fire_count;
390 Ai_huge_fire_info.clear();
447 Ppfp = &Path_points[xlt];
468 if (i != pp_xlate[i])
469 Path_points[pp_xlate[
i]] = Path_points[
i];
479 int addval = curval & 1;
483 curval |= 0x80000000;
496 unsigned int hashval = 0;
499 ip = (
int *) &objp->
orient;
501 for (i=0; i<9; i++) {
502 hashval =
hash(hashval, *ip);
506 ip = (
int *) &objp->
pos;
508 for (i=0; i<3; i++) {
509 hashval =
hash(hashval, *ip);
518 if(Ai_classes != NULL)
777 aicp = &Ai_classes[
i];
783 #define AI_CLASS_INCREMENT 10
838 mprintf((
"TABLES: Unable to parse '%s'! Error message = %s.\n",
"ai.tbl", e.what()));
906 #define STEALTH_NOT_IN_FRUSTUM 0
907 #define STEALTH_IN_FRUSTUM 1
908 #define STEALTH_FULLY_TARGETABLE 2
969 vec3d vec_to_stealth;
970 float dot_to_stealth, dist_to_stealth, max_stealth_dist;
983 dot_to_stealth =
vm_vec_dot(&viewer_objp->
orient.
vec.fvec, &vec_to_stealth) / dist_to_stealth;
989 float needed_dot_to_stealth;
990 if (dist_to_stealth < 100) {
991 needed_dot_to_stealth = 0.0f;
995 if (dot_to_stealth > needed_dot_to_stealth) {
996 if (dist_to_stealth < max_stealth_dist) {
1026 if (from_dot != NULL)
1041 object *stealth_objp;
1058 object *
objp, *weapon_objp;
1060 float old_dist, new_dist;
1061 float old_dot, new_dot;
1062 object *old_weapon_objp = NULL;
1064 if ((attacked_objnum == -1) || (weapon_objnum == -1)) {
1068 objp = &
Objects[attacked_objnum];
1076 weapon_objp = &
Objects[weapon_objnum];
1102 new_dist =
compute_dots(weapon_objp, objp, &new_dot, NULL);
1105 if (new_dist < 1500.0
f) {
1106 if (new_dot > 0.5
f) {
1112 Assert(old_weapon_objp != NULL);
1113 old_dist =
compute_dots(old_weapon_objp, objp, &old_dot, NULL);
1115 if (old_dot < 0.5
f) {
1120 if ((new_dot > 0.5
f) && (new_dot > old_dot-0.01
f)) {
1121 if (new_dist < old_dist) {
1134 vec3d vel_in, vel_out, desired_fvec,
src;
1137 vec3d vel_limit, acc_limit;
1150 curr_orient = objp->
orient;
1153 if(turn_time > 0.0
f)
1156 if (!(flags &
AITTV_FAST) && !(sexp_flags & AITTV_VIA_SEXP) ){
1165 vel_limit.
xyz.x =
PI2/turn_time;
1166 vel_limit.
xyz.y =
PI2/turn_time;
1167 vel_limit.
xyz.z =
PI2/turn_time;
1176 acc_limit = vel_limit;
1182 if (rel_pos != NULL) {
1193 if (slide_vec != NULL) {
1203 delta_bank = bank_override;
1206 delta_bank = 100.0f * (1.0f - delta_bank);
1208 delta_bank = -delta_bank;
1221 vel_in_copy = vel_in;
1222 objp_orient_copy = objp->
orient;
1224 vel_in = vel_in_copy;
1225 objp->
orient = objp_orient_copy;
1229 matrix out_orient, goal_orient;
1232 vm_matrix_interpolate(&goal_orient, &curr_orient, &vel_in, delta_time, &out_orient, &vel_out, &vel_limit, &acc_limit);
1233 objp->
orient = out_orient;
1381 if (delta_accel < 0.0
f) {
1389 if (new_accel > 1.0
f)
1391 else if (new_accel < -1.0
f)
1407 max_speed = Ships[objp->
instance].current_max_speed;
1409 if (max_speed > 0.0
f) {
1410 AI_ci.
forward = tspeed/max_speed;
1459 vec3d dest_vec, v2c, perp_vec, temp_vec,
v2;
1476 ratio = dist / radius;
1515 vec3d opposite_point;
1538 vec3d up_vec, perp_vec;
1560 vec3d r_vec, theta_vec;
1561 vec3d center_vec, vec_on_cylinder, sph_r_vec;
1582 Assert(mag > 0.9999 && mag < 1.0001);
1591 Assert( dot >0.9999 && dot < 1.0001);
1613 vec3d up_vec, perp_vec;
1666 if ( radar_return > 0.4 ) {
1723 float lowest_max_speed;
1734 wingnum = aip->
wing;
1738 if ( wingnum == -1 )
1739 return lowest_max_speed;
1758 lowest_max_speed = cur_max;
1763 return lowest_max_speed;
1773 float lowest_max_av_ab_speed;
1774 float recharge_scale;
1787 wingnum = aip->
wing;
1800 if ( wingnum == -1 )
1801 return lowest_max_av_ab_speed;
1830 lowest_max_av_ab_speed = cur_max;
1835 return lowest_max_av_ab_speed;
1851 else if (*ignore_objnum >= 0)
1854 if (
Objects[*ignore_objnum].signature != *ignore_signature)
1860 else if (*ignore_objnum == objnum)
1898 if (!just_the_original)
2000 dist *= (
float) (num_attacking+2)/2.0f;
2007 if (dist < eno->nearest_dist) {
2031 object *danger_weapon_objp;
2060 if (danger_weapon_objp->
parent >= 0) {
2099 nearest_objnum = -1;
2100 nearest_dist =
range;
2122 if (dist < nearest_dist) {
2123 nearest_dist = dist;
2131 return nearest_objnum;
2188 int enemy_team_mask;
2207 return target_objnum;
2262 Assert(attacker != NULL);
2271 if (attacker == attacked) {
2278 nprintf((
"AI",
"AI ship %s is large ship ordered to attack %s\n", Ships[attacker->
instance].ship_name, Ships[attacked->
instance].ship_name));
2282 if (attacked == NULL) {
2330 Assert(attacker != NULL);
2371 if (evaded == evader) {
2396 int next_occupied_index = -1;
2416 next_occupied_index =
i;
2421 if (next_occupied_index < 0)
2422 return current_index;
2448 Assert(ignorer != ignored);
2516 if (modify_index == -1) {
2522 pnp = &Path_points[modify_index];
2545 tvec.
xyz.x = -tvec.
xyz.z;
2547 tvec.
xyz.y = -tvec.
xyz.x;
2582 radius = goalobjp->
radius;
2627 int start_index, finish_index;
2628 vec3d submodel_offset, local_vert;
2629 bool rotating_submodel;
2643 start_index = mp->
nverts-1;
2644 finish_index =
MAX(-1, mp->
nverts-1-count);
2653 rotating_submodel =
true;
2659 rotating_submodel =
false;
2663 for (i=start_index; i != finish_index; i += dir)
2667 if (rotating_submodel)
2680 if ( randomize_pnt == i ) {
2688 pp_index = pnp-Path_points +
offset;
2727 Assert(path_num < pm->n_paths);
2729 mp = &pm->
paths[path_num];
2741 perim_point2 = pl_objp->
pos;
2761 if ( subsys_path ) {
2819 Assert(path_num < pm->n_paths);
2821 mp = &pm->
paths[path_num];
2849 if (big_only_flag) {
2854 if ((objp != ignore_objp1) && (objp != ignore_objp2)) {
2855 if (
pp_collide(curpos, goalpos, objp, radius))
2875 void ai_find_path(
object *pl_objp,
int objnum,
int path_num,
int exit_flag,
int subsys_path)
2891 Error(
LOCATION,
"ai_find_path tring to find a path (%d) that doesn't exist, on ship %s", path_num, shipp->
ship_name);
2914 vec3d cur_pos, new_goal_pos;
2915 object *player_objp;
2916 vec3d n_vec_to_goal, n_vec_to_player;
2934 if (obj_obj_dist > speed_time*2.0
f)
2937 cur_pos = objp->
pos;
2939 new_goal_pos = *goal_pos;
2944 if (dist > speed_time*2.0f) {
2953 vm_vec_sub(&avoid_vec, &n_vec_to_goal, &n_vec_to_player);
2998 if (view_pos != NULL)
3010 Assert((docker != NULL) && (dockee != NULL));
3015 Warning(
LOCATION,
"Call to ai_do_objects_docked_stuff when objects are already docked! Trace out and fix!\n");
3056 Assert((docker != NULL) && (dockee != NULL));
3061 Warning(
LOCATION,
"Call to ai_do_objects_undocked_stuff when objects are already undocked! Trace out and fix!\n");
3108 Assert(docker_index >= 0);
3109 Assert(dockee_index >= 0);
3118 switch (dock_type) {
3173 Error(
LOCATION,
"Cannot find a dock path for ship %s, dock index %d. Aborting dock.\n", Ships[dockee->
instance].ship_name, dockee_index);
3226 Warning(
LOCATION,
"aip->wp_index should have been assigned already!");
3258 Assert(objp != other_objp);
3299 if ( objp == goal_objp ) {
3304 Assert(objp != goal_objp);
3311 nprintf((
"AI",
"Warning: Ship %s tried to form on player's wing, but not fighter or bomber.\n", shipp->
ship_name));
3351 #define BIGNUM 100000.0f
3363 vec3d vec_to_target;
3368 vm_vec_sub(&vec_to_target, targpos, attackpos);
3369 pos_dot_vel =
vm_vec_dot(&vec_to_target, targvel);
3370 vel_sqr =
vm_vec_dot(targvel, targvel) - weapon_speed*weapon_speed;
3371 discrim = pos_dot_vel*pos_dot_vel - vel_sqr*
vm_vec_dot(&vec_to_target, &vec_to_target);
3373 if (discrim > 0.0
f) {
3374 float t1,
t2, t_solve;
3376 t1 = (-pos_dot_vel +
fl_sqrt(discrim)) / vel_sqr;
3377 t2 = (-pos_dot_vel -
fl_sqrt(discrim)) / vel_sqr;
3383 if ((t2 > 0.0
f) && (t2 < t_solve))
3405 float time_to_enemy;
3407 float max_laser_distance, max_laser_speed;
3408 int bank_num, weapon_num;
3419 if (dist_to_enemy > 1.5 * max_laser_distance) {
3420 if (pl_speed > 0.0
f)
3421 time_to_enemy = dist_to_enemy/pl_speed;
3423 time_to_enemy = 1.0f;
3424 }
else if (dist_to_enemy > 1.1*max_laser_distance) {
3425 if (pl_speed > 0.1
f) {
3428 scale = (
float) ((dist_to_enemy - max_laser_distance) / max_laser_distance);
3430 time_to_enemy = (
float) (dist_to_enemy/(pl_speed * scale + max_laser_speed * (1.0
f - scale)));
3432 time_to_enemy = 2.0f;
3434 time_to_enemy = (
float) (dist_to_enemy/max_laser_speed);
3464 *tts = dist * 100.0f;
3471 *player_pos = pl_objp->
pos;
3476 *enemy_pos = en_objp->
pos;
3511 pnode *pn = &Path_points[path_cur];
3548 Assert((path_num >= 0) && (path_num < pm->n_paths));
3587 force_recreate_flag = 1;
3611 if (force_recreate_flag || (dist > 2.0
f)) {
3651 }
else if ((prev_dot_to_goal-dot) > 0.01) {
3652 if (prev_dot_to_goal > dot + 0.05
f) {
3665 float speed_mult = FLT_MIN;
3669 speed_mult = gsip->
pathMetadata[pathName].arrive_speed_mult;
3672 if (speed_mult == FLT_MIN) {
3677 speed_mult = gsip->
pathMetadata[pathName].depart_speed_mult;
3680 if (speed_mult == FLT_MIN) {
3685 if (speed_mult != FLT_MIN && speed_mult != 1.0
f) {
3698 max_bay_speed = sip->
max_speed * (speed_mult + (1.0f - speed_mult) * (dist_to_end / total_path_length));
3703 if (max_allowed_speed <= 0)
3704 max_allowed_speed = max_bay_speed;
3706 max_allowed_speed =
MIN(max_allowed_speed, max_bay_speed);
3710 }
else if ((dot_to_next >= dot * .9) || (dist_to_next > 100.0
f)) {
3711 if (dist_to_goal > 200.0
f) {
3717 xdot = (dot_to_next + dot)/2.0
f;
3735 xdot =
MAX(dot_to_next, 0.1
f);
3741 speed = dist_to_goal/8.0f + 2.0f;
3742 }
else if (dist_to_goal < 4*objp->radius + 50.0
f) {
3743 speed = dist_to_goal/4.0f + 4.0f;
3745 speed = max_allowed_speed * (3*xdot + 1.0f)/4.0
f;
3748 speed = speed * 2.0f + 1.0f;
3783 float dot, dist_to_goal, dist_to_next, dot_to_next;
3789 vec3d temp_vec, *slop_vec;
3791 vec3d *cvp, *nvp, next_vec, gcvp, gnvp;
3873 else if (mag > 5.0
f) {
3876 if ((nv_dot > 0.5
f) && (nv_dot < 0.97
f)) {
3877 slop_vec = &temp_vec;
3882 if (dist_to_goal > 0.1
f)
3896 vec3d nearest_point;
3897 float r, min_dist_to_goal;
3918 return dist_to_goal;
3927 float dot, dist_to_goal, dist_to_next, dot_to_next;
3934 vec3d *pvp, *cvp, *nvp, next_vec, gpvp, gcvp, gnvp;
3981 if (prev_point >= aip->
path_start && prev_point <= aip->path_start + num_points)
3982 pvp = &Path_points[prev_point].
pos;
3986 gpvp = (pvp != NULL) ? *pvp : *cvp;
4007 vec3d *prvec = NULL;
4015 if (dist_to_goal > 0.1
f) {
4017 vec3d closest_point;
4024 vm_vec_avg3(&midpoint, &gcvp, &closest_point, &closest_point);
4038 float max_allowed_speed = 0.0f;
4043 set_accel_for_docking(Pl_objp, aip, dot, dot_to_next, dist_to_next, dist_to_goal, sip, max_allowed_speed, gobjp);
4049 vec3d nearest_point;
4050 float r, min_dist_to_goal;
4063 float goal_mag = 0.0f;
4084 return dist_to_goal;
4108 else if (val > *max)
4127 *min_vec = objp->
pos;
4128 *max_vec = objp->
pos;
4150 int enemy_team_mask;
4151 vec3d min_vec, max_vec;
4152 vec3d vec_to_center, center;
4186 dot_val = (1.1f + dot) / 2.0
f;
4187 if (dist > 200.0
f) {
4249 float dot, dist_to_goal;
4255 float prev_dot_to_goal;
4259 bool ab_allowed =
true;
4261 Assert( target_pos != NULL );
4263 if ( pl_done_p != NULL ) {
4296 }
else if (mag > 5.0
f) {
4299 if ((nv_dot > 0.5
f) && (nv_dot < 0.97
f)) {
4300 slop_vec = &temp_vec;
4308 if (aip->
wing >= 0) {
4310 scale = (
int) ((scale+1)/2);
4321 vec3d perp, goal_point;
4333 Assertion( Autopilot_flight_leader != NULL,
"When under autopilot there must be a flight leader" );
4336 if (aip->
wing != -1) {
4340 if (wing_leader != Pl_objp) {
4351 vm_vec_add(&goal_point, &Autopilot_flight_leader->
pos, &perp);
4358 vm_vec_add(&goal_point, &Autopilot_flight_leader->
pos, &perp);
4364 Pl_objp->
pos = goal_point;
4374 if (dist_to_goal > 0.1
f) {
4388 }
else if (prev_dot_to_goal > dot+0.01
f) {
4392 }
else if (dist_to_goal < 100.0
f) {
4394 if (
fl_abs(slew_dot) < 0.9
f) {
4396 }
else if (dot < 0.88
f + 0.1
f*(100.0
f - dist_to_goal)/100.0
f) {
4404 if (dist_to_goal < 250.0
f) {
4414 if (dist_to_goal > 100.0
f + Pl_objp->
radius * 2) {
4434 float max_allowed_speed = 9999.9f;
4435 float max_allowed_ab_speed = 10000.1f;
4436 float self_ab_speed = 10000.0f;
4451 max_allowed_ab_speed = max_allowed_speed;
4454 if ((self_ab_speed < 5.0
f) || (max_allowed_ab_speed < 5.0f)){
4456 }
else if (max_allowed_ab_speed < shipp->current_max_speed) {
4457 if (max_allowed_speed < max_allowed_ab_speed) {
4458 max_allowed_speed = max_allowed_ab_speed;
4466 if (self_ab_speed <= (1.001 * max_allowed_ab_speed)){
4469 if (percent_left > 30.0
f) {
4476 if ((self_ab_speed - max_allowed_ab_speed) > (0.2
f * max_allowed_ab_speed)) {
4477 switch_value = 0.2f * max_allowed_ab_speed;
4479 switch_value = self_ab_speed - max_allowed_ab_speed;
4483 if ((Pl_objp->
phys_info.
speed < (max_allowed_ab_speed - switch_value)) && (percent_left > 30.0f)){
4488 if (Pl_objp->
phys_info.
speed > (max_allowed_ab_speed + 0.9 * switch_value)){
4509 vec3d nearest_point;
4523 if ( Ships[Pl_objp->
instance].wingnum != -1 ) {
4537 if ( pl_done_p != NULL ) {
4539 if ( pl_treat_as_ship_p != NULL ) {
4540 if ( treat_as_ship ) {
4541 *pl_treat_as_ship_p =
true;
4543 *pl_treat_as_ship_p =
false;
4548 "pl_done_p cannot be NULL while pl_treat_as_ship_p is not NULL" );
4573 bool done, treat_as_ship;
4593 if ( treat_as_ship ) {
4610 object* target_p = NULL;
4616 "ai_fly_to_ship called for '%s' when ai_info.mode not equal to AIM_FLY_TO_SHIP. Is actually '%d'",
4617 Ships[Pl_objp->
instance].ship_name,
4624 "'%s' is trying to fly-to a ship without an active AI_GOAL\n\n"
4625 "Active ai mode is '%d'",
4626 Ships[Pl_objp->
instance].ship_name,
4633 Warning(
LOCATION,
"'%s' is trying to fly-to-ship without a name for the ship", Ships[Pl_objp->
instance].ship_name);
4643 target_p = &
Objects[Ships[j].objnum];
4648 if ( target_p == NULL ) {
4654 mprintf((
"Ship '%s' told to fly to target ship '%s'",
4655 Ships[Pl_objp->
instance].ship_name,
4660 Warning(
LOCATION,
"Ship '%s' told to fly to a ship but none of the ships it was told to fly to exist.\n"
4661 "See log before this message for list of ships set as fly-to tagets",
4662 Ships[Pl_objp->
instance].ship_name);
4667 bool done, treat_as_ship;
4674 if ( treat_as_ship ) {
4705 vec3d player_pos, enemy_pos;
4733 if (away_dot < 0.0
f) {
4747 else if (dist < 2*radsum)
4784 if ((En_objp != NULL) && (En_objp->
type ==
OBJ_SHIP)) {
4818 return !(t % modulus);
4842 if (dist < 150.0
f) {
4850 if (dot * dist > 50.0
f)
4875 if (en_objp != NULL) {
4906 object *weapon_objp = NULL;
4907 object *unlocked_weapon_objp = NULL, *locked_weapon_objp = NULL;
4908 vec3d weapon_pos, player_pos, goal_point;
4909 vec3d vec_from_enemy;
4910 float dot_from_enemy, dot_to_enemy;
4932 if (locked_weapon_objp != NULL) {
4933 if (unlocked_weapon_objp != NULL) {
4935 weapon_objp = locked_weapon_objp;
4937 weapon_objp = unlocked_weapon_objp;
4939 weapon_objp = locked_weapon_objp;
4940 }
else if (unlocked_weapon_objp != NULL)
4941 weapon_objp = unlocked_weapon_objp;
4948 Assert(weapon_objp != NULL);
4956 weapon_pos = weapon_objp->
pos;
4957 player_pos = Pl_objp->
pos;
4968 if (dot_from_enemy < 0.3
f) {
4969 if (weapon_objp == unlocked_weapon_objp)
4972 }
else if (dot_from_enemy > 0.7
f) {
4973 if (dist < 200.0
f) {
4983 if ((dot_to_enemy < -0.5
f) || (dot_to_enemy > 0.5
f)) {
4994 if ((udot < -0.5
f) || (udot > 0.5
f))
5001 if ((rdot < -0.5
f) || (rdot > 0.5
f))
5030 float dot_from_enemy;
5031 vec3d vec_from_enemy, vec_to_goal;
5069 if (dist < 200.0
f) {
5070 if (dot_from_enemy < 0.7
f)
5075 if (dot_from_enemy < 0.7
f) {
5089 vec3d player_pos, enemy_pos, goal_point;
5090 vec3d vec_from_enemy;
5091 float dot_from_enemy;
5096 float bank_override = 0.0f;
5113 if (percent_left > 30.0
f + ((
OBJ_INDEX(Pl_objp)) & 0x0f)) {
5124 vm_vec_sub(&vec_from_enemy, &player_pos, &enemy_pos);
5129 if (dist > 250.0
f) {
5138 }
else if (dot_from_enemy < 0.1
f) {
5141 }
else if (dot_from_enemy > 0.9
f) {
5146 vm_vec_sub(&vec_to_enemy, &enemy_pos, &player_pos);
5150 if (dot_to_enemy > 0.75
f) {
5168 psrandval = psrandval/16.0f;
5180 temp = ((temp * (temp+1)) % 16)/2 - 4;
5181 if ((psrandval == 0) && (temp == 0))
5184 scale = 200.0f *
temp;
5241 int weapon_info_index;
5245 if (weapon_info_index > -1){
5246 if (
Weapon_info[weapon_info_index].wi_flags & WIF_PUNCTURE) {
5303 if (other_objp==NULL)
5307 mprintf((
"'other_objpp == NULL' in ai_select_primary_weapon()\n"));
5335 int weapon_info_index;
5339 if (weapon_info_index > -1)
5341 if (
Weapon_info[weapon_info_index].wi_flags & WIF_PUNCTURE)
5370 if (enemy_remaining_shield <= 0.05
f)
5374 float i_hullfactor_prev = 0;
5375 int i_hullfactor_prev_bank = -1;
5388 i_hullfactor_prev_bank =
i;
5393 if (i_hullfactor_prev_bank == -1)
5395 i_hullfactor_prev_bank = 0;
5398 return i_hullfactor_prev_bank;
5402 if (enemy_remaining_shield >= 0.10
f)
5417 int weapon_info_index;
5421 if (weapon_info_index > -1)
5433 if (enemy_remaining_shield <= 0.50
f)
5437 float i_hullfactor_prev = 0;
5438 int i_hullfactor_prev_bank = -1;
5450 i_hullfactor_prev_bank =
i;
5455 if (i_hullfactor_prev_bank == -1)
5457 i_hullfactor_prev_bank = 0;
5460 return i_hullfactor_prev_bank;
5466 float i_hullfactor_prev = 0;
5467 int i_hullfactor_prev_bank = -1;
5479 i_hullfactor_prev_bank =
i;
5484 if (i_hullfactor_prev_bank == -1)
5486 i_hullfactor_prev_bank = 0;
5489 return i_hullfactor_prev_bank;
5604 ammo_pct =
float (current_ammo) /
float (total_ammo) * 100.0f;
5673 if (
vm_vec_cmp(&G_predicted_pos, &G_fire_pos) ) {
5676 if (dot > .998629534
f){
5684 enemy_objp != NULL && enemy_sip != NULL &&
5693 float distanceFactor = 1.0f - distToTarget/weaponRange;
5697 dotToTarget = pow(dotToTarget, 4);
5701 float burstFireProb = ((0.6f * percentAmmoLeft) + (0.4
f * distanceFactor)) * dotToTarget * aip->
ai_primary_ammo_burst_mult * fof_spread_cooldown_factor;
5803 int num_weapon_types;
5806 int ignore_mask, ignore_mask_without_huge;
5814 ignore_mask_without_huge = 0;
5817 if (!(
WIF_HUGE & (priority1 | priority2))) {
5834 weapon_id_list[
i] = -1;
5835 weapon_bank_list[
i] = -1;
5848 int priority2_index = -1;
5850 for (i=0; i<num_weapon_types; i++) {
5855 if (!(wi_flags & ignore_mask_to_use)) {
5856 if (wi_flags & priority1) {
5859 }
else if (wi_flags & priority2)
5860 priority2_index = weapon_bank_list[
i];
5862 if (!(wi_flags2 & ignore_mask_to_use)) {
5863 if (wi_flags2 & wif2_priority1) {
5866 }
else if (wi_flags2 & wif2_priority2)
5867 priority2_index = weapon_bank_list[
i];
5878 if (i == num_weapon_types) {
5880 if (priority2_index == -1) {
5881 for (i=0; i<num_weapon_types; i++) {
5885 if (!(wi_flags & ignore_mask_to_use)) {
5943 int firing_ship_team;
5969 float payload = 0.0f;
5997 if (target_objnum >= 0) {
5998 object *tobjp = &
Objects[target_objnum];
6026 }
else if (num_homers > 3) {
6027 float incoming_payload;
6072 if (current_bank == -1) {
6076 Assert(current_bank < shipp->weapons.num_secondary_banks);
6111 if (dot_to_enemy > 0.8
f - 2*(obj1->
radius + obj2->
radius)/dist_to_enemy)
6152 vec3d global_path_point;
6158 memset(&v, 0,
sizeof(v));
6163 for ( j = 0; j < mp->
nverts; j++ ) {
6172 if ( j == mp->
nverts-1 ) {
6197 vec3d global_path_point;
6203 memset(&v, 0,
sizeof(v));
6205 for ( i = 0; i < pm->
n_paths; i++ ) {
6207 for ( j = 0; j < mp->
nverts; j++ ) {
6216 if ( j == mp->
nverts-1 ) {
6245 vec3d dock_point, global_dock_point;
6262 for (i=0; i<num_points; i++) {
6265 memset(&v0, 0,
sizeof(v0));
6273 if (pp-Path_points == aip->
path_cur)
6290 int bank_num, weapon_num;
6297 if (weapon_num == -1) {
6306 int bank_num, weapon_num;
6314 if (weapon_num == -1) {
6323 int bank_num, weapon_num;
6331 if (weapon_num == -1) {
6349 if (weapon_speed < 1.0
f)
6350 weapon_speed = 1.0f;
6358 if (time_enemy_in_range < range_time) {
6362 vm_vec_scale_add(predicted_enemy_pos, enemy_pos, enemy_vel, time_enemy_in_range * dist/weapon_speed);
6364 float collision_time,
scale;
6370 if (collision_time == 0.0
f){
6371 collision_time = 100.0f;
6374 vm_vec_scale_add(predicted_enemy_pos, enemy_pos, enemy_vel, collision_time);
6375 if (time_enemy_in_range > 2*range_time){
6378 scale = (1.0f - aip->
ai_accuracy) * 4.0
f * (1.0
f + 4.0
f * (1.0
f - time_enemy_in_range/(2*range_time)));
6385 G_fire_pos = *gun_pos;
6388 G_predicted_pos = *predicted_enemy_pos;
6399 float weapon_speed, range_time;
6402 vec3d target_moving_direction;
6404 Assert( enemy_pos != NULL );
6405 Assert( enemy_vel != NULL );
6408 target_moving_direction = *enemy_vel;
6416 weapon_speed = 100.0f;
6418 weapon_speed =
MAX(weapon_speed, 1.0
f);
6436 float collision_time;
6453 if (collision_time == 0.0
f) {
6454 collision_time = 100.0f;
6457 vm_vec_scale_add(predicted_enemy_pos, enemy_pos, &target_moving_direction, collision_time);
6461 G_fire_pos = gun_pos;
6479 mprintf((
"AI miss scale factor (EMP) %f\n",scale));
6499 G_predicted_pos = *predicted_enemy_pos;
6518 tvec = Pl_objp->
pos;
6547 float dot_to_enemy, dot_from_enemy;
6549 compute_dots(Pl_objp, En_objp, &dot_to_enemy, &dot_from_enemy);
6552 _pep = *predicted_enemy_pos;
6553 if ((dot_to_enemy > dot_from_enemy + 0.1
f) || (dot_to_enemy > 0.9
f))
6567 float to_dot, from_dot, dist;
6569 dist =
compute_dots(ship_objp, weapon_objp, &to_dot, &from_dot);
6576 else if ((from_dot > 0.1
f) && (dist/(from_dot*from_dot) < 48*ship_objp->
radius))
6586 object *weapon_objp;
6619 if (strafeHoldDirAmount > 0) {
6623 Warning(
LOCATION,
"Division by zero in do_random_sidethrust averted. Please tell a coder.\n");
6648 if ((dist_to_enemy > 200.0
f) && (dist_to_enemy < 800.0
f)) {
6687 if (dist_to_enemy > 800.0
f) {
6698 if (percent_left > 30.0
f + ((
OBJ_INDEX(Pl_objp)) & 0x0f)) {
6702 float time_to_exhaust_25pct_fuel;
6703 float time_to_fly_75pct_of_distance;
6708 max_ab_vel = max_ab_vel > 0.0f ? max_ab_vel : 0.0001f;
6714 time_to_fly_75pct_of_distance = dist_to_enemy * 0.75f / max_ab_vel;
6717 ab_time =
MIN(time_to_exhaust_25pct_fuel, time_to_fly_75pct_of_distance);
6732 && (dist_to_enemy > 25.0f)
6733 && (dot_to_enemy > 0.8f)
6734 && (dot_from_enemy < 0.8f)) {
6736 }
else if ((dot_from_enemy < 0.25
f) && (dot_to_enemy > 0.5
f)) {
6741 if (dot_from_enemy > 0.75
f)
6756 vec3d vec_from_enemy;
6833 if (goal_point == NULL) {
6836 end_pos = *goal_point;
6850 int collision_obj_index = -1;
6851 float min_dist = 999999.9f;
6856 if (big_objp == ignore_objp)
6860 vec3d cur_collision_point;
6867 if (cur_dist < min_dist) {
6868 min_dist = cur_dist;
6869 *collision_point = cur_collision_point;
6870 collision_obj_index =
OBJ_INDEX(big_objp);
6876 *distance = min_dist;
6877 return collision_obj_index;
6905 for (s=0.5
f; s<1.3f; s += 0.25f) {
6907 for (i=0; i<4; i++) {
6926 float min_dist = 9999999.9f;
6929 for (i=0; i<4; i++) {
6930 if (!goals[i].
collide && (goals[i].dist < min_dist)) {
6931 min_dist = goals[
i].
dist;
6938 *avoid_pos = goals[min_index].
pos;
6959 vec3d collision_point;
6983 float d2 = (1.0f + dot) * (1.0
f + dot);
7002 rvec->
xyz.z = -v2e.
xyz.x;
7015 vec3d new_pos, vec_to_enemy;
7016 float dist_to_enemy, dot_to_enemy, dot_from_enemy;
7027 if (delta_time > 10000) {
7079 if (dist_to_enemy > 500.0
f) {
7120 box_size =
MIN(200.0
f, box_size);
7121 box_size =
MAX(500.0
f, box_size);
7201 if (dist_to_goal < 15) {
7215 if (dist_to_goal < 100) {
7230 float dot_to_enemy, dot_from_enemy;
7231 float bank_override = 0.0f;
7236 compute_dots(Pl_objp, En_objp, &dot_to_enemy, &dot_from_enemy);
7246 if (po->
n_guns && start_bank != -1 ) {
7255 scale = dist_to_enemy/(dist_to_enemy + En_objp->
radius) * En_objp->
radius;
7259 new_pos = *predicted_enemy_pos;
7269 if (dist_to_enemy > 500.0
f) {
7291 tvec = Pl_objp->
pos;
7296 if (timeslice & 0x01)
7298 if (timeslice & 0x02)
7300 if (timeslice & 0x04)
7302 if (timeslice & 0x08)
7323 float bank_override;
7324 vec3d vec_from_enemy;
7326 if (En_objp != NULL) {
7329 vec_from_enemy = Pl_objp->
orient.
vec.fvec;
7345 if (percent_left > 30.0
f + ((
OBJ_INDEX(Pl_objp)) & 0x0f)) {
7365 object *attacked_objp;
7419 Assert(objp != guard_objp);
7420 if (objp == guard_objp) {
7427 radius = 5.0f * (objp->
radius + guard_objp->
radius) + 50.0
f;
7428 if (radius > 300.0
f) {
7429 radius = guard_objp->
radius * 1.25f;
7454 int leader_objnum, leader_shipnum;
7478 if (
Wings[wingnum].current_count < 1) {
7521 Assert(other_objnum >= 0);
7540 Assert(objp != other_objp);
7565 Assert(other_objnum >= 0);
7579 int num_weapon_types;
7607 if (dist_to_enemy > 300.0
f -
MIN(enemy_radius, 100.0
f))
7616 float needed_dot = 0.9f - 0.5f * enemy_radius/(dist_to_enemy + enemy_radius);
7617 if (dot_to_enemy > needed_dot &&
7702 float subsystem_strength = 0.0f;
7703 int is_big_ship, wif_priority1, wif_priority2, wif2_priority1, wif2_priority2;
7723 if (preferred_secondary != -1) {
7756 else if (subsystem_strength > 100.0
f)
7807 t = t * 2.0f + 2.0f;
7824 if (dist_to_goal > 400.0
f) {
7827 *accel = dist_to_goal/400.0f;
7843 float temp, r_target, r_attacker;
7845 vec3d vec_to_target;
7853 r_attacker =
MAX(temp, r_attacker);
7858 r_target =
MAX(temp, r_target);
7871 *desired_separation = 1000 + r_target + r_attacker;
7877 float temp, r_target, r_attacker;
7878 float separation, optimal_separation;
7879 vec3d horz_vec_to_target;
7887 r_attacker =
MAX(temp, r_attacker);
7892 r_target =
MAX(temp, r_target);
7908 vm_vec_scale_add2(goal_pos, &horz_vec_to_target, optimal_separation/separation);
7911 vec3d vec_to_target;
7915 float match_accel = 0.0f;
7916 float length_scale = attack_objp->
radius;
7918 if (
Ship_info[Ships[attack_objp->
instance].ship_info_index].max_vel.xyz.z != 0.0f) {
7924 perp_dist = -perp_dist;
7927 if (perp_dist > 0) {
7929 *accel = match_accel + (1.0f - match_accel) / length_scale * (perp_dist);
7932 *accel = match_accel - match_accel / length_scale * -perp_dist;
7933 *accel =
MAX(0.0
f, *accel);
8024 vec3d *rvecp = NULL;
8052 float dist_to_enemy;
8059 if ( dist_to_enemy < (Pl_objp->
radius + En_objp->
radius)*1.25f + 200.0f ) {
8081 float desired_sep, cur_sep;
8089 if (cur_sep > (0.9
f * desired_sep)) {
8098 float desired_sep, cur_sep;
8106 if (cur_sep > (0.9
f * desired_sep)) {
8119 if (cur_sep > (0.9
f * desired_sep)) {
8134 if ( dist_to_enemy > (0.75 * (En_objp->
radius + Pl_objp->
radius)) ) {
8150 float dist_to_enemy;
8151 float dot_to_enemy, dot_from_enemy, real_dot_to_enemy;
8152 vec3d player_pos, enemy_pos, predicted_enemy_pos, real_vec_to_enemy, predicted_vec_to_enemy;
8157 int enemy_sip_flags, enemy_shipp_flags2;
8165 bool go_after_it =
true;
8170 go_after_it =
false;
8176 for(
size_t i = 0;
i < ap_size;
i++)
8189 mprintf((
"AI-WARNING: No class_type specified for '%s', assuming that it's ok to chase!\n", esip->
name));
8204 Assert( En_objp != NULL );
8210 enemy_sip_flags = 0;
8211 enemy_shipp_flags2 = 0;
8214 if ( enemy_sip_flags > 0 ) {
8231 vm_vec_sub(&real_vec_to_enemy, &enemy_pos, &player_pos);
8240 int is_stealthy_ship = 0;
8241 if ( (enemy_sip_flags > 0) && (enemy_shipp_flags2 &
SF2_STEALTH) ) {
8243 is_stealthy_ship = 1;
8257 if ((real_dot_to_enemy < 0.25
f) || (aip->
target_time < 1.0f)) {
8258 predicted_enemy_pos = enemy_pos;
8261 predicted_enemy_pos = enemy_pos;
8262 G_predicted_pos = predicted_enemy_pos;
8271 predicted_enemy_pos = enemy_pos;
8272 predicted_vec_to_enemy = real_vec_to_enemy;
8286 vm_vec_sub(&predicted_vec_to_enemy, &predicted_enemy_pos, &player_pos);
8325 ai_chase_eb(aip, sip, &predicted_enemy_pos, dist_to_enemy);
8391 (dot_to_enemy < 0.95f - 0.5f * En_objp->radius/
MAX(1.0
f, En_objp->
radius + dist_to_enemy)))
8442 }
else if (dist_to_enemy < CIRCLE_STRAFE_MAX_DIST + En_objp->radius &&
8453 (dist_to_enemy < 500.0
f) && (dot_to_enemy < 0.2
f) &&
8459 && (dot_to_enemy < dot_from_enemy)
8461 && (dist_to_enemy < 200.0f)
8462 && (dist_to_enemy > 50.0f)
8463 && (dot_to_enemy < 0.1f)
8467 }
else if ((dot_to_enemy > 0.2
f) && (dot_from_enemy > -0.2
f) && (dot_from_enemy < 0.1
f)) {
8470 }
else if ((enemy_sip_flags & SIF_SMALL_SHIP) && (dist_to_enemy < 150.0
f) && (dot_from_enemy > dot_to_enemy + 0.5
f + aip->
ai_courage*.002)) {
8483 if ((dot_to_enemy < 0.8
f) && (dot_from_enemy > dot_to_enemy)) {
8484 if (
frand() > 0.5f) {
8503 if ((dist_to_enemy < 100.0
f) && (dot_to_enemy < 0.0
f) && (dot_from_enemy > 0.5
f)) {
8533 if ((dot_to_enemy < 0.2
f) && (dot_from_enemy < 0.8
f) && (dist_to_enemy < 100.0
f) && (En_objp->
phys_info.
speed > 15.0f)) {
8537 }
else if (((dot_to_enemy > dot_from_enemy - 0.1
f)
8539 || (dist_to_enemy > 150.0
f + 2*(Pl_objp->
radius + En_objp->
radius))) {
8544 if (dot_from_enemy > 0.8
f) {
8557 }
else if (dist_to_enemy < CIRCLE_STRAFE_MAX_DIST + En_objp->radius &&
8607 if ((dot_to_enemy > -0.2
f) && (dist_to_enemy / (dot_to_enemy + 0.3
f) < 100.0
f)) {
8632 rand_dist = ((
Missiontime >> 17) & 0x03) * 100.0f + 200.0f;
8733 dist_to_enemy < aip->ai_stalemate_dist_thresh &&
8748 if (dot_to_enemy > 0.95
f - 0.5
f * En_objp->
radius/
MAX(1.0
f, En_objp->
radius + dist_to_enemy)) {
8768 scale = (scale - 0.6f) * 1.5
f;
8771 if (dist_to_enemy < pwip->max_speed * (1.0
f + scale)) {
8787 if (current_bank > -1) {
8796 if (current_bank >= 0) {
8816 firing_range *= 0.8f;
8829 else if (count >= 1) {
8832 if (hull_percent < 0.01
f)
8833 hull_percent = 0.01f;
8835 if (
frand() < 0.25
f/(30.0
f*hull_percent) * count)
8840 if (spawn_fire || (dist_to_enemy < firing_range)) {
8895 if(has_fired == -1){
8916 speed =
fl_sqrt(dist) * speed_scale;
8919 if (rdinfo && (rdinfo->submodel >= 0))
8923 switch (rdinfo->dock_mode)
8927 speed += (rdinfo->submodel_r * rdinfo->submodel_w) / (dist);
8933 speed += (
vm_vec_dist(&rdinfo->submodel_pos, &objp->
pos) * rdinfo->submodel_w);
8939 speed += other_obj_speed;
9008 if ((path_num >= 0) && (path_num < pm->n_paths))
9030 vec3d submodel_offset;
9031 vec3d local_p0, local_p1;
9076 vec3d docker_p0, docker_p1, docker_p0_norm;
9077 vec3d dockee_p0, dockee_p1, dockee_p0_norm;
9101 Assert( docker_index >= 0 );
9102 Assert( dockee_index >= 0 );
9116 vm_vec_avg(&docker_point, &docker_p0, &docker_p1);
9117 vm_vec_avg(&dockee_point, &dockee_p0, &dockee_p1);
9121 float submodel_radius = 0.0f;
9122 float submodel_omega = 0.0f;
9123 if ((dockee_rotating_submodel >= 0) && (dock_mode !=
DOA_DOCK_STAY))
9125 vec3d submodel_offset;
9126 vec3d dockpoint_temp;
9130 vm_vec_add(&submodel_pos, &dockee_objp->
pos, &submodel_offset);
9136 if ( pmi1->
submodel[dockee_rotating_submodel].
sii != NULL ) {
9141 vm_vec_avg(&dockpoint_temp, &dockee_p0, &dockee_p1);
9142 submodel_radius =
vm_vec_dist(&submodel_pos, &dockpoint_temp);
9148 rdinfo = &rdinfo_buf;
9153 rdinfo->
submodel = dockee_rotating_submodel;
9159 float speed_scale = 1.0f;
9164 switch (dock_mode) {
9175 vec3d omega_in, omega_out, vel_limit, acc_limit;
9176 float tdist, mdist, ss1;
9188 docker_objp->
orient = nm;
9197 ss1 = tdist/(10.0f * mdist);
9204 if (dockee_rotating_submodel >= 0)
9207 speed_scale *= 1.0f + ss1;
9212 fdist += 2.0f * mdist;
9226 vec3d omega_in, omega_out, vel_limit, acc_limit;
9238 docker_objp->
orient = nm;
9247 vec3d origin_docker_point, adjusted_docker_point, v_offset;
9254 vm_vec_sub(&origin_docker_point, &docker_point, &docker_objp->
pos);
9255 vm_vec_rotate(&adjusted_docker_point, &origin_docker_point, &m_offset);
9259 vm_vec_sub(&v_offset, &dockee_point, &adjusted_docker_point);
9262 docker_objp->
orient = dom;
9293 float dist, goal_dist;
9296 goal_dist = docker_objp->
radius + dockee_objp->
radius + 25.0f;
9305 float turn_time =
Ship_info[Ships[docker_objp->
instance].ship_info_index].srotation_time;
9312 if (dist > goal_dist/2)
9313 accel *= 1.2f - 0.5f*goal_dist/dist;
9348 object *attacking_objp;
9386 object *
objp, *objp2, *farthest_objp;
9388 float farthest_dist;
9392 farthest_dist = 9999999.9f;
9393 farthest_objp = NULL;
9408 if (dist < farthest_dist) {
9409 farthest_dist = dist;
9410 farthest_objp =
objp;
9418 if (farthest_objp != NULL) {
9478 if (guard_objp == hitter_objp) {
9563 int num_attacking_cur, num_attacking_new;
9566 if (num_attacking_cur > 1) {
9569 if (num_attacking_new < num_attacking_cur) {
9617 object *bomb_objp, *closest_bomb_objp=NULL;
9618 float dist, dist_to_guarding_obj,closest_dist_to_guarding_obj=999999.0f;
9645 if ( dist_to_guarding_obj < closest_dist_to_guarding_obj ) {
9646 closest_dist_to_guarding_obj = dist_to_guarding_obj;
9647 closest_bomb_objp = bomb_objp;
9652 if ( closest_bomb_objp ) {
9708 object *closest_asteroid_objp=NULL, *danger_asteroid_objp=NULL, *asteroid_objp;
9709 float dist_to_self, closest_danger_asteroid_dist=999999.0f, closest_asteroid_dist=999999.0f;
9718 if( dist_to_self < closest_danger_asteroid_dist ) {
9719 danger_asteroid_objp=asteroid_objp;
9720 closest_danger_asteroid_dist=dist_to_self;
9723 if ( dist_to_self < closest_asteroid_dist ) {
9726 closest_asteroid_dist = dist_to_self;
9727 closest_asteroid_objp = asteroid_objp;
9734 if ( danger_asteroid_objp ) {
9736 }
else if ( closest_asteroid_objp ) {
9756 if ( !bomb_found ) {
9781 *radius =
MAX(tempx, tempy);
9798 return extended_cylinder_z;
9818 vec3d axis_pt, r_vec, theta_vec;
9819 float radius, extended_z;
9829 if (objval > 0.5
f) {
9833 float min_guard_dist = radius + Pl_objp->
radius + 50.0f;
9834 float desired_guard_dist = min_guard_dist + 0.5f * ((1.0f + objval) *
MAX_GUARD_DIST);
9835 float max_guard_dist = min_guard_dist + 1.0f * ((1.0f + objval) *
MAX_GUARD_DIST);
9838 float min_z, max_z,
length;
9842 length = max_z - min_z;
9847 int time_choose =
int(floor(log(length * 0.001
f) / log(2.0f)));
9854 int inside = (extended_z > min_z) && (extended_z < min_z + length);
9858 if (cur_guard_rad < max_guard_dist) {
9859 if ( cur_guard_rad > min_guard_dist ) {
9866 if (extended_z < min_z) {
9881 if (extended_z < min_z) {
9899 float delta_z = desired_z - extended_z;
9900 float v_z = delta_z * 0.2f;
9903 }
else if (v_z > 20) {
9912 float delta_z = desired_z - extended_z;
9917 if ( (cur_guard_rad > max_guard_dist) || (extended_z < min_z) || (extended_z > max_z) ) {
9946 float dot_to_goal_point;
9988 float dist_to_guardobj;
9989 vec3d vec_to_guardobj;
10000 if (guard_objp == Pl_objp) {
10027 float dist_to_goal_point, dot_to_goal_point, accel_scale;
10045 accel_scale = (1.0f + dot_to_goal_point)/2.0
f;
10100 if (dist_to_guardobj < dist_to_goal_point) {
10106 if (speed > 10.0
f) {
10115 if (dist_to_goal_point > Pl_objp->
radius + 10.0f) {
10122 if (dot_to_goal_point > 0.8
f) {
10130 }
else if (guard_objp->
radius < 50.0f) {
10131 if (dist_to_goal_point > 15.0
f) {
10142 }
else if (dist_to_guardobj < Pl_objp->radius + guard_objp->
radius) {
10198 Assert(repaired_objp != NULL);
10205 if (p_index >= 0) {
10264 if (repair_objp != NULL) {
10269 if ( p_index >= 0 ) {
10277 if ( repair_objp ){
10294 if ( p_index >= 0 ) {
10320 if ( repair_objp ) {
10326 Assert( repaired_objp != NULL );
10368 Warning(
LOCATION,
"Normally dock indexes should be calculated for only AIS_DOCK_0 and AIS_UNDOCK_0. Trace out and debug.");
10376 Assert(docker_index >= 0);
10377 Assert(dockee_index >= 0);
10385 Warning(
LOCATION,
"Normally dock indexes should be calculated for only AIS_DOCK_0 and AIS_UNDOCK_0. Trace out and debug.");
10389 Assert(goal_objp != NULL);
10392 Assert(docker_index >= 0);
10393 Assert(dockee_index >= 0);
10400 Warning(
LOCATION,
"Normally dock indexes should be calculated for only AIS_DOCK_0 and AIS_UNDOCK_0. Additionally, dock indexes can't always be determined for AIS_UNDOCK_3 or AIS_UNDOCK_4. Trace out and debug.");
10547 float dist, max_dist,
scale;
10548 vec3d rand_vec, goal_pos, vec_to_goal;
10551 goal_objp = &
Objects[goal_objnum];
10558 if (
vm_vec_dot(&rand_vec, &vec_to_goal) > 1.0
f) {
10565 scale = dist - max_dist/2;
10571 if (max_dist < Pl_objp->radius + goal_objp->
radius + 25.0f)
10572 max_dist = Pl_objp->
radius + goal_objp->
radius + 25.0f;
10574 if (dist > max_dist) {
10586 vec3d *goalpos, *curpos;
10589 int collide_objnum;
10598 curpos = &cur_objp->
pos;
10599 radius = cur_objp->
radius;
10601 collide_objnum =
pp_collide_any(curpos, goalpos, radius, cur_objp, goal_objp, big_only_flag);
10603 if (collide_objnum != -1)
10606 return collide_objnum;
10676 Assert(goal_objp != NULL);
10678 char *goal_ship_class_name = goal_sip->
name;
10681 Warning(
LOCATION,
"Ship class %s has only %i points on dock path \"%s\". Recommended minimum number of points is 4. "\
10682 "Docking along that path will look strange. You may wish to edit the model.", goal_ship_class_name, aip->
path_length, goal_dock_path_name);
10756 if ( dist < tolerance) {
10795 if (dist < tolerance)
10833 if (aigp == NULL) {
10868 else if (dist > 5.0
f)
10961 float dist_to_dock;
11017 if (goal_objp == NULL)
11030 if (dist < Pl_objp->radius/2 + 5.0
f) {
11071 #define MAX_AI_DEBUG_RENDER_STUFF 100
11094 ss = AI_debug_render_stuff[
i].
ss;
11110 Num_AI_debug_render_stuff = 0;
11129 int enemies_present = -1;
11139 switch (psub->
type) {
11150 if(enemies_present == -1)
11152 enemies_present = 0;
11162 enemies_present = 1;
11165 enemies_present = 1;
11169 if(enemies_present==1)
11179 Warning(
LOCATION,
"Turret %s on ship %s has no firing points assigned to it.\nThis needs to be fixed in the model.\n", psub->
name, shipp->
ship_name );
11237 wingp = &
Wings[wingnum];
11262 wingp = &
Wings[wingnum];
11289 #define DEFAULT_WING_X_DELTA 1.0f
11290 #define DEFAULT_WING_Y_DELTA 0.25f
11291 #define DEFAULT_WING_Z_DELTA 0.75f
11292 #define DEFAULT_WING_MAG (fl_sqrt(DEFAULT_WING_X_DELTA*DEFAULT_WING_X_DELTA + DEFAULT_WING_Y_DELTA*DEFAULT_WING_Y_DELTA + DEFAULT_WING_Z_DELTA*DEFAULT_WING_Z_DELTA))
11294 #define MAX_FORMATION_ROWS 4
11303 Assert(wing_index >= 0);
11318 column = wi0 - k + row + 1;
11331 int wingnum = aip->
wing;
11338 max_radius = objp->
radius;
11343 if (o->
radius > max_radius)
11359 max_radius = objp->
radius;
11364 if (o->
radius > max_radius)
11385 if (formation_object_flag) {
11388 return gwlr_1(objp, aip);
11395 DCF(wing_y_scale,
"Adjusts the wing formation scale along the Y axis (Default is 2.0)")
11400 DCF(wing_scale,
"Adjusts the wing formation scale. (Default is 1.0f)")
11411 vec3d wing_delta, rotated_wing_delta;
11412 float wing_spread_size;
11428 vm_vec_add(result_pos, &leader_objp->
pos, &rotated_wing_delta);
11434 vec3d wing_delta, rotated_wing_delta;
11435 float wing_spread_size;
11442 vm_vec_add(result_pos, &leader_objp->
pos, &rotated_wing_delta);
11465 wingnum = aip->
wing;
11473 if (wing_index != 0)
11476 for (i=0; i<32; i++)
11509 wingnum = aip->
wing;
11517 if (wing_index != 0)
11597 Leader_chaos += fdot * speed_scale + udot * speed_scale;
11641 object *leader_objp;
11646 vec3d goal_point, future_goal_point_5, future_goal_point_2, future_goal_point_x, future_goal_point_1000x, vec_to_goal, dir_to_goal;
11647 float dot_to_goal, dist_to_goal, leader_speed;
11678 wingnum = aip->
wing;
11680 if (wingnum == -1) {
11716 Assert(leader_objp != NULL);
11720 if (wing_index == -1) {
11725 if (leader_objp == Pl_objp) {
11763 vec_to_goal.
xyz.x += 0.1f;
11770 int chaotic_leader = 0;
11775 bool ab_allowed =
false;
11783 float switch_value = 0.0f;
11792 if (dist_to_goal > 500.0
f) {
11796 if (percent_left > 30.0
f) {
11802 }
else if (dist_to_goal > 200.0
f) {
11803 if (dot_to_goal > -0.5
f) {
11806 if (range_speed > 0.0
f) {
11815 if ((percent_left > 30.0
f) && (Pl_objp->
phys_info.
speed < leader_speed)) {
11820 if ((Pl_objp->
phys_info.
speed > leader_speed + 1.5 * switch_value) || (dot_to_goal < 0.2f))
11827 if (leader_speed > 10.0
f)
11843 if (chaotic_leader) {
11848 }
else if (dist_to_goal > 75.0
f) {
11852 if (range_speed > 0.0
f) {
11853 delta_speed = dist_to_goal_2/500.0f * range_speed;
11861 if ((percent_left > 30.0
f) && (Pl_objp->
phys_info.
speed < leader_speed - 0.5 * switch_value)) {
11866 if ((Pl_objp->
phys_info.
speed > leader_speed + 0.95 * switch_value) || (dot_to_goal < 0.4f))
11871 if (dot_to_goal < 0.0
f) {
11872 delta_speed = -delta_speed;
11873 if (-delta_speed > leader_speed/2)
11874 delta_speed = -leader_speed/2;
11877 if (leader_speed < 5.0
f)
11878 if (delta_speed < 5.0
f)
11879 delta_speed = 5.0f;
11881 float scale = dot_to_f2;
11890 if (leader_speed < 5.0
f) {
11894 if ((dist_to_goal > 10.0
f) || ((Pl_objp->
phys_info.
speed > leader_speed + 2.5f) && (dot_to_goal > 0.5f))) {
11906 }
else if (dist_to_goal > 10.0
f) {
11911 if (dist_to_goal > 25.0
f) {
11912 if (dot_to_goal < 0.3
f)
11915 dv = dot_to_goal - 0.2f;
11923 if (range_speed > 0.0
f) {
11930 if ((percent_left > 30.0
f) && (Pl_objp->
phys_info.
speed < leader_speed - 0.75 * switch_value)) {
11935 if ((Pl_objp->
phys_info.
speed > leader_speed + 0.95 * switch_value) || (dot_to_goal < 0.7f))
11951 if (range_speed > 0.0
f) {
11958 if ((percent_left > 30.0
f) && (Pl_objp->
phys_info.
speed < leader_speed - 0.75 * switch_value)) {
11963 if ((Pl_objp->
phys_info.
speed > leader_speed + 0.75 * switch_value) || (dot_to_goal < 0.8f))
11976 if (up_dot < 0.996
f) {
11979 vec3d angular_accel;
11984 Pl_objp->
orient = new_orient;
11998 static bool rearm_eta_found=
false;
12006 int support_objnum;
12012 if (support_objnum == -1)
12029 rearm_eta_found =
true;
12064 rearm_eta_found =
false;
12116 object *weapon_objp;
12139 if (fire_chance <
r) {
12184 #define CHASE_CIRCLE_DIST 100.0f
12188 float dist_to_goal;
12189 float target_speed;
12222 if (dist < ignore_objp->radius*2 + 1500.0
f) {
12224 if (dist < ignore_objp->radius*2 + 1300.0
f)
12225 target_speed = sip->
max_speed * (1.25f - dist/(ignore_objp->
radius*2 + 1500.0f));
12237 #define SHIELD_BALANCE_RATE 0.2f // 0.1f -> takes 10 seconds to equalize shield.
12245 float transfer_amount;
12246 float transfer_delta;
12247 float max_quadrant_strength;
12251 transfer_amount = 0.0f;
12258 if (i != quadrant_num) {
12261 transfer_amount += transfer_delta;
12274 float shield_strength_avg;
12370 object *missile_objp;
12382 if (dist < dist2) {
12383 switch (aip->
mode) {
12469 switch (aip->
mode) {
12512 if ((t > 0.0
f) && (t < 1.0
f)) {
12520 switch (aip->
mode) {
12634 int path_index, bay_path;
12641 if ( parent_objnum == -1 ) {
12646 object *parent_objp = &
Objects[parent_objnum];
12652 if ( bay == NULL ) {
12664 if (allowed_path_mask != 0)
12668 memset(allowed_bay_paths, 0,
sizeof(allowed_bay_paths));
12672 if (allowed_path_mask & (1 << i))
12674 allowed_bay_paths[num_allowed_paths] =
i;
12675 num_allowed_paths++;
12692 if ( path_index == -1 )
12713 next_point = &pnp->
pos;
12754 Assert( Pl_objp != NULL );
12772 if ( !parent_died ) {
12778 if ( !parent_died ) {
12785 if ( parent_died ) {
12826 int i, j, best_path, best_free_path;
12827 float dist, min_dist, min_free_dist;
12834 best_free_path = best_path = -1;
12835 min_free_dist = min_dist = 1e20f;
12842 if ((allowed_path_mask != 0) && !(allowed_path_mask & (1 << i)))
12846 for ( j = 0; j < mp->
nverts; j++ )
12850 if (dist < min_dist)
12859 if (dist < min_free_dist)
12861 min_free_dist = dist;
12862 best_free_path =
i;
12868 if (best_free_path >= 0)
12870 return best_free_path;
12885 int path_index = -1;
12886 int ship_bay_path = -1;
12891 if ( parent_objnum < 0 )
12893 Warning(
LOCATION,
"In ai_acquire_depart_path(), specified a negative object number for the parent ship! (Departing ship is %s.) Looking for another ship...", shipp->
ship_name);
12904 if ( parent_objnum < 0 )
12907 object *parent_objp = &
Objects[parent_objnum];
12919 if ( ship_bay_path < 0 )
12926 if ( path_index == -1 ) {
12931 Ships[parent_objp->
instance].bay_doors_wanting_open++;
12938 Assert(path_index < pm->n_paths);
12959 int anchor_shipnum;
12973 mprintf((
"Aborting bay departure!\n"));
12982 if ( Ships[anchor_shipnum].bay_doors_status !=
MA_POS_READY )
13001 if ( bay != NULL ) {
13031 switch (aip->
mode) {
13146 return (
int) ((1.0f -
t) * 3);
13244 desire += (
int) ((1.0f -
r) * 3.0
f);
13271 bool try_to_rearm =
false;
13276 try_to_rearm =
true;
13279 try_to_rearm =
true;
13280 }
else if (desire >= 3) {
13285 try_to_rearm =
true;
13290 if (try_to_rearm) {
13429 float speed, goal_speed;
13469 float nearest_dist = 999999.9f;
13470 int nearest_index = -1;
13490 if (dist < nearest_dist) {
13491 nearest_dist = dist;
13492 nearest_index = mo->
objnum;
13497 return nearest_index;
13501 #define EVADE_SHOCKWAVE_DAMAGE_THRESHOLD 100.0f
13535 float nearest_dist = 999999.9f;
13536 int nearest_index = -1;
13556 if (dist < nearest_dist) {
13557 nearest_dist = dist;
13558 nearest_index = so->
objnum;
13564 return nearest_index;
13576 if (shockwave_weapon == -1) {
13595 object *target_ship_obj = NULL;
13604 vec3d expected_pos;
13623 expected_pos = target_ship_obj->
pos;
13636 time_scale = weaponp->
lifeleft/2.0f;
13648 vec3d vec_from_exp;
13665 if (shockwave_ship == -1) {
13675 if (ship_objp == objp) {
13726 ? ((
float) aip->
ai_class/4.0f + 0.25f)
13732 if (!
aas_1(objp, aip, &safe_pos)) {
13741 vec3d vec_to_safe_pos;
13747 if (dot_to_goal < -0.5
f)
13751 if (dot_to_goal > 0.2
f) {
13785 object *repair_objp;
13800 if (dist > 200.0
f) {
13815 Assertion(objp->
type ==
OBJ_SHIP,
"ai_maybe_self_destruct() can only be called with objects that are ships!");
13854 if ( target_objnum < 0 ) {
13858 objp = &
Objects[target_objnum];
13929 switch (aip->
mode) {
13979 Pl_objp = &Objects[objnum];
14029 Assert(objnum != target_objnum);
14054 if (target_objnum != -1) {
14059 if (target_objnum >= 0)
14061 En_objp = &Objects[target_objnum];
14066 }
else if (target_objnum >= 0) {
14067 En_objp = &Objects[target_objnum];
14086 }
else if (dist < 100) {
14107 if (En_objp == NULL) {
14117 if (target_objnum != -1) {
14140 if ( subsys_type != -1 ) {
14143 if ( new_subsys != NULL ) {
14162 int in_formation = 0;
14167 if ( !in_formation ) {
14245 Assert( ai_index >= 0 );
14252 memset( &AI_ci, 0,
sizeof(AI_ci) );
14256 AI_ci.
pitch = 0.0f;
14267 switch (aip->
mode) {
14302 int i, ship_index, ai_index, ship_type;
14467 for (
int i = 0;
i < 31;
i++)
14469 int flag = (1 <<
i);
14471 if (override_set & flag)
14473 if (override_flags & flag)
14478 if (base_flags & flag)
14604 #define FRIENDLY_DAMAGE_THRESHOLD 50.0f // Display a message at this threshold. Note, this gets scaled by Skill_level
14677 if (shipp_hitter->
team != shipp_hit->
team) {
14687 if ((time_since_last_hit >= 0.0
f) && (time_since_last_hit < 10000.0
f)) {
14688 if (time_since_last_hit > 60.0
f) {
14691 }
else if (time_since_last_hit > 2.0
f) {
14717 factor =
MIN(100.0
f, factor);
14825 if (bank_index != -1) {
14854 if (collision_normal) {
14866 if (collision_normal) {
14867 direction = *collision_normal;
14893 int dont_count =
FALSE;
14895 int parent = other_obj->
parent;
14916 float lethality = 0.025f * damage;
14936 int hitter_objnum = -2;
14937 object *objp_hitter = NULL;
14949 hitter_objnum = hit_objp->
parent;
14951 if (hitter_objnum == -1) {
14954 objp_hitter = &
Objects[hitter_objnum];
14956 objp_hitter = hit_objp;
14961 Assert(objp_hitter != NULL);
14983 if(hit_objp->
parent < 0){
14990 hitter_objnum = hit_objp->
parent;
14992 objp_hitter = &
Objects[hitter_objnum];
15028 objp_hitter = hit_objp;
15044 Assert(objp_hitter != NULL);
15075 Assert(hitter_objnum != -2);
15107 switch (aip->
mode) {
15237 object *other_objp;
15264 shipp = &Ships[other_objp->
instance];
15307 object *docked_objp = ptr->docked_objp;
15308 int docker_index = ptr->dockpoint_used;
15340 ship *requester_shipp;
15363 object *repair_objp;
15391 nprintf((
"AI",
"Not aborting rearm since already undocking\n"));
15423 ship *support_shipp, *requester_shipp;
15424 ai_info *support_aip, *requester_aip;
15448 object *
objp = NULL;
15449 ship *requester_shipp;
15471 if (result == 0 || result == 2) {
15477 else if (result == 1 || result == 3) {
15485 Assertion(
false,
"This case should have already been caught by the is_support_allowed precheck!");
15518 if ( dockbay_index < 0 || dockee_objp == NULL ) {
15533 if(pm->
n_docks <= dockbay_index){
15585 int wing_index, time;
15591 wing_index = shipp->
ship_name[6] -
'1';
15600 int modulus = 17 + wing_index*3;
15602 if ((time % modulus) < 2)
void mc_info_init(mc_info *mc)
float ai_stalemate_time_thresh[NUM_SKILL_LEVELS]
int ai_profile_flags2_set
void dock_dead_dock_objects(object *objp1, int dockpoint1, object *objp2, int dockpoint2)
float ai_glide_strafe_percent
void ai_update_aim(ai_info *aip)
void ai_attack_wing(object *attacker, int wingnum)
int model_collide(mc_info *mc_info_obj)
char Parse_names[MAX_SHIPS+MAX_WINGS][NAME_LENGTH]
#define MESSAGE_PRIORITY_NORMAL
bool model_anim_start_type(ship_subsys *pss, int animation_type, int subtype, int direction, bool instant)
#define SHIP_GET_UNSILENCED
#define MESSAGE_TIME_IMMEDIATE
int timestamp(int delta_ms)
void ai_chase_eb(ai_info *aip, ship_info *sip, vec3d *predicted_enemy_pos, float dist_to_enemy)
float vm_vec_dot_to_point(const vec3d *dir, const vec3d *p1, const vec3d *p2)
#define MULTIPLAYER_CLIENT
int chance_to_use_missiles_on_plr[NUM_SKILL_LEVELS]
float get_world_closest_box_point_with_delta(vec3d *closest_box_point, object *box_obj, vec3d *start_point, int *is_inside, float delta)
struct eval_nearest_objnum eval_nearest_objnum
#define SUBSYSTEM_NAVIGATION
float get_max_shield_quad(object *objp)
int ai_find_shockwave_weapon(object *objp, ai_info *aip)
#define TRIGGER_TYPE_DOCKING_STAGE_2
void ship_set_subsystem_strength(ship *shipp, int type, float strength)
void ai_set_guard_wing(object *objp, int wingnum)
#define DEFAULT_WING_Y_DELTA
#define AIS_STRAFE_RETREAT1
model_subsystem * system_info
#define STEALTH_FULLY_TARGETABLE
weapon Weapons[MAX_WEAPONS]
int primary_bank_weapons[MAX_SHIP_PRIMARY_BANKS]
float ai_accuracy[NUM_SKILL_LEVELS]
fix avoid_check_timestamp
float ai_ship_fire_secondary_delay_scale_friendly
void ai_mission_goal_complete(ai_info *aip)
void ai_process(object *obj, int ai_index, float frametime)
#define MAX_SHIP_PRIMARY_BANKS
int ai_find_shockwave_ship(object *objp, ai_info *aip)
EModelAnimationPosition turret_animation_position
void init_semirand()
Initialize Semirand array. Doesn't have to be called.
void ai_cleanup_rearm_mode(object *objp)
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 AIPF_FIX_LINKED_PRIMARY_BUG
float vm_vec_mag_quick(const vec3d *v)
int ship_engine_ok_to_warp(ship *sp)
matrix * vm_matrix_x_matrix(matrix *dest, const matrix *src0, const matrix *src1)
float glide_strafe_percent[NUM_SKILL_LEVELS]
int iff_get_attacker_mask(int attackee_team)
void mission_log_add_entry(int type, char *pname, char *sname, int info_index)
float ship_get_max_speed(ship *shipp)
#define MAX_IGNORE_NEW_OBJECTS
control_info ai_override_ci
#define AIG_TYPE_EVENT_WING
void vm_vec_scale_add(vec3d *dest, const vec3d *src1, const vec3d *src2, float k)
#define MISSION_FLAG_FULLNEB
#define AI_PATH_MODE_ALT1
int compute_num_homing_objects(object *target_objp)
int secondary_select_timestamp
float ai_glide_strafe_percent[NUM_SKILL_LEVELS]
float frand_range(float min, float max)
Return a floating point number in the range min..max.
int static_rand_alt()
Get a random integer between 1 and RND_MAX.
int set_target_objnum(ai_info *aip, int objnum)
int might_collide_with_ship(object *obj1, object *obj2, float dot_to_enemy, float dist_to_enemy, float duration)
char Game_current_mission_filename[MAX_FILENAME_LEN]
polymodel * model_get(int model_num)
ubyte bay_doors_launched_from
int obj_team(object *objp)
weapon_info Weapon_info[MAX_WEAPON_TYPES]
submodel_instance_info * sii
void update_min_max(float val, float *min, float *max)
float nearest_locked_distance
void ai_good_secondary_time(int team, int weapon_index, int max_fire_count, char *shipname)
float shield_get_strength(object *objp)
float ship_fire_delay_scale_friendly[NUM_SKILL_LEVELS]
ship_subsys * set_targeted_subsys(ai_info *aip, ship_subsys *new_subsys, int parent_objnum)
SCP_vector< game_snd > Snds
#define DELAY_TARGET_TIME
float vm_vec_mag(const vec3d *v)
#define SF2_NO_DISABLED_SELF_DESTRUCT
#define WIF_LOCKED_HOMING
#define AIPF_SMART_SECONDARY_WEAPON_SELECTION
void validate_mode_submode(ai_info *aip)
float ai_endangered_by_weapon(ai_info *aip)
float stalemate_time_thresh[NUM_SKILL_LEVELS]
void ai_add_ship_goal_player(int type, int mode, int submode, char *shipname, ai_info *aip)
#define SF2_NO_SUBSPACE_DRIVE
float ship_get_warpout_speed(object *objp)
int collide_predict_large_ship(object *objp, float distance)
void change_acceleration(ai_info *aip, float delta_accel)
int avoid_player(object *objp, vec3d *goal_pos)
int mission_do_departure(object *objp, bool goal_is_to_warp)
int path_subsystem_next_check
#define MISSION_FLAG_USE_AP_CINEMATICS
void ai_preprocess_ignore_objnum(object *objp, ai_info *aip)
float ai_get_away_chance[NUM_SKILL_LEVELS]
float turn_time_scale[NUM_SKILL_LEVELS]
void ai_ignore_object(object *ignorer, object *ignored, int ignore_new)
float ship_max_shield_strength
#define AITTV_IGNORE_BANK
int next_primary_fire_stamp[MAX_SHIP_PRIMARY_BANKS]
void parse_int_list(int *ilist, int size)
#define AI_PATH_MODE_NORMAL
#define MSS_FLAG2_DESTROYED_ROTATION
void render_path_points(object *objp)
int ai_return_path_num_from_dockbay(object *dockee_objp, int dockbay_index)
#define STEALTH_MAX_VIEW_DIST
int ai_chance_to_use_missiles_on_plr[NUM_SKILL_LEVELS]
void init_aip_from_class_and_profile(ai_info *aip, ai_class *aicp, ai_profile_t *profile)
#define AIF_TRYING_UNSUCCESSFULLY_TO_WARP
void mabs_pick_goal_point(object *objp, object *big_objp, vec3d *collision_point, vec3d *avoid_pos)
float vm_vec_normalize_quick(vec3d *src)
#define INSTRUCTOR_SHIP_NAME
int next_secondary_fire_stamp[MAX_SHIP_SECONDARY_BANKS]
float ai_glide_attack_percent[NUM_SKILL_LEVELS]
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
#define MESSAGE_INSTRUCTOR_ATTACK
#define STI_AI_AUTO_ATTACKS
void ai_start_waypoints(object *objp, waypoint_list *wp_list, int wp_flags)
void _cdecl void void _cdecl void _cdecl void _cdecl WarningEx(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
void update_aspect_lock_information(ai_info *aip, vec3d *vec_to_enemy, float dist_to_enemy, float enemy_radius)
int detail[MAX_MODEL_DETAIL_LEVELS]
int ai_set_attack_subsystem(object *objp, int subnum)
#define MISSION_FLAG_SUPPORT_REPAIRS_HULL
#define TRIGGER_TYPE_DOCKING_STAGE_1
#define MESSAGE_SUPPORT_KILLED
int ship_fire_primary(object *obj, int stream_weapons, int force)
int is_training_mission()
fix afterburner_stop_time
void ai_emerge_bay_path_cleanup(ai_info *aip)
int ship_stop_fire_primary(object *obj)
float link_energy_levels_always[NUM_SKILL_LEVELS]
#define AIPF_SMART_SUBSYSTEM_TARGETING_FOR_TURRETS
#define DEFAULT_WING_Z_DELTA
float dock_move_towards_point(object *objp, vec3d *start, vec3d *finish, float speed_scale, float other_obj_speed=0.0f, rotating_dockpoint_info *rdinfo=NULL)
void multi_maybe_send_repair_info(object *dest_objp, object *source_objp, int code)
float ai_endangered_time(object *ship_objp, object *weapon_objp)
float bay_arrive_speed_mult
void ai_add_goal_ship_internal(ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate)
pnode Path_points[MAX_PATH_POINTS]
#define LOG_SHIP_UNDOCKED
#define SM_EVADE_SQUIGGLE
void ai_form_on_wing(object *objp, object *goal_objp)
int get_nearest_bbox_point(object *ship_objp, vec3d *start, vec3d *box_pt)
int secondary_bank_start_ammo[MAX_SHIP_SECONDARY_BANKS]
struct vec3d::@225::@227 xyz
int next_rearm_request_timestamp
#define AIGF_DEPART_SOUND_PLAYED
float bay_depart_speed_mult
void static_randvec(int num, vec3d *vp)
[To be described]
float link_ammo_levels_maybe[NUM_SKILL_LEVELS]
object * get_wing_leader(int wingnum)
void ai_warp_out(object *objp)
SCP_vector< huge_fire_info > Ai_huge_fire_info
void mission_goal_fail_all()
void ai_find_path(object *pl_objp, int objnum, int path_num, int exit_flag, int subsys_path)
int find_ignore_new_object_index(ai_info *aip, int objnum)
void ai_start_fly_to_ship(object *objp, int shipnum)
void set_accel_for_target_speed(object *objp, float tspeed)
matrix * vm_copy_transpose(matrix *dest, const matrix *src)
bool dock_check_find_direct_docked_object(object *objp, object *other_objp)
ai_info Ai_info[MAX_AI_INFO]
float compute_time_to_enemy(float dist_to_enemy, object *pobjp)
float afterburner_fuel_capacity
vec3d * vm_vec_rotate(vec3d *dest, const vec3d *src, const matrix *m)
#define Assertion(expr, msg,...)
#define REPAIR_INFO_COMPLETE
int mrs_subsystem(ship *shipp, int type)
int dock_find_dockpoint_used_by_object(object *objp, object *other_objp)
#define END_OF_LIST(head)
float ai_link_energy_levels_always
#define SF2_NAVPOINT_CARRY
int find_parent_rotating_submodel(polymodel *pm, int dock_index)
EModelAnimationPosition bay_doors_status
#define STI_AI_GUARDS_ATTACK
void render_all_subsys_paths(object *objp)
int big_recover_timestamp
#define AI_GOAL_DISARM_SHIP
void ai_do_objects_undocked_stuff(object *docker, object *dockee)
void ai_safety_circle_spot(object *objp)
ship_subsys * targeted_subsys
void ai_ignore_wing(object *ignorer, int wingnum)
void ai_maybe_announce_shockwave_weapon(object *firing_objp, int weapon_index)
void ai_maybe_evade_locked_missile(object *objp, ai_info *aip)
#define UNINITIALIZED_VALUE
int ai_good_time_to_rearm(object *objp)
float ai_turret_max_aim_update_delay
void vm_vec_scale_add2(vec3d *dest, const vec3d *src, float k)
GLenum GLuint GLenum GLsizei const GLchar * message
int vector_object_collision(vec3d *start_pos, vec3d *end_pos, object *objp, float radius_scale)
float dock_calc_docked_speed(object *objp)
#define MAX_SHIP_BAY_PATHS
int ship_fire_secondary(object *obj, int allow_swarm)
void ai_maybe_self_destruct(object *objp, ai_info *aip)
#define MAX_UNDOCK_ABORT_SPEED
#define WIF_HOMING_ASPECT
void ai_clear_ship_goals(ai_info *aip)
float ai_stalemate_time_thresh
void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
int g3_draw_line(vertex *p0, vertex *p1)
#define MAX_SHIPS_PER_WING
char dockee_point[NAME_LENGTH]
std::basic_string< char, std::char_traits< char >, std::allocator< char > > SCP_string
int aas_1(object *objp, ai_info *aip, vec3d *safe_pos)
#define AIPF_USE_ADDITIVE_WEAPON_VELOCITY
void ai_set_guard_vec(object *objp, object *guard_objp)
int ship_navigation_ok_to_warp(ship *sp)
void ai_add_rearm_goal(object *requester_objp, object *support_objp)
int ai_select_primary_weapon_OLD(object *objp, object *other_objp, int flags)
GLenum GLenum GLenum GLenum GLenum scale
int current_secondary_bank
GLfloat GLfloat GLfloat v2
#define MESSAGE_HAMMER_SWINE
float beam_get_ship_damage(beam *b, object *objp)
char stamp[STAMP_STRING_LENGTH]
int required_string_either(char *str1, char *str2)
Checks for one of two required strings.
int ai_formation_object_get_slotnum(int objnum, object *objp)
int Debug_render_wing_phantoms
void process_friendly_hit_message(int message, object *objp)
void ai_set_positions(object *pl_objp, object *en_objp, ai_info *aip, vec3d *player_pos, vec3d *enemy_pos)
#define STEALTH_NOT_IN_FRUSTUM
float ai_max_aim_update_delay
int is_preferred_weapon(int weapon_num, object *firer_objp, object *target_objp)
int objects_will_collide(object *A, object *B, float duration, float radius_scale)
#define AIF_USE_STATIC_PATH
#define SUBSYSTEM_GAS_COLLECT
void ship_get_global_turret_info(object *objp, model_subsystem *tp, vec3d *gpos, vec3d *gvec)
#define TRIGGER_TYPE_DOCKING_STAGE_3
#define NEXT_REARM_TIMESTAMP
SCP_list< waypoint_list > Waypoint_lists
float vm_vec_mag_squared(const vec3d *v)
float ship_fire_secondary_delay_scale_friendly[NUM_SKILL_LEVELS]
void ai_rearm_repair(object *objp, int docker_index, object *goal_objp, int dockee_index)
float ai_glide_attack_percent
vec3d last_predicted_enemy_pos
int ai_issue_rearm_request(object *requester_objp)
void ai_attack_object(object *attacker, object *attacked, ship_subsys *ssp)
int ai_need_new_target(object *pl_objp, int target_objnum)
float ai_random_sidethrust_percent
#define MAX_EMP_INACCURACY
#define AIF_FORMATION_OBJECT
float ai_cmeasure_fire_chance[NUM_SKILL_LEVELS]
#define AIPF_ALLOW_VERTICAL_DODGE
#define DCF(function_name, help_text)
The potent DCF macro, used to define new debug commands for the console.
#define AIPF_HUGE_TURRET_WEAPONS_IGNORE_BOMBS
#define WIF2_CAPITAL_PLUS
#define CLAMP(x, min, max)
void find_adjusted_dockpoint_info(vec3d *global_p0, vec3d *global_p1, vec3d *global_p0_norm, object *objp, polymodel *pm, int modelnum, int submodel, int dock_index)
fix ai_predict_position_delay
void ship_actually_depart(int shipnum, int method)
iff_info Iff_info[MAX_IFFS]
int iff_get_attackee_mask(int attacker_team)
#define AIG_TYPE_PLAYER_SHIP
#define AIPF_NO_MIN_DOCK_SPEED_CAP
int num_ships_attacking(int target_objnum)
void ai_balance_shield(object *objp)
#define SUBSYSTEM_COMMUNICATION
void gr_set_color(int r, int g, int b)
void ai_do_safety(object *objp)
int get_available_secondary_weapons(object *objp, int *outlist, int *outbanklist)
SCP_vector< waypoint > & get_waypoints()
void ai_chase_big_approach_set_goal(vec3d *goal_pos, object *attack_objp, object *target_objp, float *accel)
#define AI_ACTIVE_GOAL_DYNAMIC
void ai_evade_object(object *evader, object *evaded)
float ai_random_sidethrust_percent[NUM_SKILL_LEVELS]
int abort_rearm_timestamp
#define CIRCLE_STRAFE_MAX_DIST
GLenum GLenum GLvoid * row
player Players[MAX_PLAYERS]
void maybe_process_friendly_hit(object *objp_hitter, object *objp_hit, object *objp_weapon)
int object_is_docked(object *objp)
void model_find_submodel_offset(vec3d *outpnt, int model_num, int sub_model_num)
int Num_alloced_ai_classes
int mission_remove_scheduled_repair(object *objp)
fix next_predict_pos_time
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
#define MAX_SHIP_SECONDARY_BANKS
void model_instance_find_world_point(vec3d *outpnt, vec3d *mpnt, int model_instance_num, int submodel_num, const matrix *objorient, const vec3d *objpos)
matrix * vm_transpose(matrix *m)
void add_path_point(vec3d *pos, int path_num, int path_index, int modify_index)
int stealth_last_cheat_visible_stamp
void send_ai_info_update_packet(object *objp, char what, object *other_objp)
#define AIF_TEMPORARY_IGNORE
float ai_turret_max_aim_update_delay[NUM_SKILL_LEVELS]
void afterburners_stop(object *objp, int key_released)
fix friendly_last_hit_time
#define MESSAGE_INSTRUCTOR_HIT
int ai_select_primary_weapon(object *objp, object *other_objp, int flags)
matrix * vm_vector_2_matrix(matrix *m, const vec3d *fvec, const vec3d *uvec, const vec3d *rvec)
int ok_to_target_timestamp
float ship_get_subsystem_strength(ship *shipp, int type)
void hud_support_view_stop(int stop_now)
Stop displaying the support view pop-up.
void ai_get_dock_goal_indexes(object *objp, ai_info *aip, ai_goal *aigp, object *goal_objp, int &docker_index, int &dockee_index)
int repair_penalty[NUM_SKILL_LEVELS]
void vm_vec_add2(vec3d *dest, const vec3d *src)
float ai_circle_strafe_percent
float gwlr_1(object *objp, ai_info *aip)
float ai_matrix_dist(matrix *mat1, matrix *mat2)
float stealth_sweep_box_size
void ai_update_lethality(object *pship_obj, object *other_obj, float damage)
ship_subsys * ship_get_indexed_subsys(ship *sp, int index, vec3d *attacker_pos)
GLdouble GLdouble GLdouble r
dock_instance * dock_list
void ship_maybe_tell_about_low_ammo(ship *sp)
#define CHASE_CIRCLE_DIST
struct matrix::@228::@230 vec
#define AIPF_PREVENT_TARGETING_BOMBS_BEYOND_RANGE
int maybe_avoid_big_ship(object *objp, object *ignore_objp, ai_info *aip, vec3d *goal_point, float delta_time)
void ai_cleanup_dock_mode_objective(object *objp)
float ship_max_hull_strength
int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers)
void vm_vec_scale(vec3d *dest, float s)
int timestamp_until(int stamp)
void ai_cruiser_chase_set_goal_pos(vec3d *goal_pos, object *pl_objp, object *en_objp)
int g3_draw_sphere(vertex *pnt, float rad)
int check_ok_to_fire(int objnum, int target_objnum, weapon_info *wip)
#define AIS_STRAFE_POSITION
int compact_ignore_new_objects(ai_info *aip, int force=0)
int primary_bank_ammo[MAX_SHIP_PRIMARY_BANKS]
#define SIF_AVOID_SHOCKWAVE
#define AIPF_ALLOW_RAPID_SECONDARY_DUMBFIRE
#define SW_FLAG_TURRET_LOCK
void parse_float_list(float *plist, int size)
#define SHIP_DEPARTED_BAY
void ai_update_danger_weapon(int attacked_objnum, int weapon_objnum)
int secondary_bank_capacity[MAX_SHIP_SECONDARY_BANKS]
int ai_guard_find_nearby_bomb(object *guarding_objp, object *guarded_objp)
#define AIF_USE_EXIT_PATH
#define TRIGGER_TYPE_DOCKED
int ai_fire_primary_weapon(object *objp)
void ai_do_stay_near(object *objp, object *other_objp, float dist)
#define DEFAULT_WING_X_DELTA
ai_profile_t * ai_profile
#define AIF_AVOID_SHOCKWAVE_WEAPON
int self_destruct_timestamp
void ai_debug_render_stuff()
float get_hull_pct(object *objp)
void dock_undock_objects(object *objp1, object *objp2)
void ai_choose_secondary_weapon(object *objp, ai_info *aip, object *en_objp)
#define strnicmp(s1, s2, n)
#define AIPF2_FIX_AI_PATH_ORDER_BUG
int is_ignore_object(ai_info *aip, int objnum, int just_the_original=0)
void guard_object_was_hit(object *guard_objp, object *hitter_objp)
#define AIPF2_ALL_SHIPS_MANAGE_SHIELDS
int bay_doors_anim_done_time
float compute_incoming_payload(object *target_objp)
float ai_get_weapon_dist(ship_weapon *swp)
int maybe_resume_previous_mode(object *objp, ai_info *aip)
#define AIPF2_NO_SPECIAL_PLAYER_AVOID
ai_goal goals[MAX_AI_GOALS]
int snd_play_3d(game_snd *gs, vec3d *source_pos, vec3d *listen_pos, float radius, vec3d *source_vel, int looping, float vol_scale, int priority, vec3d *sound_fvec, float range_factor, int force, bool is_ambient)
int rand_chance(float frametime, float chance)
Call this in the frame interval to get TRUE chance times per second.
void ai_transfer_shield(object *objp, int quadrant_num)
float time_enemy_in_range
void remove_farthest_attacker(int objnum)
float primary_ammo_burst_mult[NUM_SKILL_LEVELS]
float set_secondary_fire_delay(ai_info *aip, ship *shipp, weapon_info *swip, bool burst)
void ship_maybe_ask_for_help(ship *sp)
void accelerate_ship(ai_info *aip, float accel)
int stealth_last_visible_stamp
#define AIF_BIG_SHIP_COLLIDE_RECOVER_1
int ai_avoid_shockwave(object *objp, ai_info *aip)
void set_aic_flag(ai_class *aicp, char *name, int flag, int type)
void stuff_string(char *outstr, int type, int len, char *terminators)
#define TRIGGER_TYPE_DOCK_BAY_DOOR
int ship_get_SIF(ship *shipp)
ship_subsys * last_subsys_target
float turn_toward_tangent_with_axis(object *objp, object *center_objp, float radius)
float get_skill_stealth_dist_scaler()
#define MESSAGE_REPAIR_ABORTED
int ship_get_random_player_wing_ship(int flags, float max_dist, int persona_index, int get_first, int multi_team)
float ai_link_ammo_levels_maybe
vec3d big_collision_normal
void vm_vec_sub2(vec3d *dest, const vec3d *src)
float turn_towards_tangent(object *objp, vec3d *point, float radius)
void hud_lock_reset(float lock_time_scale)
float ai_ship_fire_delay_scale_friendly
float ai_ship_fire_secondary_delay_scale_hostile
#define AIPF_DONT_INSERT_RANDOM_TURRET_FIRE_DELAY
#define REPAIR_INFO_ONWAY
void hud_support_view_abort()
submodel_instance * submodel
int ai_find_closest_depart_path(ai_info *aip, polymodel *pm, int allowed_path_mask)
fix path_next_create_time
#define SF_HIDDEN_FROM_SENSORS
void copy_xlate_model_path_points(object *objp, model_path *mp, int dir, int count, int path_num, pnode *pnp, int randomize_pnt=-1)
int has_preferred_secondary(object *objp, object *en_objp, ship_weapon *swp)
void project_point_to_perimeter(vec3d *perim_point, vec3d *pos, float radius, vec3d *vp)
void do_random_sidethrust(ai_info *aip, ship_info *sip)
void force_avoid_player_check(object *objp, ai_info *aip)
int danger_weapon_signature
float ai_ship_fire_delay_scale_friendly[NUM_SKILL_LEVELS]
void ai_set_goal_maybe_abort_dock(object *objp, ai_info *aip)
ubyte g3_rotate_vertex(vertex *dest, const vec3d *src)
void ai_do_repair_frame(object *objp, ai_info *aip, float frametime)
char * Mode_text[MAX_AI_BEHAVIORS]
vec3d norm[MAX_DOCK_SLOTS]
void ai_dock_with_object(object *docker, int docker_index, object *dockee, int dockee_index, int dock_type)
int required_string(const char *pstr)
void ai_disband_formation(int wingnum)
int static_rand_timed(int num, int modulus)
void bisect_chord(vec3d *p0, vec3d *p1, vec3d *centerp, float radius)
int engine_recharge_index
void ai_stay_still(object *still_objp, vec3d *view_pos)
#define SF_PRIMARY_LINKED
float ai_link_energy_levels_always[NUM_SKILL_LEVELS]
void hud_support_view_start()
Start displaying the support view pop-up. This will remain up until hud_support_view_stop() is called...
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
#define AIPF2_AI_AIMS_FROM_SHIP_CENTER
void get_behind_ship(ai_info *aip, ship_info *sip, float dist_to_enemy)
float ai_stalemate_dist_thresh
#define MAX_AI_DEBUG_RENDER_STUFF
int model_anim_get_time_type(ship_subsys *pss, int animation_type, int subtype)
int ai_near_full_strength(object *objp)
ship_subsys * ship_return_next_subsys(ship *shipp, int type, vec3d *attacker_pos)
#define AIG_TYPE_PLAYER_WING
float vm_vec_normalized_dir(vec3d *dest, const vec3d *end, const vec3d *start)
int shield_manage_timestamp
SCP_map< int, int > autopilot_wings
int bay_doors_wanting_open
object * dock_get_first_docked_object(object *objp)
float vm_vec_dist(const vec3d *v0, const vec3d *v1)
void ship_primary_changed(ship *sp)
float ai_ship_fire_delay_scale_hostile[NUM_SKILL_LEVELS]
int optional_string(const char *pstr)
int maybe_big_ship_collide_recover_frame(object *objp, ai_info *aip)
float get_skill_stealth_dot_scaler()
#define AI_CLASS_INCREMENT
float compute_dots(object *objp, object *other_objp, float *to_dot, float *from_dot)
weapon_info * ai_get_weapon(ship_weapon *swp)
float ai_link_ammo_levels_always
float ai_get_weapon_speed(ship_weapon *swp)
void ai_announce_ship_dying(object *dying_objp)
#define REARM_BREAKOFF_DELAY
float ai_evasion[NUM_SKILL_LEVELS]
float ai_turn_time_scale[NUM_SKILL_LEVELS]
#define SIF_BALLISTIC_PRIMARIES
char Mission_filename[80]
void read_file_text(const char *filename, int mode, char *processed_text, char *raw_text)
#define AIF_FREE_AFTERBURNER_USE
char * Strafe_submode_text[5]
void ai_set_guard_object(object *objp, object *other_objp)
ai_flag_name Ai_flag_names[]
int combine_flags(int base_flags, int override_flags, int override_set)
int max_allowed_player_homers[NUM_SKILL_LEVELS]
#define AIF_UNLOAD_SECONDARIES
int get_base_path_info(int path_cur, int goal_objnum, model_path **pmp, mp_vert **pmpv)
float ai_max_aim_update_delay[NUM_SKILL_LEVELS]
#define AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS
int turret_num_firing_points
float ai_circle_strafe_percent[NUM_SKILL_LEVELS]
#define MESSAGE_PRIORITY_LOW
int will_collide_with_big_ship(object *objp, vec3d *goal_point, object *big_objp, vec3d *collision_point, float delta_time)
int pp_collide(vec3d *curpos, vec3d *goalpos, object *goalobjp, float radius)
#define AIF_AWAITING_REPAIR
int secondary_bank_ammo[MAX_SHIP_SECONDARY_BANKS]
int maybe_avoid_player(object *objp, vec3d *goal_pos)
#define MC_CHECK_SPHERELINE
#define MIN_DIST_TO_WAYPOINT_GOAL
void ai_chase_fly_away(object *objp, ai_info *aip)
int targeted_subsys_parent
void set_primary_weapon_linkage(object *objp)
void set_goal_dock_orient(matrix *dom, vec3d *docker_p0, vec3d *docker_p1, vec3d *docker_p0_norm, matrix *docker_orient, vec3d *dockee_p0, vec3d *dockee_p1, vec3d *dockee_p0_norm, matrix *dockee_orient)
int ai_chance_to_use_missiles_on_plr
int maybe_request_support(object *objp)
#define SUBSYSTEM_WEAPONS
int max_attackers[NUM_SKILL_LEVELS]
float ai_primary_ammo_burst_mult[NUM_SKILL_LEVELS]
void dock_dock_objects(object *objp1, int dockpoint1, object *objp2, int dockpoint2)
vec3d * vm_vec_unrotate(vec3d *dest, const vec3d *src, const matrix *m)
#define SM_CONTINUOUS_TURN
int ignore_new_objnums[MAX_IGNORE_NEW_OBJECTS]
float vm_vec_dist_squared(const vec3d *v0, const vec3d *v1)
float ai_link_ammo_levels_maybe[NUM_SKILL_LEVELS]
int ai_acquire_emerge_path(object *pl_objp, int parent_objnum, int allowed_path_mask, vec3d *pos, vec3d *fvec)
#define SHIELD_BALANCE_RATE
#define AIF_AVOIDING_BIG_SHIP
int iff_x_attacks_y(int team_x, int team_y)
#define AI_GOAL_FLY_TO_SHIP
int get_subsystem_pos(vec3d *pos, object *objp, ship_subsys *subsysp)
float get_wing_largest_radius(object *objp, int formation_object_flag)
bool ship_useful_for_departure(int shipnum, int path_mask)
const size_t INVALID_WAYPOINT_POSITION
object Objects[MAX_OBJECTS]
for(int idx=0;idx< i;idx++)
float vm_vec_copy_normalize_quick(vec3d *dest, const vec3d *src)
void shield_add_strength(object *objp, float delta)
vec3d afterburner_max_vel
int find_nearby_threat(int objnum, int enemy_team_mask, float range, int *count)
float primary_bank_fof_cooldown[MAX_SHIP_PRIMARY_BANKS]
float afterburner_recharge_scale[NUM_SKILL_LEVELS]
const char * XSTR(const char *str, int index)
void get_wing_delta(vec3d *_delta_vec, int wing_index)
float Energy_levels[NUM_ENERGY_LEVELS]
float get_wing_lowest_av_ab_speed(object *objp)
SCP_map< SCP_string, path_metadata > pathMetadata
int ship_get_ship_for_departure(int team)
#define vm_vec_make(v, _x, _y, _z)
void get_absolute_wing_pos(vec3d *result_pos, object *leader_objp, int wing_index, int formation_object_flag)
int mission_is_repair_scheduled(object *objp)
vec3d * vm_vec_avg3(vec3d *dest, const vec3d *src0, const vec3d *src1, const vec3d *src2)
void stuff_boolean(int *i, bool a_to_eol)
void ai_maybe_depart(object *objp)
int primary_select_timestamp
#define AIF_AVOIDING_SMALL_SHIP
int ship_find_repair_ship(object *requester_obj, object **ship_we_found)
#define SIF2_NO_PRIMARY_LINKING
#define MESSAGE_REPAIR_DONE
int is_support_allowed(object *objp, bool do_simple_check)
char * ai_get_goal_target_name(const char *name, int *index)
float gwlr_object_1(object *objp, ai_info *aip)
void init_ai_stealth_info(ai_info *aip, object *stealth_objp)
#define HULL_DAMAGE_THRESHOLD_PERCENT
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 garbage_collect_path_points()
void fds_aux(float *dot, float *tts, vec3d *pos, float dtime, object *objp)
void _cdecl void void _cdecl Error(const char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
int ai_override_timestamp
int rearm_first_ballistic_primary
#define AIF_ATTACK_SLOWLY
#define AIS_STRAFE_RETREAT2
void dc_stuff_float(float *f)
Stuffs a float to the given variable.
void vm_vec_rand_vec_quick(vec3d *rvec)
#define STEALTH_VIEW_CONE_DOT
#define AIPF_SMART_AFTERBURNER_MANAGEMENT
#define WBF_RANDOM_LENGTH
float ship_get_exp_outer_rad(object *ship_objp)
float ai_patience[NUM_SKILL_LEVELS]
#define WIF2_PIERCE_SHIELDS
#define SF2_NO_BUILTIN_MESSAGES
int turret_animation_done_time
void ai_select_secondary_weapon(object *objp, ship_weapon *swp, int priority1=-1, int priority2=-1, int wif2_priority1=-1, int wif2_priority2=-1)
void ai_chase_attack(ai_info *aip, ship_info *sip, vec3d *predicted_enemy_pos, float dist_to_enemy, int modelnum)
void reset_parse(char *text)
float max_aim_update_delay[NUM_SKILL_LEVELS]
#define FRIENDLY_DAMAGE_THRESHOLD
#define AIF_BEING_REPAIRED
GLuint const GLchar * name
#define REPAIR_INFO_QUEUE
float ai_cmeasure_fire_chance
float ai_link_ammo_levels_always[NUM_SKILL_LEVELS]
float awacs_get_level(object *target, ship *viewer, int use_awacs)
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
void physics_read_flying_controls(matrix *orient, physics_info *pi, control_info *ci, float sim_time, vec3d *wash_rot)
int ignore_expire_timestamp
#define vm_realloc(ptr, size)
#define MISSION_TYPE_TRAINING
int will_collide_with_big_ship_all(object *objp, object *ignore_objp, vec3d *goal_point, vec3d *collision_point, float *distance, float delta_time)
float ai_in_range_time[NUM_SKILL_LEVELS]
float turret_max_aim_update_delay[NUM_SKILL_LEVELS]
#define AIPF_ALLOW_TURRETS_TARGET_WEAPONS_FREELY
void model_instance_find_world_dir(vec3d *out_dir, vec3d *in_dir, int model_instance_num, int submodel_num, const matrix *objorient)
void ai_control_info_check(object *obj, ai_info *aip)
int pick_big_attack_point_timestamp
int num_nearby_fighters(int enemy_team_mask, vec3d *pos, float threshold)
float get_shield_pct(object *objp)
#define REPAIR_INFO_KILLED
void ai_big_ship(object *objp)
#define MESSAGE_PRIORITY_HIGH
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 process_subobjects(int objnum)
int scan_for_enemy_timestamp
void cheat_fire_synaptic(object *objp, ship *shipp, ai_info *aip)
void afterburners_start(object *objp)
float circle_strafe_percent[NUM_SKILL_LEVELS]
int create_object_hash(object *objp)
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
#define SM_ATTACK_FOREVER
#define AIPF_SMART_PRIMARY_WEAPON_SELECTION
void turn_towards_point(object *objp, vec3d *point, vec3d *slide_vec, float bank_override)
void create_model_exit_path(object *pl_objp, object *mobjp, int path_num, int count=1)
float in_range_time[NUM_SKILL_LEVELS]
float get_wing_lowest_max_speed(object *objp)
float best_dot_from_enemy
int ship_launch_countermeasure(object *objp, int rand_val)
polymodel_instance * model_get_instance(int model_instance_num)
#define REPAIR_INFO_ABORT
float ai_shockwave_evade_chance[NUM_SKILL_LEVELS]
void ai_set_evade_object(object *objp, object *other_objp)
vec3d * vm_vec_normal(vec3d *dest, const vec3d *p0, const vec3d *p1, const vec3d *p2)
void render_all_ship_bay_paths(object *objp)
void evaluate_object_as_nearest_objnum(eval_nearest_objnum *eno)
float vm_vec_dist_quick(const vec3d *v0, const vec3d *v1)
int will_collide_pp(vec3d *p0, vec3d *p1, float radius, object *big_objp, vec3d *collision_point)
float frand()
Return random value in range 0.0..1.0- (1.0- means the closest number less than 1.0)
int hash(unsigned int curval, int newval)
#define SF_SECONDARY_DUAL_FIRE
#define AIGF_DOCK_INDEXES_VALID
void ai_safety_pick_spot(object *objp)
int num_allies_rearming(object *objp)
void ai_most_massive_object_of_its_wing_of_all_docked_objects_helper(object *objp, dock_function_info *infop)
#define AI_GOAL_DISABLE_SHIP
void ai_chase_circle(object *objp)
float ai_safety_goto_spot(object *objp)
void ai_object_init(object *obj, int ai_index)
float ai_ship_fire_delay_scale_hostile
void vm_matrix_interpolate(const matrix *goal_orient, const matrix *curr_orient, const vec3d *w_in, float delta_t, matrix *next_orient, vec3d *w_out, const vec3d *vel_limit, const vec3d *acc_limit, int no_overshoot)
float ai_secondary_range_mult[NUM_SKILL_LEVELS]
void vm_vec_boxscale(vec2d *vec, float scale)
void mission_bring_in_support_ship(object *requester_objp)
#define SUBSYSTEM_SENSORS
void ai_ship_destroy(int shipnum, int method)
#define SUBSYSTEM_UNKNOWN
void ai_chase_big_parallel_set_goal(vec3d *goal_pos, object *attack_objp, object *target_objp, float *accel)
#define STEALTH_IN_FRUSTUM
float ai_courage[NUM_SKILL_LEVELS]
void ai_chase_ga(ai_info *aip, ship_info *sip)
float ship_fire_secondary_delay_scale_hostile[NUM_SKILL_LEVELS]
void ai_execute_behavior(ai_info *aip)
#define MESSAGE_TIME_ANYTIME
void message_send_builtin_to_player(int type, ship *shipp, int priority, int timing, int group, int delay, int multi_target, int multi_team_filter)
float link_ammo_levels_always[NUM_SKILL_LEVELS]
struct dock_function_info::@258 parameter_variables
float glide_attack_percent[NUM_SKILL_LEVELS]
struct dock_function_info::@258 maintained_variables
void ship_maybe_tell_about_rearm(ship *sp)
void ai_mission_wing_goal_complete(int wingnum, ai_goal *remove_goalp)
void init_ai_object(int objnum)
int ship_do_rearm_frame(object *objp, float frametime)
ship_subsys * ship_get_closest_subsys_in_sight(ship *sp, int subsys_type, vec3d *attacker_pos)
int asteroid_collide_objnum(object *asteroid_objp)
void ai_cleanup_dock_mode_subjective(object *objp)
int find_enemy(int objnum, float range, int max_attackers)
int ai_acquire_depart_path(object *pl_objp, int parent_objnum, int allowed_path_mask)
int ai_abort_rearm_request(object *requester_objp)
void ai_deathroll_start(object *dying_objp)
float vm_vec_copy_normalize(vec3d *dest, const vec3d *src)
int choose_enemy_timestamp
fix predict_position_delay[NUM_SKILL_LEVELS]
void modify_model_path_points(object *objp)
int get_enemy_team_range(object *my_objp, float range, int enemy_team_mask, vec3d *min_vec, vec3d *max_vec)
void dock_evaluate_all_docked_objects(object *objp, dock_function_info *infop, void(*function)(object *, dock_function_info *))
void ship_secondary_changed(ship *sp)
#define MAX_ENEMY_DISTANCE
void ai_chase_es(ai_info *aip, ship_info *sip)
#define MULTIPLAYER_MASTER
#define AIPF2_ALLOW_PRIMARY_LINK_AT_START
An overhauled/updated debug console to allow monitoring, testing, and general debugging of new featur...
void adjust_accel_for_docking(ai_info *aip)
SCP_vector< ship_info > Ship_info
float cmeasure_fire_chance[NUM_SKILL_LEVELS]
vec3d * vm_vec_avg(vec3d *dest, const vec3d *src0, const vec3d *src1)
void render_wing_phantoms_all()
vec3d afterburner_max_vel
float compute_collision_time(vec3d *targpos, vec3d *targvel, vec3d *attackpos, float weapon_speed)
int bay_doors_parent_shipnum
void ai_do_default_behavior(object *obj)
#define SF2_AFTERBURNER_LOCKED
void ai_fly_in_formation(int wingnum)
int num_turrets_attacking(object *turret_parent, int target_objnum)
void ship_apply_local_damage(object *ship_objp, object *other_obj, vec3d *hitpos, float damage, int quadrant, bool create_spark, int submodel_num, vec3d *hit_normal)
fix last_warning_message_time
void ai_do_objects_docked_stuff(object *docker, int docker_point, object *dockee, int dockee_point, bool update_clients)
int static_rand(int num)
Return a pseudo random 32 bit value given a reasonably small number.
int nearest_locked_object
#define timestamp_elapsed(stamp)
SCP_vector< float > shield_quadrant
int static_rand_range(int num, int min, int max)
Return a random integer within a range. Note: min and max are inclusive.
int vm_vec_cmp(const vec3d *a, const vec3d *b)
float ai_ship_fire_secondary_delay_scale_hostile[NUM_SKILL_LEVELS]
#define OF_SHOULD_BE_DEAD
void debug_find_guard_object()
#define AIF_REPAIR_OBSTRUCTED
void reset_ai_class_names()
void get_absolute_wing_pos_autopilot(vec3d *result_pos, object *leader_objp, int wing_index, int formation_object_flag)
int check_danger_weapon_objnum
GLenum GLenum GLvoid GLvoid * column
#define MAX_FORMATION_ROWS
void shipfx_warpout_start(object *objp)
#define MISSION_FLAG_NO_BUILTIN_COMMAND
int ship_is_visible_by_team(object *target, ship *viewer)
GLsizei GLsizei GLuint * obj
float ship_fire_delay_scale_hostile[NUM_SKILL_LEVELS]
float ai_shield_manage_delay
void ai_frame(int objnum)
#define AIS_CHASE_CIRCLESTRAFE
float vm_vec_dot(const vec3d *v0, const vec3d *v1)
GLenum GLuint GLenum GLsizei length
#define AICODE_SMALL_MAGNITUDE
int ai_is_stealth_visible(object *viewer_objp, object *stealth_objp)
void ai_process_mission_orders(int objnum, ai_info *aip)
bool is_object_stealth_ship(object *objp)
int ignore_new_signatures[MAX_IGNORE_NEW_OBJECTS]
void vm_vec_scale_sub2(vec3d *dest, const vec3d *src, float k)
void maybe_afterburner_after_ship_hit(object *objp, ai_info *aip, object *en_objp)
int ai_maybe_limit_attackers(int attacked_objnum)
float ai_shield_manage_delay[NUM_SKILL_LEVELS]
void ai_manage_bay_doors(object *pl_objp, ai_info *aip, bool done)
void ai_big_subsys_path_cleanup(ai_info *aip)
SCP_vector< int > ai_actively_pursues
GLsizei GLsizei GLchar * source
int get_wing_index(object *objp, int wingnum)
#define AIS_CHASE_GLIDEATTACK
void get_tangent_point(vec3d *tan1, vec3d *p0, vec3d *centerp, vec3d *p1, float radius)
int support_ship_signature
int game_get_default_skill_level()
#define AIF_AVOID_SHOCKWAVE
float dock_orient_and_approach(object *docker_objp, int docker_index, object *dockee_objp, int dockee_index, int dock_mode, rotating_dockpoint_info *rdinfo)
#define TRIGGER_TYPE_TURRET_FIRING
float shield_manage_delay[NUM_SKILL_LEVELS]
#define AIF_FORMATION_WING
int might_hit_teammate(object *firing_objp)
float ai_ship_fire_secondary_delay_scale_friendly[NUM_SKILL_LEVELS]
void player_stop_repair_sound()
#define SUBSYSTEM_ACTIVATION
float get_cylinder_points(object *other_objp, object *cyl_objp, vec3d *axis_pt, vec3d *r_vec, float *radius)
#define SF_DEPART_DOCKBAY
void maybe_cheat_fire_synaptic(object *objp, ai_info *aip)
#define WIF_HOMING_JAVELIN
float maybe_recreate_path(object *objp, ai_info *aip, int force_recreate_flag, int override_hash=0)
int ai_maybe_fire_afterburner(object *objp, ai_info *aip)
float ai_stalemate_dist_thresh[NUM_SKILL_LEVELS]
#define AI_GOAL_REARM_REPAIR
int maybe_hack_cruiser_chase_abort()
#define PF_AFTERBURNER_ON
int ship_index[MAX_SHIPS_PER_WING]
int is_ignore_object_sub(int *ignore_objnum, int *ignore_signature, int objnum)
void ai_fly_to_target_position(vec3d *target_pos, bool *pl_done_p=NULL, bool *pl_treat_as_ship_p=NULL)
int Player_attacking_enabled
#define EVADE_SHOCKWAVE_DAMAGE_THRESHOLD
void ai_guard_find_nearby_ship(object *guarding_objp, object *guarded_objp)
int iff_matches_mask(int team, int mask)
void turn_away_from_point(object *objp, vec3d *point, float bank_override)
#define LOG_WAYPOINTS_DONE
int primary_bank_start_ammo[MAX_SHIP_PRIMARY_BANKS]
#define AIF_STEALTH_PURSUIT
#define REPAIR_INFO_BEGIN
int pp_collide_any(vec3d *curpos, vec3d *goalpos, float radius, object *ignore_objp1, object *ignore_objp2, int big_only_flag)
float ai_shockwave_evade_chance
#define AIGF_TARGET_OWN_TEAM
int ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int consider_target_only)
int ship_name_lookup(const char *name, int inc_players)
int ai_await_repair_frame(object *objp, ai_info *aip)
int ai_aburn_use_factor[NUM_SKILL_LEVELS]
vec3d * vm_vec_cross(vec3d *dest, const vec3d *src0, const vec3d *src1)
int maybe_dock_obstructed(object *cur_objp, object *goal_objp, int big_only_flag)
#define AIPF_SMART_SHIELD_MANAGEMENT
void ai_chase_big_circle_set_goal(vec3d *goal_pos, object *attack_objp, object *target_objp, float *accel)
float random_sidethrust_percent[NUM_SKILL_LEVELS]
void call_doa(object *child, object *parent)
#define AIPF2_AI_GUARDS_SPECIFIC_SHIP_IN_WING
void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_quadrant, vec3d *hit_normal)
float ai_secondary_range_mult
void big_ship_collide_recover_start(object *objp, object *big_objp, vec3d *collide_pos, vec3d *collision_normal)
void ai_guard_find_nearby_asteroid(object *guarding_objp, object *guarded_objp)
int object_is_targetable(object *target, ship *viewer)
void maybe_set_dynamic_chase(ai_info *aip, int hitter_objnum)
missile_obj Missile_obj_list
#define AIF_BIG_SHIP_COLLIDE_RECOVER_2
struct ai_render_stuff ai_render_stuff
float dock_calc_total_docked_mass(object *objp)
#define AIF_AVOID_SHOCKWAVE_SHIP
ai_render_stuff AI_debug_render_stuff[MAX_AI_DEBUG_RENDER_STUFF]
#define REARM_SOUND_DELAY
fix ai_predict_position_delay[NUM_SKILL_LEVELS]
shockwave_create_info shockwave
#define WIF3_FIGHTER_INTERCEPTABLE
#define STI_AI_ATTEMPT_BROADSIDE
#define REPAIR_INFO_BROKEN
int firing_aspect_seeking_bomb(object *objp)
#define SF_FROM_PLAYER_WING
float find_nearest_point_on_line(vec3d *nearest_point, const vec3d *p0, const vec3d *p1, const vec3d *int_pnt)
const char * Skill_level_names(int level, int translate)
int ai_fire_secondary_weapon(object *objp, int priority1, int priority2)
float afterburner_recover_rate
int multi_find_player_by_object(object *objp)
char filename[FILESPEC_LENGTH]
#define MISSION_FLAG_NO_TRAITOR
void create_model_path(object *pl_objp, object *mobjp, int path_num, int subsys_path)
#define AIS_STRAFE_ATTACK
void render_wing_phantoms(object *objp)
net_player Net_players[MAX_PLAYERS]
void gameseq_post_event(int event)
int num_enemies_attacking(int objnum)
void ai_manage_shield(object *objp, ai_info *aip)
void set_predicted_enemy_pos(vec3d *predicted_enemy_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, ai_info *aip)
vec3d pnt[MAX_DOCK_SLOTS]
int burst_counter[MAX_SHIP_PRIMARY_BANKS+MAX_SHIP_SECONDARY_BANKS]
float ship_calculate_rearm_duration(object *objp)
void vm_vec_add(vec3d *dest, const vec3d *src0, const vec3d *src1)
float ship_get_exp_damage(object *objp)
float ai_link_energy_levels_maybe[NUM_SKILL_LEVELS]
void attack_set_accel(ai_info *aip, ship_info *sip, float dist_to_enemy, float dot_to_enemy, float dot_from_enemy)
int get_enemy_timestamp()
void ship_do_submodel_rotation(ship *shipp, model_subsystem *psub, ship_subsys *pss)
void ai_init_secondary_info()
void ai_maybe_launch_cmeasure(object *objp, ai_info *aip)
#define timestamp_valid(stamp)
float stalemate_dist_thresh[NUM_SKILL_LEVELS]
float link_energy_levels_maybe[NUM_SKILL_LEVELS]
void ai_chase_big_get_separations(object *attack_objp, object *target_objp, vec3d *horz_vec_to_target, float *desired_separation, float *cur_separation)
NavPoint Navs[MAX_NAVPOINTS]
int is_instructor(object *objp)
float static_randf(int num)
Return a random float in 0.0f .. 1.0f- (ie, it will never return 1.0f).
float ai_primary_ammo_burst_mult
#define AIF_TARGET_COLLISION
#define AIF_AVOID_SHOCKWAVE_STARTED
char ship_name[NAME_LENGTH]
void maybe_evade_dumbfire_weapon(ai_info *aip)
#define LOG_PLAYER_ABORTED_REARM
void maybe_update_guard_object(object *hit_objp, object *hitter_objp)
float afterburner_burn_rate
#define SF2_NO_SECONDARY_LOCKON
char docker_point[NAME_LENGTH]
void create_path_to_point(vec3d *curpos, vec3d *goalpos, object *curobjp, object *goalobjp, int subsys_path)
void physics_ship_init(object *objp)
float static_randf_range(int num, float min, float max)
Return a random float within a range. Note: min and max are inclusive.
SCP_vector< ship_type_info > Ship_types
#define IFFF_SUPPORT_ALLOWED
float ai_link_energy_levels_maybe
void vm_forward_interpolate(const vec3d *goal_f, const matrix *orient, const vec3d *w_in, float delta_t, float delta_bank, matrix *next_orient, vec3d *w_out, const vec3d *vel_limit, const vec3d *acc_limit, int no_overshoot)
void ai_do_objects_repairing_stuff(object *repaired_objp, object *repair_objp, int how)
matrix path_create_orient
object * Autopilot_flight_leader
#define MISSION_FLAG_SUBSPACE
void init_ai_class(ai_class *aicp)
#define OBJ_RECALC_PAIRS(obj_to_reset)
int formation_is_leader_chaotic(object *objp)
void ai_set_mode_warp_out(object *objp, ai_info *aip)
int current_target_is_locked
void update_ai_stealth_info_with_error(ai_info *aip)
int path_indexes[MAX_SHIP_BAY_PATHS]
#define MESSAGE_TIME_SOON
float vm_vec_normalize(vec3d *v)
int previous_target_objnum
void compute_desired_rvec(vec3d *rvec, vec3d *goal_pos, vec3d *cur_pos)
void ai_guard_find_nearby_object()
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 max_allowed_speed, object *gobjp)
void ai_remove_ship_goal(ai_info *aip, int index)
int Num_AI_debug_render_stuff
void ai_set_rearm_status(int team, int time)