Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42e618e330 | ||
|
|
3e1b9c173b | ||
|
|
3e61b43b31 | ||
|
|
918a805080 | ||
|
|
75f5273c0e | ||
|
|
e130b74231 | ||
|
|
3a6f03a984 | ||
|
|
0287e166df | ||
|
|
1fb5f9cd9b | ||
|
|
92d8507c12 | ||
|
|
914ed7a2f5 | ||
|
|
9dca3f22db | ||
|
|
42ad6cba7c | ||
|
|
12b153fd73 | ||
|
|
7a7eb3b711 | ||
|
|
d18277e2ba | ||
|
|
f035cd2b6e | ||
|
|
245aefcb44 | ||
|
|
3fb37e85b0 | ||
|
|
1086be9eba | ||
|
|
41bbd6cc16 | ||
|
|
1dda11f9ec | ||
|
|
0ca63f3c96 | ||
|
|
cefb883d55 | ||
|
|
a711c256b4 | ||
|
|
82561d3b27 | ||
|
|
25d6129168 | ||
|
|
b57a68c0eb | ||
|
|
14d88eef33 | ||
|
|
f7422e1aee | ||
|
|
8103398fbf | ||
|
|
a387a68a5a | ||
|
|
251e565593 | ||
|
|
549589bdd2 | ||
|
|
604faf652f | ||
|
|
77f6c1bc9c | ||
|
|
2d05da8f31 | ||
|
|
759872d98b | ||
|
|
c53f86384b | ||
|
|
e4cb3479a7 | ||
|
|
a8fae4465f | ||
|
|
40f8d02425 | ||
|
|
a988f5eab2 | ||
|
|
0e86ab07b4 | ||
|
|
2f23ea485f | ||
|
|
dfa4206d02 | ||
|
|
364e644cf0 | ||
|
|
df5d78f07b | ||
|
|
cd2afc57f4 | ||
|
|
42a84a2a88 | ||
|
|
c8d5f8678d | ||
|
|
6c856eb341 | ||
|
|
1aef19ab7f | ||
|
|
7f2de46f30 | ||
|
|
c040093c68 | ||
|
|
1b2c251be6 | ||
|
|
e26c2a7487 | ||
|
|
b6fceca721 | ||
|
|
39f5113405 | ||
|
|
2899799bfa | ||
|
|
f7cf34487a | ||
|
|
babcedc220 | ||
|
|
86c74f9211 | ||
|
|
6f1932987d | ||
|
|
32c5fa6d1d | ||
|
|
0a06e62093 | ||
|
|
e90acd5b5d | ||
|
|
c99874389c | ||
|
|
6d085d6d22 | ||
|
|
eb468ff25c | ||
|
|
7ed32a9525 | ||
|
|
c7b3ad7aaf | ||
|
|
677a285bcf | ||
|
|
3090cd74b0 | ||
|
|
d8c2926962 | ||
|
|
04df95e8c9 | ||
|
|
2d5b4119a5 | ||
|
|
11d8505cdf | ||
|
|
75baeadbed | ||
|
|
c2bc245f81 | ||
|
|
88693b7388 | ||
|
|
94d2357dd4 |
No files matched your search
@@ -211,6 +211,9 @@ FS2_SOURCES = \
|
||||
ai/aiturret.cpp \
|
||||
ai/ai_profiles.cpp \
|
||||
ai/ai_profiles.h \
|
||||
ai/aimodular.h \
|
||||
ai/aimodular.cpp \
|
||||
ai/newai/newai.cpp \
|
||||
anim/animplay.cpp \
|
||||
anim/animplay.h \
|
||||
anim/packunpack.cpp \
|
||||
@@ -822,6 +825,8 @@ fs2_open_r_SOURCES = \
|
||||
|
||||
fs2_open_d_LDADD = libcode.a ../libjpeg/libjpeg.a ../lua/liblua.a
|
||||
fs2_open_r_LDADD = libcode.a ../libjpeg/libjpeg.a ../lua/liblua.a
|
||||
fs2_open_d_LDFLAGS = -rdynamic
|
||||
fs2_open_r_LDFLAGS = -rdynamic
|
||||
|
||||
##
|
||||
## End MAIN binary
|
||||
|
||||
@@ -235,6 +235,10 @@ void parse_ai_profiles_tbl(char *filename)
|
||||
// fill in any and all settings; they're all optional and can be in any order
|
||||
while (!check_for_string("$Profile Name:") && !check_for_string("#End"))
|
||||
{
|
||||
strcpy(profile->ai_module, "retail");
|
||||
if (optional_string("$AI Module:"))
|
||||
stuff_string(profile->ai_module, F_NAME, NAME_LENGTH);
|
||||
|
||||
if (optional_string("$Player Afterburner Recharge Scale:"))
|
||||
parse_float_list(profile->afterburner_recharge_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
@@ -310,6 +314,12 @@ void parse_ai_profiles_tbl(char *filename)
|
||||
if (optional_string("$Player Weapon Recharge Scale:"))
|
||||
parse_float_list(profile->weapon_energy_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Turret Target Ownage:"))
|
||||
parse_int_list(profile->max_turret_ownage_target, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Turret Player Ownage:"))
|
||||
parse_int_list(profile->max_turret_ownage_player, NUM_SKILL_LEVELS);
|
||||
|
||||
set_flag(profile, "$big ships can attack beam turrets on untargeted ships:", AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS);
|
||||
|
||||
set_flag(profile, "$smart primary weapon selection:", AIPF_SMART_PRIMARY_WEAPON_SELECTION);
|
||||
|
||||
@@ -80,6 +80,8 @@
|
||||
typedef struct ai_profile_t {
|
||||
|
||||
char profile_name[NAME_LENGTH];
|
||||
|
||||
char ai_module[NAME_LENGTH];
|
||||
|
||||
int flags;
|
||||
|
||||
@@ -115,6 +117,10 @@ typedef struct ai_profile_t {
|
||||
float ship_fire_delay_scale_hostile[NUM_SKILL_LEVELS];
|
||||
float ship_fire_delay_scale_friendly[NUM_SKILL_LEVELS];
|
||||
|
||||
// Maximum turrets of one ship allowed to shoot the same target
|
||||
int max_turret_ownage_target[NUM_SKILL_LEVELS];
|
||||
int max_turret_ownage_player[NUM_SKILL_LEVELS];
|
||||
|
||||
} ai_profile_t;
|
||||
|
||||
|
||||
|
||||
@@ -482,13 +482,141 @@ extern int model_which_octant_distant_many( vec3d *pnt, int model_num,matrix *mo
|
||||
extern void compute_desired_rvec(vec3d *rvec, vec3d *goal_pos, vec3d *cur_pos);
|
||||
extern void big_ship_collide_recover_start(object *objp, object *big_objp, vec3d *collide_pos, vec3d *collision_normal);
|
||||
|
||||
// FF 14-06-07
|
||||
// AI Big Table Wrapper
|
||||
|
||||
struct aibig_call_table *aibig_table = &AIBigDefaultTable;
|
||||
|
||||
void ai_big_evade_ship ()
|
||||
{
|
||||
aibig_table->ai_big_evade_ship();
|
||||
}
|
||||
|
||||
void ai_big_chase_attack (ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum)
|
||||
{
|
||||
aibig_table->ai_big_chase_attack(aip, sip, enemy_pos, dist_to_enemy, modelnum);
|
||||
}
|
||||
|
||||
void ai_big_avoid_ship ()
|
||||
{
|
||||
aibig_table->ai_big_avoid_ship();
|
||||
}
|
||||
|
||||
int ai_big_maybe_follow_subsys_path (int do_dot_check)
|
||||
{
|
||||
return aibig_table->ai_big_maybe_follow_subsys_path(do_dot_check);
|
||||
}
|
||||
|
||||
void ai_bpap (object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal)
|
||||
{
|
||||
aibig_table->ai_bpap(objp, attacker_objp_pos, attacker_objp_fvec, attack_point, local_attack_point, fov, weapon_travel_dist, surface_normal);
|
||||
}
|
||||
|
||||
void ai_big_pick_attack_point_turret (object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
|
||||
{
|
||||
aibig_table->ai_big_pick_attack_point_turret(objp, ssp, gpos, gvec, attack_point, fov, weapon_travel_dist);
|
||||
}
|
||||
|
||||
void ai_big_pick_attack_point (object *objp, object *attacker_objp, vec3d *attack_point, float fov)
|
||||
{
|
||||
aibig_table->ai_big_pick_attack_point(objp, attacker_objp, attack_point, fov);
|
||||
}
|
||||
|
||||
void ai_big_subsys_path_cleanup (ai_info *aip)
|
||||
{
|
||||
aibig_table->ai_big_subsys_path_cleanup(aip);
|
||||
}
|
||||
|
||||
int ai_big_maybe_start_strafe (ai_info *aip, ship_info *sip)
|
||||
{
|
||||
return aibig_table->ai_big_maybe_start_strafe(aip, sip);
|
||||
}
|
||||
|
||||
void ai_big_chase_ct ()
|
||||
{
|
||||
aibig_table->ai_big_chase_ct();
|
||||
}
|
||||
|
||||
void ai_big_maybe_fire_weapons (float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel)
|
||||
{
|
||||
aibig_table->ai_big_maybe_fire_weapons(dist_to_enemy, dot_to_enemy, firing_pos, enemy_pos, enemy_vel);
|
||||
}
|
||||
|
||||
void ai_big_switch_to_chase_mode (ai_info *aip)
|
||||
{
|
||||
aibig_table->ai_big_switch_to_chase_mode(aip);
|
||||
}
|
||||
|
||||
int ai_big_strafe_maybe_retreat (float dist, vec3d *target_pos)
|
||||
{
|
||||
return aibig_table->ai_big_strafe_maybe_retreat(dist, target_pos);
|
||||
}
|
||||
|
||||
void ai_big_chase ()
|
||||
{
|
||||
aibig_table->ai_big_chase();
|
||||
}
|
||||
|
||||
void ai_big_ship (object *objp)
|
||||
{
|
||||
aibig_table->ai_big_ship(objp);
|
||||
}
|
||||
|
||||
void ai_big_attack_get_data (vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy)
|
||||
{
|
||||
aibig_table->ai_big_attack_get_data(enemy_pos, dist_to_enemy, dot_to_enemy);
|
||||
}
|
||||
|
||||
void ai_big_strafe_attack ()
|
||||
{
|
||||
aibig_table->ai_big_strafe_attack();
|
||||
}
|
||||
|
||||
void ai_big_strafe_avoid ()
|
||||
{
|
||||
aibig_table->ai_big_strafe_avoid();
|
||||
}
|
||||
|
||||
void ai_big_strafe_retreat1 ()
|
||||
{
|
||||
aibig_table->ai_big_strafe_retreat1();
|
||||
}
|
||||
|
||||
void ai_big_strafe_retreat2 ()
|
||||
{
|
||||
aibig_table->ai_big_strafe_retreat2();
|
||||
}
|
||||
|
||||
void ai_big_strafe_position ()
|
||||
{
|
||||
aibig_table->ai_big_strafe_position();
|
||||
}
|
||||
|
||||
void ai_big_strafe ()
|
||||
{
|
||||
aibig_table->ai_big_strafe();
|
||||
}
|
||||
|
||||
int ai_big_maybe_enter_strafe_mode (object *pl_objp, int weapon_objnum, int consider_target_only)
|
||||
{
|
||||
return aibig_table->ai_big_maybe_enter_strafe_mode(pl_objp, weapon_objnum, consider_target_only);
|
||||
}
|
||||
|
||||
void ai_big_strafe_maybe_attack_turret (object *ship_objp, object *weapon_objp)
|
||||
{
|
||||
aibig_table->ai_big_strafe_maybe_attack_turret(ship_objp, weapon_objp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// AI Big Default implementation
|
||||
|
||||
// Called by ai_big_pick_attack_point.
|
||||
// Generates a random attack point.
|
||||
// If truly_random flag set (haha), then generate a pretty random number. Otherwise, generate a static rand which
|
||||
// tends to not change from frame to frame.
|
||||
// Try four times and choose nearest point to increase chance of getting a good point.
|
||||
void ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal)
|
||||
void aibig_ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal)
|
||||
{
|
||||
float nearest_dist;
|
||||
vec3d result_point, best_point;
|
||||
@@ -607,7 +735,7 @@ done_1:
|
||||
//
|
||||
// Note: Default value for fov is 1.0f 1.0f means don't use fov parameter.
|
||||
// If fov != 1.0f, try up to four times to find a point that's in the field of view.
|
||||
void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
|
||||
void aibig_ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist)
|
||||
{
|
||||
if (!timestamp_elapsed(ssp->turret_pick_big_attack_point_timestamp)) {
|
||||
vec3d result_point;
|
||||
@@ -627,7 +755,7 @@ void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos
|
||||
// Note: Default value for fov is 1.0f 1.0f means don't use fov parameter.
|
||||
// If fov != 1.0f, try up to four times to find a point that's in the field of view.
|
||||
// Note, attacker_objp can be a ship or a weapon.
|
||||
void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov)
|
||||
void aibig_ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov)
|
||||
{
|
||||
Assert(objp->instance > -1);
|
||||
Assert(objp->type == OBJ_SHIP);
|
||||
@@ -696,7 +824,7 @@ void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack
|
||||
}
|
||||
|
||||
// Handler for SM_EVADE submode ( called from ai_big_chase() )
|
||||
void ai_big_evade_ship()
|
||||
void aibig_ai_big_evade_ship()
|
||||
{
|
||||
vec3d player_pos, enemy_pos;
|
||||
float dist;
|
||||
@@ -744,13 +872,13 @@ void ai_big_evade_ship()
|
||||
}
|
||||
|
||||
// Handler for SM_AVOID submode ( called from ai_big_chase() )
|
||||
void ai_big_avoid_ship()
|
||||
void aibig_ai_big_avoid_ship()
|
||||
{
|
||||
ai_big_evade_ship();
|
||||
}
|
||||
|
||||
// reset path following information
|
||||
void ai_big_subsys_path_cleanup(ai_info *aip)
|
||||
void aibig_ai_big_subsys_path_cleanup(ai_info *aip)
|
||||
{
|
||||
if ( aip->ai_flags & AIF_ON_SUBSYS_PATH ) {
|
||||
aip->ai_flags &= ~AIF_ON_SUBSYS_PATH;
|
||||
@@ -765,7 +893,7 @@ void ai_big_subsys_path_cleanup(ai_info *aip)
|
||||
// input: do_dot_check => default value 0, flag to indicate whether check should be done to ensure
|
||||
// subsystem is within certain field of view. We don't want to check fov when
|
||||
// strafing, since ship is weaving to avoid turret fire
|
||||
int ai_big_maybe_follow_subsys_path(int do_dot_check)
|
||||
int aibig_ai_big_maybe_follow_subsys_path(int do_dot_check)
|
||||
{
|
||||
ai_info *aip;
|
||||
float dot = 1.0f, min_dot;
|
||||
@@ -899,7 +1027,7 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
|
||||
// 0 => ship should not change ai mode, no fighter/bomber threats are near
|
||||
//
|
||||
// NOTE: uses SCAN_FIGHTERS_INTERVAL and ENTER_STRAFE_THREAT_DIST_SQUARED which are defined in AiBig.h
|
||||
int ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
|
||||
int aibig_ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
|
||||
{
|
||||
// if moving slowly (or stopped), and SIF_SMALL_SHIP, then enter STRAFE mode if enemy fighter/bombers
|
||||
// are near
|
||||
@@ -934,7 +1062,7 @@ int ai_big_maybe_start_strafe(ai_info *aip, ship_info *sip)
|
||||
}
|
||||
|
||||
// ATTACK submode handler for chase mode.
|
||||
void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum)
|
||||
void aibig_ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum)
|
||||
{
|
||||
int start_bank;
|
||||
float dot_to_enemy, time_to_hit;
|
||||
@@ -1051,7 +1179,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
|
||||
}
|
||||
|
||||
// Handler for submode SM_CONTINUOUS_TURN
|
||||
void ai_big_chase_ct()
|
||||
void aibig_ai_big_chase_ct()
|
||||
{
|
||||
ai_chase_ct();
|
||||
}
|
||||
@@ -1068,7 +1196,7 @@ extern void maybe_cheat_fire_synaptic(object *objp, ai_info *aip);
|
||||
// dist_to_enemy => distance (in m) to attack point on current target
|
||||
// dot_to_enemy => dot product between fvec of Pl_objp and vector from Pl_objp to attack point
|
||||
//
|
||||
void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel)
|
||||
void aibig_ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel)
|
||||
{
|
||||
ai_info *aip;
|
||||
ship_weapon *swp;
|
||||
@@ -1173,7 +1301,7 @@ void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *f
|
||||
}
|
||||
|
||||
// switch ai ship into chase mode
|
||||
void ai_big_switch_to_chase_mode(ai_info *aip)
|
||||
void aibig_ai_big_switch_to_chase_mode(ai_info *aip)
|
||||
{
|
||||
aip->previous_mode = aip->mode;
|
||||
aip->mode = AIM_CHASE;
|
||||
@@ -1184,7 +1312,7 @@ void ai_big_switch_to_chase_mode(ai_info *aip)
|
||||
extern int ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos);
|
||||
|
||||
// Make object Pl_objp chase object En_objp, which is a big ship, not a small ship.
|
||||
void ai_big_chase()
|
||||
void aibig_ai_big_chase()
|
||||
{
|
||||
float dist_to_enemy, dot_to_enemy;
|
||||
vec3d player_pos, enemy_pos, vec_to_enemy;
|
||||
@@ -1474,7 +1602,7 @@ void ai_big_chase()
|
||||
aip->time_enemy_in_range *= (1.0f - flFrametime);
|
||||
}
|
||||
|
||||
void ai_big_ship(object *objp)
|
||||
void aibig_ai_big_ship(object *objp)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@@ -1485,7 +1613,7 @@ void ai_big_ship(object *objp)
|
||||
// dist => distance from Pl_objp front to attack point
|
||||
// dot => dot of Pl_objp fvec and vector to attack point
|
||||
// fire_pos => world pos from which firing
|
||||
void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy)
|
||||
void aibig_ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy)
|
||||
{
|
||||
vec3d player_pos, vec_to_enemy, predicted_enemy_pos;
|
||||
ship *shipp = &Ships[Pl_objp->instance];
|
||||
@@ -1544,7 +1672,7 @@ void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_t
|
||||
|
||||
// check to see if Pl_objp has gotten too close to attacking point.. if so, break off by entering
|
||||
// AIS_STRAFE_RETREAT
|
||||
int ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
|
||||
int aibig_ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
|
||||
{
|
||||
ai_info *aip;
|
||||
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
|
||||
@@ -1601,7 +1729,7 @@ int ai_big_strafe_maybe_retreat(float dist, vec3d *target_pos)
|
||||
}
|
||||
|
||||
// attack directly to the turret and fire weapons
|
||||
void ai_big_strafe_attack()
|
||||
void aibig_ai_big_strafe_attack()
|
||||
{
|
||||
ai_info *aip;
|
||||
vec3d target_pos;
|
||||
@@ -1704,7 +1832,7 @@ void ai_big_strafe_attack()
|
||||
}
|
||||
|
||||
// pick a new attack point when entering this state, and keep using it
|
||||
void ai_big_strafe_avoid()
|
||||
void aibig_ai_big_strafe_avoid()
|
||||
{
|
||||
ai_info *aip;
|
||||
vec3d target_pos;
|
||||
@@ -1730,7 +1858,7 @@ void ai_big_strafe_avoid()
|
||||
}
|
||||
|
||||
// move towards aip->goal_point in an evasive manner
|
||||
void ai_big_strafe_retreat1()
|
||||
void aibig_ai_big_strafe_retreat1()
|
||||
{
|
||||
float dist;
|
||||
ai_info *aip;
|
||||
@@ -1776,7 +1904,7 @@ void ai_big_strafe_retreat1()
|
||||
accelerate_ship(aip, 1.0f);
|
||||
}
|
||||
|
||||
void ai_big_strafe_retreat2()
|
||||
void aibig_ai_big_strafe_retreat2()
|
||||
{
|
||||
float dist;
|
||||
ai_info *aip;
|
||||
@@ -1815,7 +1943,7 @@ void ai_big_strafe_retreat2()
|
||||
}
|
||||
|
||||
// reposition self to begin another strafing run
|
||||
void ai_big_strafe_position()
|
||||
void aibig_ai_big_strafe_position()
|
||||
{
|
||||
ai_info *aip;
|
||||
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
|
||||
@@ -1833,7 +1961,7 @@ void ai_big_strafe_position()
|
||||
// #define AIS_STRAFE_RETREAT1 204 // fly away from attack point (on an avoid vector)
|
||||
// #define AIS_STRAFE_POSITION 205 // re-position to resume strafing attack
|
||||
//
|
||||
void ai_big_strafe()
|
||||
void aibig_ai_big_strafe()
|
||||
{
|
||||
ai_info *aip;
|
||||
|
||||
@@ -1883,7 +2011,7 @@ void ai_big_strafe()
|
||||
//
|
||||
// Check if weapon_objnum was fired by Pl_objp's target, and whether Pl_objp's target is a big ship, if
|
||||
// so, enter AIM_STRAFE
|
||||
int ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int consider_target_only)
|
||||
int aibig_ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int consider_target_only)
|
||||
{
|
||||
ai_info *aip;
|
||||
ship_info *sip;
|
||||
@@ -1957,7 +2085,7 @@ int ai_big_maybe_enter_strafe_mode(object *pl_objp, int weapon_objnum, int consi
|
||||
// Consider attacking a turret, if a turret actually fired the weapon
|
||||
// input: ship_objp => ship that will attack the turret
|
||||
// weapon_objp =>
|
||||
void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp)
|
||||
void aibig_ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp)
|
||||
{
|
||||
ai_info *aip;
|
||||
object *parent_objp;
|
||||
@@ -2006,3 +2134,30 @@ void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp)
|
||||
// attack the turret
|
||||
set_targeted_subsys(aip, Weapons[weapon_objp->instance].turret_subsys, OBJ_INDEX(parent_objp));
|
||||
}
|
||||
|
||||
struct aibig_call_table AIBigDefaultTable = {
|
||||
aibig_ai_big_evade_ship,
|
||||
aibig_ai_big_chase_attack,
|
||||
aibig_ai_big_avoid_ship,
|
||||
aibig_ai_big_maybe_follow_subsys_path,
|
||||
aibig_ai_bpap,
|
||||
aibig_ai_big_pick_attack_point_turret,
|
||||
aibig_ai_big_pick_attack_point,
|
||||
aibig_ai_big_subsys_path_cleanup,
|
||||
aibig_ai_big_maybe_start_strafe,
|
||||
aibig_ai_big_chase_ct,
|
||||
aibig_ai_big_maybe_fire_weapons,
|
||||
aibig_ai_big_switch_to_chase_mode,
|
||||
aibig_ai_big_strafe_maybe_retreat,
|
||||
aibig_ai_big_chase,
|
||||
aibig_ai_big_ship,
|
||||
aibig_ai_big_attack_get_data,
|
||||
aibig_ai_big_strafe_attack,
|
||||
aibig_ai_big_strafe_avoid,
|
||||
aibig_ai_big_strafe_retreat1,
|
||||
aibig_ai_big_strafe_retreat2,
|
||||
aibig_ai_big_strafe_position,
|
||||
aibig_ai_big_strafe,
|
||||
aibig_ai_big_maybe_enter_strafe_mode,
|
||||
aibig_ai_big_strafe_maybe_attack_turret
|
||||
};
|
||||
@@ -102,6 +102,43 @@ void ai_big_strafe_maybe_attack_turret(object *ship_objp, object *weapon_objp);
|
||||
void ai_big_pick_attack_point(object *objp, object *attacker_objp, vec3d *attack_point, float fov=1.0f);
|
||||
void ai_big_pick_attack_point_turret(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float weapon_travel_dist, float fov=1.0f);
|
||||
|
||||
// AI Big Table Wrapper
|
||||
|
||||
#include "ship/ship.h"
|
||||
|
||||
struct aibig_call_table
|
||||
{
|
||||
void (*ai_big_evade_ship) ();
|
||||
void (*ai_big_chase_attack) (ai_info *aip, ship_info *sip, vec3d *enemy_pos, float dist_to_enemy, int modelnum);
|
||||
void (*ai_big_avoid_ship) ();
|
||||
int (*ai_big_maybe_follow_subsys_path) (int do_dot_check=1);
|
||||
void (*ai_bpap) (object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, vec3d *attack_point, vec3d *local_attack_point, float fov, float weapon_travel_dist, vec3d *surface_normal);
|
||||
void (*ai_big_pick_attack_point_turret) (object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, vec3d *attack_point, float fov, float weapon_travel_dist);
|
||||
void (*ai_big_pick_attack_point) (object *objp, object *attacker_objp, vec3d *attack_point, float fov);
|
||||
void (*ai_big_subsys_path_cleanup) (ai_info *aip);
|
||||
int (*ai_big_maybe_start_strafe) (ai_info *aip, ship_info *sip);
|
||||
void (*ai_big_chase_ct) ();
|
||||
void (*ai_big_maybe_fire_weapons) (float dist_to_enemy, float dot_to_enemy, vec3d *firing_pos, vec3d *enemy_pos, vec3d *enemy_vel);
|
||||
void (*ai_big_switch_to_chase_mode) (ai_info *aip);
|
||||
int (*ai_big_strafe_maybe_retreat) (float dist, vec3d *target_pos);
|
||||
void (*ai_big_chase) ();
|
||||
void (*ai_big_ship) (object *objp);
|
||||
void (*ai_big_attack_get_data) (vec3d *enemy_pos, float *dist_to_enemy, float *dot_to_enemy);
|
||||
void (*ai_big_strafe_attack) ();
|
||||
void (*ai_big_strafe_avoid) ();
|
||||
void (*ai_big_strafe_retreat1) ();
|
||||
void (*ai_big_strafe_retreat2) ();
|
||||
void (*ai_big_strafe_position) ();
|
||||
void (*ai_big_strafe) ();
|
||||
int (*ai_big_maybe_enter_strafe_mode) (object *pl_objp, int weapon_objnum, int consider_target_only);
|
||||
void (*ai_big_strafe_maybe_attack_turret) (object *ship_objp, object *weapon_objp);
|
||||
};
|
||||
|
||||
// Set new pointer to override ai_big* function calls
|
||||
// possibly copying the old function calls first
|
||||
|
||||
extern struct aibig_call_table *aibig_table;
|
||||
|
||||
extern struct aibig_call_table AIBigDefaultTable;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -772,11 +772,176 @@ ai_goal_list Ai_goal_names[] =
|
||||
|
||||
int Num_ai_goals = sizeof(Ai_goal_names) / sizeof(ai_goal_list);
|
||||
|
||||
// FF 04-06-07
|
||||
// AI Goal Table Wrapper
|
||||
|
||||
struct aigoal_call_table *aigoal_table = &AIGoalDefaultTable;
|
||||
|
||||
char* Ai_goal_text (int goal)
|
||||
{
|
||||
return aigoal_table->Ai_goal_text(goal);
|
||||
}
|
||||
|
||||
void ai_maybe_add_form_goal (wing *wingp)
|
||||
{
|
||||
aigoal_table->ai_maybe_add_form_goal(wingp);
|
||||
}
|
||||
|
||||
void ai_post_process_mission ()
|
||||
{
|
||||
aigoal_table->ai_post_process_mission();
|
||||
}
|
||||
|
||||
int ai_query_goal_valid (int ship, int ai_goal)
|
||||
{
|
||||
return aigoal_table->ai_query_goal_valid(ship, ai_goal);
|
||||
}
|
||||
|
||||
void ai_remove_ship_goal (ai_info *aip, int index)
|
||||
{
|
||||
aigoal_table->ai_remove_ship_goal(aip, index);
|
||||
}
|
||||
|
||||
void ai_clear_ship_goals (ai_info *aip)
|
||||
{
|
||||
aigoal_table->ai_clear_ship_goals(aip);
|
||||
}
|
||||
|
||||
void ai_clear_wing_goals (int wingnum)
|
||||
{
|
||||
aigoal_table->ai_clear_wing_goals(wingnum);
|
||||
}
|
||||
|
||||
void ai_mission_wing_goal_complete (int wingnum, ai_goal *remove_goalp)
|
||||
{
|
||||
aigoal_table->ai_mission_wing_goal_complete(wingnum, remove_goalp);
|
||||
}
|
||||
|
||||
void ai_mission_goal_complete (ai_info *aip)
|
||||
{
|
||||
aigoal_table->ai_mission_goal_complete(aip);
|
||||
}
|
||||
|
||||
int ai_get_subsystem_type (char *subsystem)
|
||||
{
|
||||
return aigoal_table->ai_get_subsystem_type(subsystem);
|
||||
}
|
||||
|
||||
void ai_goal_purge_invalid_goals (ai_goal *aigp, ai_goal *goal_list)
|
||||
{
|
||||
aigoal_table->ai_goal_purge_invalid_goals(aigp, goal_list);
|
||||
}
|
||||
|
||||
void ai_goal_purge_all_invalid_goals (ai_goal *aigp)
|
||||
{
|
||||
aigoal_table->ai_goal_purge_all_invalid_goals(aigp);
|
||||
}
|
||||
|
||||
int ai_goal_find_dockpoint (int shipnum, int dock_type)
|
||||
{
|
||||
return aigoal_table->ai_goal_find_dockpoint(shipnum, dock_type);
|
||||
}
|
||||
|
||||
void ai_goal_fixup_dockpoints (ai_info *aip, ai_goal *aigp)
|
||||
{
|
||||
aigoal_table->ai_goal_fixup_dockpoints(aip, aigp);
|
||||
}
|
||||
|
||||
void ai_add_goal_sub_player (int type, int mode, int submode, char *shipname, ai_goal *aigp)
|
||||
{
|
||||
aigoal_table->ai_add_goal_sub_player(type, mode, submode, shipname, aigp);
|
||||
}
|
||||
|
||||
int ai_goal_find_empty_slot (ai_goal *goals, int active_goal)
|
||||
{
|
||||
return aigoal_table->ai_goal_find_empty_slot(goals, active_goal);
|
||||
}
|
||||
|
||||
void ai_add_ship_goal_player (int type, int mode, int submode, char *shipname, ai_info *aip)
|
||||
{
|
||||
aigoal_table->ai_add_ship_goal_player(type, mode, submode, shipname, aip);
|
||||
}
|
||||
|
||||
void ai_add_wing_goal_player (int type, int mode, int submode, char *shipname, int wingnum)
|
||||
{
|
||||
aigoal_table->ai_add_wing_goal_player(type, mode, submode, shipname, wingnum);
|
||||
}
|
||||
|
||||
void ai_add_goal_sub_sexp (int sexp, int type, ai_goal *aigp, char *actor_name)
|
||||
{
|
||||
aigoal_table->ai_add_goal_sub_sexp(sexp, type, aigp, actor_name);
|
||||
}
|
||||
|
||||
void ai_add_ship_goal_sexp (int sexp, int type, ai_info *aip)
|
||||
{
|
||||
aigoal_table->ai_add_ship_goal_sexp(sexp, type, aip);
|
||||
}
|
||||
|
||||
void ai_add_wing_goal_sexp (int sexp, int type, int wingnum)
|
||||
{
|
||||
aigoal_table->ai_add_wing_goal_sexp(sexp, type, wingnum);
|
||||
}
|
||||
|
||||
void ai_add_goal_ship_internal (ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate)
|
||||
{
|
||||
aigoal_table->ai_add_goal_ship_internal(aip, goal_type, name, docker_point, dockee_point, immediate);
|
||||
}
|
||||
|
||||
void ai_add_goal_wing_internal (wing *wingp, int goal_type, char *name, int immediate)
|
||||
{
|
||||
aigoal_table->ai_add_goal_wing_internal(wingp, goal_type, name, immediate);
|
||||
}
|
||||
|
||||
void ai_copy_mission_wing_goal (ai_goal *aigp, ai_info *aip)
|
||||
{
|
||||
aigoal_table->ai_copy_mission_wing_goal(aigp, aip);
|
||||
}
|
||||
|
||||
int ai_mission_goal_achievable (int objnum, ai_goal *aigp)
|
||||
{
|
||||
return aigoal_table->ai_mission_goal_achievable(objnum, aigp);
|
||||
}
|
||||
|
||||
int ai_goal_priority_compare (const void *a, const void *b)
|
||||
{
|
||||
return aigoal_table->ai_goal_priority_compare(a, b);
|
||||
}
|
||||
|
||||
void prioritize_goals (int objnum, ai_info *aip)
|
||||
{
|
||||
aigoal_table->prioritize_goals(objnum, aip);
|
||||
}
|
||||
|
||||
void validate_mission_goals (int objnum, ai_info *aip)
|
||||
{
|
||||
aigoal_table->validate_mission_goals(objnum, aip);
|
||||
}
|
||||
|
||||
void ai_process_mission_orders (int objnum, ai_info *aip)
|
||||
{
|
||||
aigoal_table->ai_process_mission_orders(objnum, aip);
|
||||
}
|
||||
|
||||
void ai_update_goal_references (ai_goal *goals, int type, char *old_name, char *new_name)
|
||||
{
|
||||
aigoal_table->ai_update_goal_references(goals, type, old_name, new_name);
|
||||
}
|
||||
|
||||
int query_referenced_in_ai_goals (ai_goal *goals, int type, char *name)
|
||||
{
|
||||
return aigoal_table->query_referenced_in_ai_goals(goals, type, name);
|
||||
}
|
||||
|
||||
char* ai_add_dock_name (char *str)
|
||||
{
|
||||
return aigoal_table->ai_add_dock_name(str);
|
||||
}
|
||||
|
||||
// AL 11-17-97: A text description of the AI goals. This is used for printing out on the
|
||||
// HUD what a ship's current orders are. If the AI goal doesn't correspond to something that
|
||||
// ought to be printable, then NULL is used.
|
||||
// JAS: Converted to a function in order to externalize the strings
|
||||
char *Ai_goal_text(int goal)
|
||||
char *aigoal_Ai_goal_text(int goal)
|
||||
{
|
||||
switch(goal) {
|
||||
case 1:
|
||||
@@ -815,7 +980,7 @@ char *Ai_goal_text(int goal)
|
||||
|
||||
// function to maybe add the form on my wing goal for a player's starting wing. Called when a player wing arrives.
|
||||
// Goober5000 - made more generic
|
||||
void ai_maybe_add_form_goal( wing *wingp )
|
||||
void aigoal_ai_maybe_add_form_goal( wing *wingp )
|
||||
{
|
||||
int j;
|
||||
char *wing_leader;
|
||||
@@ -853,7 +1018,7 @@ void ai_maybe_add_form_goal( wing *wingp )
|
||||
}
|
||||
}
|
||||
|
||||
void ai_post_process_mission()
|
||||
void aigoal_ai_post_process_mission()
|
||||
{
|
||||
object *objp;
|
||||
|
||||
@@ -907,7 +1072,7 @@ void ai_post_process_mission()
|
||||
}
|
||||
|
||||
// function which determines is a goal is valid for a particular type of ship
|
||||
int ai_query_goal_valid( int ship, int ai_goal )
|
||||
int aigoal_ai_query_goal_valid( int ship, int ai_goal )
|
||||
{
|
||||
int accepted;
|
||||
|
||||
@@ -930,7 +1095,7 @@ int ai_query_goal_valid( int ship, int ai_goal )
|
||||
}
|
||||
|
||||
// remove an ai goal from it's list. Uses the active_goal member as the goal to remove
|
||||
void ai_remove_ship_goal( ai_info *aip, int index )
|
||||
void aigoal_ai_remove_ship_goal( ai_info *aip, int index )
|
||||
{
|
||||
// only need to set the ai_mode for the particular goal to AI_GOAL_NONE
|
||||
// reset ai mode to default behavior. Might get changed next time through
|
||||
@@ -950,7 +1115,7 @@ void ai_remove_ship_goal( ai_info *aip, int index )
|
||||
//ai_do_default_behavior( &Objects[Ships[aip->shipnum].objnum] );
|
||||
}
|
||||
|
||||
void ai_clear_ship_goals( ai_info *aip )
|
||||
void aigoal_ai_clear_ship_goals( ai_info *aip )
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -969,7 +1134,7 @@ void ai_clear_ship_goals( ai_info *aip )
|
||||
}
|
||||
}
|
||||
|
||||
void ai_clear_wing_goals( int wingnum )
|
||||
void aigoal_ai_clear_wing_goals( int wingnum )
|
||||
{
|
||||
int i;
|
||||
wing *wingp = &Wings[wingnum];
|
||||
@@ -999,7 +1164,7 @@ void ai_clear_wing_goals( int wingnum )
|
||||
// structure of the goal to be removed. This process is slightly tricky since some member of the wing
|
||||
// might be pursuing a different goal. We will have to compare based on mode, submode, priority,
|
||||
// and name.. This routine is only currently called from waypoint code!!!
|
||||
void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
|
||||
void aigoal_ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
|
||||
{
|
||||
int mode, submode, priority, i;
|
||||
char *name;
|
||||
@@ -1059,7 +1224,7 @@ void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp )
|
||||
// routine which is called with an ai object complete it's goal. Do some action
|
||||
// based on the goal what was just completed
|
||||
|
||||
void ai_mission_goal_complete( ai_info *aip )
|
||||
void aigoal_ai_mission_goal_complete( ai_info *aip )
|
||||
{
|
||||
// if the active goal is dynamic or none, just return. (AI_GOAL_NONE is probably an error, but
|
||||
// I don't think that this is a problem)
|
||||
@@ -1071,7 +1236,7 @@ void ai_mission_goal_complete( ai_info *aip )
|
||||
|
||||
}
|
||||
|
||||
int ai_get_subsystem_type( char *subsystem )
|
||||
int aigoal_ai_get_subsystem_type( char *subsystem )
|
||||
{
|
||||
if ( strstr(subsystem, "engine") ) {
|
||||
return SUBSYSTEM_ENGINE;
|
||||
@@ -1107,7 +1272,7 @@ int ai_get_subsystem_type( char *subsystem )
|
||||
// which are destroy, etc, should get removed. goal list is the list of goals to purge. It is
|
||||
// always MAX_AI_GOALS in length. This function will only get called when the goal which causes
|
||||
// purging becomes valid.
|
||||
void ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list )
|
||||
void aigoal_ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list )
|
||||
{
|
||||
int i;
|
||||
ai_goal *purge_goal;
|
||||
@@ -1173,7 +1338,7 @@ void ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list )
|
||||
}
|
||||
|
||||
// function to purge the goals of *all* ships in the game based on the incoming goal structure
|
||||
void ai_goal_purge_all_invalid_goals(ai_goal *aigp)
|
||||
void aigoal_ai_goal_purge_all_invalid_goals(ai_goal *aigp)
|
||||
{
|
||||
int i;
|
||||
ship_obj *sop;
|
||||
@@ -1196,7 +1361,7 @@ void ai_goal_purge_all_invalid_goals(ai_goal *aigp)
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
int ai_goal_find_dockpoint(int shipnum, int dock_type)
|
||||
int aigoal_ai_goal_find_dockpoint(int shipnum, int dock_type)
|
||||
{
|
||||
int dock_index = -1;
|
||||
int loop_count = 0;
|
||||
@@ -1247,7 +1412,7 @@ int ai_goal_find_dockpoint(int shipnum, int dock_type)
|
||||
// passed are the pointer to goal we are working with. aip if the ai_info pointer
|
||||
// of the ship with the order. aigp is a pointer to the goal (of aip) of which we are
|
||||
// fixing up the docking points
|
||||
void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
|
||||
void aigoal_ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
|
||||
{
|
||||
int shipnum, docker_index, dockee_index;
|
||||
|
||||
@@ -1318,7 +1483,7 @@ void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
|
||||
// from the mission goals (i.e. those goals which come from events) in that we don't
|
||||
// use sexpressions for goals from the player...so we enumerate all the parameters
|
||||
|
||||
void ai_add_goal_sub_player(int type, int mode, int submode, char *shipname, ai_goal *aigp )
|
||||
void aigoal_ai_add_goal_sub_player(int type, int mode, int submode, char *shipname, ai_goal *aigp )
|
||||
{
|
||||
Assert ( (type == AIG_TYPE_PLAYER_WING) || (type == AIG_TYPE_PLAYER_SHIP) );
|
||||
|
||||
@@ -1359,7 +1524,7 @@ void ai_add_goal_sub_player(int type, int mode, int submode, char *shipname, ai_
|
||||
// friendlies want to rearm at the same time. The support ship forgets what it's doing and flies
|
||||
// off to repair somebody while still docked. I reproduced this with retail, so it's not a bug in
|
||||
// my new docking code. :)
|
||||
int ai_goal_find_empty_slot( ai_goal *goals, int active_goal )
|
||||
int aigoal_ai_goal_find_empty_slot( ai_goal *goals, int active_goal )
|
||||
{
|
||||
int gindex, oldest_index;
|
||||
|
||||
@@ -1389,7 +1554,7 @@ int ai_goal_find_empty_slot( ai_goal *goals, int active_goal )
|
||||
// is issued to ship or wing (from player), mode is AI_GOAL_*. submode is the submode the
|
||||
// ship should go into. shipname is the object of the action. aip is the ai_info pointer
|
||||
// of the ship receiving the order
|
||||
void ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip )
|
||||
void aigoal_ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip )
|
||||
{
|
||||
int empty_index;
|
||||
ai_goal *aigp;
|
||||
@@ -1415,7 +1580,7 @@ void ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, a
|
||||
|
||||
// adds a goal from the player to the given wing (which in turn will add it to the proper
|
||||
// ships in the wing
|
||||
void ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, int wingnum )
|
||||
void aigoal_ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, int wingnum )
|
||||
{
|
||||
int i, empty_index;
|
||||
wing *wingp = &Wings[wingnum];
|
||||
@@ -1439,7 +1604,7 @@ void ai_add_wing_goal_player( int type, int mode, int submode, char *shipname, i
|
||||
|
||||
|
||||
// common routine to add a sexpression mission goal to the appropriate goal structure.
|
||||
void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
void aigoal_ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
{
|
||||
int node, dummy, op;
|
||||
char *text;
|
||||
@@ -1630,7 +1795,7 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
|
||||
// adds an ai goal for an individual ship
|
||||
// type determines who has issues this ship a goal (i.e. the player/mission event/etc)
|
||||
void ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip )
|
||||
void aigoal_ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip )
|
||||
{
|
||||
int gindex;
|
||||
|
||||
@@ -1639,7 +1804,7 @@ void ai_add_ship_goal_sexp( int sexp, int type, ai_info *aip )
|
||||
}
|
||||
|
||||
// code to add ai goals to wings.
|
||||
void ai_add_wing_goal_sexp(int sexp, int type, int wingnum)
|
||||
void aigoal_ai_add_wing_goal_sexp(int sexp, int type, int wingnum)
|
||||
{
|
||||
int i;
|
||||
wing *wingp = &Wings[wingnum];
|
||||
@@ -1673,7 +1838,7 @@ void ai_add_wing_goal_sexp(int sexp, int type, int wingnum)
|
||||
// this name can be a shipname or a wingname)
|
||||
// docker_point and dockee_point are used for the AI_GOAL_DOCK command to tell two ships where to dock
|
||||
// immediate means to process this order right away
|
||||
void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate )
|
||||
void aigoal_ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate )
|
||||
{
|
||||
int gindex;
|
||||
ai_goal *aigp;
|
||||
@@ -1753,7 +1918,7 @@ void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int doc
|
||||
// across waves of the wing so we merely need to add the goal to each ship in the wing. Certain
|
||||
// goal are simply not valid for wings (like dock, undock). Immediate parameter gets passed to add_ship_goal
|
||||
// to say whether or not we should process this goal right away
|
||||
void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate )
|
||||
void aigoal_ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate )
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1769,7 +1934,7 @@ void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int imme
|
||||
}
|
||||
|
||||
// this function copies goals from a wing to an ai_info * from a ship.
|
||||
void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
|
||||
void aigoal_ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
|
||||
{
|
||||
int j;
|
||||
|
||||
@@ -1790,7 +1955,7 @@ void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
|
||||
// function to determine if an ai goal is achieveable or not. Will return
|
||||
// one of the AI_GOAL_* values. Also determines is a goal was successful.
|
||||
|
||||
int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
int aigoal_ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
{
|
||||
int status;
|
||||
char *ai_shipname;
|
||||
@@ -2269,7 +2434,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
|
||||
// Compare function for sorting ai_goals based on priority.
|
||||
// Return values set to sort array in _decreasing_ order.
|
||||
int ai_goal_priority_compare(const void *a, const void *b)
|
||||
int aigoal_ai_goal_priority_compare(const void *a, const void *b)
|
||||
{
|
||||
ai_goal *ga, *gb;
|
||||
|
||||
@@ -2318,7 +2483,7 @@ int ai_goal_priority_compare(const void *a, const void *b)
|
||||
// Then sort on time for goals of equivalent priority.
|
||||
// objnum The object number to act upon. Redundant with *aip.
|
||||
// *aip The AI info to act upon. Goals are stored at aip->goals
|
||||
void prioritize_goals(int objnum, ai_info *aip)
|
||||
void aigoal_prioritize_goals(int objnum, ai_info *aip)
|
||||
{
|
||||
// First sort based on priority field.
|
||||
insertion_sort(aip->goals, MAX_AI_GOALS, sizeof(ai_goal), ai_goal_priority_compare);
|
||||
@@ -2328,7 +2493,7 @@ void prioritize_goals(int objnum, ai_info *aip)
|
||||
// Remove obsolete goals.
|
||||
// objnum Object of interest. Redundant with *aip.
|
||||
// *aip contains goals at aip->goals.
|
||||
void validate_mission_goals(int objnum, ai_info *aip)
|
||||
void aigoal_validate_mission_goals(int objnum, ai_info *aip)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -2403,7 +2568,7 @@ extern char *Mode_text[MAX_AI_BEHAVIORS];
|
||||
// code to process ai "orders". Orders include those determined from the mission file and those
|
||||
// given by the player to a ship that is under his control. This function gets called for every
|
||||
// AI object every N seconds through the ai loop.
|
||||
void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
void aigoal_ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
{
|
||||
object *objp = &Objects[objnum];
|
||||
object *other_obj;
|
||||
@@ -2724,7 +2889,7 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
|
||||
}
|
||||
|
||||
void ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *new_name)
|
||||
void aigoal_ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *new_name)
|
||||
{
|
||||
int i, mode, flag, dummy;
|
||||
|
||||
@@ -2791,7 +2956,7 @@ void ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *n
|
||||
}
|
||||
}
|
||||
|
||||
int query_referenced_in_ai_goals(ai_goal *goals, int type, char *name)
|
||||
int aigoal_query_referenced_in_ai_goals(ai_goal *goals, int type, char *name)
|
||||
{
|
||||
int i, mode, flag;
|
||||
|
||||
@@ -2856,7 +3021,7 @@ int query_referenced_in_ai_goals(ai_goal *goals, int type, char *name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *ai_add_dock_name(char *str)
|
||||
char *aigoal_ai_add_dock_name(char *str)
|
||||
{
|
||||
char *ptr;
|
||||
int i;
|
||||
@@ -2871,3 +3036,39 @@ char *ai_add_dock_name(char *str)
|
||||
strcpy(ptr, str);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
struct aigoal_call_table AIGoalDefaultTable = {
|
||||
aigoal_Ai_goal_text,
|
||||
aigoal_ai_maybe_add_form_goal,
|
||||
aigoal_ai_post_process_mission,
|
||||
aigoal_ai_query_goal_valid,
|
||||
aigoal_ai_remove_ship_goal,
|
||||
aigoal_ai_clear_ship_goals,
|
||||
aigoal_ai_clear_wing_goals,
|
||||
aigoal_ai_mission_wing_goal_complete,
|
||||
aigoal_ai_mission_goal_complete,
|
||||
aigoal_ai_get_subsystem_type,
|
||||
aigoal_ai_goal_purge_invalid_goals,
|
||||
aigoal_ai_goal_purge_all_invalid_goals,
|
||||
aigoal_ai_goal_find_dockpoint,
|
||||
aigoal_ai_goal_fixup_dockpoints,
|
||||
aigoal_ai_add_goal_sub_player,
|
||||
aigoal_ai_goal_find_empty_slot,
|
||||
aigoal_ai_add_ship_goal_player,
|
||||
aigoal_ai_add_wing_goal_player,
|
||||
aigoal_ai_add_goal_sub_sexp,
|
||||
aigoal_ai_add_ship_goal_sexp,
|
||||
aigoal_ai_add_wing_goal_sexp,
|
||||
aigoal_ai_add_goal_ship_internal,
|
||||
aigoal_ai_add_goal_wing_internal,
|
||||
aigoal_ai_copy_mission_wing_goal,
|
||||
aigoal_ai_mission_goal_achievable,
|
||||
aigoal_ai_goal_priority_compare,
|
||||
aigoal_prioritize_goals,
|
||||
aigoal_validate_mission_goals,
|
||||
aigoal_ai_process_mission_orders,
|
||||
aigoal_ai_update_goal_references,
|
||||
aigoal_query_referenced_in_ai_goals,
|
||||
aigoal_ai_add_dock_name
|
||||
};
|
||||
@@ -292,4 +292,48 @@ extern int ai_query_goal_valid( int ship, int ai_goal );
|
||||
extern void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate = 1 );
|
||||
extern void ai_add_goal_wing_internal( wing *wingp, int goal_type, char *name, int immediate = 1 );
|
||||
|
||||
// AI Goal Table Wrapper
|
||||
struct aigoal_call_table
|
||||
{
|
||||
char* (*Ai_goal_text) (int goal);
|
||||
void (*ai_maybe_add_form_goal) (wing *wingp);
|
||||
void (*ai_post_process_mission) ();
|
||||
int (*ai_query_goal_valid) (int ship, int ai_goal);
|
||||
void (*ai_remove_ship_goal) (ai_info *aip, int index);
|
||||
void (*ai_clear_ship_goals) (ai_info *aip);
|
||||
void (*ai_clear_wing_goals) (int wingnum);
|
||||
void (*ai_mission_wing_goal_complete) (int wingnum, ai_goal *remove_goalp);
|
||||
void (*ai_mission_goal_complete) (ai_info *aip);
|
||||
int (*ai_get_subsystem_type) (char *subsystem);
|
||||
void (*ai_goal_purge_invalid_goals) (ai_goal *aigp, ai_goal *goal_list);
|
||||
void (*ai_goal_purge_all_invalid_goals) (ai_goal *aigp);
|
||||
int (*ai_goal_find_dockpoint) (int shipnum, int dock_type);
|
||||
void (*ai_goal_fixup_dockpoints) (ai_info *aip, ai_goal *aigp);
|
||||
void (*ai_add_goal_sub_player) (int type, int mode, int submode, char *shipname, ai_goal *aigp);
|
||||
int (*ai_goal_find_empty_slot) (ai_goal *goals, int active_goal);
|
||||
void (*ai_add_ship_goal_player) (int type, int mode, int submode, char *shipname, ai_info *aip);
|
||||
void (*ai_add_wing_goal_player) (int type, int mode, int submode, char *shipname, int wingnum);
|
||||
void (*ai_add_goal_sub_sexp) (int sexp, int type, ai_goal *aigp, char *actor_name);
|
||||
void (*ai_add_ship_goal_sexp) (int sexp, int type, ai_info *aip);
|
||||
void (*ai_add_wing_goal_sexp) (int sexp, int type, int wingnum);
|
||||
void (*ai_add_goal_ship_internal) (ai_info *aip, int goal_type, char *name, int docker_point, int dockee_point, int immediate);
|
||||
void (*ai_add_goal_wing_internal) (wing *wingp, int goal_type, char *name, int immediate);
|
||||
void (*ai_copy_mission_wing_goal) (ai_goal *aigp, ai_info *aip);
|
||||
int (*ai_mission_goal_achievable) (int objnum, ai_goal *aigp);
|
||||
int (*ai_goal_priority_compare) (const void *a, const void *b);
|
||||
void (*prioritize_goals) (int objnum, ai_info *aip);
|
||||
void (*validate_mission_goals) (int objnum, ai_info *aip);
|
||||
void (*ai_process_mission_orders) (int objnum, ai_info *aip);
|
||||
void (*ai_update_goal_references) (ai_goal *goals, int type, char *old_name, char *new_name);
|
||||
int (*query_referenced_in_ai_goals) (ai_goal *goals, int type, char *name);
|
||||
char* (*ai_add_dock_name) (char *str);
|
||||
};
|
||||
|
||||
// Set new pointer to override ai_goal* function calls
|
||||
// possibly copying the old function calls first
|
||||
|
||||
extern struct aigoal_call_table *aigoal_table;
|
||||
|
||||
extern struct aigoal_call_table AIGoalDefaultTable;
|
||||
|
||||
#endif
|
||||
@@ -10,6 +10,22 @@
|
||||
#ifndef _AIINTERNAL_H
|
||||
#define _AIINTERNAL_H
|
||||
|
||||
#include "weapon/weapon.h"
|
||||
#include "weapon/swarm.h"
|
||||
#include "object/objectdock.h"
|
||||
|
||||
typedef struct eval_nearest_objnum {
|
||||
int objnum;
|
||||
object *trial_objp;
|
||||
int enemy_team_mask;
|
||||
int enemy_wing;
|
||||
float range;
|
||||
int max_attackers;
|
||||
int nearest_objnum;
|
||||
float nearest_dist;
|
||||
int check_danger_weapon_objnum;
|
||||
} eval_nearest_objnum;
|
||||
|
||||
//Returns true if the specified object is a stealth ship, false if not
|
||||
bool is_object_stealth_ship(object* objp);
|
||||
|
||||
@@ -28,4 +44,243 @@ int check_ok_to_fire(int objnum, int target_objnum, weapon_info *wip);
|
||||
//Does all the stuff needed to aim and fire a turret.
|
||||
void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum);
|
||||
|
||||
// AI Turret Table Wrapper
|
||||
|
||||
struct eval_enemy_obj_struct;
|
||||
|
||||
struct aiturret_call_table
|
||||
{
|
||||
int (*turret_select_best_weapon) (ship_subsys *turret, object *target);
|
||||
int (*valid_turret_enemy) (object *objp, object *turret_parent);
|
||||
void (*evaluate_obj_as_target) (object *objp, eval_enemy_obj_struct *eeo);
|
||||
int (*get_nearest_turret_objnum) (int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag);
|
||||
int (*find_turret_enemy) (ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov);
|
||||
int (*turret_should_pick_new_target) (ship_subsys *turret);
|
||||
void (*turret_set_next_fire_timestamp) (int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip);
|
||||
int (*turret_should_fire_aspect) (ship_subsys *turret, float dot, weapon_info *wip);
|
||||
bool (*turret_fire_weapon) (int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos, float flak_range_override);
|
||||
void (*turret_swarm_fire_from_turret) (turret_swarm_info *tsi);
|
||||
void (*ai_fire_from_turret) (ship *shipp, ship_subsys *ss, int parent_objnum);
|
||||
};
|
||||
|
||||
// Set new pointer to override ai_goal* function calls
|
||||
// possibly copying the old function calls first
|
||||
|
||||
extern struct aiturret_call_table *aiturret_table;
|
||||
|
||||
extern struct aiturret_call_table AITurretDefaultTable;
|
||||
|
||||
// AI Code Table Wrapper
|
||||
struct aicode_call_table
|
||||
{
|
||||
void (*ai_set_rearm_status) (int team, int time);
|
||||
int (*ai_good_time_to_rearm) (object *objp);
|
||||
void (*ai_good_secondary_time) (int team, int weapon_index, int max_fire_count, char *shipname);
|
||||
int (*is_preferred_weapon) (int weapon_num, object *firer_objp, object *target_objp);
|
||||
void (*ai_init_secondary_info) ();
|
||||
void (*free_ai_stuff) ();
|
||||
void (*parse_ai_class) ();
|
||||
void (*reset_ai_class_names) ();
|
||||
void (*parse_aitbl) ();
|
||||
void (*ai_init) ();
|
||||
void (*ai_level_init) ();
|
||||
int (*ai_is_stealth_visible) (object *viewer_objp, object *stealth_objp);
|
||||
void (*update_ai_stealth_info_with_error) (ai_info *aip);
|
||||
void (*ai_update_danger_weapon) (int attacked_objnum, int weapon_objnum);
|
||||
void (*ai_turn_towards_vector) (vec3d *dest, object *objp, float frametime, float turn_time, vec3d *slide_vec, vec3d *rel_pos, float bank_override, int flags, vec3d *rvec, int sexp_flags);
|
||||
void (*init_ship_info) ();
|
||||
int (*set_target_objnum) (ai_info *aip, int objnum);
|
||||
ship_subsys* (*set_targeted_subsys) (ai_info *aip, ship_subsys *new_subsys, int parent_objnum);
|
||||
void (*ai_object_init) (object *obj, int ai_index);
|
||||
void (*adjust_accel_for_docking) (ai_info *aip);
|
||||
void (*accelerate_ship) (ai_info *aip, float accel);
|
||||
void (*change_acceleration) (ai_info *aip, float delta_accel);
|
||||
void (*set_accel_for_target_speed) (object *objp, float tspeed);
|
||||
void (*turn_towards_point) (object *objp, vec3d *point, vec3d *slide_vec, float bank_override);
|
||||
void (*turn_away_from_point) (object *objp, vec3d *point, float bank_override);
|
||||
float (*turn_towards_tangent) (object *objp, vec3d *point, float radius);
|
||||
float (*turn_toward_tangent_with_axis) (object *objp, object *center_objp, float radius);
|
||||
int (*object_is_targetable) (object *target, ship *viewer);
|
||||
int (*num_enemies_attacking) (int objnum);
|
||||
float (*get_wing_lowest_max_speed) (object *objp);
|
||||
int (*is_ignore_object_sub) (int *ignore_objnum, int *ignore_signature, int objnum);
|
||||
int (*find_ignore_new_object_index) (ai_info *aip, int objnum);
|
||||
int (*is_ignore_object) (ai_info *aip, int objnum, int just_the_original=0);
|
||||
int (*get_nearest_bbox_point) (object *ship_obj, vec3d *start, vec3d *box_pt);
|
||||
void (*evaluate_object_as_nearest_objnum) (eval_nearest_objnum *eno);
|
||||
int (*get_nearest_objnum) (int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers);
|
||||
int (*find_nearby_threat) (int objnum, int enemy_team_mask, float range, int *count);
|
||||
int (*num_turrets_attacking) (object *turret_parent, int target_objnum);
|
||||
int (*get_enemy_timestamp) ();
|
||||
int (*find_enemy) (int objnum, float range, int max_attackers);
|
||||
void (*ai_set_goal_maybe_abort_dock) (object *objp, ai_info *aip);
|
||||
void (*force_avoid_player_check) (object *objp, ai_info *aip);
|
||||
void (*ai_attack_object) (object *attacker, object *attacked, int priority, ship_subsys *ssp);
|
||||
void (*ai_attack_wing) (object *attacker, int wingnum, int priority);
|
||||
void (*ai_evade_object) (object *evader, object *evaded, int priority);
|
||||
int (*compact_ignore_new_objects) (ai_info *aip, int force=0);
|
||||
void (*ai_ignore_object) (object *ignorer, object *ignored, int priority, int ignore_new);
|
||||
void (*ai_ignore_wing) (object *ignorer, int wingnum, int priority);
|
||||
void (*create_model_path) (object *pl_objp, object *mobjp, int path_num, int subsys_path);
|
||||
void (*create_model_exit_path) (object *pl_objp, object *mobjp, int path_num, int count);
|
||||
void (*ai_find_path) (object *pl_objp, int objnum, int path_num, int exit_flag, int subsys_path);
|
||||
int (*maybe_avoid_player) (object *objp, vec3d *goal_pos);
|
||||
void (*ai_stay_still) (object *still_objp, vec3d *view_pos);
|
||||
void (*ai_do_objects_docked_stuff) (object *docker, int docker_point, object *dockee, int dockee_point);
|
||||
void (*ai_do_objects_undocked_stuff) (object *docker, object *dockee);
|
||||
void (*ai_dock_with_object) (object *docker, int docker_index, object *dockee, int dockee_index, int priority, int dock_type);
|
||||
void (*ai_start_fly_to_ship) (object *objp, int shipnum);
|
||||
void (*ai_start_waypoints) (object *objp, int waypoint_list_index, int wp_flags);
|
||||
void (*ai_do_stay_near) (object *objp, object *other_objp, float dist);
|
||||
void (*ai_do_safety) (object *objp);
|
||||
void (*ai_form_on_wing) (object *objp, object *goal_objp);
|
||||
int (*ai_formation_object_get_slotnum) (int objnum, object *objp);
|
||||
float (*compute_time_to_enemy) (float dist_to_enemy, object *pobjp, object *eobjp);
|
||||
void (*ai_set_positions) (object *pl_objp, object *en_objp, ai_info *aip, vec3d *player_pos, vec3d *enemy_pos);
|
||||
float (*maybe_recreate_path) (object *objp, ai_info *aip, int force_recreate_flag, int override_hash=0);
|
||||
void (*set_accel_for_docking) (object *objp, ai_info *aip, float dot, float dot_to_next, float dist_to_next, float dist_to_goal, ship_info *sip);
|
||||
float (*ai_path) ();
|
||||
void (*ai_safety_pick_spot) (object *objp);
|
||||
float (*ai_safety_goto_spot) (object *objp);
|
||||
void (*ai_safety_circle_spot) (object *objp);
|
||||
void (*ai_safety) ();
|
||||
void (*ai_fly_to_ship) ();
|
||||
void (*ai_waypoints) ();
|
||||
void (*avoid_ship) ();
|
||||
int (*maybe_resume_previous_mode) (object *objp, ai_info *aip);
|
||||
int (*ai_maybe_fire_afterburner) (object *objp, ai_info *aip);
|
||||
void (*maybe_afterburner_after_ship_hit) (object *objp, ai_info *aip, object *en_objp);
|
||||
int (*is_instructor) (object *objp);
|
||||
void (*evade_weapon) ();
|
||||
void (*slide_face_ship) ();
|
||||
void (*evade_ship) ();
|
||||
void (*ai_evade) ();
|
||||
int (*ai_select_primary_weapon_OLD) (object *objp, object *other_objp, int flags);
|
||||
int (*ai_select_primary_weapon) (object *objp, object *other_objp, int flags);
|
||||
void (*set_primary_weapon_linkage) (object *objp);
|
||||
int (*ai_fire_primary_weapon) (object *objp);
|
||||
void (*ai_select_secondary_weapon) (object *objp, ship_weapon *swp, int priority1=-1, int priority2=-1);
|
||||
void (*ai_maybe_announce_shockwave_weapon) (object *firing_objp, int weapon_index);
|
||||
int (*check_ok_to_fire) (int objnum, int target_objnum, weapon_info *wip);
|
||||
int (*ai_fire_secondary_weapon) (object *objp, int priority1, int priority2);
|
||||
void (*set_predicted_enemy_pos_turret) (vec3d *predicted_enemy_pos, vec3d *gun_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, float weapon_speed, float time_enemy_in_range);
|
||||
void (*set_predicted_enemy_pos) (vec3d *predicted_enemy_pos, object *pobjp, object *eobjp, ai_info *aip);
|
||||
void (*ai_chase_ct) ();
|
||||
void (*ai_chase_eb) (ai_info *aip, ship_info *sip, vec3d *predicted_enemy_pos, float dist_to_enemy);
|
||||
float (*ai_endangered_time) (object *ship_objp, object *weapon_objp);
|
||||
float (*ai_endangered_by_weapon) (ai_info *aip);
|
||||
int (*ai_near_full_strength) (object *objp);
|
||||
void (*attack_set_accel) (ai_info *aip, float dist_to_enemy, float dot_to_enemy, float dot_from_enemy);
|
||||
void (*get_behind_ship) (ai_info *aip, ship_info *sip, float dist_to_enemy);
|
||||
int (*avoid_player) (object *objp, vec3d *goal_pos);
|
||||
int (*maybe_avoid_big_ship) (object *objp, object *ignore_objp, ai_info *aip, vec3d *goal_point, float delta_time);
|
||||
void (*ai_stealth_find) ();
|
||||
void (*ai_stealth_sweep) ();
|
||||
void (*ai_chase_attack) (ai_info *aip, ship_info *sip, vec3d *predicted_enemy_pos, float dist_to_enemy, int modelnum);
|
||||
void (*ai_chase_es) (ai_info *aip, ship_info *sip);
|
||||
void (*ai_chase_ga) (ai_info *aip, ship_info *sip);
|
||||
int (*ai_set_attack_subsystem) (object *objp, int subnum);
|
||||
void (*ai_set_guard_vec) (object *objp, object *guard_objp);
|
||||
void (*ai_set_guard_wing) (object *objp, int wingnum);
|
||||
void (*ai_set_evade_object) (object *objp, object *other_objp);
|
||||
void (*ai_set_guard_object) (object *objp, object *other_objp);
|
||||
void (*update_aspect_lock_information) (ai_info *aip, vec3d *vec_to_enemy, float dist_to_enemy, float enemy_radius);
|
||||
void (*ai_chase_fly_away) (object *objp, ai_info *aip);
|
||||
int (*has_preferred_secondary) (object *objp, object *en_objp, ship_weapon *swp);
|
||||
void (*ai_choose_secondary_weapon) (object *objp, ai_info *aip, object *en_objp);
|
||||
float (*set_secondary_fire_delay) (ai_info *aip, ship *shipp, weapon_info *swip);
|
||||
void (*ai_chase_big_approach_set_goal) (vec3d *goal_pos, object *attack_objp, object *target_objp, float *accel);
|
||||
void (*ai_chase_big_circle_set_goal) (vec3d *goal_pos, object *attack_objp, object *target_objp, float *accel);
|
||||
void (*ai_chase_big_get_separations) (object *attack_objp, object *target_objp, vec3d *horz_vec_to_target, float *desired_separation, float *cur_separation);
|
||||
void (*ai_chase_big_parallel_set_goal) (vec3d *goal_pos, object *attack_objp, object *target_objp, float *accel);
|
||||
void (*ai_cruiser_chase_set_goal_pos) (vec3d *goal_pos, object *pl_objp, object *en_objp);
|
||||
int (*maybe_hack_cruiser_chase_abort) ();
|
||||
void (*ai_cruiser_chase) ();
|
||||
void (*ai_chase) ();
|
||||
int (*num_ships_attacking) (int target_objnum);
|
||||
void (*remove_farthest_attacker) (int objnum);
|
||||
int (*ai_maybe_limit_attackers) (int attacked_objnum);
|
||||
void (*guard_object_was_hit) (object *guard_objp, object *hitter_objp);
|
||||
void (*maybe_update_guard_object) (object *hit_objp, object *hitter_objp);
|
||||
int (*ai_guard_find_nearby_bomb) (object *guarding_objp, object *guarded_objp);
|
||||
void (*ai_guard_find_nearby_ship) (object *guarding_objp, object *guarded_objp);
|
||||
void (*ai_guard_find_nearby_asteroid) (object *guarding_objp, object *guarded_objp);
|
||||
void (*ai_guard_find_nearby_object) ();
|
||||
void (*ai_big_guard) ();
|
||||
void (*ai_guard) ();
|
||||
void (*ai_do_objects_repairing_stuff) (object *repaired_objp, object *repair_objp, int how);
|
||||
void (*ai_cleanup_dock_mode_subjective) (object *objp);
|
||||
void (*ai_cleanup_dock_mode_objective) (object *objp);
|
||||
void (*ai_cleanup_rearm_mode) (object *objp);
|
||||
void (*ai_still) ();
|
||||
void (*ai_stay_near) ();
|
||||
int (*maybe_dock_obstructed) (object *cur_objp, object *goal_objp, int big_only_flag);
|
||||
void (*ai_dock) ();
|
||||
void (*process_subobjects) (int objnum);
|
||||
void (*ai_fly_in_formation) (int wingnum);
|
||||
void (*ai_disband_formation) (int wingnum);
|
||||
int (*formation_is_leader_chaotic) (object *objp);
|
||||
void (*ai_most_massive_object_of_its_wing_of_all_docked_objects_helper) (object *objp, dock_function_info *infop);
|
||||
int (*ai_formation) ();
|
||||
void (*ai_do_repair_frame) (object *objp, ai_info *aip, float frametime);
|
||||
void (*call_doa) (object *child, object *parent);
|
||||
void (*ai_maybe_launch_cmeasure) (object *objp, ai_info *aip);
|
||||
void (*ai_preprocess_ignore_objnum) (object *objp, ai_info *aip);
|
||||
void (*ai_chase_circle) (object *objp);
|
||||
void (*ai_transfer_shield) (object *objp, int quadrant_num);
|
||||
void (*ai_balance_shield) (object *objp);
|
||||
void (*ai_manage_shield) (object *objp, ai_info *aip);
|
||||
void (*ai_maybe_evade_locked_missile) (object *objp, ai_info *aip);
|
||||
void (*maybe_evade_dumbfire_weapon) (ai_info *aip);
|
||||
int (*ai_acquire_emerge_path) (object *pl_objp, int parent_objnum, int allowed_path_mask, vec3d *pos, vec3d *fvec);
|
||||
void (*ai_emerge_bay_path_cleanup) (ai_info *aip);
|
||||
void (*ai_bay_emerge) ();
|
||||
int (*ai_find_closest_depart_path) (ai_info *aip, polymodel *pm, int allowed_path_mask);
|
||||
int (*ai_acquire_depart_path) (object *pl_objp, int parent_objnum, int allowed_path_mask);
|
||||
void (*ai_bay_depart) ();
|
||||
void (*ai_sentrygun) ();
|
||||
void (*ai_execute_behavior) (ai_info *aip);
|
||||
int (*maybe_request_support) (object *objp);
|
||||
void (*ai_set_mode_warp_out) (object *objp, ai_info *aip);
|
||||
void (*ai_maybe_depart) (object *objp);
|
||||
void (*ai_warp_out) (object *objp);
|
||||
void (*ai_announce_ship_dying) (object *dying_objp);
|
||||
int (*aas_1) (object *objp, ai_info *aip, vec3d *safe_pos);
|
||||
int (*ai_avoid_shockwave) (object *objp, ai_info *aip);
|
||||
int (*ai_await_repair_frame) (object *objp, ai_info *aip);
|
||||
void (*ai_maybe_self_destruct) (object *objp, ai_info *aip);
|
||||
int (*ai_need_new_target) (object *pl_objp, int target_objnum);
|
||||
int (*maybe_big_ship_collide_recover_frame) (object *objp, ai_info *aip);
|
||||
void (*validate_mode_submode) (ai_info *aip);
|
||||
void (*ai_frame) (int objnum);
|
||||
void (*ai_process) (object *obj, int ai_index, float frametime);
|
||||
void (*init_ai_object) (int objnum);
|
||||
void (*init_ai_objects) ();
|
||||
void (*init_ai_system) ();
|
||||
void (*ai_set_default_behavior) (object *obj, int classnum);
|
||||
void (*ai_do_default_behavior) (object *obj);
|
||||
void (*process_friendly_hit_message) (int message, object *objp);
|
||||
void (*maybe_process_friendly_hit) (object *objp_hitter, object *objp_hit, object *objp_weapon);
|
||||
void (*maybe_set_dynamic_chase) (ai_info *aip, int hitter_objnum);
|
||||
void (*big_ship_collide_recover_start) (object *objp, object *big_objp, vec3d *collide_pos, vec3d *collision_normal);
|
||||
void (*ai_update_lethality) (object *ship_obj, object *other_obj, float damage);
|
||||
void (*ai_ship_hit) (object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_quadrant, vec3d *hit_normal);
|
||||
void (*ai_ship_destroy) (int shipnum, int method);
|
||||
void (*ai_deathroll_start) (object *dying_objp);
|
||||
int (*ai_abort_rearm_request) (object *requester_objp);
|
||||
void (*ai_add_rearm_goal) (object *requester_objp, object *support_objp);
|
||||
int (*ai_issue_rearm_request) (object *requester_objp);
|
||||
void (*ai_rearm_repair) (object *objp, int docker_index, object *goal_objp, int dockee_index, int priority);
|
||||
void (*cheat_fire_synaptic) (object *objp, ship *shipp, ai_info *aip);
|
||||
void (*maybe_cheat_fire_synaptic) (object *objp, ai_info *aip);
|
||||
};
|
||||
|
||||
|
||||
// Set new pointer to override ai_code* function calls
|
||||
// possibly copying the old function calls first
|
||||
|
||||
extern struct aicode_call_table *aicode_table;
|
||||
|
||||
extern struct aicode_call_table AICodeDefaultTable;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,185 @@
|
||||
/**
|
||||
* @file aimodular.cpp
|
||||
* @brief Modular loading of new AI code based on name in AI Profile.
|
||||
*
|
||||
* The ai_module_init function should be called by ai_init.
|
||||
*
|
||||
* @author Fabian Franz <[email protected]>
|
||||
*
|
||||
*/
|
||||
#include "ai/aibig.h"
|
||||
#include "ai/aigoals.h"
|
||||
#include "ai/aiinternal.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <Windows.h>
|
||||
/** @brief Wrapper for the dlopen functions for Windows */
|
||||
#define dlopen(x,y) ((x==NULL)?GetModuleHandle(x):LoadLibrary(x))
|
||||
#define dlsym GetProcAddress
|
||||
#define dlclose FreeLibrary
|
||||
static HINSTANCE handle = NULL; /**< @brief Handle for the loaded library */
|
||||
|
||||
#else
|
||||
|
||||
#include <dlfcn.h>
|
||||
static void* handle = NULL; /**< @brief Handle for the loaded library */
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/** @brief ai_module_init_function prototype */
|
||||
typedef void (*ai_module_init_function)(void);
|
||||
|
||||
void ai_module_dlclose(void);
|
||||
|
||||
/**
|
||||
* @brief Fallback function to load new AI from same process image.
|
||||
*
|
||||
* This function is used if no dynamic library with the name can be found
|
||||
* or it does not contain the correct symbol.
|
||||
*
|
||||
* @param func_name The symbol to look for in handle
|
||||
* @return Returns 0 on success and -1,-2 on errors
|
||||
*
|
||||
*/
|
||||
int ai_module_dlopen_process(char* func_name)
|
||||
{
|
||||
ai_module_init_function ai_module_init_func;
|
||||
|
||||
// Maybe close handle first
|
||||
ai_module_dlclose();
|
||||
|
||||
handle = dlopen(NULL, RTLD_NOW);
|
||||
|
||||
if (handle == NULL)
|
||||
return -1;
|
||||
|
||||
ai_module_init_func=(ai_module_init_function)dlsym(handle, func_name);
|
||||
|
||||
#ifdef _WIN32
|
||||
// Under WIN32 GetModuleHandle is not
|
||||
// incrementing the reference counter
|
||||
// so we need to "free" the handle directly
|
||||
|
||||
handle=NULL;
|
||||
#endif
|
||||
|
||||
if (ai_module_init_func == NULL)
|
||||
return -2;
|
||||
|
||||
ai_module_init_func();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Loads new AI from dynamic library
|
||||
*
|
||||
* This function looks for dllname.dll or dllname.so
|
||||
* tries to load it into memory and if it finds the
|
||||
* dllname_ai_module_init function it starts it.
|
||||
*
|
||||
* If it does not find the library or symbol it falls
|
||||
* back to ai_module_dlopen_process.
|
||||
*
|
||||
* @param dllname The name of the library to load
|
||||
* @return Returns 0 on success and -1,-2 on errors
|
||||
*
|
||||
*/
|
||||
|
||||
int ai_module_dlopen(char* dllname)
|
||||
{
|
||||
char buf[PATH_MAX+1];
|
||||
char init_func_name[PATH_MAX+1];
|
||||
ai_module_init_function ai_module_init_func;
|
||||
|
||||
#ifdef _WIN32
|
||||
snprintf(buf, PATH_MAX, "%s.dll", dllname);
|
||||
#else
|
||||
snprintf(buf, PATH_MAX, "%s.so", dllname);
|
||||
#endif
|
||||
snprintf(init_func_name, PATH_MAX, "%s_ai_module_init", dllname);
|
||||
|
||||
handle = dlopen(buf, RTLD_NOW);
|
||||
|
||||
if (handle == NULL)
|
||||
return ai_module_dlopen_process(init_func_name);
|
||||
|
||||
ai_module_init_func=(ai_module_init_function)dlsym(handle, init_func_name);
|
||||
|
||||
if (ai_module_init_func == NULL)
|
||||
return ai_module_dlopen_process(init_func_name);
|
||||
|
||||
ai_module_init_func();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Closes the library handle
|
||||
*
|
||||
* This function closes the library handle.
|
||||
*
|
||||
*/
|
||||
void ai_module_dlclose(void)
|
||||
{
|
||||
if (handle != NULL)
|
||||
{
|
||||
dlclose(handle);
|
||||
handle=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inits or resets the AI code tables
|
||||
*
|
||||
* This function first resets the AI code tables,
|
||||
* then closes any open libraries from before.
|
||||
*
|
||||
* Then it ooks if the ai_module is not "retail"
|
||||
* and if that is the case it loads a library with this name.
|
||||
*
|
||||
*/
|
||||
void ai_module_init(void)
|
||||
{
|
||||
// First Reset values
|
||||
aibig_table = &AIBigDefaultTable;
|
||||
aicode_table = &AICodeDefaultTable;
|
||||
aigoal_table = &AIGoalDefaultTable;
|
||||
aiturret_table = &AITurretDefaultTable;
|
||||
|
||||
ai_module_dlclose();
|
||||
|
||||
if (The_mission.ai_profile == NULL)
|
||||
return;
|
||||
|
||||
if (strncmp(The_mission.ai_profile->ai_module, "retail", 6) != 0)
|
||||
{
|
||||
if (ai_module_dlopen(The_mission.ai_profile->ai_module) != 0)
|
||||
{
|
||||
char err[1024];
|
||||
|
||||
snprintf(err, sizeof(err), "AI_module_init(%s) failed: %s\n", The_mission.ai_profile->ai_module, dlerror());
|
||||
|
||||
mprintf(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void newai_ai_module_init(void);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Dummy function
|
||||
*
|
||||
* This dummy functions calls all AI implementations
|
||||
* that should be statically included.
|
||||
*
|
||||
*/
|
||||
void ai_module_dummy()
|
||||
{
|
||||
newai_ai_module_init();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef _AIMODULAR_H
|
||||
#define _AIMODULAR_H
|
||||
|
||||
void ai_module_init(void);
|
||||
|
||||
#endif
|
||||
@@ -233,6 +233,69 @@ typedef struct eval_enemy_obj_struct {
|
||||
int nearest_objnum;
|
||||
} eval_enemy_obj_struct;
|
||||
|
||||
// FF 17-06-07
|
||||
// AI Turret Table Wrapper
|
||||
|
||||
struct aiturret_call_table *aiturret_table = &AITurretDefaultTable;
|
||||
|
||||
int turret_select_best_weapon (ship_subsys *turret, object *target)
|
||||
{
|
||||
return aiturret_table->turret_select_best_weapon(turret, target);
|
||||
}
|
||||
|
||||
int valid_turret_enemy (object *objp, object *turret_parent)
|
||||
{
|
||||
return aiturret_table->valid_turret_enemy(objp, turret_parent);
|
||||
}
|
||||
|
||||
void evaluate_obj_as_target (object *objp, eval_enemy_obj_struct *eeo)
|
||||
{
|
||||
aiturret_table->evaluate_obj_as_target(objp, eeo);
|
||||
}
|
||||
|
||||
int get_nearest_turret_objnum (int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag)
|
||||
{
|
||||
return aiturret_table->get_nearest_turret_objnum(turret_parent_objnum, turret_subsys, enemy_team_mask, tpos, tvec, current_enemy, big_only_flag, small_only_flag, tagged_only_flag, beam_flag);
|
||||
}
|
||||
|
||||
int find_turret_enemy (ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov)
|
||||
{
|
||||
return aiturret_table->find_turret_enemy(turret_subsys, objnum, tpos, tvec, current_enemy, fov);
|
||||
}
|
||||
|
||||
int turret_should_pick_new_target (ship_subsys *turret)
|
||||
{
|
||||
return aiturret_table->turret_should_pick_new_target(turret);
|
||||
}
|
||||
|
||||
void turret_set_next_fire_timestamp (int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip)
|
||||
{
|
||||
aiturret_table->turret_set_next_fire_timestamp(weapon_num, wip, turret, aip);
|
||||
}
|
||||
|
||||
int turret_should_fire_aspect (ship_subsys *turret, float dot, weapon_info *wip)
|
||||
{
|
||||
return aiturret_table->turret_should_fire_aspect(turret, dot, wip);
|
||||
}
|
||||
|
||||
bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos = NULL, float flak_range_override = 100.0f)
|
||||
{
|
||||
return aiturret_table->turret_fire_weapon(weapon_num, turret, parent_objnum, turret_pos, turret_fvec, predicted_pos, flak_range_override);
|
||||
}
|
||||
|
||||
void turret_swarm_fire_from_turret (turret_swarm_info *tsi)
|
||||
{
|
||||
aiturret_table->turret_swarm_fire_from_turret(tsi);
|
||||
}
|
||||
|
||||
void ai_fire_from_turret (ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
{
|
||||
aiturret_table->ai_fire_from_turret(shipp, ss, parent_objnum);
|
||||
}
|
||||
|
||||
|
||||
// AI Turret default implementation
|
||||
|
||||
// return 1 if objp is in fov of the specified turret, tp. Otherwise return 0.
|
||||
// dist = distance from turret to center point of object
|
||||
int object_in_turret_fov(object *objp, model_subsystem *tp, vec3d *tvec, vec3d *tpos, float dist)
|
||||
@@ -274,7 +337,7 @@ int bomb_headed_towards_ship(object *bomb_objp, object *ship_objp)
|
||||
//Note that all non-negative return values are expressed in
|
||||
//what I like to call "widx"s.
|
||||
//Returns -1 if unable to find a weapon for the target at all.
|
||||
int turret_select_best_weapon(ship_subsys *turret, object *target)
|
||||
int aiturret_turret_select_best_weapon(ship_subsys *turret, object *target)
|
||||
{
|
||||
//TODO: Fill this out with extraodinary gun-picking algorithms
|
||||
if(turret->weapons.num_primary_banks > 0)
|
||||
@@ -441,7 +504,7 @@ float longest_turret_weapon_range(ship_weapon *swp)
|
||||
// input: objp => object that turret is considering as an enemy
|
||||
// turret_parent => object index for ship that turret sits on
|
||||
// turret => turret pointer
|
||||
int valid_turret_enemy(object *objp, object *turret_parent)
|
||||
int aiturret_valid_turret_enemy(object *objp, object *turret_parent)
|
||||
{
|
||||
if ( objp == turret_parent ) {
|
||||
return 0;
|
||||
@@ -505,7 +568,7 @@ int valid_turret_enemy(object *objp, object *turret_parent)
|
||||
}
|
||||
|
||||
extern int Player_attacking_enabled;
|
||||
void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
|
||||
void aiturret_evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
|
||||
{
|
||||
object *turret_parent_obj = &Objects[eeo->turret_parent_objnum];
|
||||
ship *shipp;
|
||||
@@ -632,7 +695,11 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
|
||||
dist *= (1.0f + 0.1f*num_att_turrets);
|
||||
|
||||
// return if we're over the cap
|
||||
int max_turrets = 3 + Game_skill_level * Game_skill_level;
|
||||
// int max_turrets = 3 + Game_skill_level * Game_skill_level;
|
||||
int max_turrets = The_mission.ai_profile->max_turret_ownage_target[Game_skill_level];
|
||||
if (objp->flags & OF_PLAYER_SHIP) {
|
||||
max_turrets = The_mission.ai_profile->max_turret_ownage_player[Game_skill_level];
|
||||
}
|
||||
if (num_att_turrets > max_turrets) {
|
||||
return;
|
||||
}
|
||||
@@ -712,7 +779,7 @@ int is_target_beam_valid(ship_weapon *swp, object *objp)
|
||||
// tpos => position of turret (world coords)
|
||||
// tvec => forward vector of turret (world coords)
|
||||
// current_enemy => objnum of current turret target
|
||||
int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag)
|
||||
int aiturret_get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag)
|
||||
{
|
||||
//float weapon_travel_dist;
|
||||
int weapon_system_ok;
|
||||
@@ -853,7 +920,7 @@ DCF_BOOL(use_parent_target, Use_parent_target)
|
||||
// tpos => position of turret (world coords)
|
||||
// tvec => forward vector of turret (world coords)
|
||||
// current_enemy => objnum of current turret target
|
||||
int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov)
|
||||
int aiturret_find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov)
|
||||
{
|
||||
int enemy_team_mask, enemy_objnum;
|
||||
model_subsystem *tp;
|
||||
@@ -1197,7 +1264,7 @@ ship_subsys *aifft_find_turret_subsys(object *objp, ship_subsys *ssp, object *en
|
||||
}
|
||||
|
||||
// return !0 if the specified target should scan for a new target, otherwise return 0
|
||||
int turret_should_pick_new_target(ship_subsys *turret)
|
||||
int aiturret_turret_should_pick_new_target(ship_subsys *turret)
|
||||
{
|
||||
// int target_type;
|
||||
|
||||
@@ -1220,7 +1287,7 @@ int turret_should_pick_new_target(ship_subsys *turret)
|
||||
}
|
||||
|
||||
// Set the next fire timestamp for a turret, based on weapon type and ai class
|
||||
void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip)
|
||||
void aiturret_turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsys *turret, ai_info *aip)
|
||||
{
|
||||
Assert(weapon_num < MAX_SHIP_WEAPONS);
|
||||
float wait = wip->fire_wait * 1000.0f;
|
||||
@@ -1276,7 +1343,7 @@ void turret_set_next_fire_timestamp(int weapon_num, weapon_info *wip, ship_subsy
|
||||
}
|
||||
|
||||
// Decide if a turret should launch an aspect seeking missile
|
||||
int turret_should_fire_aspect(ship_subsys *turret, float dot, weapon_info *wip)
|
||||
int aiturret_turret_should_fire_aspect(ship_subsys *turret, float dot, weapon_info *wip)
|
||||
{
|
||||
if ( (dot > AICODE_TURRET_DUMBFIRE_ANGLE) && (turret->turret_time_enemy_in_range >= MIN(wip->min_lock_time,AICODE_TURRET_MAX_TIME_IN_RANGE)) ) {
|
||||
return 1;
|
||||
@@ -1300,7 +1367,7 @@ void turret_update_enemy_in_range(ship_subsys *turret, float seconds)
|
||||
}
|
||||
|
||||
// Fire a weapon from a turret
|
||||
bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos = NULL, float flak_range_override = 100.0f)
|
||||
bool aiturret_turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum, vec3d *turret_pos, vec3d *turret_fvec, vec3d *predicted_pos = NULL, float flak_range_override = 100.0f)
|
||||
{
|
||||
matrix turret_orient;
|
||||
int weapon_objnum;
|
||||
@@ -1351,11 +1418,6 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
// 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
|
||||
@@ -1422,11 +1484,6 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((parent_ship->cloak_stage > 0) && (parent_ship->cloak_stage < 3))
|
||||
{
|
||||
shipfx_start_cloak(parent_ship,500);
|
||||
}
|
||||
}
|
||||
|
||||
// reset any animations if we need to
|
||||
@@ -1445,8 +1502,8 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
return true;
|
||||
}
|
||||
|
||||
//void turret_swarm_fire_from_turret(ship_subsys *turret, int parent_objnum, int target_objnum, ship_subsys *target_subsys)
|
||||
void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
|
||||
//void aiturret_turret_swarm_fire_from_turret(ship_subsys *turret, int parent_objnum, int target_objnum, ship_subsys *target_subsys)
|
||||
void aiturret_turret_swarm_fire_from_turret(turret_swarm_info *tsi)
|
||||
{
|
||||
int weapon_objnum;
|
||||
matrix turret_orient;
|
||||
@@ -1510,7 +1567,7 @@ int Num_find_turret_enemy = 0;
|
||||
int Num_turrets_fired = 0;
|
||||
// Given a turret tp and its parent parent_objnum, fire from the turret at its enemy.
|
||||
extern int Nebula_sec_range;
|
||||
void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
void aiturret_ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
{
|
||||
float weapon_firing_range;
|
||||
|
||||
@@ -1636,6 +1693,10 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
int secnum = 0;
|
||||
for(i = 0; i < (MAX_SHIP_WEAPONS); i++)
|
||||
{
|
||||
//WMC - Only fire more than once if we have multiple guns flag set.
|
||||
if(num_valid > 0 && !(tp->flags & MSS_FLAG_USE_MULTIPLE_GUNS))
|
||||
break;
|
||||
|
||||
if(i < MAX_SHIP_PRIMARY_BANKS)
|
||||
{
|
||||
if(i >= swp->num_primary_banks)
|
||||
@@ -1903,6 +1964,25 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
}
|
||||
}
|
||||
|
||||
if ( ok_to_fire && (tp->flags & MSS_FLAG_TURRET_HULL_CHECK) ) {
|
||||
int model_num = Ship_info[shipp->ship_info_index].model_num;
|
||||
mc_info hull_check;
|
||||
vec3d end;
|
||||
|
||||
vm_vec_scale_add(&end, &gpos, &gvec, model_get_radius(model_num));
|
||||
|
||||
hull_check.model_num = model_num;
|
||||
hull_check.orient = &objp->orient;
|
||||
hull_check.pos = &objp->pos;
|
||||
hull_check.p0 = &gpos;
|
||||
hull_check.p1 = &end;
|
||||
hull_check.flags = MC_CHECK_MODEL | MC_CHECK_RAY;
|
||||
|
||||
if ( model_collide(&hull_check) ) {
|
||||
ok_to_fire = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ok_to_fire )
|
||||
{
|
||||
something_was_ok_to_fire = true;
|
||||
@@ -1958,3 +2038,17 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
ss->turret_time_enemy_in_range = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
struct aiturret_call_table AITurretDefaultTable = {
|
||||
aiturret_turret_select_best_weapon,
|
||||
aiturret_valid_turret_enemy,
|
||||
aiturret_evaluate_obj_as_target,
|
||||
aiturret_get_nearest_turret_objnum,
|
||||
aiturret_find_turret_enemy,
|
||||
aiturret_turret_should_pick_new_target,
|
||||
aiturret_turret_set_next_fire_timestamp,
|
||||
aiturret_turret_should_fire_aspect,
|
||||
aiturret_turret_fire_weapon,
|
||||
aiturret_turret_swarm_fire_from_turret,
|
||||
aiturret_ai_fire_from_turret
|
||||
};
|
||||
@@ -0,0 +1,122 @@
|
||||
#include "ai/aibig.h"
|
||||
#include "ai/aigoals.h"
|
||||
#include "ai/aiinternal.h"
|
||||
|
||||
struct aicode_call_table AICodeNewAITable;
|
||||
|
||||
#include "iff_defs/iff_defs.h"
|
||||
|
||||
#define DEPARTURE_HULL_PERCENT 0.3 // Departure if 15% to 30% hull strength left
|
||||
|
||||
void newai_ai_maybe_depart(object* objp_ship)
|
||||
{
|
||||
ship *shipp = &Ships[objp_ship->instance];
|
||||
|
||||
// Coward mode:
|
||||
//
|
||||
// Depart if:
|
||||
// * not player and
|
||||
// * same team as player and player not traitor and
|
||||
// * fighter or bomber
|
||||
// * hull multiplied with random value below critical
|
||||
|
||||
if (objp_ship->flags & OF_PLAYER_SHIP)
|
||||
return;
|
||||
|
||||
// make sure player is on their team and not a traitor
|
||||
if ((Player_ship->team != shipp->team) || (Player_ship->team == Iff_traitor))
|
||||
return;
|
||||
|
||||
if ((Ship_info[shipp->ship_info_index].flags & (SIF_FIGHTER|SIF_BOMBER)) == 0)
|
||||
return;
|
||||
|
||||
if (objp_ship->hull_strength*(frand()+1) < DEPARTURE_HULL_PERCENT * shipp->ship_max_hull_strength)
|
||||
mission_do_departure(objp_ship);
|
||||
}
|
||||
|
||||
// Object *objp_ship was hit by either weapon *objp_weapon or collided into by ship hit_objp at point *hitpos.
|
||||
void newai_aicode_ai_ship_hit (object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_quadrant, vec3d *hit_normal)
|
||||
{
|
||||
// Call the default implementation
|
||||
AICodeDefaultTable.ai_ship_hit(objp_ship, hit_objp, hitpos, shield_quadrant, hit_normal);
|
||||
|
||||
if (hit_objp->parent >= 0)
|
||||
{
|
||||
object *objp_hitter = &Objects[hit_objp->parent];
|
||||
|
||||
if ( objp_hitter->type == OBJ_SHIP )
|
||||
{
|
||||
ship *shipp_hitter = &Ships[objp_hitter->instance];
|
||||
ship *shipp_hit = &Ships[objp_ship->instance];
|
||||
|
||||
fprintf(stderr, "Ship %s hit %s\n", shipp_hitter->ship_name, shipp_hit->ship_name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
newai_ai_maybe_depart(objp_ship);
|
||||
}
|
||||
|
||||
|
||||
void newai_aicode_maybe_process_friendly_hit(object *objp_hitter, object *objp_hit, object *objp_weapon)
|
||||
{
|
||||
AICodeDefaultTable.maybe_process_friendly_hit(objp_hitter, objp_hit, objp_weapon);
|
||||
|
||||
if (obj_team(objp_hitter) == obj_team(objp_hit))
|
||||
{
|
||||
if ( objp_hitter->type != OBJ_SHIP )
|
||||
return;
|
||||
|
||||
ship *shipp_hitter = &Ships[objp_hitter->instance];
|
||||
ship *shipp_hit = &Ships[objp_hit->instance];
|
||||
|
||||
fprintf(stderr, "Ship %s friendly hit %s\n", shipp_hitter->ship_name, shipp_hit->ship_name);
|
||||
}
|
||||
}
|
||||
|
||||
int newai_aicode_ai_fire_primary_weapon(object *objp)
|
||||
{
|
||||
int fired = AICodeDefaultTable.ai_fire_primary_weapon(objp);
|
||||
|
||||
if (fired)
|
||||
{
|
||||
ship *shipp = &Ships[objp->instance];
|
||||
fprintf(stderr, "Ship %s fired primary weapon\n", shipp->ship_name);
|
||||
}
|
||||
}
|
||||
|
||||
void newai_aicode_init_ship_info()
|
||||
{
|
||||
static int called=0;
|
||||
if (called == 0)
|
||||
{
|
||||
fprintf(stderr, "Init ship info was called\n");
|
||||
called=1;
|
||||
}
|
||||
AICodeDefaultTable.init_ship_info();
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void newai_ai_module_init();
|
||||
}
|
||||
|
||||
void newai_ai_module_init()
|
||||
{
|
||||
|
||||
#ifdef PACKAGE_NAME
|
||||
fprintf(stderr, "ai_module_init() called\n");
|
||||
#else
|
||||
fprintf(stderr, "ai_module_init() modular called\n");
|
||||
#endif
|
||||
|
||||
// First make a copy
|
||||
memcpy(&AICodeNewAITable, &AICodeDefaultTable, sizeof(AICodeNewAITable));
|
||||
|
||||
// Now set up our overridden functions
|
||||
|
||||
aicode_table = &AICodeNewAITable;
|
||||
aicode_table->init_ship_info=newai_aicode_init_ship_info;
|
||||
aicode_table->ai_ship_hit=newai_aicode_ai_ship_hit;
|
||||
//aicode_table->ai_fire_primary_weapon=newai_aicode_ai_fire_primary_weapon;
|
||||
//aicode_table->maybe_process_friendly_hit=newai_aicode_maybe_process_friendly_hit;
|
||||
}
|
||||
@@ -421,18 +421,27 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_t
|
||||
if(image_id != -1)
|
||||
{
|
||||
text_pos[0] = image_pos[0] + w; //Still set from bm_get_info call
|
||||
deltax = text_pos[0] / 1024.0f; //MikeStar;
|
||||
text_pos[0] = gr_screen.max_w * deltax; //MikeStar;
|
||||
if (!center_x)
|
||||
{
|
||||
deltax = text_pos[0] / 1024.0f; //MikeStar;
|
||||
text_pos[0] = gr_screen.max_w * deltax; //MikeStar;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
text_pos[0] = image_pos[0];
|
||||
deltax = text_pos[0] / 1024.0f; //MikeStar;
|
||||
text_pos[0] = gr_screen.max_w * deltax; //MikeStar;
|
||||
if (!center_x)
|
||||
{
|
||||
deltax = text_pos[0] / 1024.0f; //MikeStar;
|
||||
text_pos[0] = gr_screen.max_w * deltax; //MikeStar;
|
||||
}
|
||||
}
|
||||
text_pos[1] = image_pos[1];
|
||||
deltay = text_pos[1] / 768.0f; //MikeStar;
|
||||
text_pos[1] = gr_screen.max_h * deltay; //MikeStar;
|
||||
if (!center_y)
|
||||
{
|
||||
deltay = text_pos[1] / 768.0f; //MikeStar;
|
||||
text_pos[1] = gr_screen.max_h * deltay; //MikeStar;
|
||||
}
|
||||
|
||||
time_displayed = 0.0f;
|
||||
time_displayed_end = 2.0f*fade_time + display_time;
|
||||
@@ -462,11 +471,12 @@ void subtitle::do_frame(float frametime)
|
||||
gr_set_color_fast(&text_color);
|
||||
|
||||
int font_height = gr_get_font_height();
|
||||
int y = text_pos[1];
|
||||
int x = fl2i(text_pos[0]);
|
||||
int y = fl2i(text_pos[1]);
|
||||
|
||||
for(unsigned int i = 0; i < text_lines.size(); i++)
|
||||
{
|
||||
gr_string(text_pos[0], y, (char*)text_lines[i].c_str(), false);
|
||||
gr_string(x, y, (char*)text_lines[i].c_str(), false);
|
||||
y += font_height;
|
||||
}
|
||||
|
||||
|
||||
@@ -1660,9 +1660,11 @@ int cf_get_file_list( int max, char **list, int pathtype, char *filter, int sort
|
||||
if (find_handle != -1) {
|
||||
do {
|
||||
if (num_files >= max)
|
||||
|
||||
break;
|
||||
|
||||
if ( strlen(find.name) >= MAX_FILENAME_LEN )
|
||||
continue;
|
||||
|
||||
if (!(find.attrib & _A_SUBDIR)) {
|
||||
if ( !Get_file_list_filter || (*Get_file_list_filter)(find.name) ) {
|
||||
ptr = strrchr(find.name, '.');
|
||||
@@ -1699,6 +1701,10 @@ int cf_get_file_list( int max, char **list, int pathtype, char *filter, int sort
|
||||
if (num_files >= max)
|
||||
break;
|
||||
|
||||
if ( strlen(dir->d_name) >= MAX_FILENAME_LEN ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fnmatch(filter, dir->d_name, 0) != 0)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -162,8 +162,8 @@ void pack_file( char *filespec, char *filename, int filesize, _fs_time_t time_wr
|
||||
}
|
||||
|
||||
if ( strlen(filename) > 31 ) {
|
||||
printf( "Filename '%s' too long\n", filename );
|
||||
exit(1);
|
||||
printf( "Filename '%s' too long! Skipping...\n", filename );
|
||||
return;
|
||||
}
|
||||
|
||||
memset( path, 0, sizeof(path) );
|
||||
@@ -255,7 +255,7 @@ void pack_directory( char * filespec)
|
||||
find_handle = _findfirst( tmp1, &find );
|
||||
if( find_handle != -1 ) {
|
||||
if ( find.attrib & _A_SUBDIR ) {
|
||||
if (strcmp( "..", find.name) && strcmp( ".", find.name)) {
|
||||
if (strcmp( "..", find.name) && strcmp( ".", find.name) && strcmp( ".svn", find.name)) {
|
||||
strcpy( tmp, filespec );
|
||||
strcat( tmp, "\\" );
|
||||
strcat( tmp, find.name );
|
||||
@@ -267,7 +267,7 @@ void pack_directory( char * filespec)
|
||||
|
||||
while( !_findnext( find_handle, &find ) ) {
|
||||
if ( find.attrib & _A_SUBDIR ) {
|
||||
if (strcmp( "..", find.name) && strcmp( ".", find.name)) {
|
||||
if (strcmp( "..", find.name) && strcmp( ".", find.name) && strcmp( ".svn", find.name)) {
|
||||
strcpy( tmp, filespec );
|
||||
strcat( tmp, "\\" );
|
||||
strcat( tmp, find.name );
|
||||
@@ -300,6 +300,10 @@ void pack_directory( char * filespec)
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (strcmp(dir->d_name, ".svn") == 0) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (S_ISDIR(buf.st_mode)) {
|
||||
strcpy( tmp, filespec );
|
||||
strcat( tmp, "/" );
|
||||
|
||||
@@ -560,6 +560,7 @@ void cutscenes_screen_play()
|
||||
// full_name = cf_add_ext(name, NOX(".mve"));
|
||||
|
||||
main_hall_stop_music();
|
||||
main_hall_stop_ambient();
|
||||
int rval = movie_play(name);
|
||||
main_hall_start_music();
|
||||
|
||||
|
||||
@@ -117,7 +117,6 @@
|
||||
#include "cutscene/cutscenes.h" // cutscene_mark_viewable()
|
||||
#include "cutscene/mvelib.h"
|
||||
#include "cutscene/oggplayer.h"
|
||||
#include "menuui/mainhallmenu.h"
|
||||
|
||||
extern int Game_mode;
|
||||
|
||||
@@ -196,9 +195,6 @@ bool movie_play(char *name)
|
||||
return false;
|
||||
}
|
||||
|
||||
// kill all background sounds
|
||||
main_hall_pause();
|
||||
|
||||
// clear the screen and hide the mouse cursor
|
||||
Mouse_hidden++;
|
||||
gr_reset_clip();
|
||||
@@ -251,9 +247,8 @@ bool movie_play(char *name)
|
||||
}
|
||||
}
|
||||
|
||||
// show the mouse cursor again, and unpause the mainhall music
|
||||
// show the mouse cursor again
|
||||
Mouse_hidden--;
|
||||
main_hall_unpause();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -374,7 +374,7 @@ void bg_bitmap_dlg::create()
|
||||
box->AddString(Nebula_colors[i]);
|
||||
}
|
||||
|
||||
m_slider.SetRange(100, MAX_STARS);
|
||||
m_slider.SetRange(0, MAX_STARS);
|
||||
m_slider.SetPos(Num_stars);
|
||||
sprintf(buf, "%d", Num_stars);
|
||||
GetDlgItem(IDC_TOTAL)->SetWindowText(buf);
|
||||
@@ -1384,15 +1384,18 @@ void bg_bitmap_dlg::OnImportBackground()
|
||||
Mp = saved_mp;
|
||||
|
||||
// pick one (if count is 0, it's retail with just one background)
|
||||
if (count > 1)
|
||||
if (count > 0)
|
||||
{
|
||||
int i, which;
|
||||
int i, which = 0;
|
||||
|
||||
BackgroundChooser dlg(count);
|
||||
if (dlg.DoModal() == IDCANCEL)
|
||||
return;
|
||||
if (count > 1)
|
||||
{
|
||||
BackgroundChooser dlg(count);
|
||||
if (dlg.DoModal() == IDCANCEL)
|
||||
return;
|
||||
|
||||
which = dlg.GetChosenBackground();
|
||||
which = dlg.GetChosenBackground();
|
||||
}
|
||||
|
||||
for (i = 0; i < which + 1; i++)
|
||||
skip_to_string("$Bitmap List:");
|
||||
|
||||
@@ -90,21 +90,26 @@ IDB_CHAINED_DIRECTIVE BITMAP MOVEABLE PURE "res\\chained_directive.bmp"
|
||||
IDB_GREEN_DOT BITMAP MOVEABLE PURE "res\\green_do.bmp"
|
||||
IDB_BLACK_DOT BITMAP MOVEABLE PURE "res\\black_do.bmp"
|
||||
IDB_VARIABLE BITMAP MOVEABLE PURE "res\\variable.bmp"
|
||||
IDB_DATA_12 BITMAP MOVEABLE PURE "res\\data12.bmp"
|
||||
IDB_DATA_02 BITMAP MOVEABLE PURE "res\\data02.bmp"
|
||||
IDB_DATA_03 BITMAP MOVEABLE PURE "res\\data03.bmp"
|
||||
IDB_DATA_04 BITMAP MOVEABLE PURE "res\\data04.bmp"
|
||||
IDB_DATA_05 BITMAP MOVEABLE PURE "res\\data05.bmp"
|
||||
IDB_DATA_06 BITMAP MOVEABLE PURE "res\\data06.bmp"
|
||||
IDB_DATA_07 BITMAP MOVEABLE PURE "res\\data07.bmp"
|
||||
IDB_DATA_08 BITMAP MOVEABLE PURE "res\\data08.bmp"
|
||||
IDB_DATA_09 BITMAP MOVEABLE PURE "res\\data09.bmp"
|
||||
IDB_DATA_00 BITMAP MOVEABLE PURE "res\\data00.bmp"
|
||||
IDB_DATA_10 BITMAP MOVEABLE PURE "res\\data10.bmp"
|
||||
IDB_DATA_11 BITMAP MOVEABLE PURE "res\\data11.bmp"
|
||||
IDB_DATA_01 BITMAP MOVEABLE PURE "res\\data01.bmp"
|
||||
IDB_DATA_15 BITMAP MOVEABLE PURE "res\\data15.bmp"
|
||||
IDB_DATA_14 BITMAP MOVEABLE PURE "res\\data14.bmp"
|
||||
IDB_DATA_13 BITMAP MOVEABLE PURE "res\\data13.bmp"
|
||||
IDB_DATA_20 BITMAP MOVEABLE PURE "res\\data20.bmp"
|
||||
IDB_DATA_25 BITMAP MOVEABLE PURE "res\\data25.bmp"
|
||||
IDB_DATA_30 BITMAP MOVEABLE PURE "res\\data30.bmp"
|
||||
IDB_DATA_35 BITMAP MOVEABLE PURE "res\\data35.bmp"
|
||||
IDB_DATA_40 BITMAP MOVEABLE PURE "res\\data40.bmp"
|
||||
IDB_DATA_45 BITMAP MOVEABLE PURE "res\\data45.bmp"
|
||||
IDB_DATA_50 BITMAP MOVEABLE PURE "res\\data50.bmp"
|
||||
IDB_DATA_55 BITMAP MOVEABLE PURE "res\\data55.bmp"
|
||||
IDB_DATA_60 BITMAP MOVEABLE PURE "res\\data60.bmp"
|
||||
IDB_DATA_65 BITMAP MOVEABLE PURE "res\\data65.bmp"
|
||||
IDB_DATA_70 BITMAP MOVEABLE PURE "res\\data70.bmp"
|
||||
IDB_DATA_75 BITMAP MOVEABLE PURE "res\\data75.bmp"
|
||||
IDB_DATA_80 BITMAP MOVEABLE PURE "res\\data80.bmp"
|
||||
IDB_DATA_85 BITMAP MOVEABLE PURE "res\\data85.bmp"
|
||||
IDB_DATA_90 BITMAP MOVEABLE PURE "res\\data90.bmp"
|
||||
IDB_DATA_95 BITMAP MOVEABLE PURE "res\\data95.bmp"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -873,13 +878,19 @@ BEGIN
|
||||
PUSHBUTTON "Cancel",IDCANCEL,355,184,50,14
|
||||
END
|
||||
|
||||
IDD_MISSION_NOTES DIALOGEX 0, 0, 464, 324
|
||||
IDD_MISSION_NOTES DIALOG DISCARDABLE 0, 0, 479, 327
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Mission Specs"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
RTEXT "Title",IDC_STATIC,7,10,29,8
|
||||
EDITTEXT IDC_MISSION_TITLE,41,7,109,14,ES_AUTOHSCROLL
|
||||
RTEXT "Designer",IDC_STATIC,7,25,29,8
|
||||
EDITTEXT IDC_DESIGNER_NAME,41,23,109,14,ES_AUTOHSCROLL
|
||||
RTEXT "Created:",IDC_STATIC,23,42,28,8
|
||||
LTEXT "xx/xx/xx",IDC_CREATED,57,42,91,8
|
||||
RTEXT "Last Modified:",IDC_STATIC,7,51,45,8
|
||||
LTEXT "xx/xx/xx",IDC_MODIFIED,57,51,92,8
|
||||
CONTROL "Single Player",IDC_SINGLE,"Button",BS_AUTORADIOBUTTON |
|
||||
WS_GROUP,7,63,57,10
|
||||
CONTROL "Multi Player",IDC_MULTI,"Button",BS_AUTORADIOBUTTON,7,
|
||||
@@ -892,100 +903,100 @@ BEGIN
|
||||
BS_AUTORADIOBUTTON,76,72,66,10
|
||||
CONTROL "Dogfight",IDC_DOGFIGHT,"Button",BS_AUTORADIOBUTTON,76,
|
||||
81,43,10
|
||||
EDITTEXT IDC_RESPAWNS,92,94,50,14,ES_AUTOHSCROLL | ES_NUMBER
|
||||
LTEXT "Max Respawns",IDC_STATIC,8,97,52,8
|
||||
EDITTEXT IDC_RESPAWNS,86,94,50,14,ES_AUTOHSCROLL | ES_NUMBER
|
||||
CONTROL "Spin1",IDC_RESPAWN_SPIN,"msctls_updown32",
|
||||
UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
|
||||
UDS_ARROWKEYS,142,94,11,14
|
||||
PUSHBUTTON "Custom Wing Names",IDC_CUSTOM_WING_NAMES,13,115,136,14
|
||||
EDITTEXT IDC_SQUAD_NAME,356,124,98,14,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "Logo",IDC_SQUAD_LOGO_BUTTON,316,139,31,14
|
||||
EDITTEXT IDC_SQUAD_LOGO,356,139,98,14,ES_AUTOHSCROLL |
|
||||
ES_READONLY
|
||||
PUSHBUTTON "640x480",IDC_LOADING_SCREEN_BUTTON640,317,284,40,14
|
||||
EDITTEXT IDC_LOADING_SCREEN640,357,284,97,14,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "1024x768",IDC_LOADING_SCREEN_BUTTON1024,317,300,40,16
|
||||
EDITTEXT IDC_LOADING_SCREEN1024,357,300,97,16,ES_AUTOHSCROLL
|
||||
CONTROL "All Teams at War",IDC_FULL_WAR,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,165,22,72,10
|
||||
CONTROL "Red Alert Mission",IDC_RED_ALERT,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,165,33,78,10
|
||||
CONTROL "Scramble Mission",IDC_SCRAMBLE,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,165,42,72,10
|
||||
CONTROL "No Briefing",IDC_NO_BRIEFING,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,165,52,72,10
|
||||
CONTROL "No Debriefing",IDC_NO_DEBRIEFING,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,165,62,72,10
|
||||
CONTROL "Disallow Promotions/Badges",IDC_NO_PROMOTION,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,165,73,106,10
|
||||
CONTROL "Disable Built-in Messages",IDC_DISABLE_BUILTIN_MSGS,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,165,82,123,10
|
||||
CONTROL "Disable Built-in Command Messages",
|
||||
IDC_DISABLE_BUILTIN_COMMAND_MSGS,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,165,92,129,10
|
||||
CONTROL "No Traitor",IDC_NO_TRAITOR,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,165,102,123,10
|
||||
CONTROL "All Ships Beam-Freed By Default",
|
||||
IDC_BEAM_FREE_ALL_BY_DEFAULT,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,304,38,123,10
|
||||
CONTROL "Allow Daisy-Chained Docking",IDC_ALLOW_DOCK_TREES,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,304,47,123,10
|
||||
UDS_ARROWKEYS,136,94,11,14
|
||||
PUSHBUTTON "Custom Wing Names",IDC_CUSTOM_WING_NAMES,10,115,128,14
|
||||
GROUPBOX "Squadron Reassign",IDC_STATIC,2,136,148,44
|
||||
LTEXT "Name",IDC_STATIC,14,147,28,8
|
||||
EDITTEXT IDC_SQUAD_NAME,48,147,98,14,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "Logo",IDC_SQUAD_LOGO_BUTTON,8,161,31,14
|
||||
EDITTEXT IDC_SQUAD_LOGO,48,161,98,14,ES_AUTOHSCROLL | ES_READONLY
|
||||
GROUPBOX "Loading Screen",IDC_STATIC,2,185,148,46
|
||||
PUSHBUTTON "640x480",IDC_LOADING_SCREEN_BUTTON640,7,197,40,14
|
||||
EDITTEXT IDC_LOADING_SCREEN640,47,197,97,14,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "1024x768",IDC_LOADING_SCREEN_BUTTON1024,7,213,40,16
|
||||
EDITTEXT IDC_LOADING_SCREEN1024,47,213,97,16,ES_AUTOHSCROLL
|
||||
GROUPBOX "Support Ships",IDC_STATIC,160,6,152,71
|
||||
CONTROL "Disallow Support Ships",IDC_SUPPORT_ALLOWED,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,309,168,95,10
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,164,16,95,10
|
||||
CONTROL "Support Ships Repair Hull",IDC_SUPPORT_REPAIRS_HULL,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,309,179,123,10
|
||||
EDITTEXT IDC_MAX_HULL_REPAIR_VAL,389,193,59,14,ES_AUTOHSCROLL
|
||||
EDITTEXT IDC_MAX_SUBSYS_REPAIR_VAL,389,211,59,14,ES_AUTOHSCROLL
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,164,27,123,10
|
||||
LTEXT "Hull Repair Ceiling",IDC_STATIC,164,43,60,8
|
||||
EDITTEXT IDC_MAX_HULL_REPAIR_VAL,244,41,49,14,ES_AUTOHSCROLL
|
||||
LTEXT "%",IDC_STATIC,298,46,8,8
|
||||
LTEXT "Subsytem Repair Ceiling",IDC_STATIC,164,64,75,8
|
||||
EDITTEXT IDC_MAX_SUBSYS_REPAIR_VAL,244,59,49,14,ES_AUTOHSCROLL
|
||||
LTEXT "%",IDC_STATIC,298,60,8,8
|
||||
GROUPBOX "Ship Trails",IDC_STATIC,160,81,154,41
|
||||
CONTROL "Toggle (off in nebula; on elsewhere)",
|
||||
IDC_SPECS_TOGGLE_TRAILS,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,309,242,141,10
|
||||
WS_TABSTOP,162,92,141,10
|
||||
CONTROL "Minimium speed to display",IDC_CONTRAIL_THRESHOLD_CHECK,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,309,253,93,10
|
||||
EDITTEXT IDC_CONTRAIL_THRESHOLD,411,252,48,14,ES_READONLY
|
||||
COMBOBOX IDC_AI_PROFILE,59,134,93,140,CBS_DROPDOWNLIST |
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,162,103,93,10
|
||||
EDITTEXT IDC_CONTRAIL_THRESHOLD,262,102,48,14,ES_READONLY
|
||||
GROUPBOX "Built-in Command Messages",IDC_STATIC,158,131,154,46
|
||||
LTEXT "Sender",IDC_STATIC,165,145,40,8
|
||||
COMBOBOX IDC_COMMAND_SENDER,209,143,99,140,CBS_DROPDOWN |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_EVENT_MUSIC,211,134,93,140,CBS_DROPDOWNLIST |
|
||||
LTEXT "Persona",IDC_STATIC,165,161,40,8
|
||||
COMBOBOX IDC_COMMAND_PERSONA,209,160,99,140,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_SUBSTITUTE_EVENT_MUSIC,211,150,93,140,CBS_DROPDOWN |
|
||||
GROUPBOX "Mission Music",IDC_STATIC,157,188,154,47
|
||||
LTEXT "Default",IDC_STATIC,161,200,40,8
|
||||
COMBOBOX IDC_EVENT_MUSIC,207,199,99,140,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
EDITTEXT IDC_MISSION_DESC,0,182,299,57,ES_MULTILINE |
|
||||
ES_AUTOVSCROLL | ES_WANTRETURN
|
||||
EDITTEXT IDC_MISSION_NOTES,1,254,297,57,ES_MULTILINE |
|
||||
ES_AUTOVSCROLL | ES_WANTRETURN
|
||||
DEFPUSHBUTTON "OK",IDOK,347,7,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,403,7,50,14
|
||||
LTEXT "Max Respawns",IDC_STATIC,8,97,52,8
|
||||
RTEXT "Title",IDC_STATIC,7,10,29,8
|
||||
RTEXT "Designer Notes",IDC_STATIC,1,243,50,8
|
||||
LTEXT "xx/xx/xx",IDC_MODIFIED,57,51,101,8
|
||||
RTEXT "Designer",IDC_STATIC,7,25,29,8
|
||||
RTEXT "Created:",IDC_STATIC,23,42,28,8
|
||||
LTEXT "xx/xx/xx",IDC_CREATED,57,42,103,8
|
||||
RTEXT "Last Modified:",IDC_STATIC,7,51,45,8
|
||||
LTEXT "Mission Description",IDC_STATIC,0,170,62,8
|
||||
LTEXT "Music",IDC_STATIC,153,137,32,8
|
||||
GROUPBOX "Squadron Reassign",IDC_STATIC,310,114,150,44
|
||||
LTEXT "Name",IDC_STATIC,322,125,28,8
|
||||
GROUPBOX "Loading Screen",IDC_STATIC,309,274,151,46
|
||||
GROUPBOX "Support Ships",IDC_STATIC,305,158,154,71
|
||||
LTEXT "Hull Repair Ceiling",IDC_STATIC,309,195,60,8
|
||||
LTEXT "Subsytem Repair Ceiling",IDC_STATIC,309,216,75,8
|
||||
LTEXT "%",IDC_STATIC,452,196,8,8
|
||||
LTEXT "%",IDC_STATIC,452,210,8,8
|
||||
GROUPBOX "Ship Trails",IDC_STATIC,306,231,154,41
|
||||
LTEXT "Substitute Music",IDC_STATIC,153,153,52,8
|
||||
LTEXT "AI Profile",IDC_STATIC,1,137,32,8
|
||||
CONTROL "Player Starts under AI Control (NO MULTI)",
|
||||
IDC_PLAYER_START_AI,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,3,153,149,10
|
||||
LTEXT "If music pack is present",IDC_STATIC,161,213,43,16
|
||||
COMBOBOX IDC_SUBSTITUTE_EVENT_MUSIC,207,215,99,140,CBS_DROPDOWN |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
GROUPBOX "Flags",IDC_STATIC,321,20,154,198
|
||||
CONTROL "All Teams at War",IDC_FULL_WAR,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,326,31,72,10
|
||||
CONTROL "Red Alert Mission",IDC_RED_ALERT,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,326,41,78,10
|
||||
CONTROL "Scramble Mission",IDC_SCRAMBLE,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,326,51,72,10
|
||||
CONTROL "Disallow Promotions/Badges",IDC_NO_PROMOTION,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,326,61,106,10
|
||||
CONTROL "Disable Built-in Messages",IDC_DISABLE_BUILTIN_MSGS,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,326,71,123,10
|
||||
CONTROL "Disable Built-in Command Messages",
|
||||
IDC_DISABLE_BUILTIN_COMMAND_MSGS,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,326,81,129,10
|
||||
CONTROL "No Traitor",IDC_NO_TRAITOR,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,326,91,123,10
|
||||
CONTROL "All Ships Beam-Freed By Default",
|
||||
IDC_BEAM_FREE_ALL_BY_DEFAULT,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,326,101,123,10
|
||||
CONTROL "Allow Daisy-Chained Docking",IDC_ALLOW_DOCK_TREES,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,326,111,123,10
|
||||
CONTROL "No Briefing",IDC_NO_BRIEFING,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,326,121,72,10
|
||||
CONTROL "No Debriefing",IDC_NO_DEBRIEFING,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,326,131,72,10
|
||||
CONTROL "Use Autopilot Cinematics",IDC_USE_AUTOPILOT_CINEMATICS,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,304,58,123,10
|
||||
CONTROL "2D Mission",IDC_2D_MISSION,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,304,70,123,10
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,326,141,123,10
|
||||
CONTROL "Deactivate Hardcoded Autopilot",
|
||||
IDC_DEACTIVATE_AUTOPILOT,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,304,81,123,10
|
||||
LTEXT "Retail Flags:",IDC_STATIC,167,7,40,8
|
||||
LTEXT "FS2 Open Flags",IDC_STATIC,304,25,52,8
|
||||
WS_TABSTOP,326,151,123,10
|
||||
CONTROL "Player Starts under AI Control (NO MULTI)",
|
||||
IDC_PLAYER_START_AI,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,326,161,146,10
|
||||
CONTROL "2D Mission",IDC_2D_MISSION,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,326,171,123,10
|
||||
LTEXT "AI Profile",IDC_STATIC,320,229,32,8
|
||||
COMBOBOX IDC_AI_PROFILE,378,226,93,140,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Mission Description",IDC_STATIC,4,238,62,8
|
||||
EDITTEXT IDC_MISSION_DESC,4,250,471,29,ES_MULTILINE |
|
||||
ES_AUTOVSCROLL | ES_WANTRETURN
|
||||
RTEXT "Designer Notes",IDC_STATIC,2,284,50,8
|
||||
EDITTEXT IDC_MISSION_NOTES,3,294,472,29,ES_MULTILINE |
|
||||
ES_AUTOVSCROLL | ES_WANTRETURN
|
||||
DEFPUSHBUTTON "OK",IDOK,368,0,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,424,0,50,14
|
||||
END
|
||||
|
||||
IDD_PREFERENCES DIALOG DISCARDABLE 0, 0, 333, 81
|
||||
@@ -1917,11 +1928,11 @@ BEGIN
|
||||
ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL
|
||||
END
|
||||
|
||||
IDD_BRIEFING_EDITOR DIALOGEX 0, 0, 258, 407
|
||||
IDD_BRIEFING_EDITOR DIALOGEX 0, 0, 258, 417
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Briefing Editor"
|
||||
MENU IDR_PLAYER_EDIT_MENU
|
||||
FONT 8, "MS Sans Serif", 0, 0, 0x1
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
PUSHBUTTON "Prev",IDC_PREV,147,7,23,14,0,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "Next",IDC_NEXT,173,7,23,14,0,WS_EX_STATICEDGE
|
||||
@@ -1943,57 +1954,58 @@ BEGIN
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,38,69,10
|
||||
CONTROL "Cut to previous stage",IDC_CUT_PREV,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,47,83,10
|
||||
EDITTEXT IDC_TEXT,7,75,244,40,ES_MULTILINE | ES_AUTOVSCROLL |
|
||||
EDITTEXT IDC_TEXT,7,72,244,40,ES_MULTILINE | ES_AUTOVSCROLL |
|
||||
ES_WANTRETURN
|
||||
EDITTEXT IDC_VOICE,63,118,83,13,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "Browse",IDC_BROWSE,150,118,42,14,0,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "IDB_PLAY",IDC_PLAY,194,118,13,14,BS_BITMAP,
|
||||
EDITTEXT IDC_VOICE,63,115,83,13,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "Browse",IDC_BROWSE,150,115,42,14,0,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "IDB_PLAY",IDC_PLAY,194,115,13,14,BS_BITMAP,
|
||||
WS_EX_TRANSPARENT | WS_EX_STATICEDGE
|
||||
COMBOBOX IDC_BRIEFING_MUSIC,63,134,83,135,CBS_DROPDOWNLIST |
|
||||
COMBOBOX IDC_BRIEFING_MUSIC,70,142,83,135,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_SUBSTITUTE_BRIEFING_MUSIC,63,151,83,135,CBS_DROPDOWN |
|
||||
COMBOBOX IDC_SUBSTITUTE_BRIEFING_MUSIC,70,159,83,135,CBS_DROPDOWN |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "Tree1",IDC_TREE,"SysTreeView32",TVS_HASBUTTONS |
|
||||
TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS |
|
||||
WS_BORDER | WS_TABSTOP,7,181,244,71,WS_EX_CLIENTEDGE
|
||||
WS_BORDER | WS_TABSTOP,7,190,244,71,WS_EX_CLIENTEDGE
|
||||
CONTROL "Draw lines between marked icons",IDC_LINES,"Button",
|
||||
BS_3STATE | WS_TABSTOP,129,255,122,10
|
||||
EDITTEXT IDC_ICON_LABEL,51,277,75,14,ES_AUTOHSCROLL
|
||||
COMBOBOX IDC_ICON_IMAGE,52,293,75,135,CBS_DROPDOWNLIST |
|
||||
BS_3STATE | WS_TABSTOP,129,264,122,10
|
||||
EDITTEXT IDC_ICON_LABEL,51,288,75,14,ES_AUTOHSCROLL
|
||||
COMBOBOX IDC_ICON_IMAGE,52,304,75,135,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_SHIP_TYPE,52,309,75,145,CBS_DROPDOWNLIST |
|
||||
COMBOBOX IDC_SHIP_TYPE,52,320,75,145,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_TEAM,52,325,75,84,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
COMBOBOX IDC_TEAM,52,336,75,84,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
EDITTEXT IDC_ID,151,273,30,12,ES_AUTOHSCROLL | ES_NUMBER
|
||||
EDITTEXT IDC_ID,151,284,30,12,ES_AUTOHSCROLL | ES_NUMBER
|
||||
CONTROL "Highlight",IDC_HILIGHT,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,135,291,43,10
|
||||
WS_TABSTOP,135,302,43,10
|
||||
CONTROL "Change locally",IDC_LOCAL,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,135,308,62,10
|
||||
WS_TABSTOP,135,319,62,10
|
||||
CONTROL "Flip Icon",IDC_FLIP_ICON,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,136,324,43,10
|
||||
PUSHBUTTON "Make Icon",IDC_MAKE_ICON,197,272,50,14,0,
|
||||
WS_TABSTOP,136,335,43,10
|
||||
PUSHBUTTON "Make Icon",IDC_MAKE_ICON,197,283,50,14,0,
|
||||
WS_EX_STATICEDGE
|
||||
PUSHBUTTON "Delete Icon",IDC_DELETE_ICON,197,289,50,14,0,
|
||||
PUSHBUTTON "Delete Icon",IDC_DELETE_ICON,197,300,50,14,0,
|
||||
WS_EX_STATICEDGE
|
||||
PUSHBUTTON "Propagate",IDC_PROPAGATE_ICONS,197,306,50,14,0,
|
||||
PUSHBUTTON "Propagate",IDC_PROPAGATE_ICONS,197,317,50,14,0,
|
||||
WS_EX_STATICEDGE
|
||||
EDITTEXT IDC_ICON_TEXT,14,352,230,40,ES_MULTILINE |
|
||||
EDITTEXT IDC_ICON_TEXT,14,363,230,40,ES_MULTILINE |
|
||||
ES_AUTOVSCROLL | ES_WANTRETURN
|
||||
LTEXT "Stage 1 of 9",IDC_STAGE_TITLE,7,7,53,8
|
||||
GROUPBOX "Current Icon Info",IDC_STATIC,7,264,244,136
|
||||
LTEXT "Label",IDC_STATIC,13,280,18,8
|
||||
LTEXT "Icon image",IDC_STATIC,13,296,36,8
|
||||
LTEXT "Text",IDC_STATIC,7,65,15,8
|
||||
GROUPBOX "Current Icon Info",IDC_STATIC,7,274,244,136
|
||||
LTEXT "Label",IDC_STATIC,13,291,18,8
|
||||
LTEXT "Icon image",IDC_STATIC,13,307,36,8
|
||||
LTEXT "Text",IDC_STATIC,7,62,15,8
|
||||
LTEXT "Camera Transition Time (ms)",IDC_STATIC,7,25,90,8
|
||||
LTEXT "Voice Wave File",IDC_STATIC,7,120,53,8
|
||||
LTEXT "Text",IDC_STATIC,14,341,15,8
|
||||
LTEXT "Team",IDC_STATIC,13,328,19,8
|
||||
LTEXT "Ship Type",IDC_STATIC,13,312,33,8
|
||||
LTEXT "ID",IDC_STATIC,137,275,8,8
|
||||
LTEXT "Briefing Music",IDC_STATIC,7,137,45,8
|
||||
LTEXT "Usage Formula",IDC_STATIC,7,171,48,8
|
||||
LTEXT "Substitute Music",IDC_STATIC,7,154,53,8
|
||||
LTEXT "Voice Wave File",IDC_STATIC,7,117,53,8
|
||||
LTEXT "Text",IDC_STATIC,14,352,15,8
|
||||
LTEXT "Team",IDC_STATIC,13,339,19,8
|
||||
LTEXT "Ship Type",IDC_STATIC,13,323,33,8
|
||||
LTEXT "ID",IDC_STATIC,137,286,8,8
|
||||
LTEXT "Default",IDC_STATIC,14,144,24,8
|
||||
LTEXT "Usage Formula",IDC_STATIC,7,180,48,8
|
||||
LTEXT "If music pack is present",IDC_STATIC,14,157,44,17
|
||||
GROUPBOX "Briefing Music",IDC_STATIC,7,132,150,44
|
||||
END
|
||||
|
||||
IDD_IGNORE_ORDERS DIALOG DISCARDABLE 0, 0, 120, 217
|
||||
@@ -2556,8 +2568,8 @@ BEGIN
|
||||
|
||||
IDD_MISSION_NOTES, DIALOG
|
||||
BEGIN
|
||||
RIGHTMARGIN, 460
|
||||
BOTTOMMARGIN, 320
|
||||
RIGHTMARGIN, 475
|
||||
BOTTOMMARGIN, 323
|
||||
END
|
||||
|
||||
IDD_PREFERENCES, DIALOG
|
||||
@@ -2731,7 +2743,7 @@ BEGIN
|
||||
RIGHTMARGIN, 251
|
||||
VERTGUIDE, 136
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 400
|
||||
BOTTOMMARGIN, 410
|
||||
END
|
||||
|
||||
IDD_IGNORE_ORDERS, DIALOG
|
||||
|
||||
@@ -1572,6 +1572,10 @@ void clear_mission()
|
||||
|
||||
The_mission.contrail_threshold = CONTRAIL_THRESHOLD_DEFAULT;
|
||||
|
||||
// Goober5000
|
||||
The_mission.command_persona = Default_command_persona;
|
||||
strcpy(The_mission.command_sender, DEFAULT_COMMAND);
|
||||
|
||||
// Goober5000: reset ALL mission flags, not just nebula!
|
||||
The_mission.flags = 0;
|
||||
The_mission.support_ships.max_support_ships = -1; // negative means infinite
|
||||
|
||||
@@ -266,6 +266,7 @@
|
||||
#include "gamesnd/eventmusic.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "mission/missionparse.h"
|
||||
#include "mission/missionmessage.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
@@ -297,6 +298,8 @@ CMissionNotesDlg::CMissionNotesDlg(CWnd* pParent /*=NULL*/) : CDialog(CMissionNo
|
||||
m_ai_profile = -1;
|
||||
m_event_music = -1;
|
||||
m_substitute_event_music = _T("");
|
||||
m_command_persona = -1;
|
||||
m_command_sender = _T("");
|
||||
m_full_war = FALSE;
|
||||
m_red_alert = FALSE;
|
||||
m_scramble = FALSE;
|
||||
@@ -341,6 +344,8 @@ void CMissionNotesDlg::DoDataExchange(CDataExchange* pDX)
|
||||
DDX_CBIndex(pDX, IDC_AI_PROFILE, m_ai_profile);
|
||||
DDX_CBIndex(pDX, IDC_EVENT_MUSIC, m_event_music);
|
||||
DDX_Text(pDX, IDC_SUBSTITUTE_EVENT_MUSIC, m_substitute_event_music);
|
||||
DDX_CBIndex(pDX, IDC_COMMAND_PERSONA, m_command_persona);
|
||||
DDX_Text(pDX, IDC_COMMAND_SENDER, m_command_sender);
|
||||
DDX_Check(pDX, IDC_FULL_WAR, m_full_war);
|
||||
DDX_Check(pDX, IDC_RED_ALERT, m_red_alert);
|
||||
DDX_Check(pDX, IDC_SCRAMBLE, m_scramble);
|
||||
@@ -609,6 +614,12 @@ void CMissionNotesDlg::OnOK()
|
||||
MODIFY(Current_soundtrack_num, m_event_music - 1);
|
||||
strcpy(The_mission.substitute_event_music_name, m_substitute_event_music);
|
||||
|
||||
MODIFY(The_mission.command_persona, ((CComboBox *) GetDlgItem(IDC_COMMAND_PERSONA))->GetItemData(m_command_persona));
|
||||
if (m_command_sender.GetAt(0) == '#')
|
||||
strcpy(The_mission.command_sender, m_command_sender.Mid(1));
|
||||
else
|
||||
strcpy(The_mission.command_sender, m_command_sender);
|
||||
|
||||
MODIFY(Mission_all_attack, m_full_war);
|
||||
if (query_modified()){
|
||||
set_modified();
|
||||
@@ -633,7 +644,7 @@ void CMissionNotesDlg::OnCancel()
|
||||
|
||||
BOOL CMissionNotesDlg::OnInitDialog()
|
||||
{
|
||||
int i;
|
||||
int i, box_index = 0, mission_command_persona_box_index = -1;
|
||||
CComboBox *box;
|
||||
CEdit *edit;
|
||||
|
||||
@@ -650,6 +661,7 @@ BOOL CMissionNotesDlg::OnInitDialog()
|
||||
m_mission_desc_orig = m_mission_desc = convert_multiline_string(The_mission.mission_desc);
|
||||
m_red_alert = (The_mission.flags & MISSION_FLAG_RED_ALERT) ? 1 : 0;
|
||||
m_scramble = (The_mission.flags & MISSION_FLAG_SCRAMBLE) ? 1 : 0;
|
||||
m_full_war = Mission_all_attack;
|
||||
m_daisy_chained_docking = (The_mission.flags & MISSION_FLAG_ALLOW_DOCK_TREES) ? 1 : 0;
|
||||
m_disallow_support = (The_mission.support_ships.max_support_ships == 0) ? 1 : 0;
|
||||
m_no_promotion = (The_mission.flags & MISSION_FLAG_NO_PROMOTION) ? 1 : 0;
|
||||
@@ -688,6 +700,25 @@ BOOL CMissionNotesDlg::OnInitDialog()
|
||||
box->AddString(Soundtracks[i].name);
|
||||
}
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_COMMAND_PERSONA);
|
||||
for (i=0; i<Num_personas; i++){
|
||||
if (Personas[i].flags & PERSONA_FLAG_COMMAND){
|
||||
box->AddString(Personas[i].name);
|
||||
box->SetItemData(box_index, i);
|
||||
if (i == The_mission.command_persona)
|
||||
mission_command_persona_box_index = box_index;
|
||||
box_index++;
|
||||
}
|
||||
}
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_COMMAND_SENDER);
|
||||
box->AddString(DEFAULT_COMMAND);
|
||||
for (i=0; i<MAX_SHIPS; i++){
|
||||
if (Ships[i].objnum >= 0)
|
||||
if (Ship_info[Ships[i].ship_info_index].flags & SIF_HUGE_SHIP)
|
||||
box->AddString(Ships[i].ship_name);
|
||||
}
|
||||
|
||||
// squad info
|
||||
if(strlen(The_mission.squad_name) > 0){
|
||||
m_squad_name = _T(The_mission.squad_name);
|
||||
@@ -699,9 +730,12 @@ BOOL CMissionNotesDlg::OnInitDialog()
|
||||
|
||||
m_type = The_mission.game_type;
|
||||
m_ai_profile = (The_mission.ai_profile - Ai_profiles);
|
||||
|
||||
m_event_music = Current_soundtrack_num + 1;
|
||||
m_substitute_event_music = The_mission.substitute_event_music_name;
|
||||
m_full_war = Mission_all_attack;
|
||||
|
||||
m_command_persona = mission_command_persona_box_index;
|
||||
m_command_sender = The_mission.command_sender;
|
||||
|
||||
// set up the game type checkboxes accoring to m_type
|
||||
if ( m_type & MISSION_TYPE_SINGLE ){
|
||||
|
||||
@@ -211,6 +211,8 @@ public:
|
||||
int m_ai_profile;
|
||||
int m_event_music;
|
||||
CString m_substitute_event_music;
|
||||
int m_command_persona;
|
||||
CString m_command_sender;
|
||||
BOOL m_full_war;
|
||||
BOOL m_red_alert;
|
||||
BOOL m_scramble;
|
||||
|
||||
@@ -141,11 +141,15 @@
|
||||
#include "ship/ship.h"
|
||||
#include "object/waypoint.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define BACKUP_DEPTH 9
|
||||
|
||||
class CFred_mission_save {
|
||||
private:
|
||||
char *raw_ptr;
|
||||
std::vector<std::string> fso_ver_comment;
|
||||
int err;
|
||||
CFILE *fp;
|
||||
|
||||
@@ -183,15 +187,18 @@ public:
|
||||
int save_reinforcements();
|
||||
void save_ai_goals(ai_goal *goalp, int ship);
|
||||
int fout(char *format, ...);
|
||||
int fout_ext(char *format, ...);
|
||||
int fout_version(char *format, ...);
|
||||
int fout_ext(char *pre_str, char *format, ...);
|
||||
void parse_comments(int = 1);
|
||||
CFred_mission_save() : err(0), raw_ptr(Mission_text_raw) { }
|
||||
int save_mission_file(char *pathname);
|
||||
int autosave_mission_file(char *pathname);
|
||||
int save_campaign_file(char *pathname);
|
||||
|
||||
void fso_comment_push(char *ver);
|
||||
void fso_comment_pop(bool pop_all = false);
|
||||
|
||||
// Goober5000
|
||||
int fout_and_bypass(char *format, ...);
|
||||
void bypass_comment(char *comment);
|
||||
};
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 206 B |
|
Before Width: | Height: | Size: 822 B |
|
Before Width: | Height: | Size: 822 B |
|
Before Width: | Height: | Size: 822 B |
|
Before Width: | Height: | Size: 822 B |
|
Before Width: | Height: | Size: 822 B After Width: | Height: | Size: 206 B |
|
Before Width: | Height: | Size: 822 B |
|
Before Width: | Height: | Size: 822 B |
|
Before Width: | Height: | Size: 822 B |
|
Before Width: | Height: | Size: 822 B |
|
Before Width: | Height: | Size: 822 B After Width: | Height: | Size: 206 B |
|
Before Width: | Height: | Size: 822 B |
|
Before Width: | Height: | Size: 822 B |
|
Before Width: | Height: | Size: 822 B |
|
Before Width: | Height: | Size: 822 B |
|
Before Width: | Height: | Size: 822 B After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
@@ -1,6 +1,6 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by fred.rc
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by FRED.rc
|
||||
//
|
||||
#define IDC_SAVE_DEFAULT_PREFS 3
|
||||
#define ID_DELETE_VARIABLE 3
|
||||
@@ -101,21 +101,26 @@
|
||||
#define IDD_CUSTOM_WING_NAMES 267
|
||||
#define IDD_RESTRICT_PATHS 270
|
||||
#define IDD_BACKGROUND_CHOOSER 272
|
||||
#define IDB_DATA_02 274
|
||||
#define IDB_DATA_03 275
|
||||
#define IDB_DATA_04 276
|
||||
#define IDB_DATA_05 277
|
||||
#define IDB_DATA_06 278
|
||||
#define IDB_DATA_07 279
|
||||
#define IDB_DATA_08 280
|
||||
#define IDB_DATA_09 281
|
||||
#define IDB_DATA_01 285
|
||||
#define IDB_DATA_10 286
|
||||
#define IDB_DATA_11 287
|
||||
#define IDB_DATA_12 288
|
||||
#define IDB_DATA_15 289
|
||||
#define IDB_DATA_14 290
|
||||
#define IDB_DATA_13 291
|
||||
#define IDB_DATA_15 296
|
||||
#define IDB_DATA_00 297
|
||||
#define IDB_DATA_20 300
|
||||
#define IDB_DATA_25 301
|
||||
#define IDB_DATA_30 302
|
||||
#define IDB_DATA_35 303
|
||||
#define IDB_DATA_40 304
|
||||
#define IDB_DATA_45 305
|
||||
#define IDB_DATA_50 306
|
||||
#define IDB_DATA_55 307
|
||||
#define IDB_DATA_60 308
|
||||
#define IDB_DATA_65 309
|
||||
#define IDB_DATA_70 310
|
||||
#define IDB_DATA_75 311
|
||||
#define IDB_DATA_80 312
|
||||
#define IDB_DATA_85 313
|
||||
#define IDB_DATA_90 314
|
||||
#define IDB_DATA_95 315
|
||||
#define IDC_SHIP_CLASS 1003
|
||||
#define IDC_SHIP_WING 1004
|
||||
#define IDC_SOUND_CLIP_NAME 1007
|
||||
@@ -573,6 +578,8 @@
|
||||
#define IDC_LIST3 1208
|
||||
#define IDC_FILELIST 1208
|
||||
#define IDC_YES_MESSAGE_LIST 1208
|
||||
#define IDC_COMMAND_SENDER 1209
|
||||
#define IDC_COMMAND_PERSONA 1210
|
||||
#define IDC_FILTER_WAYPOINTS 1211
|
||||
#define IDC_FILTER_STARTS 1212
|
||||
#define IDC_FILTER_SHIPS 1213
|
||||
@@ -1362,7 +1369,7 @@
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_3D_CONTROLS 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 292
|
||||
#define _APS_NEXT_RESOURCE_VALUE 316
|
||||
#define _APS_NEXT_COMMAND_VALUE 33091
|
||||
#define _APS_NEXT_CONTROL_VALUE 1595
|
||||
#define _APS_NEXT_SYMED_VALUE 105
|
||||
|
||||
@@ -820,6 +820,7 @@
|
||||
#include "weapon/weapon.h"
|
||||
#include "hud/hudartillery.h"
|
||||
#include "iff_defs/iff_defs.h"
|
||||
#include "mission/missionmessage.h"
|
||||
|
||||
#define TREE_NODE_INCREMENT 100
|
||||
|
||||
@@ -3139,6 +3140,7 @@ int sexp_tree::get_default_value(sexp_list_item *item, int op, int i)
|
||||
case OPF_SUBSYSTEM:
|
||||
case OPF_AWACS_SUBSYSTEM:
|
||||
case OPF_ROTATING_SUBSYSTEM:
|
||||
case OPF_SUBSYS_OR_GENERIC:
|
||||
str = "<name of subsystem>";
|
||||
break;
|
||||
|
||||
@@ -3191,6 +3193,10 @@ int sexp_tree::get_default_value(sexp_list_item *item, int op, int i)
|
||||
str = "<any data>";
|
||||
break;
|
||||
|
||||
case OPF_PERSONA:
|
||||
str = "<persona name>";
|
||||
break;
|
||||
|
||||
default:
|
||||
str = "<new default required!>";
|
||||
break;
|
||||
@@ -3259,6 +3265,7 @@ int sexp_tree::query_default_argument_available(int op, int i)
|
||||
case OPF_SKYBOX_MODEL_NAME:
|
||||
case OPF_SHIP_OR_NONE:
|
||||
case OPF_SUBSYSTEM_OR_NONE:
|
||||
case OPF_SUBSYS_OR_GENERIC:
|
||||
case OPF_BACKGROUND_BITMAP:
|
||||
case OPF_SUN_BITMAP:
|
||||
case OPF_NEBULA_STORM_TYPE:
|
||||
@@ -3288,6 +3295,12 @@ int sexp_tree::query_default_argument_available(int op, int i)
|
||||
|
||||
return 0;
|
||||
|
||||
case OPF_PERSONA:
|
||||
if (Num_personas)
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
|
||||
case OPF_POINT:
|
||||
case OPF_WAYPOINT_PATH:
|
||||
if (Num_waypoint_lists)
|
||||
@@ -4241,21 +4254,26 @@ void sexp_tree::OnLButtonUp(UINT nFlags, CPoint point)
|
||||
}
|
||||
|
||||
const static UINT Numbered_data_bitmaps[] = {
|
||||
IDB_DATA_01,
|
||||
IDB_DATA_02,
|
||||
IDB_DATA_03,
|
||||
IDB_DATA_04,
|
||||
IDB_DATA_00,
|
||||
IDB_DATA_05,
|
||||
IDB_DATA_06,
|
||||
IDB_DATA_07,
|
||||
IDB_DATA_08,
|
||||
IDB_DATA_09,
|
||||
IDB_DATA_10,
|
||||
IDB_DATA_11,
|
||||
IDB_DATA_12,
|
||||
IDB_DATA_13,
|
||||
IDB_DATA_14,
|
||||
IDB_DATA_15,
|
||||
IDB_DATA_20,
|
||||
IDB_DATA_25,
|
||||
IDB_DATA_30,
|
||||
IDB_DATA_35,
|
||||
IDB_DATA_40,
|
||||
IDB_DATA_45,
|
||||
IDB_DATA_50,
|
||||
IDB_DATA_55,
|
||||
IDB_DATA_60,
|
||||
IDB_DATA_65,
|
||||
IDB_DATA_70,
|
||||
IDB_DATA_75,
|
||||
IDB_DATA_80,
|
||||
IDB_DATA_85,
|
||||
IDB_DATA_90,
|
||||
IDB_DATA_95
|
||||
};
|
||||
|
||||
void sexp_tree::setup(CEdit *ptr)
|
||||
@@ -4816,6 +4834,10 @@ sexp_list_item *sexp_tree::get_listing_opf(int opf, int parent_node, int arg_ind
|
||||
list = get_listing_opf_subsystem_or_none(parent_node, arg_index);
|
||||
break;
|
||||
|
||||
case OPF_SUBSYS_OR_GENERIC:
|
||||
list = get_listing_opf_subsys_or_generic(parent_node, arg_index);
|
||||
break;
|
||||
|
||||
case OPF_JUMP_NODE_NAME:
|
||||
list = get_listing_opf_jump_nodes();
|
||||
break;
|
||||
@@ -4856,6 +4878,10 @@ sexp_list_item *sexp_tree::get_listing_opf(int opf, int parent_node, int arg_ind
|
||||
list = get_listing_opf_turret_target_order();
|
||||
break;
|
||||
|
||||
case OPF_PERSONA:
|
||||
list = get_listing_opf_persona();
|
||||
break;
|
||||
|
||||
default:
|
||||
Int3(); // unknown OPF code
|
||||
list = NULL;
|
||||
@@ -4866,15 +4892,12 @@ 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 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)
|
||||
{
|
||||
// also skip for OPF_NULL, because it takes no data (though it can take plenty of operators)
|
||||
if (opf == OPF_NULL) {
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -4946,15 +4969,25 @@ int sexp_tree::find_ancestral_argument_number(int parent_op, int child_node)
|
||||
*/
|
||||
int sexp_tree::get_data_image(int node)
|
||||
{
|
||||
int count = get_sibling_place(node);
|
||||
int count = get_sibling_place(node) + 1;
|
||||
|
||||
if(count < 0)
|
||||
if (count <= 0) {
|
||||
return BITMAP_DATA;
|
||||
}
|
||||
|
||||
if(count > NUM_BITMAP_NUMBERED_DATA)
|
||||
if (count % 5) {
|
||||
return BITMAP_DATA;
|
||||
}
|
||||
|
||||
return BITMAP_NUMBERED_DATA + count;
|
||||
int idx = (count % 100) / 5;
|
||||
|
||||
int num = sizeof(Numbered_data_bitmaps)/sizeof(UINT);
|
||||
|
||||
if (idx > num) {
|
||||
return BITMAP_DATA;
|
||||
}
|
||||
|
||||
return BITMAP_NUMBERED_DATA + idx;
|
||||
}
|
||||
|
||||
int sexp_tree::get_sibling_place(int node)
|
||||
@@ -5551,6 +5584,20 @@ sexp_list_item *sexp_tree::get_listing_opf_message()
|
||||
return head.next;
|
||||
}
|
||||
|
||||
sexp_list_item *sexp_tree::get_listing_opf_persona()
|
||||
{
|
||||
int i;
|
||||
sexp_list_item head;
|
||||
|
||||
for (i = 0; i < Num_personas; i++) {
|
||||
if (Personas[i].flags & PERSONA_FLAG_WINGMAN) {
|
||||
head.add_data (Personas[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
return head.next;
|
||||
}
|
||||
|
||||
sexp_list_item *sexp_tree::get_listing_opf_who_from()
|
||||
{
|
||||
object *ptr;
|
||||
@@ -5889,6 +5936,17 @@ sexp_list_item *sexp_tree::get_listing_opf_subsystem_or_none(int parent_node, in
|
||||
return head.next;
|
||||
}
|
||||
|
||||
sexp_list_item *sexp_tree::get_listing_opf_subsys_or_generic(int parent_node, int arg_index)
|
||||
{
|
||||
sexp_list_item head;
|
||||
|
||||
head.add_data(SEXP_ALL_ENGINES_STRING);
|
||||
head.add_data(SEXP_ALL_TURRETS_STRING);
|
||||
head.add_list(get_listing_opf_subsystem(parent_node, arg_index));
|
||||
|
||||
return head.next;
|
||||
}
|
||||
|
||||
sexp_list_item *sexp_tree::get_listing_opf_jump_nodes()
|
||||
{
|
||||
sexp_list_item head;
|
||||
|
||||
@@ -55,7 +55,6 @@
|
||||
#define BITMAP_BLUE_DOT BITMAP_ROOT
|
||||
#define BITMAP_RED_DOT BITMAP_ROOT_DIRECTIVE
|
||||
#define BITMAP_NUMBERED_DATA 9
|
||||
#define NUM_BITMAP_NUMBERED_DATA 15
|
||||
//Therefore NEXT DEFINE should be 9+12 or 21
|
||||
|
||||
|
||||
@@ -247,7 +246,9 @@ public:
|
||||
sexp_list_item *get_listing_opf_flexible_argument();
|
||||
sexp_list_item *get_listing_opf_ship_or_none();
|
||||
sexp_list_item *get_listing_opf_subsystem_or_none(int parent_node, int arg_index);
|
||||
sexp_list_item *get_listing_opf_subsys_or_generic(int parent_node, int arg_index);
|
||||
sexp_list_item *get_listing_opf_turret_target_order();
|
||||
sexp_list_item *get_listing_opf_persona();
|
||||
// ---------------------------------------------------------
|
||||
|
||||
int m_mode;
|
||||
|
||||
@@ -132,6 +132,7 @@ BOOL ShipSpecialDamage::OnInitDialog()
|
||||
m_special_exp_enabled = TRUE;
|
||||
}
|
||||
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// maybe gray out lots of stuff
|
||||
@@ -163,6 +164,25 @@ void ShipSpecialDamage::OnOK()
|
||||
{
|
||||
UpdateData(TRUE);
|
||||
|
||||
object *objp;
|
||||
|
||||
objp = GET_FIRST(&obj_used_list);
|
||||
while (objp != END_OF_LIST(&obj_used_list)) {
|
||||
if ((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) {
|
||||
if (objp->flags & OF_MARKED)
|
||||
update_ship(objp->instance);
|
||||
}
|
||||
|
||||
objp = GET_NEXT(objp);
|
||||
}
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void ShipSpecialDamage::update_ship(int shipnum)
|
||||
{
|
||||
ship *shipp = &Ships[shipnum];
|
||||
|
||||
// TODO: Add extra validation here
|
||||
if (m_special_exp_enabled) {
|
||||
|
||||
@@ -173,17 +193,17 @@ void ShipSpecialDamage::OnOK()
|
||||
return;
|
||||
}
|
||||
|
||||
if (Ships[m_ship_num].special_exp_index == -1) {
|
||||
if (shipp->special_exp_index == -1) {
|
||||
// get free sexp_variables
|
||||
start = sexp_variable_allocate_block(Ships[m_ship_num].ship_name, SEXP_VARIABLE_BLOCK | SEXP_VARIABLE_BLOCK_EXP);
|
||||
start = sexp_variable_allocate_block(shipp->ship_name, SEXP_VARIABLE_BLOCK | SEXP_VARIABLE_BLOCK_EXP);
|
||||
if (start == -1) {
|
||||
MessageBox("Unable to allocate storage, try deleting Sexp variables");
|
||||
return;
|
||||
} else {
|
||||
Ships[m_ship_num].special_exp_index = start;
|
||||
shipp->special_exp_index = start;
|
||||
}
|
||||
} else {
|
||||
start = Ships[m_ship_num].special_exp_index;
|
||||
start = shipp->special_exp_index;
|
||||
}
|
||||
// set to update
|
||||
set_modified();
|
||||
@@ -197,17 +217,16 @@ void ShipSpecialDamage::OnOK()
|
||||
sprintf(Sexp_variables[start+SHOCK_SPEED].text, "%d", m_shock_speed);
|
||||
|
||||
} else {
|
||||
if (Ships[m_ship_num].special_exp_index != -1) {
|
||||
if (shipp->special_exp_index != -1) {
|
||||
// set to update
|
||||
set_modified();
|
||||
|
||||
// free block
|
||||
sexp_variable_block_free(Ships[m_ship_num].ship_name, Ships[m_ship_num].special_exp_index, SEXP_VARIABLE_BLOCK |SEXP_VARIABLE_BLOCK_EXP);
|
||||
sexp_variable_block_free(shipp->ship_name, Ships[m_ship_num].special_exp_index, SEXP_VARIABLE_BLOCK |SEXP_VARIABLE_BLOCK_EXP);
|
||||
|
||||
// set index to no exp block
|
||||
Ships[m_ship_num].special_exp_index = -1;
|
||||
shipp->special_exp_index = -1;
|
||||
}
|
||||
}
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ class ShipSpecialDamage : public CDialog
|
||||
// Construction
|
||||
public:
|
||||
ShipSpecialDamage(CWnd* pParent = NULL); // standard constructor
|
||||
void update_ship(int ship);
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(ShipSpecialDamage)
|
||||
|
||||
@@ -124,7 +124,7 @@ BOOL starfield_editor::OnInitDialog()
|
||||
CDialog::OnInitDialog();
|
||||
theApp.init_window(&Starfield_wnd_data, this);
|
||||
|
||||
m_slider.SetRange(100, MAX_STARS);
|
||||
m_slider.SetRange(0, MAX_STARS);
|
||||
m_slider.SetPos(Num_stars);
|
||||
sprintf(buf, "%d", Num_stars);
|
||||
GetDlgItem(IDC_TOTAL)->SetWindowText(buf);
|
||||
|
||||
@@ -1833,6 +1833,7 @@
|
||||
#include "osapi/osregistry.h"
|
||||
#include "parse/encrypt.h"
|
||||
#include "parse/lua.h"
|
||||
#include "parse/parselo.h"
|
||||
#include "parse/scripting.h"
|
||||
#include "parse/sexp.h"
|
||||
#include "particle/particle.h"
|
||||
@@ -1899,7 +1900,7 @@ extern int Om_tracker_flag; // needed for FS2OpenPXO config
|
||||
// This function is defined in code\network\multiutil.cpp so will be linked from multiutil.obj
|
||||
// it's required fro the -missioncrcs command line option - Kazan
|
||||
void multi_spew_pxo_checksums(int max_files, char *outfile);
|
||||
void multi_spew_table_checksums(int max_files, char *outfile);
|
||||
void fs2netd_spew_table_checksums(char *outfile);
|
||||
|
||||
extern bool frame_rate_display;
|
||||
|
||||
@@ -4168,7 +4169,7 @@ void game_show_framerate()
|
||||
#endif
|
||||
|
||||
|
||||
if (Show_framerate) {
|
||||
if (Show_framerate && HUD_draw) {
|
||||
gr_set_color_fast(&HUD_color_debug);
|
||||
|
||||
if (frametotal != 0.0f)
|
||||
@@ -4190,7 +4191,7 @@ void game_show_framerate()
|
||||
// MONITOR_INC(BmpNew, bitmaps_new_this_frame);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (Cmdline_show_stats) {
|
||||
if (Cmdline_show_stats && HUD_draw) {
|
||||
char mem_buffer[50];
|
||||
|
||||
#ifndef NO_DIRECT3D
|
||||
@@ -4394,7 +4395,7 @@ void game_show_framerate()
|
||||
|
||||
void game_show_eye_pos(vec3d *eye_pos, matrix* eye_orient)
|
||||
{
|
||||
if(!Cmdline_show_pos)
|
||||
if ( !Cmdline_show_pos && HUD_draw )
|
||||
return;
|
||||
|
||||
//Do stuff
|
||||
@@ -4976,19 +4977,17 @@ void say_view_target()
|
||||
if (!(Game_mode & GM_DEAD_DIED) && ((Game_mode & (GM_DEAD_BLEW_UP)) || ((Last_view_target != NULL) && (Last_view_target != view_target)))) {
|
||||
if (view_target != Player_obj){
|
||||
|
||||
char *view_target_name = NULL;
|
||||
char view_target_name[128] = "";
|
||||
switch(Objects[Player_ai->target_objnum].type) {
|
||||
case OBJ_SHIP:
|
||||
view_target_name = Ships[Objects[Player_ai->target_objnum].instance].ship_name;
|
||||
strcpy(view_target_name, Ships[Objects[Player_ai->target_objnum].instance].ship_name);
|
||||
break;
|
||||
case OBJ_WEAPON:
|
||||
view_target_name = Weapon_info[Weapons[Objects[Player_ai->target_objnum].instance].weapon_info_index].name;
|
||||
strcpy(view_target_name, Weapon_info[Weapons[Objects[Player_ai->target_objnum].instance].weapon_info_index].name);
|
||||
Viewer_mode &= ~VM_OTHER_SHIP;
|
||||
break;
|
||||
case OBJ_JUMP_NODE: {
|
||||
char jump_node_name[128];
|
||||
strcpy(jump_node_name, XSTR( "jump node", 184));
|
||||
view_target_name = jump_node_name;
|
||||
strcpy(view_target_name, XSTR( "jump node", 184));
|
||||
Viewer_mode &= ~VM_OTHER_SHIP;
|
||||
break;
|
||||
}
|
||||
@@ -4998,6 +4997,7 @@ void say_view_target()
|
||||
break;
|
||||
}
|
||||
|
||||
end_string_at_first_hash_symbol(view_target_name);
|
||||
if ( view_target_name ) {
|
||||
HUD_fixed_printf(0.0f, XSTR( "Viewing %s%s\n", 185), (Viewer_mode & VM_OTHER_SHIP) ? XSTR( "from ", 186) : "", view_target_name);
|
||||
Show_viewing_from_self = 1;
|
||||
@@ -5575,7 +5575,7 @@ void game_render_frame( vec3d *eye_pos, matrix *eye_orient )
|
||||
// maybe offset the HUD (jitter stuff) and measure the 2D displacement between the player's view and ship vector
|
||||
dont_offset = ((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_OBSERVER));
|
||||
HUD_set_offsets(Viewer_obj, !dont_offset, &eye_no_jitter);
|
||||
|
||||
|
||||
// for multiplayer clients, call code in Shield.cpp to set up the Shield_hit array. Have to
|
||||
// do this becaues of the disjointed nature of this system (in terms of setup and execution).
|
||||
// must be done before ships are rendered
|
||||
@@ -6423,7 +6423,7 @@ void game_frame(int paused)
|
||||
popupdead_start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_GET_TIME( render3_time2 )
|
||||
DEBUG_GET_TIME( render2_time1 )
|
||||
@@ -7940,7 +7940,7 @@ void game_leave_state( int old_state, int new_state )
|
||||
}
|
||||
break;
|
||||
|
||||
case GS_STATE_MULTI_MISSION_SYNC:
|
||||
case GS_STATE_MULTI_MISSION_SYNC:
|
||||
common_select_close();
|
||||
|
||||
// if we're moving into the options menu we don't need to do anything else
|
||||
@@ -9104,7 +9104,7 @@ int game_main(char *cmdline)
|
||||
multi_spew_pxo_checksums(1024, "mission_crcs.txt");
|
||||
|
||||
if (Cmdline_spew_table_crcs) {
|
||||
multi_spew_table_checksums(50, "table_crcs.txt");
|
||||
fs2netd_spew_table_checksums("table_crcs.txt");
|
||||
}
|
||||
|
||||
game_shutdown();
|
||||
@@ -9113,7 +9113,7 @@ int game_main(char *cmdline)
|
||||
|
||||
|
||||
if (Cmdline_spew_table_crcs) {
|
||||
multi_spew_table_checksums(50, "table_crcs.txt");
|
||||
fs2netd_spew_table_checksums("table_crcs.txt");
|
||||
game_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
#include "graphics/font.h"
|
||||
#include "globalincs/alphacolors.h"
|
||||
#include "network/multi_options.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "cfile/cfilesystem.h"
|
||||
|
||||
#ifdef WIN32
|
||||
//#include <windows.h>
|
||||
@@ -603,6 +605,8 @@ void fs2netd_do_frame()
|
||||
Logged_in = false;
|
||||
PXO_SID = -1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
@@ -765,6 +769,99 @@ int fs2netd_load_servers()
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static char Chk_mission_name[NAME_LENGTH+1];
|
||||
static uint Chk_mission_crc = 0;
|
||||
|
||||
int fs2netd_check_mission_do()
|
||||
{
|
||||
if (timeout == -1) {
|
||||
timeout = timer_get_fixed_seconds() + (15 * F1_0);
|
||||
}
|
||||
|
||||
// if timeout passes then bail on stats failure
|
||||
if ( timer_get_fixed_seconds() > timeout ) {
|
||||
timeout = -1;
|
||||
return 4;
|
||||
}
|
||||
|
||||
int rescode = FS2NetD_CheckSingleMission(Chk_mission_name, Chk_mission_crc, do_full_packet);
|
||||
|
||||
do_full_packet = 0;
|
||||
|
||||
if (rescode) {
|
||||
timeout = -1;
|
||||
return rescode;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool fs2netd_check_mission(char *mission_name)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
// don't bother with this if we aren't on FS2NetD
|
||||
if ( !Om_tracker_flag ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !(Game_mode & GM_MULTIPLAYER) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !Is_connected ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy(Chk_mission_name, mission_name);
|
||||
cf_chksum_long(Chk_mission_name, &Chk_mission_crc);
|
||||
|
||||
do_full_packet = 1;
|
||||
|
||||
In_process = true;
|
||||
|
||||
if (Is_standalone) {
|
||||
do { rc = fs2netd_check_mission_do(); } while (!rc);
|
||||
} else {
|
||||
rc = popup_till_condition(fs2netd_check_mission_do, XSTR("&Cancel", 779), XSTR("Sending stats...", -1));
|
||||
}
|
||||
|
||||
In_process = false;
|
||||
|
||||
switch (rc) {
|
||||
// operation canceled, or invalid
|
||||
case 0:
|
||||
return false;
|
||||
|
||||
// successful, but invalid
|
||||
case 1:
|
||||
return false;
|
||||
|
||||
// successful and valid
|
||||
case 2:
|
||||
return true;
|
||||
|
||||
// failed to send request packet
|
||||
case 3:
|
||||
if ( !Is_standalone ) {
|
||||
popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("Server request failed!", -1));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
// it timed out
|
||||
case 4:
|
||||
if ( !Is_standalone ) {
|
||||
popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("Server request timed out!", -1));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void fs2netd_debrief_init()
|
||||
{
|
||||
if ( !(Game_mode & GM_MULTIPLAYER) ) {
|
||||
@@ -780,12 +877,7 @@ void fs2netd_debrief_init()
|
||||
}
|
||||
|
||||
|
||||
uint CurrentMissionChsum;
|
||||
bool mValidStatus = false;
|
||||
|
||||
cf_chksum_long(Netgame.mission_name, &CurrentMissionChsum);
|
||||
|
||||
mValidStatus = FS2NetD_CheckSingleMission(Netgame.mission_name, CurrentMissionChsum);
|
||||
bool mValidStatus = fs2netd_check_mission(Netgame.mission_name);
|
||||
|
||||
if ( ((multi_num_players() > 1) || (Multi_num_players_at_start > 1)) && !game_hacked_data() && mValidStatus ) {
|
||||
// verify that we are logged in before doing anything else
|
||||
@@ -1326,12 +1418,15 @@ int fs2netd_get_pilot_info(const char *callsign, player *out_plr, bool first_cal
|
||||
strncpy( new_plr.callsign, callsign, CALLSIGN_LEN );
|
||||
|
||||
memset( out_plr, 0, sizeof(player) );
|
||||
|
||||
timeout = timer_get_fixed_seconds() + (30 * F1_0);
|
||||
}
|
||||
|
||||
int rc = FS2NetD_GetPlayerData(-2, callsign, &new_plr, false, (int)first_call );
|
||||
|
||||
// some sort of failure
|
||||
if (rc > 0) {
|
||||
timeout = -1;
|
||||
return -2;
|
||||
}
|
||||
|
||||
@@ -1339,6 +1434,12 @@ int fs2netd_get_pilot_info(const char *callsign, player *out_plr, bool first_cal
|
||||
memcpy( out_plr, &new_plr, sizeof(player) );
|
||||
}
|
||||
|
||||
// if timeout passes then bail on failure
|
||||
if ( timer_get_fixed_seconds() > timeout ) {
|
||||
timeout = -1;
|
||||
return -2;
|
||||
}
|
||||
|
||||
// we should only be returning -1 (processing) or 0 (got data successfully)
|
||||
return rc;
|
||||
}
|
||||
@@ -1392,3 +1493,50 @@ void fs2netd_update_game_count(char *chan_name)
|
||||
FS2NetD_GameCountUpdate(chan_name);
|
||||
}
|
||||
|
||||
void fs2netd_spew_table_checksums(char *outfile)
|
||||
{
|
||||
char full_name[MAX_PATH_LEN];
|
||||
int count, idx;
|
||||
FILE *out = NULL;
|
||||
char modname[128];
|
||||
time_t my_time = 0;
|
||||
|
||||
if ( Table_valid_status.empty() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
cf_create_default_path_string(full_name, sizeof(full_name) - 1, CF_TYPE_ROOT, outfile);
|
||||
|
||||
// open the outfile
|
||||
out = fopen(full_name, "wt");
|
||||
|
||||
if (out == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset( modname, 0, sizeof(modname) );
|
||||
strcpy( modname, Cmdline_spew_table_crcs );
|
||||
|
||||
my_time = time(NULL);
|
||||
|
||||
fprintf(out, "-- Table CRCs generated on %s \n", ctime(&my_time));
|
||||
|
||||
fprintf(out, "LOCK TABLES `fstables` WRITE;\n");
|
||||
fprintf(out, "INSERT INTO `fstables` VALUES ");
|
||||
|
||||
count = (int)Table_valid_status.size();
|
||||
|
||||
// do all the checksums
|
||||
for (idx = 0; idx < count; idx++) {
|
||||
if (idx == 0) {
|
||||
fprintf(out, "('%s',%u,'%s')", Table_valid_status[idx].name, Table_valid_status[idx].crc32, modname);
|
||||
} else {
|
||||
fprintf(out, ",('%s',%u,'%s')", Table_valid_status[idx].name, Table_valid_status[idx].crc32, modname);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(out, ";\n");
|
||||
fprintf(out, "UNLOCK TABLES;\n");
|
||||
|
||||
fclose(out);
|
||||
}
|
||||
@@ -175,7 +175,7 @@
|
||||
extern std::vector<crc_valid_status> Table_valid_status;
|
||||
|
||||
|
||||
bool FS2NetD_CheckSingleMission(const char *m_name, uint crc32, int timeout)
|
||||
int FS2NetD_CheckSingleMission(const char *m_name, uint crc32, int timeout)
|
||||
{
|
||||
int rc, buffer_size, buffer_offset;
|
||||
bool my_packet = false;
|
||||
@@ -197,7 +197,7 @@ bool FS2NetD_CheckSingleMission(const char *m_name, uint crc32, int timeout)
|
||||
DONE_PACKET();
|
||||
|
||||
if ( FS2NetD_SendData(buffer, buffer_size) == -1 )
|
||||
return false;
|
||||
return 3;
|
||||
|
||||
|
||||
Recieve_Only:
|
||||
@@ -207,12 +207,12 @@ Recieve_Only:
|
||||
|
||||
if ( (rc = FS2NetD_GetData(buffer, sizeof(buffer))) != -1 ) {
|
||||
if (rc < BASE_PACKET_SIZE)
|
||||
return false;
|
||||
return 0;
|
||||
|
||||
VRFY_PACKET2( PCKT_MCHECK_REPLY );
|
||||
|
||||
if (!my_packet)
|
||||
return false;
|
||||
return 0;
|
||||
|
||||
PXO_GET_DATA( status );
|
||||
Assert( (status == 0) || (status == 1) );
|
||||
@@ -220,9 +220,11 @@ Recieve_Only:
|
||||
// anything beyond 'true' is considered a failure of some kind
|
||||
if (status > 1)
|
||||
status = 0;
|
||||
|
||||
return status+1;
|
||||
}
|
||||
|
||||
return (status == 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FS2NetD_SendPlayerData(int SID, const char *player_name, const char *user, player *pl, int timeout)
|
||||
|
||||
@@ -96,7 +96,7 @@ struct netgame_info;
|
||||
|
||||
int FS2NetD_SendPlayerData(int SID, const char* player_name, const char* user, player *pl, int timeout = 15);
|
||||
int FS2NetD_GetPlayerData(int SID, const char* player_name, player *pl, bool CanCreate = false, int timeout = 15);
|
||||
bool FS2NetD_CheckSingleMission(const char *m_name, uint crc32, int timeout = 15);
|
||||
int FS2NetD_CheckSingleMission(const char *m_name, uint crc32, int timeout = 15);
|
||||
int FS2NetD_CheckValidSID(int SID);
|
||||
int FS2NetD_GetServerList(int timeout = 15);
|
||||
void FS2NetD_Ping();
|
||||
|
||||
@@ -771,6 +771,14 @@ $Player Shield Recharge Scale: 4, 2, 1.5, 1.25, 1 \n\
|
||||
;; factor applied to the speed at which the player's weapons recharge \n\
|
||||
$Player Weapon Recharge Scale: 10, 4, 2.5, 2, 1.5 \n\
|
||||
\n\
|
||||
;; maximum number of turrets on one ship allowed to be attacking a \n\
|
||||
;; target at a given time \n\
|
||||
$Max Turret Target Ownage: 3, 4, 7, 12, 19 \n\
|
||||
\n\
|
||||
;; maximum number of turrets on one ship allowed to be attacking the \n\
|
||||
;; player at a given time \n\
|
||||
$Max Turret Player Ownage: 3, 4, 7, 12, 19 \n\
|
||||
\n\
|
||||
\n\
|
||||
;; General AI-related flags. These were previously all lumped together \n\
|
||||
;; under the New AI mission flag. \n\
|
||||
|
||||
@@ -1400,6 +1400,8 @@ void gr_init_res(int res, int mode, int max_w, int max_h)
|
||||
gr_screen.clip_width = gr_screen.clip_width_unscaled = gr_screen.max_w;
|
||||
gr_screen.clip_height = gr_screen.clip_height_unscaled = gr_screen.max_h;
|
||||
gr_screen.clip_aspect = i2fl(gr_screen.clip_width) / i2fl(gr_screen.clip_height);
|
||||
gr_screen.clip_center_x = (gr_screen.clip_left + gr_screen.clip_right) * 0.5f;
|
||||
gr_screen.clip_center_y = (gr_screen.clip_top + gr_screen.clip_bottom) * 0.5f;
|
||||
|
||||
if (gr_screen.custom_size >= 0) {
|
||||
gr_unsize_screen_pos( &gr_screen.max_w_unscaled, &gr_screen.max_h_unscaled );
|
||||
|
||||
@@ -874,6 +874,8 @@ typedef struct screen {
|
||||
int clip_left, clip_right, clip_top, clip_bottom;
|
||||
// same as above except in 1024x768 or 640x480 dimensions
|
||||
int clip_left_unscaled, clip_right_unscaled, clip_top_unscaled, clip_bottom_unscaled;
|
||||
// center of clip area
|
||||
float clip_center_x, clip_center_y;
|
||||
|
||||
int current_alphablend_mode; // See GR_ALPHABLEND defines above
|
||||
int current_bitblt_mode; // See GR_BITBLT_MODE defines above
|
||||
|
||||
@@ -1755,6 +1755,9 @@ void gr_opengl_set_clip(int x, int y, int w, int h, bool resize)
|
||||
|
||||
gr_screen.clip_aspect = i2fl(w) / i2fl(h);
|
||||
|
||||
gr_screen.clip_center_x = (gr_screen.clip_left + gr_screen.clip_right) * 0.5f;
|
||||
gr_screen.clip_center_y = (gr_screen.clip_top + gr_screen.clip_bottom) * 0.5f;
|
||||
|
||||
// just return early if we aren't actually going to need the scissor test
|
||||
if ( (x == 0) && (y == 0) && (w == max_w) && (h == max_h) ) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
@@ -1783,6 +1786,9 @@ void gr_opengl_reset_clip()
|
||||
|
||||
gr_screen.clip_aspect = i2fl(gr_screen.clip_width) / i2fl(gr_screen.clip_height);
|
||||
|
||||
gr_screen.clip_center_x = (gr_screen.clip_left + gr_screen.clip_right) * 0.5f;
|
||||
gr_screen.clip_center_y = (gr_screen.clip_top + gr_screen.clip_bottom) * 0.5f;
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
@@ -4815,8 +4821,8 @@ void gr_opengl_init(int reinit)
|
||||
if ( !Cmdline_nohtl && !Cmdline_novbo && Is_Extension_Enabled(OGL_ARB_VERTEX_BUFFER_OBJECT) )
|
||||
VBO_ENABLED = 1;
|
||||
|
||||
if ( Is_Extension_Enabled(OGL_ARB_PIXEL_BUFFER_OBJECT) )
|
||||
Use_PBOs = 1;
|
||||
//if ( Is_Extension_Enabled(OGL_ARB_PIXEL_BUFFER_OBJECT) )
|
||||
// Use_PBOs = 1;
|
||||
|
||||
// setup the best fog function found
|
||||
// start with NV Radial Fog (GeForces only) -- needs t&l, will have to wait
|
||||
|
||||
@@ -563,34 +563,10 @@ void gr_opengl_destroy_buffer(int idx)
|
||||
|
||||
#define DO_RENDER() { \
|
||||
if ( (ibuffer != NULL) || (sbuffer != NULL) ) { \
|
||||
if ( multiple_elements ) { \
|
||||
start_tmp = 0; \
|
||||
end_tmp = (GL_max_elements_indices - 1); \
|
||||
count_tmp = (end_tmp - start_tmp + 1); \
|
||||
\
|
||||
if (ibuffer) { \
|
||||
vglDrawRangeElements(GL_TRIANGLES, start_tmp, end_tmp, count_tmp, GL_UNSIGNED_INT, ibuffer + start_tmp); \
|
||||
} else { \
|
||||
vglDrawRangeElements(GL_TRIANGLES, start_tmp, end_tmp, count_tmp, GL_UNSIGNED_SHORT, sbuffer + start_tmp); \
|
||||
} \
|
||||
\
|
||||
while (end_tmp < end) { \
|
||||
start_tmp += (GL_max_elements_indices - 1); \
|
||||
end_tmp = MIN( (start_tmp + GL_max_elements_indices - 1), end ); \
|
||||
count_tmp = (end_tmp - start_tmp + 1); \
|
||||
\
|
||||
if (ibuffer) { \
|
||||
vglDrawRangeElements(GL_TRIANGLES, start_tmp, end_tmp, count_tmp, GL_UNSIGNED_INT, ibuffer + start_tmp); \
|
||||
} else { \
|
||||
vglDrawRangeElements(GL_TRIANGLES, start_tmp, end_tmp, count_tmp, GL_UNSIGNED_SHORT, sbuffer + start_tmp); \
|
||||
} \
|
||||
} \
|
||||
if (ibuffer) { \
|
||||
vglDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_INT, ibuffer + start); \
|
||||
} else { \
|
||||
if (ibuffer) { \
|
||||
vglDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_INT, ibuffer + start); \
|
||||
} else { \
|
||||
vglDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_SHORT, sbuffer + start); \
|
||||
} \
|
||||
vglDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_SHORT, sbuffer + start); \
|
||||
} \
|
||||
} else { \
|
||||
glDrawArrays(GL_TRIANGLES, 0, vbp->n_verts); \
|
||||
@@ -620,7 +596,6 @@ void gr_opengl_render_buffer(int start, int n_prim, ushort *sbuffer, uint *ibuff
|
||||
|
||||
int end = ((n_prim * 3) - 1);
|
||||
int count = (end - start + 1); //(n_prim * 3);
|
||||
int start_tmp, end_tmp, count_tmp, multiple_elements = 0;
|
||||
|
||||
int textured = (flags & TMAP_FLAG_TEXTURED);
|
||||
|
||||
@@ -631,10 +606,6 @@ void gr_opengl_render_buffer(int start, int n_prim, ushort *sbuffer, uint *ibuff
|
||||
// disable all arbs before we start
|
||||
opengl_switch_arb(-1, 0);
|
||||
|
||||
// see if we need to optimize glDrawRangeElements
|
||||
if ( count > GL_max_elements_indices )
|
||||
multiple_elements = 1;
|
||||
|
||||
if ( glIsEnabled(GL_CULL_FACE) )
|
||||
glFrontFace(GL_CW);
|
||||
|
||||
|
||||
@@ -1986,7 +1986,7 @@ void HUD_render_2d(float frametime)
|
||||
}
|
||||
|
||||
if ( show_gauge_flag ) {
|
||||
hud_show_cmeasure_gague();
|
||||
hud_show_cmeasure_gauge();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3498,7 +3498,7 @@ void HUD_set_offsets(object *viewer_obj, int wiggedy_wack, matrix *eye_orient)
|
||||
|
||||
flags = g3_rotate_vertex(&pt,&tmp);
|
||||
|
||||
g3_project_vertex(&pt);
|
||||
g3_project_vertex(&pt);
|
||||
|
||||
gr_unsize_screen_posf( &pt.sx, &pt.sy );
|
||||
HUD_offset_x -= 0.45f * (i2fl(gr_screen.clip_width_unscaled)*0.5f - pt.sx);
|
||||
@@ -3538,8 +3538,8 @@ void HUD_get_nose_coordinates(int *x, int *y)
|
||||
vertex v0;
|
||||
vec3d p0;
|
||||
|
||||
int x_nose;
|
||||
int y_nose;
|
||||
float x_nose;
|
||||
float y_nose;
|
||||
|
||||
vm_vec_scale_add(&p0, &Player_obj->pos, &Player_obj->orient.vec.fvec, 100.0f);
|
||||
g3_rotate_vertex(&v0, &p0);
|
||||
@@ -3547,9 +3547,16 @@ void HUD_get_nose_coordinates(int *x, int *y)
|
||||
if (v0.codes == 0) {
|
||||
g3_project_vertex(&v0);
|
||||
|
||||
if (! (v0.codes & PF_OVERFLOW)) {
|
||||
x_nose = fl2i(v0.sx);
|
||||
y_nose = fl2i(v0.sy);
|
||||
if ( !(v0.codes & PF_OVERFLOW) ) {
|
||||
x_nose = v0.sx;
|
||||
y_nose = v0.sy;
|
||||
} else {
|
||||
// Means that the ship forward vector is not going through the frame buffer.
|
||||
// We're assigning a high negative value so that the the bitmaps will be drawn offscreen so that
|
||||
// we can give the illusion that the player is looking away from the slewable HUD reticle.
|
||||
*x = -100000;
|
||||
*y = -100000;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Means that the ship forward vector is not going through the frame buffer.
|
||||
@@ -3560,8 +3567,8 @@ void HUD_get_nose_coordinates(int *x, int *y)
|
||||
return;
|
||||
}
|
||||
|
||||
*x = x_nose - SCREEN_CENTER_X;
|
||||
*y = y_nose - SCREEN_CENTER_Y;
|
||||
*x = fl2i(x_nose - gr_screen.clip_center_x);
|
||||
*y = fl2i(y_nose - gr_screen.clip_center_y);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -338,9 +338,6 @@
|
||||
#include "graphics/2d.h"
|
||||
#include "hud/hudparse.h"
|
||||
|
||||
#define SCREEN_CENTER_X ((gr_screen.clip_left + gr_screen.clip_right) / 2.0f)
|
||||
#define SCREEN_CENTER_Y ((gr_screen.clip_top + gr_screen.clip_bottom) / 2.0f)
|
||||
|
||||
struct object;
|
||||
|
||||
typedef struct hud_anim {
|
||||
@@ -358,6 +355,7 @@ typedef struct hud_frames {
|
||||
int num_frames;
|
||||
} hud_frames;
|
||||
|
||||
extern int HUD_draw;
|
||||
extern int HUD_contrast;
|
||||
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@ void ssm_level_init()
|
||||
}
|
||||
|
||||
// start a subspace missile effect
|
||||
void ssm_create(vec3d *target, vec3d *start, int ssm_index, ssm_firing_info *override)
|
||||
void ssm_create(object *target, vec3d *start, int ssm_index, ssm_firing_info *override, int team)
|
||||
{
|
||||
ssm_strike *ssm;
|
||||
matrix dir;
|
||||
@@ -280,13 +280,17 @@ void ssm_create(vec3d *target, vec3d *start, int ssm_index, ssm_firing_info *ove
|
||||
else {
|
||||
// forward orientation
|
||||
vec3d temp;
|
||||
vm_vec_sub(&temp, target, start);
|
||||
vm_vec_normalize(&temp);
|
||||
|
||||
vm_vec_sub(&temp, &target->pos, 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.target = target;
|
||||
ssm->sinfo.ssm_team = team;
|
||||
|
||||
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);
|
||||
@@ -326,6 +330,7 @@ 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);
|
||||
@@ -351,12 +356,16 @@ void ssm_process()
|
||||
vec3d temp;
|
||||
matrix orient;
|
||||
|
||||
vm_vec_sub(&temp, &moveup->sinfo.target, &moveup->sinfo.start_pos[idx]);
|
||||
vm_vec_sub(&temp, &moveup->sinfo.target->pos, &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_create(&moveup->sinfo.start_pos[idx], &orient, si->weapon_info_index, -1, -1, 1);
|
||||
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;
|
||||
|
||||
// this makes this particular missile done
|
||||
moveup->done_flags[idx] = 1;
|
||||
@@ -368,7 +377,7 @@ void ssm_process()
|
||||
vec3d temp;
|
||||
matrix orient;
|
||||
|
||||
vm_vec_sub(&temp, &moveup->sinfo.target, &moveup->sinfo.start_pos[idx]);
|
||||
vm_vec_sub(&temp, &moveup->sinfo.target->pos, &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);
|
||||
|
||||
@@ -82,11 +82,12 @@ 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
|
||||
vec3d target; // target for the strike
|
||||
int ssm_index; // index info ssm_info array
|
||||
struct object* target; // target for the strike
|
||||
int ssm_team; // team that fired the ssm.
|
||||
} ssm_firing_info;
|
||||
|
||||
// the strike itself
|
||||
@@ -119,7 +120,7 @@ void hud_artillery_update();
|
||||
void hud_artillery_render();
|
||||
|
||||
// start a subspace missile effect
|
||||
void ssm_create(vec3d *target, vec3d *start, int ssm_index, ssm_firing_info *override);
|
||||
void ssm_create(object *target, vec3d *start, int ssm_index, ssm_firing_info *override, int team);
|
||||
|
||||
// Goober5000
|
||||
extern int ssm_info_lookup(char *name);
|
||||
|
||||
@@ -753,7 +753,7 @@ void draw_bounding_brackets(int x1, int y1, int x2, int y2, int w_correction, in
|
||||
( y1 > gr_screen.clip_height && y2 > gr_screen.clip_height ) )
|
||||
return;
|
||||
|
||||
// *** everything blow is taken care of with this unsize ***
|
||||
// *** everything below is taken care of with this unsize ***
|
||||
gr_unsize_screen_pos(&x1, &y1);
|
||||
gr_unsize_screen_pos(&x2, &y2);
|
||||
|
||||
@@ -837,23 +837,24 @@ void draw_bounding_brackets(int x1, int y1, int x2, int y2, int w_correction, in
|
||||
object* t_objp = &Objects[target_objnum];
|
||||
char* tinfo_name = NULL;
|
||||
char* tinfo_class = NULL;
|
||||
char temp[NAME_LENGTH];
|
||||
char buffer[NAME_LENGTH];
|
||||
char empty='\0';
|
||||
|
||||
switch(t_objp->type)
|
||||
{
|
||||
case OBJ_SHIP:
|
||||
if ( Cmdline_wcsaga &&
|
||||
(Ships[t_objp->instance].wingnum >= 0) &&
|
||||
(iff_x_attacks_y(Player_ship->team, Ships[t_objp->instance].team)) )
|
||||
{
|
||||
// if ( Cmdline_wcsaga &&
|
||||
// (Ships[t_objp->instance].wingnum >= 0) &&
|
||||
// (iff_x_attacks_y(Player_ship->team, Ships[t_objp->instance].team)) )
|
||||
// Backslash - Instead of rely on command line, let's use a flag in Iff_defs.tbl
|
||||
if ( (Iff_info[Ships[t_objp->instance].team].flags & IFFF_WING_NAME_HIDDEN) && (Ships[t_objp->instance].wingnum != -1) ) {
|
||||
tinfo_name = ∅
|
||||
} else {
|
||||
strcpy(temp, Ships[t_objp->instance].ship_name);
|
||||
end_string_at_first_hash_symbol(temp);
|
||||
tinfo_name = temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
tinfo_name = Ships[t_objp->instance].ship_name;
|
||||
}
|
||||
|
||||
|
||||
tinfo_class = Ship_info[Ships[t_objp->instance].ship_info_index].name;
|
||||
|
||||
@@ -862,9 +863,8 @@ void draw_bounding_brackets(int x1, int y1, int x2, int y2, int w_correction, in
|
||||
mission_parse_lookup_alt_index(Ships[t_objp->instance].alt_type_index, buffer);
|
||||
} else {
|
||||
strcpy(buffer, Ship_info[Ships[t_objp->instance].ship_info_index].name);
|
||||
end_string_at_first_hash_symbol(buffer);
|
||||
}
|
||||
|
||||
end_string_at_first_hash_symbol(buffer);
|
||||
tinfo_class = buffer;
|
||||
|
||||
break;
|
||||
|
||||
@@ -820,7 +820,6 @@ void hud_do_lock_indicator(float frametime)
|
||||
object *tobjp = &Objects[Player_ai->target_objnum];
|
||||
vec3d dir_to_target;
|
||||
vm_vec_normalized_dir(&dir_to_target, &tobjp->pos, &Player_obj->pos);
|
||||
float dot_target_orient = vm_vec_dot(&tobjp->orient.vec.fvec, &dir_to_target);
|
||||
|
||||
if ( !(wip->wi_flags & WIF_LOCKED_HOMING) ) {
|
||||
hud_lock_reset();
|
||||
@@ -1223,20 +1222,20 @@ void hud_calculate_lock_start_pos()
|
||||
double delta_x;
|
||||
double target_mag, target_x, target_y;
|
||||
|
||||
delta_x = Player->current_target_sx - SCREEN_CENTER_X;
|
||||
delta_y = Player->current_target_sy - SCREEN_CENTER_Y;
|
||||
delta_x = Player->current_target_sx - gr_screen.clip_center_x;
|
||||
delta_y = Player->current_target_sy - gr_screen.clip_center_y;
|
||||
|
||||
if (!delta_x && !delta_y) {
|
||||
Players[Player_num].lock_indicator_start_x = fl2i(SCREEN_CENTER_X + Lock_start_dist);
|
||||
Players[Player_num].lock_indicator_start_y = fl2i(SCREEN_CENTER_Y);
|
||||
if ( (delta_x == 0.0) && (delta_y == 0.0) ) {
|
||||
Players[Player_num].lock_indicator_start_x = fl2i(gr_screen.clip_center_x + Lock_start_dist);
|
||||
Players[Player_num].lock_indicator_start_y = fl2i(gr_screen.clip_center_y);
|
||||
return;
|
||||
}
|
||||
|
||||
hypotenuse = _hypot(delta_y, delta_x);
|
||||
|
||||
if (hypotenuse >= Lock_start_dist) {
|
||||
Players[Player_num].lock_indicator_start_x = fl2i(SCREEN_CENTER_X);
|
||||
Players[Player_num].lock_indicator_start_y = fl2i(SCREEN_CENTER_Y);
|
||||
Players[Player_num].lock_indicator_start_x = fl2i(gr_screen.clip_center_x);
|
||||
Players[Player_num].lock_indicator_start_y = fl2i(gr_screen.clip_center_y);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1244,20 +1243,11 @@ void hud_calculate_lock_start_pos()
|
||||
target_x = target_mag * (delta_x / hypotenuse);
|
||||
target_y = target_mag * (delta_y / hypotenuse);
|
||||
|
||||
Players[Player_num].lock_indicator_start_x = fl2i(SCREEN_CENTER_X - target_x);
|
||||
Players[Player_num].lock_indicator_start_y = fl2i(SCREEN_CENTER_Y - target_y);
|
||||
Players[Player_num].lock_indicator_start_x = fl2i(gr_screen.clip_center_x - target_x);
|
||||
Players[Player_num].lock_indicator_start_y = fl2i(gr_screen.clip_center_y - target_y);
|
||||
|
||||
if (Players[Player_num].lock_indicator_start_x > gr_screen.clip_right)
|
||||
Players[Player_num].lock_indicator_start_x = gr_screen.clip_right;
|
||||
|
||||
if (Players[Player_num].lock_indicator_start_y > gr_screen.clip_bottom)
|
||||
Players[Player_num].lock_indicator_start_y = gr_screen.clip_bottom;
|
||||
|
||||
if (Players[Player_num].lock_indicator_start_x < gr_screen.clip_left)
|
||||
Players[Player_num].lock_indicator_start_x = gr_screen.clip_left;
|
||||
|
||||
if (Players[Player_num].lock_indicator_start_y < gr_screen.clip_top)
|
||||
Players[Player_num].lock_indicator_start_y = gr_screen.clip_top;
|
||||
CLAMP(Players[Player_num].lock_indicator_start_x, gr_screen.clip_left, gr_screen.clip_right);
|
||||
CLAMP(Players[Player_num].lock_indicator_start_y, gr_screen.clip_top, gr_screen.clip_bottom);
|
||||
}
|
||||
|
||||
// hud_stop_looped_locking_sounds() will terminate any hud related looping sounds that are playing
|
||||
@@ -1421,8 +1411,8 @@ void hud_lock_determine_lock_point(vec3d *lock_world_pos_out)
|
||||
if ( lock_local_pos.xyz.z > 0.0f ) {
|
||||
// Get the location of our target in the "virtual frame" where the locking computation will be done
|
||||
float w = 1.0f / lock_local_pos.xyz.z;
|
||||
float sx = ((SCREEN_CENTER_X*2) + (lock_local_pos.xyz.x*(SCREEN_CENTER_X*2)*w))*0.5f;
|
||||
float sy = ((SCREEN_CENTER_Y*2) - (lock_local_pos.xyz.y*(SCREEN_CENTER_Y*2)*w))*0.5f;
|
||||
float sx = ((gr_screen.clip_center_x*2.0f) + (lock_local_pos.xyz.x*(gr_screen.clip_center_x*2.0f)*w))*0.5f;
|
||||
float sy = ((gr_screen.clip_center_y*2.0f) - (lock_local_pos.xyz.y*(gr_screen.clip_center_y*2.0f)*w))*0.5f;
|
||||
|
||||
Player->current_target_sx = (int)sx;
|
||||
Player->current_target_sy = (int)sy;
|
||||
|
||||
@@ -552,7 +552,7 @@ void hud_shield_show(object *objp)
|
||||
sip = &Ship_info[sp->ship_info_index];
|
||||
|
||||
// bool digitus_improbus = (fod_model != -2 && strstr(sp->ship_name, "Sathanas") != NULL);
|
||||
if ( sip->shield_icon_index == 255 && !(sip->flags & SIF2_GENERATE_HUD_ICON) /*&& !digitus_improbus*/) {
|
||||
if ( sip->shield_icon_index == 255 && !(sip->flags2 & SIF2_GENERATE_HUD_ICON) /*&& !digitus_improbus*/) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 > 1 ) {
|
||||
if ( Wings[i].current_count > 0 ) {
|
||||
if ( hud_squadmsg_send_wing_command(i, command, send_message, player_num) ) {
|
||||
send_message = 0;
|
||||
}
|
||||
|
||||
@@ -1094,7 +1094,7 @@ typedef struct homing_beep_info
|
||||
float precalced_interp; // a precalculated value used in a linear interpretation
|
||||
} homing_beep_info;
|
||||
|
||||
homing_beep_info Homing_beep = { -1, 0, 150, 1000, 30.0f, 1500.0f };
|
||||
homing_beep_info Homing_beep = { -1, 0, 150, 1000, 30.0f, 1500.0f, 1.729412f };
|
||||
|
||||
// Set at the start of a mission, used to decide how to draw the separation for the warning missile indicators
|
||||
float Min_warning_missile_dist;
|
||||
@@ -4449,7 +4449,7 @@ int hud_get_best_primary_bank(float *range)
|
||||
//
|
||||
// Called by the draw lead indicator code to predict where the enemy is going to be
|
||||
//
|
||||
void polish_predicted_target_pos(object *targetp, vec3d *enemy_pos, vec3d *predicted_enemy_pos, float dist_to_enemy, vec3d *last_delta_vec, int num_polish_steps)
|
||||
void polish_predicted_target_pos(weapon_info *wip, object *targetp, vec3d *enemy_pos, vec3d *predicted_enemy_pos, float dist_to_enemy, vec3d *last_delta_vec, int num_polish_steps)
|
||||
{
|
||||
int iteration;
|
||||
vec3d player_pos = Player_obj->pos;
|
||||
@@ -4458,8 +4458,8 @@ void polish_predicted_target_pos(object *targetp, vec3d *enemy_pos, vec3d *predi
|
||||
|
||||
ship *shipp;
|
||||
shipp = &Ships[Player_obj->instance];
|
||||
Assert(shipp->weapons.current_primary_bank < shipp->weapons.num_primary_banks);
|
||||
weapon_info *wip = &Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]];
|
||||
// Assert(shipp->weapons.current_primary_bank < shipp->weapons.num_primary_banks);
|
||||
// weapon_info *wip = &Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]];
|
||||
|
||||
float weapon_speed = wip->max_speed;
|
||||
|
||||
@@ -4598,12 +4598,9 @@ void hud_show_lead_indicator(vec3d *target_world_pos)
|
||||
{
|
||||
int bank = swp->current_secondary_bank;
|
||||
tmp = &Weapon_info[swp->secondary_bank_weapons[bank]];
|
||||
if ( tmp->wi_flags & WIF_LOCKED_HOMING )
|
||||
{
|
||||
if ( !Player->target_in_lock_cone )
|
||||
{
|
||||
srange = -1.0f;
|
||||
}
|
||||
if ( !(tmp->wi_flags & WIF_HOMING) && !(tmp->wi_flags & WIF_LOCKED_HOMING && Player->target_in_lock_cone) ) {
|
||||
//The secondary lead indicator is handled farther below if it is a non-locking type
|
||||
srange = -1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4660,14 +4657,17 @@ 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(&targetp->phys_info.vel) < 0.1f) // Find distance!
|
||||
if ( vm_vec_mag_quick(&target_moving_direction) < 0.1f ) // Find distance!
|
||||
Players[Player_num].lead_target_pos = *target_world_pos;
|
||||
else {
|
||||
vm_vec_normalize(&target_moving_direction);
|
||||
vm_vec_scale(&target_moving_direction,target_moved_dist);
|
||||
vm_vec_add(&Players[Player_num].lead_target_pos, target_world_pos, &target_moving_direction );
|
||||
polish_predicted_target_pos(targetp, target_world_pos, &Players[Player_num].lead_target_pos, dist_to_target, &last_delta_vector, 1); // Not used:, float time_to_enemy)
|
||||
polish_predicted_target_pos(wip, targetp, target_world_pos, &Players[Player_num].lead_target_pos, dist_to_target, &last_delta_vector, 1); // Not used:, float time_to_enemy)
|
||||
}
|
||||
|
||||
g3_rotate_vertex(&lead_target_vertex,&Players[Player_num].lead_target_pos);
|
||||
@@ -4729,14 +4729,17 @@ 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(&targetp->phys_info.vel) < 0.1f) // Find distance!
|
||||
if ( vm_vec_mag_quick(&target_moving_direction) < 0.1f ) // Find distance!
|
||||
Players[Player_num].lead_target_pos = *target_world_pos;
|
||||
else {
|
||||
vm_vec_normalize(&target_moving_direction);
|
||||
vm_vec_scale(&target_moving_direction,target_moved_dist);
|
||||
vm_vec_add(&Players[Player_num].lead_target_pos, target_world_pos, &target_moving_direction );
|
||||
polish_predicted_target_pos(targetp, target_world_pos, &Players[Player_num].lead_target_pos, dist_to_target, &last_delta_vector, 1); // Not used:, float time_to_enemy)
|
||||
polish_predicted_target_pos(wip, targetp, target_world_pos, &Players[Player_num].lead_target_pos, dist_to_target, &last_delta_vector, 1); // Not used:, float time_to_enemy)
|
||||
}
|
||||
|
||||
g3_rotate_vertex(&lead_target_vertex,&Players[Player_num].lead_target_pos);
|
||||
@@ -4778,7 +4781,6 @@ void hud_show_lead_indicator_quick(vec3d *target_world_pos, object *targetp)
|
||||
polymodel *pm;
|
||||
ship_weapon *swp;
|
||||
weapon_info *wip;
|
||||
weapon_info *tmp=NULL;
|
||||
float dist_to_target, time_to_target, target_moved_dist, prange;
|
||||
int bank_to_fire, indicator_frame, frame_offset;
|
||||
float sx, sy;
|
||||
@@ -4860,14 +4862,17 @@ 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(&targetp->phys_info.vel) < 0.1f) // Find distance!
|
||||
if ( vm_vec_mag_quick(&target_moving_direction) < 0.1f ) // Find distance!
|
||||
Players[Player_num].lead_target_pos = *target_world_pos;
|
||||
else {
|
||||
vm_vec_normalize(&target_moving_direction);
|
||||
vm_vec_scale(&target_moving_direction,target_moved_dist);
|
||||
vm_vec_add(&Players[Player_num].lead_target_pos, target_world_pos, &target_moving_direction );
|
||||
polish_predicted_target_pos(targetp, target_world_pos, &Players[Player_num].lead_target_pos, dist_to_target, &last_delta_vector, 1); // Not used:, float time_to_enemy)
|
||||
polish_predicted_target_pos(wip, targetp, target_world_pos, &Players[Player_num].lead_target_pos, dist_to_target, &last_delta_vector, 1); // Not used:, float time_to_enemy)
|
||||
vm_vec_add2(&Players[Player_num].lead_target_pos, rel_pos );
|
||||
}
|
||||
|
||||
@@ -5079,7 +5084,7 @@ void hud_target_change_check()
|
||||
//
|
||||
// draws the offscreen target indicator
|
||||
//
|
||||
void hud_draw_offscreen_indicator(vertex* target_point, vec3d *tpos, float distance)
|
||||
void hud_draw_offscreen_indicator(vertex* target_point, vec3d *tpos, float distance, int draw_solid)
|
||||
{
|
||||
char buf[32];
|
||||
int w = 0, h = 0;
|
||||
@@ -5327,8 +5332,13 @@ void hud_draw_offscreen_indicator(vertex* target_point, vec3d *tpos, float dista
|
||||
}
|
||||
}
|
||||
|
||||
hud_tri(x3,y3,x2,y2,x1,y1);
|
||||
hud_tri(x4,y4,x5,y5,x6,y6);
|
||||
if (draw_solid) {
|
||||
hud_tri(x3,y3,x2,y2,x1,y1);
|
||||
hud_tri(x4,y4,x5,y5,x6,y6);
|
||||
} else {
|
||||
hud_tri_empty(x3,y3,x2,y2,x1,y1);
|
||||
hud_tri_empty(x4,y4,x5,y5,x6,y6);
|
||||
}
|
||||
if (on_right || on_bottom){
|
||||
gr_line(fl2i(x2),fl2i(y2),fl2i(x5),fl2i(y5));
|
||||
} else if (on_left) {
|
||||
@@ -5631,7 +5641,7 @@ void hud_maybe_flash_weapon(int index)
|
||||
}
|
||||
|
||||
// render the coutermeasure HUD gauge
|
||||
void hud_show_cmeasure_gague()
|
||||
void hud_show_cmeasure_gauge()
|
||||
{
|
||||
if ( Cmeasure_gauge.first_frame == -1) {
|
||||
Int3(); // failed to load coutermeasure gauge background
|
||||
|
||||
@@ -329,6 +329,7 @@
|
||||
struct ship;
|
||||
struct ship_subsys;
|
||||
struct object;
|
||||
struct weapon_info;
|
||||
|
||||
#define INCREASING 0
|
||||
#define DECREASING 1
|
||||
@@ -344,7 +345,7 @@ struct object;
|
||||
// structure and defines used for hotkey targeting
|
||||
//WMC - bumped from 50 to 150; 10/24/2005
|
||||
#define MAX_HOTKEY_TARGET_ITEMS 150 // maximum number of ships that can be targeted on *all* keys
|
||||
#define SELECTION_SET 0x5000 // variable used for drawing brackets. The bracketinng code uses
|
||||
#define SELECTION_SET 0x5000 // variable used for drawing brackets. The bracketing code uses
|
||||
// TEAM_* values. I picked this value to be totally out of that
|
||||
// range. Only used for drawing selection sets
|
||||
#define MESSAGE_SENDER 0x5001 // variable used for drawing brackets around a message sender.
|
||||
@@ -391,7 +392,7 @@ void hud_target_missile(object *source_obj, int next_flag);
|
||||
void hud_target_next_list(int hostile=1, int next_flag=1);
|
||||
int hud_target_closest_repair_ship(int goal_objnum=-1);
|
||||
void hud_target_auto_target_next();
|
||||
void hud_show_remote_detonate_missile();
|
||||
void hud_show_remote_detonate_missile();
|
||||
|
||||
void hud_target_uninspected_object(int next_flag);
|
||||
void hud_target_newest_ship();
|
||||
@@ -423,9 +424,9 @@ void hud_show_weapons();
|
||||
void hud_start_flash_weapon(int index);
|
||||
void hud_show_auto_icons();
|
||||
void hud_show_weapon_energy_gauge();
|
||||
void hud_show_cmeasure_gague();
|
||||
void hud_show_cmeasure_gauge();
|
||||
void hud_show_brackets(object *targetp, vertex *projected_v);
|
||||
void hud_draw_offscreen_indicator(vertex* target_point, vec3d *tpos, float distance=0.0f);
|
||||
void hud_draw_offscreen_indicator(vertex* target_point, vec3d *tpos, float distance=0.0f, int draw_solid=1);
|
||||
void hud_show_homing_missiles(void);
|
||||
|
||||
int hud_sensors_ok(ship *sp, int show_msg = 1);
|
||||
@@ -454,6 +455,6 @@ void hud_tri_empty(float x1,float y1,float x2,float y2,float x3,float y3);
|
||||
|
||||
float hud_find_target_distance( object *targetee, object *targeter );
|
||||
|
||||
extern void polish_predicted_target_pos(object *targetp, vec3d *enemy_pos, vec3d *predicted_enemy_pos, float dist_to_enemy, vec3d *last_delta_vec, int num_polish_steps);
|
||||
extern void polish_predicted_target_pos(weapon_info *wip, object *targetp, vec3d *enemy_pos, vec3d *predicted_enemy_pos, float dist_to_enemy, vec3d *last_delta_vec, int num_polish_steps);
|
||||
|
||||
#endif
|
||||
@@ -952,7 +952,8 @@ void hud_targetbox_show_extra_ship_info(ship *target_shipp, object *target_objp)
|
||||
if ( not_training && (hud_gauge_active(HUD_TARGET_MONITOR_EXTRA_DATA)) && (Targetbox_show_extra_info) ) {
|
||||
// Print out current orders if the targeted ship is friendly
|
||||
// AL 12-26-97: only show orders and time to target for friendly ships
|
||||
if ( (Player_ship->team == target_shipp->team) && !(ship_get_SIF(target_shipp) & SIF_NOT_FLYABLE) ) {
|
||||
// Backslash: actually let's consult the IFF table. Maybe we want to show orders for certain teams, or hide orders for friendlies
|
||||
if ( ((Player_ship->team == target_shipp->team) || ((Iff_info[target_shipp->team].flags & IFFF_ORDERS_SHOWN) && !(Iff_info[target_shipp->team].flags & IFFF_ORDERS_HIDDEN)) ) && !(ship_get_SIF(target_shipp) & SIF_NOT_FLYABLE) ) {
|
||||
extra_data_shown=1;
|
||||
if ( ship_return_orders(outstr, target_shipp) ) {
|
||||
gr_force_fit_string(outstr, 255, 162);
|
||||
@@ -984,6 +985,7 @@ 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
|
||||
@@ -1050,6 +1052,9 @@ void hud_render_target_jump_node(object *target_objp)
|
||||
emp_hud_string(Targetbox_coords[gr_screen.res][TBOX_NAME][0], Targetbox_coords[gr_screen.res][TBOX_NAME][1], EG_TBOX_NAME, target_objp->jnp->get_name_ptr());
|
||||
|
||||
dist = vm_vec_dist_quick(&target_objp->pos, &Player_obj->pos);
|
||||
if ( Hud_unit_multiplier > 0.0f ) { // use a different displayed distance scale
|
||||
dist = dist * Hud_unit_multiplier;
|
||||
}
|
||||
|
||||
// account for hud shaking
|
||||
hx = fl2i(HUD_offset_x);
|
||||
@@ -1218,15 +1223,15 @@ void hud_render_target_ship_info(object *target_objp)
|
||||
target_shipp = &Ships[target_objp->instance];
|
||||
target_sip = &Ship_info[target_shipp->ship_info_index];
|
||||
|
||||
if (Cmdline_wcsaga &&
|
||||
(target_shipp->wingnum != -1) &&
|
||||
(target_shipp->team != Player_ship->team))
|
||||
{
|
||||
// if (Cmdline_wcsaga &&
|
||||
// (target_shipp->wingnum != -1) &&
|
||||
// (target_shipp->team != Player_ship->team))
|
||||
// Backslash - Instead of rely on command line, let's use a flag in Iff_defs.tbl
|
||||
if ( (Iff_info[target_shipp->team].flags & IFFF_WING_NAME_HIDDEN) && (target_shipp->wingnum != -1) ) {
|
||||
strcpy( outstr, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
strcpy( outstr, target_shipp->ship_name );
|
||||
end_string_at_first_hash_symbol(outstr);
|
||||
}
|
||||
|
||||
if ( hud_gauge_maybe_flash(HUD_TARGET_MONITOR) == 1 ) {
|
||||
@@ -1250,12 +1255,12 @@ void hud_render_target_ship_info(object *target_objp)
|
||||
char temp_name[NAME_LENGTH+2] = "";
|
||||
|
||||
// if this ship has an alternate type name
|
||||
if(target_shipp->alt_type_index >= 0){
|
||||
if (target_shipp->alt_type_index >= 0) {
|
||||
mission_parse_lookup_alt_index(target_shipp->alt_type_index, temp_name);
|
||||
} else {
|
||||
strcpy(temp_name, Ship_info[target_shipp->ship_info_index].name);
|
||||
end_string_at_first_hash_symbol(temp_name);
|
||||
strcpy(temp_name, Ship_info[target_shipp->ship_info_index].name);
|
||||
}
|
||||
end_string_at_first_hash_symbol(temp_name);
|
||||
|
||||
if (Lcl_gr) {
|
||||
lcl_translate_targetbox_name(temp_name);
|
||||
@@ -1421,7 +1426,7 @@ void hud_blit_target_integrity(int disabled,int force_obj_num)
|
||||
}
|
||||
}
|
||||
|
||||
// determine if the subsystem is in line-of sight, without taking into accout whether the player ship is
|
||||
// determine if the subsystem is in line-of sight, without taking into account whether the player ship is
|
||||
// facing the subsystem
|
||||
int hud_targetbox_subsystem_in_view(object *target_objp, int *sx, int *sy)
|
||||
{
|
||||
|
||||
@@ -268,6 +268,12 @@ void iff_init()
|
||||
iff->flags |= IFFF_SUPPORT_ALLOWED;
|
||||
else if (!stricmp(NOX("exempt from all teams at war"), flag_strings[i]))
|
||||
iff->flags |= IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR;
|
||||
else if (!stricmp(NOX("orders hidden"), flag_strings[i]))
|
||||
iff->flags |= IFFF_ORDERS_HIDDEN;
|
||||
else if (!stricmp(NOX("orders shown"), flag_strings[i]))
|
||||
iff->flags |= IFFF_ORDERS_SHOWN;
|
||||
else if (!stricmp(NOX("wing name hidden"), flag_strings[i]))
|
||||
iff->flags |= IFFF_WING_NAME_HIDDEN;
|
||||
else
|
||||
Warning(LOCATION, "Bogus string in iff flags: %s\n", flag_strings[i]);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,10 @@
|
||||
// iff flags
|
||||
#define IFFF_SUPPORT_ALLOWED (1 << 0) // this IFF can call for support
|
||||
#define IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR (1 << 1) // self-explanatory
|
||||
#define MAX_IFF_FLAGS 2
|
||||
#define IFFF_ORDERS_HIDDEN (1 << 2) // the HUD will not show a targeted ship's orders
|
||||
#define IFFF_ORDERS_SHOWN (1 << 3) // the HUD will show a targeted ship's orders (friendly has by default)
|
||||
#define IFFF_WING_NAME_HIDDEN (1 << 4) // the HUD will not show a targeted ship's name if it is in a wing
|
||||
#define MAX_IFF_FLAGS 5
|
||||
|
||||
// Goober5000
|
||||
typedef struct iff_info {
|
||||
|
||||
@@ -661,9 +661,13 @@ float key_down_timef(uint scancode)
|
||||
uint time_down, time;
|
||||
uint delta_time;
|
||||
|
||||
if ( !key_inited ) return 0.0f;
|
||||
if ( !key_inited ) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if ((scancode<0)|| (scancode>=NUM_KEYS)) return 0.0f;
|
||||
if (scancode >= NUM_KEYS) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
ENTER_CRITICAL_SECTION( key_lock );
|
||||
|
||||
|
||||
@@ -2354,7 +2354,49 @@ int button_function_critical(int n, net_player *p = NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (n) {
|
||||
switch (n) {
|
||||
// cycle to next primary weapon
|
||||
case CYCLE_NEXT_PRIMARY:
|
||||
if (at_self) {
|
||||
control_used(CYCLE_NEXT_PRIMARY);
|
||||
}
|
||||
|
||||
hud_gauge_popup_start(HUD_WEAPONS_GAUGE);
|
||||
if (ship_select_next_primary(Player_obj, CYCLE_PRIMARY_NEXT)) {
|
||||
ship* shipp = &Ships[objp->instance];
|
||||
if ( timestamp_elapsed(shipp->weapons.next_primary_fire_stamp[shipp->weapons.current_primary_bank]) ) {
|
||||
shipp->weapons.next_primary_fire_stamp[shipp->weapons.current_primary_bank] = timestamp(250); // 1/4 second delay until can fire
|
||||
}
|
||||
|
||||
// multiplayer server should maintain bank/link status here
|
||||
if ( (Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER) ) {
|
||||
Assert(npl != NULL);
|
||||
multi_server_update_player_weapons(npl,shipp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// cycle to previous primary weapon
|
||||
case CYCLE_PREV_PRIMARY:
|
||||
if (at_self) {
|
||||
control_used(CYCLE_PREV_PRIMARY);
|
||||
}
|
||||
|
||||
hud_gauge_popup_start(HUD_WEAPONS_GAUGE);
|
||||
if (ship_select_next_primary(objp, CYCLE_PRIMARY_PREV)) {
|
||||
ship* shipp = &Ships[objp->instance];
|
||||
if ( timestamp_elapsed(shipp->weapons.next_primary_fire_stamp[shipp->weapons.current_primary_bank]) ) {
|
||||
shipp->weapons.next_primary_fire_stamp[shipp->weapons.current_primary_bank] = timestamp(250); // 1/4 second delay until can fire
|
||||
}
|
||||
|
||||
// multiplayer server should maintain bank/link status here
|
||||
if ( (Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER) ) {
|
||||
Assert(npl != NULL);
|
||||
multi_server_update_player_weapons(npl,shipp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// cycle to next secondary weapon
|
||||
case CYCLE_SECONDARY:
|
||||
if(at_self)
|
||||
@@ -2821,41 +2863,12 @@ int button_function(int n)
|
||||
switch (n) {
|
||||
// cycle to next primary weapon
|
||||
case CYCLE_NEXT_PRIMARY:
|
||||
// bogus?
|
||||
if((Player_obj == NULL) || (Player_ship == NULL)){
|
||||
break;
|
||||
}
|
||||
|
||||
hud_gauge_popup_start(HUD_WEAPONS_GAUGE);
|
||||
if (ship_select_next_primary(Player_obj, CYCLE_PRIMARY_NEXT)) {
|
||||
ship* shipp = Player_ship;
|
||||
shipp->weapons.next_primary_fire_stamp[shipp->weapons.current_primary_bank] = timestamp(250); // 1/4 second delay until can fire
|
||||
// multiplayer server should maintain bank/link status here
|
||||
// if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
|
||||
// Assert(npl != NULL);
|
||||
// multi_server_update_player_weapons(npl,shipp);
|
||||
// }
|
||||
}
|
||||
return button_function_critical(CYCLE_NEXT_PRIMARY);
|
||||
break;
|
||||
|
||||
// cycle to previous primary weapon
|
||||
case CYCLE_PREV_PRIMARY:
|
||||
// bogus?
|
||||
if((Player_obj == NULL) || (Player_ship == NULL)){
|
||||
break;
|
||||
}
|
||||
|
||||
hud_gauge_popup_start(HUD_WEAPONS_GAUGE);
|
||||
if (ship_select_next_primary(Player_obj, CYCLE_PRIMARY_PREV)) {
|
||||
ship* shipp = Player_ship;
|
||||
shipp->weapons.next_primary_fire_stamp[shipp->weapons.current_primary_bank] = timestamp(250); // 1/4 second delay until can fire
|
||||
|
||||
// multiplayer server should maintain bank/link status here
|
||||
// if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
|
||||
// Assert(npl != NULL);
|
||||
// multi_server_update_player_weapons(npl,shipp);
|
||||
// }
|
||||
}
|
||||
return button_function_critical(CYCLE_PREV_PRIMARY);
|
||||
break;
|
||||
|
||||
// cycle to next secondary weapon
|
||||
|
||||
@@ -126,7 +126,7 @@ public:
|
||||
//Setting
|
||||
void set_alphacolor(int r, int g, int b, int alpha);
|
||||
void set_model(char *model_name, bool show_polys=false);
|
||||
void show(bool show){if(show){m_flags&=~JN_HIDE;}else{m_flags|=JN_HIDE;}}
|
||||
void show(bool enabled){if(enabled){m_flags&=~JN_HIDE;}else{m_flags|=JN_HIDE;}}
|
||||
|
||||
//Rendering
|
||||
void render(vec3d *pos, vec3d *view_pos = NULL);
|
||||
|
||||
@@ -233,6 +233,7 @@
|
||||
#include "globalincs/alphacolors.h"
|
||||
#include "weapon/beam.h"
|
||||
#include "iff_defs/iff_defs.h"
|
||||
#include "parse/parselo.h"
|
||||
|
||||
|
||||
static int Key_sets[MAX_KEYED_TARGETS] = {
|
||||
@@ -1464,6 +1465,7 @@ void mission_hotkey_do_frame(float frametime)
|
||||
|
||||
// draw ship/wing name
|
||||
strcpy(buf, Hotkey_lines[line].label);
|
||||
end_string_at_first_hash_symbol(buf);
|
||||
if (Hotkey_lines[line].type == HOTKEY_LINE_SUBSHIP) {
|
||||
// indent
|
||||
gr_force_fit_string(buf, 255, Hotkey_list_coords[gr_screen.res][0] + Hotkey_list_coords[gr_screen.res][2] - (Hotkey_ship_x[gr_screen.res]+20));
|
||||
|
||||
@@ -299,7 +299,7 @@ int mission_load(char *filename_ext)
|
||||
mprintf(("MISSION LOAD: '%s'\n", filename_ext));
|
||||
|
||||
strncpy(filename, filename_ext, 127);
|
||||
ext = strchr(filename, '.');
|
||||
ext = strrchr(filename, '.');
|
||||
if (ext) {
|
||||
mprintf(( "Hmmm... Extension passed to mission_load...\n" ));
|
||||
*ext = 0; // remove any extension!
|
||||
|
||||
@@ -1060,6 +1060,7 @@ void mission_log_scrollback(int line, int list_x, int list_y, int list_w, int li
|
||||
else
|
||||
gr_force_fit_string(buf, 256, list_w - seg->x);
|
||||
|
||||
end_string_at_first_hash_symbol(buf);
|
||||
gr_string(list_x + seg->x, list_y + y, buf);
|
||||
|
||||
// possibly "print" some symbols for interesting log entries
|
||||
|
||||
@@ -796,7 +796,7 @@ char *Persona_type_names[MAX_PERSONA_TYPES] =
|
||||
//XSTR:ON
|
||||
};
|
||||
|
||||
int Command_persona;
|
||||
int Default_command_persona;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// used to distort incoming messages when comms are damaged
|
||||
@@ -870,10 +870,10 @@ void persona_parse()
|
||||
|
||||
Personas[Num_personas].flags |= (1<<i);
|
||||
|
||||
// save the Terran Command persona in a global
|
||||
// save the Command persona in a global
|
||||
if ( Personas[Num_personas].flags & PERSONA_FLAG_COMMAND ) {
|
||||
// Assert ( Command_persona == -1 );
|
||||
Command_persona = Num_personas;
|
||||
if (Default_command_persona < 0)
|
||||
Default_command_persona = Num_personas;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1091,7 +1091,7 @@ void messages_init()
|
||||
static int table_read = 0;
|
||||
|
||||
if ( !table_read ) {
|
||||
Command_persona = -1;
|
||||
Default_command_persona = -1;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "messages.tbl", rval));
|
||||
@@ -1604,7 +1604,7 @@ void message_play_anim( message_q *q )
|
||||
// attached to it. Deal with munging the name
|
||||
|
||||
// support ships use a wingman head.
|
||||
// terran command uses it's own set of heads.
|
||||
// terran command uses its own set of heads.
|
||||
int subhead_selected = FALSE;
|
||||
if ( (q->message_num < Num_builtin_messages) || !(_strnicmp(HEAD_PREFIX_STRING, ani_name, strlen(HEAD_PREFIX_STRING)-1)) ) {
|
||||
persona_index = m->persona_index;
|
||||
@@ -1612,7 +1612,7 @@ void message_play_anim( message_q *q )
|
||||
// if this ani should be converted to a terran command, set the persona to the command persona
|
||||
// so the correct head plays.
|
||||
if ( q->flags & MQF_CONVERT_TO_COMMAND ) {
|
||||
persona_index = Command_persona;
|
||||
persona_index = The_mission.command_persona;
|
||||
strcpy( ani_name, COMMAND_HEAD_PREFIX );
|
||||
}
|
||||
|
||||
@@ -1990,7 +1990,9 @@ 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 );
|
||||
|
||||
@@ -2071,7 +2073,7 @@ void message_queue_message( int message_num, int priority, int timing, char *who
|
||||
// to this message, then set a bit to tell the wave/anim playing code to play the command version
|
||||
// of the wave and head
|
||||
MessageQ[i].flags = 0;
|
||||
if ( !stricmp(who_from, TERRAN_COMMAND) && (m_persona != -1) && (Personas[m_persona].flags & PERSONA_FLAG_WINGMAN) ) {
|
||||
if ( !stricmp(who_from, The_mission.command_sender) && (m_persona != -1) && (Personas[m_persona].flags & PERSONA_FLAG_WINGMAN) ) {
|
||||
MessageQ[i].flags |= MQF_CONVERT_TO_COMMAND;
|
||||
MessageQ[i].source = HUD_SOURCE_TERRAN_CMD;
|
||||
}
|
||||
@@ -2239,7 +2241,7 @@ void message_send_unique_to_player( char *id, void *data, int m_source, int prio
|
||||
// if the ship is NULL and special_who is not NULL, then this is from special_who
|
||||
// otherwise, message is from ship.
|
||||
if ( m_source == MESSAGE_SOURCE_COMMAND ) {
|
||||
who_from = TERRAN_COMMAND;
|
||||
who_from = The_mission.command_sender;
|
||||
source = HUD_SOURCE_TERRAN_CMD;
|
||||
} else if ( m_source == MESSAGE_SOURCE_SPECIAL ) {
|
||||
who_from = (char *)data;
|
||||
@@ -2260,7 +2262,7 @@ void message_send_unique_to_player( char *id, void *data, int m_source, int prio
|
||||
|
||||
// if the ship_index is -1, then make the message come from Terran command
|
||||
if ( ship_index == -1 ) {
|
||||
who_from = TERRAN_COMMAND;
|
||||
who_from = The_mission.command_sender;
|
||||
source = HUD_SOURCE_TERRAN_CMD;
|
||||
} else {
|
||||
who_from = Ships[ship_index].ship_name;
|
||||
@@ -2335,7 +2337,7 @@ void message_send_builtin_to_player( int type, ship *shipp, int priority, int ti
|
||||
// be sure that this ship can actually send a message!!! (i.e. not-not-flyable -- get it!)
|
||||
Assert( !(Ship_info[shipp->ship_info_index].flags & SIF_NOT_FLYABLE) ); // get allender or alan
|
||||
} else {
|
||||
persona_index = Command_persona; // use the terran command persona
|
||||
persona_index = The_mission.command_persona; // use the terran command persona
|
||||
}
|
||||
|
||||
// try to find a builtin message with the given type for the given persona
|
||||
@@ -2359,17 +2361,23 @@ void message_send_builtin_to_player( int type, ship *shipp, int priority, int ti
|
||||
}
|
||||
|
||||
// get who this message is from -- kind of a hack since we assume Terran Command in the
|
||||
// absense of a ship. This will be fixed later
|
||||
// absence of a ship. This will be fixed later
|
||||
if ( shipp ) {
|
||||
source = HUD_team_get_source( shipp->team );
|
||||
who_from = shipp->ship_name;
|
||||
source = HUD_team_get_source( shipp->team );
|
||||
} else {
|
||||
source = HUD_SOURCE_TERRAN_CMD;
|
||||
who_from = TERRAN_COMMAND;
|
||||
who_from = The_mission.command_sender;
|
||||
|
||||
// Goober5000 - if Command is a ship that is present, change the source accordingly
|
||||
int shipnum = ship_name_lookup(who_from);
|
||||
if (shipnum >= 0)
|
||||
source = HUD_team_get_source( Ships[shipnum].team );
|
||||
else
|
||||
source = HUD_SOURCE_TERRAN_CMD;
|
||||
}
|
||||
|
||||
// maybe change the who from here for special rearm cases (always seems like that is the case :-) )
|
||||
if ( !stricmp(who_from, TERRAN_COMMAND) && (type == MESSAGE_REARM_ON_WAY) ){
|
||||
if ( !stricmp(who_from, The_mission.command_sender) && (type == MESSAGE_REARM_ON_WAY) ){
|
||||
who_from = SUPPORT_NAME;
|
||||
}
|
||||
|
||||
|
||||
@@ -268,7 +268,7 @@
|
||||
|
||||
struct ship;
|
||||
|
||||
#define MAX_MISSION_MESSAGES 500
|
||||
#define MAX_MISSION_MESSAGES 1000
|
||||
//Bumped to 500 from 300 06/15/2004 -C
|
||||
|
||||
// keep seperate lists of AVI's and wav files. I suspect that many messages will have
|
||||
@@ -306,7 +306,7 @@ extern message_extra Message_waves[MAX_MESSAGE_WAVES];
|
||||
#define MESSAGE_SOURCE_SPECIAL 4
|
||||
|
||||
// define used for sender of a message when you want it to be Terran Command
|
||||
#define TERRAN_COMMAND "Command"
|
||||
#define DEFAULT_COMMAND "Command"
|
||||
|
||||
// defines for message id's used in FreeSpace code. Callers to message_send_to_player() should
|
||||
// probably use these defines.
|
||||
@@ -408,6 +408,7 @@ typedef struct persona_s {
|
||||
|
||||
extern Persona *Personas;
|
||||
extern int Num_personas;
|
||||
extern int Default_command_persona;
|
||||
|
||||
// function to parse a message from either messages.tbl or the mission file. Both files have the
|
||||
// exact same format, so this function just gets reused in both instances.
|
||||
|
||||
@@ -1701,7 +1701,7 @@ void parse_mission_info(mission *pm, bool basic = false)
|
||||
//
|
||||
// NOTE: this can be dangerous so be sure that any get_mission_info() call (defaults to basic info) will
|
||||
// only reference data parsed before this point!! (like current FRED2 and game code does)
|
||||
if (basic == true)
|
||||
if (basic)
|
||||
return;
|
||||
|
||||
|
||||
@@ -1811,6 +1811,7 @@ void parse_mission_info(mission *pm, bool basic = false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// wing stuff by Goober5000 ------------------------------------------
|
||||
// the wing name arrays are initialized in ship_level_init
|
||||
if (optional_string("$Starting wing names:"))
|
||||
@@ -1835,6 +1836,7 @@ void parse_mission_info(mission *pm, bool basic = false)
|
||||
}
|
||||
// end of wing stuff -------------------------------------------------
|
||||
|
||||
|
||||
// set up the Num_teams variable accoriding to the game_type variable'
|
||||
Num_teams = 1; // assume 1
|
||||
|
||||
@@ -3811,10 +3813,28 @@ int parse_object(mission *pm, int flag, p_object *p_objp)
|
||||
if (optional_string("+Group:"))
|
||||
stuff_int(&p_objp->group);
|
||||
|
||||
if (optional_string("+Score:"))
|
||||
stuff_int(&p_objp->score);
|
||||
else
|
||||
bool table_score = false;
|
||||
if (optional_string("+Use Table Score:")) {
|
||||
table_score = true;
|
||||
}
|
||||
|
||||
if (optional_string("+Score:")) {
|
||||
if (!table_score) {
|
||||
stuff_int(&p_objp->score);
|
||||
}
|
||||
// throw away the value the mission file has and use the table value.
|
||||
else {
|
||||
int temp_score;
|
||||
stuff_int(&temp_score);
|
||||
}
|
||||
}
|
||||
else {
|
||||
table_score = true;
|
||||
}
|
||||
|
||||
if (table_score) {
|
||||
p_objp->score = Ship_info[p_objp->ship_class].score;
|
||||
}
|
||||
|
||||
// parse the persona index if present
|
||||
p_objp->persona_index = -1;
|
||||
@@ -4111,8 +4131,8 @@ void swap_parse_object(p_object *p_obj, int new_ship_class)
|
||||
Assert (p_obj->ship_max_hull_strength > 0);
|
||||
Assert (old_ship_info->max_hull_strength > 0);
|
||||
|
||||
float hp_multiplier = p_obj->ship_max_hull_strength / i2fl(old_ship_info->max_hull_strength);
|
||||
p_obj->ship_max_hull_strength = fl2i(new_ship_info->max_hull_strength * hp_multiplier);
|
||||
float hp_multiplier = p_obj->ship_max_hull_strength / old_ship_info->max_hull_strength;
|
||||
p_obj->ship_max_hull_strength = new_ship_info->max_hull_strength * hp_multiplier;
|
||||
|
||||
|
||||
// Shields
|
||||
@@ -4383,6 +4403,8 @@ int parse_wing_create_ships( wing *wingp, int num_to_create, int force, int spec
|
||||
if (p_objp->wingnum != wingnum)
|
||||
continue;
|
||||
|
||||
Assert( (p_objp->pos_in_wing >= 0) && (p_objp->pos_in_wing < MAX_SHIPS_PER_WING) );
|
||||
|
||||
// when ingame joining, we need to create a specific ship out of the list of ships for a
|
||||
// wing. specific_instance is a 0 based integer which specified which ship in the wing
|
||||
// to create. So, only create the ship we actually need to.
|
||||
@@ -4434,16 +4456,17 @@ int parse_wing_create_ships( wing *wingp, int num_to_create, int force, int spec
|
||||
aip->ai_flags |= AIF_NO_DYNAMIC;
|
||||
|
||||
// update housekeeping variables
|
||||
wingp->ship_index[wingp->current_count] = Objects[objnum].instance;
|
||||
|
||||
// since wing order and object order aren't necessarily the same thing
|
||||
// be sure to reset the special ship to the correct ship_index[] offset
|
||||
if (p_objp->special_ship) {
|
||||
wingp->special_ship = wingp->current_count;
|
||||
// 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;
|
||||
}
|
||||
|
||||
// set up wingman status index
|
||||
hud_wingman_status_set_index(wingp->ship_index[wingp->current_count]);
|
||||
hud_wingman_status_set_index(Objects[objnum].instance);
|
||||
|
||||
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;
|
||||
@@ -4497,6 +4520,24 @@ int parse_wing_create_ships( wing *wingp, int num_to_create, int force, int spec
|
||||
// we should always have enough ships in the list!!!
|
||||
Assert (num_to_create == 0);
|
||||
|
||||
// wing current_count needs to match the end of the ship_index[] list, but there
|
||||
// is a very off chance it could have holes in it, so make sure to compact the list
|
||||
for (i = 0; i < (MAX_SHIPS_PER_WING-1); i++) {
|
||||
if (wingp->ship_index[i] == -1) {
|
||||
j = i;
|
||||
while ( j < (MAX_SHIPS_PER_WING-1) ) {
|
||||
wingp->ship_index[j] = wingp->ship_index[j+1];
|
||||
|
||||
// update "special" ship too
|
||||
if (wingp->special_ship == j+1) {
|
||||
wingp->special_ship--;
|
||||
}
|
||||
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// possibly play some event driven music here. Send a network packet indicating the wing was
|
||||
// created. Only do this stuff if actually in the mission.
|
||||
if ( (objnum != -1) && (Game_mode & GM_IN_MISSION) ) { // if true, we have created at least one new ship.
|
||||
@@ -4861,7 +4902,6 @@ void parse_wing(mission *pm)
|
||||
|
||||
p_objp->wingnum = wingnum;
|
||||
p_objp->pos_in_wing = i;
|
||||
p_objp->special_ship = (i == wingp->special_ship) ? true : false;
|
||||
|
||||
assigned++;
|
||||
}
|
||||
@@ -5237,6 +5277,35 @@ void parse_messages(mission *pm, int flags)
|
||||
{
|
||||
required_string("#Messages");
|
||||
|
||||
// command stuff by Goober5000 ---------------------------------------
|
||||
strcpy(pm->command_sender, DEFAULT_COMMAND);
|
||||
if (optional_string("$Command Sender:"))
|
||||
{
|
||||
char temp[NAME_LENGTH];
|
||||
stuff_string(temp, F_NAME, NAME_LENGTH);
|
||||
|
||||
if (*temp == '#')
|
||||
strcpy(pm->command_sender, &temp[1]);
|
||||
else
|
||||
strcpy(pm->command_sender, temp);
|
||||
}
|
||||
|
||||
pm->command_persona = Default_command_persona;
|
||||
if (optional_string("$Command Persona:"))
|
||||
{
|
||||
int idx;
|
||||
char temp[NAME_LENGTH];
|
||||
stuff_string(temp, F_NAME, NAME_LENGTH);
|
||||
|
||||
idx = message_persona_name_lookup(temp);
|
||||
if (idx >= 0)
|
||||
pm->command_persona = idx;
|
||||
else
|
||||
Warning(LOCATION, "Supplied Command Persona is invalid! Defaulting to %s.", Personas[Default_command_persona].name);
|
||||
}
|
||||
// end of command stuff ----------------------------------------------
|
||||
|
||||
|
||||
mprintf(("Starting mission message count : %d\n", Num_message_waves));
|
||||
|
||||
// the message_parse function can be found in MissionMessage.h. The format in the
|
||||
@@ -6062,7 +6131,7 @@ int get_mission_info(char *filename, mission *mission_p, bool basic)
|
||||
{
|
||||
char real_fname[MAX_FILENAME_LEN];
|
||||
strcpy(real_fname, filename);
|
||||
char *p = strchr(real_fname, '.');
|
||||
char *p = strrchr(real_fname, '.');
|
||||
if (p) *p = 0; // remove any extension
|
||||
strcat(real_fname, FS_MISSION_FILE_EXT); // append mission extension
|
||||
|
||||
|
||||
@@ -692,6 +692,10 @@ typedef struct mission {
|
||||
int contrail_threshold;
|
||||
int ambient_light_level;
|
||||
|
||||
// Goober5000
|
||||
int command_persona;
|
||||
char command_sender[NAME_LENGTH];
|
||||
|
||||
// Goober5000
|
||||
char event_music_name[NAME_LENGTH];
|
||||
char briefing_music_name[NAME_LENGTH];
|
||||
@@ -738,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 25
|
||||
#define MAX_ALT_TYPE_NAMES 100
|
||||
extern char Mission_alt_types[MAX_ALT_TYPE_NAMES][NAME_LENGTH];
|
||||
extern int Mission_alt_type_count;
|
||||
|
||||
@@ -862,7 +866,6 @@ typedef struct p_object {
|
||||
|
||||
int wingnum; // set to -1 if not in a wing -- Wing array index otherwise
|
||||
int pos_in_wing; // Goober5000 - needed for FRED with the new way things work
|
||||
bool special_ship; // what "$Special Ship:" actually points to in the wing array (for later cleanup)
|
||||
|
||||
int flags; // mission savable flags
|
||||
int flags2; // Goober5000
|
||||
|
||||
@@ -765,6 +765,7 @@ typedef struct submodel_instance_info {
|
||||
#define MSS_FLAG_CARRY_NO_DAMAGE (1 << 9) // WMC
|
||||
#define MSS_FLAG_USE_MULTIPLE_GUNS (1 << 10) // WMC
|
||||
#define MSS_FLAG_FIRE_ON_NORMAL (1 << 11) // forces a turret to fire down its normal vecs
|
||||
#define MSS_FLAG_TURRET_HULL_CHECK (1 << 12) // makes the turret check to see if it's going to shoot through it's own hull before fireing - Bobboau
|
||||
|
||||
// definition of stepped rotation struct
|
||||
typedef struct stepped_rotation {
|
||||
|
||||
@@ -156,7 +156,7 @@ triggered_rotation::~triggered_rotation()
|
||||
{
|
||||
}
|
||||
|
||||
void triggered_rotation::add_queue(queued_animation *the_queue, int direction)
|
||||
void triggered_rotation::add_queue(queued_animation *the_queue, int dir)
|
||||
{
|
||||
int i;
|
||||
queued_animation new_queue;
|
||||
@@ -164,7 +164,7 @@ void triggered_rotation::add_queue(queued_animation *the_queue, int direction)
|
||||
memcpy( &new_queue, the_queue, sizeof(queued_animation) );
|
||||
|
||||
|
||||
if (direction == -1) {
|
||||
if (dir == -1) {
|
||||
new_queue.start = new_queue.reverse_start;
|
||||
vm_vec_negate( &new_queue.angle );
|
||||
}
|
||||
@@ -208,9 +208,9 @@ void triggered_rotation::add_queue(queued_animation *the_queue, int direction)
|
||||
|
||||
if (new_queue.instance == instance) {
|
||||
// same animation is playing that we are about to think about playing some point in the future
|
||||
if ( (this->direction.xyz.x * rot_vel.xyz.x) == new_queue.vel.xyz.x &&
|
||||
(this->direction.xyz.y * rot_vel.xyz.y) == new_queue.vel.xyz.y &&
|
||||
(this->direction.xyz.z * rot_vel.xyz.z) == new_queue.vel.xyz.z)
|
||||
if ( (direction.xyz.x * rot_vel.xyz.x) == new_queue.vel.xyz.x &&
|
||||
(direction.xyz.y * rot_vel.xyz.y) == new_queue.vel.xyz.y &&
|
||||
(direction.xyz.z * rot_vel.xyz.z) == new_queue.vel.xyz.z)
|
||||
{
|
||||
// they're going in opposite directions, one of them is a reversal!
|
||||
// so this means thata there is some sort of delay that's getting fubared becase of other queue items getting removed due to reversal
|
||||
|
||||
@@ -113,7 +113,7 @@ class triggered_rotation
|
||||
void start(queued_animation *q);
|
||||
void set_to_end(queued_animation *q);
|
||||
|
||||
void add_queue(queued_animation *new_queue, int direction);
|
||||
void add_queue(queued_animation *new_queue, int dir);
|
||||
void process_queue();
|
||||
|
||||
vec3d current_ang;
|
||||
|
||||
@@ -4718,9 +4718,7 @@ void model_really_render(int model_num, matrix *orient, vec3d * pos, uint flags,
|
||||
vec3d pnt = gpt->pnt;
|
||||
vec3d norm = gpt->norm;
|
||||
|
||||
if (bank->submodel_parent > 0) { //this is were it rotates for the submodel parent-Bobboau
|
||||
matrix m;
|
||||
|
||||
if (bank->submodel_parent > 0) { //this is where it rotates for the submodel parent-Bobboau
|
||||
if (pm->submodel[bank->submodel_parent].blown_off)
|
||||
continue;
|
||||
|
||||
@@ -4740,14 +4738,15 @@ void model_really_render(int model_num, matrix *orient, vec3d * pos, uint flags,
|
||||
matrix inv_orientation;
|
||||
vm_copy_transpose_matrix(&inv_orientation, &pm->submodel[bank->submodel_parent].orientation);
|
||||
|
||||
vm_matrix_x_matrix(&m, &rotation_matrix, &inv_orientation);
|
||||
matrix submodel_matrix;
|
||||
vm_matrix_x_matrix(&submodel_matrix, &rotation_matrix, &inv_orientation);
|
||||
|
||||
vec3d offset = pm->submodel[bank->submodel_parent].offset;
|
||||
vm_vec_sub(&pnt, &pnt, &offset);
|
||||
vec3d p = pnt;
|
||||
vec3d n = norm;
|
||||
vm_vec_rotate(&pnt, &p, &m);
|
||||
vm_vec_rotate(&norm, &n, &m);
|
||||
vm_vec_rotate(&pnt, &p, &submodel_matrix);
|
||||
vm_vec_rotate(&norm, &n, &submodel_matrix);
|
||||
vm_vec_add2(&pnt, &offset);
|
||||
}
|
||||
|
||||
@@ -4884,7 +4883,7 @@ void model_really_render(int model_num, matrix *orient, vec3d * pos, uint flags,
|
||||
|
||||
vm_vec_zero(&controle_rotval);
|
||||
|
||||
cull = gr_set_cull(0);
|
||||
cull = gr_set_cull(0);
|
||||
|
||||
// Draw the thruster subobjects
|
||||
if (is_outlines_only_htl) {
|
||||
@@ -6187,20 +6186,38 @@ void model_render_children_buffers(bsp_info *model, polymodel *pm, int mn, int d
|
||||
return;
|
||||
}
|
||||
|
||||
if (model->gun_rotation) {
|
||||
if (pm->gun_submodel_rotation > PI2 )
|
||||
pm->gun_submodel_rotation -= PI2;
|
||||
else if (pm->gun_submodel_rotation < 0.0f )
|
||||
pm->gun_submodel_rotation += PI2;
|
||||
|
||||
angles ang = pm->submodel[mn].angs;
|
||||
ang.b += pm->gun_submodel_rotation;
|
||||
// Get submodel rotation data and use submodel orientation matrix
|
||||
// to put together a matrix describing the final orientation of
|
||||
// the submodel relative to its parent
|
||||
angles ang = pm->submodel[mn].angs;
|
||||
|
||||
g3_start_instance_angles(&pm->submodel[mn].offset, &ang);
|
||||
} else {
|
||||
g3_start_instance_angles(&pm->submodel[mn].offset, &pm->submodel[mn].angs);
|
||||
// Add barrel rotation if needed
|
||||
if (model->gun_rotation) {
|
||||
if ( pm->gun_submodel_rotation > PI2 ) {
|
||||
pm->gun_submodel_rotation -= PI2;
|
||||
} else if ( pm->gun_submodel_rotation < 0.0f ) {
|
||||
pm->gun_submodel_rotation += PI2;
|
||||
}
|
||||
|
||||
ang.b += pm->gun_submodel_rotation;
|
||||
}
|
||||
|
||||
// Compute final submodel orientation by using the orientation matrix
|
||||
// and the rotation angles.
|
||||
// By using this kind of computation, the rotational angles can always
|
||||
// be computed relative to the submodel itself, instead of relative
|
||||
// to the parent
|
||||
matrix rotation_matrix = model->orientation;
|
||||
vm_rotate_matrix_by_angles(&rotation_matrix, &ang);
|
||||
|
||||
matrix inv_orientation;
|
||||
vm_copy_transpose_matrix(&inv_orientation, &model->orientation);
|
||||
|
||||
matrix submodel_matrix;
|
||||
vm_matrix_x_matrix(&submodel_matrix, &rotation_matrix, &inv_orientation);
|
||||
|
||||
g3_start_instance_matrix(&pm->submodel[mn].offset, &submodel_matrix, true);
|
||||
|
||||
if ( !(Interp_flags & MR_NO_LIGHTING) )
|
||||
light_rotate_all();
|
||||
|
||||
|
||||
@@ -3038,6 +3038,11 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs
|
||||
|
||||
case ID_PATH:
|
||||
pm->n_paths = cfread_int( fp );
|
||||
|
||||
if (pm->n_paths <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
pm->paths = (model_path *)vm_malloc(sizeof(model_path)*pm->n_paths);
|
||||
Assert( pm->paths != NULL );
|
||||
|
||||
@@ -3670,6 +3675,8 @@ void model_maybe_fixup_subsys_path(polymodel *pm, int path_num)
|
||||
float dist;
|
||||
int index_1, index_2;
|
||||
|
||||
Assert( (path_num >= 0) && (path_num < pm->n_paths) );
|
||||
|
||||
model_path *mp;
|
||||
mp = &pm->paths[path_num];
|
||||
|
||||
@@ -5405,13 +5412,13 @@ void swap_bsp_data( polymodel * pm, void *model_ptr )
|
||||
void swap_sldc_data(ubyte *buffer)
|
||||
{
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
char *type_p = (char *)(Mc_pm->shield_collision_tree+offset);
|
||||
int *size_p = (int *)(Mc_pm->shield_collision_tree+offset+1);
|
||||
char *type_p = (char *)(buffer);
|
||||
int *size_p = (int *)(buffer+1);
|
||||
*size_p = INTEL_INT(*size_p);
|
||||
|
||||
// split and polygons
|
||||
vec3d *minbox_p = (vec3d*)(Mc_pm->shield_collision_tree+offset+5);
|
||||
vec3d *maxbox_p = (vec3d*)(Mc_pm->shield_collision_tree+offset+17);
|
||||
vec3d *minbox_p = (vec3d*)(buffer+5);
|
||||
vec3d *maxbox_p = (vec3d*)(buffer+17);
|
||||
|
||||
minbox_p->xyz.x = INTEL_FLOAT(&minbox_p->xyz.x);
|
||||
minbox_p->xyz.y = INTEL_FLOAT(&minbox_p->xyz.y);
|
||||
@@ -5423,20 +5430,18 @@ void swap_sldc_data(ubyte *buffer)
|
||||
|
||||
|
||||
// split
|
||||
unsigned int *front_offset_p = (unsigned int*)(Mc_pm->shield_collision_tree+offset+29);
|
||||
unsigned int *back_offset_p = (unsigned int*)(Mc_pm->shield_collision_tree+offset+33);
|
||||
unsigned int *front_offset_p = (unsigned int*)(buffer+29);
|
||||
unsigned int *back_offset_p = (unsigned int*)(buffer+33);
|
||||
|
||||
// polygons
|
||||
unsigned int *num_polygons_p = (unsigned int*)(Mc_pm->shield_collision_tree+offset+29);
|
||||
unsigned int *num_polygons_p = (unsigned int*)(buffer+29);
|
||||
|
||||
unsigned int *shld_polys = (unsigned int*)(Mc_pm->shield_collision_tree+offset+33);
|
||||
unsigned int *shld_polys = (unsigned int*)(buffer+33);
|
||||
|
||||
if (*type_p == 0) // SPLIT
|
||||
{
|
||||
*front_offset_p = INTEL_INT(*front_offset_p);
|
||||
*back_offset_p = INTEL_INT(*back_offset_p);
|
||||
mc_check_sldc(buffer+*front_offset_p);
|
||||
mc_check_sldc(buffer+*back_offset_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||