Compare commits

..
Author SHA1 Message Date
Goober5000 3dc8ab068f made a copy 2008-05-04 00:53:27 +00:00
30 changed files with 491 additions and 3009 deletions

No files matched your search

-5
View File
@@ -211,9 +211,6 @@ FS2_SOURCES = \
ai/aiturret.cpp \
ai/ai_profiles.cpp \
ai/ai_profiles.h \
ai/aimodular.h \
ai/aimodular.cpp \
ai/newai/newai.cpp \
anim/animplay.cpp \
anim/animplay.h \
anim/packunpack.cpp \
@@ -825,8 +822,6 @@ fs2_open_r_SOURCES = \
fs2_open_d_LDADD = libcode.a ../libjpeg/libjpeg.a ../lua/liblua.a
fs2_open_r_LDADD = libcode.a ../libjpeg/libjpeg.a ../lua/liblua.a
fs2_open_d_LDFLAGS = -rdynamic
fs2_open_r_LDFLAGS = -rdynamic
##
## End MAIN binary
-4
View File
@@ -235,10 +235,6 @@ void parse_ai_profiles_tbl(char *filename)
// fill in any and all settings; they're all optional and can be in any order
while (!check_for_string("$Profile Name:") && !check_for_string("#End"))
{
strcpy(profile->ai_module, "retail");
if (optional_string("$AI Module:"))
stuff_string(profile->ai_module, F_NAME, NAME_LENGTH);
if (optional_string("$Player Afterburner Recharge Scale:"))
parse_float_list(profile->afterburner_recharge_scale, NUM_SKILL_LEVELS);
-2
View File
@@ -80,8 +80,6 @@
typedef struct ai_profile_t {
char profile_name[NAME_LENGTH];
char ai_module[NAME_LENGTH];
int flags;
+24 -179
View File
@@ -482,141 +482,13 @@ extern int model_which_octant_distant_many( vec3d *pnt, int model_num,matrix *mo
extern void compute_desired_rvec(vec3d *rvec, vec3d *goal_pos, vec3d *cur_pos);
extern void big_ship_collide_recover_start(object *objp, object *big_objp, vec3d *collide_pos, vec3d *collision_normal);
// FF 14-06-07
// AI Big Table Wrapper
struct aibig_call_table *aibig_table = &AIBigDefaultTable;
void ai_big_evade_ship ()
{
aibig_table->ai_big_evade_ship();
}
void ai_big_chase_attack (ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum)
{
aibig_table->ai_big_chase_attack(aip, sip, enemy_pos, dist_to_enemy, modelnum);
}
void ai_big_avoid_ship ()
{
aibig_table->ai_big_avoid_ship();
}
int ai_big_maybe_follow_subsys_path (int do_dot_check)
{
return aibig_table->ai_big_maybe_follow_subsys_path(do_dot_check);
}
void ai_bpap (object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal)
{
aibig_table->ai_bpap(objp, attacker_objp_pos, attacker_objp_fvec, attack_point, local_attack_point, fov, weapon_travel_dist, surface_normal);
}
void ai_big_pick_attack_point_turret (object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
{
aibig_table->ai_big_pick_attack_point_turret(objp, ssp, gpos, gvec, attack_point, fov, weapon_travel_dist);
}
void ai_big_pick_attack_point (object *objp, object *attacker_objp, vec3d *attack_point, float fov)
{
aibig_table->ai_big_pick_attack_point(objp, attacker_objp, attack_point, fov);
}
void ai_big_subsys_path_cleanup (ai_info *aip)
{
aibig_table->ai_big_subsys_path_cleanup(aip);
}
int ai_big_maybe_start_strafe (ai_info *aip, ship_info *sip)
{
return aibig_table->ai_big_maybe_start_strafe(aip, sip);
}
void ai_big_chase_ct ()
{
aibig_table->ai_big_chase_ct();
}
void ai_big_maybe_fire_weapons (float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel)
{
aibig_table->ai_big_maybe_fire_weapons(dist_to_enemy, dot_to_enemy, firing_pos, enemy_pos, enemy_vel);
}
void ai_big_switch_to_chase_mode (ai_info *aip)
{
aibig_table->ai_big_switch_to_chase_mode(aip);
}
int ai_big_strafe_maybe_retreat (float dist, vec3d *target_pos)
{
return aibig_table->ai_big_strafe_maybe_retreat(dist, target_pos);
}
void ai_big_chase ()
{
aibig_table->ai_big_chase();
}
void ai_big_ship (object *objp)
{
aibig_table->ai_big_ship(objp);
}
void ai_big_attack_get_data (vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy)
{
aibig_table->ai_big_attack_get_data(enemy_pos, dist_to_enemy, dot_to_enemy);
}
void ai_big_strafe_attack ()
{
aibig_table->ai_big_strafe_attack();
}
void ai_big_strafe_avoid ()
{
aibig_table->ai_big_strafe_avoid();
}
void ai_big_strafe_retreat1 ()
{
aibig_table->ai_big_strafe_retreat1();
}
void ai_big_strafe_retreat2 ()
{
aibig_table->ai_big_strafe_retreat2();
}
void ai_big_strafe_position ()
{
aibig_table->ai_big_strafe_position();
}
void ai_big_strafe ()
{
aibig_table->ai_big_strafe();
}
int ai_big_maybe_enter_strafe_mode (object *pl_objp, int weapon_objnum, int consider_target_only)
{
return aibig_table->ai_big_maybe_enter_strafe_mode(pl_objp, weapon_objnum, consider_target_only);
}
void ai_big_strafe_maybe_attack_turret (object *ship_objp, object *weapon_objp)
{
aibig_table->ai_big_strafe_maybe_attack_turret(ship_objp, weapon_objp);
}
// AI Big Default implementation
// Called by ai_big_pick_attack_point.
// Generates a random attack point.
// If truly_random flag set (haha), then generate a pretty random number. Otherwise, generate a static rand which
// tends to not change from frame to frame.
// Try four times and choose nearest point to increase chance of getting a good point.
void aibig_ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal)
void ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal)
{
float nearest_dist;
vec3d result_point, best_point;
@@ -735,7 +607,7 @@ done_1:
//
// Note: Default value for fov is 1.0f 1.0f means don't use fov parameter.
// If fov != 1.0f, try up to four times to find a point that's in the field of view.
void aibig_ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
{
if (!timestamp_elapsed(ssp->turret_pick_big_attack_point_timestamp)) {
vec3d result_point;
@@ -755,7 +627,7 @@ void aibig_ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d
// Note: Default value for fov is 1.0f 1.0f means don't use fov parameter.
// If fov != 1.0f, try up to four times to find a point that's in the field of view.
// Note, attacker_objp can be a ship or a weapon.
void aibig_ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov)
void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov)
{
Assert(objp->instance > -1);
Assert(objp->type == OBJ_SHIP);
@@ -824,7 +696,7 @@ void aibig_ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *
}
// Handler for SM_EVADE submode ( called from ai_big_chase() )
void aibig_ai_big_evade_ship()
void ai_big_evade_ship()
{
vec3d player_pos, enemy_pos;
float dist;
@@ -872,13 +744,13 @@ void aibig_ai_big_evade_ship()
}
// Handler for SM_AVOID submode ( called from ai_big_chase() )
void aibig_ai_big_avoid_ship()
void ai_big_avoid_ship()
{
ai_big_evade_ship();
}
// reset path following information
void aibig_ai_big_subsys_path_cleanup(ai_info *aip)
void ai_big_subsys_path_cleanup(ai_info *aip)
{
if ( aip->ai_flags & AIF_ON_SUBSYS_PATH ) {
aip->ai_flags &= ~AIF_ON_SUBSYS_PATH;
@@ -893,7 +765,7 @@ void aibig_ai_big_subsys_path_cleanup(ai_info *aip)
// input: do_dot_check => default value 0, flag to indicate whether check should be done to ensure
// subsystem is within certain field of view. We don't want to check fov when
// strafing, since ship is weaving to avoid turret fire
int aibig_ai_big_maybe_follow_subsys_path(int do_dot_check)
int ai_big_maybe_follow_subsys_path(int do_dot_check)
{
ai_info *aip;
float dot = 1.0f, min_dot;
@@ -1027,7 +899,7 @@ int aibig_ai_big_maybe_follow_subsys_path(int do_dot_check)
// 0 => ship should not change ai mode, no fighter/bomber threats are near
//
// NOTE: uses SCAN_FIGHTERS_INTERVAL and ENTER_STRAFE_THREAT_DIST_SQUARED which are defined in AiBig.h
int aibig_ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
int ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
{
// if moving slowly (or stopped), and SIF_SMALL_SHIP, then enter STRAFE mode if enemy fighter/bombers
// are near
@@ -1062,7 +934,7 @@ int aibig_ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
}
// ATTACK submode handler for chase mode.
void aibig_ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum)
void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum)
{
int start_bank;
float dot_to_enemy, time_to_hit;
@@ -1179,7 +1051,7 @@ void aibig_ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, f
}
// Handler for submode SM_CONTINUOUS_TURN
void aibig_ai_big_chase_ct()
void ai_big_chase_ct()
{
ai_chase_ct();
}
@@ -1196,7 +1068,7 @@ extern void maybe_cheat_fire_synaptic(object *objp, ai_info *aip);
// dist_to_enemy => distance (in m) to attack point on current target
// dot_to_enemy => dot product between fvec of Pl_objp and vector from Pl_objp to attack point
//
void aibig_ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel)
void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel)
{
ai_info *aip;
ship_weapon *swp;
@@ -1301,7 +1173,7 @@ void aibig_ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, ve
}
// switch ai ship into chase mode
void aibig_ai_big_switch_to_chase_mode(ai_info *aip)
void ai_big_switch_to_chase_mode(ai_info *aip)
{
aip->previous_mode = aip->mode;
aip->mode = AIM_CHASE;
@@ -1312,7 +1184,7 @@ void aibig_ai_big_switch_to_chase_mode(ai_info *aip)
extern int ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos);
// Make object Pl_objp chase object En_objp, which is a big ship, not a small ship.
void aibig_ai_big_chase()
void ai_big_chase()
{
float dist_to_enemy, dot_to_enemy;
vec3d player_pos, enemy_pos, vec_to_enemy;
@@ -1602,7 +1474,7 @@ void aibig_ai_big_chase()
aip->time_enemy_in_range *= (1.0f - flFrametime);
}
void aibig_ai_big_ship(object *objp)
void ai_big_ship(object *objp)
{
// do nothing
}
@@ -1613,7 +1485,7 @@ void aibig_ai_big_ship(object *objp)
// dist => distance from Pl_objp front to attack point
// dot => dot of Pl_objp fvec and vector to attack point
// fire_pos => world pos from which firing
void aibig_ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy)
void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy)
{
vec3d player_pos, vec_to_enemy, predicted_enemy_pos;
ship *shipp = &Ships[Pl_objp->instance];
@@ -1672,7 +1544,7 @@ void aibig_ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float
// check to see if Pl_objp has gotten too close to attacking point.. if so, break off by entering
// AIS_STRAFE_RETREAT
int aibig_ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
int ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
{
ai_info *aip;
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
@@ -1729,7 +1601,7 @@ int aibig_ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
}
// attack directly to the turret and fire weapons
void aibig_ai_big_strafe_attack()
void ai_big_strafe_attack()
{
ai_info *aip;
vec3d target_pos;
@@ -1832,7 +1704,7 @@ void aibig_ai_big_strafe_attack()
}
// pick a new attack point when entering this state, and keep using it
void aibig_ai_big_strafe_avoid()
void ai_big_strafe_avoid()
{
ai_info *aip;
vec3d target_pos;
@@ -1858,7 +1730,7 @@ void aibig_ai_big_strafe_avoid()
}
// move towards aip->goal_point in an evasive manner
void aibig_ai_big_strafe_retreat1()
void ai_big_strafe_retreat1()
{
float dist;
ai_info *aip;
@@ -1904,7 +1776,7 @@ void aibig_ai_big_strafe_retreat1()
accelerate_ship(aip, 1.0f);
}
void aibig_ai_big_strafe_retreat2()
void ai_big_strafe_retreat2()
{
float dist;
ai_info *aip;
@@ -1943,7 +1815,7 @@ void aibig_ai_big_strafe_retreat2()
}
// reposition self to begin another strafing run
void aibig_ai_big_strafe_position()
void ai_big_strafe_position()
{
ai_info *aip;
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
@@ -1961,7 +1833,7 @@ void aibig_ai_big_strafe_position()
// #define AIS_STRAFE_RETREAT1 204 // fly away from attack point (on an avoid vector)
// #define AIS_STRAFE_POSITION 205 // re-position to resume strafing attack
//
void aibig_ai_big_strafe()
void ai_big_strafe()
{
ai_info *aip;
@@ -2011,7 +1883,7 @@ void aibig_ai_big_strafe()
//
// Check if weapon_objnum was fired by Pl_objp's target, and whether Pl_objp's target is a big ship, if
// so, enter AIM_STRAFE
int aibig_ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int consider_target_only)
int ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int consider_target_only)
{
ai_info *aip;
ship_info *sip;
@@ -2085,7 +1957,7 @@ int aibig_ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int
// Consider attacking a turret, if a turret actually fired the weapon
// input: ship_objp => ship that will attack the turret
// weapon_objp =>
void aibig_ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp)
void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp)
{
ai_info *aip;
object *parent_objp;
@@ -2134,30 +2006,3 @@ void aibig_ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_o
// attack the turret
set_targeted_subsys(aip, Weapons[weapon_objp->instance].turret_subsys, OBJ_INDEX(parent_objp));
}
struct aibig_call_table AIBigDefaultTable = {
aibig_ai_big_evade_ship,
aibig_ai_big_chase_attack,
aibig_ai_big_avoid_ship,
aibig_ai_big_maybe_follow_subsys_path,
aibig_ai_bpap,
aibig_ai_big_pick_attack_point_turret,
aibig_ai_big_pick_attack_point,
aibig_ai_big_subsys_path_cleanup,
aibig_ai_big_maybe_start_strafe,
aibig_ai_big_chase_ct,
aibig_ai_big_maybe_fire_weapons,
aibig_ai_big_switch_to_chase_mode,
aibig_ai_big_strafe_maybe_retreat,
aibig_ai_big_chase,
aibig_ai_big_ship,
aibig_ai_big_attack_get_data,
aibig_ai_big_strafe_attack,
aibig_ai_big_strafe_avoid,
aibig_ai_big_strafe_retreat1,
aibig_ai_big_strafe_retreat2,
aibig_ai_big_strafe_position,
aibig_ai_big_strafe,
aibig_ai_big_maybe_enter_strafe_mode,
aibig_ai_big_strafe_maybe_attack_turret
};
+1 -38
View File
@@ -102,43 +102,6 @@ void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp);
void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov=1.0f);
void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float weapon_travel_dist, float fov=1.0f);
// AI Big Table Wrapper
#include "ship/ship.h"
struct aibig_call_table
{
void (*ai_big_evade_ship) ();
void (*ai_big_chase_attack) (ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum);
void (*ai_big_avoid_ship) ();
int (*ai_big_maybe_follow_subsys_path) (int do_dot_check=1);
void (*ai_bpap) (object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal);
void (*ai_big_pick_attack_point_turret) (object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist);
void (*ai_big_pick_attack_point) (object *objp, object *attacker_objp, vec3d *attack_point, float fov);
void (*ai_big_subsys_path_cleanup) (ai_info *aip);
int (*ai_big_maybe_start_strafe) (ai_info *aip, ship_info *sip);
void (*ai_big_chase_ct) ();
void (*ai_big_maybe_fire_weapons) (float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel);
void (*ai_big_switch_to_chase_mode) (ai_info *aip);
int (*ai_big_strafe_maybe_retreat) (float dist, vec3d *target_pos);
void (*ai_big_chase) ();
void (*ai_big_ship) (object *objp);
void (*ai_big_attack_get_data) (vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy);
void (*ai_big_strafe_attack) ();
void (*ai_big_strafe_avoid) ();
void (*ai_big_strafe_retreat1) ();
void (*ai_big_strafe_retreat2) ();
void (*ai_big_strafe_position) ();
void (*ai_big_strafe) ();
int (*ai_big_maybe_enter_strafe_mode) (object *pl_objp, int weapon_objnum, int consider_target_only);
void (*ai_big_strafe_maybe_attack_turret) (object *ship_objp, object *weapon_objp);
};
// Set new pointer to override ai_big* function calls
// possibly copying the old function calls first
extern struct aibig_call_table *aibig_table;
extern struct aibig_call_table AIBigDefaultTable;
#endif
+212 -1414
View File
File diff suppressed because it is too large. Load diff
+32 -233
View File
@@ -772,176 +772,11 @@ ai_goal_list Ai_goal_names[] =
int Num_ai_goals = sizeof(Ai_goal_names) / sizeof(ai_goal_list);
// FF 04-06-07
// AI Goal Table Wrapper
struct aigoal_call_table *aigoal_table = &AIGoalDefaultTable;
char* Ai_goal_text (int goal)
{
return aigoal_table->Ai_goal_text(goal);
}
void ai_maybe_add_form_goal (wing *wingp)
{
aigoal_table->ai_maybe_add_form_goal(wingp);
}
void ai_post_process_mission ()
{
aigoal_table->ai_post_process_mission();
}
int ai_query_goal_valid (int ship, int ai_goal)
{
return aigoal_table->ai_query_goal_valid(ship, ai_goal);
}
void ai_remove_ship_goal (ai_info *aip, int index)
{
aigoal_table->ai_remove_ship_goal(aip, index);
}
void ai_clear_ship_goals (ai_info *aip)
{
aigoal_table->ai_clear_ship_goals(aip);
}
void ai_clear_wing_goals (int wingnum)
{
aigoal_table->ai_clear_wing_goals(wingnum);
}
void ai_mission_wing_goal_complete (int wingnum, ai_goal *remove_goalp)
{
aigoal_table->ai_mission_wing_goal_complete(wingnum, remove_goalp);
}
void ai_mission_goal_complete (ai_info *aip)
{
aigoal_table->ai_mission_goal_complete(aip);
}
int ai_get_subsystem_type (char *subsystem)
{
return aigoal_table->ai_get_subsystem_type(subsystem);
}
void ai_goal_purge_invalid_goals (ai_goal *aigp, ai_goal *goal_list)
{
aigoal_table->ai_goal_purge_invalid_goals(aigp, goal_list);
}
void ai_goal_purge_all_invalid_goals (ai_goal *aigp)
{
aigoal_table->ai_goal_purge_all_invalid_goals(aigp);
}
int ai_goal_find_dockpoint (int shipnum, int dock_type)
{
return aigoal_table->ai_goal_find_dockpoint(shipnum, dock_type);
}
void ai_goal_fixup_dockpoints (ai_info *aip, ai_goal *aigp)
{
aigoal_table->ai_goal_fixup_dockpoints(aip, aigp);
}
void ai_add_goal_sub_player (int type, int mode, int submode, char *shipname, ai_goal *aigp)
{
aigoal_table->ai_add_goal_sub_player(type, mode, submode, shipname, aigp);
}
int ai_goal_find_empty_slot (ai_goal *goals, int active_goal)
{
return aigoal_table->ai_goal_find_empty_slot(goals, active_goal);
}
void ai_add_ship_goal_player (int type, int mode, int submode, char *shipname, ai_info *aip)
{
aigoal_table->ai_add_ship_goal_player(type, mode, submode, shipname, aip);
}
void ai_add_wing_goal_player (int type, int mode, int submode, char *shipname, int wingnum)
{
aigoal_table->ai_add_wing_goal_player(type, mode, submode, shipname, wingnum);
}
void ai_add_goal_sub_sexp (int sexp, int type, ai_goal *aigp, char *actor_name)
{
aigoal_table->ai_add_goal_sub_sexp(sexp, type, aigp, actor_name);
}
void ai_add_ship_goal_sexp (int sexp, int type, ai_info *aip)
{
aigoal_table->ai_add_ship_goal_sexp(sexp, type, aip);
}
void ai_add_wing_goal_sexp (int sexp, int type, int wingnum)
{
aigoal_table->ai_add_wing_goal_sexp(sexp, type, wingnum);
}
void ai_add_goal_ship_internal (ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate)
{
aigoal_table->ai_add_goal_ship_internal(aip, goal_type, name, docker_point, dockee_point, immediate);
}
void ai_add_goal_wing_internal (wing *wingp, int goal_type, char *name, int immediate)
{
aigoal_table->ai_add_goal_wing_internal(wingp, goal_type, name, immediate);
}
void ai_copy_mission_wing_goal (ai_goal *aigp, ai_info *aip)
{
aigoal_table->ai_copy_mission_wing_goal(aigp, aip);
}
int ai_mission_goal_achievable (int objnum, ai_goal *aigp)
{
return aigoal_table->ai_mission_goal_achievable(objnum, aigp);
}
int ai_goal_priority_compare (const void *a, const void *b)
{
return aigoal_table->ai_goal_priority_compare(a, b);
}
void prioritize_goals (int objnum, ai_info *aip)
{
aigoal_table->prioritize_goals(objnum, aip);
}
void validate_mission_goals (int objnum, ai_info *aip)
{
aigoal_table->validate_mission_goals(objnum, aip);
}
void ai_process_mission_orders (int objnum, ai_info *aip)
{
aigoal_table->ai_process_mission_orders(objnum, aip);
}
void ai_update_goal_references (ai_goal *goals, int type, char *old_name, char *new_name)
{
aigoal_table->ai_update_goal_references(goals, type, old_name, new_name);
}
int query_referenced_in_ai_goals (ai_goal *goals, int type, char *name)
{
return aigoal_table->query_referenced_in_ai_goals(goals, type, name);
}
char* ai_add_dock_name (char *str)
{
return aigoal_table->ai_add_dock_name(str);
}
// AL 11-17-97: A text description of the AI goals. This is used for printing out on the
// HUD what a ship's current orders are. If the AI goal doesn't correspond to something that
// ought to be printable, then NULL is used.
// JAS: Converted to a function in order to externalize the strings
char *aigoal_Ai_goal_text(int goal)
char *Ai_goal_text(int goal)
{
switch(goal) {
case 1:
@@ -980,7 +815,7 @@ char *aigoal_Ai_goal_text(int goal)
// function to maybe add the form on my wing goal for a player's starting wing. Called when a player wing arrives.
// Goober5000 - made more generic
void aigoal_ai_maybe_add_form_goal( wing *wingp )
void ai_maybe_add_form_goal( wing *wingp )
{
int j;
char *wing_leader;
@@ -1018,7 +853,7 @@ void aigoal_ai_maybe_add_form_goal( wing *wingp )
}
}
void aigoal_ai_post_process_mission()
void ai_post_process_mission()
{
object *objp;
@@ -1072,7 +907,7 @@ void aigoal_ai_post_process_mission()
}
// function which determines is a goal is valid for a particular type of ship
int aigoal_ai_query_goal_valid( int ship, int ai_goal )
int ai_query_goal_valid( int ship, int ai_goal )
{
int accepted;
@@ -1095,7 +930,7 @@ int aigoal_ai_query_goal_valid( int ship, int ai_goal )
}
// remove an ai goal from it's list. Uses the active_goal member as the goal to remove
void aigoal_ai_remove_ship_goal( ai_info *aip, int index )
void ai_remove_ship_goal( ai_info *aip, int index )
{
// only need to set the ai_mode for the particular goal to AI_GOAL_NONE
// reset ai mode to default behavior. Might get changed next time through
@@ -1115,7 +950,7 @@ void aigoal_ai_remove_ship_goal( ai_info *aip, int index )
//ai_do_default_behavior( &Objects[Ships[aip->shipnum].objnum] );
}
void aigoal_ai_clear_ship_goals( ai_info *aip )
void ai_clear_ship_goals( ai_info *aip )
{
int i;
@@ -1134,7 +969,7 @@ void aigoal_ai_clear_ship_goals( ai_info *aip )
}
}
void aigoal_ai_clear_wing_goals( int wingnum )
void ai_clear_wing_goals( int wingnum )
{
int i;
wing *wingp = &Wings[wingnum];
@@ -1164,7 +999,7 @@ void aigoal_ai_clear_wing_goals( int wingnum )
// structure of the goal to be removed. This process is slightly tricky since some member of the wing
// might be pursuing a different goal. We will have to compare based on mode, submode, priority,
// and name.. This routine is only currently called from waypoint code!!!
void aigoal_ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
{
int mode, submode, priority, i;
char *name;
@@ -1224,7 +1059,7 @@ void aigoal_ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
// routine which is called with an ai object complete it's goal. Do some action
// based on the goal what was just completed
void aigoal_ai_mission_goal_complete( ai_info *aip )
void ai_mission_goal_complete( ai_info *aip )
{
// if the active goal is dynamic or none, just return. (AI_GOAL_NONE is probably an error, but
// I don't think that this is a problem)
@@ -1236,7 +1071,7 @@ void aigoal_ai_mission_goal_complete( ai_info *aip )
}
int aigoal_ai_get_subsystem_type( char *subsystem )
int ai_get_subsystem_type( char *subsystem )
{
if ( strstr(subsystem, "engine") ) {
return SUBSYSTEM_ENGINE;
@@ -1272,7 +1107,7 @@ int aigoal_ai_get_subsystem_type( char *subsystem )
// which are destroy, etc, should get removed. goal list is the list of goals to purge. It is
// always MAX_AI_GOALS in length. This function will only get called when the goal which causes
// purging becomes valid.
void aigoal_ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list )
void ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list )
{
int i;
ai_goal *purge_goal;
@@ -1338,7 +1173,7 @@ void aigoal_ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list )
}
// function to purge the goals of *all* ships in the game based on the incoming goal structure
void aigoal_ai_goal_purge_all_invalid_goals(ai_goal *aigp)
void ai_goal_purge_all_invalid_goals(ai_goal *aigp)
{
int i;
ship_obj *sop;
@@ -1361,7 +1196,7 @@ void aigoal_ai_goal_purge_all_invalid_goals(ai_goal *aigp)
}
// Goober5000
int aigoal_ai_goal_find_dockpoint(int shipnum, int dock_type)
int ai_goal_find_dockpoint(int shipnum, int dock_type)
{
int dock_index = -1;
int loop_count = 0;
@@ -1412,7 +1247,7 @@ int aigoal_ai_goal_find_dockpoint(int shipnum, int dock_type)
// passed are the pointer to goal we are working with. aip if the ai_info pointer
// of the ship with the order. aigp is a pointer to the goal (of aip) of which we are
// fixing up the docking points
void aigoal_ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
{
int shipnum, docker_index, dockee_index;
@@ -1483,7 +1318,7 @@ void aigoal_ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
// from the mission goals (i.e. those goals which come from events) in that we don't
// use sexpressions for goals from the player...so we enumerate all the parameters
void aigoal_ai_add_goal_sub_player(int type, int mode, int submode, char *shipname, ai_goal *aigp )
void ai_add_goal_sub_player(int type, int mode, int submode, char *shipname, ai_goal *aigp )
{
Assert ( (type == AIG_TYPE_PLAYER_WING) || (type == AIG_TYPE_PLAYER_SHIP) );
@@ -1524,7 +1359,7 @@ void aigoal_ai_add_goal_sub_player(int type, int mode, int submode, char *shipna
// friendlies want to rearm at the same time. The support ship forgets what it's doing and flies
// off to repair somebody while still docked. I reproduced this with retail, so it's not a bug in
// my new docking code. :)
int aigoal_ai_goal_find_empty_slot( ai_goal *goals, int active_goal )
int ai_goal_find_empty_slot( ai_goal *goals, int active_goal )
{
int gindex, oldest_index;
@@ -1554,7 +1389,7 @@ int aigoal_ai_goal_find_empty_slot( ai_goal *goals, int active_goal )
// is issued to ship or wing (from player), mode is AI_GOAL_*. submode is the submode the
// ship should go into. shipname is the object of the action. aip is the ai_info pointer
// of the ship receiving the order
void aigoal_ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip )
void ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip )
{
int empty_index;
ai_goal *aigp;
@@ -1580,7 +1415,7 @@ void aigoal_ai_add_ship_goal_player( int type, int mode, int submode, char *ship
// adds a goal from the player to the given wing (which in turn will add it to the proper
// ships in the wing
void aigoal_ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, int wingnum )
void ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, int wingnum )
{
int i, empty_index;
wing *wingp = &Wings[wingnum];
@@ -1604,7 +1439,7 @@ void aigoal_ai_add_wing_goal_player( int type, int mode, int submode, char *ship
// common routine to add a sexpression mission goal to the appropriate goal structure.
void aigoal_ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
{
int node, dummy, op;
char *text;
@@ -1795,7 +1630,7 @@ void aigoal_ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor
// adds an ai goal for an individual ship
// type determines who has issues this ship a goal (i.e. the player/mission event/etc)
void aigoal_ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip )
void ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip )
{
int gindex;
@@ -1804,7 +1639,7 @@ void aigoal_ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip )
}
// code to add ai goals to wings.
void aigoal_ai_add_wing_goal_sexp(int sexp, int type, int wingnum)
void ai_add_wing_goal_sexp(int sexp, int type, int wingnum)
{
int i;
wing *wingp = &Wings[wingnum];
@@ -1838,7 +1673,7 @@ void aigoal_ai_add_wing_goal_sexp(int sexp, int type, int wingnum)
// this name can be a shipname or a wingname)
// docker_point and dockee_point are used for the AI_GOAL_DOCK command to tell two ships where to dock
// immediate means to process this order right away
void aigoal_ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate )
void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate )
{
int gindex;
ai_goal *aigp;
@@ -1918,7 +1753,7 @@ void aigoal_ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name,
// across waves of the wing so we merely need to add the goal to each ship in the wing. Certain
// goal are simply not valid for wings (like dock, undock). Immediate parameter gets passed to add_ship_goal
// to say whether or not we should process this goal right away
void aigoal_ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate )
void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate )
{
int i;
@@ -1934,7 +1769,7 @@ void aigoal_ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, i
}
// this function copies goals from a wing to an ai_info * from a ship.
void aigoal_ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
{
int j;
@@ -1955,7 +1790,7 @@ void aigoal_ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
// function to determine if an ai goal is achieveable or not. Will return
// one of the AI_GOAL_* values. Also determines is a goal was successful.
int aigoal_ai_mission_goal_achievable( int objnum, ai_goal *aigp )
int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
{
int status;
char *ai_shipname;
@@ -2434,7 +2269,7 @@ int aigoal_ai_mission_goal_achievable( int objnum, ai_goal *aigp )
// Compare function for sorting ai_goals based on priority.
// Return values set to sort array in _decreasing_ order.
int aigoal_ai_goal_priority_compare(const void *a, const void *b)
int ai_goal_priority_compare(const void *a, const void *b)
{
ai_goal *ga, *gb;
@@ -2483,7 +2318,7 @@ int aigoal_ai_goal_priority_compare(const void *a, const void *b)
// Then sort on time for goals of equivalent priority.
// objnum The object number to act upon. Redundant with *aip.
// *aip The AI info to act upon. Goals are stored at aip->goals
void aigoal_prioritize_goals(int objnum, ai_info *aip)
void prioritize_goals(int objnum, ai_info *aip)
{
// First sort based on priority field.
insertion_sort(aip->goals, MAX_AI_GOALS, sizeof(ai_goal), ai_goal_priority_compare);
@@ -2493,7 +2328,7 @@ void aigoal_prioritize_goals(int objnum, ai_info *aip)
// Remove obsolete goals.
// objnum Object of interest. Redundant with *aip.
// *aip contains goals at aip->goals.
void aigoal_validate_mission_goals(int objnum, ai_info *aip)
void validate_mission_goals(int objnum, ai_info *aip)
{
int i;
@@ -2568,7 +2403,7 @@ extern char *Mode_text[MAX_AI_BEHAVIORS];
// code to process ai "orders". Orders include those determined from the mission file and those
// given by the player to a ship that is under his control. This function gets called for every
// AI object every N seconds through the ai loop.
void aigoal_ai_process_mission_orders( int objnum, ai_info *aip )
void ai_process_mission_orders( int objnum, ai_info *aip )
{
object *objp = &Objects[objnum];
object *other_obj;
@@ -2889,7 +2724,7 @@ void aigoal_ai_process_mission_orders( int objnum, ai_info *aip )
}
void aigoal_ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *new_name)
void ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *new_name)
{
int i, mode, flag, dummy;
@@ -2956,7 +2791,7 @@ void aigoal_ai_update_goal_references(ai_goal *goals, int type, char *old_name,
}
}
int aigoal_query_referenced_in_ai_goals(ai_goal *goals, int type, char *name)
int query_referenced_in_ai_goals(ai_goal *goals, int type, char *name)
{
int i, mode, flag;
@@ -3021,7 +2856,7 @@ int aigoal_query_referenced_in_ai_goals(ai_goal *goals, int type, char *name)
return 0;
}
char *aigoal_ai_add_dock_name(char *str)
char *ai_add_dock_name(char *str)
{
char *ptr;
int i;
@@ -3036,39 +2871,3 @@ char *aigoal_ai_add_dock_name(char *str)
strcpy(ptr, str);
return ptr;
}
struct aigoal_call_table AIGoalDefaultTable = {
aigoal_Ai_goal_text,
aigoal_ai_maybe_add_form_goal,
aigoal_ai_post_process_mission,
aigoal_ai_query_goal_valid,
aigoal_ai_remove_ship_goal,
aigoal_ai_clear_ship_goals,
aigoal_ai_clear_wing_goals,
aigoal_ai_mission_wing_goal_complete,
aigoal_ai_mission_goal_complete,
aigoal_ai_get_subsystem_type,
aigoal_ai_goal_purge_invalid_goals,
aigoal_ai_goal_purge_all_invalid_goals,
aigoal_ai_goal_find_dockpoint,
aigoal_ai_goal_fixup_dockpoints,
aigoal_ai_add_goal_sub_player,
aigoal_ai_goal_find_empty_slot,
aigoal_ai_add_ship_goal_player,
aigoal_ai_add_wing_goal_player,
aigoal_ai_add_goal_sub_sexp,
aigoal_ai_add_ship_goal_sexp,
aigoal_ai_add_wing_goal_sexp,
aigoal_ai_add_goal_ship_internal,
aigoal_ai_add_goal_wing_internal,
aigoal_ai_copy_mission_wing_goal,
aigoal_ai_mission_goal_achievable,
aigoal_ai_goal_priority_compare,
aigoal_prioritize_goals,
aigoal_validate_mission_goals,
aigoal_ai_process_mission_orders,
aigoal_ai_update_goal_references,
aigoal_query_referenced_in_ai_goals,
aigoal_ai_add_dock_name
};
-44
View File
@@ -292,48 +292,4 @@ extern int ai_query_goal_valid( int ship, int ai_goal );
extern void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate = 1 );
extern void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate = 1 );
// AI Goal Table Wrapper
struct aigoal_call_table
{
char* (*Ai_goal_text) (int goal);
void (*ai_maybe_add_form_goal) (wing *wingp);
void (*ai_post_process_mission) ();
int (*ai_query_goal_valid) (int ship, int ai_goal);
void (*ai_remove_ship_goal) (ai_info *aip, int index);
void (*ai_clear_ship_goals) (ai_info *aip);
void (*ai_clear_wing_goals) (int wingnum);
void (*ai_mission_wing_goal_complete) (int wingnum, ai_goal *remove_goalp);
void (*ai_mission_goal_complete) (ai_info *aip);
int (*ai_get_subsystem_type) (char *subsystem);
void (*ai_goal_purge_invalid_goals) (ai_goal *aigp, ai_goal *goal_list);
void (*ai_goal_purge_all_invalid_goals) (ai_goal *aigp);
int (*ai_goal_find_dockpoint) (int shipnum, int dock_type);
void (*ai_goal_fixup_dockpoints) (ai_info *aip, ai_goal *aigp);
void (*ai_add_goal_sub_player) (int type, int mode, int submode, char *shipname, ai_goal *aigp);
int (*ai_goal_find_empty_slot) (ai_goal *goals, int active_goal);
void (*ai_add_ship_goal_player) (int type, int mode, int submode, char *shipname, ai_info *aip);
void (*ai_add_wing_goal_player) (int type, int mode, int submode, char *shipname, int wingnum);
void (*ai_add_goal_sub_sexp) (int sexp, int type, ai_goal *aigp, char *actor_name);
void (*ai_add_ship_goal_sexp) (int sexp, int type, ai_info *aip);
void (*ai_add_wing_goal_sexp) (int sexp, int type, int wingnum);
void (*ai_add_goal_ship_internal) (ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate);
void (*ai_add_goal_wing_internal) (wing *wingp, int goal_type, char *name, int immediate);
void (*ai_copy_mission_wing_goal) (ai_goal *aigp, ai_info *aip);
int (*ai_mission_goal_achievable) (int objnum, ai_goal *aigp);
int (*ai_goal_priority_compare) (const void *a, const void *b);
void (*prioritize_goals) (int objnum, ai_info *aip);
void (*validate_mission_goals) (int objnum, ai_info *aip);
void (*ai_process_mission_orders) (int objnum, ai_info *aip);
void (*ai_update_goal_references) (ai_goal *goals, int type, char *old_name, char *new_name);
int (*query_referenced_in_ai_goals) (ai_goal *goals, int type, char *name);
char* (*ai_add_dock_name) (char *str);
};
// Set new pointer to override ai_goal* function calls
// possibly copying the old function calls first
extern struct aigoal_call_table *aigoal_table;
extern struct aigoal_call_table AIGoalDefaultTable;
#endif
-255
View File
@@ -10,22 +10,6 @@
#ifndef _AIINTERNAL_H
#define _AIINTERNAL_H
#include "weapon/weapon.h"
#include "weapon/swarm.h"
#include "object/objectdock.h"
typedef struct eval_nearest_objnum {
int objnum;
object *trial_objp;
int enemy_team_mask;
int enemy_wing;
float range;
int max_attackers;
int nearest_objnum;
float nearest_dist;
int check_danger_weapon_objnum;
} eval_nearest_objnum;
//Returns true if the specified object is a stealth ship, false if not
bool is_object_stealth_ship(object* objp);
@@ -44,243 +28,4 @@ int check_ok_to_fire(int objnum, int target_objnum, weapon_info *wip);
//Does all the stuff needed to aim and fire a turret.
void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum);
// AI Turret Table Wrapper
struct eval_enemy_obj_struct;
struct aiturret_call_table
{
int (*turret_select_best_weapon) (ship_subsys *turret, object *target);
int (*valid_turret_enemy) (object *objp, object *turret_parent);
void (*evaluate_obj_as_target) (object *objp, eval_enemy_obj_struct *eeo);
int (*get_nearest_turret_objnum) (int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag);
int (*find_turret_enemy) (ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov);
int (*turret_should_pick_new_target) (ship_subsys *turret);
void (*turret_set_next_fire_timestamp) (int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip);
int (*turret_should_fire_aspect) (ship_subsys *turret, float dot, weapon_info *wip);
bool (*turret_fire_weapon) (int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos, float flak_range_override);
void (*turret_swarm_fire_from_turret) (turret_swarm_info *tsi);
void (*ai_fire_from_turret) (ship *shipp, ship_subsys *ss, int parent_objnum);
};
// Set new pointer to override ai_goal* function calls
// possibly copying the old function calls first
extern struct aiturret_call_table *aiturret_table;
extern struct aiturret_call_table AITurretDefaultTable;
// AI Code Table Wrapper
struct aicode_call_table
{
void (*ai_set_rearm_status) (int team, int time);
int (*ai_good_time_to_rearm) (object *objp);
void (*ai_good_secondary_time) (int team, int weapon_index, int max_fire_count, char *shipname);
int (*is_preferred_weapon) (int weapon_num, object *firer_objp, object *target_objp);
void (*ai_init_secondary_info) ();
void (*free_ai_stuff) ();
void (*parse_ai_class) ();
void (*reset_ai_class_names) ();
void (*parse_aitbl) ();
void (*ai_init) ();
void (*ai_level_init) ();
int (*ai_is_stealth_visible) (object *viewer_objp, object *stealth_objp);
void (*update_ai_stealth_info_with_error) (ai_info *aip);
void (*ai_update_danger_weapon) (int attacked_objnum, int weapon_objnum);
void (*ai_turn_towards_vector) (vec3d *dest, object *objp, float frametime, float turn_time, vec3d *slide_vec, vec3d *rel_pos, float bank_override, int flags, vec3d *rvec, int sexp_flags);
void (*init_ship_info) ();
int (*set_target_objnum) (ai_info *aip, int objnum);
ship_subsys* (*set_targeted_subsys) (ai_info *aip, ship_subsys *new_subsys, int parent_objnum);
void (*ai_object_init) (object *obj, int ai_index);
void (*adjust_accel_for_docking) (ai_info *aip);
void (*accelerate_ship) (ai_info *aip, float accel);
void (*change_acceleration) (ai_info *aip, float delta_accel);
void (*set_accel_for_target_speed) (object *objp, float tspeed);
void (*turn_towards_point) (object *objp, vec3d *point, vec3d *slide_vec, float bank_override);
void (*turn_away_from_point) (object *objp, vec3d *point, float bank_override);
float (*turn_towards_tangent) (object *objp, vec3d *point, float radius);
float (*turn_toward_tangent_with_axis) (object *objp, object *center_objp, float radius);
int (*object_is_targetable) (object *target, ship *viewer);
int (*num_enemies_attacking) (int objnum);
float (*get_wing_lowest_max_speed) (object *objp);
int (*is_ignore_object_sub) (int *ignore_objnum, int *ignore_signature, int objnum);
int (*find_ignore_new_object_index) (ai_info *aip, int objnum);
int (*is_ignore_object) (ai_info *aip, int objnum, int just_the_original=0);
int (*get_nearest_bbox_point) (object *ship_obj, vec3d *start, vec3d *box_pt);
void (*evaluate_object_as_nearest_objnum) (eval_nearest_objnum *eno);
int (*get_nearest_objnum) (int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers);
int (*find_nearby_threat) (int objnum, int enemy_team_mask, float range, int *count);
int (*num_turrets_attacking) (object *turret_parent, int target_objnum);
int (*get_enemy_timestamp) ();
int (*find_enemy) (int objnum, float range, int max_attackers);
void (*ai_set_goal_maybe_abort_dock) (object *objp, ai_info *aip);
void (*force_avoid_player_check) (object *objp, ai_info *aip);
void (*ai_attack_object) (object *attacker, object *attacked, int priority, ship_subsys *ssp);
void (*ai_attack_wing) (object *attacker, int wingnum, int priority);
void (*ai_evade_object) (object *evader, object *evaded, int priority);
int (*compact_ignore_new_objects) (ai_info *aip, int force=0);
void (*ai_ignore_object) (object *ignorer, object *ignored, int priority, int ignore_new);
void (*ai_ignore_wing) (object *ignorer, int wingnum, int priority);
void (*create_model_path) (object *pl_objp, object *mobjp, int path_num, int subsys_path);
void (*create_model_exit_path) (object *pl_objp, object *mobjp, int path_num, int count);
void (*ai_find_path) (object *pl_objp, int objnum, int path_num, int exit_flag, int subsys_path);
int (*maybe_avoid_player) (object *objp, vec3d *goal_pos);
void (*ai_stay_still) (object *still_objp, vec3d *view_pos);
void (*ai_do_objects_docked_stuff) (object *docker, int docker_point, object *dockee, int dockee_point);
void (*ai_do_objects_undocked_stuff) (object *docker, object *dockee);
void (*ai_dock_with_object) (object *docker, int docker_index, object *dockee, int dockee_index, int priority, int dock_type);
void (*ai_start_fly_to_ship) (object *objp, int shipnum);
void (*ai_start_waypoints) (object *objp, int waypoint_list_index, int wp_flags);
void (*ai_do_stay_near) (object *objp, object *other_objp, float dist);
void (*ai_do_safety) (object *objp);
void (*ai_form_on_wing) (object *objp, object *goal_objp);
int (*ai_formation_object_get_slotnum) (int objnum, object *objp);
float (*compute_time_to_enemy) (float dist_to_enemy, object *pobjp, object *eobjp);
void (*ai_set_positions) (object *pl_objp, object *en_objp, ai_info *aip, vec3d *player_pos, vec3d *enemy_pos);
float (*maybe_recreate_path) (object *objp, ai_info *aip, int force_recreate_flag, int override_hash=0);
void (*set_accel_for_docking) (object *objp, ai_info *aip, float dot, float dot_to_next, float dist_to_next, float dist_to_goal, ship_info *sip);
float (*ai_path) ();
void (*ai_safety_pick_spot) (object *objp);
float (*ai_safety_goto_spot) (object *objp);
void (*ai_safety_circle_spot) (object *objp);
void (*ai_safety) ();
void (*ai_fly_to_ship) ();
void (*ai_waypoints) ();
void (*avoid_ship) ();
int (*maybe_resume_previous_mode) (object *objp, ai_info *aip);
int (*ai_maybe_fire_afterburner) (object *objp, ai_info *aip);
void (*maybe_afterburner_after_ship_hit) (object *objp, ai_info *aip, object *en_objp);
int (*is_instructor) (object *objp);
void (*evade_weapon) ();
void (*slide_face_ship) ();
void (*evade_ship) ();
void (*ai_evade) ();
int (*ai_select_primary_weapon_OLD) (object *objp, object *other_objp, int flags);
int (*ai_select_primary_weapon) (object *objp, object *other_objp, int flags);
void (*set_primary_weapon_linkage) (object *objp);
int (*ai_fire_primary_weapon) (object *objp);
void (*ai_select_secondary_weapon) (object *objp, ship_weapon *swp, int priority1=-1, int priority2=-1);
void (*ai_maybe_announce_shockwave_weapon) (object *firing_objp, int weapon_index);
int (*check_ok_to_fire) (int objnum, int target_objnum, weapon_info *wip);
int (*ai_fire_secondary_weapon) (object *objp, int priority1, int priority2);
void (*set_predicted_enemy_pos_turret) (vec3d *predicted_enemy_pos, vec3d *gun_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, float weapon_speed, float time_enemy_in_range);
void (*set_predicted_enemy_pos) (vec3d *predicted_enemy_pos, object *pobjp, object *eobjp, ai_info *aip);
void (*ai_chase_ct) ();
void (*ai_chase_eb) (ai_info *aip, ship_info *sip, vec3d *predicted_enemy_pos, float dist_to_enemy);
float (*ai_endangered_time) (object *ship_objp, object *weapon_objp);
float (*ai_endangered_by_weapon) (ai_info *aip);
int (*ai_near_full_strength) (object *objp);
void (*attack_set_accel) (ai_info *aip, float dist_to_enemy, float dot_to_enemy, float dot_from_enemy);
void (*get_behind_ship) (ai_info *aip, ship_info *sip, float dist_to_enemy);
int (*avoid_player) (object *objp, vec3d *goal_pos);
int (*maybe_avoid_big_ship) (object *objp, object *ignore_objp, ai_info *aip, vec3d *goal_point, float delta_time);
void (*ai_stealth_find) ();
void (*ai_stealth_sweep) ();
void (*ai_chase_attack) (ai_info *aip, ship_info *sip, vec3d *predicted_enemy_pos, float dist_to_enemy, int modelnum);
void (*ai_chase_es) (ai_info *aip, ship_info *sip);
void (*ai_chase_ga) (ai_info *aip, ship_info *sip);
int (*ai_set_attack_subsystem) (object *objp, int subnum);
void (*ai_set_guard_vec) (object *objp, object *guard_objp);
void (*ai_set_guard_wing) (object *objp, int wingnum);
void (*ai_set_evade_object) (object *objp, object *other_objp);
void (*ai_set_guard_object) (object *objp, object *other_objp);
void (*update_aspect_lock_information) (ai_info *aip, vec3d *vec_to_enemy, float dist_to_enemy, float enemy_radius);
void (*ai_chase_fly_away) (object *objp, ai_info *aip);
int (*has_preferred_secondary) (object *objp, object *en_objp, ship_weapon *swp);
void (*ai_choose_secondary_weapon) (object *objp, ai_info *aip, object *en_objp);
float (*set_secondary_fire_delay) (ai_info *aip, ship *shipp, weapon_info *swip);
void (*ai_chase_big_approach_set_goal) (vec3d *goal_pos, object *attack_objp, object *target_objp, float *accel);
void (*ai_chase_big_circle_set_goal) (vec3d *goal_pos, object *attack_objp, object *target_objp, float *accel);
void (*ai_chase_big_get_separations) (object *attack_objp, object *target_objp, vec3d *horz_vec_to_target, float *desired_separation, float *cur_separation);
void (*ai_chase_big_parallel_set_goal) (vec3d *goal_pos, object *attack_objp, object *target_objp, float *accel);
void (*ai_cruiser_chase_set_goal_pos) (vec3d *goal_pos, object *pl_objp, object *en_objp);
int (*maybe_hack_cruiser_chase_abort) ();
void (*ai_cruiser_chase) ();
void (*ai_chase) ();
int (*num_ships_attacking) (int target_objnum);
void (*remove_farthest_attacker) (int objnum);
int (*ai_maybe_limit_attackers) (int attacked_objnum);
void (*guard_object_was_hit) (object *guard_objp, object *hitter_objp);
void (*maybe_update_guard_object) (object *hit_objp, object *hitter_objp);
int (*ai_guard_find_nearby_bomb) (object *guarding_objp, object *guarded_objp);
void (*ai_guard_find_nearby_ship) (object *guarding_objp, object *guarded_objp);
void (*ai_guard_find_nearby_asteroid) (object *guarding_objp, object *guarded_objp);
void (*ai_guard_find_nearby_object) ();
void (*ai_big_guard) ();
void (*ai_guard) ();
void (*ai_do_objects_repairing_stuff) (object *repaired_objp, object *repair_objp, int how);
void (*ai_cleanup_dock_mode_subjective) (object *objp);
void (*ai_cleanup_dock_mode_objective) (object *objp);
void (*ai_cleanup_rearm_mode) (object *objp);
void (*ai_still) ();
void (*ai_stay_near) ();
int (*maybe_dock_obstructed) (object *cur_objp, object *goal_objp, int big_only_flag);
void (*ai_dock) ();
void (*process_subobjects) (int objnum);
void (*ai_fly_in_formation) (int wingnum);
void (*ai_disband_formation) (int wingnum);
int (*formation_is_leader_chaotic) (object *objp);
void (*ai_most_massive_object_of_its_wing_of_all_docked_objects_helper) (object *objp, dock_function_info *infop);
int (*ai_formation) ();
void (*ai_do_repair_frame) (object *objp, ai_info *aip, float frametime);
void (*call_doa) (object *child, object *parent);
void (*ai_maybe_launch_cmeasure) (object *objp, ai_info *aip);
void (*ai_preprocess_ignore_objnum) (object *objp, ai_info *aip);
void (*ai_chase_circle) (object *objp);
void (*ai_transfer_shield) (object *objp, int quadrant_num);
void (*ai_balance_shield) (object *objp);
void (*ai_manage_shield) (object *objp, ai_info *aip);
void (*ai_maybe_evade_locked_missile) (object *objp, ai_info *aip);
void (*maybe_evade_dumbfire_weapon) (ai_info *aip);
int (*ai_acquire_emerge_path) (object *pl_objp, int parent_objnum, int allowed_path_mask, vec3d *pos, vec3d *fvec);
void (*ai_emerge_bay_path_cleanup) (ai_info *aip);
void (*ai_bay_emerge) ();
int (*ai_find_closest_depart_path) (ai_info *aip, polymodel *pm, int allowed_path_mask);
int (*ai_acquire_depart_path) (object *pl_objp, int parent_objnum, int allowed_path_mask);
void (*ai_bay_depart) ();
void (*ai_sentrygun) ();
void (*ai_execute_behavior) (ai_info *aip);
int (*maybe_request_support) (object *objp);
void (*ai_set_mode_warp_out) (object *objp, ai_info *aip);
void (*ai_maybe_depart) (object *objp);
void (*ai_warp_out) (object *objp);
void (*ai_announce_ship_dying) (object *dying_objp);
int (*aas_1) (object *objp, ai_info *aip, vec3d *safe_pos);
int (*ai_avoid_shockwave) (object *objp, ai_info *aip);
int (*ai_await_repair_frame) (object *objp, ai_info *aip);
void (*ai_maybe_self_destruct) (object *objp, ai_info *aip);
int (*ai_need_new_target) (object *pl_objp, int target_objnum);
int (*maybe_big_ship_collide_recover_frame) (object *objp, ai_info *aip);
void (*validate_mode_submode) (ai_info *aip);
void (*ai_frame) (int objnum);
void (*ai_process) (object *obj, int ai_index, float frametime);
void (*init_ai_object) (int objnum);
void (*init_ai_objects) ();
void (*init_ai_system) ();
void (*ai_set_default_behavior) (object *obj, int classnum);
void (*ai_do_default_behavior) (object *obj);
void (*process_friendly_hit_message) (int message, object *objp);
void (*maybe_process_friendly_hit) (object *objp_hitter, object *objp_hit, object *objp_weapon);
void (*maybe_set_dynamic_chase) (ai_info *aip, int hitter_objnum);
void (*big_ship_collide_recover_start) (object *objp, object *big_objp, vec3d *collide_pos, vec3d *collision_normal);
void (*ai_update_lethality) (object *ship_obj, object *other_obj, float damage);
void (*ai_ship_hit) (object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_quadrant, vec3d *hit_normal);
void (*ai_ship_destroy) (int shipnum, int method);
void (*ai_deathroll_start) (object *dying_objp);
int (*ai_abort_rearm_request) (object *requester_objp);
void (*ai_add_rearm_goal) (object *requester_objp, object *support_objp);
int (*ai_issue_rearm_request) (object *requester_objp);
void (*ai_rearm_repair) (object *objp, int docker_index, object *goal_objp, int dockee_index, int priority);
void (*cheat_fire_synaptic) (object *objp, ship *shipp, ai_info *aip);
void (*maybe_cheat_fire_synaptic) (object *objp, ai_info *aip);
};
// Set new pointer to override ai_code* function calls
// possibly copying the old function calls first
extern struct aicode_call_table *aicode_table;
extern struct aicode_call_table AICodeDefaultTable;
#endif
-185
View File
@@ -1,185 +0,0 @@
/**
* @file aimodular.cpp
* @brief Modular loading of new AI code based on name in AI Profile.
*
* The ai_module_init function should be called by ai_init.
*
* @author Fabian Franz <[email protected]>
*
*/
#include "ai/aibig.h"
#include "ai/aigoals.h"
#include "ai/aiinternal.h"
#ifdef _WIN32
#include <Windows.h>
/** @brief Wrapper for the dlopen functions for Windows */
#define dlopen(x,y) ((x==NULL)?GetModuleHandle(x):LoadLibrary(x))
#define dlsym GetProcAddress
#define dlclose FreeLibrary
static HINSTANCE handle = NULL; /**< @brief Handle for the loaded library */
#else
#include <dlfcn.h>
static void* handle = NULL; /**< @brief Handle for the loaded library */
#endif
/** @brief ai_module_init_function prototype */
typedef void (*ai_module_init_function)(void);
void ai_module_dlclose(void);
/**
* @brief Fallback function to load new AI from same process image.
*
* This function is used if no dynamic library with the name can be found
* or it does not contain the correct symbol.
*
* @param func_name The symbol to look for in handle
* @return Returns 0 on success and -1,-2 on errors
*
*/
int ai_module_dlopen_process(char* func_name)
{
ai_module_init_function ai_module_init_func;
// Maybe close handle first
ai_module_dlclose();
handle = dlopen(NULL, RTLD_NOW);
if (handle == NULL)
return -1;
ai_module_init_func=(ai_module_init_function)dlsym(handle, func_name);
#ifdef _WIN32
// Under WIN32 GetModuleHandle is not
// incrementing the reference counter
// so we need to "free" the handle directly
handle=NULL;
#endif
if (ai_module_init_func == NULL)
return -2;
ai_module_init_func();
return 0;
}
/**
* @brief Loads new AI from dynamic library
*
* This function looks for dllname.dll or dllname.so
* tries to load it into memory and if it finds the
* dllname_ai_module_init function it starts it.
*
* If it does not find the library or symbol it falls
* back to ai_module_dlopen_process.
*
* @param dllname The name of the library to load
* @return Returns 0 on success and -1,-2 on errors
*
*/
int ai_module_dlopen(char* dllname)
{
char buf[PATH_MAX+1];
char init_func_name[PATH_MAX+1];
ai_module_init_function ai_module_init_func;
#ifdef _WIN32
snprintf(buf, PATH_MAX, "%s.dll", dllname);
#else
snprintf(buf, PATH_MAX, "%s.so", dllname);
#endif
snprintf(init_func_name, PATH_MAX, "%s_ai_module_init", dllname);
handle = dlopen(buf, RTLD_NOW);
if (handle == NULL)
return ai_module_dlopen_process(init_func_name);
ai_module_init_func=(ai_module_init_function)dlsym(handle, init_func_name);
if (ai_module_init_func == NULL)
return ai_module_dlopen_process(init_func_name);
ai_module_init_func();
return 0;
}
/**
* @brief Closes the library handle
*
* This function closes the library handle.
*
*/
void ai_module_dlclose(void)
{
if (handle != NULL)
{
dlclose(handle);
handle=NULL;
}
}
/**
* @brief Inits or resets the AI code tables
*
* This function first resets the AI code tables,
* then closes any open libraries from before.
*
* Then it ooks if the ai_module is not "retail"
* and if that is the case it loads a library with this name.
*
*/
void ai_module_init(void)
{
// First Reset values
aibig_table = &AIBigDefaultTable;
aicode_table = &AICodeDefaultTable;
aigoal_table = &AIGoalDefaultTable;
aiturret_table = &AITurretDefaultTable;
ai_module_dlclose();
if (The_mission.ai_profile == NULL)
return;
if (strncmp(The_mission.ai_profile->ai_module, "retail", 6) != 0)
{
if (ai_module_dlopen(The_mission.ai_profile->ai_module) != 0)
{
char err[1024];
snprintf(err, sizeof(err), "AI_module_init(%s) failed: %s\n", The_mission.ai_profile->ai_module, dlerror());
mprintf(err);
}
}
}
extern "C" {
void newai_ai_module_init(void);
}
/**
* @brief Dummy function
*
* This dummy functions calls all AI implementations
* that should be statically included.
*
*/
void ai_module_dummy()
{
newai_ai_module_init();
}
-6
View File
@@ -1,6 +0,0 @@
#ifndef _AIMODULAR_H
#define _AIMODULAR_H
void ai_module_init(void);
#endif
+22 -89
View File
@@ -233,69 +233,6 @@ typedef struct eval_enemy_obj_struct {
int nearest_objnum;
} eval_enemy_obj_struct;
// FF 17-06-07
// AI Turret Table Wrapper
struct aiturret_call_table *aiturret_table = &AITurretDefaultTable;
int turret_select_best_weapon (ship_subsys *turret, object *target)
{
return aiturret_table->turret_select_best_weapon(turret, target);
}
int valid_turret_enemy (object *objp, object *turret_parent)
{
return aiturret_table->valid_turret_enemy(objp, turret_parent);
}
void evaluate_obj_as_target (object *objp, eval_enemy_obj_struct *eeo)
{
aiturret_table->evaluate_obj_as_target(objp, eeo);
}
int get_nearest_turret_objnum (int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag)
{
return aiturret_table->get_nearest_turret_objnum(turret_parent_objnum, turret_subsys, enemy_team_mask, tpos, tvec, current_enemy, big_only_flag, small_only_flag, tagged_only_flag, beam_flag);
}
int find_turret_enemy (ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov)
{
return aiturret_table->find_turret_enemy(turret_subsys, objnum, tpos, tvec, current_enemy, fov);
}
int turret_should_pick_new_target (ship_subsys *turret)
{
return aiturret_table->turret_should_pick_new_target(turret);
}
void turret_set_next_fire_timestamp (int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip)
{
aiturret_table->turret_set_next_fire_timestamp(weapon_num, wip, turret, aip);
}
int turret_should_fire_aspect (ship_subsys *turret, float dot, weapon_info *wip)
{
return aiturret_table->turret_should_fire_aspect(turret, dot, wip);
}
bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos = NULL, float flak_range_override = 100.0f)
{
return aiturret_table->turret_fire_weapon(weapon_num, turret, parent_objnum, turret_pos, turret_fvec, predicted_pos, flak_range_override);
}
void turret_swarm_fire_from_turret (turret_swarm_info *tsi)
{
aiturret_table->turret_swarm_fire_from_turret(tsi);
}
void ai_fire_from_turret (ship *shipp, ship_subsys *ss, int parent_objnum)
{
aiturret_table->ai_fire_from_turret(shipp, ss, parent_objnum);
}
// AI Turret default implementation
// return 1 if objp is in fov of the specified turret, tp. Otherwise return 0.
// dist = distance from turret to center point of object
int object_in_turret_fov(object *objp, model_subsystem *tp, vec3d *tvec, vec3d *tpos, float dist)
@@ -337,7 +274,7 @@ int bomb_headed_towards_ship(object *bomb_objp, object *ship_objp)
//Note that all non-negative return values are expressed in
//what I like to call "widx"s.
//Returns -1 if unable to find a weapon for the target at all.
int aiturret_turret_select_best_weapon(ship_subsys *turret, object *target)
int turret_select_best_weapon(ship_subsys *turret, object *target)
{
//TODO: Fill this out with extraodinary gun-picking algorithms
if(turret->weapons.num_primary_banks > 0)
@@ -504,7 +441,7 @@ float longest_turret_weapon_range(ship_weapon *swp)
// input: objp => object that turret is considering as an enemy
// turret_parent => object index for ship that turret sits on
// turret => turret pointer
int aiturret_valid_turret_enemy(object *objp, object *turret_parent)
int valid_turret_enemy(object *objp, object *turret_parent)
{
if ( objp == turret_parent ) {
return 0;
@@ -568,7 +505,7 @@ int aiturret_valid_turret_enemy(object *objp, object *turret_parent)
}
extern int Player_attacking_enabled;
void aiturret_evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
{
object *turret_parent_obj = &Objects[eeo->turret_parent_objnum];
ship *shipp;
@@ -779,7 +716,7 @@ int is_target_beam_valid(ship_weapon *swp, object *objp)
// tpos => position of turret (world coords)
// tvec => forward vector of turret (world coords)
// current_enemy => objnum of current turret target
int aiturret_get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag)
int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag)
{
//float weapon_travel_dist;
int weapon_system_ok;
@@ -920,7 +857,7 @@ DCF_BOOL(use_parent_target, Use_parent_target)
// tpos => position of turret (world coords)
// tvec => forward vector of turret (world coords)
// current_enemy => objnum of current turret target
int aiturret_find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov)
int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov)
{
int enemy_team_mask, enemy_objnum;
model_subsystem *tp;
@@ -1264,7 +1201,7 @@ ship_subsys *aifft_find_turret_subsys(object *objp, ship_subsys *ssp, object *en
}
// return !0 if the specified target should scan for a new target, otherwise return 0
int aiturret_turret_should_pick_new_target(ship_subsys *turret)
int turret_should_pick_new_target(ship_subsys *turret)
{
// int target_type;
@@ -1287,7 +1224,7 @@ int aiturret_turret_should_pick_new_target(ship_subsys *turret)
}
// Set the next fire timestamp for a turret, based on weapon type and ai class
void aiturret_turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip)
void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip)
{
Assert(weapon_num < MAX_SHIP_WEAPONS);
float wait = wip->fire_wait * 1000.0f;
@@ -1343,7 +1280,7 @@ void aiturret_turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, s
}
// Decide if a turret should launch an aspect seeking missile
int aiturret_turret_should_fire_aspect(ship_subsys *turret, float dot, weapon_info *wip)
int turret_should_fire_aspect(ship_subsys *turret, float dot, weapon_info *wip)
{
if ( (dot > AICODE_TURRET_DUMBFIRE_ANGLE) && (turret->turret_time_enemy_in_range >= MIN(wip->min_lock_time,AICODE_TURRET_MAX_TIME_IN_RANGE)) ) {
return 1;
@@ -1367,7 +1304,7 @@ void turret_update_enemy_in_range(ship_subsys *turret, float seconds)
}
// Fire a weapon from a turret
bool aiturret_turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos = NULL, float flak_range_override = 100.0f)
bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos = NULL, float flak_range_override = 100.0f)
{
matrix turret_orient;
int weapon_objnum;
@@ -1418,6 +1355,11 @@ bool aiturret_turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent
// fire a beam weapon
beam_fire(&fire_info);
if (parent_ship->cloak_stage == 2) {
beam_weapon_info *bip=&wip->b_info;
shipfx_start_cloak(parent_ship,bip->beam_warmup + bip->beam_warmdown + (int)(bip->beam_life*1000.0f) + 1000);
}
return true;
}
// don't fire swam, but set up swarm info instead
@@ -1484,6 +1426,11 @@ bool aiturret_turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent
}
}
}
if ((parent_ship->cloak_stage > 0) && (parent_ship->cloak_stage < 3))
{
shipfx_start_cloak(parent_ship,500);
}
}
// reset any animations if we need to
@@ -1502,8 +1449,8 @@ bool aiturret_turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent
return true;
}
//void aiturret_turret_swarm_fire_from_turret(ship_subsys *turret, int parent_objnum, int target_objnum, ship_subsys *target_subsys)
void aiturret_turret_swarm_fire_from_turret(turret_swarm_info *tsi)
//void turret_swarm_fire_from_turret(ship_subsys *turret, int parent_objnum, int target_objnum, ship_subsys *target_subsys)
void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
{
int weapon_objnum;
matrix turret_orient;
@@ -1567,7 +1514,7 @@ int Num_find_turret_enemy = 0;
int Num_turrets_fired = 0;
// Given a turret tp and its parent parent_objnum, fire from the turret at its enemy.
extern int Nebula_sec_range;
void aiturret_ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
{
float weapon_firing_range;
@@ -2038,17 +1985,3 @@ void aiturret_ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnu
ss->turret_time_enemy_in_range = 0.0f;
}
}
struct aiturret_call_table AITurretDefaultTable = {
aiturret_turret_select_best_weapon,
aiturret_valid_turret_enemy,
aiturret_evaluate_obj_as_target,
aiturret_get_nearest_turret_objnum,
aiturret_find_turret_enemy,
aiturret_turret_should_pick_new_target,
aiturret_turret_set_next_fire_timestamp,
aiturret_turret_should_fire_aspect,
aiturret_turret_fire_weapon,
aiturret_turret_swarm_fire_from_turret,
aiturret_ai_fire_from_turret
};
-122
View File
@@ -1,122 +0,0 @@
#include "ai/aibig.h"
#include "ai/aigoals.h"
#include "ai/aiinternal.h"
struct aicode_call_table AICodeNewAITable;
#include "iff_defs/iff_defs.h"
#define DEPARTURE_HULL_PERCENT 0.3 // Departure if 15% to 30% hull strength left
void newai_ai_maybe_depart(object* objp_ship)
{
ship *shipp = &Ships[objp_ship->instance];
// Coward mode:
//
// Depart if:
// * not player and
// * same team as player and player not traitor and
// * fighter or bomber
// * hull multiplied with random value below critical
if (objp_ship->flags & OF_PLAYER_SHIP)
return;
// make sure player is on their team and not a traitor
if ((Player_ship->team != shipp->team) || (Player_ship->team == Iff_traitor))
return;
if ((Ship_info[shipp->ship_info_index].flags & (SIF_FIGHTER|SIF_BOMBER)) == 0)
return;
if (objp_ship->hull_strength*(frand()+1) < DEPARTURE_HULL_PERCENT * shipp->ship_max_hull_strength)
mission_do_departure(objp_ship);
}
// Object *objp_ship was hit by either weapon *objp_weapon or collided into by ship hit_objp at point *hitpos.
void newai_aicode_ai_ship_hit (object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_quadrant, vec3d *hit_normal)
{
// Call the default implementation
AICodeDefaultTable.ai_ship_hit(objp_ship, hit_objp, hitpos, shield_quadrant, hit_normal);
if (hit_objp->parent >= 0)
{
object *objp_hitter = &Objects[hit_objp->parent];
if ( objp_hitter->type == OBJ_SHIP )
{
ship *shipp_hitter = &Ships[objp_hitter->instance];
ship *shipp_hit = &Ships[objp_ship->instance];
fprintf(stderr, "Ship %s hit %s\n", shipp_hitter->ship_name, shipp_hit->ship_name);
}
}
newai_ai_maybe_depart(objp_ship);
}
void newai_aicode_maybe_process_friendly_hit(object *objp_hitter, object *objp_hit, object *objp_weapon)
{
AICodeDefaultTable.maybe_process_friendly_hit(objp_hitter, objp_hit, objp_weapon);
if (obj_team(objp_hitter) == obj_team(objp_hit))
{
if ( objp_hitter->type != OBJ_SHIP )
return;
ship *shipp_hitter = &Ships[objp_hitter->instance];
ship *shipp_hit = &Ships[objp_hit->instance];
fprintf(stderr, "Ship %s friendly hit %s\n", shipp_hitter->ship_name, shipp_hit->ship_name);
}
}
int newai_aicode_ai_fire_primary_weapon(object *objp)
{
int fired = AICodeDefaultTable.ai_fire_primary_weapon(objp);
if (fired)
{
ship *shipp = &Ships[objp->instance];
fprintf(stderr, "Ship %s fired primary weapon\n", shipp->ship_name);
}
}
void newai_aicode_init_ship_info()
{
static int called=0;
if (called == 0)
{
fprintf(stderr, "Init ship info was called\n");
called=1;
}
AICodeDefaultTable.init_ship_info();
}
extern "C" {
void newai_ai_module_init();
}
void newai_ai_module_init()
{
#ifdef PACKAGE_NAME
fprintf(stderr, "ai_module_init() called\n");
#else
fprintf(stderr, "ai_module_init() modular called\n");
#endif
// First make a copy
memcpy(&AICodeNewAITable, &AICodeDefaultTable, sizeof(AICodeNewAITable));
// Now set up our overridden functions
aicode_table = &AICodeNewAITable;
aicode_table->init_ship_info=newai_aicode_init_ship_info;
aicode_table->ai_ship_hit=newai_aicode_ai_ship_hit;
//aicode_table->ai_fire_primary_weapon=newai_aicode_ai_fire_primary_weapon;
//aicode_table->maybe_process_friendly_hit=newai_aicode_maybe_process_friendly_hit;
}
+6 -3
View File
@@ -4892,12 +4892,15 @@ sexp_list_item *sexp_tree::get_listing_opf(int opf, int parent_node, int arg_ind
// every-time-argument... meaning if either w_arg or e_arg is >= 1, we can continue
w_arg = find_ancestral_argument_number(OP_WHEN_ARGUMENT, current_node);
e_arg = find_ancestral_argument_number(OP_EVERY_TIME_ARGUMENT, current_node);
if (w_arg < 1 && e_arg < 1 /* && the same for any future _ARGUMENT sexps */ ) {
if (w_arg < 1 && e_arg < 1 /* && the same for any future _ARGUMENT sexps */ )
{
return list;
}
// also skip for OPF_NULL, because it takes no data (though it can take plenty of operators)
if (opf == OPF_NULL) {
// also skip if the list is empty, and *also* skip for OPF_NULL, because
// it takes no data (though it can take plenty of operators)
if (list == NULL || opf == OPF_NULL)
{
return list;
}
+7 -16
View File
@@ -231,7 +231,7 @@ void ssm_level_init()
}
// start a subspace missile effect
void ssm_create(object *target, vec3d *start, int ssm_index, ssm_firing_info *override, int team)
void ssm_create(vec3d *target, vec3d *start, int ssm_index, ssm_firing_info *override)
{
ssm_strike *ssm;
matrix dir;
@@ -280,17 +280,13 @@ void ssm_create(object *target, vec3d *start, int ssm_index, ssm_firing_info *ov
else {
// forward orientation
vec3d temp;
vm_vec_sub(&temp, &target->pos, start);
vm_vec_normalize(&temp);
vm_vec_sub(&temp, target, start);
vm_vec_normalize(&temp);
vm_vector_2_matrix(&dir, &temp, NULL, NULL);
// stuff info
ssm->sinfo.ssm_index = ssm_index;
ssm->sinfo.target = target;
ssm->sinfo.ssm_team = team;
ssm->sinfo.target = *target;
for(idx=0; idx<Ssm_info[ssm_index].count; idx++){
ssm->sinfo.delay_stamp[idx] = timestamp(200 + (int)frand_range(-199.0f, 1000.0f));
ssm_get_random_start_pos(&ssm->sinfo.start_pos[idx], start, &dir, ssm_index);
@@ -330,7 +326,6 @@ void ssm_process()
int idx, finished;
ssm_strike *moveup, *next_one;
ssm_info *si;
int weapon_objnum;
// process all strikes
moveup=GET_FIRST(&Ssm_used_list);
@@ -356,16 +351,12 @@ void ssm_process()
vec3d temp;
matrix orient;
vm_vec_sub(&temp, &moveup->sinfo.target->pos, &moveup->sinfo.start_pos[idx]);
vm_vec_sub(&temp, &moveup->sinfo.target, &moveup->sinfo.start_pos[idx]);
vm_vec_normalize(&temp);
vm_vector_2_matrix(&orient, &temp, NULL, NULL);
// fire the missile and flash the screen
weapon_objnum = weapon_create(&moveup->sinfo.start_pos[idx], &orient, si->weapon_info_index, -1, -1, 1);
Weapons[Objects[weapon_objnum].instance].team = moveup->sinfo.ssm_team;
Weapons[Objects[weapon_objnum].instance].homing_object = moveup->sinfo.target;
Weapons[Objects[weapon_objnum].instance].target_sig = moveup->sinfo.target->signature;
weapon_create(&moveup->sinfo.start_pos[idx], &orient, si->weapon_info_index, -1, -1, 1);
// this makes this particular missile done
moveup->done_flags[idx] = 1;
@@ -377,7 +368,7 @@ void ssm_process()
vec3d temp;
matrix orient;
vm_vec_sub(&temp, &moveup->sinfo.target->pos, &moveup->sinfo.start_pos[idx]);
vm_vec_sub(&temp, &moveup->sinfo.target, &moveup->sinfo.start_pos[idx]);
vm_vec_normalize(&temp);
vm_vector_2_matrix(&orient, &temp, NULL, NULL);
moveup->fireballs[idx] = fireball_create(&moveup->sinfo.start_pos[idx], FIREBALL_WARP_EFFECT, -1, si->warp_radius, 0, &vmd_zero_vector, si->warp_time, 0, &orient);
+5 -6
View File
@@ -82,12 +82,11 @@ typedef struct ssm_info {
// creation info for the strike (useful for multiplayer)
typedef struct ssm_firing_info {
int delay_stamp[MAX_SSM_COUNT]; // timestamps
vec3d start_pos[MAX_SSM_COUNT]; // start positions
int delay_stamp[MAX_SSM_COUNT]; // timestamps
vec3d start_pos[MAX_SSM_COUNT]; // start positions
int ssm_index; // index info ssm_info array
struct object* target; // target for the strike
int ssm_team; // team that fired the ssm.
int ssm_index; // index info ssm_info array
vec3d target; // target for the strike
} ssm_firing_info;
// the strike itself
@@ -120,7 +119,7 @@ void hud_artillery_update();
void hud_artillery_render();
// start a subspace missile effect
void ssm_create(object *target, vec3d *start, int ssm_index, ssm_firing_info *override, int team);
void ssm_create(vec3d *target, vec3d *start, int ssm_index, ssm_firing_info *override);
// Goober5000
extern int ssm_info_lookup(char *name);
+1 -1
View File
@@ -1472,7 +1472,7 @@ void hud_squadmsg_send_to_all_fighters( int command, int player_num )
continue;
// send the command to the wing
if ( Wings[i].current_count > 0 ) {
if ( Wings[i].current_count > 1 ) {
if ( hud_squadmsg_send_wing_command(i, command, send_message, player_num) ) {
send_message = 0;
}
+3 -12
View File
@@ -4657,11 +4657,8 @@ void hud_show_lead_indicator(vec3d *target_world_pos)
// if we've reached here, the lead target indicator will be displayed
Players[Player_num].lead_indicator_active = 1;
if(The_mission.ai_profile->flags & AIPF_USE_ADDITIVE_WEAPON_VELOCITY)
vm_vec_sub2(&target_moving_direction, &Player_obj->phys_info.vel);
// test if the target is moving at all
if ( vm_vec_mag_quick(&target_moving_direction) < 0.1f ) // Find distance!
if ( vm_vec_mag_quick(&targetp->phys_info.vel) < 0.1f && !(The_mission.ai_profile->flags & AIPF_USE_ADDITIVE_WEAPON_VELOCITY) ) // Find distance!
Players[Player_num].lead_target_pos = *target_world_pos;
else {
vm_vec_normalize(&target_moving_direction);
@@ -4729,11 +4726,8 @@ void hud_show_lead_indicator(vec3d *target_world_pos)
// if we've reached here, the lead target indicator will be displayed
Players[Player_num].lead_indicator_active = 1;
if(The_mission.ai_profile->flags & AIPF_USE_ADDITIVE_WEAPON_VELOCITY)
vm_vec_sub2(&target_moving_direction, &Player_obj->phys_info.vel);
// test if the target is moving at all
if ( vm_vec_mag_quick(&target_moving_direction) < 0.1f ) // Find distance!
if ( vm_vec_mag_quick(&targetp->phys_info.vel) < 0.1f && !(The_mission.ai_profile->flags & AIPF_USE_ADDITIVE_WEAPON_VELOCITY) ) // Find distance!
Players[Player_num].lead_target_pos = *target_world_pos;
else {
vm_vec_normalize(&target_moving_direction);
@@ -4862,11 +4856,8 @@ void hud_show_lead_indicator_quick(vec3d *target_world_pos, object *targetp)
// if we've reached here, the lead target indicator will be displayed
Players[Player_num].lead_indicator_active = 1;
if(The_mission.ai_profile->flags & AIPF_USE_ADDITIVE_WEAPON_VELOCITY)
vm_vec_sub2(&target_moving_direction, &Player_obj->phys_info.vel);
// test if the target is moving at all
if ( vm_vec_mag_quick(&target_moving_direction) < 0.1f ) // Find distance!
if ( vm_vec_mag_quick(&targetp->phys_info.vel) < 0.1f && !(The_mission.ai_profile->flags & AIPF_USE_ADDITIVE_WEAPON_VELOCITY) ) // Find distance!
Players[Player_num].lead_target_pos = *target_world_pos;
else {
vm_vec_normalize(&target_moving_direction);
-1
View File
@@ -985,7 +985,6 @@ void hud_targetbox_show_extra_ship_info(ship *target_shipp, object *target_objp)
if (dock_count == 1)
{
sprintf(outstr, XSTR("Docked: %s", 339), Ships[dock_get_first_docked_object(target_objp)->instance].ship_name);
end_string_at_first_hash_symbol(outstr);
}
// docked to multiple objects
else
+1 -3
View File
@@ -1990,9 +1990,7 @@ void message_queue_process()
// if this is a ship do we use name or alt name?
if ( Message_shipnum != -1 && (Ships[Message_shipnum].flags2 & SF2_USE_ALT_NAME_AS_CALLSIGN) ) {
mission_parse_lookup_alt_index(Ships[Message_shipnum].alt_type_index, who_from);
}
end_string_at_first_hash_symbol(who_from);
}
HUD_sourced_printf( q->source, NOX("%s: %s"), who_from, buf );
+2 -9
View File
@@ -4456,17 +4456,10 @@ int parse_wing_create_ships( wing *wingp, int num_to_create, int force, int spec
aip->ai_flags |= AIF_NO_DYNAMIC;
// update housekeeping variables
// NOTE: for the initial wing setup we use actual position to get around
// object order isses, but ships in all following waves just get
// tacked onto the end of the list
if (wingp->current_wave == 1) {
wingp->ship_index[p_objp->pos_in_wing] = Objects[objnum].instance;
} else {
wingp->ship_index[wingp->current_count] = Objects[objnum].instance;
}
wingp->ship_index[p_objp->pos_in_wing] = Objects[objnum].instance;
// set up wingman status index
hud_wingman_status_set_index(Objects[objnum].instance);
hud_wingman_status_set_index(wingp->ship_index[p_objp->pos_in_wing]);
p_objp->wing_status_wing_index = Ships[Objects[objnum].instance].wing_status_wing_index;
p_objp->wing_status_wing_pos = Ships[Objects[objnum].instance].wing_status_wing_pos;
+1 -1
View File
@@ -742,7 +742,7 @@ extern char Mission_filename[80]; // filename of mission in The_mission (Fred o
#define MAX_GOAL_TYPE_NAMES 3
// alternate ship type names
#define MAX_ALT_TYPE_NAMES 100
#define MAX_ALT_TYPE_NAMES 25
extern char Mission_alt_types[MAX_ALT_TYPE_NAMES][NAME_LENGTH];
extern int Mission_alt_type_count;
+121 -283
View File
@@ -1951,7 +1951,7 @@ sexp_oper Operators[] = {
{ "supernova-start", OP_SUPERNOVA_START, 1, 1 },
{ "shields-on", OP_SHIELDS_ON, 1, INT_MAX }, //-Sesquipedalian
{ "shields-off", OP_SHIELDS_OFF, 1, INT_MAX }, //-Sesquipedalian
{ "ship-tag", OP_SHIP_TAG, 3, 8 }, // Goober5000
{ "ship-tag", OP_SHIP_TAG, 3, 7 }, // Goober5000
{ "ship-untag", OP_SHIP_UNTAG, 1, 1 }, // Goober5000
{ "explosion-effect", OP_EXPLOSION_EFFECT, 11, 13 }, // Goober5000
{ "warp-effect", OP_WARP_EFFECT, 12, 12 }, // Goober5000
@@ -2182,9 +2182,6 @@ arg_item Sexp_applicable_argument_list;
bool is_blank_argument_op(int op_const);
bool is_blank_of_op(int op_const);
//Karajorma
bool is_generic_subsys(char *subsy_name);
bool ship_class_unchanged(int ship_index);
// Goober5000 - arg_item class stuff, borrowed from sexp_list_item class stuff -------------
void arg_item::add_data(char *str)
@@ -6216,10 +6213,7 @@ int sexp_hits_left_subsystem(int n)
ss = GET_NEXT( ss );
}
// we reached end of ship subsys list without finding subsys_name
if (ship_class_unchanged(shipnum)) {
Error(LOCATION, "Invalid subsystem '%s' passed to hits-left-subsystem", subsys_name);
}
return SEXP_NAN;
Error(LOCATION, "Invalid subsystem '%s' passed to hits-left-subsystem or hits-left-single-subsystem", subsys_name);
} else {
percent = (int)(ship_get_subsystem_strength(&Ships[shipnum],type) * 100.0f);
@@ -6411,8 +6405,7 @@ int sexp_distance(int n)
}
// locate the subsystem on a ship - Goober5000
// Karajorma - switched to a boolean so that it can report failure to do so
bool sexp_get_subsystem_world_pos(vec3d *subsys_world_pos, int shipnum, char *subsys_name)
void sexp_get_subsystem_world_pos(vec3d *subsys_world_pos, int shipnum, char *subsys_name)
{
Assert(subsys_name);
Assert(subsys_world_pos);
@@ -6433,17 +6426,14 @@ bool sexp_get_subsystem_world_pos(vec3d *subsys_world_pos, int shipnum, char *su
{
// find world position of subsystem on this object (the ship)
get_subsystem_world_pos(&Objects[Ships[shipnum].objnum], ss, subsys_world_pos);
return true;
return;
}
ss = GET_NEXT( ss );
}
// we reached end of ship subsys list without finding subsys_name
if (ship_class_unchanged(shipnum)) {
// this ship should have had the subsystem named as it shouldn't have changed class
Error(LOCATION, "sexp_get_subsystem_world_pos could not find subsystem '%s'", subsys_name);
}
return false;
// we reached end of ship subsys list without finding subsys_name
Error(LOCATION, "sexp_get_subsystem_world_pos could not find subsystem '%s'", subsys_name);
Int3();
}
// Goober5000
@@ -6473,9 +6463,8 @@ int sexp_distance_subsystem(int n)
if (ship_with_subsys_num < 0)
return SEXP_NAN;
// get the subsystem's coordinates or bail if we can't
if (!sexp_get_subsystem_world_pos(&subsys_pos, ship_with_subsys_num, subsys_name))
return SEXP_NAN;
// get the subsystem's coordinates
sexp_get_subsystem_world_pos(&subsys_pos, ship_with_subsys_num, subsys_name);
switch (oswpt.type)
{
@@ -6727,9 +6716,7 @@ int sexp_get_object_coordinate(int n, int axis)
if ((subsystem_name != NULL) && stricmp(subsystem_name, SEXP_NONE_STRING) && stricmp(subsystem_name, SEXP_HULL_STRING))
{
pos = &subsys_pos_buf;
// get the world pos but bail if we can't get one
if (!sexp_get_subsystem_world_pos(pos, oswpt.objp->instance, subsystem_name))
return SEXP_NAN;
sexp_get_subsystem_world_pos(pos, oswpt.objp->instance, subsystem_name);
}
}
@@ -7564,7 +7551,8 @@ void sexp_set_scanned_unscanned(int n, int flag)
}
// if we didn't find the subsystem -- bad
if (!subsys_set && ship_class_unchanged(shipnum)) {
if (!subsys_set)
{
Error(LOCATION, "Couldn't find subsystem '%s' on ship '%s' in sexp_set_scanned_unscanned", subsys_name, ship_name);
}
@@ -8390,9 +8378,10 @@ int sexp_is_ai_class(int n)
ss = GET_NEXT( ss );
}
Assert(class_to_test >= 0);
// if no match (or nothing to match), return false immediately
if ((class_to_test < 0) || (ai_class != class_to_test))
// if no match, return false immediately
if (ai_class != class_to_test)
return SEXP_FALSE;
}
@@ -9318,11 +9307,10 @@ void sexp_end_campaign(int n)
void sexp_sabotage_subsystem(int n)
{
char *shipname, *subsystem;
int percentage, shipnum, index, subsys_type;
int percentage, shipnum, index;
float sabotage_hits;
ship *shipp;
ship_subsys *ss, *ss_start;
bool generic, do_loop = true;
ship_subsys *ss;
shipname = CTEXT(n);
subsystem = CTEXT(CDR(n));
@@ -9364,56 +9352,29 @@ void sexp_sabotage_subsystem(int n)
return;
}
// now find the given subsystem on the ship.This could be a generic type like <All Engines>
generic = is_generic_subsys(subsystem);
subsys_type = ai_get_subsystem_type(subsystem);
ss_start = GET_FIRST(&shipp->subsys_list);
// now find the given subsystem on the ship. The subsystem should be an actual subsystem name
// and not a generic type (generic type meaning SUBSYSTEM_ENGINE, etc).
while (do_loop) {
if (generic) {
// loop until we find a subsystem of that type
for ( ; ss_start != END_OF_LIST(&Ships[shipnum].subsys_list); ss_start = GET_NEXT(ss_start)) {
ss = NULL;
if (subsys_type == ai_get_subsystem_type(ss_start->system_info->name)) {
ss = ss_start;
ss_start = GET_NEXT(ss_start);
break;
}
}
// reached the end of the subsystem list
if (ss_start == END_OF_LIST(&Ships[shipnum].subsys_list)) {
// If the last subsystem wasn't of interest we don't need to go any further
if (ss == NULL) {
return;
}
do_loop = false;
}
}
else {
do_loop = false;
index = ship_get_subsys_index(shipp, subsystem, 1); // Bypass any error since we supply one here
if ( index == -1 ) {
nprintf(("Warning", "Couldn't find subsystem %s on ship %s for sabotage subsystem\n", subsystem, shipp->ship_name));
return;
}
// get the pointer to the subsystem. Check it's current hits against it's max hits, and
// set the strength to the given percentage if current strength is > given percentage
ss = ship_get_indexed_subsys( shipp, index );
}
sabotage_hits = ss->max_hits * ((float)percentage / 100.0f);
ss->current_hits -= sabotage_hits;
if ( ss->current_hits < 0.0f )
ss->current_hits = 0.0f;
// maybe blow up subsys
if (ss->current_hits <= 0) {
do_subobj_destroyed_stuff(shipp, ss, NULL);
}
ship_recalc_subsys_strength( shipp );
index = ship_get_subsys_index(shipp, subsystem);
if ( index == -1 ) {
nprintf(("Warning", "Couldn't find subsystem %s on ship %s for sabotage subsystem\n", subsystem, shipp->ship_name));
return;
}
// get the pointer to the subsystem. Check it's current hits against it's max hits, and
// set the strength to the given percentage if current strength is > given percentage
ss = ship_get_indexed_subsys( shipp, index );
sabotage_hits = ss->max_hits * ((float)percentage / 100.0f);
ss->current_hits -= sabotage_hits;
if ( ss->current_hits < 0.0f )
ss->current_hits = 0.0f;
// maybe blow up subsys
if (ss->current_hits <= 0) {
do_subobj_destroyed_stuff(shipp, ss, NULL);
}
ship_recalc_subsys_strength( shipp );
}
// repair_subsystem adds some percentage of hits to a subsystem. Anything repaired about 100% is
@@ -9421,11 +9382,10 @@ void sexp_sabotage_subsystem(int n)
void sexp_repair_subsystem(int n)
{
char *shipname, *subsystem;
int percentage, shipnum, index, do_submodel_repair, subsys_type;
int percentage, shipnum, index, do_submodel_repair;
float repair_hits;
ship *shipp;
ship_subsys *ss, *ss_start;
bool generic, do_loop = true;
ship_subsys *ss;
shipname = CTEXT(n);
subsystem = CTEXT(CDR(n));
@@ -9470,67 +9430,39 @@ void sexp_repair_subsystem(int n)
return;
}
// now find the given subsystem on the ship.This could be a generic type like <All Engines>
generic = is_generic_subsys(subsystem);
subsys_type = ai_get_subsystem_type(subsystem);
ss_start = GET_FIRST(&shipp->subsys_list);
// now find the given subsystem on the ship. The subsystem should be an actual subsystem name
// and not a generic type (generic type meaning SUBSYSTEM_ENGINE, etc).
while (do_loop) {
if (generic) {
// loop until we find a subsystem of that type
for ( ; ss_start != END_OF_LIST(&Ships[shipnum].subsys_list); ss_start = GET_NEXT(ss_start)) {
ss = NULL;
if (subsys_type == ai_get_subsystem_type(ss_start->system_info->name)) {
ss = ss_start;
ss_start = GET_NEXT(ss_start);
break;
}
}
// reached the end of the subsystem list
if (ss_start == END_OF_LIST(&Ships[shipnum].subsys_list)) {
// If the last subsystem wasn't of interest we don't need to go any further
if (ss == NULL) {
return;
}
do_loop = false;
}
}
else {
do_loop = false;
index = ship_get_subsys_index(shipp, subsystem, 1); // Bypass any error since we supply one here
if ( index == -1 ) {
nprintf(("Warning", "Couldn't find subsystem %s on ship %s for repair subsystem\n", subsystem, shipp->ship_name));
return;
}
// get the pointer to the subsystem. Check it's current hits against it's max hits, and
// set the strength to the given percentage if current strength is < given percentage
ss = ship_get_indexed_subsys( shipp, index );
}
repair_hits = ss->max_hits * ((float)percentage / 100.0f);
ss->current_hits += repair_hits;
if ( ss->current_hits > ss->max_hits )
ss->current_hits = ss->max_hits;
if ((ss->current_hits > 0) && (do_submodel_repair))
{
ss->submodel_info_1.blown_off = 0;
ss->submodel_info_2.blown_off = 0;
}
ship_recalc_subsys_strength( shipp );
index = ship_get_subsys_index(shipp, subsystem);
if ( index == -1 ) {
nprintf(("Warning", "Couldn't find subsystem %s on ship %s for repair subsystem\n", subsystem, shipp->ship_name));
return;
}
// get the pointer to the subsystem. Check it's current hits against it's max hits, and
// set the strength to the given percentage if current strength is < given percentage
ss = ship_get_indexed_subsys( shipp, index );
repair_hits = ss->max_hits * ((float)percentage / 100.0f);
ss->current_hits += repair_hits;
if ( ss->current_hits > ss->max_hits )
ss->current_hits = ss->max_hits;
if ((ss->current_hits > 0) && (do_submodel_repair))
{
ss->submodel_info_1.blown_off = 0;
ss->submodel_info_2.blown_off = 0;
}
ship_recalc_subsys_strength( shipp );
}
// sexpression code to set a subsystem of a ship at a specific percentage
void sexp_set_subsystem_strength(int n)
{
char *shipname, *subsystem;
int percentage, shipnum, index, do_submodel_repair, subsys_type;
int percentage, shipnum, index, do_submodel_repair;
ship *shipp;
ship_subsys *ss, *ss_start;
bool generic, do_loop = true;
ship_subsys *ss;
shipname = CTEXT(n);
subsystem = CTEXT(CDR(n));
@@ -9583,63 +9515,36 @@ void sexp_set_subsystem_strength(int n)
return;
}
// now find the given subsystem on the ship.This could be a generic type like <All Engines>
generic = is_generic_subsys(subsystem);
subsys_type = ai_get_subsystem_type(subsystem);
ss_start = GET_FIRST(&shipp->subsys_list);
// now find the given subsystem on the ship. The subsystem should be an actual subsystem name
// and not a generic type (generic type meaning SUBSYSTEM_ENGINE, etc).
while (do_loop) {
if (generic) {
// loop until we find a subsystem of that type
for ( ; ss_start != END_OF_LIST(&Ships[shipnum].subsys_list); ss_start = GET_NEXT(ss_start)) {
ss = NULL;
if (subsys_type == ai_get_subsystem_type(ss_start->system_info->name)) {
ss = ss_start;
ss_start = GET_NEXT(ss_start);
break;
}
}
// reached the end of the subsystem list
if (ss_start == END_OF_LIST(&Ships[shipnum].subsys_list)) {
// If the last subsystem wasn't of interest we don't need to go any further
if (ss == NULL) {
return;
}
do_loop = false;
}
}
else {
do_loop = false;
index = ship_get_subsys_index(shipp, subsystem, 1); // Bypass any error since we supply one here
if ( index == -1 ) {
nprintf(("Warning", "Couldn't find subsystem %s on ship %s for set subsystem strength\n", subsystem, shipp->ship_name));
return;
}
// get the pointer to the subsystem. Check it's current hits against it's max hits, and
// set the strength to the given percentage
ss = ship_get_indexed_subsys( shipp, index );
}
// maybe blow up subsys
if (ss->current_hits > 0) {
if (percentage < 1) {
do_subobj_destroyed_stuff(shipp, ss, NULL);
}
}
// set hit points
ss->current_hits = ss->max_hits * ((float)percentage / 100.0f);
if ((ss->current_hits > 0) && (do_submodel_repair))
{
ss->submodel_info_1.blown_off = 0;
ss->submodel_info_2.blown_off = 0;
}
ship_recalc_subsys_strength( shipp );
index = ship_get_subsys_index(shipp, subsystem);
if ( index == -1 ) {
nprintf(("Warning", "Couldn't find subsystem %s on ship %s for repair subsystem\n", subsystem, shipp->ship_name));
return;
}
// get the pointer to the subsystem. Check it's current hits against it's max hits, and
// set the strength to the given percentage if current strength is < given percentage
ss = ship_get_indexed_subsys( shipp, index );
// maybe blow up subsys
if (ss->current_hits > 0) {
if (percentage < 1) {
do_subobj_destroyed_stuff(shipp, ss, NULL);
}
}
// set hit points
ss->current_hits = ss->max_hits * ((float)percentage / 100.0f);
if ((ss->current_hits > 0) && (do_submodel_repair))
{
ss->submodel_info_1.blown_off = 0;
ss->submodel_info_2.blown_off = 0;
}
ship_recalc_subsys_strength( shipp );
}
// function which changes the validity of a goal. The flag paramater tells us whether to mark the goals
@@ -9799,8 +9704,9 @@ void sexp_set_cargo(int n)
if (subsystem)
{
ship_subsys *ss = ship_get_subsys(&Ships[ship_num], subsystem);
if (ss == NULL) {
Assert (!ship_class_unchanged(ship_num));
if (ss == NULL)
{
Int3();
return;
}
@@ -11100,9 +11006,6 @@ void sexp_friendly_stealth_invisible(int n, int invisible)
// Goober5000
void sexp_ship_subsys_untargetable(int n, int untargetable)
{
char *subsys;
ship_subsys *ss;
// get the ship
int ship_num = ship_name_lookup(CTEXT(n));
if (ship_num < 0)
@@ -11112,30 +11015,14 @@ void sexp_ship_subsys_untargetable(int n, int untargetable)
// get the subsystems
for (; n >= 0; n = CDR(n))
{
subsys = CTEXT(n);
ship_subsys *ss = ship_get_subsys(&Ships[ship_num], CTEXT(n));
if (ss == NULL)
continue;
// deal with generic subsystem names
if (is_generic_subsys(subsys)) {
int subsys_type = ai_get_subsystem_type(subsys);
for (ss = GET_FIRST(&Ships[ship_num].subsys_list); ss != END_OF_LIST(&Ships[ship_num].subsys_list); ss = GET_NEXT(ss)) {
if (subsys_type == ai_get_subsystem_type(ss->sub_name)) {
if (untargetable)
ss->flags |= SSF_UNTARGETABLE;
else
ss->flags &= ~SSF_UNTARGETABLE;
}
}
}
else {
ss = ship_get_subsys(&Ships[ship_num], subsys);
if (ss == NULL)
continue;
if (untargetable)
ss->flags |= SSF_UNTARGETABLE;
else
ss->flags &= ~SSF_UNTARGETABLE;
}
if (untargetable)
ss->flags |= SSF_UNTARGETABLE;
else
ss->flags &= ~SSF_UNTARGETABLE;
}
}
@@ -11143,7 +11030,6 @@ void sexp_ship_subsys_untargetable(int n, int untargetable)
void sexp_ship_tag( int n, int tag )
{
int ship_num, tag_level, tag_time, ssm_index(0);
int ssm_team;
// check to see if ship destroyed or departed. In either case, do nothing.
if ( mission_log_get_time(LOG_SHIP_DEPARTED, CTEXT(n), NULL, NULL) || mission_log_get_time(LOG_SHIP_DESTROYED, CTEXT(n), NULL, NULL) )
@@ -11193,20 +11079,9 @@ void sexp_ship_tag( int n, int tag )
if (n < 0)
return;
start.xyz.z = (float)eval_num(n);
n = CDR(n);
if (n < 0)
{
ssm_team = 0;
}
else
{
ssm_team = iff_lookup(CTEXT(n));
}
}
ship_apply_tag(ship_num, tag_level, (float)tag_time, &Objects[Ships[ship_num].objnum], &start, ssm_index, ssm_team);
ship_apply_tag(ship_num, tag_level, (float)tag_time, &Objects[Ships[ship_num].objnum].pos, &start, ssm_index);
}
// sexpression to toggle invulnerability flag of ships.
@@ -11286,11 +11161,11 @@ void sexp_ship_subsys_guardian_threshold(int num)
if ( !strcmp(hull_name, SEXP_HULL_STRING) ) {
Ships[ship_num].ship_guardian_threshold = threshold;
}
else if (is_generic_subsys(hull_name)) {
else if (!strcmp(hull_name, SEXP_ALL_ENGINES_STRING) || !strcmp(hull_name, SEXP_ALL_TURRETS_STRING)) {
subsys_type = ai_get_subsystem_type(hull_name);
// search through all subsystems
for (ss = GET_FIRST(&Ships[ship_num].subsys_list); ss != END_OF_LIST(&Ships[ship_num].subsys_list); ss = GET_NEXT(ss)) {
if (subsys_type == ai_get_subsystem_type(ss->system_info->name)) {
for (ss = GET_FIRST(&Ships[ship_num].subsys_list); ss != GET_LAST(&Ships[ship_num].subsys_list); ss = GET_NEXT(ss)) {
if (subsys_type == ai_get_subsystem_type(ss->sub_name)) {
ss->subsys_guardian_threshold = threshold;
}
}
@@ -11298,9 +11173,7 @@ void sexp_ship_subsys_guardian_threshold(int num)
else {
ss = ship_get_subsys(&Ships[ship_num], hull_name);
if ( ss == NULL ) {
if (ship_class_unchanged(ship_num)) {
Warning(LOCATION, "Invalid subsystem passed to ship-subsys-guardian-threshold: %s does not have a %s subsystem", ship_name, hull_name);
}
Warning(LOCATION, "Invalid subsystem passed to ship-subsys-guardian-threshold: %s does not have a %s subsystem", ship_name, hull_name);
}
else {
ss->subsys_guardian_threshold = threshold;
@@ -12711,6 +12584,7 @@ void sexp_change_subsystem_name(int node)
}
shipp = &Ships[ship_index];
node = CDR(node);
if (node < 0) {
@@ -12718,6 +12592,7 @@ void sexp_change_subsystem_name(int node)
}
new_name = CTEXT(node);
node = CDR(node);
// loop through all the subsystems the SEXP has provided
@@ -12725,9 +12600,7 @@ void sexp_change_subsystem_name(int node)
//Get the new subsystem name
subsystem_to_rename = ship_get_subsys(&Ships[ship_index], CTEXT(node));
if (subsystem_to_rename != NULL) {
ship_subsys_set_name(subsystem_to_rename, new_name);
}
ship_subsys_set_name (subsystem_to_rename, new_name);
node = CDR(node);
}
@@ -13097,8 +12970,7 @@ void sexp_beam_free(int node)
// get the subsystem
turret = ship_get_subsys(&Ships[sindex], CTEXT(node));
if(turret == NULL){
node = CDR(node);
continue;
return;
}
// flag it as beam free :)
@@ -13165,8 +13037,7 @@ void sexp_beam_lock(int node)
// get the subsystem
turret = ship_get_subsys(&Ships[sindex], CTEXT(node));
if(turret == NULL){
node = CDR(node);
continue;
return;
}
// flag it as not beam free
@@ -13231,8 +13102,7 @@ void sexp_turret_free(int node)
// get the subsystem
turret = ship_get_subsys(&Ships[sindex], CTEXT(node));
if(turret == NULL){
node = CDR(node);
continue;
return;
}
// flag turret as no longer locked :)
@@ -13299,8 +13169,7 @@ void sexp_turret_lock(int node)
// get the subsystem
turret = ship_get_subsys(&Ships[sindex], CTEXT(node));
if(turret == NULL){
node = CDR(node);
continue;
return;
}
// flag turret as locked
@@ -13706,8 +13575,7 @@ void sexp_turret_tagged_specific(int node)
// get the subsystem
subsys = ship_get_subsys(&Ships[sindex], CTEXT(node));
if(subsys == NULL){
node = CDR(node);
continue;
return;
}
// flag turret as slaved to tag
@@ -13737,8 +13605,7 @@ void sexp_turret_tagged_clear_specific(int node)
// get the subsystem
subsys = ship_get_subsys(&Ships[sindex], CTEXT(node));
if(subsys == NULL){
node = CDR(node);
continue;
return;
}
// flag turret as slaved to tag
@@ -15539,32 +15406,6 @@ int sexp_script_eval(int node, int return_type)
return r;
}
//Karajorma - Returns true if the name of a subsystem is actually a generic type (e.g <all engines> or <all turrets>
bool is_generic_subsys(char *subsys_name)
{
if (!strcmp(subsys_name, SEXP_ALL_ENGINES_STRING) || !strcmp(subsys_name, SEXP_ALL_TURRETS_STRING)) {
return true;
}
return false;
}
// Karajorma - returns false if the ship class has changed since the mission was parsed in
// Changes can be from use of the change-ship-class SEXP, loadout or any future method
bool ship_class_unchanged(int ship_index)
{
p_object *p_objp;
ship *shipp = &Ships[ship_index];
p_objp = mission_parse_get_parse_object(shipp->ship_name);
if ((p_objp != NULL) && (p_objp->ship_class == shipp->ship_info_index)) {
return true;
}
return false;
}
// Goober5000 - needed because any nonzero integer value is "true"
int is_sexp_true(int cur_node, int referenced_node)
{
@@ -17826,7 +17667,7 @@ int query_operator_argument_type(int op, int argnum)
if (argnum == 0)
return OPF_SHIP;
else
return OPF_SUBSYS_OR_GENERIC;
return OPF_SUBSYSTEM;
case OP_IS_DESTROYED:
case OP_HAS_ARRIVED:
@@ -17844,8 +17685,6 @@ int query_operator_argument_type(int op, int argnum)
case OP_SHIP_TAG:
if (argnum == 0)
return OPF_SHIP;
else if (argnum == 7)
return OPF_IFF;
else
return OPF_POSITIVE;
@@ -18288,7 +18127,7 @@ int query_operator_argument_type(int op, int argnum)
if (!argnum)
return OPF_SHIP; // changed from OPF_SHIP_NOT_PLAYER by Goober5000: now it can be the player ship also
else if (argnum == 1 )
return OPF_SUBSYS_OR_GENERIC;
return OPF_SUBSYSTEM;
else
return OPF_POSITIVE;
@@ -18297,7 +18136,7 @@ int query_operator_argument_type(int op, int argnum)
if (!argnum)
return OPF_SHIP; // changed from OPF_SHIP_NOT_PLAYER by Goober5000: now it can be the player ship also
else if (argnum == 1 )
return OPF_SUBSYS_OR_GENERIC;
return OPF_SUBSYSTEM;
else if (argnum == 2)
return OPF_POSITIVE;
else
@@ -20992,15 +20831,14 @@ sexp_help_struct Sexp_help[] = {
// Goober5000
{ OP_SHIP_TAG, "ship-tag\r\n"
"\tTags a ship. Takes 3 or 8 arguments...\r\n"
"\tTags a ship. Takes 3 or 7 arguments...\r\n"
"\t1: The name of a ship.\r\n"
"\t2: The tag level (currently 1, 2, or 3).\r\n"
"\t3: The tag time (in seconds).\r\n"
"\t4: A SSM missile (optional - used only for TAG-C).\r\n"
"\t5: The X origin of the SSM missile (optional - used only for TAG-C).\r\n"
"\t6: The Y origin of the SSM missile (optional - used only for TAG-C).\r\n"
"\t7: The Z origin of the SSM missile (optional - used only for TAG-C).\r\n"
"\t8: The team the SSM missile belongs to (optional - used only for TAG-C).\r\n" },
"\t7: The Z origin of the SSM missile (optional - used only for TAG-C)." },
/* made obsolete by Goober5000 - it only works in debug builds anyway
{ OP_INT3, "Error (Debug directive)\r\n"
+2 -2
View File
@@ -1452,8 +1452,8 @@ struct ship_subsys;
// defines for string constants
#define SEXP_HULL_STRING "Hull"
#define SEXP_SIM_HULL_STRING "Simulated Hull"
#define SEXP_ALL_ENGINES_STRING "<all engines>"
#define SEXP_ALL_TURRETS_STRING "<all turrets>"
#define SEXP_ALL_ENGINES_STRING "<All Engines>"
#define SEXP_ALL_TURRETS_STRING "<All Turrets>"
#define SEXP_ARGUMENT_STRING "<argument>"
#define SEXP_NONE_STRING "<none>"
+39 -19
View File
@@ -6833,6 +6833,21 @@ void ship_render(object * obj)
model_set_fog_level(neb2_get_fog_intensity(obj));
}
if (shipp->cloak_stage>0)
{
//cloaking
if (shipp->cloak_stage==2)
{
model_setup_cloak(&shipp->current_translation,1,shipp->cloak_alpha);
render_flags |= MR_FORCE_TEXTURE | MR_NO_LIGHTING;
}
else
{
model_setup_cloak(&shipp->current_translation,0,255);
}
}
//draw weapon models
if (sip->draw_models) {
int i,k;
@@ -8216,9 +8231,7 @@ void ship_do_weapon_thruster_frame( weapon *weaponp, object *objp, float frameti
Assert( frametime > 0.0f );
if ((flame_anim->first_frame >= 0) &&
(flame_anim->total_time > 0.0f))
{
if (flame_anim->first_frame >= 0) {
weaponp->thruster_frame += frametime * rate;
// Sanity checks
@@ -8246,9 +8259,7 @@ void ship_do_weapon_thruster_frame( weapon *weaponp, object *objp, float frameti
// Do it for glow bitmaps
if ((glow_anim->first_frame >= 0) &&
(glow_anim->total_time > 0.0f))
{
if (glow_anim->first_frame >= 0) {
weaponp->thruster_glow_frame += frametime * rate;
// Sanity checks
@@ -8659,6 +8670,8 @@ void ship_process_post(object * obj, float frametime)
ship_dying_frame(obj, num);
shipfx_cloak_frame(shipp, frametime);
ship_chase_shield_energy_targets(shipp, obj, frametime);
/* if (timestamp_elapsed(shipp->boost_finish_stamp))
@@ -10689,6 +10702,11 @@ void ship_process_targeting_lasers()
fire_info.targeting_laser_offset = m->gun_banks[shipp->targeting_laser_bank].pnt[0];
shipp->targeting_laser_objnum = beam_fire_targeting(&fire_info);
if (shipp->cloak_stage ==2)
{
shipfx_start_cloak(shipp,500);
}
// hmm, why didn't it fire?
if(shipp->targeting_laser_objnum < 0){
Int3();
@@ -11207,7 +11225,12 @@ done_secondary:
Player->stats.ms_shots_fired += num_fired;
}
}
if ((shipp->cloak_stage > 0) && (shipp->cloak_stage < 3))
{
shipfx_start_cloak(shipp,500);
}
// maybe announce a shockwave weapon
ai_maybe_announce_shockwave_weapon(obj, weapon);
}
@@ -14073,7 +14096,6 @@ char *ship_return_orders(char *outbuf, ship *sp)
ai_info *aip;
ai_goal *aigp;
char *order_text;
char temp_name[256];
Assert(sp->ai_index >= 0);
aip = &Ai_info[sp->ai_index];
@@ -14089,18 +14111,13 @@ char *ship_return_orders(char *outbuf, ship *sp)
return NULL;
strcpy(outbuf, order_text);
if ( aigp->ship_name ) {
strcpy(temp_name, aigp->ship_name);
end_string_at_first_hash_symbol(temp_name);
}
switch (aigp->ai_mode ) {
case AI_GOAL_FORM_ON_WING:
case AI_GOAL_GUARD_WING:
case AI_GOAL_CHASE_WING:
if ( aigp->ship_name ) {
strcat(outbuf, temp_name);
strcat(outbuf, aigp->ship_name);
strcat(outbuf, XSTR( "'s Wing", 494));
} else {
strcpy(outbuf, XSTR( "no orders", 495));
@@ -14116,7 +14133,7 @@ char *ship_return_orders(char *outbuf, ship *sp)
case AI_GOAL_EVADE_SHIP:
case AI_GOAL_REARM_REPAIR:
if ( aigp->ship_name ) {
strcat(outbuf, temp_name);
strcat(outbuf, aigp->ship_name);
} else {
strcpy(outbuf, XSTR( "no orders", 495));
}
@@ -14125,8 +14142,8 @@ char *ship_return_orders(char *outbuf, ship *sp)
case AI_GOAL_DESTROY_SUBSYSTEM: {
char name[NAME_LENGTH];
if ( aip->targeted_subsys != NULL ) {
sprintf(outbuf, XSTR( "atk %s %s", 496), temp_name, hud_targetbox_truncate_subsys_name(aip->targeted_subsys->system_info->name));
strcat(outbuf, name); //what is this for?
sprintf(outbuf, XSTR( "atk %s %s", 496), aigp->ship_name, hud_targetbox_truncate_subsys_name(aip->targeted_subsys->system_info->name));
strcat(outbuf, name);
} else {
strcpy(outbuf, XSTR( "no orders", 495) );
}
@@ -15864,7 +15881,10 @@ void ship_update_artillery_lock()
if(aip->artillery_lock_time >= 2.0f){
HUD_printf("Firing artillery");
ssm_create(&Objects[aip->artillery_objnum], &cinfo->hit_point_world, 0, NULL, shipp->team);
vec3d temp;
vm_vec_unrotate(&temp, &aip->artillery_lock_pos, &Objects[aip->artillery_objnum].orient);
vm_vec_add2(&temp, &Objects[aip->artillery_objnum].pos);
ssm_create(&temp, &Objects[so->objnum].pos, 0, NULL);
// reset the artillery
aip->artillery_lock_time = 0.0f;
@@ -16028,7 +16048,7 @@ void ship_subsystem_set_new_ai_class(int ship_num, char *subsystem, int new_ai_c
ss = GET_NEXT( ss );
}
// Int3(); // subsystem not found
Int3(); // subsystem not found
}
// Goober5000 - will attempt to load an insignia bitmap and set it as active for the wing
+10 -7
View File
@@ -748,7 +748,7 @@
//#pragma auto_inline(off)
struct ssm_firing_info;
extern void ssm_create(object *target, vec3d *start, int ssm_index, ssm_firing_info *override, int team);
extern void ssm_create(vec3d *target, vec3d *start, int ssm_index, ssm_firing_info *override);
typedef struct spark_pair {
int index1, index2;
@@ -2808,7 +2808,7 @@ static void ship_do_damage(object *ship_obj, object *other_obj, vec3d *hitpos, f
}
// Goober5000
void ship_apply_tag(int ship_num, int tag_level, float tag_time, object *target, vec3d *start, int ssm_index, int ssm_team)
void ship_apply_tag(int ship_num, int tag_level, float tag_time, vec3d *target, vec3d *start, int ssm_index)
{
// set time first tagged
if (Ships[ship_num].time_first_tagged == 0)
@@ -2837,7 +2837,7 @@ void ship_apply_tag(int ship_num, int tag_level, float tag_time, object *target,
HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR("Firing artillery", 1570));
ssm_create(target, start, ssm_index, NULL, ssm_team);
ssm_create(target, start, ssm_index, NULL);
}
}
@@ -2850,12 +2850,14 @@ void ship_apply_local_damage(object *ship_obj, object *other_obj, vec3d *hitpos,
Assert(ship_obj); // Goober5000
Assert(other_obj); // Goober5000
ship *ship_p = &Ships[ship_obj->instance];
weapon *wp = &Weapons[other_obj->instance];
ship *ship_p = &Ships[ship_obj->instance];
// If got hit by a weapon, tell the AI so it can react. Only do this line in single player,
// or if I am the master in a multiplayer game
if ( other_obj->type == OBJ_WEAPON && ( !(Game_mode & GM_MULTIPLAYER) || ((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)) )) {
weapon *wp;
wp = &Weapons[other_obj->instance];
// If weapon hits ship on same team and that ship not targeted and parent of weapon not player,
// don't do damage.
// Ie, player can always do damage. AI can only damage team if that ship is targeted.
@@ -2907,10 +2909,11 @@ void ship_apply_local_damage(object *ship_obj, object *other_obj, vec3d *hitpos,
weapon_info *wip = &Weapon_info[Weapons[other_obj->instance].weapon_info_index];
// ssm stuff
vec3d *start = hitpos;
vec3d *target = hitpos;
vec3d *start = &Objects[ship_obj->instance].pos;
int ssm_index = wip->SSM_index;
ship_apply_tag(ship_obj->instance, wip->tag_level, wip->tag_time, ship_obj, start, ssm_index, wp->team);
ship_apply_tag(ship_obj->instance, wip->tag_level, wip->tag_time, target, start, ssm_index);
}
#ifndef NDEBUG
+1 -1
View File
@@ -133,7 +133,7 @@ struct object;
extern void do_subobj_destroyed_stuff( ship *ship_p, ship_subsys *subsys, vec3d *hitpos );
// Goober5000
extern void ship_apply_tag(int ship_num, int tag_level, float tag_time, object *target, vec3d *start, int ssm_index, int ssm_team);
extern void ship_apply_tag(int ship_num, int tag_level, float tag_time, vec3d *target, vec3d *start, int ssm_index);
// This gets called to apply damage when something hits a particular point on a ship.
// This assumes that whoever called this knows if the shield got hit or not.
+1 -8
View File
@@ -5664,14 +5664,7 @@ int weapon_create( vec3d * pos, matrix * porient, int weapon_type, int parent_ob
if(parent_objp != NULL){
vm_vec_copy_scale(&objp->phys_info.desired_vel, &objp->orient.vec.fvec, vm_vec_dot(&parent_objp->phys_info.vel, &parent_objp->orient.vec.fvec) + objp->phys_info.max_vel.xyz.z/4 );
} else {
if (!is_locked)
{
vm_vec_copy_scale(&objp->phys_info.desired_vel, &objp->orient.vec.fvec, objp->phys_info.max_vel.xyz.z/4 );
}
else
{
vm_vec_copy_scale(&objp->phys_info.desired_vel, &objp->orient.vec.fvec, objp->phys_info.max_vel.xyz.z );
}
vm_vec_copy_scale(&objp->phys_info.desired_vel, &objp->orient.vec.fvec, objp->phys_info.max_vel.xyz.z/4 );
}
objp->phys_info.vel = objp->phys_info.desired_vel;
objp->phys_info.speed = vm_vec_mag(&objp->phys_info.vel);
-9
View File
@@ -217,12 +217,6 @@
<File
RelativePath="..\..\code\ai\ai_profiles.h">
</File>
<File
RelativePath="..\..\code\ai\aimodular.cpp">
</File>
<File
RelativePath="..\..\code\ai\aimodular.h">
</File>
<File
RelativePath="..\..\code\ai\AiBig.cpp">
<FileConfiguration
@@ -283,9 +277,6 @@
<File
RelativePath="..\..\code\ai\AiTurret.cpp">
</File>
<File
RelativePath="..\..\code\ai\newai\newai.cpp">
</File>
</Filter>
<Filter
Name="Anim"
-52
View File
@@ -236,34 +236,6 @@
RelativePath="..\..\code\ai\ai_profiles.h"
>
</File>
<File
RelativePath="..\..\code\ai\aimodular.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
UndefinePreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
UndefinePreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\code\ai\aimodular.h"
>
</File>
<File
RelativePath="..\..\code\ai\AiBig.cpp"
>
@@ -379,30 +351,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\code\ai\newai\newai.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
UndefinePreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
UndefinePreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Anim"