mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-08 07:28:22 -10:00
Compare commits
148
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00828e8410 | ||
|
|
898760e237 | ||
|
|
b76a1e779c | ||
|
|
59553db975 | ||
|
|
aad8c85e51 | ||
|
|
3a2e0f2c4e | ||
|
|
8fc0593dca | ||
|
|
388fe6b029 | ||
|
|
e6dc61fec8 | ||
|
|
1ec9395914 | ||
|
|
fca80c1a83 | ||
|
|
7985dc1bb5 | ||
|
|
d7936867c7 | ||
|
|
0034a4ccee | ||
|
|
22d4de689b | ||
|
|
80c2b908ce | ||
|
|
63514f47b6 | ||
|
|
aad9dd77c1 | ||
|
|
da0e3676c1 | ||
|
|
88ed177663 | ||
|
|
51c6b581cb | ||
|
|
d4084ce89d | ||
|
|
af56b471c1 | ||
|
|
3cb841101c | ||
|
|
f25a1448be | ||
|
|
00a62e93a4 | ||
|
|
b8fca97f43 | ||
|
|
e7a7d75ccc | ||
|
|
14f81c7b63 | ||
|
|
7dfc67e9be | ||
|
|
6ac52660b6 | ||
|
|
bf9766e1ef | ||
|
|
ac9ad20924 | ||
|
|
eb663c01d3 | ||
|
|
7ced087af7 | ||
|
|
54f37f82ae | ||
|
|
4963b751b0 | ||
|
|
a4fe0df027 | ||
|
|
ec5c83a56e | ||
|
|
ce731986ae | ||
|
|
c061d53614 | ||
|
|
485d173906 | ||
|
|
4b2da1591e | ||
|
|
eed55a1925 | ||
|
|
a91b666702 | ||
|
|
9262e8bb0b | ||
|
|
787f58abfd | ||
|
|
f66a232b8c | ||
|
|
f7057f970f | ||
|
|
e0af8bf08e | ||
|
|
8250a303ec | ||
|
|
cdb14a005b | ||
|
|
040252c2ea | ||
|
|
34bc9b17d8 | ||
|
|
653a201993 | ||
|
|
8affc3c984 | ||
|
|
16a1013a0b | ||
|
|
0c9739a2ef | ||
|
|
4cedbe3c66 | ||
|
|
4fa32baf8b | ||
|
|
8fa09e962a | ||
|
|
bfd88b192e | ||
|
|
f4053eb18b | ||
|
|
8374a8be75 | ||
|
|
8a79889583 | ||
|
|
6316b4639f | ||
|
|
8bf974973e | ||
|
|
749548cacb | ||
|
|
db0c0a6e6b | ||
|
|
4300a67da3 | ||
|
|
75410b1465 | ||
|
|
eaf516756f | ||
|
|
fc88ab03a5 | ||
|
|
8da643a5db | ||
|
|
ea3e865836 | ||
|
|
d24e2985d2 | ||
|
|
eb4e65fc6e | ||
|
|
1185261974 | ||
|
|
336fd14f8b | ||
|
|
042b4ce0db | ||
|
|
0c513e053a | ||
|
|
c32b39a247 | ||
|
|
e610de3516 | ||
|
|
ef63b44a16 | ||
|
|
e17526eb89 | ||
|
|
f0544cb485 | ||
|
|
b1741d2b49 | ||
|
|
8a1cac238f | ||
|
|
c5e346b72b | ||
|
|
da999df482 | ||
|
|
80fddda455 | ||
|
|
d14d3b3b6c | ||
|
|
cabf5068e2 | ||
|
|
a90b70d7f9 | ||
|
|
578aced1a5 | ||
|
|
876743b40e | ||
|
|
7a796e13a4 | ||
|
|
ba52d6bbc0 | ||
|
|
1880beca07 | ||
|
|
0ceb9dc04b | ||
|
|
dc8e8c1270 | ||
|
|
2007614ace | ||
|
|
cf05b699a3 | ||
|
|
8f3144c5c4 | ||
|
|
928858d48e | ||
|
|
9b03393fa8 | ||
|
|
b9f7c4501b | ||
|
|
2c6adfd3ef | ||
|
|
dac5af56e0 | ||
|
|
9fa0cbe8c5 | ||
|
|
c0e3b6699c | ||
|
|
631fbc5094 | ||
|
|
fb02c34646 | ||
|
|
e136784952 | ||
|
|
a6986b7598 | ||
|
|
5d32313599 | ||
|
|
12fdf1e4fa | ||
|
|
6c82fcce32 | ||
|
|
28c573d47b | ||
|
|
845d8472c4 | ||
|
|
09cca0f12b | ||
|
|
93ff4c441b | ||
|
|
6753656848 | ||
|
|
29eb3a8866 | ||
|
|
7b0bcfc8ae | ||
|
|
eb47335e1e | ||
|
|
05b3645062 | ||
|
|
f325afcd54 | ||
|
|
8551b19697 | ||
|
|
1b930557cd | ||
|
|
586f419413 | ||
|
|
f985b10eb7 | ||
|
|
5fb12eebf4 | ||
|
|
c0ed3c79e3 | ||
|
|
dc12a13ff8 | ||
|
|
b2c6a52ae4 | ||
|
|
fc41b260af | ||
|
|
5c7bd6494e | ||
|
|
e8aad6f979 | ||
|
|
af01576b82 | ||
|
|
3c606b90ab | ||
|
|
b2adf4c326 | ||
|
|
c666741e93 | ||
|
|
8b67b33a08 | ||
|
|
d585439096 | ||
|
|
f3f6548293 | ||
|
|
7231b32c99 | ||
|
|
38aac6bd3a |
No files matched your search
+2
-2
@@ -49,7 +49,7 @@ DIE=0
|
||||
DIE=1
|
||||
}
|
||||
|
||||
for AM in automake-1.9 automake-1.8 automake-1.7 automake-1.6 automake; do
|
||||
for AM in automake-1.11 automake-1.10 automake-1.9 automake-1.8 automake-1.7 automake-1.6 automake; do
|
||||
(check_version "$AM" 1 6 1) && {
|
||||
AUTOMAKE="$AM"
|
||||
break
|
||||
@@ -67,7 +67,7 @@ fi
|
||||
|
||||
# if no automake, don't bother testing for aclocal
|
||||
test -z "$AUTOMAKE" || {
|
||||
for ACL in aclocal-1.9 aclocal-1.8 aclocal-1.7 aclocal-1.6 aclocal; do
|
||||
for ACL in aclocal-1.11 aclocal-1.10 aclocal-1.9 aclocal-1.8 aclocal-1.7 aclocal-1.6 aclocal; do
|
||||
(check_version "$ACL" 1 6 1) && {
|
||||
ACLOCAL="$ACL"
|
||||
break
|
||||
|
||||
@@ -205,12 +205,16 @@ typedef struct ai_class {
|
||||
float ai_glide_attack_percent[NUM_SKILL_LEVELS];
|
||||
float ai_circle_strafe_percent[NUM_SKILL_LEVELS];
|
||||
float ai_glide_strafe_percent[NUM_SKILL_LEVELS];
|
||||
float ai_random_sidethrust_percent[NUM_SKILL_LEVELS];
|
||||
float ai_stalemate_time_thresh[NUM_SKILL_LEVELS];
|
||||
float ai_stalemate_dist_thresh[NUM_SKILL_LEVELS];
|
||||
int ai_chance_to_use_missiles_on_plr[NUM_SKILL_LEVELS];
|
||||
float ai_max_aim_update_delay[NUM_SKILL_LEVELS];
|
||||
float ai_turret_max_aim_update_delay[NUM_SKILL_LEVELS];
|
||||
int ai_profile_flags; //Holds the state of flags that are set
|
||||
int ai_profile_flags_set; //Holds which flags are set and which are just left alone
|
||||
int ai_profile_flags2;
|
||||
int ai_profile_flags2_set;
|
||||
|
||||
//SUSHI: These are optional overrides to an AI class to prevent the automatic scaling based on AI class index
|
||||
int ai_aburn_use_factor[NUM_SKILL_LEVELS];
|
||||
@@ -435,11 +439,14 @@ typedef struct ai_info {
|
||||
float ai_glide_attack_percent;
|
||||
float ai_circle_strafe_percent;
|
||||
float ai_glide_strafe_percent;
|
||||
float ai_random_sidethrust_percent;
|
||||
float ai_stalemate_time_thresh;
|
||||
float ai_stalemate_dist_thresh;
|
||||
int ai_chance_to_use_missiles_on_plr;
|
||||
float ai_max_aim_update_delay;
|
||||
float ai_turret_max_aim_update_delay;
|
||||
int ai_profile_flags; //Holds AI_Profiles flags (possibly overriden by AI class) that actually apply to AI
|
||||
int ai_profile_flags2;
|
||||
|
||||
|
||||
union {
|
||||
@@ -632,6 +639,7 @@ extern ship_subsys *set_targeted_subsys(ai_info *aip, ship_subsys *new_subsys, i
|
||||
extern void ai_rearm_repair( object *objp, int docker_index, object *goal_objp, int dockee_index );
|
||||
extern void ai_add_rearm_goal( object *requester_objp, object *support_objp );
|
||||
extern void create_model_path(object *pl_objp, object *mobjp, int path_num, int subsys_path=0);
|
||||
extern int ai_find_goal_index( ai_goal* aigp, int mode, int submode = -1, int priority = -1 );
|
||||
|
||||
// Goober5000
|
||||
extern void ai_do_safety(object *objp);
|
||||
|
||||
+21
-1
@@ -49,7 +49,6 @@ void set_flag(ai_profile_t *profile, char *name, int flag, int type)
|
||||
void parse_ai_profiles_tbl(char *filename)
|
||||
{
|
||||
int i, rval;
|
||||
bool no_create = false;
|
||||
char profile_name[NAME_LENGTH];
|
||||
ai_profile_t dummy_profile;
|
||||
char *saved_Mp = NULL;
|
||||
@@ -84,6 +83,7 @@ void parse_ai_profiles_tbl(char *filename)
|
||||
{
|
||||
ai_profile_t *profile = &dummy_profile;
|
||||
ai_profile_t *previous_profile = NULL;
|
||||
bool no_create = false;
|
||||
|
||||
// get the name
|
||||
required_string("$Profile Name:");
|
||||
@@ -273,6 +273,19 @@ void parse_ai_profiles_tbl(char *filename)
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Random Sidethrust Percent:")) {
|
||||
parse_float_list(profile->random_sidethrust_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (int i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->random_sidethrust_percent[i] < 0.0f || profile->random_sidethrust_percent[i] > 100.0f) {
|
||||
profile->random_sidethrust_percent[i] = 0.0f;
|
||||
Warning(LOCATION, "$Random Sidethrust Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->random_sidethrust_percent[i]);
|
||||
}
|
||||
profile->random_sidethrust_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Stalemate Time Threshold:"))
|
||||
parse_float_list(profile->stalemate_time_thresh, NUM_SKILL_LEVELS);
|
||||
|
||||
@@ -309,6 +322,9 @@ void parse_ai_profiles_tbl(char *filename)
|
||||
if (optional_string("$Max Aim Update Delay:"))
|
||||
parse_float_list(profile->max_aim_update_delay, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Turret Max Aim Update Delay:"))
|
||||
parse_float_list(profile->turret_max_aim_update_delay, 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, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart primary weapon selection:", AIPF_SMART_PRIMARY_WEAPON_SELECTION, AIP_FLAG);
|
||||
@@ -375,6 +391,10 @@ void parse_ai_profiles_tbl(char *filename)
|
||||
|
||||
set_flag(profile, "$turrets ignore targets radius in range checks:", AIPF2_TURRETS_IGNORE_TARGET_RADIUS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$no extra collision avoidance vs player:", AIPF2_NO_SPECIAL_PLAYER_AVOID, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$perform less checks for death screams:", AIPF2_PERFORM_LESS_SCREAM_CHECKS, AIP_FLAG2);
|
||||
|
||||
// if we've been through once already and are at the same place, force a move
|
||||
if ( saved_Mp && (saved_Mp == Mp) )
|
||||
Mp++;
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
|
||||
// flags2
|
||||
#define AIPF2_TURRETS_IGNORE_TARGET_RADIUS (1 << 0)
|
||||
#define AIPF2_NO_SPECIAL_PLAYER_AVOID (1 << 1)
|
||||
#define AIPF2_PERFORM_LESS_SCREAM_CHECKS (1 << 2)
|
||||
|
||||
#define MAX_AI_PROFILES 5
|
||||
|
||||
@@ -94,9 +96,11 @@ typedef struct ai_profile_t {
|
||||
float glide_attack_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to use the "glide attack" move
|
||||
float circle_strafe_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to use the "circle strafe" move
|
||||
float glide_strafe_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to use glide when strafing capships
|
||||
float random_sidethrust_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to randomly use sidethrust while dogfihthing
|
||||
float stalemate_time_thresh[NUM_SKILL_LEVELS]; // SUSHI: The amount of time required for the AI to detect (and try to break) dogfight stalemate
|
||||
float stalemate_dist_thresh[NUM_SKILL_LEVELS]; // SUSHI: The maximum distance the AI and target must be within for a stalemate
|
||||
float max_aim_update_delay[NUM_SKILL_LEVELS]; // SUSHI: The maximum delay before the AI updates their aim against small ships
|
||||
float turret_max_aim_update_delay[NUM_SKILL_LEVELS]; // SUSHI: As above, but for turrets updating their aim
|
||||
|
||||
// Multiplicative delay factors for increasing skill levels.
|
||||
float ship_fire_delay_scale_hostile[NUM_SKILL_LEVELS];
|
||||
@@ -125,6 +129,7 @@ typedef struct ai_profile_t {
|
||||
// the chance (x/7) that ship is allowed to fire missiles at player ship.
|
||||
int chance_to_use_missiles_on_plr[NUM_SKILL_LEVELS];
|
||||
|
||||
|
||||
} ai_profile_t;
|
||||
|
||||
|
||||
|
||||
+21
-7
@@ -704,6 +704,9 @@ void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *f
|
||||
// ship_stop_fire_primary(Pl_objp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tswp->num_secondary_banks > 0) {
|
||||
|
||||
int priority1, priority2;
|
||||
|
||||
@@ -787,7 +790,10 @@ void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *f
|
||||
}
|
||||
}
|
||||
} else {
|
||||
aip->time_enemy_in_range *= (1.0f - flFrametime);
|
||||
if (flFrametime < 1.0f)
|
||||
aip->time_enemy_in_range *= (1.0f - flFrametime);
|
||||
else
|
||||
aip->time_enemy_in_range = 0;
|
||||
}
|
||||
|
||||
if(has_fired == -1){ //stuff that hapens when the ship stops fireing
|
||||
@@ -1094,8 +1100,12 @@ void ai_big_chase()
|
||||
// a big ship
|
||||
if (aip->mode != AIM_EVADE && aip->path_start == -1 ) {
|
||||
ai_big_maybe_fire_weapons(dist_to_enemy, dot_to_enemy, &player_pos, &predicted_enemy_pos, &En_objp->phys_info.vel);
|
||||
} else
|
||||
aip->time_enemy_in_range *= (1.0f - flFrametime);
|
||||
} else {
|
||||
if (flFrametime < 1.0f)
|
||||
aip->time_enemy_in_range *= (1.0f - flFrametime);
|
||||
else
|
||||
aip->time_enemy_in_range = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ai_big_ship(object *objp)
|
||||
@@ -1151,9 +1161,13 @@ void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_t
|
||||
float weapon_speed;
|
||||
|
||||
// Compute position of gun in absolute space and use that as fire position.
|
||||
pnt = po->gun_banks[0].pnt[0];
|
||||
vm_vec_unrotate(&gun_pos, &pnt, &Pl_objp->orient);
|
||||
vm_vec_add2(&gun_pos, &Pl_objp->pos);
|
||||
if (po->n_guns > 0) {
|
||||
pnt = po->gun_banks[0].pnt[0];
|
||||
vm_vec_unrotate(&gun_pos, &pnt, &Pl_objp->orient);
|
||||
vm_vec_add2(&gun_pos, &Pl_objp->pos);
|
||||
} else {
|
||||
gun_pos = Pl_objp->pos;
|
||||
}
|
||||
weapon_speed = ai_get_weapon_speed(&shipp->weapons);
|
||||
|
||||
set_predicted_enemy_pos_turret(&predicted_enemy_pos, &gun_pos, Pl_objp, enemy_pos, &En_objp->phys_info.vel, weapon_speed, aip->time_enemy_in_range);
|
||||
@@ -1417,7 +1431,7 @@ void ai_big_strafe_glide_attack()
|
||||
if (aip->submode_parm1 == 1) {
|
||||
accelerate_ship(aip, 1.0f);
|
||||
//Use afterburners if we have them and are pointed the right way
|
||||
if (dot_to_goal > 0.99f && ai_maybe_fire_afterburner(Pl_objp, aip)) {
|
||||
if (dot_to_goal > 0.99f) {
|
||||
afterburners_start(Pl_objp);
|
||||
aip->afterburner_stop_time = Missiontime + 3*F1_0;
|
||||
}
|
||||
|
||||
+381
-397
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -990,7 +990,7 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
|
||||
* Pass -1 in priority to ignore priority when searching
|
||||
* Returns -1 if not found, or [0, MAX_AI_GOALS)
|
||||
*/
|
||||
int ai_find_goal_index( ai_goal* aigp, int mode, int submode = -1, int priority = -1 )
|
||||
int ai_find_goal_index( ai_goal* aigp, int mode, int submode, int priority )
|
||||
{
|
||||
Assert( aigp != NULL );
|
||||
for ( int i = 0; i < MAX_AI_GOALS; i++ )
|
||||
|
||||
+24
-24
@@ -26,35 +26,35 @@ struct ai_goal;
|
||||
// Fred. If the goal you add doesn't have a target (such as chase_any), then you don't have
|
||||
// to worry about doing this. Also add it to list in Fred\Management.cpp, and let Hoffoss know!
|
||||
// WMC - Oh and add them to Ai_goal_names plz. TY! :)
|
||||
#define AI_GOAL_CHASE (1<<1)
|
||||
#define AI_GOAL_DOCK (1<<2) // used for undocking as well
|
||||
#define AI_GOAL_WAYPOINTS (1<<3)
|
||||
#define AI_GOAL_WAYPOINTS_ONCE (1<<4)
|
||||
#define AI_GOAL_WARP (1<<5)
|
||||
#define AI_GOAL_DESTROY_SUBSYSTEM (1<<6)
|
||||
#define AI_GOAL_FORM_ON_WING (1<<7)
|
||||
#define AI_GOAL_UNDOCK (1<<8)
|
||||
#define AI_GOAL_CHASE_WING (1<<9)
|
||||
#define AI_GOAL_GUARD (1<<10)
|
||||
#define AI_GOAL_DISABLE_SHIP (1<<11)
|
||||
#define AI_GOAL_DISARM_SHIP (1<<12)
|
||||
#define AI_GOAL_CHASE_ANY (1<<13)
|
||||
#define AI_GOAL_IGNORE (1<<14)
|
||||
#define AI_GOAL_GUARD_WING (1<<15)
|
||||
#define AI_GOAL_EVADE_SHIP (1<<16)
|
||||
#define AI_GOAL_CHASE (1<<1) // 0x00000002
|
||||
#define AI_GOAL_DOCK (1<<2) // 0x00000004 // used for undocking as well
|
||||
#define AI_GOAL_WAYPOINTS (1<<3) // 0x00000008
|
||||
#define AI_GOAL_WAYPOINTS_ONCE (1<<4) // 0x00000010
|
||||
#define AI_GOAL_WARP (1<<5) // 0x00000020
|
||||
#define AI_GOAL_DESTROY_SUBSYSTEM (1<<6) // 0x00000040
|
||||
#define AI_GOAL_FORM_ON_WING (1<<7) // 0x00000080
|
||||
#define AI_GOAL_UNDOCK (1<<8) // 0x00000100
|
||||
#define AI_GOAL_CHASE_WING (1<<9) // 0x00000200
|
||||
#define AI_GOAL_GUARD (1<<10) // 0x00000400
|
||||
#define AI_GOAL_DISABLE_SHIP (1<<11) // 0x00000800
|
||||
#define AI_GOAL_DISARM_SHIP (1<<12) // 0x00001000
|
||||
#define AI_GOAL_CHASE_ANY (1<<13) // 0x00002000
|
||||
#define AI_GOAL_IGNORE (1<<14) // 0x00004000
|
||||
#define AI_GOAL_GUARD_WING (1<<15) // 0x00008000
|
||||
#define AI_GOAL_EVADE_SHIP (1<<16) // 0x00010000
|
||||
|
||||
// the next goals are for support ships only
|
||||
#define AI_GOAL_STAY_NEAR_SHIP (1<<17)
|
||||
#define AI_GOAL_KEEP_SAFE_DISTANCE (1<<18)
|
||||
#define AI_GOAL_REARM_REPAIR (1<<19)
|
||||
#define AI_GOAL_STAY_NEAR_SHIP (1<<17) // 0x00020000
|
||||
#define AI_GOAL_KEEP_SAFE_DISTANCE (1<<18) // 0x00040000
|
||||
#define AI_GOAL_REARM_REPAIR (1<<19) // 0x00080000
|
||||
|
||||
// resume regular goals
|
||||
#define AI_GOAL_STAY_STILL (1<<20)
|
||||
#define AI_GOAL_PLAY_DEAD (1<<21)
|
||||
#define AI_GOAL_CHASE_WEAPON (1<<22)
|
||||
#define AI_GOAL_STAY_STILL (1<<20) // 0x00100000
|
||||
#define AI_GOAL_PLAY_DEAD (1<<21) // 0x00200000
|
||||
#define AI_GOAL_CHASE_WEAPON (1<<22) // 0x00400000
|
||||
|
||||
#define AI_GOAL_FLY_TO_SHIP (1<<23) // kazan
|
||||
#define AI_GOAL_IGNORE_NEW (1<<24) // Goober5000
|
||||
#define AI_GOAL_FLY_TO_SHIP (1<<23) // 0x00800000
|
||||
#define AI_GOAL_IGNORE_NEW (1<<24) // 0x01000000
|
||||
|
||||
// now the masks for ship types
|
||||
|
||||
|
||||
+35
-7
@@ -1011,6 +1011,23 @@ void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos
|
||||
ship_model_stop(objp);
|
||||
}
|
||||
|
||||
//Update turret aiming data based on max turret aim update delay
|
||||
void turret_ai_update_aim(ai_info *aip, object *En_Objp, ship_subsys *ss)
|
||||
{
|
||||
if (Missiontime >= ss->next_aim_pos_time)
|
||||
{
|
||||
ss->last_aim_enemy_pos = En_Objp->pos;
|
||||
ss->last_aim_enemy_vel = En_Objp->phys_info.vel;
|
||||
ss->next_aim_pos_time = Missiontime + fl2f(frand_range(0.0f, aip->ai_turret_max_aim_update_delay));
|
||||
}
|
||||
else
|
||||
{
|
||||
//Update the position based on the velocity (assume no velocity vector change)
|
||||
vm_vec_scale_add2(&ss->last_aim_enemy_pos, &ss->last_aim_enemy_vel, flFrametime);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Rotate a turret towards an enemy.
|
||||
// Return TRUE if caller should use angles in subsequent rotations.
|
||||
// Some obscure model thing only John Slagel knows about.
|
||||
@@ -1041,23 +1058,26 @@ int aifft_rotate_turret(ship *shipp, int parent_objnum, ship_subsys *ss, object
|
||||
|
||||
ship_get_global_turret_info(&Objects[parent_objnum], tp, &gun_pos, &gun_vec);
|
||||
|
||||
//Update "known" position and velocity of target. Only matters if max_aim_update_delay is set.
|
||||
turret_ai_update_aim(&Ai_info[shipp->ai_index], &Objects[ss->turret_enemy_objnum], ss);
|
||||
|
||||
//Figure out what point on the ship we want to point the gun at, and store the global location
|
||||
//in enemy_point.
|
||||
vec3d enemy_point;
|
||||
if ((ss->targeted_subsys != NULL) && !(ss->flags & SSF_NO_SS_TARGETING)) {
|
||||
if (ss->turret_enemy_objnum != -1) {
|
||||
vm_vec_unrotate(&enemy_point, &ss->targeted_subsys->system_info->pnt, &Objects[ss->turret_enemy_objnum].orient);
|
||||
vm_vec_add2(&enemy_point, &Objects[ss->turret_enemy_objnum].pos);
|
||||
vm_vec_add2(&enemy_point, &ss->last_aim_enemy_pos);
|
||||
}
|
||||
} else {
|
||||
if ((lep->type == OBJ_SHIP) && (Ship_info[Ships[lep->instance].ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP))) {
|
||||
ai_big_pick_attack_point_turret(lep, ss, &gun_pos, &gun_vec, &enemy_point, tp->turret_fov, MIN(wip->max_speed * wip->lifetime, wip->weapon_range));
|
||||
} else {
|
||||
enemy_point = lep->pos;
|
||||
enemy_point = ss->last_aim_enemy_pos;
|
||||
}
|
||||
}
|
||||
|
||||
target_moving_direction = lep->phys_info.vel;
|
||||
target_moving_direction = ss->last_aim_enemy_vel;
|
||||
|
||||
//Try to guess where the enemy will be, and store that spot in predicted_enemy_pos
|
||||
if (The_mission.ai_profile->flags & AIPF_USE_ADDITIVE_WEAPON_VELOCITY) {
|
||||
@@ -2119,6 +2139,12 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
turret_fire_weapon(valid_weapons[0], ss, parent_objnum, &gpos, &tv2e, &predicted_enemy_pos);
|
||||
else
|
||||
turret_fire_weapon(valid_weapons[i], ss, parent_objnum, &gpos, &tv2e, &predicted_enemy_pos);
|
||||
} else {
|
||||
// make sure salvo fire mode does not turn into autofire
|
||||
if ((tp->flags & MSS_FLAG_TURRET_SALVO) && ((i + 1) == number_of_firings)) {
|
||||
ai_info *parent_aip = &Ai_info[Ships[Objects[parent_objnum].instance].ai_index];
|
||||
turret_set_next_fire_timestamp(valid_weapons[0], wip, ss, parent_aip);
|
||||
}
|
||||
}
|
||||
// moved this here so we increment the fire pos only after we have fired and not during it
|
||||
ss->turret_next_fire_pos++;
|
||||
@@ -2191,14 +2217,16 @@ bool turret_adv_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mo
|
||||
if (((dot + size_mod) > tp->turret_fov) && ((dot - size_mod) <= tp->turret_max_fov)) {
|
||||
vec3d of_dst;
|
||||
vm_vec_rotate( &of_dst, v2e, &ss->world_to_turret_matrix );
|
||||
vm_vec_normalize(&of_dst);
|
||||
if ((of_dst.xyz.x == 0) && (of_dst.xyz.y == 0)) {
|
||||
return true;
|
||||
} else {
|
||||
of_dst.xyz.z = 0;
|
||||
// now we have 2d vector with lenght of 1 that points at the targets direction after being rotated to turrets FOR
|
||||
if ((-of_dst.xyz.y + size_mod) > tp->turret_y_fov)
|
||||
return true;
|
||||
if (!IS_VEC_NULL_SQ_SAFE(&of_dst)) {
|
||||
vm_vec_normalize(&of_dst);
|
||||
// now we have 2d vector with lenght of 1 that points at the targets direction after being rotated to turrets FOR
|
||||
if ((-of_dst.xyz.y + size_mod) > tp->turret_y_fov)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
+198
-141
@@ -39,6 +39,7 @@ extern int Cmdline_autopilot_interruptable;
|
||||
// Module variables
|
||||
bool AutoPilotEngaged;
|
||||
bool UseCutsceneBars;
|
||||
bool LockWeaponsDuringAutopilot;
|
||||
int CurrentNav;
|
||||
float ramp_bias;
|
||||
NavPoint Navs[MAX_NAVPOINTS];
|
||||
@@ -55,6 +56,9 @@ bool CinematicStarted, CameraMoving;
|
||||
vec3d cameraPos, cameraTarget;
|
||||
std::map<int,int> autopilot_wings;
|
||||
|
||||
int AutopilotMinEnemyDistance;
|
||||
int AutopilotMinAsteroidDistance;
|
||||
|
||||
// used for ramping time compression;
|
||||
int start_dist;
|
||||
|
||||
@@ -149,12 +153,7 @@ char* NavPoint::GetInteralName()
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
// Tell us if autopilot is allowed
|
||||
// This needs:
|
||||
// * Nav point selected
|
||||
// * No enemies within X distance
|
||||
// * Destination > 1,000 meters away
|
||||
bool CanAutopilot(bool send_msg)
|
||||
bool CanAutopilot(vec3d targetPos, bool send_msg)
|
||||
{
|
||||
if (CurrentNav == -1)
|
||||
{
|
||||
@@ -162,99 +161,69 @@ bool CanAutopilot(bool send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_NOSEL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (object_get_gliding(Player_obj))
|
||||
{
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_GLIDING);
|
||||
return false;
|
||||
}
|
||||
|
||||
// You cannot autopilot if you're within 1000 meters of your destination nav point
|
||||
if (vm_vec_dist_quick(&Player_obj->pos, Navs[CurrentNav].GetPosition()) < 1000)
|
||||
{
|
||||
if (vm_vec_dist_quick(&targetPos, Navs[CurrentNav].GetPosition()) < 1000) {
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_TOCLOSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
// see if any hostiles are nearby
|
||||
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
|
||||
{
|
||||
object *other_objp = &Objects[so->objnum];
|
||||
|
||||
// attacks player?
|
||||
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
|
||||
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO))
|
||||
if ( AutopilotMinEnemyDistance > 0 ) {
|
||||
// see if any hostiles are nearby
|
||||
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
|
||||
{
|
||||
// Cannot autopilot if enemy within 5,000 meters
|
||||
if (vm_vec_dist_quick(&Player_obj->pos, &other_objp->pos) < 5000)
|
||||
object *other_objp = &Objects[so->objnum];
|
||||
// attacks player?
|
||||
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
|
||||
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO)) // ignore cargo
|
||||
{
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_HOSTILES);
|
||||
return false;
|
||||
// Cannot autopilot if enemy within AutopilotMinEnemyDistance meters
|
||||
if (vm_vec_dist_quick(&targetPos, &other_objp->pos) < AutopilotMinEnemyDistance) {
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_HOSTILES);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//check for asteroids
|
||||
for (int n=0; n<MAX_ASTEROIDS; n++)
|
||||
{
|
||||
// asteroid
|
||||
if (Asteroids[n].flags & AF_USED)
|
||||
{
|
||||
// Cannot autopilot if asteroid within 1,000 meters
|
||||
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[Asteroids[n].objnum].pos) < 1000)
|
||||
{
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_HAZARD);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
// Tell us if autopilot is allowed at a certain position (only performs checks based on that position)
|
||||
// This needs:
|
||||
// * Nav point selected
|
||||
// * No enemies within X distance
|
||||
// * Destination > 1,000 meters away
|
||||
bool CanAutopilotPos(vec3d targetPos)
|
||||
{
|
||||
// You cannot autopilot if you're within 1000 meters of your destination nav point
|
||||
if (vm_vec_dist_quick(&targetPos, Navs[CurrentNav].GetPosition()) < 1000)
|
||||
return false;
|
||||
// see if any hostiles are nearby
|
||||
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
|
||||
{
|
||||
object *other_objp = &Objects[so->objnum];
|
||||
// attacks player?
|
||||
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
|
||||
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO)) // ignore cargo
|
||||
{
|
||||
// Cannot autopilot if enemy within 5,000 meters
|
||||
if (vm_vec_dist_quick(&targetPos, &other_objp->pos) < 5000)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//check for asteroids
|
||||
for (int n=0; n<MAX_ASTEROIDS; n++)
|
||||
{
|
||||
// asteroid
|
||||
if (Asteroids[n].flags & AF_USED)
|
||||
if ( AutopilotMinAsteroidDistance > 0 ) {
|
||||
//check for asteroids
|
||||
for (int n=0; n<MAX_ASTEROIDS; n++)
|
||||
{
|
||||
// Cannot autopilot if asteroid within 1,000 meters
|
||||
if (vm_vec_dist_quick(&targetPos, &Objects[Asteroids[n].objnum].pos) < 1000)
|
||||
return false;
|
||||
// asteroid
|
||||
if (Asteroids[n].flags & AF_USED)
|
||||
{
|
||||
// Cannot autopilot if asteroid within AutopilotMinAsteroidDistance meters
|
||||
if (vm_vec_dist_quick(&targetPos, &Objects[Asteroids[n].objnum].pos) < AutopilotMinAsteroidDistance) {
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_HAZARD);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for support ships
|
||||
// cannot autopilot if support ship present
|
||||
if ( ship_find_repair_ship(Player_obj) != NULL ) {
|
||||
if (send_msg)
|
||||
send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_PRESENT);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
extern object* Autopilot_flight_leader;
|
||||
// ********************************************************************************************
|
||||
// Engages autopilot
|
||||
// This does:
|
||||
@@ -263,13 +232,54 @@ bool CanAutopilotPos(vec3d targetPos)
|
||||
// * Lock time compression -WMC
|
||||
// * Tell AI to fly to targetted Nav Point (for all nav-status wings/ships)
|
||||
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
|
||||
void StartAutopilot()
|
||||
bool StartAutopilot()
|
||||
{
|
||||
// Check for support ship and dismiss it if it is not doing anything.
|
||||
// If the support ship is doing something then tell the user such.
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
object* support_ship_op = ship_find_repair_ship(Player_obj);
|
||||
if ( support_ship_op == NULL ) {
|
||||
// no more
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
Assert( support_ship_op->type == OBJ_SHIP );
|
||||
Assert( support_ship_op->instance >= 0 );
|
||||
Assert( support_ship_op->instance < MAX_SHIPS );
|
||||
Assert( Ships[support_ship_op->instance].ai_index != -1 );
|
||||
|
||||
ai_info* support_ship_aip = &(Ai_info[Ships[support_ship_op->instance].ai_index]);
|
||||
|
||||
// is support ship trying to rearm-repair
|
||||
if ( ai_find_goal_index( support_ship_aip->goals, AI_GOAL_REARM_REPAIR ) == -1 ) {
|
||||
// no, so tell it to depart
|
||||
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_WARP, -1, NULL, support_ship_aip );
|
||||
} else {
|
||||
// yes
|
||||
send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_WORKING);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
if (!CanAutopilot())
|
||||
return;
|
||||
return false;
|
||||
|
||||
AutoPilotEngaged = true;
|
||||
|
||||
// find the ship that is "leading" all of the ships when the player starts
|
||||
// autopilot
|
||||
// by default the ship that is leading the autopilot session the player's
|
||||
// wing leader (if the player is the wing leader then it will be the
|
||||
// player).
|
||||
// TODO:implement a way to allow a FREDer to say a different ship is leader
|
||||
Autopilot_flight_leader = get_wing_leader(Player_ship->wingnum);
|
||||
if ( Autopilot_flight_leader == NULL ) {
|
||||
// force player to be the leader if he doesn't have a wing
|
||||
Autopilot_flight_leader = Player_obj;
|
||||
}
|
||||
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
LockAPConv = timestamp(); // lock convergence instantly
|
||||
else
|
||||
@@ -328,10 +338,20 @@ void StartAutopilot()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// damp speed_cap to 90% of actual -- to make sure ships stay in formation
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
|
||||
speed_cap = 0.90f * speed_cap;
|
||||
|
||||
if ( speed_cap < 1.0f ) {
|
||||
/* We need to deal with this so that incorrectly flagged ships will not
|
||||
cause the engine to fail to limit all the ships speeds correctly. */
|
||||
Warning(LOCATION, "Ship speed cap is way too small (%f)!\n"
|
||||
"This is normally caused by a ship that has nav-carry-status set, but cannot move itself (like a Cargo container).\n"
|
||||
"Speed cap has been set to 1.0 m/s.",
|
||||
speed_cap);
|
||||
speed_cap = 1.0f;
|
||||
}
|
||||
|
||||
ramp_bias = speed_cap/50.0f;
|
||||
|
||||
// assign ship goals
|
||||
@@ -397,10 +417,10 @@ void StartAutopilot()
|
||||
vm_vector_2_matrix(&Objects[Ships[i].objnum].orient, &norm1, NULL, NULL);
|
||||
}
|
||||
|
||||
// snap wings into formation them into formation
|
||||
// snap wings into formation
|
||||
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS && // only if using cinematics
|
||||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY) // only if in a wing
|
||||
&& Player_obj != &Objects[Ships[i].objnum]) //only if not player object
|
||||
&& Autopilot_flight_leader != &Objects[Ships[i].objnum]) //only if not flight leader's object
|
||||
{
|
||||
ai_info *aip = &Ai_info[Ships[i].ai_index];
|
||||
int wingnum = aip->wing, wing_index = get_wing_index(&Objects[Ships[i].objnum], wingnum);
|
||||
@@ -419,33 +439,34 @@ void StartAutopilot()
|
||||
switch (wcount % 2)
|
||||
{
|
||||
case 1: // back-left
|
||||
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
//vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.fvec);
|
||||
vm_vec_normalize(&perp);
|
||||
vm_vec_scale(&perp, -166.0f*j); // 166m is supposedly the optimal range according to tolwyn
|
||||
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
|
||||
vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
|
||||
break;
|
||||
|
||||
default: //back-right
|
||||
case 0:
|
||||
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
//vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.fvec);
|
||||
vm_vec_normalize(&perp);
|
||||
vm_vec_scale(&perp, 166.0f*j);
|
||||
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
|
||||
vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
|
||||
break;
|
||||
}
|
||||
autopilot_wings[wingnum] = wcount;
|
||||
wcount++;
|
||||
}
|
||||
Objects[Ships[i].objnum].pos = goal_point;
|
||||
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos) > distance)
|
||||
if (vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos) > distance)
|
||||
{
|
||||
distance = vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos);
|
||||
distance = vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos);
|
||||
}
|
||||
}
|
||||
// lock primary and secondary weapons
|
||||
//Ships[i].flags2 |= (SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
|
||||
if ( LockWeaponsDuringAutopilot )
|
||||
Ships[i].flags2 |= (SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
|
||||
|
||||
// clear the ship goals and cap the waypoint speed
|
||||
ai_clear_ship_goals(&Ai_info[Ships[i].ai_index]);
|
||||
@@ -540,9 +561,9 @@ void StartAutopilot()
|
||||
vec3d right, front, up, offset;
|
||||
for (i = 0; i < (int)capIndexes.size(); i++)
|
||||
{
|
||||
vm_vec_add(&right, &Player_obj->orient.vec.rvec, &zero);
|
||||
vm_vec_add(&front, &Player_obj->orient.vec.fvec, &zero);
|
||||
vm_vec_add(&up, &Player_obj->orient.vec.uvec, &zero);
|
||||
vm_vec_add(&right, &Autopilot_flight_leader->orient.vec.rvec, &zero);
|
||||
vm_vec_add(&front, &Autopilot_flight_leader->orient.vec.fvec, &zero);
|
||||
vm_vec_add(&up, &Autopilot_flight_leader->orient.vec.uvec, &zero);
|
||||
vm_vec_add(&offset, &zero, &zero);
|
||||
if (Ship_info[Ships[capIndexes[i]].ship_info_index].flags & (SIF_CAPITAL | SIF_SUPERCAP))
|
||||
{
|
||||
@@ -610,7 +631,7 @@ void StartAutopilot()
|
||||
vm_vec_scale(&up, (1+((float)floor((float)capship_placed[1]/3))));
|
||||
|
||||
// move ourselves up and out of the way of the smaller ships
|
||||
vm_vec_add(&perp, &Player_obj->orient.vec.uvec, &zero);
|
||||
vm_vec_add(&perp, &Autopilot_flight_leader->orient.vec.uvec, &zero);
|
||||
vm_vec_scale(&perp, capship_spreads[2]);
|
||||
vm_vec_add(&up, &up, &perp);
|
||||
|
||||
@@ -665,7 +686,7 @@ void StartAutopilot()
|
||||
vm_vec_scale(&front, 2*(1+((float)floor((float)capship_placed[2]/3))));
|
||||
|
||||
// move "out" by 166*(wcount-1) so we don't bump into fighters
|
||||
vm_vec_add(&perp, &Player_obj->orient.vec.rvec, &zero);
|
||||
vm_vec_add(&perp, &Autopilot_flight_leader->orient.vec.rvec, &zero);
|
||||
vm_vec_scale(&perp, 166.0f*float(wcount-1));
|
||||
if ( (capship_placed[2] % 2) == 0)
|
||||
vm_vec_add(&right, &right, &perp);
|
||||
@@ -687,16 +708,16 @@ void StartAutopilot()
|
||||
// global scale the position by 50%
|
||||
//vm_vec_scale(&offset, 1.5);
|
||||
|
||||
vm_vec_add(&Objects[Ships[capIndexes[i]].objnum].pos, &Player_obj->pos, &offset);
|
||||
vm_vec_add(&Objects[Ships[capIndexes[i]].objnum].pos, &Autopilot_flight_leader->pos, &offset);
|
||||
|
||||
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos) > distance)
|
||||
if (vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos) > distance)
|
||||
{
|
||||
distance = vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos);
|
||||
distance = vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ftemp = floor(Player_obj->phys_info.max_vel.xyz.z/speed_cap);
|
||||
ftemp = floor(Autopilot_flight_leader->phys_info.max_vel.xyz.z/speed_cap);
|
||||
if (ftemp >= 2.0f && ftemp < 4.0f)
|
||||
tc_factor = 2;
|
||||
else if (ftemp >= 4.0f && ftemp < 8.0f)
|
||||
@@ -708,11 +729,11 @@ void StartAutopilot()
|
||||
|
||||
tpos = *Navs[CurrentNav].GetPosition();
|
||||
// determine distance toward nav at which camera will be
|
||||
vm_vec_sub(&pos, &tpos, &Player_obj->pos);
|
||||
vm_vec_sub(&pos, &tpos, &Autopilot_flight_leader->pos);
|
||||
vm_vec_normalize(&pos); // pos is now a unit vector in the direction we will be moving the camera
|
||||
//norm1 = pos;
|
||||
vm_vec_scale(&pos, 5*speed_cap*tc_factor); // pos is now scaled by 5 times the speed (5 seconds ahead)
|
||||
vm_vec_add(&pos, &pos, &Player_obj->pos); // pos is now 5*speed cap in front of player ship
|
||||
vm_vec_add(&pos, &pos, &Autopilot_flight_leader->pos); // pos is now 5*speed cap in front of player ship
|
||||
|
||||
switch (myrand()%24)
|
||||
// 8 different ways of getting perp points
|
||||
@@ -723,74 +744,74 @@ void StartAutopilot()
|
||||
case 9:
|
||||
case 16:
|
||||
if (capship_placed[0] == 0)
|
||||
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.uvec);
|
||||
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
else
|
||||
{ // become up-left
|
||||
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.uvec);
|
||||
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // up
|
||||
case 10:
|
||||
case 23:
|
||||
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
if (capshipPresent) // become up-right
|
||||
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
break;
|
||||
|
||||
case 3: // left
|
||||
case 11:
|
||||
case 22:
|
||||
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
break;
|
||||
|
||||
case 4: // up-left
|
||||
case 12:
|
||||
case 21:
|
||||
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
break;
|
||||
|
||||
case 5: // up-right
|
||||
case 13:
|
||||
case 20:
|
||||
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
break;
|
||||
|
||||
case 6: // down-left
|
||||
case 14:
|
||||
case 19:
|
||||
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
if (capship_placed[0] < 2)
|
||||
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
else
|
||||
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
break;
|
||||
|
||||
case 7: // down-right
|
||||
case 15:
|
||||
case 18:
|
||||
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
|
||||
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
|
||||
if (capship_placed[0] < 1)
|
||||
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
else
|
||||
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
|
||||
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
|
||||
break;
|
||||
|
||||
default:
|
||||
case 0: // right
|
||||
case 8:
|
||||
case 17:
|
||||
perp = Player_obj->orient.vec.rvec;
|
||||
perp = Autopilot_flight_leader->orient.vec.rvec;
|
||||
break;
|
||||
|
||||
}
|
||||
vm_vec_normalize(&perp);
|
||||
//vm_vec_scale(&perp, 2*radius+distance);
|
||||
|
||||
vm_vec_scale(&perp, Player_obj->radius+radius);
|
||||
vm_vec_scale(&perp, Autopilot_flight_leader->radius+radius);
|
||||
|
||||
// randomly scale up/down by up to 20%
|
||||
j = 20-myrand()%40; // [-20,20]
|
||||
@@ -830,16 +851,8 @@ void StartAutopilot()
|
||||
camMovingTime = int(4.5*float(tc_factor));
|
||||
set_time_compression((float)tc_factor);
|
||||
}
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
// Checks if autopilot should automatically die
|
||||
// Returns true if:
|
||||
// * Targetted waypoint < 10,000 meters away
|
||||
// * Enemy < 10,000 meters
|
||||
bool Autopilot_AutoDiable()
|
||||
{
|
||||
return !CanAutopilot();
|
||||
return true;
|
||||
}
|
||||
|
||||
// ********************************************************************************************
|
||||
@@ -852,6 +865,8 @@ void EndAutoPilot()
|
||||
{
|
||||
AutoPilotEngaged = false;
|
||||
|
||||
Autopilot_flight_leader = NULL;
|
||||
|
||||
set_time_compression(1);
|
||||
lock_time_compression(false);
|
||||
Player_use_ai = 0;
|
||||
@@ -899,8 +914,10 @@ void EndAutoPilot()
|
||||
)
|
||||
{
|
||||
//unlock their weaponry
|
||||
//Ships[i].flags2 &= ~(SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
|
||||
if ( LockWeaponsDuringAutopilot )
|
||||
Ships[i].flags2 &= ~(SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
|
||||
Ai_info[Ships[i].ai_index].waypoint_speed_cap = -1; // uncap their speed
|
||||
Ai_info[Ships[i].ai_index].mode = AIM_NONE; // make AI re-evaluate current ship mode
|
||||
|
||||
for (j = 0; j < MAX_AI_GOALS; j++)
|
||||
{
|
||||
@@ -975,34 +992,54 @@ camera* nav_get_set_camera()
|
||||
|
||||
void nav_warp(bool prewarp=false)
|
||||
{
|
||||
// ok... find our end distance - norm1 is still a unit vector in the direction from the player to the navpoint
|
||||
vec3d targetPos, tpos=Player_obj->pos, pos;
|
||||
|
||||
vm_vec_sub(&pos, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
|
||||
/* ok... find our end distance - norm1 is still a unit vector in the
|
||||
direction from the flight leader to the navpoint */
|
||||
vec3d targetPos, tpos=Autopilot_flight_leader->pos, pos, velocity;
|
||||
|
||||
/* calculate a vector that we can use to make a path from the flight
|
||||
leader's location to the nav point */
|
||||
vm_vec_sub(&pos, Navs[CurrentNav].GetPosition(), &Autopilot_flight_leader->pos);
|
||||
vm_vec_normalize(&pos);
|
||||
velocity = pos; // make a copy for later when we do setup veleocity vector
|
||||
vm_vec_scale(&pos, 250.0f); // we move by increments of 250
|
||||
|
||||
while (CanAutopilotPos(tpos))
|
||||
/* using the vector of the flight leaders's path, simulate moving the
|
||||
flight along this path by checking the autopilot conditions as specific
|
||||
intervals along the path*/
|
||||
while (CanAutopilot(tpos))
|
||||
{
|
||||
vm_vec_add(&tpos, &tpos, &pos);
|
||||
}
|
||||
vm_vec_sub(&targetPos, &tpos, &Player_obj->pos); //targetPos is actually a projection in a the direction toward the nav
|
||||
vm_vec_sub(&targetPos, &tpos, &Autopilot_flight_leader->pos);
|
||||
/* targetPos is actually a vector that describes the exact 3D movement that
|
||||
the flgith leader needs to execute to reach the location that the auto
|
||||
pilot is to shut off */
|
||||
|
||||
// Check if we are actually just setting up for the cinimatic shot of the
|
||||
// flight flying on autopilot. Only jump halfway. Also we also need to
|
||||
// put the camera in the correct position to show the player this cinimatic
|
||||
if (prewarp)
|
||||
{
|
||||
vm_vec_scale(&targetPos, 0.5);
|
||||
vm_vec_add(&cameraPos, &cameraPos, &targetPos);
|
||||
}
|
||||
|
||||
/* calcuate the speed that everyone is supposed to be going so that there
|
||||
is no need for anyone to accelerate or decelerate (most obvious with
|
||||
the player's fighter slowing down as it changes the camera pan speed). */
|
||||
Assert( Ai_info[Ships[Autopilot_flight_leader->instance].ai_index].waypoint_speed_cap > 0 );
|
||||
vm_vec_scale(&velocity, (float)Ai_info[Ships[Autopilot_flight_leader->instance].ai_index].waypoint_speed_cap);
|
||||
|
||||
// Find all ships that are supposed to autopilot with the player and move them
|
||||
// to the cinimatic location or the final destination
|
||||
for (int i = 0; i < MAX_SHIPS; i++)
|
||||
{
|
||||
if (Ships[i].objnum != -1 &&
|
||||
(Ships[i].flags2 & SF2_NAVPOINT_CARRY ||
|
||||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY)
|
||||
)
|
||||
)
|
||||
if (Ships[i].objnum != -1
|
||||
&& (Ships[i].flags2 & SF2_NAVPOINT_CARRY
|
||||
|| (Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY)))
|
||||
{
|
||||
vm_vec_add(&Objects[Ships[i].objnum].pos, &Objects[Ships[i].objnum].pos, &targetPos);
|
||||
Objects[Ships[i].objnum].phys_info.vel = velocity;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1041,7 +1078,7 @@ void NavSystem_Do()
|
||||
}
|
||||
|
||||
|
||||
if (timestamp() >= EndAPCinematic || Autopilot_AutoDiable())
|
||||
if (timestamp() >= EndAPCinematic || !CanAutopilot())
|
||||
{
|
||||
nav_warp();
|
||||
EndAutoPilot();
|
||||
@@ -1060,7 +1097,7 @@ void NavSystem_Do()
|
||||
if(cam != NULL)
|
||||
{
|
||||
cam->set_position(&cameraPos);
|
||||
cam->set_rotation_facing(&Player_obj->pos);
|
||||
cam->set_rotation_facing(&Autopilot_flight_leader->pos);
|
||||
}
|
||||
|
||||
CinematicStarted = true;
|
||||
@@ -1068,7 +1105,7 @@ void NavSystem_Do()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Autopilot_AutoDiable())
|
||||
if (!CanAutopilot())
|
||||
EndAutoPilot();
|
||||
|
||||
}
|
||||
@@ -1141,7 +1178,10 @@ void NavSystem_Do()
|
||||
}
|
||||
}
|
||||
|
||||
// autopilot linking
|
||||
/* Link in any ships that need to be linked in when the player gets close
|
||||
enough. Always done by the player because: "making sure the AI fighters
|
||||
are where they're supposed to be at all times is like herding cats" -Woolie Wool
|
||||
*/
|
||||
for (int i = 0; i < MAX_SHIPS; i++)
|
||||
{
|
||||
if (Ships[i].objnum != -1 && Ships[i].flags2 & SF2_NAVPOINT_NEEDSLINK)
|
||||
@@ -1247,6 +1287,21 @@ void parse_autopilot_table(char *filename)
|
||||
required_string("$Link Distance:");
|
||||
stuff_int(&NavLinkDistance);
|
||||
|
||||
if (optional_string("$Interrupt autopilot if enemy within distance:"))
|
||||
stuff_int(&AutopilotMinEnemyDistance);
|
||||
else
|
||||
AutopilotMinEnemyDistance = 5000;
|
||||
|
||||
if (optional_string("$Interrupt autopilot if asteroid within distance:"))
|
||||
stuff_int(&AutopilotMinAsteroidDistance);
|
||||
else
|
||||
AutopilotMinAsteroidDistance = 1000;
|
||||
|
||||
if (optional_string("$Lock Weapons During Autopilot:"))
|
||||
stuff_boolean(&LockWeaponsDuringAutopilot);
|
||||
else
|
||||
LockWeaponsDuringAutopilot = false;
|
||||
|
||||
// optional no cutscene bars
|
||||
if (optional_string("+No_Cutscene_Bars"))
|
||||
UseCutsceneBars = false;
|
||||
@@ -1255,7 +1310,9 @@ void parse_autopilot_table(char *filename)
|
||||
Cmdline_autopilot_interruptable = 0;
|
||||
|
||||
// No Nav selected message
|
||||
char *msg_tags[] = { "$No Nav Selected:", "$Gliding:", "$Too Close:", "$Hostiles:", "$Linked:", "$Hazard:" };
|
||||
char *msg_tags[] = { "$No Nav Selected:", "$Gliding:",
|
||||
"$Too Close:", "$Hostiles:", "$Linked:", "$Hazard:",
|
||||
"$Support Present:", "$Support Working:" };
|
||||
for (int i = 0; i < NP_NUM_MESSAGES; i++)
|
||||
{
|
||||
required_string(msg_tags[i]);
|
||||
|
||||
+17
-13
@@ -8,6 +8,7 @@
|
||||
#define _AUTOPILOT_H_
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "object/object.h"
|
||||
#include <map>
|
||||
|
||||
// milliseconds between updates
|
||||
@@ -37,13 +38,15 @@ struct NavPoint
|
||||
};
|
||||
|
||||
|
||||
#define NP_NUM_MESSAGES 6
|
||||
#define NP_MSG_FAIL_NOSEL 0
|
||||
#define NP_MSG_FAIL_GLIDING 1
|
||||
#define NP_MSG_FAIL_TOCLOSE 2
|
||||
#define NP_MSG_FAIL_HOSTILES 3
|
||||
#define NP_MSG_MISC_LINKED 4
|
||||
#define NP_MSG_FAIL_HAZARD 5
|
||||
#define NP_MSG_FAIL_SUPPORT_PRESENT 6
|
||||
#define NP_MSG_FAIL_SUPPORT_WORKING 7
|
||||
#define NP_NUM_MESSAGES 8
|
||||
|
||||
struct NavMessage
|
||||
{
|
||||
@@ -62,27 +65,28 @@ extern std::map<int,int> autopilot_wings;
|
||||
bool Sel_NextNav();
|
||||
|
||||
|
||||
// Tell us is autopilot is allow
|
||||
// Tell us if autopilot is allowed
|
||||
// This needs:
|
||||
// * Nav point selected
|
||||
// * No enemies within 5,000 meters
|
||||
// * No enemies within AutopilotMinEnemyDistance meters
|
||||
// * No asteroids within AutopilotMinAsteroidDistance meters
|
||||
// * Destination > 1,000 meters away
|
||||
bool CanAutopilot(bool send_msg=false);
|
||||
bool CanAutopilotPos(vec3d targetPos);
|
||||
// * Support ship not present or is actively leaving
|
||||
bool CanAutopilot(vec3d targetPos, bool send_msg=false);
|
||||
|
||||
// Check if autopilot is allowed at player's current position
|
||||
// See CanAutopilot(vec3d, bool) for more information
|
||||
inline bool CanAutopilot(bool send_msg=false) { return CanAutopilot(Player_obj->pos, send_msg); }
|
||||
|
||||
// Engages autopilot
|
||||
// This does:
|
||||
// * Checks if Autopilot is allowed. See CanAutopilot() for conditions.
|
||||
// * Control switched from player to AI
|
||||
// * Time compression to 32x
|
||||
// * Tell AI to fly to targetted Nav Point (for all nav-status wings/ships)
|
||||
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
|
||||
void StartAutopilot();
|
||||
|
||||
// Checks if autopilot should automatically die
|
||||
// Returns true if:
|
||||
// * Targetted waypoint < 1,000 meters away
|
||||
// * Enemy < 5,000 meters
|
||||
bool Autopilot_AutoDiable();
|
||||
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
|
||||
// Returns false if autopilot cannot be started. True otherwise.
|
||||
bool StartAutopilot();
|
||||
|
||||
// Disengages autopilot
|
||||
// this does:
|
||||
|
||||
+61
-42
@@ -471,6 +471,8 @@ void camera::get_info(vec3d *position, matrix *orientation)
|
||||
mtxB.a1d[i] = pos;
|
||||
}
|
||||
vm_matrix_x_matrix(&c_ori, &mtxA, &mtxB);
|
||||
|
||||
vm_orthogonalize_matrix(&c_ori);
|
||||
/*
|
||||
angles a;
|
||||
ori_p.get(&a.p, NULL);
|
||||
@@ -613,15 +615,25 @@ void warp_camera::get_info(vec3d *position, matrix *orientation)
|
||||
//*************************subtitle*************************
|
||||
|
||||
#define MAX_SUBTITLE_LINES 64
|
||||
subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_time, char* in_imageanim, float in_fade_time, color *in_text_color, bool center_x, bool center_y, int in_width, bool in_post_shaded)
|
||||
subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, char* in_imageanim, float in_display_time, float in_fade_time, color *in_text_color, bool center_x, bool center_y, int in_width, int in_height, bool in_post_shaded)
|
||||
{
|
||||
// basic init, this always has to be done
|
||||
memset( imageanim, 0, sizeof(imageanim) );
|
||||
memset( &text_pos, 0, 2*sizeof(int) );
|
||||
memset( &image_pos, 0, 4*sizeof(int) );
|
||||
image_id = -1;
|
||||
|
||||
if ( ((in_text != NULL) && (strlen(in_text) <= 0)) && ((in_imageanim != NULL) && (strlen(in_imageanim) <= 0)) )
|
||||
return;
|
||||
|
||||
char text_buf[256];
|
||||
if (in_text != NULL && strlen(in_text) > 0)
|
||||
{
|
||||
strcpy(text_buf, in_text);
|
||||
sexp_replace_variable_names_with_values(text_buf, 256);
|
||||
in_text = text_buf;
|
||||
}
|
||||
|
||||
|
||||
int num_text_lines = 0;
|
||||
char *text_line_ptrs[MAX_SUBTITLE_LINES];
|
||||
@@ -629,7 +641,9 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_t
|
||||
|
||||
//Setup text
|
||||
if ( (in_text != NULL) && (strlen(in_text) > 0) ) {
|
||||
num_text_lines = split_str(in_text, in_width, text_line_lens, text_line_ptrs, MAX_SUBTITLE_LINES);
|
||||
int split_width = (in_width > 0) ? in_width : 200;
|
||||
|
||||
num_text_lines = split_str(in_text, split_width, text_line_lens, text_line_ptrs, MAX_SUBTITLE_LINES);
|
||||
std::string temp_str;
|
||||
for(int i = 0; i < num_text_lines; i++)
|
||||
{
|
||||
@@ -639,7 +653,7 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_t
|
||||
}
|
||||
|
||||
//Setup text color
|
||||
if(in_text_color)
|
||||
if(in_text_color != NULL)
|
||||
text_color = *in_text_color;
|
||||
else
|
||||
gr_init_alphacolor(&text_color, 255, 255, 255, 255);
|
||||
@@ -659,9 +673,6 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_t
|
||||
|
||||
//Setup pos
|
||||
int w=0, h=0, tw=0, th=0;
|
||||
float deltax, deltay;
|
||||
image_pos[0] = 0;
|
||||
image_pos[1] = 0;
|
||||
if(center_x || center_y)
|
||||
{
|
||||
//Get text size
|
||||
@@ -679,6 +690,11 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_t
|
||||
if(image_id != -1)
|
||||
{
|
||||
bm_get_info(image_id, &w, &h);
|
||||
if (in_width > 0)
|
||||
w = in_width;
|
||||
if (in_height > 0)
|
||||
h = in_height;
|
||||
|
||||
tw += w;
|
||||
if(h > th)
|
||||
th = h;
|
||||
@@ -686,44 +702,29 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_t
|
||||
|
||||
//Center it?
|
||||
if(center_x)
|
||||
image_pos[0] = (gr_screen.max_w - tw)/2;
|
||||
image_pos.x = (gr_screen.max_w - tw)/2;
|
||||
if(center_y)
|
||||
image_pos[1] = (gr_screen.max_h - th)/2;
|
||||
image_pos.y = (gr_screen.max_h - th)/2;
|
||||
}
|
||||
|
||||
if(in_x_pos < 0 && !center_x)
|
||||
image_pos[0] += gr_screen.max_w + in_x_pos;
|
||||
image_pos.x += gr_screen.max_w + in_x_pos;
|
||||
else if(!center_x)
|
||||
image_pos[0] += in_x_pos;
|
||||
image_pos.x += in_x_pos;
|
||||
|
||||
if(in_y_pos < 0 && !center_y)
|
||||
image_pos[1] += gr_screen.max_h + in_y_pos;
|
||||
image_pos.y += gr_screen.max_h + in_y_pos;
|
||||
else if(!center_y)
|
||||
image_pos[1] += in_y_pos;
|
||||
image_pos.y += in_y_pos;
|
||||
|
||||
image_pos.w = in_width;
|
||||
image_pos.h = in_height;
|
||||
|
||||
if(image_id != -1)
|
||||
{
|
||||
text_pos[0] = (float) (image_pos[0] + w); //Still set from bm_get_info call
|
||||
if (!center_x)
|
||||
{
|
||||
deltax = text_pos[0] / 1024.0f; //MikeStar;
|
||||
text_pos[0] = gr_screen.max_w * deltax; //MikeStar;
|
||||
}
|
||||
}
|
||||
text_pos.x = image_pos.x + w; //Still set from bm_get_info call
|
||||
else
|
||||
{
|
||||
text_pos[0] = (float) image_pos[0];
|
||||
if (!center_x)
|
||||
{
|
||||
deltax = text_pos[0] / 1024.0f; //MikeStar;
|
||||
text_pos[0] = gr_screen.max_w * deltax; //MikeStar;
|
||||
}
|
||||
}
|
||||
text_pos[1] = (float) image_pos[1];
|
||||
if (!center_y)
|
||||
{
|
||||
deltay = text_pos[1] / 768.0f; //MikeStar;
|
||||
text_pos[1] = gr_screen.max_h * deltay; //MikeStar;
|
||||
}
|
||||
text_pos.x = image_pos.x;
|
||||
text_pos.y = image_pos.y;
|
||||
|
||||
time_displayed = 0.0f;
|
||||
time_displayed_end = 2.0f*fade_time + display_time;
|
||||
@@ -755,8 +756,8 @@ void subtitle::do_frame(float frametime)
|
||||
gr_set_color_fast(&text_color);
|
||||
|
||||
int font_height = gr_get_font_height();
|
||||
int x = fl2i(text_pos[0]);
|
||||
int y = fl2i(text_pos[1]);
|
||||
int x = text_pos.x;
|
||||
int y = text_pos.y;
|
||||
|
||||
for(unsigned int i = 0; i < text_lines.size(); i++)
|
||||
{
|
||||
@@ -767,7 +768,27 @@ void subtitle::do_frame(float frametime)
|
||||
if(image_id != -1)
|
||||
{
|
||||
gr_set_bitmap(image_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, text_color.alpha/255.0f);
|
||||
gr_bitmap(image_pos[0], image_pos[1], false);
|
||||
|
||||
// scaling?
|
||||
if (image_pos.w > 0 || image_pos.h > 0)
|
||||
{
|
||||
int orig_w, orig_h;
|
||||
vec3d scale;
|
||||
|
||||
bm_get_info(image_id, &orig_w, &orig_h);
|
||||
scale.xyz.x = image_pos.w / (float) orig_w;
|
||||
scale.xyz.y = image_pos.h / (float) orig_h;
|
||||
scale.xyz.z = 1.0f;
|
||||
|
||||
gr_push_scale_matrix(&scale);
|
||||
gr_bitmap(image_pos.x, image_pos.y, false);
|
||||
gr_pop_scale_matrix();
|
||||
}
|
||||
// no scaling
|
||||
else
|
||||
{
|
||||
gr_bitmap(image_pos.x, image_pos.y, false);
|
||||
}
|
||||
}
|
||||
|
||||
time_displayed += frametime;
|
||||
@@ -790,8 +811,9 @@ void subtitle::clone(const subtitle &sub)
|
||||
text_lines.push_back(sub.text_lines[i]);
|
||||
}
|
||||
|
||||
text_pos[0] = sub.text_pos[0];
|
||||
text_pos[1] = sub.text_pos[1];
|
||||
// copy the structs
|
||||
text_pos = sub.text_pos;
|
||||
image_pos = sub.image_pos;
|
||||
|
||||
display_time = sub.display_time;
|
||||
fade_time = sub.fade_time;
|
||||
@@ -806,9 +828,6 @@ void subtitle::clone(const subtitle &sub)
|
||||
image_id = -1;
|
||||
}
|
||||
|
||||
image_pos[0] = sub.image_pos[0];
|
||||
image_pos[1] = sub.image_pos[1];
|
||||
|
||||
time_displayed = sub.time_displayed;
|
||||
time_displayed_end = sub.time_displayed_end;
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ private:
|
||||
void clone(const subtitle &sub);
|
||||
|
||||
SCP_vector<std::string> text_lines;
|
||||
float text_pos[2];
|
||||
struct { int x; int y; } text_pos;
|
||||
|
||||
float display_time;
|
||||
float fade_time;
|
||||
@@ -134,7 +134,7 @@ private:
|
||||
//Done with set
|
||||
char imageanim[MAX_FILENAME_LEN];
|
||||
int image_id;
|
||||
int image_pos[2];
|
||||
struct { int x; int y; int w; int h; } image_pos;
|
||||
|
||||
//Time this has been displayed
|
||||
float time_displayed;
|
||||
@@ -144,9 +144,9 @@ private:
|
||||
|
||||
bool post_shaded;
|
||||
public:
|
||||
subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_time,
|
||||
char* in_imageanim = NULL, float in_fade_time = 0.0f, color *in_text_color = NULL,
|
||||
bool center_x = false, bool center_y = false, int in_width = 200, bool post_shaded=false);
|
||||
subtitle(int in_x_pos, int in_y_pos, char* in_text = NULL, char* in_imageanim = NULL,
|
||||
float in_display_time = 0, float in_fade_time = 0.0f, color *in_text_color = NULL,
|
||||
bool center_x = false, bool center_y = false, int in_width = 0, int in_height = 0, bool post_shaded=false);
|
||||
~subtitle();
|
||||
|
||||
subtitle(const subtitle &sub) { clone(sub); }
|
||||
|
||||
@@ -147,9 +147,14 @@ int cfile_in_root_dir(char *exe_path)
|
||||
token_count++;
|
||||
tok = strtok(NULL, DIR_SEPARATOR_STR);
|
||||
} while(tok != NULL);
|
||||
|
||||
// root directory if we have <= 1 slash
|
||||
|
||||
#ifdef SCP_UNIX
|
||||
// /freespace works, / does not
|
||||
if(token_count <= 1) {
|
||||
#else
|
||||
// C:/freespace works, C:/ does not
|
||||
if(token_count <= 2){
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1168,7 +1168,7 @@ int cf_find_file_location_ext( char *filename, const int ext_num, const char **e
|
||||
int last_root_index = -1;
|
||||
int last_path_index = -1;
|
||||
|
||||
file_list_index.reserve(Num_files);
|
||||
file_list_index.reserve( MIN(ext_num * 4, Num_files) );
|
||||
|
||||
// next, run though and pick out base matches
|
||||
for (i = 0; i < Num_files; i++) {
|
||||
|
||||
+78
-56
@@ -21,6 +21,7 @@
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#include <direct.h>
|
||||
#elif defined(APPLE_APP)
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
@@ -49,6 +50,7 @@ public:
|
||||
int get_int();
|
||||
float get_float();
|
||||
char *str();
|
||||
bool check_if_args_is_valid();
|
||||
};
|
||||
|
||||
static cmdline_parm Parm_list(NULL, NULL);
|
||||
@@ -108,16 +110,15 @@ typedef struct
|
||||
// Please group them by type, ie graphics, gameplay etc, maximum 20 different types
|
||||
Flag exe_params[] =
|
||||
{
|
||||
{ "-spec", "Enable specular", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-spec", },
|
||||
{ "-spec", "Enable specular", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-spec", },
|
||||
{ "-glow", "Enable glowmaps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-glow", },
|
||||
{ "-env", "Enable environment maps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-env", },
|
||||
{ "-mipmap", "Enable mipmapping", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mipmap", },
|
||||
{ "-mipmap", "Enable mipmapping", true, 0, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mipmap", },
|
||||
{ "-nomotiondebris", "Disable motion debris", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomotiondebris",},
|
||||
{ "-noscalevid", "Disable scale-to-window for movies", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noscalevid", },
|
||||
{ "-missile_lighting", "Apply Lighting to Missiles" , true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missile_lighting", },
|
||||
{ "-normal", "Enable normal maps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-normal" },
|
||||
{ "-3dshockwave", "Enable 3D shockwaves", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dshockwave" },
|
||||
{ "-post_process", "Enable post processing", true, EASY_MEM_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-post_process" },
|
||||
{ "-3dshockwave", "Enable 3D shockwaves", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dshockwave" },
|
||||
|
||||
{ "-img2dds", "Compress non-compressed images", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-img2dds", },
|
||||
{ "-no_vsync", "Disable vertical sync", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_vsync", },
|
||||
@@ -126,18 +127,16 @@ Flag exe_params[] =
|
||||
{ "-dualscanlines", "Another pair of scanning lines", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dualscanlines", },
|
||||
{ "-targetinfo", "Enable info next to target", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-targetinfo", },
|
||||
{ "-orbradar", "Enables 3d radar", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-orbradar", },
|
||||
{ "-rearm_timer", "Enable Rearm/Repair Completion Timer", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-rearm_timer", },
|
||||
{ "-rearm_timer", "Enable Rearm/Repair Completion Timer", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-rearm_timer", },
|
||||
{ "-ballistic_gauge", "Enable the analog ballistic ammo gauge", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ballistic_gauge", },
|
||||
|
||||
{ "-ship_choice_3d", "Use models for ship selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ship_choice_3d", },
|
||||
{ "-weapon_choice_3d", "Use models for weapon selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-weapon_choice_3d", },
|
||||
{ "-weapon_choice_3d", "Use models for weapon selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-weapon_choice_3d", },
|
||||
{ "-3dwarp", "Enable 3d warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dwarp", },
|
||||
{ "-warp_flash", "Enable flash upon warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-warp_flash", },
|
||||
{ "-no_ap_interrupt", "Disable interrupting autopilot", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_ap_interrupt", },
|
||||
{ "-tbp", "Toggle features for The Babylon Project", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tbp", }, // TBP warp effects -Et1
|
||||
{ "-wcsaga", "Toggle features for Wing Commander Saga", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-wcsaga", },
|
||||
|
||||
{ "-snd_preload", "Preload mission game sounds", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-snd_preload", },
|
||||
{ "-snd_preload", "Preload mission game sounds", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-snd_preload", },
|
||||
{ "-nosound", "Disable sound and music", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nosound", },
|
||||
{ "-nomusic", "Disable music", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomusic", },
|
||||
|
||||
@@ -151,40 +150,40 @@ Flag exe_params[] =
|
||||
|
||||
{ "-oldfire", "", false, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-oldfire", },
|
||||
{ "-nohtl", "Software mode (very slow)", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nohtl", },
|
||||
{ "-no_set_gamma", "Disable setting of gamma", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_set_gamma", },
|
||||
{ "-no_set_gamma", "Disable setting of gamma", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_set_gamma", },
|
||||
{ "-nomovies", "Disable video playback", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomovies", },
|
||||
{ "-noparseerrors", "Disable parsing errors", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noparseerrors", },
|
||||
{ "-safeloading", "", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-safeloading", },
|
||||
{ "-query_speech", "Does this build have speech?", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-query_speech", },
|
||||
{ "-query_speech", "Does this build have speech?", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-query_speech", },
|
||||
{ "-d3d_bad_tsys", "Enable inefficient textures", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-d3d_bad_tsys", },
|
||||
{ "-novbo", "Disable OpenGL VBO", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-novbo", },
|
||||
{ "-noibx", "Don't use cached index buffers (IBX)", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noibx", },
|
||||
{ "-noibx", "Don't use cached index buffers (IBX)", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noibx", },
|
||||
{ "-loadallweps", "Load all weapons, even those not used", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-loadallweps", },
|
||||
{ "-disable_fbo", "Disable OpenGL RenderTargets", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
|
||||
{ "-disable_fbo", "Disable OpenGL RenderTargets", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
|
||||
{ "-no_glsl", "Disable GLSL (shader) support", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
|
||||
{ "-ati_swap", "Fix Color issues on some ATI cards", true, 0, EASY_DEFAULT, "Troubleshoot", "http://scp.indiegames.us/mantis/view.php?id=1669", },
|
||||
{ "-ati_swap", "Fix Color issues on some ATI cards", true, 0, EASY_DEFAULT, "Troubleshoot", "http://scp.indiegames.us/mantis/view.php?id=1669", },
|
||||
|
||||
{ "-ingame_join", "Allows ingame joining", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
|
||||
{ "-voicer", "Voice recognition", true, 0, EASY_DEFAULT, "Experimental", "", },
|
||||
{ "-post_process", "Enable post processing", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-post_process" },
|
||||
|
||||
{ "-fps", "Show frames per second on HUD", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fps", },
|
||||
{ "-pos", "Show position of camera", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pos", },
|
||||
{ "-window", "Run in window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-window", },
|
||||
{ "-fullscreen_window", "Run in fullscreen window", false, 0, 0, "Dev Tool", "", },
|
||||
{ "-res", "Run at specified resolution", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-res", },
|
||||
{ "-fullscreen_window", "Run in fullscreen window", false, 0, EASY_DEFAULT, "Dev Tool", "", },
|
||||
{ "-timerbar", "", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-timerbar", },
|
||||
{ "-stats", "Show statistics", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stats", },
|
||||
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
|
||||
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
|
||||
{ "-show_mem_usage", "Show memory usage", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-show_mem_usage", },
|
||||
{ "-pofspew", "", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pofspew", },
|
||||
{ "-tablecrcs", "", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tablecrcs", },
|
||||
{ "-missioncrcs", "", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missioncrcs", },
|
||||
{ "-dis_collisions", "Disable collisions", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_collisions", },
|
||||
{ "-dis_weapons", "Disable weapon rendering", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_weapons", },
|
||||
{ "-dis_weapons", "Disable weapon rendering", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_weapons", },
|
||||
{ "-output_sexps", "Outputs SEXPs to sexps.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_sexps", },
|
||||
{ "-output_scripting", "Outputs scripting to scripting.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_scripting", },
|
||||
{ "-save_render_target", "Save render targets to file", true, 0, EASY_DEFAULT, "Dev Tool", "", },
|
||||
{ "-debug_window", "Display debug window", true, 0, EASY_DEFAULT, "Dev Tool", "", },
|
||||
{ "-debug_window", "Display debug window", true, 0, EASY_DEFAULT, "Dev Tool", "", },
|
||||
{ "-verify_vps", "Spew VP crcs to vp_crcs.txt", true, 0, EASY_DEFAULT, "Dev Tool", "", },
|
||||
#ifdef SCP_UNIX
|
||||
{ "-nograb", "Don't grab mouse/keyboard in a window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nograb", },
|
||||
@@ -332,12 +331,8 @@ int Cmdline_voice_recognition = 0;
|
||||
|
||||
// MOD related
|
||||
cmdline_parm mod_arg("-mod", NULL, true); // Cmdline_mod -- DTP modsupport
|
||||
cmdline_parm tbp("-tbp", NULL); // Cmdline_tbp -- TBP warp effects -Et1
|
||||
cmdline_parm wcsaga("-wcsaga", NULL); // Cmdline_wcsaga
|
||||
|
||||
char *Cmdline_mod = NULL; //DTP for mod arguement
|
||||
int Cmdline_tbp = 0;
|
||||
int Cmdline_wcsaga = 0;
|
||||
|
||||
// Multiplayer/Network related
|
||||
cmdline_parm almission_arg("-almission", NULL); // Cmdline_almission -- DTP for autoload Multi mission
|
||||
@@ -385,6 +380,7 @@ cmdline_parm dis_collisions("-dis_collisions", NULL); // Cmdline_dis_collisions
|
||||
cmdline_parm dis_weapons("-dis_weapons", NULL); // Cmdline_dis_weapons
|
||||
cmdline_parm noparseerrors_arg("-noparseerrors", NULL); // Cmdline_noparseerrors -- turns off parsing errors -C
|
||||
cmdline_parm nowarn_arg("-no_warn", NULL); // Cmdline_nowarn
|
||||
cmdline_parm extra_warn_arg("-extra_warn", NULL); // Cmdline_extra_warn
|
||||
cmdline_parm fps_arg("-fps", NULL); // Cmdline_show_fps
|
||||
cmdline_parm show_mem_usage_arg("-show_mem_usage", NULL); // Cmdline_show_mem_usage
|
||||
cmdline_parm pos_arg("-pos", NULL); // Cmdline_show_pos
|
||||
@@ -405,6 +401,7 @@ int Cmdline_dis_collisions = 0;
|
||||
int Cmdline_dis_weapons = 0;
|
||||
int Cmdline_noparseerrors = 0;
|
||||
int Cmdline_nowarn = 0; // turn warnings off in FRED
|
||||
int Cmdline_extra_warn = 0;
|
||||
int Cmdline_show_mem_usage = 0;
|
||||
int Cmdline_show_pos = 0;
|
||||
int Cmdline_show_stats = 0;
|
||||
@@ -502,7 +499,7 @@ void parm_stuff_args(cmdline_parm *parm, char *cmdline)
|
||||
|
||||
cmdline += strlen(parm->name);
|
||||
|
||||
while ((*cmdline != '\0') && strncmp(cmdline, " -", 2)) {
|
||||
while ((*cmdline != '\0') && strncmp(cmdline, " -", 2) && ((size_t)(dest-buffer) < sizeof(buffer))) {
|
||||
*dest++ = *cmdline++;
|
||||
}
|
||||
|
||||
@@ -521,12 +518,15 @@ void parm_stuff_args(cmdline_parm *parm, char *cmdline)
|
||||
parm->args = NULL;
|
||||
}
|
||||
|
||||
int size = strlen(buffer) + 1;
|
||||
|
||||
if (saved_args != NULL)
|
||||
size += (strlen(saved_args) + 1); // an ',' is used as a separator when combining, so be sure to account for it
|
||||
int size = strlen(buffer);
|
||||
|
||||
if (size > 0) {
|
||||
size++; // nul char
|
||||
|
||||
if (saved_args != NULL) {
|
||||
size += (strlen(saved_args) + 1); // an ',' is used as a separator when combining, so be sure to account for it
|
||||
}
|
||||
|
||||
parm->args = new char[size];
|
||||
memset(parm->args, 0, size);
|
||||
|
||||
@@ -537,13 +537,14 @@ void parm_stuff_args(cmdline_parm *parm, char *cmdline)
|
||||
strcat_s(parm->args, size, ",");
|
||||
// now the new arg
|
||||
strcat_s(parm->args, size, buffer);
|
||||
|
||||
delete [] saved_args;
|
||||
} else {
|
||||
strcpy_s(parm->args, size, buffer);
|
||||
}
|
||||
} else {
|
||||
parm->args = saved_args;
|
||||
}
|
||||
|
||||
if (saved_args != NULL)
|
||||
delete[] saved_args;
|
||||
}
|
||||
|
||||
|
||||
@@ -698,9 +699,12 @@ void os_init_cmdline(char *cmdline)
|
||||
|
||||
// if the file exists, get a single line, and deal with it
|
||||
if ( fp ) {
|
||||
char buf[1024], *p;
|
||||
char *buf, *p;
|
||||
|
||||
fgets(buf, 1024, fp);
|
||||
size_t len = filelength( fileno(fp) ) + 2;
|
||||
buf = new char [len];
|
||||
|
||||
fgets(buf, len-1, fp);
|
||||
|
||||
// replace the newline character with a NULL
|
||||
if ( (p = strrchr(buf, '\n')) != NULL ) {
|
||||
@@ -709,11 +713,12 @@ void os_init_cmdline(char *cmdline)
|
||||
|
||||
#ifdef SCP_UNIX
|
||||
// append a space for the os_parse_parms() check
|
||||
strcat_s(buf, " ");
|
||||
strcat_s(buf, len, " ");
|
||||
#endif
|
||||
|
||||
os_parse_parms(buf);
|
||||
os_validate_parms(buf);
|
||||
delete [] buf;
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
@@ -732,9 +737,12 @@ void os_init_cmdline(char *cmdline)
|
||||
|
||||
// if the file exists, get a single line, and deal with it
|
||||
if ( fp ) {
|
||||
char buf[1024], *p;
|
||||
char *buf, *p;
|
||||
|
||||
fgets(buf, 1024, fp);
|
||||
size_t len = filelength( fileno(fp) ) + 2;
|
||||
buf = new char [len];
|
||||
|
||||
fgets(buf, len-1, fp);
|
||||
|
||||
// replace the newline character with a NULL
|
||||
if ( (p = strrchr(buf, '\n')) != NULL ) {
|
||||
@@ -742,10 +750,11 @@ void os_init_cmdline(char *cmdline)
|
||||
}
|
||||
|
||||
// append a space for the os_parse_parms() check
|
||||
strcat_s(buf, " ");
|
||||
strcat_s(buf, len, " ");
|
||||
|
||||
os_parse_parms(buf);
|
||||
os_validate_parms(buf);
|
||||
delete [] buf;
|
||||
fclose(fp);
|
||||
}
|
||||
#endif
|
||||
@@ -788,6 +797,21 @@ cmdline_parm::~cmdline_parm()
|
||||
#endif
|
||||
}
|
||||
|
||||
// checks if the objects args variable is valid
|
||||
// returns true if it is, shows an error box and returns false if not valid.
|
||||
bool cmdline_parm::check_if_args_is_valid() {
|
||||
if ( args == NULL ) {
|
||||
Error(__FILE__, __LINE__,
|
||||
"Command line flag passed that requires an argument, but the argument is missing!\r\n"
|
||||
"The flag is '%s', make sure that you have an argument that follows it.\r\n"
|
||||
"You may need to close your launcher and remove the flag manually from %s/data/cmdline_fso.cfg\r\n",
|
||||
name, "<Freespace directory>");
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// returns - true if the parameter exists on the command line, otherwise false
|
||||
int cmdline_parm::found()
|
||||
@@ -798,7 +822,8 @@ int cmdline_parm::found()
|
||||
// returns - the interger representation for the parameter arguement
|
||||
int cmdline_parm::get_int()
|
||||
{
|
||||
Assert(args);
|
||||
check_if_args_is_valid();
|
||||
|
||||
int offset = 0;
|
||||
|
||||
if (stacks) {
|
||||
@@ -821,7 +846,8 @@ int cmdline_parm::get_int()
|
||||
// returns - the float representation for the parameter arguement
|
||||
float cmdline_parm::get_float()
|
||||
{
|
||||
Assert(args!=NULL);
|
||||
check_if_args_is_valid();
|
||||
|
||||
int offset = 0;
|
||||
|
||||
if (stacks) {
|
||||
@@ -844,7 +870,8 @@ float cmdline_parm::get_float()
|
||||
// returns - the string value for the parameter arguement
|
||||
char *cmdline_parm::str()
|
||||
{
|
||||
Assert(args);
|
||||
check_if_args_is_valid();
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
@@ -879,6 +906,11 @@ bool SetCmdlineParams()
|
||||
Cmdline_FRED2_htl = 1;
|
||||
}*/
|
||||
|
||||
if (extra_warn_arg.found())
|
||||
{
|
||||
Cmdline_extra_warn = 1;
|
||||
}
|
||||
|
||||
if (timerbar_arg.found()) {
|
||||
Cmdline_timerbar = 1;
|
||||
}
|
||||
@@ -1125,7 +1157,12 @@ bool SetCmdlineParams()
|
||||
}
|
||||
|
||||
if ( fov_arg.found() ) {
|
||||
VIEWER_ZOOM_DEFAULT = Cmdline_fov = fov_arg.get_float();
|
||||
Cmdline_fov = fov_arg.get_float();
|
||||
if (Cmdline_fov > 0.1) {
|
||||
VIEWER_ZOOM_DEFAULT = Cmdline_fov;
|
||||
} else {
|
||||
VIEWER_ZOOM_DEFAULT = Cmdline_fov = 0.75f;
|
||||
}
|
||||
}
|
||||
|
||||
if( clip_dist_arg.found() ) {
|
||||
@@ -1137,16 +1174,6 @@ bool SetCmdlineParams()
|
||||
Cmdline_orb_radar = 1;
|
||||
}
|
||||
|
||||
// TBP warp effects -Et1
|
||||
// Chief1983 - Add 3d shockwave, ship choice 3d and weapon choice 3d if TBP is checked
|
||||
if( tbp.found() )
|
||||
{
|
||||
Cmdline_tbp = 1;
|
||||
Cmdline_enable_3d_shockwave = 1;
|
||||
Cmdline_ship_choice_3d = 1;
|
||||
Cmdline_weapon_choice_3d = 1;
|
||||
}
|
||||
|
||||
if ( use_3dwarp.found() ) {
|
||||
Cmdline_3dwarp = 1;
|
||||
}
|
||||
@@ -1326,11 +1353,6 @@ bool SetCmdlineParams()
|
||||
Cmdline_ballistic_gauge = 1;
|
||||
}
|
||||
|
||||
if (wcsaga.found())
|
||||
{
|
||||
Cmdline_wcsaga = 1;
|
||||
}
|
||||
|
||||
if ( cache_bitmaps_arg.found() ) {
|
||||
Cmdline_cache_bitmaps = 1;
|
||||
}
|
||||
|
||||
@@ -104,9 +104,6 @@ extern int Cmdline_voice_recognition;
|
||||
|
||||
// MOD related
|
||||
extern char *Cmdline_mod; // DTP for mod support
|
||||
extern int Cmdline_tbp;
|
||||
extern int Cmdline_wcsaga;
|
||||
|
||||
// Multiplayer/Network related
|
||||
extern char *Cmdline_almission; // DTP for autoload mission (for multi only)
|
||||
extern int Cmdline_ingamejoin;
|
||||
@@ -134,6 +131,7 @@ extern int Cmdline_dis_collisions;
|
||||
extern int Cmdline_dis_weapons;
|
||||
extern int Cmdline_noparseerrors;
|
||||
extern int Cmdline_nowarn;
|
||||
extern int Cmdline_extra_warn;
|
||||
extern int Cmdline_show_mem_usage;
|
||||
extern int Cmdline_show_pos;
|
||||
extern int Cmdline_show_stats;
|
||||
|
||||
@@ -87,7 +87,6 @@ BOOL AltShipClassDlg::OnInitDialog()
|
||||
while (objp != END_OF_LIST(&obj_used_list)) {
|
||||
if ((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) {
|
||||
if (objp->flags & OF_MARKED) {
|
||||
|
||||
m_selected_ships[num_selected_ships++] = objp->instance;
|
||||
}
|
||||
}
|
||||
@@ -95,6 +94,8 @@ BOOL AltShipClassDlg::OnInitDialog()
|
||||
}
|
||||
|
||||
Assert (num_selected_ships > 0);
|
||||
Assert (Objects[cur_object_index].flags & OF_MARKED);
|
||||
|
||||
if (num_selected_ships > 1)
|
||||
{
|
||||
multi_edit = true;
|
||||
@@ -137,7 +138,7 @@ BOOL AltShipClassDlg::OnInitDialog()
|
||||
|
||||
// Set up the actual list of alt classes
|
||||
alt_class_pool.clear();
|
||||
alt_class_pool = Ships[m_selected_ships[0]].s_alt_classes;
|
||||
alt_class_pool = Ships[Objects[cur_object_index].instance].s_alt_classes;
|
||||
alt_class_list_rebuild();
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
|
||||
+41
-2
@@ -28,6 +28,8 @@
|
||||
#include "debugconsole/dbugfile.h"
|
||||
#include "globalincs/mspdb_callstack.h"
|
||||
|
||||
#include "AFXADV.H"
|
||||
|
||||
#ifdef NDEBUG
|
||||
#ifndef FRED
|
||||
#error macro FRED is not defined when trying to build release Fred. Please define FRED macro in build settings in all Fred projects
|
||||
@@ -80,12 +82,12 @@ window_data Mission_notes_wnd_data;
|
||||
BEGIN_MESSAGE_MAP(CFREDApp, CWinApp)
|
||||
//{{AFX_MSG_MAP(CFREDApp)
|
||||
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
|
||||
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code!
|
||||
//}}AFX_MSG_MAP
|
||||
// Standard file based document commands
|
||||
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
|
||||
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
|
||||
// Standard print setup command
|
||||
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
|
||||
END_MESSAGE_MAP()
|
||||
@@ -236,9 +238,23 @@ BOOL CFREDApp::InitInstance()
|
||||
*str_end = '\0';
|
||||
|
||||
|
||||
// Goober5000 - figure out where the FRED file dialog should go
|
||||
if ((m_pRecentFileList != NULL) && (m_pRecentFileList->GetSize() > 0))
|
||||
{
|
||||
// use the most recently opened file to supply the default folder
|
||||
m_sInitialDir = m_pRecentFileList->operator[](0); // lol syntax
|
||||
}
|
||||
else
|
||||
{
|
||||
// use FRED's own directory to search for missions
|
||||
m_sInitialDir = Fred_base_dir;
|
||||
m_sInitialDir += "\\data\\missions";
|
||||
}
|
||||
|
||||
|
||||
// Parse command line for standard shell commands, DDE, file open
|
||||
CCommandLineInfo cmdInfo;
|
||||
ParseCommandLine(cmdInfo);
|
||||
ParseCommandLine(cmdInfo);
|
||||
|
||||
m_nCmdShow = Main_wnd_data.p.showCmd;
|
||||
|
||||
@@ -309,6 +325,25 @@ void CFREDApp::OnAppAbout()
|
||||
aboutDlg.DoModal();
|
||||
}
|
||||
|
||||
// G5K - from http://www.experts-exchange.com/Programming/System/Windows__Programming/MFC/Q_20155824.html
|
||||
void CFREDApp::OnFileOpen()
|
||||
{
|
||||
// use the initial dir the first time we prompt for a file
|
||||
// name. after a successful open, the file name will be
|
||||
// changed to be the empty string and the default dir
|
||||
// will be supplied by the CFileDialog internal memory
|
||||
if(!DoPromptFileName(m_sInitialDir, AFX_IDS_OPENFILE, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL))
|
||||
{
|
||||
// open cancelled
|
||||
return;
|
||||
}
|
||||
AfxGetApp()->OpenDocumentFile(m_sInitialDir);
|
||||
// if returns NULL, the user has already been alerted
|
||||
|
||||
// now erase the initial dir since we only want to use it once
|
||||
m_sInitialDir.Empty();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CFREDApp commands
|
||||
|
||||
@@ -668,3 +703,7 @@ int CFREDApp::ExitInstance()
|
||||
|
||||
return CWinApp::ExitInstance();
|
||||
}
|
||||
|
||||
// Empty functions to make fred link with the sexp_mission_set_subspace
|
||||
void game_start_subspace_ambient_sound() {}
|
||||
void game_stop_subspace_ambient_sound() {}
|
||||
@@ -52,6 +52,7 @@ typedef struct window_data {
|
||||
class CFREDApp : public CWinApp
|
||||
{
|
||||
int app_init;
|
||||
CString m_sInitialDir;
|
||||
|
||||
public:
|
||||
void record_window_data(window_data *wndd, CWnd *wnd);
|
||||
@@ -75,6 +76,7 @@ public:
|
||||
|
||||
//{{AFX_MSG(CFREDApp)
|
||||
afx_msg void OnAppAbout();
|
||||
afx_msg void OnFileOpen();
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code !
|
||||
//}}AFX_MSG
|
||||
|
||||
+18
-16
@@ -634,7 +634,7 @@ CAPTION "About FRED2"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
ICON IDR_MAINFRAME,IDC_STATIC,10,17,20,20,SS_REALSIZEIMAGE
|
||||
LTEXT "FRED2_OPEN - FreeSpace Editor, Version 3.6.11 OpenGL",
|
||||
LTEXT "FRED2_OPEN - FreeSpace Editor, Version 3.6.12 OpenGL",
|
||||
IDC_STATIC,39,8,184,10,SS_NOPREFIX
|
||||
LTEXT "Copyright © 1999 Volition, Inc. All Rights Reserved",
|
||||
IDC_STATIC,39,17,164,8
|
||||
@@ -1527,7 +1527,7 @@ END
|
||||
IDD_EVENT_EDITOR DIALOGEX 0, 0, 437, 431
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Mission Event Edit"
|
||||
FONT 8, "MS Sans Serif", 0, 0, 0x1
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
CONTROL "Tree1",IDC_EVENT_TREE,"SysTreeView32",TVS_HASBUTTONS |
|
||||
TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS |
|
||||
@@ -1552,8 +1552,8 @@ BEGIN
|
||||
EDITTEXT IDC_CHAIN_DELAY,210,255,45,14,ES_AUTOHSCROLL | ES_NUMBER
|
||||
EDITTEXT IDC_OBJ_TEXT,86,246,117,14,ES_AUTOHSCROLL
|
||||
EDITTEXT IDC_OBJ_KEY_TEXT,86,262,117,14,ES_AUTOHSCROLL
|
||||
EDITTEXT IDC_HELP_BOX,7,298,423,126,ES_MULTILINE | ES_READONLY,
|
||||
WS_EX_TRANSPARENT
|
||||
EDITTEXT IDC_HELP_BOX,7,298,423,126,ES_MULTILINE | ES_AUTOVSCROLL |
|
||||
ES_READONLY | WS_VSCROLL,WS_EX_TRANSPARENT
|
||||
PUSHBUTTON "New Msg",IDC_NEW_MSG,229,59,50,14,0,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "Delete Msg",IDC_DELETE_MSG,229,77,50,14,0,
|
||||
WS_EX_STATICEDGE
|
||||
@@ -2270,8 +2270,8 @@ BEGIN
|
||||
BS_3STATE | WS_TABSTOP,165,17,85,10
|
||||
CONTROL "Affected By Gravity",IDC_AFFECTED_BY_GRAVITY,"Button",
|
||||
BS_3STATE | WS_TABSTOP,165,27,77,10
|
||||
CONTROL "Special Warpin",IDC_SPECIAL_WARPIN,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,165,37,59,10
|
||||
CONTROL "Special Warpin",IDC_SPECIAL_WARPIN,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,165,37,59,10
|
||||
CONTROL "Targetable as Bomb",IDC_TARGETABLE_AS_BOMB,"Button",
|
||||
BS_3STATE | WS_TABSTOP,165,47,79,10
|
||||
CONTROL "Disable Built-in Messages",IDC_DISABLE_BUILTIN_SHIP,
|
||||
@@ -2398,19 +2398,21 @@ BEGIN
|
||||
CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
END
|
||||
|
||||
IDD_SPECIAL_HITPOINTS DIALOG DISCARDABLE 0, 0, 234, 57
|
||||
IDD_SPECIAL_HITPOINTS DIALOG DISCARDABLE 0, 0, 234, 85
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Special Hitpoints"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
CONTROL "Enable Special Hitpoints",IDC_ENABLE_SPECIAL_HITPOINTS,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,93,10
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,37,93,10
|
||||
EDITTEXT IDC_SPECIAL_SHIELDS,91,19,62,12,ES_AUTOHSCROLL
|
||||
LTEXT "Shields:",-1,61,23,26,8
|
||||
EDITTEXT IDC_SPECIAL_HULL,91,33,62,12,ES_AUTOHSCROLL
|
||||
LTEXT "Hull:",-1,72,36,15,8
|
||||
LTEXT "Shields:",-1,62,23,26,8
|
||||
EDITTEXT IDC_SPECIAL_HULL,91,52,62,12,ES_AUTOHSCROLL
|
||||
LTEXT "Hull:",-1,73,55,15,8
|
||||
DEFPUSHBUTTON "OK",ID_OK,177,7,50,14
|
||||
PUSHBUTTON "Cancel",ID_CANCEL,177,24,50,14
|
||||
CONTROL "Enable Special Shield Points",IDC_ENABLE_SPECIAL_SHIELD,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,106,10
|
||||
END
|
||||
|
||||
IDD_SET_GLOBAL_SHIP_FLAGS DIALOG DISCARDABLE 0, 0, 114, 79
|
||||
@@ -2560,8 +2562,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,6,11,0
|
||||
PRODUCTVERSION 3,6,11,0
|
||||
FILEVERSION 3,6,12,0
|
||||
PRODUCTVERSION 3,6,12,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -2578,12 +2580,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Volition Inc.\0"
|
||||
VALUE "FileDescription", "Fred 2 Open\0"
|
||||
VALUE "FileVersion", "3.6.11.0000\0"
|
||||
VALUE "FileVersion", "3.6.12.0\0"
|
||||
VALUE "InternalName", "Fred 2 Open\0"
|
||||
VALUE "LegalCopyright", "Copyright © 1998\0"
|
||||
VALUE "OriginalFilename", "fred2.exe\0"
|
||||
VALUE "ProductName", "Fred 2 Open\0"
|
||||
VALUE "ProductVersion", "3.6.11\0"
|
||||
VALUE "ProductVersion", "3.6.12.0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
@@ -3145,7 +3147,7 @@ IDC_CURSOR2 CURSOR DISCARDABLE "res\\cursor2.cur"
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDR_MAINFRAME "FRED2_OPEN 3.6.11 - FreeSpace2 Mission Editor\nUntitled\nFRED2\nFreeSpace2 Missions (*.fs2)\n.fs2\nFreeSpace2Mission\nFreeSpace2 Mission"
|
||||
IDR_MAINFRAME "FRED2_OPEN 3.6.12 - FreeSpace2 Mission Editor\nUntitled\nFRED2\nFreeSpace2 Missions (*.fs2)\n.fs2\nFreeSpace2Mission\nFreeSpace2 Mission"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
|
||||
@@ -324,8 +324,10 @@ bool fred_init()
|
||||
|
||||
timer_init();
|
||||
|
||||
Assert(strlen(Fred_exe_dir) > 0);
|
||||
Assert(strlen(Fred_base_dir) > 0);
|
||||
|
||||
// sigh... this should enable proper reading of cmdline_fso.cfg - Goober5000
|
||||
cfile_chdir(Fred_base_dir);
|
||||
|
||||
// this should enable mods - Kazan
|
||||
fred2_parse_cmdline(__argc, __argv);
|
||||
@@ -563,6 +565,7 @@ int create_ship(matrix *orient, vec3d *pos, int ship_type)
|
||||
resolve_parse_flags(&Objects[obj], Iff_info[shipp->team].default_parse_flags, Iff_info[shipp->team].default_parse_flags2);
|
||||
|
||||
// default shield setting
|
||||
shipp->special_shield = -1;
|
||||
z1 = Shield_sys_teams[shipp->team];
|
||||
z2 = Shield_sys_types[ship_type];
|
||||
if (((z1 == 1) && z2) || (z2 == 1))
|
||||
@@ -601,9 +604,9 @@ int create_ship(matrix *orient, vec3d *pos, int ship_type)
|
||||
}
|
||||
|
||||
// calc kamikaze stuff
|
||||
if (shipp->special_hitpoint_index != -1)
|
||||
if (shipp->use_special_explosion)
|
||||
{
|
||||
temp_max_hull_strength = (float) atoi(Sexp_variables[shipp->special_hitpoint_index+HULL_STRENGTH].text);
|
||||
temp_max_hull_strength = (float)shipp->special_exp_blast;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2518,7 +2521,7 @@ void generate_weaponry_usage_list(int *arr, int wing)
|
||||
j = swp->num_secondary_banks;
|
||||
while (j--) {
|
||||
if (swp->secondary_bank_weapons[j] >=0 && swp->secondary_bank_weapons[j] < MAX_WEAPON_TYPES) {
|
||||
arr[swp->secondary_bank_weapons[j]] += int(ceil(swp->secondary_bank_ammo[j] * swp->secondary_bank_capacity[j] / 100 / (Weapon_info[swp->secondary_bank_weapons[j]].cargo_size + 0.5f)));
|
||||
arr[swp->secondary_bank_weapons[j]] += (int) floor((swp->secondary_bank_ammo[j] * swp->secondary_bank_capacity[j] / 100.0f / Weapon_info[swp->secondary_bank_weapons[j]].cargo_size) + 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+110
-15
@@ -1035,13 +1035,18 @@ int CFred_mission_save::save_variables()
|
||||
char string[] = "string";
|
||||
char block[] = "block";
|
||||
int i;
|
||||
int num_block_vars = 0;
|
||||
|
||||
// sort sexp_variables
|
||||
sexp_variable_sort();
|
||||
|
||||
// get count
|
||||
int num_variables = sexp_variable_count();
|
||||
int num_block_vars = sexp_variable_block_count();
|
||||
|
||||
if (Format_fs2_open == FSO_FORMAT_RETAIL) {
|
||||
generate_special_explosion_block_variables();
|
||||
num_block_vars = num_block_variables();
|
||||
}
|
||||
int total_variables = num_variables + num_block_vars;
|
||||
|
||||
if (total_variables > 0) {
|
||||
@@ -1087,7 +1092,7 @@ int CFred_mission_save::save_variables()
|
||||
|
||||
for (i=MAX_SEXP_VARIABLES-num_block_vars; i<MAX_SEXP_VARIABLES; i++) {
|
||||
type = block;
|
||||
fout("\n\t\t%d\t\t\"%s\"\t\t\"%s\"\t\t\"%s\"", i, Sexp_variables[i].variable_name, Sexp_variables[i].text, type);
|
||||
fout("\n\t\t%d\t\t\"%s\"\t\t\"%s\"\t\t\"%s\"", i, Block_variables[i].variable_name, Block_variables[i].text, type);
|
||||
}
|
||||
|
||||
fout("\n)");
|
||||
@@ -1626,27 +1631,117 @@ int CFred_mission_save::save_objects()
|
||||
fout(" %d", Ships[i].escort_priority);
|
||||
}
|
||||
|
||||
if (Ships[i].special_exp_index != -1) {
|
||||
if (optional_string_fred("+Special Exp index:", "$Name:")) {
|
||||
parse_comments();
|
||||
} else {
|
||||
fout("\n+Special Exp index:");
|
||||
}
|
||||
// special explosions
|
||||
if (Format_fs2_open != FSO_FORMAT_RETAIL) {
|
||||
if (Ships[i].use_special_explosion) {
|
||||
if (optional_string_fred("$Special Explosion:", "$Name:")) {
|
||||
parse_comments();
|
||||
|
||||
fout(" %d", Ships[i].special_exp_index);
|
||||
required_string_fred("+Special Exp Damage:");
|
||||
parse_comments();
|
||||
fout(" %d", Ships[i].special_exp_damage);
|
||||
|
||||
required_string_fred("+Special Exp Blast:");
|
||||
parse_comments();
|
||||
fout(" %d", Ships[i].special_exp_blast);
|
||||
|
||||
required_string_fred("+Special Exp Inner Radius:");
|
||||
parse_comments();
|
||||
fout(" %d", Ships[i].special_exp_inner);
|
||||
|
||||
required_string_fred("+Special Exp Outer Radius:");
|
||||
parse_comments();
|
||||
fout(" %d", Ships[i].special_exp_outer);
|
||||
|
||||
if (Ships[i].use_shockwave && (Ships[i].special_exp_shockwave_speed > 0)) {
|
||||
optional_string_fred("+Special Exp Shockwave Speed:");
|
||||
parse_comments();
|
||||
fout(" %d", Ships[i].special_exp_shockwave_speed);
|
||||
}
|
||||
else {
|
||||
bypass_comment(";;FSO 3.6.13;; +Special Exp Shockwave Speed:");
|
||||
}
|
||||
}
|
||||
else {
|
||||
fso_comment_push(";;FSO 3.6.13;;");
|
||||
fout_version("\n$Special Explosion:");
|
||||
|
||||
fout_version("\n+Special Exp Damage:");
|
||||
fout(" %d", Ships[i].special_exp_damage);
|
||||
|
||||
fout_version("\n+Special Exp Blast:");
|
||||
fout(" %d", Ships[i].special_exp_blast);
|
||||
|
||||
fout_version("\n+Special Exp Inner Radius:");
|
||||
fout(" %d", Ships[i].special_exp_inner);
|
||||
|
||||
fout_version("\n+Special Exp Outer Radius:");
|
||||
fout(" %d", Ships[i].special_exp_outer);
|
||||
|
||||
if (Ships[i].use_shockwave && (Ships[i].special_exp_shockwave_speed > 0)) {
|
||||
fout_version("\n+Special Exp Shockwave Speed:");
|
||||
fout(" %d", Ships[i].special_exp_shockwave_speed);
|
||||
}
|
||||
|
||||
fso_comment_pop();
|
||||
}
|
||||
}
|
||||
else {
|
||||
bypass_comment(";;FSO 3.6.13;; +Special Exp Shockwave Speed:");
|
||||
}
|
||||
}
|
||||
// retail format special explosions
|
||||
else {
|
||||
if (Ships[i].use_special_explosion) {
|
||||
int special_exp_index;
|
||||
|
||||
if (has_special_explosion_block_index(&Ships[i], &special_exp_index)) {
|
||||
fout("\n+Special Exp index:");
|
||||
fout(" %d", special_exp_index);
|
||||
}
|
||||
else {
|
||||
CString text = "You are saving in the retail mission format, but ";
|
||||
text += "the mission has too many special explosions defined. \"";
|
||||
text += Ships[i].ship_name;
|
||||
text += "\" has therefore lost any special explosion data that was defined for it. ";
|
||||
text += "\" Either remove special explosions or SEXP variables if you need it to have one ";
|
||||
MessageBox(NULL, text, "Too many variables!", MB_OK);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Goober5000 ------------------------------------------------
|
||||
if (Format_fs2_open != FSO_FORMAT_RETAIL)
|
||||
{
|
||||
if (Ships[i].special_hitpoint_index != -1) {
|
||||
if (optional_string_fred("+Special Hitpoint index:", "$Name:")) {
|
||||
if (Ships[i].special_hitpoints) {
|
||||
if (optional_string_fred("+Special Hitpoints:", "$Name:")) {
|
||||
parse_comments();
|
||||
} else {
|
||||
fout("\n+Special Hitpoint index:");
|
||||
fso_comment_push(";;FSO 3.6.13;;");
|
||||
fout_version("\n+Special Hitpoints:");
|
||||
fso_comment_pop();
|
||||
}
|
||||
|
||||
fout(" %d", Ships[i].special_hitpoint_index);
|
||||
fout(" %d", Ships[i].special_hitpoints);
|
||||
}
|
||||
else {
|
||||
bypass_comment(";;FSO 3.6.13;; +Special Hitpoints:");
|
||||
}
|
||||
|
||||
if (Ships[i].special_shield >= 0) {
|
||||
if (optional_string_fred("+Special Shield Points:", "$Name:")) {
|
||||
parse_comments();
|
||||
} else {
|
||||
fso_comment_push(";;FSO 3.6.13;;");
|
||||
fout_version("\n+Special Shield Points:");
|
||||
fso_comment_pop();
|
||||
}
|
||||
|
||||
fout(" %d", Ships[i].special_shield);
|
||||
}
|
||||
else {
|
||||
bypass_comment(";;FSO 3.6.13;; +Special Shield Points:");
|
||||
}
|
||||
}
|
||||
// -----------------------------------------------------------
|
||||
@@ -1864,9 +1959,9 @@ int CFred_mission_save::save_common_object_data(object *objp, ship *shipp)
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
if (Format_fs2_open != FSO_FORMAT_RETAIL && (shipp->special_hitpoint_index != -1))
|
||||
if (Format_fs2_open != FSO_FORMAT_RETAIL && (shipp->special_hitpoints))
|
||||
{
|
||||
temp_max_hull_strength = (float) atoi(Sexp_variables[shipp->special_hitpoint_index+HULL_STRENGTH].text);
|
||||
temp_max_hull_strength = (float)shipp->special_hitpoints;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by FRED.rc
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by fred.rc
|
||||
//
|
||||
#define IDC_SAVE_DEFAULT_PREFS 3
|
||||
#define ID_DELETE_VARIABLE 3
|
||||
@@ -1048,6 +1048,7 @@
|
||||
#define IDC_SPECIAL_SHIELDS 1555
|
||||
#define IDC_SPECIAL_HULL 1556
|
||||
#define IDC_LOADING_SCREEN_BUTTON1024 1557
|
||||
#define IDC_ENABLE_SPECIAL_SHIELD 1557
|
||||
#define IDC_LOADING_SCREEN640 1558
|
||||
#define IDC_TYPE_CAMPAIGN_PERSISTENT 1559
|
||||
#define IDC_MAX_HULL_REPAIR_VAL 1559
|
||||
|
||||
+50
-10
@@ -867,8 +867,9 @@ void sexp_tree::right_clicked(int mode)
|
||||
case OP_TECH_ADD_INTEL:
|
||||
case OP_TECH_RESET_TO_DEFAULT:
|
||||
#endif*/
|
||||
// unlike the above operators, this one is deprecated
|
||||
// unlike the above operators, these are deprecated
|
||||
case OP_HITS_LEFT_SUBSYSTEM:
|
||||
case OP_CUTSCENES_SHOW_SUBTITLE:
|
||||
j = Num_op_menus; // don't allow these operators to be visible
|
||||
break;
|
||||
}
|
||||
@@ -904,8 +905,9 @@ void sexp_tree::right_clicked(int mode)
|
||||
case OP_TECH_ADD_INTEL:
|
||||
case OP_TECH_RESET_TO_DEFAULT:
|
||||
#endif*/
|
||||
// unlike the above operators, this one is deprecated
|
||||
// unlike the above operators, these are deprecated
|
||||
case OP_HITS_LEFT_SUBSYSTEM:
|
||||
case OP_CUTSCENES_SHOW_SUBTITLE:
|
||||
j = Num_submenus; // don't allow these operators to be visible
|
||||
break;
|
||||
}
|
||||
@@ -1145,7 +1147,7 @@ void sexp_tree::right_clicked(int mode)
|
||||
}
|
||||
|
||||
// modify string or number if (modify_variable)
|
||||
if ( Operators[op].value == OP_MODIFY_VARIABLE || Operators[op].value == OP_SET_VARIABLE_BY_INDEX ) {
|
||||
if ( Operators[op].value == OP_MODIFY_VARIABLE ) {
|
||||
int modify_type = get_modify_variable_type(parent);
|
||||
|
||||
if (modify_type == OPF_NUMBER) {
|
||||
@@ -1154,6 +1156,24 @@ void sexp_tree::right_clicked(int mode)
|
||||
}
|
||||
// no change for string type
|
||||
}
|
||||
else if ( Operators[op].value == OP_SET_VARIABLE_BY_INDEX ) {
|
||||
// it depends on which argument we are modifying
|
||||
// first argument is always a number
|
||||
if (Replace_count == 0) {
|
||||
menu.EnableMenuItem(ID_REPLACE_NUMBER, MF_ENABLED);
|
||||
menu.EnableMenuItem(ID_REPLACE_STRING, MF_GRAYED);
|
||||
}
|
||||
// second argument could be anything
|
||||
else {
|
||||
int modify_type = get_modify_variable_type(parent);
|
||||
|
||||
if (modify_type == OPF_NUMBER) {
|
||||
menu.EnableMenuItem(ID_REPLACE_NUMBER, MF_ENABLED);
|
||||
menu.EnableMenuItem(ID_REPLACE_STRING, MF_GRAYED);
|
||||
}
|
||||
// no change for string type
|
||||
}
|
||||
}
|
||||
|
||||
list->destroy();
|
||||
|
||||
@@ -2632,6 +2652,7 @@ int sexp_tree::query_default_argument_available(int op, int i)
|
||||
case OPF_POST_EFFECT:
|
||||
case OPF_TARGET_PRIORITIES:
|
||||
case OPF_ARMOR_TYPES:
|
||||
case OPF_HUD_ELEMENT:
|
||||
return 1;
|
||||
|
||||
case OPF_SHIP:
|
||||
@@ -3136,20 +3157,27 @@ void get_variable_name_from_sexp_tree_node_text(const char *text, char *var_name
|
||||
|
||||
int sexp_tree::get_modify_variable_type(int parent)
|
||||
{
|
||||
Assert(parent >= 0);
|
||||
int sexp_var_index = -1;
|
||||
|
||||
Assert(parent >= 0);
|
||||
int op_const = get_operator_const(tree_nodes[parent].text);
|
||||
|
||||
Assert(tree_nodes[parent].child >= 0);
|
||||
char *node_text = tree_nodes[tree_nodes[parent].child].text;
|
||||
|
||||
if ( op_const == OP_MODIFY_VARIABLE ) {
|
||||
Assert(tree_nodes[parent].child >= 0);
|
||||
sexp_var_index = get_tree_name_to_sexp_variable_index(tree_nodes[tree_nodes[parent].child].text);
|
||||
sexp_var_index = get_tree_name_to_sexp_variable_index(node_text);
|
||||
Assert(sexp_var_index >= 0);
|
||||
} else if ( op_const == OP_SET_VARIABLE_BY_INDEX ) {
|
||||
Assert(tree_nodes[parent].child != -1);
|
||||
if (can_construe_as_integer(tree_nodes[tree_nodes[parent].child].text)) {
|
||||
sexp_var_index = atoi(tree_nodes[tree_nodes[parent].child].text);
|
||||
}
|
||||
else if ( op_const == OP_SET_VARIABLE_BY_INDEX ) {
|
||||
if (can_construe_as_integer(node_text)) {
|
||||
sexp_var_index = atoi(node_text);
|
||||
Assert(sexp_var_index >= 0);
|
||||
}
|
||||
else if (strchr(node_text, '(') && strchr(node_text, ')')) {
|
||||
// the variable index is itself a variable!
|
||||
return OPF_AMBIGUOUS;
|
||||
}
|
||||
} else {
|
||||
Int3(); // should not be called otherwise
|
||||
}
|
||||
@@ -4316,6 +4344,10 @@ sexp_list_item *sexp_tree::get_listing_opf(int opf, int parent_node, int arg_ind
|
||||
|
||||
case OPF_POST_EFFECT:
|
||||
list = get_listing_opf_post_effect();
|
||||
break;
|
||||
|
||||
case OPF_HUD_ELEMENT:
|
||||
list = get_listing_opf_hud_elements();
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -5636,6 +5668,14 @@ sexp_list_item *sexp_tree::get_listing_opf_armor_types()
|
||||
return head.next;
|
||||
}
|
||||
|
||||
sexp_list_item *sexp_tree::get_listing_opf_hud_elements()
|
||||
{
|
||||
sexp_list_item head;
|
||||
head.add_data("warpout");
|
||||
|
||||
return head.next;
|
||||
}
|
||||
|
||||
// Deletes sexp_variable from sexp_tree.
|
||||
// resets tree to not include given variable, and resets text and type
|
||||
void sexp_tree::delete_sexp_tree_variable(const char *var_name)
|
||||
|
||||
@@ -258,6 +258,7 @@ public:
|
||||
sexp_list_item *get_listing_opf_persona();
|
||||
// ---------------------------------------------------------
|
||||
sexp_list_item *get_listing_opf_post_effect();
|
||||
sexp_list_item *get_listing_opf_hud_elements();
|
||||
|
||||
int m_mode;
|
||||
int item_index;
|
||||
|
||||
@@ -1253,9 +1253,16 @@ int CShipEditorDlg::update_ship(int ship)
|
||||
if (strlen(m_cargo1)) {
|
||||
z = string_lookup(m_cargo1, Cargo_names, Num_cargo);
|
||||
if (z == -1) {
|
||||
Assert(Num_cargo < MAX_CARGO);
|
||||
z = Num_cargo++;
|
||||
strcpy(Cargo_names[z], m_cargo1);
|
||||
if (Num_cargo < MAX_CARGO) {
|
||||
z = Num_cargo++;
|
||||
strcpy(Cargo_names[z], m_cargo1);
|
||||
}
|
||||
else {
|
||||
str.Format("Maximum number of cargo names (%d) reached.\nIgnoring new name.\n", MAX_CARGO);
|
||||
MessageBox(str, "Error", MB_ICONEXCLAMATION);
|
||||
z = 0;
|
||||
m_cargo1 = Cargo_names[z];
|
||||
}
|
||||
}
|
||||
|
||||
MODIFY(Ships[ship].cargo1, (char)z);
|
||||
@@ -1314,7 +1321,7 @@ int CShipEditorDlg::update_ship(int ship)
|
||||
m_arrival_delay.save(&Ships[ship].arrival_delay);
|
||||
m_departure_delay.save(&Ships[ship].departure_delay);
|
||||
if (m_arrival_target >= 0) {
|
||||
z = ((CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET)) -> GetItemData(m_arrival_target);
|
||||
z = ((CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET))->GetItemData(m_arrival_target);
|
||||
MODIFY(Ships[ship].arrival_anchor, z);
|
||||
|
||||
// if the arrival is not hyperspace or docking bay -- force arrival distance to be
|
||||
@@ -1324,7 +1331,7 @@ int CShipEditorDlg::update_ship(int ship)
|
||||
if ((Ships[ship].arrival_distance < d) && (Ships[ship].arrival_distance > -d)) {
|
||||
str.Format("Ship must arrive at least %d meters away from target.\n"
|
||||
"Value has been reset to this. Use with caution!\r\n"
|
||||
"Reccomended distance is %d meters.\r\n", d, (int)(2.0f * Objects[Ships[ship].objnum].radius) );
|
||||
"Recommended distance is %d meters.\r\n", d, (int)(2.0f * Objects[Ships[ship].objnum].radius) );
|
||||
|
||||
MessageBox(str);
|
||||
if (Ships[ship].arrival_distance < 0)
|
||||
@@ -1336,8 +1343,10 @@ int CShipEditorDlg::update_ship(int ship)
|
||||
}
|
||||
}
|
||||
}
|
||||
z = ((CComboBox *)GetDlgItem(IDC_DEPARTURE_TARGET))->GetItemData(m_departure_target);
|
||||
MODIFY(Ships[ship].departure_anchor, z );
|
||||
if (m_departure_target >= 0) {
|
||||
z = ((CComboBox *) GetDlgItem(IDC_DEPARTURE_TARGET))->GetItemData(m_departure_target);
|
||||
MODIFY(Ships[ship].departure_anchor, z );
|
||||
}
|
||||
}
|
||||
|
||||
if (m_hotkey != -1)
|
||||
|
||||
@@ -42,15 +42,15 @@ void ShipSpecialDamage::DoDataExchange(CDataExchange* pDX)
|
||||
DDX_Check(pDX, IDC_ENABLE_SHOCKWAVE, m_shock_enabled);
|
||||
DDX_Check(pDX, IDC_ENABLE_SPECIAL_EXP, m_special_exp_enabled);
|
||||
DDX_Text(pDX, IDC_SPECIAL_INNER_RAD, m_inner_rad);
|
||||
DDV_MinMaxInt(pDX, m_inner_rad, 10, 10000);
|
||||
DDV_MinMaxInt(pDX, m_inner_rad, 1, INT_MAX);
|
||||
DDX_Text(pDX, IDC_SPECIAL_OUTER_RAD, m_outer_rad);
|
||||
DDV_MinMaxInt(pDX, m_outer_rad, 11, 10000);
|
||||
DDV_MinMaxInt(pDX, m_outer_rad, 2, INT_MAX);
|
||||
DDX_Text(pDX, IDC_SPECIAL_DAMAGE, m_damage);
|
||||
DDV_MinMaxInt(pDX, m_damage, 0, 100000);
|
||||
DDV_MinMaxInt(pDX, m_damage, 0, INT_MAX);
|
||||
DDX_Text(pDX, IDC_SPECIAL_SHOCK_SPEED, m_shock_speed);
|
||||
DDV_MinMaxInt(pDX, m_shock_speed, 10, 10000);
|
||||
DDV_MinMaxInt(pDX, m_shock_speed, 0, INT_MAX);
|
||||
DDX_Text(pDX, IDC_SPECIAL_BLAST, m_blast);
|
||||
DDV_MinMaxInt(pDX, m_blast, 0, 100000);
|
||||
DDV_MinMaxInt(pDX, m_blast, 0, INT_MAX);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
@@ -71,7 +71,8 @@ void ShipSpecialDamage::OnEnableShockwave()
|
||||
UpdateData(TRUE);
|
||||
|
||||
// enable/disable shock speed
|
||||
DoGray();}
|
||||
DoGray();
|
||||
}
|
||||
|
||||
void ShipSpecialDamage::OnEnableSpecialExp()
|
||||
{
|
||||
@@ -89,21 +90,23 @@ BOOL ShipSpecialDamage::OnInitDialog()
|
||||
// get ship num
|
||||
object *objp;
|
||||
|
||||
m_ship_num = -1;
|
||||
num_selected_ships = 0;
|
||||
|
||||
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) {
|
||||
|
||||
m_ship_num = objp->instance;
|
||||
break;
|
||||
m_selected_ships[num_selected_ships] = objp->instance;
|
||||
num_selected_ships++;
|
||||
}
|
||||
}
|
||||
objp = GET_NEXT(objp);
|
||||
}
|
||||
|
||||
if (Ships[m_ship_num].special_exp_index == -1) {
|
||||
Assert (Objects[cur_object_index].flags & OF_MARKED);
|
||||
m_ship_num = Objects[cur_object_index].instance;
|
||||
|
||||
if (!(Ships[m_ship_num].use_special_explosion)) {
|
||||
// get default_table_values
|
||||
ship_info *sip;
|
||||
sip = &Ship_info[Ships[m_ship_num].ship_info_index];
|
||||
@@ -116,19 +119,23 @@ BOOL ShipSpecialDamage::OnInitDialog()
|
||||
m_shock_speed = (int) sip->shockwave.speed;
|
||||
m_special_exp_enabled = FALSE;
|
||||
|
||||
if (m_inner_rad < 10) m_inner_rad = 10;
|
||||
if (m_outer_rad < 11) m_outer_rad = 11;
|
||||
if (m_shock_speed < 10) m_shock_speed = 10;
|
||||
} else {
|
||||
int index = Ships[m_ship_num].special_exp_index;
|
||||
Assert( (index > 0) && (index < MAX_SEXP_VARIABLES-(BLOCK_EXP_SIZE-1)) );
|
||||
|
||||
m_inner_rad = atoi(Sexp_variables[index++].text);
|
||||
m_outer_rad = atoi(Sexp_variables[index++].text);
|
||||
m_damage = atoi(Sexp_variables[index++].text);
|
||||
m_blast = atoi(Sexp_variables[index++].text);
|
||||
m_shock_enabled = atoi(Sexp_variables[index++].text);
|
||||
m_shock_speed = atoi(Sexp_variables[index++].text);
|
||||
if (m_inner_rad < 1) {
|
||||
m_inner_rad = 1;
|
||||
}
|
||||
if (m_outer_rad < 2) {
|
||||
m_outer_rad = 2;
|
||||
}
|
||||
if (m_shock_speed < 1) {
|
||||
m_shock_speed = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_inner_rad = Ships[m_ship_num].special_exp_inner;
|
||||
m_outer_rad = Ships[m_ship_num].special_exp_outer;
|
||||
m_damage = Ships[m_ship_num].special_exp_damage;
|
||||
m_blast = Ships[m_ship_num].special_exp_blast;
|
||||
m_shock_enabled = Ships[m_ship_num].use_shockwave;
|
||||
m_shock_speed = Ships[m_ship_num].special_exp_shockwave_speed;
|
||||
m_special_exp_enabled = TRUE;
|
||||
}
|
||||
|
||||
@@ -164,16 +171,15 @@ void ShipSpecialDamage::OnOK()
|
||||
{
|
||||
UpdateData(TRUE);
|
||||
|
||||
object *objp;
|
||||
int i;
|
||||
|
||||
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);
|
||||
}
|
||||
if (m_inner_rad > m_outer_rad) {
|
||||
MessageBox("Inner radius must be less than outer radius");
|
||||
return;
|
||||
}
|
||||
|
||||
objp = GET_NEXT(objp);
|
||||
for ( i = 0; i < num_selected_ships; i++ ) {
|
||||
update_ship(m_selected_ships[i]);
|
||||
}
|
||||
|
||||
CDialog::OnOK();
|
||||
@@ -182,51 +188,33 @@ void ShipSpecialDamage::OnOK()
|
||||
void ShipSpecialDamage::update_ship(int shipnum)
|
||||
{
|
||||
ship *shipp = &Ships[shipnum];
|
||||
|
||||
// set to update
|
||||
set_modified();
|
||||
|
||||
// TODO: Add extra validation here
|
||||
if (m_special_exp_enabled) {
|
||||
|
||||
int start;
|
||||
|
||||
if (m_inner_rad > m_outer_rad) {
|
||||
MessageBox("Inner radius must be less than outer radius");
|
||||
return;
|
||||
}
|
||||
|
||||
if (shipp->special_exp_index == -1) {
|
||||
// get free sexp_variables
|
||||
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 {
|
||||
shipp->special_exp_index = start;
|
||||
}
|
||||
} else {
|
||||
start = shipp->special_exp_index;
|
||||
}
|
||||
// set to update
|
||||
set_modified();
|
||||
|
||||
// set em
|
||||
sprintf(Sexp_variables[start+INNER_RAD].text, "%d", m_inner_rad);
|
||||
sprintf(Sexp_variables[start+OUTER_RAD].text, "%d", m_outer_rad);
|
||||
sprintf(Sexp_variables[start+DAMAGE].text, "%d", m_damage);
|
||||
sprintf(Sexp_variables[start+BLAST].text, "%d", m_blast);
|
||||
sprintf(Sexp_variables[start+PROPAGATE].text, "%d", m_shock_enabled);
|
||||
sprintf(Sexp_variables[start+SHOCK_SPEED].text, "%d", m_shock_speed);
|
||||
|
||||
} else {
|
||||
if (shipp->special_exp_index != -1) {
|
||||
// set to update
|
||||
set_modified();
|
||||
|
||||
// free block
|
||||
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
|
||||
shipp->special_exp_index = -1;
|
||||
shipp->use_special_explosion = true;
|
||||
shipp->special_exp_inner = m_inner_rad;
|
||||
shipp->special_exp_outer = m_outer_rad;
|
||||
shipp->special_exp_damage = m_damage;
|
||||
shipp->special_exp_blast = m_blast;
|
||||
shipp->use_shockwave = (m_shock_enabled ? 1:0) ;
|
||||
if (m_shock_speed) {
|
||||
if (m_shock_speed < 1) {
|
||||
m_shock_speed = 1;
|
||||
MessageBox("Shockwave speed must be defined! Setting this to 1 now");
|
||||
}
|
||||
shipp->special_exp_shockwave_speed = m_shock_speed;
|
||||
}
|
||||
} else {
|
||||
shipp->use_special_explosion = false;
|
||||
shipp->special_exp_inner = -1;
|
||||
shipp->special_exp_outer = -1;
|
||||
shipp->special_exp_damage = -1;
|
||||
shipp->special_exp_blast = -1;
|
||||
shipp->use_shockwave = false;
|
||||
shipp->special_exp_shockwave_speed = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,13 +30,19 @@ public:
|
||||
//{{AFX_DATA(ShipSpecialDamage)
|
||||
enum { IDD = IDD_SPECIAL_DAMAGE };
|
||||
int m_shock_enabled;
|
||||
BOOL m_special_exp_enabled;
|
||||
BOOL m_special_exp_enabled;
|
||||
int m_inner_rad;
|
||||
int m_outer_rad;
|
||||
int m_damage;
|
||||
int m_shock_speed;
|
||||
int m_blast;
|
||||
int m_ship_num;
|
||||
|
||||
private:
|
||||
// variables to handle selection of multiple ships
|
||||
int m_selected_ships[MAX_SHIPS];
|
||||
int num_selected_ships;
|
||||
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
|
||||
@@ -31,10 +31,11 @@ void ShipSpecialHitpoints::DoDataExchange(CDataExchange* pDX)
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(ShipSpecialHitpoints)
|
||||
DDX_Check(pDX, IDC_ENABLE_SPECIAL_HITPOINTS, m_special_hitpoints_enabled);
|
||||
DDX_Check(pDX, IDC_ENABLE_SPECIAL_SHIELD, m_special_shield_enabled);
|
||||
DDX_Text(pDX, IDC_SPECIAL_SHIELDS, m_shields);
|
||||
DDV_MinMaxInt(pDX, m_shields, 0, INT_MAX);
|
||||
DDV_MinMaxInt(pDX, m_shields, -1, INT_MAX);
|
||||
DDX_Text(pDX, IDC_SPECIAL_HULL, m_hull);
|
||||
DDV_MinMaxInt(pDX, m_hull, 10, INT_MAX);
|
||||
DDV_MinMaxInt(pDX, m_hull, 1, INT_MAX);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
@@ -42,6 +43,7 @@ void ShipSpecialHitpoints::DoDataExchange(CDataExchange* pDX)
|
||||
BEGIN_MESSAGE_MAP(ShipSpecialHitpoints, CDialog)
|
||||
//{{AFX_MSG_MAP(ShipSpecialHitpoints)
|
||||
ON_BN_CLICKED(IDC_ENABLE_SPECIAL_HITPOINTS, OnEnableSpecialHitpoints)
|
||||
ON_BN_CLICKED(IDC_ENABLE_SPECIAL_SHIELD, OnEnableSpecialShieldpoints)
|
||||
ON_BN_CLICKED(ID_OK, OnOk)
|
||||
ON_BN_CLICKED(ID_CANCEL, OnCancel)
|
||||
//}}AFX_MSG_MAP
|
||||
@@ -58,46 +60,70 @@ void ShipSpecialHitpoints::OnEnableSpecialHitpoints()
|
||||
DoGray();
|
||||
}
|
||||
|
||||
void ShipSpecialHitpoints::OnEnableSpecialShieldpoints()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
UpdateData(TRUE);
|
||||
|
||||
DoGray();
|
||||
}
|
||||
|
||||
BOOL ShipSpecialHitpoints::OnInitDialog()
|
||||
{
|
||||
// get ship num
|
||||
object *objp;
|
||||
|
||||
m_ship_num = -1;
|
||||
num_selected_ships = 0;
|
||||
|
||||
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) {
|
||||
|
||||
m_ship_num = objp->instance;
|
||||
break;
|
||||
m_selected_ships[num_selected_ships] = objp->instance;
|
||||
num_selected_ships++;
|
||||
}
|
||||
}
|
||||
objp = GET_NEXT(objp);
|
||||
}
|
||||
|
||||
if (Ships[m_ship_num].special_hitpoint_index == -1)
|
||||
{
|
||||
Assert(num_selected_ships);
|
||||
Assert (Objects[cur_object_index].flags & OF_MARKED);
|
||||
m_ship_num = Objects[cur_object_index].instance;
|
||||
|
||||
// get the details from the first ship
|
||||
//hull
|
||||
if (Ships[m_ship_num].special_hitpoints) {
|
||||
m_hull = Ships[m_ship_num].special_hitpoints;
|
||||
m_special_hitpoints_enabled = TRUE;
|
||||
}
|
||||
else {
|
||||
// get default_table_values
|
||||
ship_info *sip;
|
||||
sip = &Ship_info[Ships[m_ship_num].ship_info_index];
|
||||
|
||||
m_hull = (int)sip->max_hull_strength;
|
||||
m_special_hitpoints_enabled = FALSE;
|
||||
|
||||
if (m_hull < 1) m_hull = 10;
|
||||
}
|
||||
|
||||
//shields
|
||||
if (Ships[m_ship_num].special_shield > 0){
|
||||
m_shields = Ships[m_ship_num].special_shield;
|
||||
m_special_shield_enabled = TRUE;
|
||||
}
|
||||
else {
|
||||
// get default_table_values
|
||||
ship_info *sip;
|
||||
sip = &Ship_info[Ships[m_ship_num].ship_info_index];
|
||||
|
||||
m_shields = (int)sip->max_shield_strength;
|
||||
m_hull = (int)sip->max_hull_strength;
|
||||
m_special_hitpoints_enabled = FALSE;
|
||||
m_special_shield_enabled = FALSE;
|
||||
|
||||
if (m_shields < 0) m_shields = 0;
|
||||
if (m_hull < 10) m_hull = 10;
|
||||
} else {
|
||||
int index = Ships[m_ship_num].special_hitpoint_index;
|
||||
// Assert( (index > 0) && (index < MAX_SEXP_VARIABLES-(BLOCK_HITPOINT_SIZE-1)) );
|
||||
|
||||
m_shields = atoi(Sexp_variables[index++].text);
|
||||
m_hull = atoi(Sexp_variables[index++].text);
|
||||
|
||||
m_special_hitpoints_enabled = TRUE;
|
||||
}
|
||||
if (m_shields < 0) {
|
||||
m_shields = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
@@ -110,7 +136,7 @@ BOOL ShipSpecialHitpoints::OnInitDialog()
|
||||
|
||||
void ShipSpecialHitpoints::DoGray()
|
||||
{
|
||||
GetDlgItem(IDC_SPECIAL_SHIELDS)->EnableWindow(m_special_hitpoints_enabled);
|
||||
GetDlgItem(IDC_SPECIAL_SHIELDS)->EnableWindow(m_special_shield_enabled);
|
||||
GetDlgItem(IDC_SPECIAL_HULL)->EnableWindow(m_special_hitpoints_enabled);
|
||||
}
|
||||
|
||||
@@ -124,6 +150,8 @@ void ShipSpecialHitpoints::OnCancel()
|
||||
void ShipSpecialHitpoints::OnOk()
|
||||
{
|
||||
float temp_max_hull_strength;
|
||||
int new_shield_strength, new_hull_strength;
|
||||
int i;
|
||||
|
||||
UpdateData(TRUE);
|
||||
|
||||
@@ -131,58 +159,65 @@ void ShipSpecialHitpoints::OnOk()
|
||||
if (m_special_hitpoints_enabled) {
|
||||
|
||||
// Don't update anything if the hull strength is invalid
|
||||
if (m_hull < 10)
|
||||
{
|
||||
if (m_hull < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
int start;
|
||||
|
||||
if (Ships[m_ship_num].special_hitpoint_index == -1) {
|
||||
|
||||
// get free sexp_variables
|
||||
start = sexp_variable_allocate_block(Ships[m_ship_num].ship_name, SEXP_VARIABLE_BLOCK | SEXP_VARIABLE_BLOCK_HIT);
|
||||
if (start == -1) {
|
||||
MessageBox("Unable to allocate storage, try deleting Sexp variables");
|
||||
return;
|
||||
} else {
|
||||
Ships[m_ship_num].special_hitpoint_index = start;
|
||||
}
|
||||
} else {
|
||||
start = Ships[m_ship_num].special_hitpoint_index;
|
||||
}
|
||||
// set to update
|
||||
set_modified();
|
||||
|
||||
// set em
|
||||
sprintf(Sexp_variables[start+SHIELD_STRENGTH].text, "%d", m_shields);
|
||||
sprintf(Sexp_variables[start+HULL_STRENGTH].text, "%d", m_hull);
|
||||
new_hull_strength = m_hull;
|
||||
//Ships[m_ship_num].special_hitpoints = m_hull;
|
||||
|
||||
} else {
|
||||
if (Ships[m_ship_num].special_hitpoint_index != -1) {
|
||||
// set to update
|
||||
set_modified();
|
||||
}
|
||||
else {
|
||||
// set to update
|
||||
set_modified();
|
||||
|
||||
// free block
|
||||
sexp_variable_block_free(Ships[m_ship_num].ship_name, Ships[m_ship_num].special_hitpoint_index, SEXP_VARIABLE_BLOCK | SEXP_VARIABLE_BLOCK_HIT);
|
||||
new_hull_strength = 0;
|
||||
}
|
||||
|
||||
// set index to no hit block
|
||||
Ships[m_ship_num].special_hitpoint_index = -1;
|
||||
if (m_special_shield_enabled) {
|
||||
|
||||
// Don't update anything if the hull strength is invalid
|
||||
if (m_shields < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// set to update
|
||||
set_modified();
|
||||
|
||||
new_shield_strength = m_shields;
|
||||
//Ships[m_ship_num].special_shield = m_shields;
|
||||
|
||||
}
|
||||
else {
|
||||
// set to update
|
||||
set_modified();
|
||||
|
||||
new_shield_strength = -1;
|
||||
}
|
||||
|
||||
// calc kamikaze stuff
|
||||
if (Ships[m_ship_num].special_hitpoint_index != -1)
|
||||
{
|
||||
temp_max_hull_strength = (float) atoi(Sexp_variables[Ships[m_ship_num].special_hitpoint_index+HULL_STRENGTH].text);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_max_hull_strength = Ship_info[Ships[m_ship_num].ship_info_index].max_hull_strength;
|
||||
for ( i=0; i<num_selected_ships; i++) {
|
||||
// set the special hitpoints/shield
|
||||
Ships[m_selected_ships[i]].special_hitpoints = new_hull_strength;
|
||||
Ships[m_selected_ships[i]].special_shield = new_shield_strength;
|
||||
|
||||
// calc kamikaze stuff
|
||||
if (Ships[m_selected_ships[i]].special_hitpoints)
|
||||
{
|
||||
temp_max_hull_strength = (float)Ships[m_selected_ships[i]].special_hitpoints;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_max_hull_strength = Ship_info[Ships[m_selected_ships[i]].ship_info_index].max_hull_strength;
|
||||
}
|
||||
|
||||
Ai_info[Ships[m_selected_ships[i]].ai_index].kamikaze_damage = min(1000.0f, 200.0f + (temp_max_hull_strength / 4.0f));
|
||||
|
||||
|
||||
}
|
||||
|
||||
Ai_info[Ships[m_ship_num].ai_index].kamikaze_damage = min(1000.0f, 200.0f + (temp_max_hull_strength / 4.0f));
|
||||
|
||||
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
@@ -23,11 +23,16 @@ public:
|
||||
//{{AFX_DATA(ShipSpecialHitpoints)
|
||||
enum { IDD = IDD_SPECIAL_HITPOINTS };
|
||||
BOOL m_special_hitpoints_enabled;
|
||||
BOOL m_special_shield_enabled;
|
||||
int m_shields;
|
||||
int m_hull;
|
||||
int m_ship_num;
|
||||
//}}AFX_DATA
|
||||
|
||||
private:
|
||||
// variables to handle selection of multiple ships
|
||||
int m_selected_ships[MAX_SHIPS];
|
||||
int num_selected_ships;
|
||||
int m_ship_num;
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
@@ -42,6 +47,7 @@ protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(ShipSpecialHitpoints)
|
||||
afx_msg void OnEnableSpecialHitpoints();
|
||||
afx_msg void OnEnableSpecialShieldpoints();
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void DoGray();
|
||||
virtual void OnCancel();
|
||||
|
||||
@@ -778,7 +778,7 @@ void wing_editor::update_data_safe()
|
||||
MODIFY(Wings[cur_wing].wave_delay_max, m_arrival_delay_max);
|
||||
MODIFY(Wings[cur_wing].arrival_distance, m_arrival_dist);
|
||||
if (m_arrival_target >= 0) {
|
||||
i = ((CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET)) -> GetItemData(m_arrival_target);
|
||||
i = ((CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET))->GetItemData(m_arrival_target);
|
||||
MODIFY(Wings[cur_wing].arrival_anchor, i);
|
||||
|
||||
// when arriving near or in front of a ship, be sure that we are far enough away from it!!!
|
||||
@@ -788,7 +788,7 @@ void wing_editor::update_data_safe()
|
||||
if (!bypass_errors) {
|
||||
sprintf(buf, "Ship must arrive at least %d meters away from target.\n"
|
||||
"Value has been reset to this. Use with caution!\r\n"
|
||||
"Reccomended distance is %d meters.\r\n", d, (int)(2.0f * Objects[Ships[i].objnum].radius) );
|
||||
"Recommended distance is %d meters.\r\n", d, (int)(2.0f * Objects[Ships[i].objnum].radius) );
|
||||
|
||||
MessageBox(buf);
|
||||
}
|
||||
@@ -802,9 +802,10 @@ void wing_editor::update_data_safe()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i = ((CComboBox*)GetDlgItem(IDC_DEPARTURE_TARGET))->GetItemData(m_departure_target);
|
||||
MODIFY(Wings[cur_wing].departure_anchor, i);
|
||||
if (m_departure_target >= 0) {
|
||||
i = ((CComboBox *) GetDlgItem(IDC_DEPARTURE_TARGET))->GetItemData(m_departure_target);
|
||||
MODIFY(Wings[cur_wing].departure_anchor, i);
|
||||
}
|
||||
|
||||
MODIFY(Wings[cur_wing].departure_delay, m_departure_delay);
|
||||
hotkey = m_hotkey - 1;
|
||||
|
||||
@@ -823,6 +823,7 @@ void game_sunspot_process(float frametime)
|
||||
|
||||
Sun_drew = 0;
|
||||
} else {
|
||||
Sun_spot_goal = 0.0f;
|
||||
if ( Sun_drew ) {
|
||||
// check sunspots for all suns
|
||||
n_lights = light_get_global_count();
|
||||
@@ -845,14 +846,10 @@ void game_sunspot_process(float frametime)
|
||||
|
||||
// draw the glow for this sun
|
||||
stars_draw_sun_glow(idx);
|
||||
} else {
|
||||
Sun_spot_goal = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
Sun_drew = 0;
|
||||
} else {
|
||||
Sun_spot_goal = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6211,11 +6208,17 @@ void game_leave_state( int old_state, int new_state )
|
||||
|
||||
case GS_STATE_DEATH_DIED:
|
||||
Game_mode &= ~GM_DEAD_DIED;
|
||||
|
||||
// early end while respawning or blowing up in a multiplayer game
|
||||
if((Game_mode & GM_MULTIPLAYER) && ((new_state == GS_STATE_DEBRIEF) || (new_state == GS_STATE_MULTI_DOGFIGHT_DEBRIEF)) ){
|
||||
game_stop_time();
|
||||
freespace_stop_mission();
|
||||
|
||||
if ( !(Game_mode & GM_MULTIPLAYER) ) {
|
||||
if ( end_mission && (new_state == GS_STATE_DEBRIEF) ) {
|
||||
freespace_stop_mission();
|
||||
}
|
||||
} else {
|
||||
// early end while respawning or blowing up in a multiplayer game
|
||||
if ( (new_state == GS_STATE_DEBRIEF) || (new_state == GS_STATE_MULTI_DOGFIGHT_DEBRIEF) ) {
|
||||
game_stop_time();
|
||||
freespace_stop_mission();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -6536,6 +6539,32 @@ void game_enter_state( int old_state, int new_state )
|
||||
//Game_time_compression = F1_0;
|
||||
}
|
||||
|
||||
/* game could be comming from a restart (rather than first start)
|
||||
so make sure that we zero the hud gauge overrides (Sexp_hud_*)
|
||||
\sa sexp_hud_display_gauge*/
|
||||
if ( (old_state == GS_STATE_GAME_PLAY)
|
||||
|| (old_state == GS_STATE_BRIEFING)
|
||||
|| (old_state == GS_STATE_DEBRIEF)
|
||||
|| (old_state == GS_STATE_SHIP_SELECT)
|
||||
|| (old_state == GS_STATE_WEAPON_SELECT)
|
||||
|| (old_state == GS_STATE_RED_ALERT) )
|
||||
{
|
||||
Sexp_hud_display_warpout = 0;
|
||||
}
|
||||
|
||||
/* game could be comming from a restart (rather than first start)
|
||||
so make sure that we zero the hud gauge overrides (Sexp_hud_*)
|
||||
\sa sexp_hud_display_gauge*/
|
||||
if ( (old_state == GS_STATE_GAME_PLAY)
|
||||
|| (old_state == GS_STATE_BRIEFING)
|
||||
|| (old_state == GS_STATE_DEBRIEF)
|
||||
|| (old_state == GS_STATE_SHIP_SELECT)
|
||||
|| (old_state == GS_STATE_WEAPON_SELECT)
|
||||
|| (old_state == GS_STATE_RED_ALERT) )
|
||||
{
|
||||
Sexp_hud_display_warpout = 0;
|
||||
}
|
||||
|
||||
// coming from the gameplay state or the main menu, we might need to load the mission
|
||||
if ( (Game_mode & GM_NORMAL) && ((old_state == GS_STATE_MAIN_MENU) || (old_state == GS_STATE_GAME_PLAY) || (old_state == GS_STATE_DEATH_BLEW_UP)) ) {
|
||||
if ( !game_start_mission() ) // this should put us into a new state.
|
||||
|
||||
@@ -336,8 +336,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,6,11,0000
|
||||
PRODUCTVERSION 3,6,11,0000
|
||||
FILEVERSION 3,6,12,0
|
||||
PRODUCTVERSION 3,6,12,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -354,12 +354,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Volition Inc."
|
||||
VALUE "FileDescription", "FreeSpace 2 Open"
|
||||
VALUE "FileVersion", "3.6.11.0000"
|
||||
VALUE "FileVersion", "3.6.12.0"
|
||||
VALUE "InternalName", "FreeSpace 2 Open"
|
||||
VALUE "LegalCopyright", "Copyright © 1998"
|
||||
VALUE "OriginalFilename", "fs2.exe"
|
||||
VALUE "ProductName", "FreeSpace 2 Open"
|
||||
VALUE "ProductVersion", "3.6.11"
|
||||
VALUE "ProductVersion", "3.6.12.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -66,7 +66,8 @@ static bool do_full_packet = true;
|
||||
|
||||
static int Local_timeout = -1;
|
||||
static int Next_gameserver_update = -1;
|
||||
static int Last_pong = -1;
|
||||
static int Ping_timestamp = -1;
|
||||
static int Last_activity = -1;
|
||||
static int Login_retry_time = -1;
|
||||
|
||||
static SCP_vector<file_record> FS2NetD_file_list;
|
||||
@@ -92,7 +93,8 @@ static void fs2netd_reset_state()
|
||||
do_full_packet = true;
|
||||
Local_timeout = -1;
|
||||
Next_gameserver_update = -1;
|
||||
Last_pong = -1;
|
||||
Last_activity = -1;
|
||||
Ping_timestamp = -1;
|
||||
Duplicate_login_detected = false;
|
||||
Login_retry_time = -1;
|
||||
}
|
||||
@@ -167,19 +169,38 @@ void fs2netd_reset_connection()
|
||||
|
||||
FS2NetD_Disconnect();
|
||||
|
||||
// wait a little to allow for the port to clear
|
||||
Sleep(250);
|
||||
|
||||
fs2netd_reset_state();
|
||||
|
||||
// wait a little to allow for the port to clear
|
||||
Sleep(500);
|
||||
|
||||
// try to reinit the server connection
|
||||
fs2netd_login();
|
||||
|
||||
if (reset_gameserver) {
|
||||
Sleep(250);
|
||||
|
||||
if ( reset_gameserver && fs2netd_is_online() ) {
|
||||
fs2netd_gameserver_start();
|
||||
}
|
||||
}
|
||||
|
||||
void fs2netd_disconnect()
|
||||
{
|
||||
if ( !Is_connected ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Net_player->flags & NETINFO_FLAG_MT_CONNECTED) {
|
||||
fs2netd_gameserver_disconnect();
|
||||
}
|
||||
|
||||
FS2NetD_Disconnect();
|
||||
|
||||
fs2netd_reset_state();
|
||||
|
||||
Sleep(500);
|
||||
}
|
||||
|
||||
static int fs2netd_connect_do()
|
||||
{
|
||||
int retval = FS2NetD_ConnectToServer(Multi_options_g.game_tracker_ip, Multi_options_g.tracker_port);
|
||||
@@ -307,6 +328,10 @@ int fs2netd_login_do()
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (do_full_packet) {
|
||||
ml_printf("FS2NetD MSG: Requesting login pilot stats for '%s' ...", Players[Player_num].callsign);
|
||||
}
|
||||
|
||||
int rescode = FS2NetD_GetPlayerData(Players[Player_num].callsign, &Players[Player_num], true, do_full_packet);
|
||||
|
||||
do_full_packet = false;
|
||||
@@ -469,6 +494,9 @@ bool fs2netd_login()
|
||||
if (retval) {
|
||||
Logged_in = true;
|
||||
sprintf(Multi_tracker_id_string, "%d", Multi_tracker_id);
|
||||
} else {
|
||||
// clear and reset connection, for the next time we try...
|
||||
fs2netd_disconnect();
|
||||
}
|
||||
|
||||
if (Is_standalone) {
|
||||
@@ -480,11 +508,13 @@ bool fs2netd_login()
|
||||
|
||||
static void fs2netd_handle_ping()
|
||||
{
|
||||
static int Next_ping = -1;
|
||||
bool reset = false;
|
||||
static int CONN_check = -1;
|
||||
|
||||
// if we didn't get a pong within 30 seconds of a ping then assume that the
|
||||
// server connection must of have dropped or is otherwise unresponsive
|
||||
if ( (Ping_timestamp != -1) && ((timer_get_seconds() - Ping_timestamp) > 30) ) {
|
||||
Ping_timestamp = -1;
|
||||
|
||||
// if we didn't get a PONG within 4 minutes the server connection must have dropped
|
||||
if ( (Last_pong != -1) && ((Next_ping - Last_pong) > 240) ) {
|
||||
ml_string("FS2NetD WARNING: Lost connection to server!");
|
||||
fs2netd_reset_connection();
|
||||
|
||||
@@ -496,11 +526,11 @@ static void fs2netd_handle_ping()
|
||||
}
|
||||
|
||||
ml_string("FS2NetD ERROR: Lost connection to the FS2NetD server!");
|
||||
FS2NetD_Disconnect();
|
||||
fs2netd_reset_state();
|
||||
|
||||
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 30 minutes...");
|
||||
Login_retry_time = timer_get_seconds() + 1800;
|
||||
fs2netd_disconnect();
|
||||
|
||||
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 5 minutes...");
|
||||
Login_retry_time = timer_get_seconds() + 300;
|
||||
|
||||
return;
|
||||
} else {
|
||||
@@ -508,24 +538,24 @@ static void fs2netd_handle_ping()
|
||||
}
|
||||
}
|
||||
|
||||
// send out ping every 90 seconds
|
||||
if ( (Next_ping == -1) || (timer_get_seconds() >= Next_ping) ) {
|
||||
// if we have seen a long period of time between pings then reset the pong time too
|
||||
if ( (timer_get_seconds() - Next_ping) > 120 ) {
|
||||
reset = true;
|
||||
}
|
||||
|
||||
Next_ping = timer_get_seconds() + 90;
|
||||
|
||||
// we go ahead and set the initial Last_pong here, even though we haven't gotten a pong yet
|
||||
if ( (Last_pong == -1) || reset ) {
|
||||
Last_pong = Next_ping;
|
||||
reset = false;
|
||||
}
|
||||
|
||||
// send out a ping after 5 minutes of no other activity to make sure the server
|
||||
// is still responding (probably not though)
|
||||
if ( (Ping_timestamp == -1) && (timer_get_seconds() >= (Last_activity + 300)) ) {
|
||||
Ping_timestamp = timer_get_seconds();
|
||||
FS2NetD_Ping();
|
||||
ml_string("FS2NetD sent PING");
|
||||
|
||||
// also send out a ID check to keep our login verified
|
||||
if (Last_activity < 0) {
|
||||
Last_activity = timer_get_seconds();
|
||||
}
|
||||
}
|
||||
|
||||
// check for a valid connection (SID, duplicate login, etc.)
|
||||
if ( (CONN_check == -1) || (timer_get_seconds() >= CONN_check) ) {
|
||||
// every 3 minutes
|
||||
CONN_check = timer_get_seconds() + 180;
|
||||
|
||||
// session ID check
|
||||
if ( FS2NetD_CheckValidID() < 0 ) {
|
||||
ml_string("FS2NetD WARNING: Unable to validate login!");
|
||||
fs2netd_reset_connection();
|
||||
@@ -538,11 +568,11 @@ static void fs2netd_handle_ping()
|
||||
}
|
||||
|
||||
ml_string("FS2NetD ERROR: Lost connection to the FS2NetD server!");
|
||||
FS2NetD_Disconnect();
|
||||
fs2netd_reset_state();
|
||||
|
||||
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 30 minutes...");
|
||||
Login_retry_time = timer_get_seconds() + 1800;
|
||||
fs2netd_disconnect();
|
||||
|
||||
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 5 minutes...");
|
||||
Login_retry_time = timer_get_seconds() + 300;
|
||||
|
||||
return;
|
||||
} else {
|
||||
@@ -555,7 +585,7 @@ static void fs2netd_handle_ping()
|
||||
FS2NetD_CheckDuplicateLogin();
|
||||
}
|
||||
|
||||
ml_string("FS2NetD sent PING/IDENT");
|
||||
ml_string("FS2NetD sent IDENT check");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -584,6 +614,8 @@ static void fs2netd_handle_messages()
|
||||
return;
|
||||
}
|
||||
|
||||
Last_activity = timer_get_seconds();
|
||||
|
||||
buffer_offset = 0;
|
||||
|
||||
while (buffer_offset+BASE_PACKET_SIZE <= bytes_read) {
|
||||
@@ -612,7 +644,8 @@ static void fs2netd_handle_messages()
|
||||
|
||||
ml_printf("FS2NetD PONG: %d ms", timer_get_milliseconds() - itemp);
|
||||
|
||||
Last_pong = timer_get_seconds();
|
||||
// reset timestamp, since the ping was successful
|
||||
Ping_timestamp = -1;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -739,8 +772,8 @@ void fs2netd_do_frame()
|
||||
fs2netd_login();
|
||||
|
||||
if ( !Logged_in ) {
|
||||
// bah! try again in another 30 minutes
|
||||
Login_retry_time = timer_get_seconds() + 1800;
|
||||
// bah! try again in another 5 minutes
|
||||
Login_retry_time = timer_get_seconds() + 300;
|
||||
} else {
|
||||
Login_retry_time = -1;
|
||||
}
|
||||
@@ -1550,6 +1583,10 @@ int fs2netd_get_pilot_info(const char *callsign, player *out_plr, bool first_cal
|
||||
In_process = true;
|
||||
}
|
||||
|
||||
if (first_call) {
|
||||
ml_printf("FS2NetD MSG: Requesting pilot stats for '%s' ...", callsign);
|
||||
}
|
||||
|
||||
int rc = FS2NetD_GetPlayerData(callsign, &new_plr, false, first_call);
|
||||
|
||||
// some sort of failure
|
||||
|
||||
@@ -47,6 +47,7 @@ extern tracker_game_data Multi_tracker_game_data;
|
||||
bool fs2netd_is_online();
|
||||
|
||||
void fs2netd_reset_connection();
|
||||
void fs2netd_disconnect();
|
||||
|
||||
void fs2netd_close();
|
||||
|
||||
|
||||
@@ -265,8 +265,8 @@ int FS2NetD_GetPlayerData(const char *player_name, player *pl, bool can_create,
|
||||
|
||||
PXO_GET_DATA( reply_type );
|
||||
|
||||
// if we weren't retrieved or created then bail out now
|
||||
if (reply_type > 1) {
|
||||
// if we weren't retrieved then bail out now
|
||||
if (reply_type != 0) {
|
||||
return (int)reply_type;
|
||||
}
|
||||
|
||||
|
||||
+35
-24
@@ -480,29 +480,6 @@ void event_music_do_frame()
|
||||
}
|
||||
}
|
||||
|
||||
// We want to go back to NRML track music if all the hostiles have been
|
||||
// destroyed, and we are still playing the battle music
|
||||
if (Current_pattern == SONG_BTTL_1 || Current_pattern == SONG_BTTL_2 || Current_pattern == SONG_BTTL_3)
|
||||
{
|
||||
if (timestamp_elapsed(Battle_over_timestamp) && Event_Music_battle_started == 1)
|
||||
{
|
||||
if (hostile_ships_present() == FALSE)
|
||||
{
|
||||
if (Patterns[Current_pattern].next_pattern != SONG_VICT_2)
|
||||
{
|
||||
// Goober5000
|
||||
if (Soundtracks[Current_soundtrack_num].flags & EMF_CYCLE_FS1)
|
||||
Patterns[Current_pattern].next_pattern = SONG_NRML_3;
|
||||
else
|
||||
Patterns[Current_pattern].next_pattern = SONG_NRML_1;
|
||||
|
||||
Patterns[Current_pattern].force_pattern = TRUE;
|
||||
Event_Music_battle_started = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Event_Music_battle_started == 0) {
|
||||
if (Current_pattern == SONG_NRML_1 || Current_pattern == SONG_NRML_2 || Current_pattern == SONG_NRML_3 ) {
|
||||
if (timestamp_elapsed(Check_for_battle_music)) {
|
||||
@@ -512,6 +489,39 @@ void event_music_do_frame()
|
||||
Patterns[Current_pattern].force_pattern = TRUE;
|
||||
}
|
||||
}
|
||||
} else if (Current_pattern == SONG_BTTL_1 || Current_pattern == SONG_BTTL_2 || Current_pattern == SONG_BTTL_3) {
|
||||
if (timestamp_elapsed(Battle_over_timestamp)) {
|
||||
Battle_over_timestamp = timestamp(BATTLE_CHECK_INTERVAL);
|
||||
if (hostile_ships_present() == FALSE) {
|
||||
Patterns[Current_pattern].force_pattern = TRUE;
|
||||
|
||||
if (Soundtracks[Current_soundtrack_num].flags & EMF_CYCLE_FS1) {
|
||||
Patterns[Current_pattern].next_pattern = SONG_NRML_3;
|
||||
} else {
|
||||
Patterns[Current_pattern].next_pattern = SONG_NRML_1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We want to go back to NRML track music if all the hostiles have been
|
||||
// destroyed, and we are still playing the battle music
|
||||
if (Current_pattern == SONG_BTTL_1 || Current_pattern == SONG_BTTL_2 || Current_pattern == SONG_BTTL_3) {
|
||||
if (timestamp_elapsed(Battle_over_timestamp)) {
|
||||
if (hostile_ships_present() == FALSE) {
|
||||
if (Patterns[Current_pattern].next_pattern != SONG_VICT_2) {
|
||||
// Goober5000
|
||||
if (Soundtracks[Current_soundtrack_num].flags & EMF_CYCLE_FS1) {
|
||||
Patterns[Current_pattern].next_pattern = SONG_NRML_3;
|
||||
} else {
|
||||
Patterns[Current_pattern].next_pattern = SONG_NRML_1;
|
||||
}
|
||||
|
||||
Patterns[Current_pattern].force_pattern = TRUE;
|
||||
Event_Music_battle_started = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1361,7 +1371,8 @@ void parse_menumusic()
|
||||
if ( cf_exists_full_ext(Spooled_music[idx].filename, CF_TYPE_MUSIC, NUM_EXT, exts) )
|
||||
Spooled_music[idx].flags |= SMF_VALID;
|
||||
|
||||
Num_music_files++;
|
||||
if (!nocreate)
|
||||
Num_music_files++;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
+84
-68
@@ -13,14 +13,13 @@
|
||||
#include "localization/localize.h"
|
||||
#include "species_defs/species_defs.h"
|
||||
#include "parse/parselo.h"
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
int Num_game_sounds = 0;
|
||||
game_snd *Snds = NULL;
|
||||
SCP_vector<game_snd> Snds;
|
||||
|
||||
int Num_iface_sounds = 0;
|
||||
game_snd *Snds_iface = NULL;
|
||||
int *Snds_iface_handle = NULL;
|
||||
SCP_vector<game_snd> Snds_iface;
|
||||
SCP_vector<int> Snds_iface_handle;
|
||||
|
||||
#define GAME_SND 0
|
||||
#define IFACE_SND 1
|
||||
@@ -38,7 +37,8 @@ void gamesnd_play_iface(int n)
|
||||
//WMC - now ignores file extension.
|
||||
int gamesnd_get_by_name(char* name)
|
||||
{
|
||||
for(int i = 0; i < Num_game_sounds; i++)
|
||||
Assert( Snds.size() <= INT_MAX );
|
||||
for(int i = 0; i < (int)Snds.size(); i++)
|
||||
{
|
||||
char *p = strrchr( Snds[i].filename, '.' );
|
||||
if(p == NULL)
|
||||
@@ -56,6 +56,31 @@ int gamesnd_get_by_name(char* name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int gamesnd_get_by_tbl_index(int index)
|
||||
{
|
||||
Assert( Snds.size() <= INT_MAX );
|
||||
for(int i = 0; i < (int)Snds.size(); i++) {
|
||||
if ( Snds[i].sig == index )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int gamesnd_get_by_iface_tbl_index(int index)
|
||||
{
|
||||
Assert( Snds_iface.size() <= INT_MAX );
|
||||
Assert( Snds_iface.size() == Snds_iface_handle.size() );
|
||||
for(int i = 0; i < (int)Snds_iface.size(); i++) {
|
||||
if ( Snds_iface[i].sig == index )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Takes a tag, a sound index destination, and the object name being parsed
|
||||
//tag and object_name are mostly so that we can debug stuff
|
||||
//This also means you shouldn't use optional_string or required_string,
|
||||
@@ -73,12 +98,18 @@ void parse_sound(char* tag, int *idx_dest, char* object_name)
|
||||
if(idx != -1)
|
||||
(*idx_dest) = idx;
|
||||
else
|
||||
(*idx_dest) = atoi(buf);
|
||||
|
||||
//Ensure sound is in range
|
||||
if((*idx_dest) < -1 || (*idx_dest) >= Num_game_sounds)
|
||||
{
|
||||
Warning(LOCATION, "%s sound index out of range on '%s'. Must be between 0 and %d. Forcing to -1 (Nonexistant sound).\n", tag, object_name, Num_game_sounds);
|
||||
idx = gamesnd_get_by_tbl_index(atoi(buf));
|
||||
if (idx != -1)
|
||||
(*idx_dest) = idx;
|
||||
}
|
||||
|
||||
Assert( Snds.size() <= INT_MAX );
|
||||
//Ensure sound is in range
|
||||
if((*idx_dest) < -1 || (*idx_dest) >= (int)Snds.size())
|
||||
{
|
||||
(*idx_dest) = -1;
|
||||
Warning(LOCATION, "%s sound index out of range on '%s'. Must be between 0 and %d. Forcing to -1 (Nonexistant sound).\n", tag, object_name, Snds.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,7 +127,8 @@ void gamesnd_preload_common_sounds()
|
||||
if ( !Sound_enabled )
|
||||
return;
|
||||
|
||||
for ( i = 0; i < Num_game_sounds; i++ ) {
|
||||
Assert( Snds.size() <= INT_MAX );
|
||||
for ( i = 0; i < (int)Snds.size(); i++ ) {
|
||||
gs = &Snds[i];
|
||||
if ( gs->filename[0] != 0 && strnicmp(gs->filename, NOX("none.wav"), 4) ) {
|
||||
if ( gs->preload ) {
|
||||
@@ -120,7 +152,8 @@ void gamesnd_load_gameplay_sounds()
|
||||
if ( !Sound_enabled )
|
||||
return;
|
||||
|
||||
for ( i = 0; i < Num_game_sounds; i++ ) {
|
||||
Assert( Snds.size() <= INT_MAX );
|
||||
for ( i = 0; i < (int)Snds.size(); i++ ) {
|
||||
gs = &Snds[i];
|
||||
if ( gs->filename[0] != 0 && strnicmp(gs->filename, NOX("none.wav"), 4) ) {
|
||||
if ( !gs->preload ) { // don't try to load anything that's already preloaded
|
||||
@@ -141,7 +174,8 @@ void gamesnd_unload_gameplay_sounds()
|
||||
int i;
|
||||
game_snd *gs;
|
||||
|
||||
for ( i = 0; i < Num_game_sounds; i++ ) {
|
||||
Assert( Snds.size() <= INT_MAX );
|
||||
for ( i = 0; i < (int)Snds.size(); i++ ) {
|
||||
gs = &Snds[i];
|
||||
if ( gs->id != -1 ) {
|
||||
snd_unload( gs->id );
|
||||
@@ -163,7 +197,8 @@ void gamesnd_load_interface_sounds()
|
||||
if ( !Sound_enabled )
|
||||
return;
|
||||
|
||||
for ( i = 0; i < Num_iface_sounds; i++ ) {
|
||||
Assert( Snds_iface.size() < INT_MAX );
|
||||
for ( i = 0; i < (int)Snds_iface.size(); i++ ) {
|
||||
gs = &Snds_iface[i];
|
||||
if ( gs->filename[0] != 0 && strnicmp(gs->filename, NOX("none.wav"), 4) ) {
|
||||
gs->id = snd_load(gs);
|
||||
@@ -181,7 +216,8 @@ void gamesnd_unload_interface_sounds()
|
||||
int i;
|
||||
game_snd *gs;
|
||||
|
||||
for ( i = 0; i < Num_iface_sounds; i++ ) {
|
||||
Assert( Snds_iface.size() < INT_MAX );
|
||||
for ( i = 0; i < (int)Snds_iface.size(); i++ ) {
|
||||
gs = &Snds_iface[i];
|
||||
if ( gs->id != -1 ) {
|
||||
snd_unload( gs->id );
|
||||
@@ -255,7 +291,8 @@ void gamesnd_parse_soundstbl()
|
||||
// Parse the gameplay sounds section
|
||||
required_string("#Game Sounds Start");
|
||||
while (required_string_either("#Game Sounds End","$Name:")) {
|
||||
Assert( num_game_sounds < Num_game_sounds);
|
||||
Assert( Snds.size() < INT_MAX );
|
||||
Assert( num_game_sounds < (int)Snds.size() );
|
||||
gamesnd_parse_line( &Snds[num_game_sounds], "$Name:" );
|
||||
num_game_sounds++;
|
||||
gamesnd_add_sound_slot( GAME_SND, num_game_sounds );
|
||||
@@ -265,7 +302,8 @@ void gamesnd_parse_soundstbl()
|
||||
// Parse the interface sounds section
|
||||
required_string("#Interface Sounds Start");
|
||||
while (required_string_either("#Interface Sounds End","$Name:")) {
|
||||
Assert( num_iface_sounds < Num_iface_sounds);
|
||||
Assert( Snds_iface_handle.size() < INT_MAX );
|
||||
Assert( num_iface_sounds < (int)Snds_iface.size() );
|
||||
gamesnd_parse_line(&Snds_iface[num_iface_sounds], "$Name:");
|
||||
num_iface_sounds++;
|
||||
gamesnd_add_sound_slot( IFACE_SND, num_iface_sounds );
|
||||
@@ -326,6 +364,7 @@ void gamesnd_parse_soundstbl()
|
||||
//
|
||||
void gamesnd_init_struct(game_snd *gs)
|
||||
{
|
||||
gs->sig = -1;
|
||||
gs->filename[0] = 0;
|
||||
gs->id = -1;
|
||||
gs->id_sig = -1;
|
||||
@@ -341,33 +380,26 @@ void gamesnd_init_sounds()
|
||||
{
|
||||
int i;
|
||||
|
||||
if (Snds == NULL) {
|
||||
Snds = (game_snd *) vm_malloc (sizeof(game_snd) * MIN_GAME_SOUNDS);
|
||||
Verify( Snds != NULL );
|
||||
Num_game_sounds = MIN_GAME_SOUNDS;
|
||||
}
|
||||
Snds.clear();
|
||||
Snds.resize(MIN_GAME_SOUNDS);
|
||||
|
||||
Assert( Num_game_sounds > 0 );
|
||||
Assert( Snds.size() > 0 );
|
||||
|
||||
Assert( Snds.size() <= INT_MAX );
|
||||
// init the gameplay sounds
|
||||
for ( i = 0; i < Num_game_sounds; i++ ) {
|
||||
for ( i = 0; i < (int)Snds.size(); i++ ) {
|
||||
gamesnd_init_struct(&Snds[i]);
|
||||
}
|
||||
|
||||
if (Snds_iface == NULL) {
|
||||
Snds_iface = (game_snd *) vm_malloc (sizeof(game_snd) * MIN_INTERFACE_SOUNDS);
|
||||
Verify( Snds_iface != NULL );
|
||||
Num_iface_sounds = MIN_INTERFACE_SOUNDS;
|
||||
|
||||
Assert( Snds_iface_handle == NULL );
|
||||
Snds_iface_handle = (int *) vm_malloc (sizeof(int) * Num_iface_sounds);
|
||||
Verify( Snds_iface_handle != NULL );
|
||||
}
|
||||
|
||||
Assert( Num_iface_sounds > 0 );
|
||||
Snds_iface.clear();
|
||||
Snds_iface.resize(MIN_INTERFACE_SOUNDS);
|
||||
Snds_iface_handle.resize(MIN_INTERFACE_SOUNDS);
|
||||
|
||||
Assert( Snds_iface.size() > 0 );
|
||||
|
||||
Assert( Snds_iface.size() < INT_MAX );
|
||||
// init the interface sounds
|
||||
for ( i = 0; i < Num_iface_sounds; i++ ) {
|
||||
for ( i = 0; i < (int)Snds_iface.size(); i++ ) {
|
||||
gamesnd_init_struct(&Snds_iface[i]);
|
||||
Snds_iface_handle[i] = -1;
|
||||
}
|
||||
@@ -376,20 +408,9 @@ void gamesnd_init_sounds()
|
||||
// close out gamesnd, ONLY CALL FROM game_shutdown()!!!!
|
||||
void gamesnd_close()
|
||||
{
|
||||
if (Snds != NULL) {
|
||||
vm_free(Snds);
|
||||
Snds = NULL;
|
||||
}
|
||||
|
||||
if (Snds_iface != NULL) {
|
||||
vm_free(Snds_iface);
|
||||
Snds_iface = NULL;
|
||||
}
|
||||
|
||||
if (Snds_iface_handle != NULL) {
|
||||
vm_free(Snds_iface_handle);
|
||||
Snds_iface_handle = NULL;
|
||||
}
|
||||
Snds.clear();
|
||||
Snds_iface.clear();
|
||||
Snds_iface_handle.clear();
|
||||
}
|
||||
|
||||
// callback function for the UI code to call when the mouse first goes over a button.
|
||||
@@ -411,16 +432,14 @@ void gamesnd_add_sound_slot(int type, int num)
|
||||
switch (type) {
|
||||
case GAME_SND:
|
||||
{
|
||||
Assert( Snds != NULL );
|
||||
Assert( num < (Num_game_sounds + increase_by) );
|
||||
Assert( Snds.size() <= INT_MAX );
|
||||
Assert( num < ((int)Snds.size() + increase_by) );
|
||||
|
||||
if (num >= Num_game_sounds) {
|
||||
Snds = (game_snd *) vm_realloc (Snds, sizeof(game_snd) * (Num_game_sounds + increase_by));
|
||||
Verify( Snds != NULL );
|
||||
Num_game_sounds += increase_by;
|
||||
if (num >= (int)Snds.size()) {
|
||||
Snds.resize(Snds.size() + increase_by);
|
||||
|
||||
// default all new entries
|
||||
for (i = (Num_game_sounds - increase_by); i < Num_game_sounds; i++) {
|
||||
for (i = ((int)Snds.size() - increase_by); i < (int)Snds.size(); i++) {
|
||||
gamesnd_init_struct(&Snds[i]);
|
||||
}
|
||||
}
|
||||
@@ -429,20 +448,17 @@ void gamesnd_add_sound_slot(int type, int num)
|
||||
|
||||
case IFACE_SND:
|
||||
{
|
||||
Assert( Snds_iface != NULL );
|
||||
Assert( num < (Num_game_sounds + increase_by) );
|
||||
Assert( Snds_iface.size() < INT_MAX );
|
||||
Assert( num < ((int)Snds_iface.size() + increase_by) );
|
||||
|
||||
if (num >= Num_iface_sounds) {
|
||||
Snds_iface = (game_snd *) vm_realloc (Snds_iface, sizeof(game_snd) * (Num_iface_sounds + increase_by));
|
||||
Verify( Snds_iface != NULL );
|
||||
Num_iface_sounds += increase_by;
|
||||
if (num >= (int)Snds_iface.size()) {
|
||||
Snds_iface.resize(Snds_iface.size() + increase_by);
|
||||
|
||||
Assert( Snds_iface_handle != NULL );
|
||||
Snds_iface_handle = (int *) vm_realloc (Snds_iface_handle, sizeof(int) * Num_iface_sounds);
|
||||
Verify( Snds_iface_handle != NULL );
|
||||
Snds_iface_handle.resize(Snds_iface.size());
|
||||
Assert( Snds_iface.size() < INT_MAX );
|
||||
|
||||
// default all new entries
|
||||
for (i = (Num_iface_sounds - increase_by); i < Num_iface_sounds; i++) {
|
||||
for (i = ((int)Snds_iface_handle.size() - increase_by); i < (int)Snds_iface_handle.size(); i++) {
|
||||
gamesnd_init_struct(&Snds_iface[i]);
|
||||
Snds_iface_handle[i] = -1;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ void gamesnd_preload_common_sounds();
|
||||
void gamesnd_play_iface(int n);
|
||||
void gamesnd_play_error_beep();
|
||||
int gamesnd_get_by_name(char* name);
|
||||
int gamesnd_get_by_tbl_index(int index);
|
||||
int gamesnd_get_by_iface_tbl_index(int index);
|
||||
|
||||
//This should handle NO_SOUND just fine since it doesn't directly access lowlevel code
|
||||
//Does all parsing for a sound
|
||||
@@ -40,11 +42,8 @@ void common_play_highlight_sound();
|
||||
#define MIN_GAME_SOUNDS 202
|
||||
#define MIN_INTERFACE_SOUNDS 70
|
||||
|
||||
extern int Num_game_sounds;
|
||||
extern int Num_iface_sounds;
|
||||
|
||||
extern game_snd *Snds;
|
||||
extern game_snd *Snds_iface;
|
||||
extern SCP_vector<game_snd> Snds;
|
||||
extern SCP_vector<game_snd> Snds_iface;
|
||||
|
||||
|
||||
// symbolic names for misc. game sounds. The order here must match the order in
|
||||
|
||||
@@ -30,7 +30,7 @@ color *Color_netplayer[20] = {
|
||||
&Color_bright_blue,
|
||||
&Color_green,
|
||||
&Color_bright_green,
|
||||
&Color_black,
|
||||
&Color_pink,
|
||||
&Color_grey,
|
||||
&Color_silver,
|
||||
&Color_white,
|
||||
|
||||
@@ -762,6 +762,10 @@ $Circle Strafe Percent: 0, 0, 0, 0, 0 \n\
|
||||
;; capital ships when it is an option. \n""\
|
||||
$Glide Strafe Percent: 0, 0, 0, 0, 0 \n\
|
||||
\n\
|
||||
;; Percentage of the time where AI ships will randomly sidethrust in a \n\
|
||||
;; dogfight. \n\
|
||||
$Random Sidethrust Percent: 0, 0, 0, 0, 0 \n\
|
||||
\n\
|
||||
;; The amount of time required for the AI to detect \n\
|
||||
;; (and try to break) dogfight stalemate. \n\
|
||||
$Stalemate Time Threshold: 0, 0, 0, 0, 0 \n\
|
||||
@@ -812,6 +816,10 @@ $Chance AI Has to Fire Missiles at Player: 0, 1, 2, 3, 4 \n\
|
||||
;; aim. Applies for small ships vs small ships \n\
|
||||
$Max Aim Update Delay: 0, 0, 0, 0, 0 \n\
|
||||
\n\
|
||||
;; The maximum amount of delay allowed before turret AI will update its \n\
|
||||
;; aim. Applies for turrets vs small ships \n\
|
||||
$Turret Max Aim Update Delay: 0, 0, 0, 0, 0 \n\
|
||||
\n\
|
||||
;; General AI-related flags. These were previously all lumped together \n\
|
||||
;; under the New AI mission flag. \n\
|
||||
\n\
|
||||
@@ -928,7 +936,7 @@ $use only single fov for turrets: NO \n\
|
||||
\n\
|
||||
;; allow AI ships to dodge weapons vertically as well as horizontally \n\
|
||||
$allow vertical dodge: NO \n\
|
||||
\n\
|
||||
\n""\
|
||||
;; a disam or disable goal will protect a ship globally and purge \n\
|
||||
;; standing attack orders globally. If set to NO, only the ship/wing \n\
|
||||
;; given the order to disarm or disable will be affected. \n\
|
||||
@@ -938,6 +946,14 @@ $disarm or disable cause global ai goal effects: YES \n\
|
||||
;; This should be YES if you want anything in AI.tbl to mean anything \n\
|
||||
$fix AI class bug: NO \n\
|
||||
\n\
|
||||
;; If set, the AI will NOT make extra effort to avoid ramming the player\n\
|
||||
;; during dogfights. This results in more aggressive AI. \n\
|
||||
$no extra collision avoidance vs player: NO \n\
|
||||
\n\
|
||||
;; If set, the game will check if the dying ship is a player's wingman, \n\
|
||||
;; before making it give a death scream \n\
|
||||
$perform less checks for death screams: NO \n\
|
||||
\n\
|
||||
#End \n\
|
||||
";
|
||||
|
||||
@@ -969,6 +985,12 @@ $Linked: \n\
|
||||
+Snd File: none \n\
|
||||
$Hazard: \n\
|
||||
+Msg: Cannot engage autopilot: Hazard Near \n\
|
||||
+Snd File: none \n\
|
||||
$Support Present: \n\
|
||||
+Msg: Cannot engage autopilot: Support Ship Present \n\
|
||||
+Snd File: none \n\
|
||||
$Support Working: \n\
|
||||
+Msg: Cannot engage autopilot: Support Ship is rearming or repairing a ship \n\
|
||||
+Snd File: none \n\
|
||||
\n\
|
||||
#END \n\
|
||||
|
||||
@@ -123,5 +123,7 @@ extern int Num_medals;
|
||||
// from lighting.cpp
|
||||
#define MAX_LIGHTS 256
|
||||
|
||||
// from weapon.h (and beam.h)
|
||||
#define MAX_BEAM_SECTIONS 5
|
||||
|
||||
#endif // _GLOBALS_H
|
||||
@@ -180,6 +180,7 @@ void _cdecl WinAssert(char * text, char * filename, int linenum, const char * fo
|
||||
extern void LuaError(struct lua_State *L, char *format=NULL, ...);
|
||||
extern void _cdecl Error( const char * filename, int line, const char * format, ... );
|
||||
extern void _cdecl Warning( char * filename, int line, const char * format, ... );
|
||||
extern void _cdecl WarningEx( char *filename, int line, const char *format, ... );
|
||||
|
||||
extern int Global_warning_count;
|
||||
extern int Global_error_count;
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
|
||||
#define FS_VERSION_MAJOR 3 // major version
|
||||
#define FS_VERSION_MINOR 6 // increase by 1 for minor revs
|
||||
#define FS_VERSION_BUILD 11 // bugfix release
|
||||
#define FS_VERSION_REVIS 1111 // SVN revision
|
||||
#define FS_VERSION_BUILD 12 // bugfix release
|
||||
#define FS_VERSION_REVIS 0 // SVN revision
|
||||
|
||||
#define VERSION_LOC_FNAME "version.nfo"
|
||||
#define MOTD_LOC_FNAME "motd.txt"
|
||||
|
||||
@@ -1164,6 +1164,20 @@ void _cdecl Error( const char * filename, int line, const char * format, ... )
|
||||
Messagebox_active = false;
|
||||
}
|
||||
|
||||
void _cdecl WarningEx( char *filename, int line, const char *format, ... )
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (Cmdline_extra_warn) {
|
||||
char msg[sizeof(AssertText1)];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsprintf(msg, format, args);
|
||||
va_end(args);
|
||||
Warning(filename, line, msg);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void _cdecl Warning( char *filename, int line, const char *format, ... )
|
||||
{
|
||||
Global_warning_count++;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/globals.h"
|
||||
#include "bmpman/bmpman.h"
|
||||
#include "graphics/generic.h"
|
||||
#include "graphics/2d.h"
|
||||
@@ -19,6 +20,54 @@
|
||||
//we check background type to avoid messed up colours for ANI
|
||||
#define ANI_BPP_CHECK (ga->ani.bg_type == BM_TYPE_PCX) ? 16 : 32
|
||||
|
||||
// Goober5000
|
||||
int generic_anim_init_and_stream(generic_anim *anim, char *anim_filename, ubyte bg_type, bool attempt_hi_res)
|
||||
{
|
||||
int stream_result = -1;
|
||||
char filename[NAME_LENGTH];
|
||||
char *p;
|
||||
|
||||
Assert(anim != NULL);
|
||||
Assert(anim_filename != NULL);
|
||||
|
||||
// hi-res support
|
||||
if (attempt_hi_res && (gr_screen.res == GR_1024)) {
|
||||
// attempt to load a hi-res animation
|
||||
memset(filename, 0, NAME_LENGTH);
|
||||
strcpy_s(filename, "2_");
|
||||
strncat(filename, anim_filename, NAME_LENGTH - 3);
|
||||
|
||||
// remove extension
|
||||
p = strchr(filename, '.');
|
||||
if(p) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
// attempt to stream the hi-res ani
|
||||
generic_anim_init(anim, filename);
|
||||
anim->ani.bg_type = bg_type;
|
||||
stream_result = generic_anim_stream(anim);
|
||||
}
|
||||
|
||||
// we failed to stream hi-res, or we aren't running in hi-res, so try low-res
|
||||
if (stream_result < 0) {
|
||||
strcpy_s(filename, anim_filename);
|
||||
|
||||
// remove extension
|
||||
p = strchr(filename, '.');
|
||||
if(p) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
// attempt to stream the low-res ani
|
||||
generic_anim_init(anim, filename);
|
||||
anim->ani.bg_type = bg_type;
|
||||
stream_result = generic_anim_stream(anim);
|
||||
}
|
||||
|
||||
return stream_result;
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
void generic_anim_init(generic_anim *ga, char *filename)
|
||||
{
|
||||
@@ -317,7 +366,7 @@ void generic_anim_render(generic_anim *ga, float frametime, int x, int y)
|
||||
if((ga->direction & GENERIC_ANIM_DIRECTION_PAUSED) == 0) {
|
||||
if(ga->direction & GENERIC_ANIM_DIRECTION_BACKWARDS) {
|
||||
//keep going forwards if we're in a keyframe loop
|
||||
if(ga->keyframe && (ga->anim_time > keytime)) {
|
||||
if(ga->keyframe && (ga->anim_time >= keytime)) {
|
||||
ga->anim_time += frametime;
|
||||
if(ga->anim_time >= ga->total_time) {
|
||||
ga->anim_time = keytime - 0.001f;
|
||||
@@ -327,11 +376,11 @@ void generic_anim_render(generic_anim *ga, float frametime, int x, int y)
|
||||
else {
|
||||
//playing backwards
|
||||
ga->anim_time -= frametime;
|
||||
if((ga->direction & GENERIC_ANIM_DIRECTION_NOLOOP) && ga->anim_time < 0.0) {
|
||||
if((ga->direction & GENERIC_ANIM_DIRECTION_NOLOOP) && ga->anim_time <= 0.0) {
|
||||
ga->anim_time = 0; //stop on first frame when playing in reverse
|
||||
}
|
||||
else {
|
||||
while(ga->anim_time < 0.0)
|
||||
while(ga->anim_time <= 0.0)
|
||||
ga->anim_time += ga->total_time; //make sure we're always positive, so we can go back to the end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ typedef struct generic_bitmap {
|
||||
int bitmap_id;
|
||||
} generic_bitmap;
|
||||
|
||||
|
||||
int generic_anim_init_and_stream(generic_anim *anim, char *anim_filename, ubyte bg_type, bool attempt_hi_res);
|
||||
void generic_anim_init(generic_anim *ga, char *filename = NULL);
|
||||
void generic_bitmap_init(generic_bitmap *gb, char *filename = NULL);
|
||||
int generic_anim_load(generic_anim *ga);
|
||||
|
||||
@@ -453,7 +453,11 @@ void gr_opengl_set_clip(int x, int y, int w, int h, bool resize)
|
||||
}
|
||||
|
||||
GL_state.ScissorTest(GL_TRUE);
|
||||
glScissor(x, gr_screen.max_h-y-h, w, h);
|
||||
if(GL_rendering_to_framebuffer) {
|
||||
glScissor(x, y, w, h);
|
||||
} else {
|
||||
glScissor(x, gr_screen.max_h-y-h, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
void gr_opengl_reset_clip()
|
||||
|
||||
@@ -10,9 +10,19 @@ using namespace opengl;
|
||||
bool post_effect::changed = true;
|
||||
|
||||
texture *bloom::high_pass(texture *image, int size) {
|
||||
Assert(image);
|
||||
Assert(size != 0);
|
||||
|
||||
if ( !image ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get bright pass filter
|
||||
special_shader *bright_sdr = shader_manager::get()->get_special_shader(special_shader::bright_pass);
|
||||
|
||||
if ( !bright_sdr ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Acquire render target
|
||||
opengl::render_target *target;
|
||||
|
||||
@@ -28,11 +38,13 @@ texture *bloom::high_pass(texture *image, int size) {
|
||||
target->apply();
|
||||
target->attach_texture(tex);
|
||||
target->clear(render_target::clr_color);
|
||||
// Apply bright pass filter
|
||||
special_shader *bright_sdr = shader_manager::get()->apply_special_shader(special_shader::bright_pass);
|
||||
|
||||
if (!bright_sdr)
|
||||
// Apply bright pass filter
|
||||
if ( !bright_sdr->start_pass(0) ) {
|
||||
render_target::release(target);
|
||||
texture_pool::release(tex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bright_sdr->set_texture(b_texture, image);
|
||||
|
||||
@@ -43,9 +55,19 @@ texture *bloom::high_pass(texture *image, int size) {
|
||||
}
|
||||
|
||||
texture *bloom::blur(texture *image, int size) {
|
||||
Assert(image);
|
||||
Assert(size != 0);
|
||||
|
||||
if ( !image ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Blur
|
||||
special_shader *blur_sdr = shader_manager::get()->get_special_shader(special_shader::blur);
|
||||
|
||||
if ( !blur_sdr ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Acquire render target
|
||||
opengl::render_target *target;
|
||||
|
||||
@@ -63,9 +85,12 @@ texture *bloom::blur(texture *image, int size) {
|
||||
target->apply();
|
||||
|
||||
// Blur
|
||||
special_shader *blur_sdr = shader_manager::get()->apply_special_shader(special_shader::blur);
|
||||
if (!blur_sdr)
|
||||
if ( !blur_sdr->start_pass(0) ) {
|
||||
render_target::release(target);
|
||||
texture_pool::release(texture0);
|
||||
texture_pool::release(texture1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int pass = 0; pass < 2; pass++) {
|
||||
target->attach_texture(!pass ? texture0 : texture1);
|
||||
@@ -101,7 +126,6 @@ bool bloom::begin(texture *pp_img) {
|
||||
|
||||
void bloom::end() {
|
||||
if (config::get_integer(config::bloom_int)) {
|
||||
Assert(blurred);
|
||||
texture_pool::release(blurred);
|
||||
}
|
||||
}
|
||||
@@ -126,6 +150,12 @@ void bloom::set_uniforms(post_shader *sdr) {
|
||||
bool depth_of_field::begin(texture *pp_img) {
|
||||
Assert(pp_img);
|
||||
|
||||
special_shader *blur_sdr = shader_manager::get()->apply_special_shader(special_shader::blur);
|
||||
|
||||
if ( !blur_sdr ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
render_target *target;
|
||||
|
||||
target = render_target::acquire(gr_screen.max_w / 4, gr_screen.max_h / 4);
|
||||
@@ -140,10 +170,12 @@ bool depth_of_field::begin(texture *pp_img) {
|
||||
Assert(texture0);
|
||||
Assert(texture1);
|
||||
|
||||
special_shader *blur_sdr = shader_manager::get()->apply_special_shader(special_shader::blur);
|
||||
|
||||
if (!blur_sdr)
|
||||
if ( !blur_sdr->start_pass(0) ) {
|
||||
render_target::release(target);
|
||||
texture_pool::release(texture0);
|
||||
texture_pool::release(texture1);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int pass = 0; pass < 2; pass++) {
|
||||
target->attach_texture(!pass ? texture0 : texture1);
|
||||
@@ -201,19 +233,19 @@ void simple_effects::read_list() {
|
||||
required_string("#Effects");
|
||||
while (required_string_either("#End", "$Name:")) {
|
||||
post_effect eff;
|
||||
char buf[NAME_LENGTH];
|
||||
char buf[NAME_LENGTH+1] = { 0 };
|
||||
|
||||
required_string("$Name:");
|
||||
stuff_string(buf, F_NAME, NAME_LENGTH);
|
||||
eff.name = vm_strdup(buf);
|
||||
eff.name = buf;
|
||||
|
||||
required_string("$Uniform:");
|
||||
stuff_string(buf, F_NAME, NAME_LENGTH);
|
||||
eff.uniform_name = vm_strdup(buf);
|
||||
eff.uniform_name = buf;
|
||||
|
||||
required_string("$Define:");
|
||||
stuff_string(buf, F_NAME, NAME_LENGTH);
|
||||
eff.define_name = vm_strdup(buf);
|
||||
eff.define_name = buf;
|
||||
|
||||
required_string("$AlwaysOn:");
|
||||
stuff_boolean(&eff.always_on);
|
||||
@@ -272,8 +304,18 @@ post_processing *post_processing::instance = NULL;
|
||||
|
||||
void post_processing::create() {
|
||||
Assert(instance == NULL);
|
||||
if (config::is_enabled(config::post_process))
|
||||
instance = new post_processing;
|
||||
if (config::is_enabled(config::post_process)) {
|
||||
instance = new(std::nothrow) post_processing;
|
||||
|
||||
if ( instance && !config::is_enabled(config::post_process) ) {
|
||||
delete instance;
|
||||
instance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !instance ) {
|
||||
config::disable(config::post_process);
|
||||
}
|
||||
}
|
||||
|
||||
void post_processing::remove() {
|
||||
@@ -295,14 +337,26 @@ post_processing::post_processing() {
|
||||
image = texture_pool::acquire(target->get_width(), target->get_height());
|
||||
target->attach_texture(image);
|
||||
|
||||
bloom_eff = NULL;
|
||||
simple_eff = NULL;
|
||||
#ifdef DEPTH_OF_FIELD
|
||||
dof_eff = NULL;
|
||||
#endif
|
||||
|
||||
if (!target->check_status()) {
|
||||
mprintf(("FBO error. Could not initialize post-processing.\n"));
|
||||
config::disable(config::post_process);
|
||||
} else {
|
||||
bloom_eff = new bloom;
|
||||
simple_eff = new simple_effects;
|
||||
bloom_eff = new(std::nothrow) bloom;
|
||||
simple_eff = new(std::nothrow) simple_effects;
|
||||
|
||||
if ( !(bloom_eff && simple_eff) ) {
|
||||
mprintf(("Memory error. Could not initialize post-processing.\n"));
|
||||
config::disable(config::post_process);
|
||||
}
|
||||
|
||||
#ifdef DEPTH_OF_FIELD
|
||||
dof_eff = new depth_of_field;
|
||||
dof_eff = new(std::nothrow) depth_of_field;
|
||||
|
||||
depth = texture::create(target->get_width(), target->get_height(), texture::fmt_depth);
|
||||
#endif
|
||||
@@ -473,6 +527,12 @@ void gr_opengl_post_process_init() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!resources::text_file::file_exist("post_processing.tbl", resources::text_file::table_file)) {
|
||||
mprintf(("Post-processing table not found. Disabling...\n"));
|
||||
Cmdline_postprocess = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
opengl::post_processing::create();
|
||||
|
||||
opengl::simple_effects::restore_defaults();
|
||||
|
||||
@@ -204,13 +204,13 @@ static const int Num_shader_files = sizeof(GL_shader_file) / sizeof(opengl_shade
|
||||
// Resources system - move it to more appropiate file as soon as we get working resource manager
|
||||
using namespace resources;
|
||||
|
||||
text_file::text_file(const char *filename, txt_file_type ftype) {
|
||||
bool text_file::open(const char *filename, txt_file_type ftype) {
|
||||
// open file
|
||||
CFILE *fp = cfopen(const_cast<char*>(filename), "rt", CFILE_NORMAL, get_cfile_type(ftype));
|
||||
|
||||
if (!fp) {
|
||||
mprintf(("Could not open text file \'%s\'.\n", filename));
|
||||
return;
|
||||
// nprintf(("SHADER_DEBUG", "Could not open text file \'%s\'.\n", filename));
|
||||
return false;
|
||||
}
|
||||
|
||||
// load file
|
||||
@@ -225,6 +225,8 @@ text_file::text_file(const char *filename, txt_file_type ftype) {
|
||||
|
||||
// clean
|
||||
vm_free(bytes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const SCP_string &text_file::read() const {
|
||||
@@ -273,13 +275,13 @@ bool opengl::shader::compile_link() {
|
||||
do {
|
||||
vert = compile_object((const GLcharARB*)vert_src, GL_VERTEX_SHADER_ARB);
|
||||
if (!vert) {
|
||||
mprintf(("ERROR! Unable to create vertex shader!\n"));
|
||||
mprintf((" ERROR! Unable to create vertex shader!\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
frag = compile_object((const GLcharARB*)frag_src, GL_FRAGMENT_SHADER_ARB);
|
||||
if (!frag) {
|
||||
mprintf(("ERROR! Unable to create fragment shader!\n"));
|
||||
mprintf((" ERROR! Unable to create fragment shader!\n"));
|
||||
break;
|
||||
}
|
||||
} while (false);
|
||||
@@ -288,7 +290,7 @@ bool opengl::shader::compile_link() {
|
||||
if (vert && frag) {
|
||||
shader_program = link_objects(vert, frag);
|
||||
if (!shader_program)
|
||||
mprintf(("ERROR! Unable to create shader program!\n"));
|
||||
mprintf((" ERROR! Unable to create shader program!\n"));
|
||||
}
|
||||
|
||||
// clean
|
||||
@@ -331,7 +333,7 @@ GLhandleARB opengl::shader::compile_object(const GLcharARB *shader_source, GLenu
|
||||
// we failed, bail out now...
|
||||
if (status == 0) {
|
||||
// basic error check
|
||||
mprintf(("%s shader failed to compile:\n%s\n", (shader_type == GL_VERTEX_SHADER_ARB) ? "Vertex" : "Fragment", info_log.c_str()));
|
||||
mprintf((" %s shader failed to compile:\n%s\n", (shader_type == GL_VERTEX_SHADER_ARB) ? "Vertex" : "Fragment", info_log.c_str()));
|
||||
if (shader_object) {
|
||||
vglDeleteObjectARB(shader_object);
|
||||
shader_object = 0;
|
||||
@@ -367,7 +369,7 @@ GLhandleARB opengl::shader::link_objects(GLhandleARB vertex_object, GLhandleARB
|
||||
|
||||
// we failed, bail out now...
|
||||
if (status == 0) {
|
||||
mprintf(("Shader failed to link:\n%s\n", info_log.c_str()));
|
||||
mprintf((" Shader failed to link:\n%s\n", info_log.c_str()));
|
||||
if (shader_object) {
|
||||
vglDeleteObjectARB(shader_object);
|
||||
shader_object = 0;
|
||||
@@ -686,7 +688,7 @@ void shader_manager::apply_main_shader(int flags) {
|
||||
current_main->apply();
|
||||
} else {
|
||||
current_main = NULL;
|
||||
mprintf(("Requested main shader not found: 0x%x.\n", flags));
|
||||
mprintf((" Requested main shader not found: 0x%x.\n", flags));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -713,26 +715,28 @@ opengl::post_shader *shader_manager::apply_post_shader(int flags) {
|
||||
return current_post;
|
||||
}
|
||||
|
||||
opengl::special_shader *shader_manager::apply_special_shader(int flags) {
|
||||
opengl::special_shader *shader_manager::get_special_shader(int flags) {
|
||||
special_shader *sshader;
|
||||
|
||||
SCP_map<int, special_shader*>::iterator itr = special_shaders.find(flags);
|
||||
if (itr == special_shaders.end()) {
|
||||
mprintf((" Compiling special shader -> %s / %s ... \n", special_shader::get_vert_name(flags).c_str(), special_shader::get_frag_name(flags).c_str()));
|
||||
|
||||
resources::text_file *vert = new resources::text_file(special_shader::get_vert_name(flags).c_str(), resources::text_file::shader_source);
|
||||
resources::text_file *frag = new resources::text_file(special_shader::get_frag_name(flags).c_str(), resources::text_file::shader_source);
|
||||
sshader = new opengl::special_shader(flags, vert, frag);
|
||||
special_shaders[flags] = sshader;
|
||||
resources::text_file vert;
|
||||
resources::text_file frag;
|
||||
|
||||
delete vert;
|
||||
delete frag;
|
||||
bool r_vert = vert.open(special_shader::get_vert_name(flags).c_str(), resources::text_file::shader_source);
|
||||
bool r_frag = frag.open(special_shader::get_frag_name(flags).c_str(), resources::text_file::shader_source);
|
||||
|
||||
if ( !(r_vert && r_frag) ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sshader = new opengl::special_shader(flags, &vert, &frag);
|
||||
special_shaders[flags] = sshader;
|
||||
} else
|
||||
sshader = (*itr).second;
|
||||
|
||||
if (!sshader->start_pass(0))
|
||||
return NULL;
|
||||
|
||||
return sshader;
|
||||
}
|
||||
|
||||
@@ -741,10 +745,10 @@ void shader_manager::apply_fixed_pipeline() {
|
||||
}
|
||||
|
||||
shader_manager::shader_manager() : current_main(NULL), current_post(NULL) {
|
||||
mprintf(("\nInitializing Shaders Manager...\n"));
|
||||
mprintf((" Initializing Shaders Manager...\n"));
|
||||
load_main_shaders();
|
||||
// load_post_shaders(); //we load post-processing shaders on demand
|
||||
mprintf(("Shaders Manager initialized.\n\n"));
|
||||
mprintf((" Shaders Manager initialized.\n\n"));
|
||||
}
|
||||
|
||||
shader_manager::~shader_manager() {
|
||||
@@ -766,7 +770,7 @@ shader_manager::~shader_manager() {
|
||||
opengl::shader_manager *opengl::shader_manager::instance = NULL;
|
||||
|
||||
void shader_manager::load_main_shaders() {
|
||||
mprintf(("Loading and compiling main shaders...\n"));
|
||||
mprintf((" Loading and compiling main shaders...\n"));
|
||||
|
||||
// check if we can use new main shaders
|
||||
bool main_vert = resources::text_file::file_exist("main-v.sdr", resources::text_file::shader_source) != 0;
|
||||
@@ -805,55 +809,54 @@ void shader_manager::load_main_shaders() {
|
||||
else
|
||||
frag_name = shader_file->frag;
|
||||
|
||||
mprintf((" Compiling main shader -> %s (%s) / %s (%s) ... \n", vert_name, shader_file->vert, frag_name, shader_file->frag));
|
||||
mprintf((" Compiling main shader -> %s (%s) / %s (%s) ... \n", vert_name, shader_file->vert, frag_name, shader_file->frag));
|
||||
|
||||
// create new shader program
|
||||
resources::text_file *vert = new resources::text_file(vert_name, resources::text_file::shader_source);
|
||||
resources::text_file *frag = new resources::text_file(frag_name, resources::text_file::shader_source);
|
||||
opengl::main_shader *sdr = new opengl::main_shader(vert, frag);
|
||||
resources::text_file vert, frag;
|
||||
opengl::main_shader *sdr = NULL;
|
||||
|
||||
// configure shader
|
||||
sdr->configure(shader_file->flags);
|
||||
bool r_vert = vert.open(vert_name, resources::text_file::shader_source);
|
||||
bool r_frag = frag.open(frag_name, resources::text_file::shader_source);
|
||||
|
||||
if (r_vert && r_frag) {
|
||||
sdr = new(std::nothrow) opengl::main_shader(&vert, &frag);
|
||||
Verify( sdr );
|
||||
|
||||
// configure shader
|
||||
sdr->configure(shader_file->flags);
|
||||
} else {
|
||||
mprintf((" Shader file(s) (%s / %s) not found!\n", vert_name, frag_name));
|
||||
}
|
||||
|
||||
// compile shader and add it to shaders list
|
||||
if (sdr->compile_link())
|
||||
if (sdr && sdr->compile_link())
|
||||
main_shaders[shader_file->flags] = sdr;
|
||||
else {
|
||||
// if problem caused by height map - disable
|
||||
if (shader_file->flags & main_shader::flag_height_map) {
|
||||
mprintf((" Shader in_error! Disabling height maps!\n"));
|
||||
mprintf((" Shader in_error! Disabling height maps!\n"));
|
||||
config::disable(config::height_map);
|
||||
}
|
||||
|
||||
// if problem caused by normal map - disable
|
||||
if (shader_file->flags & main_shader::flag_normal_map) {
|
||||
mprintf((" Shader in_error! Disabling normal maps and height maps!\n"));
|
||||
mprintf((" Shader in_error! Disabling normal maps and height maps!\n"));
|
||||
config::disable(config::height_map);
|
||||
config::disable(config::normal_map);
|
||||
}
|
||||
|
||||
// there is no way to use glsl
|
||||
if (i == 0) {
|
||||
mprintf((" Shader in_error! Disabling GLSL!\n"));
|
||||
mprintf((" Shader in_error! Disabling GLSL!\n"));
|
||||
|
||||
config::disable(config::glsl);
|
||||
config::disable(config::height_map);
|
||||
config::disable(config::normal_map);
|
||||
|
||||
delete sdr;
|
||||
delete vert;
|
||||
delete frag;
|
||||
|
||||
destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
delete sdr;
|
||||
}
|
||||
|
||||
// clean
|
||||
delete vert;
|
||||
delete frag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -863,27 +866,27 @@ opengl::post_shader *shader_manager::load_post_shader(int flags) {
|
||||
mprintf((" Compiling post shader (0x%x) -> %s / %s ... \n", flags, vert_name, frag_name));
|
||||
|
||||
// create new shader program
|
||||
resources::text_file *vert = new resources::text_file(vert_name, resources::text_file::shader_source);
|
||||
resources::text_file *frag = new resources::text_file(frag_name, resources::text_file::shader_source);
|
||||
opengl::post_shader *sdr = new opengl::post_shader(vert, frag);
|
||||
resources::text_file vert, frag;
|
||||
opengl::post_shader *sdr = NULL;
|
||||
|
||||
// configure shader
|
||||
sdr->configure(flags);
|
||||
bool r_vert = vert.open(vert_name, resources::text_file::shader_source);
|
||||
bool r_frag = frag.open(frag_name, resources::text_file::shader_source);
|
||||
|
||||
if (r_vert && r_frag) {
|
||||
sdr = new(std::nothrow) opengl::post_shader(&vert, &frag);
|
||||
Verify( sdr );
|
||||
|
||||
// configure shader
|
||||
sdr->configure(flags);
|
||||
}
|
||||
|
||||
// compile shader and add it to shaders list
|
||||
if (sdr->compile_link())
|
||||
if (sdr && sdr->compile_link())
|
||||
post_shaders[flags] = sdr;
|
||||
else {
|
||||
mprintf((" Post-processing shader in_error!\n"));
|
||||
|
||||
delete sdr;
|
||||
sdr = NULL;
|
||||
}
|
||||
|
||||
// clean
|
||||
delete vert;
|
||||
delete frag;
|
||||
|
||||
return sdr;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,9 @@ namespace resources {
|
||||
table_file
|
||||
};
|
||||
|
||||
text_file(const char *, txt_file_type ftype);
|
||||
text_file() { }
|
||||
|
||||
bool open(const char *, txt_file_type ftype);
|
||||
|
||||
const SCP_string &read() const;
|
||||
|
||||
@@ -470,10 +472,10 @@ namespace opengl {
|
||||
*/
|
||||
post_shader *apply_post_shader(int flags);
|
||||
|
||||
/** Applies specific special %shader.
|
||||
/** Get specific special %shader.
|
||||
* @param flags special %shader index
|
||||
*/
|
||||
special_shader *apply_special_shader(int flags);
|
||||
special_shader *get_special_shader(int flags);
|
||||
|
||||
/** Turns main %shader off. */
|
||||
void apply_fixed_pipeline();
|
||||
|
||||
@@ -914,7 +914,7 @@ int opengl_create_texture(int bitmap_handle, int bitmap_type, tcache_slot_opengl
|
||||
}
|
||||
|
||||
if ( (Detail.hardware_textures < 4) && (bitmap_type != TCACHE_TYPE_AABITMAP) && (bitmap_type != TCACHE_TYPE_INTERFACE)
|
||||
&& ((bitmap_type != TCACHE_TYPE_COMPRESSED) || (bitmap_type == TCACHE_TYPE_COMPRESSED) && (max_levels > 1)) )
|
||||
&& ((bitmap_type != TCACHE_TYPE_COMPRESSED) || ((bitmap_type == TCACHE_TYPE_COMPRESSED) && (max_levels > 1))) )
|
||||
{
|
||||
if (max_levels == 1) {
|
||||
// if we are going to cull the size then we need to force a resize
|
||||
@@ -1923,7 +1923,7 @@ namespace opengl {
|
||||
|
||||
SCP_multimap <std::pair<int, int>, render_target*> render_target::pool;
|
||||
|
||||
render_target::render_target(int w, int h) : width(w), height(h), depth_t(NULL), depth_rb(NULL), use_rb(false) {
|
||||
render_target::render_target(int w, int h) : depth_rb(NULL), depth_t(NULL), use_rb(false), target(0), width(w), height(h) {
|
||||
Assert(w > 0 && h > 0);
|
||||
|
||||
// Create frame buffer
|
||||
|
||||
@@ -167,8 +167,9 @@ namespace opengl {
|
||||
* @param tex released texture
|
||||
*/
|
||||
static void release(texture *tex) {
|
||||
Assert(tex);
|
||||
pool.insert(std::pair<std::pair<int, int>, texture*>(std::pair<int, int>(tex->get_width(), tex->get_height()), tex));
|
||||
if (tex) {
|
||||
pool.insert(std::pair<std::pair<int, int>, texture*>(std::pair<int, int>(tex->get_width(), tex->get_height()), tex));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -953,8 +953,13 @@ void gr_opengl_set_projection_matrix(float fov, float aspect, float z_near, floa
|
||||
}
|
||||
|
||||
GL_CHECK_FOR_ERRORS("start of set_projection_matrix()()");
|
||||
|
||||
glViewport(gr_screen.offset_x, (gr_screen.max_h - gr_screen.offset_y - gr_screen.clip_height), gr_screen.clip_width, gr_screen.clip_height);
|
||||
|
||||
if (GL_rendering_to_framebuffer) {
|
||||
glViewport(gr_screen.offset_x, gr_screen.offset_y, gr_screen.clip_width, gr_screen.clip_height);
|
||||
} else {
|
||||
glViewport(gr_screen.offset_x, (gr_screen.max_h - gr_screen.offset_y - gr_screen.clip_height), gr_screen.clip_width, gr_screen.clip_height);
|
||||
}
|
||||
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
@@ -964,7 +969,11 @@ void gr_opengl_set_projection_matrix(float fov, float aspect, float z_near, floa
|
||||
clip_height = tan( (double)fov * 0.5 ) * z_near;
|
||||
clip_width = clip_height * (GLdouble)aspect;
|
||||
|
||||
glFrustum( -clip_width, clip_width, -clip_height, clip_height, z_near, z_far );
|
||||
if (GL_rendering_to_framebuffer) {
|
||||
glFrustum( -clip_width, clip_width, clip_height, -clip_height, z_near, z_far );
|
||||
} else {
|
||||
glFrustum( -clip_width, clip_width, -clip_height, clip_height, z_near, z_far );
|
||||
}
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
|
||||
+17
-2
@@ -1788,7 +1788,10 @@ void hud_show_damage_popup()
|
||||
n_firstline++;
|
||||
gr_string(sx, sy, n_firstline);
|
||||
} else {
|
||||
gr_string(sx, sy, hud_targetbox_truncate_subsys_name(hud_subsys_list[best_index].name));
|
||||
char temp_name[NAME_LENGTH];
|
||||
strcpy(temp_name, hud_subsys_list[best_index].name);
|
||||
hud_targetbox_truncate_subsys_name(temp_name);
|
||||
gr_string(sx, sy, temp_name);
|
||||
}
|
||||
|
||||
sprintf(buf, XSTR( "%d%%", 219), best_str);
|
||||
@@ -2700,7 +2703,12 @@ void hud_maybe_display_subspace_notify()
|
||||
{
|
||||
int warp_aborted = 0;
|
||||
// maybe make gauge active
|
||||
if ( (Player->control_mode == PCM_WARPOUT_STAGE1) || (Player->control_mode == PCM_WARPOUT_STAGE2) || (Player->control_mode == PCM_WARPOUT_STAGE3) ) {
|
||||
if ( (Player->control_mode == PCM_WARPOUT_STAGE1)
|
||||
|| (Player->control_mode == PCM_WARPOUT_STAGE2)
|
||||
|| (Player->control_mode == PCM_WARPOUT_STAGE3)
|
||||
|| (Sexp_hud_display_warpout > 0)
|
||||
)
|
||||
{
|
||||
if (!hud_subspace_notify_active()) {
|
||||
// keep sound from being played 1e06 times
|
||||
hud_start_subspace_notify();
|
||||
@@ -2717,6 +2725,13 @@ void hud_maybe_display_subspace_notify()
|
||||
return;
|
||||
}
|
||||
|
||||
if ( Sexp_hud_display_warpout > 1 ) {
|
||||
if ( Sexp_hud_display_warpout < timestamp()) {
|
||||
Sexp_hud_display_warpout = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( Objective_display_gauge.first_frame < 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
+43
-26
@@ -12,6 +12,7 @@
|
||||
#include "graphics/2d.h"
|
||||
#include "localization/localize.h"
|
||||
#include "hud/hud.h"
|
||||
#include "mission/missiontraining.h" //for Max_directives
|
||||
#include "hud/hudescort.h"
|
||||
//#include "weapon/emp.h"
|
||||
#include "hud/hudparse.h" //Duh.
|
||||
@@ -29,6 +30,7 @@ extern int ships_inited; //Need this
|
||||
extern char Hud_Gauge_Names[NUM_HUD_GAUGES][NAME_LENGTH];
|
||||
|
||||
float Hud_unit_multiplier = 1.0f; //Backslash
|
||||
bool Hud_lead_alternate = false;
|
||||
|
||||
// Goober5000
|
||||
int Hud_reticle_style = HUD_RETICLE_STYLE_FS2;
|
||||
@@ -44,26 +46,26 @@ int Hud_reticle_style = HUD_RETICLE_STYLE_FS2;
|
||||
#define HUD_VAR(a) offsetof(hud_info, a)
|
||||
|
||||
gauge_info gauges[MAX_HUD_GAUGE_TYPES] = {
|
||||
{ NULL, HUD_VAR(Player_shield_coords), "$Player Shield:", 396, 379, 634, 670, 0, 0, 0, 0, 0, 0, 0, -1, -1 },
|
||||
{ NULL, HUD_VAR(Target_shield_coords), "$Target Shield:", 142, 379, 292, 670, 0, 0, 0, 0, 0, 0, 0, -1, -1 },
|
||||
{ NULL, HUD_VAR(Shield_mini_coords), "$Shield Mini:", 305, 291, 497, 470, 0, HUD_VAR(Shield_mini_fname), 0, 0, 0, 0, 0, -1, -1 },
|
||||
{ NULL, HUD_VAR(Aburn_coords), "$Afterburner Energy:", 171, 265, 274, 424, HUD_VAR(Aburn_size), HUD_VAR(Aburn_fname), 0, 0, 0, 0, HUD_VAR(Aburn_move_flag), -1, -1 },
|
||||
{ NULL, HUD_VAR(Wenergy_coords), "$Weapons Energy:", 416, 265, 666, 424, HUD_VAR(Wenergy_size), HUD_VAR(Wenergy_fname), 0, 0, 0, 0, HUD_VAR(Wenergy_move_flag), -1, -1 },
|
||||
{ NULL, HUD_VAR(Wenergy_text_coords), "$Weapons Energy Text:", 439, 318, 708, 509, 0, 0, 0, 0, 0, 0, 0, -1, -1 },
|
||||
{ NULL, HUD_VAR(Escort_coords), "$Escort List:", 486, 206, 865, 330, 0, HUD_VAR(Escort_filename[0]), 0, HUD_VAR(Escort_htext), 0, 0, 0, -1, -1 },
|
||||
{ NULL, HUD_VAR(Player_shield_coords), "Player Shield", 396, 379, 634, 670, 0, 0, 0, 0, 0, 0, 0, -1, -1 },
|
||||
{ NULL, HUD_VAR(Target_shield_coords), "Target Shield", 142, 379, 292, 670, 0, 0, 0, 0, 0, 0, 0, -1, -1 },
|
||||
{ NULL, HUD_VAR(Shield_mini_coords), "Shield Mini", 305, 291, 497, 470, 0, HUD_VAR(Shield_mini_fname), 0, 0, 0, 0, 0, -1, -1 },
|
||||
{ NULL, HUD_VAR(Aburn_coords), "Afterburner Energy", 171, 265, 274, 424, HUD_VAR(Aburn_size), HUD_VAR(Aburn_fname), 0, 0, 0, 0, HUD_VAR(Aburn_move_flag), -1, -1 },
|
||||
{ NULL, HUD_VAR(Wenergy_coords), "Weapons Energy", 416, 265, 666, 424, HUD_VAR(Wenergy_size), HUD_VAR(Wenergy_fname), 0, 0, 0, 0, HUD_VAR(Wenergy_move_flag), -1, -1 },
|
||||
{ NULL, HUD_VAR(Wenergy_text_coords), "Weapons Energy Text", 439, 318, 708, 509, 0, 0, 0, 0, 0, 0, 0, -1, -1 },
|
||||
{ NULL, HUD_VAR(Escort_coords), "Escort List", 486, 206, 865, 330, 0, HUD_VAR(Escort_filename[0]), 0, HUD_VAR(Escort_htext), 0, 0, 0, -1, -1 },
|
||||
|
||||
//Mini-gauges
|
||||
{ &gauges[2], HUD_VAR(Hud_mini_3digit), "$Text Base:", 310, 298, 502, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[2], HUD_VAR(Hud_mini_1digit), "$Text 1 digit:", 316, 298, 511, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
// { &gauges[2], HUD_VAR(Hud_mini_2digit), "$Text 2 digit:", 213, 298, 346, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[2], HUD_VAR(Hud_mini_2digit), "$Text 2 digit:", 313, 298, 506, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[6], HUD_VAR(Escort_htext_coords), "$Header Text:", 3, 2, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1 },
|
||||
{ &gauges[6], HUD_VAR(Escort_list), "$List:", 0, 12, 0, 13, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[6], HUD_VAR(Escort_entry), "$Ship:", 0, 11, 0, 11, 0, HUD_VAR(Escort_filename[1]), 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[6], HUD_VAR(Escort_entry_last), "$Last Ship:", 0, 11, 0, 11, 0, HUD_VAR(Escort_filename[2]), 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[6], HUD_VAR(Escort_name), "$Ship Name:", 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[6], HUD_VAR(Escort_integrity), "$Ship Hull:", 128, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[6], HUD_VAR(Escort_status), "$Ship Status:", -12, 0, -11, 0, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 }
|
||||
{ &gauges[2], HUD_VAR(Hud_mini_3digit), "Text Base", 310, 298, 502, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[2], HUD_VAR(Hud_mini_1digit), "Text 1 digit", 316, 298, 511, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
// { &gauges[2], HUD_VAR(Hud_mini_2digit), "Text 2 digit", 213, 298, 346, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[2], HUD_VAR(Hud_mini_2digit), "Text 2 digit", 313, 298, 506, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[6], HUD_VAR(Escort_htext_coords), "Header Text", 489, 208, 869, 331, 0, 0, 0, 0, 0, 0, 0, -1, -1 },
|
||||
{ &gauges[6], HUD_VAR(Escort_list), "List", 0, 12, 0, 13, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[6], HUD_VAR(Escort_entry), "Ship", 0, 11, 0, 11, 0, HUD_VAR(Escort_filename[1]), 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[6], HUD_VAR(Escort_entry_last), "Last Ship", 0, 11, 0, 11, 0, HUD_VAR(Escort_filename[2]), 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[6], HUD_VAR(Escort_name), "Ship Name", 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[6], HUD_VAR(Escort_integrity), "Ship Hull", 128, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
|
||||
{ &gauges[6], HUD_VAR(Escort_status), "Ship Status", -12, 0, -11, 0, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 }
|
||||
};
|
||||
|
||||
//Number of gauges
|
||||
@@ -181,12 +183,16 @@ int stuff_coords(hud_info* dest_hud, gauge_info* cg, bool required = false)
|
||||
float percentage_temp[2];
|
||||
int size_temp[2];
|
||||
bool size_defined = false;
|
||||
char token_name[NAME_LENGTH + 2] = "$";
|
||||
|
||||
strcat_s(token_name, cg->fieldname);
|
||||
strcat_s(token_name, ":");
|
||||
|
||||
if(required)
|
||||
{
|
||||
required_string(cg->fieldname);
|
||||
required_string(token_name);
|
||||
}
|
||||
if(!required && !optional_string(cg->fieldname))
|
||||
if(!required && !optional_string(token_name))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -332,7 +338,7 @@ static void parse_resolution_gauges(hud_info* dest_hud)
|
||||
{
|
||||
cg = &gauges[i];
|
||||
|
||||
if(!parent && !strnicmp(cg->fieldname + sizeof(char), gaugename, strlen(cg->fieldname) - 2))
|
||||
if(!parent && !stricmp(cg->fieldname, gaugename))
|
||||
{
|
||||
parent = cg;
|
||||
break;
|
||||
@@ -386,6 +392,7 @@ hud_info* parse_ship_start()
|
||||
|
||||
if(ship_index == -1)
|
||||
{
|
||||
WarningEx(LOCATION, "\"$Ship:\" name \"%s\" not found.", shipname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -464,10 +471,7 @@ void parse_custom_gauge()
|
||||
cg->moveflag_dest = HUD_VAR(custom_gauge_moveflags[0]) + (Num_custom_gauges * sizeof(bool));
|
||||
|
||||
required_string("$Name:");
|
||||
//Gotta make this a token
|
||||
cg->fieldname[0] = '$';
|
||||
stuff_string(cg->fieldname + 1, F_NAME, sizeof(cg->fieldname) - 1);
|
||||
strcat_s(cg->fieldname, ":");
|
||||
stuff_string(cg->fieldname, F_NAME, NAME_LENGTH);
|
||||
|
||||
if(optional_string("+Default640X:"))
|
||||
{
|
||||
@@ -489,6 +493,9 @@ void parse_custom_gauge()
|
||||
{
|
||||
stuff_string(buffer, F_NAME, NAME_LENGTH);
|
||||
cg->parent = hud_get_gauge(buffer);
|
||||
if (cg->parent == NULL) {
|
||||
WarningEx(LOCATION, "\"+Parent:\" HUD gauge \"%s\" not found!", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
Num_gauge_types++;
|
||||
@@ -517,6 +524,11 @@ void parse_hud_gauges_tbl(char *filename)
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
if(optional_string("$Max Directives:"))
|
||||
{
|
||||
stuff_int(&Max_directives);
|
||||
}
|
||||
|
||||
if(optional_string("$Max Escort Ships:"))
|
||||
{
|
||||
stuff_int(&Max_escort_ships);
|
||||
@@ -554,6 +566,11 @@ void parse_hud_gauges_tbl(char *filename)
|
||||
Hud_reticle_style = temp;
|
||||
}
|
||||
|
||||
if(optional_string("$Alternate Lead Indicator:"))
|
||||
{
|
||||
stuff_boolean(&Hud_lead_alternate);
|
||||
}
|
||||
|
||||
if(optional_string("#Custom Gauges"))
|
||||
{
|
||||
while(required_string_either("#End", "$Name:"))
|
||||
@@ -737,7 +754,7 @@ int hud_get_gauge_index(char* name)
|
||||
{
|
||||
for(int i = 0; i < Num_gauge_types; i++)
|
||||
{
|
||||
if(!strnicmp(gauges[i].fieldname + sizeof(char), name, strlen(gauges[i].fieldname) - 2))
|
||||
if(!stricmp(gauges[i].fieldname, name))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -145,6 +145,7 @@ typedef struct gauge_info
|
||||
//Variables
|
||||
extern int Num_custom_gauges;
|
||||
extern float Hud_unit_multiplier;
|
||||
extern bool Hud_lead_alternate;
|
||||
|
||||
|
||||
#define NUM_HUD_RETICLE_STYLES 2
|
||||
|
||||
+14
-4
@@ -585,7 +585,12 @@ void hud_show_reticle_weapons()
|
||||
// threat exists, and draw flashing frames.
|
||||
void hud_show_lock_threat()
|
||||
{
|
||||
int frame_offset;
|
||||
int frame_offset, num_frames;
|
||||
|
||||
//Let's find out how many frames our ani has, and adjust accordingly
|
||||
num_frames = Reticle_gauges[RETICLE_LOCK_WARN].num_frames;
|
||||
//We need at least two frames here
|
||||
Assert( num_frames >= 2 );
|
||||
|
||||
if ( Player->threat_flags & (THREAT_LOCK | THREAT_ATTEMPT_LOCK) ) {
|
||||
if ( timestamp_elapsed(Threat_lock_timer) ) {
|
||||
@@ -595,7 +600,7 @@ void hud_show_lock_threat()
|
||||
Threat_lock_timer = timestamp(THREAT_LOCK_FLASH);
|
||||
}
|
||||
Threat_lock_frame++;
|
||||
if ( Threat_lock_frame > 2 ) {
|
||||
if ( Threat_lock_frame > (num_frames - 1) ) { //The first frame being the default "off" setting, we need to cycle through all the other frames
|
||||
Threat_lock_frame = 1;
|
||||
}
|
||||
if ( (Threat_lock_frame == 2) && (Player->threat_flags & THREAT_ATTEMPT_LOCK ) ) {
|
||||
@@ -633,13 +638,18 @@ void hud_show_lock_threat()
|
||||
// threat exists, and draw flashing frames.
|
||||
void hud_show_dumbfire_threat()
|
||||
{
|
||||
int frame_offset;
|
||||
int frame_offset, num_frames;
|
||||
|
||||
//Check how many frames the ani actually has
|
||||
num_frames = Reticle_gauges[RETICLE_LASER_WARN].num_frames;
|
||||
//We need at least two frames here
|
||||
Assert( num_frames >= 2 );
|
||||
|
||||
if ( Player->threat_flags & THREAT_DUMBFIRE ) {
|
||||
if ( timestamp_elapsed(Threat_dumbfire_timer) ) {
|
||||
Threat_dumbfire_timer = timestamp(THREAT_DUMBFIRE_FLASH);
|
||||
Threat_dumbfire_frame++;
|
||||
if ( Threat_dumbfire_frame > 2 ) {
|
||||
if ( Threat_dumbfire_frame > (num_frames - 1) ) { //The first frame being the default "off" setting, we need to cycle through all the other frames
|
||||
Threat_dumbfire_frame = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1391,9 +1391,9 @@ int hud_squadmsg_send_ship_command( int shipnum, int command, int send_message,
|
||||
ai_submode = SM_ATTACK;
|
||||
// if no enemies present, use the affirmative, instead of engaging enemies message
|
||||
if ( hud_squadmsg_enemies_present() )
|
||||
message = MESSAGE_YESSIR;
|
||||
else
|
||||
message = MESSAGE_ENGAGE;
|
||||
else
|
||||
message = MESSAGE_YESSIR;
|
||||
target_shipname = NULL;
|
||||
break;
|
||||
|
||||
@@ -1642,10 +1642,11 @@ int hud_squadmsg_send_wing_command( int wingnum, int command, int send_message,
|
||||
case ENGAGE_ENEMY_ITEM:
|
||||
ai_mode = AI_GOAL_CHASE_ANY;
|
||||
ai_submode = SM_ATTACK;
|
||||
// if no enemies present, use the affirmative, instead of engaging enemies message
|
||||
if ( hud_squadmsg_enemies_present() )
|
||||
message = MESSAGE_YESSIR;
|
||||
else
|
||||
message = MESSAGE_ENGAGE;
|
||||
else
|
||||
message = MESSAGE_YESSIR;
|
||||
target_shipname = NULL;
|
||||
break;
|
||||
|
||||
@@ -2025,7 +2026,7 @@ void hud_squadmsg_call_reinforcement(int reinforcement_num, int player_num)
|
||||
// function to display a list of reinforcements available to the player
|
||||
void hud_squadmsg_reinforcement_select()
|
||||
{
|
||||
int i, k;
|
||||
int i, k, wingnum;
|
||||
reinforcements *rp;
|
||||
|
||||
if ( Num_menu_items == -1 ) {
|
||||
@@ -2041,7 +2042,32 @@ void hud_squadmsg_reinforcement_select()
|
||||
// don't put items which are not on my team
|
||||
if((Player_ship != NULL) && (ship_get_reinforcement_team(i) != Player_ship->team)){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// check the arrival cue sexpression of the ship/wing of this reinforcement.
|
||||
// Goober5000 - if it can't arrive, it doesn't count. This should check
|
||||
// for SEXP_FALSE as well as SEXP_KNOWN_FALSE, otherwise you end up with
|
||||
// a reinforcement menu containing no valid selections.
|
||||
if ( (wingnum = wing_name_lookup(rp->name, 1)) != -1 ) {
|
||||
Assert ( Wings[wingnum].arrival_cue >= 0 );
|
||||
if ( Sexp_nodes[Wings[wingnum].arrival_cue].value == SEXP_FALSE
|
||||
|| Sexp_nodes[Wings[wingnum].arrival_cue].value == SEXP_KNOWN_FALSE ){
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
p_object *p_objp;
|
||||
|
||||
p_objp = mission_parse_get_arrival_ship( rp->name );
|
||||
if ( p_objp != NULL ) {
|
||||
if ( Sexp_nodes[p_objp->arrival_cue].value == SEXP_FALSE
|
||||
|| Sexp_nodes[p_objp->arrival_cue].value == SEXP_KNOWN_FALSE ){
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
Int3(); // allender says bogus! reinforcement should be here since it wasn't a wing!
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Assert ( Num_menu_items < MAX_MENU_ITEMS );
|
||||
strcpy_s( MsgItems[Num_menu_items].text, rp->name );
|
||||
|
||||
+95
-23
@@ -1809,8 +1809,8 @@ void hud_target_live_turret(int next_flag, int auto_advance, int only_player_tar
|
||||
} else if (turret_weapon_has_subtype(&A->weapons, WP_LASER)) {
|
||||
ent[num_live_turrets].type = TYPE_FACING_LASER;
|
||||
} else {
|
||||
Int3();
|
||||
ent[num_live_turrets].type = TYPE_FACING_LASER;
|
||||
//Turret not live, bail
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4137,13 +4137,37 @@ void hud_show_lead_indicator(vec3d *target_world_pos)
|
||||
hud_set_iff_color(targetp, 1);
|
||||
}
|
||||
|
||||
if ( indicator_frame >= 0 ) {
|
||||
sx = lead_target_vertex.sx;
|
||||
sy = lead_target_vertex.sy;
|
||||
if (Hud_lead_alternate) {
|
||||
vertex target_vertex;
|
||||
g3_rotate_vertex(&target_vertex, target_world_pos);
|
||||
|
||||
if (target_vertex.codes == 0) { // on screen
|
||||
|
||||
gr_unsize_screen_posf(&sx, &sy);
|
||||
g3_project_vertex(&target_vertex);
|
||||
if (!(target_vertex.flags & PF_OVERFLOW)) {
|
||||
|
||||
//indicator_frame = Reticle2_indicator_gauge.first_frame + frame_offset;
|
||||
if ( indicator_frame >= 0 ) {
|
||||
//hud_set_gauge_color(HUD_CENTER_RETICLE, HUD_C_BRIGHT);
|
||||
float reticle2_target_sx = target_vertex.sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0] - lead_target_vertex.sx;
|
||||
float reticle2_target_sy = target_vertex.sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1] - lead_target_vertex.sy;
|
||||
|
||||
reticle2_target_sx += HUD_offset_x + Hud_reticle_center[gr_screen.res][0] + 0.5f;
|
||||
reticle2_target_sy += HUD_offset_y + Hud_reticle_center[gr_screen.res][1] + 0.5f;
|
||||
|
||||
GR_AABITMAP(indicator_frame, fl2i(reticle2_target_sx)+HUD_nose_x, fl2i(reticle2_target_sy)+HUD_nose_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( indicator_frame >= 0 ) {
|
||||
sx = lead_target_vertex.sx;
|
||||
sy = lead_target_vertex.sy;
|
||||
|
||||
GR_AABITMAP(indicator_frame, fl2i(sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0]), fl2i(sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1]));
|
||||
gr_unsize_screen_posf(&sx, &sy);
|
||||
|
||||
GR_AABITMAP(indicator_frame, fl2i(sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0]), fl2i(sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4210,17 +4234,41 @@ void hud_show_lead_indicator(vec3d *target_world_pos)
|
||||
hud_set_iff_color(targetp, 1);
|
||||
}
|
||||
|
||||
if ( indicator_frame >= 0 ) {
|
||||
sx = lead_target_vertex.sx;
|
||||
sy = lead_target_vertex.sy;
|
||||
if (Hud_lead_alternate) {
|
||||
vertex target_vertex;
|
||||
g3_rotate_vertex(&target_vertex, target_world_pos);
|
||||
|
||||
if (target_vertex.codes == 0) { // on screen
|
||||
|
||||
gr_unsize_screen_posf(&sx, &sy);
|
||||
g3_project_vertex(&target_vertex);
|
||||
if (!(target_vertex.flags & PF_OVERFLOW)) {
|
||||
|
||||
//indicator_frame = Reticle2_indicator_gauge.first_frame + frame_offset;
|
||||
if ( indicator_frame >= 0 ) {
|
||||
//hud_set_gauge_color(HUD_CENTER_RETICLE, HUD_C_BRIGHT);
|
||||
float reticle2_target_sx = target_vertex.sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0] - lead_target_vertex.sx;
|
||||
float reticle2_target_sy = target_vertex.sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1] - lead_target_vertex.sy;
|
||||
|
||||
reticle2_target_sx += HUD_offset_x + Hud_reticle_center[gr_screen.res][0] + 0.5f;
|
||||
reticle2_target_sy += HUD_offset_y + Hud_reticle_center[gr_screen.res][1] + 0.5f;
|
||||
|
||||
GR_AABITMAP(indicator_frame, fl2i(reticle2_target_sx)+HUD_nose_x, fl2i(reticle2_target_sy)+HUD_nose_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( indicator_frame >= 0 ) {
|
||||
sx = lead_target_vertex.sx;
|
||||
sy = lead_target_vertex.sy;
|
||||
|
||||
//WMC - shake them
|
||||
sx += HUD_nose_x;
|
||||
sy += HUD_nose_y;
|
||||
gr_unsize_screen_posf(&sx, &sy);
|
||||
|
||||
GR_AABITMAP(indicator_frame, fl2i(sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0]), fl2i(sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1]));
|
||||
//WMC - shake them
|
||||
sx += HUD_nose_x;
|
||||
sy += HUD_nose_y;
|
||||
|
||||
GR_AABITMAP(indicator_frame, fl2i(sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0]), fl2i(sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4345,17 +4393,41 @@ void hud_show_lead_indicator_quick(vec3d *target_world_pos, object *targetp)
|
||||
g3_project_vertex(&lead_target_vertex);
|
||||
if (!(lead_target_vertex.flags & PF_OVERFLOW)) {
|
||||
|
||||
if ( indicator_frame >= 0 ) {
|
||||
sx = lead_target_vertex.sx;
|
||||
sy = lead_target_vertex.sy;
|
||||
if (Hud_lead_alternate) {
|
||||
vertex target_vertex;
|
||||
g3_rotate_vertex(&target_vertex, target_world_pos);
|
||||
|
||||
if (target_vertex.codes == 0) { // on screen
|
||||
|
||||
gr_unsize_screen_posf(&sx, &sy);
|
||||
g3_project_vertex(&target_vertex);
|
||||
if (!(target_vertex.flags & PF_OVERFLOW)) {
|
||||
|
||||
//indicator_frame = Reticle2_indicator_gauge.first_frame + frame_offset;
|
||||
if ( indicator_frame >= 0 ) {
|
||||
//hud_set_gauge_color(HUD_CENTER_RETICLE, HUD_C_BRIGHT);
|
||||
float reticle2_target_sx = target_vertex.sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0] - lead_target_vertex.sx;
|
||||
float reticle2_target_sy = target_vertex.sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1] - lead_target_vertex.sy;
|
||||
|
||||
reticle2_target_sx += HUD_offset_x + Hud_reticle_center[gr_screen.res][0] + 0.5f;
|
||||
reticle2_target_sy += HUD_offset_y + Hud_reticle_center[gr_screen.res][1] + 0.5f;
|
||||
|
||||
GR_AABITMAP(indicator_frame, fl2i(reticle2_target_sx)+HUD_nose_x, fl2i(reticle2_target_sy)+HUD_nose_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( indicator_frame >= 0 ) {
|
||||
sx = lead_target_vertex.sx;
|
||||
sy = lead_target_vertex.sy;
|
||||
|
||||
//WMC - shake them
|
||||
sx += HUD_nose_x;
|
||||
sy += HUD_nose_y;
|
||||
gr_unsize_screen_posf(&sx, &sy);
|
||||
|
||||
GR_AABITMAP(indicator_frame, fl2i(sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0]), fl2i(sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1]));
|
||||
//WMC - shake them
|
||||
sx += HUD_nose_x;
|
||||
sy += HUD_nose_y;
|
||||
|
||||
GR_AABITMAP(indicator_frame, fl2i(sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0]), fl2i(sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ static int Last_ts; // holds last target status.
|
||||
void hud_blit_target_integrity(int disabled,int force_obj_num = -1);
|
||||
|
||||
// cut down long subsystem names to a more manageable length
|
||||
char *hud_targetbox_truncate_subsys_name(char *outstr)
|
||||
void hud_targetbox_truncate_subsys_name(char *outstr)
|
||||
{
|
||||
if(Lcl_gr){
|
||||
if ( strstr(outstr, "communication") ) {
|
||||
@@ -244,17 +244,15 @@ char *hud_targetbox_truncate_subsys_name(char *outstr)
|
||||
} else if ( strstr(outstr, "laser") || strstr(outstr, "turret") || strstr(outstr, "missile") ) {
|
||||
strcpy(outstr, "tourelle");
|
||||
}
|
||||
} else {
|
||||
if ( strstr(outstr, XSTR( "communication", 333))) {
|
||||
strcpy( outstr, XSTR( "comm", 334) );
|
||||
} else if ( strstr(outstr, XSTR( "navigation", 335))) {
|
||||
strcpy( outstr, XSTR( "nav", 336) );
|
||||
} else if (!stricmp(outstr, "Gas Collector")) {
|
||||
} else {
|
||||
if (strstr(outstr, XSTR("communication", 333))) {
|
||||
strcpy(outstr, XSTR("comm", 334));
|
||||
} else if (strstr(outstr, XSTR("navigation", 335))) {
|
||||
strcpy(outstr, XSTR("nav", 336));
|
||||
} else if (strstr(outstr, "gas collector")) {
|
||||
strcpy(outstr, "collector");
|
||||
}
|
||||
}
|
||||
|
||||
return outstr;
|
||||
}
|
||||
|
||||
//swich through the valid targetbox modes
|
||||
|
||||
@@ -72,7 +72,7 @@ void hud_render_target_weapon(object *target_objp);
|
||||
void hud_update_cargo_scan_sound();
|
||||
void hud_cargo_scan_update(object *targetp, float frametime);
|
||||
|
||||
char *hud_targetbox_truncate_subsys_name(char *outstr);
|
||||
void hud_targetbox_truncate_subsys_name(char *outstr);
|
||||
|
||||
//swich through the valid targetbox modes
|
||||
void hud_targetbox_switch_wireframe_mode();
|
||||
|
||||
@@ -331,6 +331,12 @@ int joy_ff_create_effects()
|
||||
void joy_ff_stop_effects()
|
||||
{
|
||||
joy_ff_afterburn_off();
|
||||
|
||||
if (pDeathroll1)
|
||||
pDeathroll1->Stop();
|
||||
|
||||
if (pDeathroll2)
|
||||
pDeathroll2->Stop();
|
||||
}
|
||||
|
||||
void joy_ff_mission_init(vec3d v)
|
||||
|
||||
@@ -2846,11 +2846,7 @@ int button_function(int n)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CanAutopilot(true))
|
||||
{
|
||||
StartAutopilot();
|
||||
}
|
||||
else
|
||||
if (!StartAutopilot())
|
||||
gamesnd_play_iface(SND_GENERAL_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#define LAB_FLAG_SHOW_DEBRIS (1<<2) // render debris instead of normal LOD
|
||||
#define LAB_FLAG_SUBMODEL_ROTATE (1<<3) // do rotation for any rotating ship subobjects
|
||||
#define LAB_FLAG_LIGHTNING_ARCS (1<<4) // show damage lightning
|
||||
#define LAB_FLAG_FULLY_LOAD (1<<5) // use create_ship() to test the ships
|
||||
|
||||
// modes
|
||||
#define LAB_MODE_NONE 0 // not showing anything
|
||||
@@ -1607,6 +1608,7 @@ void labviewer_make_render_options_window(Button *caller)
|
||||
// add all of the flags that we want/need...
|
||||
|
||||
// viewer flags
|
||||
ADD_RENDER_FLAG("Test Load Ships", Lab_viewer_flags, LAB_FLAG_FULLY_LOAD);
|
||||
ADD_RENDER_FLAG("Disable Model Rotation", Lab_viewer_flags, LAB_FLAG_NO_ROTATION);
|
||||
ADD_RENDER_FLAG("Show Insignia", Lab_viewer_flags, LAB_FLAG_SHOW_INSIGNIA);
|
||||
ADD_RENDER_FLAG("Show Damage Lightning", Lab_viewer_flags, LAB_FLAG_LIGHTNING_ARCS);
|
||||
@@ -1838,6 +1840,16 @@ void labviewer_change_ship_lod(Tree* caller)
|
||||
int ship_index = (int)(caller->GetSelectedItem()->GetParentItem()->GetData());
|
||||
Assert( ship_index >= 0 );
|
||||
|
||||
// Genghis - Attempt to create and then immediately delete the selected ship type.
|
||||
// This causes the full error-handling to kick-in, making the Lab viewer a more
|
||||
// useful tool for checking model errors.
|
||||
if (Lab_viewer_flags & LAB_FLAG_FULLY_LOAD)
|
||||
{
|
||||
The_mission.ai_profile = &Ai_profiles[Default_ai_profile];
|
||||
int test_idx = ship_create(&vmd_identity_matrix, &vmd_zero_vector, ship_index);
|
||||
obj_delete(test_idx);
|
||||
}
|
||||
|
||||
Lab_last_selected_ship = Lab_selected_index;
|
||||
|
||||
labviewer_change_model(Ship_info[ship_index].pof_file, caller->GetSelectedItem()->GetData(), ship_index);
|
||||
|
||||
@@ -35,6 +35,9 @@ int static_rand(int num)
|
||||
{
|
||||
int a, b, c;
|
||||
|
||||
if (num < 0)
|
||||
num *= -1;
|
||||
|
||||
if (!Semirand_inited)
|
||||
init_semirand();
|
||||
|
||||
|
||||
@@ -1630,7 +1630,11 @@ void vm_matrix_to_rot_axis_and_angle(matrix *m, float *theta, vec3d *rot_axis)
|
||||
rot_axis->xyz.x = (m->vec.uvec.xyz.z - m->vec.fvec.xyz.y);
|
||||
rot_axis->xyz.y = (m->vec.fvec.xyz.x - m->vec.rvec.xyz.z);
|
||||
rot_axis->xyz.z = (m->vec.rvec.xyz.y - m->vec.uvec.xyz.x);
|
||||
vm_vec_normalize(rot_axis);
|
||||
if (IS_VEC_NULL_SQ_SAFE(rot_axis)) {
|
||||
vm_vec_make(rot_axis, 1.0f, 0.0f, 0.0f);
|
||||
} else {
|
||||
vm_vec_normalize(rot_axis);
|
||||
}
|
||||
} else { // angle is PI within limits
|
||||
*theta = PI;
|
||||
|
||||
|
||||
+33
-30
@@ -33,41 +33,42 @@
|
||||
// This is the fs2_open credit list, please only add yourself if you have actually contributed code
|
||||
// Rules!
|
||||
char *fs2_open_credit_text =
|
||||
"SOURCE CODE PROJECT STAFF:\n"
|
||||
"SOURCE CODE PROJECT STAFF:\n"
|
||||
"\n"
|
||||
"Project Leaders:\n"
|
||||
"\n"
|
||||
"Ian \"Goober5000\" Warfield\n"
|
||||
"Cliff \"chief1983\" Gordon"
|
||||
"\n"
|
||||
"Senior Advisors:\n"
|
||||
"\n"
|
||||
"Taylor Richards\n"
|
||||
"\n"
|
||||
"Senior Advisor\n"
|
||||
"\n"
|
||||
"Ian \"Goober5000\" Warfield\n"
|
||||
"Edward \"Inquisitor\" Gardner\n"
|
||||
"\n"
|
||||
"Programmers:\n"
|
||||
"\n"
|
||||
"Mike \"Bobboau\" Abegg\n"
|
||||
"Dennis \"DTP\" Pedersen\n"
|
||||
"\"EdrickV\"\n"
|
||||
"Derek \"Kazan\" Meek\n"
|
||||
"Ian \"Goober5000\" Warfield\n"
|
||||
"\"Mysterial\"\n"
|
||||
"Joe \"Righteous1\" Dowd\n"
|
||||
"Jon \"Sesquipedalian\" Stovell\n"
|
||||
"Matt \"Sticks\" Nischan\n"
|
||||
"Mike \"penguin\" Harris\n"
|
||||
"Nick \"phreak\" Iannetta\n"
|
||||
"Thomas \"RandomTiger\" Whittaker\n"
|
||||
"Taylor Richards\n"
|
||||
"Will \"##Unknown Player##\" Rousnel\n"
|
||||
"\"WMCoolmon\"\n"
|
||||
"Hassan \"Karajorma\" Kazmi\n"
|
||||
"Derek \"Kazan\" Meek\n"
|
||||
"Nick \"phreak\" Iannetta\n"
|
||||
"Mike \"Bobboau\" Abegg\n"
|
||||
"Backslash\n"
|
||||
"Echelon9\n"
|
||||
"Flaming_Sword\n"
|
||||
"FUBAR\n"
|
||||
"Iss Mneur\n"
|
||||
"kkmic\n"
|
||||
"Michael \"Zacam\" LaFleur\n"
|
||||
"Shade\n"
|
||||
"Soulstorm\n"
|
||||
"Sushi\n"
|
||||
"Swifty\n"
|
||||
"Wanderer\n"
|
||||
"Fabian \"The E\" Woltermann\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"Readme Staff:\n"
|
||||
"\n"
|
||||
"\"Bottomfan\"\n"
|
||||
"Peter \"Flipside\" Dibble\n"
|
||||
"Jonathan \"Redmenace\" Willsher\n"
|
||||
"\n"
|
||||
"Web Support:\n"
|
||||
"\n"
|
||||
@@ -77,12 +78,10 @@ char *fs2_open_credit_text =
|
||||
"\n"
|
||||
"Special thanks to:\n"
|
||||
"\n"
|
||||
"\"Maeglamor\"\n"
|
||||
"for donating a graphics card!\n"
|
||||
"\n"
|
||||
"\"Lightspeed\"\n"
|
||||
"\"DaBrain\"\n"
|
||||
"for helping out with the graphics enhancements\n"
|
||||
"portej05\n"
|
||||
"Hery\n"
|
||||
"QuantumDelta\n"
|
||||
"Fury\n"
|
||||
"\n"
|
||||
"Linux and OSX version with the support of\n"
|
||||
"the icculus.org FreeSpace2 project:\n"
|
||||
@@ -102,8 +101,12 @@ char *fs2_open_credit_text =
|
||||
"\n"
|
||||
"Ogg Vorbis - (C) 2005, Xiph.Org Foundation\n"
|
||||
"JPEG - Independent JPEG Group, (C) 1991-1998, Thomas G. Lane\n"
|
||||
"\n\n"
|
||||
"\n\n";
|
||||
"libpng - Copyright (C) 1998-2010 Glenn Randers-Pehrson\n"
|
||||
"liblua - Copyright (C) 1994–2008 Lua.org, PUC-Rio\n"
|
||||
"zlib - Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n";
|
||||
|
||||
char *unmodified_credits = "ORIGINAL VOLITION STAFF:\n\n\n";
|
||||
char *mod_check = "Design:";
|
||||
|
||||
@@ -244,7 +244,6 @@ static int Techroom_ship_modelnum;
|
||||
static float Techroom_ship_rot;
|
||||
static UI_BUTTON List_buttons[LIST_BUTTONS_MAX]; // buttons for each line of text in list
|
||||
//static int Anim_playing_id = -1;
|
||||
//static int anim_done = 0;
|
||||
static int Palette_bmp;
|
||||
//static int ShipWin01;
|
||||
//static int ShipWin02;
|
||||
@@ -395,12 +394,14 @@ void techroom_select_new_entry()
|
||||
Techroom_ship_modelnum = -1;
|
||||
Trackball_mode = 0;
|
||||
|
||||
//load animation here, we now only have one loaded
|
||||
generic_anim_init(&Current_list[Cur_entry].animation, Current_list[Cur_entry].tech_anim_filename);
|
||||
Current_list[Cur_entry].animation.ani.bg_type = bm_get_type(Tech_background_bitmap);
|
||||
if(generic_anim_stream(&Current_list[Cur_entry].animation) != -1){
|
||||
// load animation here, we now only have one loaded
|
||||
int stream_result = generic_anim_init_and_stream(&Current_list[Cur_entry].animation, Current_list[Cur_entry].tech_anim_filename, bm_get_type(Tech_background_bitmap), true);
|
||||
|
||||
if (stream_result >= 0) {
|
||||
Current_list[Cur_entry].has_anim = 1;
|
||||
} else {
|
||||
// we've failed to load any animation
|
||||
// load an image and treat it like a 1 frame animation
|
||||
Current_list[Cur_entry].bitmap = bm_load(Current_list[Cur_entry].tech_anim_filename);
|
||||
}
|
||||
}
|
||||
@@ -730,7 +731,7 @@ void tech_ship_scroll_capture()
|
||||
techroom_unload_animation();
|
||||
|
||||
techroom_select_new_entry();
|
||||
}
|
||||
}
|
||||
|
||||
void techroom_anim_render(float frametime)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include "globalincs/globals.h"
|
||||
|
||||
#define MAX_INTEL_ENTRIES 30
|
||||
#define MAX_INTEL_ENTRIES 75
|
||||
#define TECH_INTEL_DESC_LEN 5120
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -264,12 +264,16 @@ void persona_parse()
|
||||
}
|
||||
}
|
||||
|
||||
if ( i == MAX_PERSONA_TYPES )
|
||||
WarningEx(LOCATION, "Unknown persona type in messages.tbl -- %s\n", type );
|
||||
|
||||
char cstrtemp[NAME_LENGTH];
|
||||
if ( optional_string("+") )
|
||||
{
|
||||
int j;
|
||||
stuff_string(cstrtemp, F_NAME, NAME_LENGTH);
|
||||
|
||||
for (int j = 0; j < (int)Species_info.size(); j++)
|
||||
for (j = 0; j < (int)Species_info.size(); j++)
|
||||
{
|
||||
if (!strcmp(cstrtemp, Species_info[j].species_name))
|
||||
{
|
||||
@@ -277,12 +281,11 @@ void persona_parse()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( j == (int)Species_info.size() )
|
||||
WarningEx(LOCATION, "Unknown species in messages.tbl -- %s\n", cstrtemp );
|
||||
}
|
||||
|
||||
if ( i == MAX_PERSONA_TYPES )
|
||||
Error(LOCATION, "Unknown persona type in messages.tbl -- %s\n", type );
|
||||
|
||||
|
||||
Num_personas++;
|
||||
}
|
||||
|
||||
@@ -367,6 +370,9 @@ void message_parse(bool importing_from_fsm)
|
||||
if ( optional_string("+Persona:") ) {
|
||||
stuff_string(persona_name, F_NAME, NAME_LENGTH);
|
||||
msg.persona_index = message_persona_name_lookup( persona_name );
|
||||
|
||||
if ( msg.persona_index == -1 )
|
||||
WarningEx(LOCATION, "Unknown persona in message %s in messages.tbl -- %s\n", msg.name, persona_name );
|
||||
}
|
||||
|
||||
if ( !Fred_running)
|
||||
|
||||
+154
-47
@@ -711,6 +711,8 @@ void parse_mission_info(mission *pm, bool basic = false)
|
||||
|
||||
if (index >= 0)
|
||||
The_mission.ai_profile = &Ai_profiles[index];
|
||||
else
|
||||
WarningEx(LOCATION, "Mission: %s\nUnknown AI profile %s!", pm->name, temp );
|
||||
}
|
||||
|
||||
Assert( The_mission.ai_profile != NULL );
|
||||
@@ -806,6 +808,9 @@ void parse_player_info2(mission *pm)
|
||||
if (optional_string("+Default_ship:")) {
|
||||
stuff_string(str, F_NAME, NAME_LENGTH);
|
||||
ptr->default_ship = ship_info_lookup(str);
|
||||
if (-1 == ptr->default_ship) {
|
||||
WarningEx(LOCATION, "Mission: %s\nUnknown default ship %s! Defaulting to %s.", pm->name, str, Ship_info[ptr->ship_list[0]].name );
|
||||
}
|
||||
// see if the player's default ship is an allowable ship (campaign only). If not, then what
|
||||
// do we do? choose the first allowable one?
|
||||
if (Game_mode & GM_CAMPAIGN_MODE || ((Game_mode & GM_MULTIPLAYER) && !(Net_player->flags & NETINFO_FLAG_AM_MASTER))) {
|
||||
@@ -1731,7 +1736,18 @@ int parse_create_object_sub(p_object *p_objp)
|
||||
shipp->team = p_objp->team;
|
||||
strcpy_s(shipp->ship_name, p_objp->name);
|
||||
shipp->escort_priority = p_objp->escort_priority;
|
||||
shipp->special_exp_index = p_objp->special_exp_index;
|
||||
|
||||
|
||||
|
||||
shipp->use_special_explosion = p_objp->use_special_explosion;
|
||||
shipp->special_exp_damage = p_objp->special_exp_damage;
|
||||
shipp->special_exp_blast = p_objp->special_exp_blast ;
|
||||
shipp->special_exp_inner = p_objp->special_exp_inner ;
|
||||
shipp->special_exp_outer = p_objp->special_exp_outer ;
|
||||
shipp->use_shockwave = p_objp->use_shockwave ;
|
||||
shipp->special_exp_shockwave_speed = p_objp->special_exp_shockwave_speed ;
|
||||
shipp->special_hitpoints = p_objp->special_hitpoints ;
|
||||
shipp->special_shield = p_objp->special_shield ;
|
||||
|
||||
for (i=0;i<MAX_IFFS;i++)
|
||||
{
|
||||
@@ -1742,13 +1758,12 @@ int parse_create_object_sub(p_object *p_objp)
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
shipp->special_hitpoint_index = p_objp->special_hitpoint_index;
|
||||
shipp->ship_max_shield_strength = p_objp->ship_max_shield_strength;
|
||||
shipp->ship_max_hull_strength = p_objp->ship_max_hull_strength;
|
||||
|
||||
// Goober5000 - ugh, this is really stupid having to do this here; if the
|
||||
// ship creation code was better organized this wouldn't be necessary
|
||||
if (shipp->special_hitpoint_index >= 0)
|
||||
if (shipp->special_hitpoints > 0)
|
||||
{
|
||||
float hull_factor = shipp->ship_max_hull_strength / sip->max_hull_strength;
|
||||
ship_subsys *ss;
|
||||
@@ -2363,6 +2378,48 @@ void resolve_parse_flags(object *objp, int parse_flags, int parse_flags2)
|
||||
shipp->flags2 |= SF2_FORCE_SHIELDS_ON;
|
||||
}
|
||||
|
||||
void fix_old_special_explosions(p_object *p_objp, int variable_index)
|
||||
{
|
||||
int i;
|
||||
|
||||
Assertion(!(p_objp->use_special_explosion), "Mission appears to be using both the new and old method of special explosions for %s. Old method values used", p_objp->name);
|
||||
|
||||
// check all the variables are valid
|
||||
for ( i = variable_index; i < (variable_index + BLOCK_EXP_SIZE); i++ ) {
|
||||
if (!( Block_variables[i].type & SEXP_VARIABLE_BLOCK )) {
|
||||
Warning (LOCATION, "%s is using the old special explosions method but does not appear to have variables for all the values", p_objp->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
p_objp->use_special_explosion = true;
|
||||
|
||||
p_objp->special_exp_damage = atoi(Block_variables[variable_index+DAMAGE].text);
|
||||
p_objp->special_exp_blast = atoi(Block_variables[variable_index+BLAST].text);
|
||||
p_objp->special_exp_inner = atoi(Block_variables[variable_index+INNER_RAD].text);
|
||||
p_objp->special_exp_outer = atoi(Block_variables[variable_index+OUTER_RAD].text);
|
||||
p_objp->use_shockwave = (atoi(Block_variables[variable_index+PROPAGATE].text) ? 1:0);
|
||||
p_objp->special_exp_shockwave_speed = atoi(Block_variables[variable_index+SHOCK_SPEED].text);
|
||||
}
|
||||
|
||||
void fix_old_special_hits(p_object *p_objp, int variable_index)
|
||||
{
|
||||
int i;
|
||||
|
||||
Assertion( ((p_objp->special_hitpoints == 0) && (p_objp->special_shield == -1)),"Mission appears to be using both the new and old method of special hitpoints for %s", p_objp->name);
|
||||
|
||||
// check all the variables are valid
|
||||
for ( i = variable_index; i < (variable_index + BLOCK_HIT_SIZE); i++ ) {
|
||||
if (!( Block_variables[i].type & SEXP_VARIABLE_BLOCK )) {
|
||||
Warning (LOCATION, "%s is using the old special hitpoints method but does not appear to have variables for all the values", p_objp->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
p_objp->special_hitpoints = atoi(Block_variables[variable_index+HULL_STRENGTH].text);
|
||||
p_objp->special_shield = atoi(Block_variables[variable_index+SHIELD_STRENGTH].text);
|
||||
}
|
||||
|
||||
// Mp points at the text of an object, which begins with the "$Name:" field.
|
||||
// Snags all object information. Creating the ship now only happens after everything has been parsed.
|
||||
//
|
||||
@@ -2457,9 +2514,8 @@ int parse_object(mission *pm, int flag, p_object *p_objp)
|
||||
|
||||
// try and find the alternate name
|
||||
p_objp->alt_type_index = (char)mission_parse_lookup_alt(name);
|
||||
Assert(p_objp->alt_type_index >= 0);
|
||||
if(p_objp->alt_type_index < 0)
|
||||
mprintf(("Error looking up alternate ship type name!\n"));
|
||||
WarningEx(LOCATION, "Mission %s\nError looking up alternate ship type name %s!\n", pm->name, name);
|
||||
else
|
||||
mprintf(("Using alternate ship type name: %s\n", name));
|
||||
}
|
||||
@@ -2473,9 +2529,8 @@ int parse_object(mission *pm, int flag, p_object *p_objp)
|
||||
|
||||
// try and find the callsign
|
||||
p_objp->callsign_index = (char)mission_parse_lookup_callsign(name);
|
||||
Assert(p_objp->callsign_index >= 0);
|
||||
if(p_objp->callsign_index < 0)
|
||||
mprintf(("Error looking up callsign!\n"));
|
||||
WarningEx(LOCATION, "Mission %s\nError looking up callsign %s!\n", pm->name, name);
|
||||
else
|
||||
mprintf(("Using callsign: %s\n", name));
|
||||
}
|
||||
@@ -2712,44 +2767,74 @@ int parse_object(mission *pm, int flag, p_object *p_objp)
|
||||
Player_starts++;
|
||||
}
|
||||
|
||||
p_objp->special_exp_index = -1;
|
||||
if (optional_string("+Special Exp index:"))
|
||||
stuff_int(&p_objp->special_exp_index);
|
||||
p_objp->use_special_explosion = false;
|
||||
p_objp->special_exp_damage = -1;
|
||||
p_objp->special_exp_blast = -1;
|
||||
p_objp->special_exp_inner = -1;
|
||||
p_objp->special_exp_outer = -1;
|
||||
p_objp->use_shockwave = false;
|
||||
p_objp->special_exp_shockwave_speed = 0;
|
||||
p_objp->special_hitpoints = 0;
|
||||
p_objp->special_shield = -1;
|
||||
|
||||
p_objp->special_hitpoint_index = -1;
|
||||
if (optional_string("+Special Hitpoint index:"))
|
||||
stuff_int(&p_objp->special_hitpoint_index);
|
||||
if (optional_string("$Special Explosion:")) {
|
||||
p_objp->use_special_explosion = true;
|
||||
|
||||
// set max hitpoint values
|
||||
p_objp->ship_max_shield_strength = Ship_info[p_objp->ship_class].max_shield_strength;
|
||||
p_objp->ship_max_hull_strength = Ship_info[p_objp->ship_class].max_hull_strength;
|
||||
|
||||
// swap to the special hitpoint ones if they were set
|
||||
if (p_objp->special_hitpoint_index != -1)
|
||||
{
|
||||
bool reset_index = false;
|
||||
|
||||
if ((Sexp_variables[p_objp->special_hitpoint_index+SHIELD_STRENGTH].type & SEXP_VARIABLE_SET) &&
|
||||
(Sexp_variables[p_objp->special_hitpoint_index+SHIELD_STRENGTH].type & SEXP_VARIABLE_BLOCK) ) {
|
||||
p_objp->ship_max_shield_strength = (float) atoi(Sexp_variables[p_objp->special_hitpoint_index+SHIELD_STRENGTH].text);
|
||||
}
|
||||
else {
|
||||
Warning(LOCATION, "Special shield hitpoints used for variable number %d. But no variable with this number exists!", p_objp->special_hitpoint_index+SHIELD_STRENGTH);
|
||||
reset_index = true;
|
||||
if (required_string("+Special Exp Damage:")) {
|
||||
stuff_int(&p_objp->special_exp_damage);
|
||||
}
|
||||
|
||||
if ((Sexp_variables[p_objp->special_hitpoint_index+HULL_STRENGTH].type & SEXP_VARIABLE_SET) &&
|
||||
(Sexp_variables[p_objp->special_hitpoint_index+HULL_STRENGTH].type & SEXP_VARIABLE_BLOCK) ) {
|
||||
p_objp->ship_max_hull_strength = (float) atoi(Sexp_variables[p_objp->special_hitpoint_index+HULL_STRENGTH].text);
|
||||
}
|
||||
else {
|
||||
Warning(LOCATION, "Special hitpoints used for variable number %d. But no variable with this number exists!", p_objp->special_hitpoint_index+HULL_STRENGTH);
|
||||
reset_index = true;
|
||||
if (required_string("+Special Exp Blast:")) {
|
||||
stuff_int(&p_objp->special_exp_blast);
|
||||
}
|
||||
|
||||
if (reset_index) {
|
||||
p_objp->special_hitpoint_index = -1;
|
||||
if (required_string("+Special Exp Inner Radius:")) {
|
||||
stuff_int(&p_objp->special_exp_inner);
|
||||
}
|
||||
|
||||
if (required_string("+Special Exp Outer Radius:")) {
|
||||
stuff_int(&p_objp->special_exp_outer);
|
||||
}
|
||||
|
||||
if (optional_string("+Special Exp Shockwave Speed:")) {
|
||||
stuff_int(&p_objp->special_exp_shockwave_speed);
|
||||
p_objp->use_shockwave = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("+Special Hitpoints:")) {
|
||||
stuff_int(&p_objp->special_hitpoints);
|
||||
}
|
||||
|
||||
if (optional_string("+Special Shield Points:")) {
|
||||
stuff_int(&p_objp->special_shield);
|
||||
}
|
||||
|
||||
if (optional_string("+Special Exp index:")) {
|
||||
int variable_index;
|
||||
stuff_int(&variable_index);
|
||||
fix_old_special_explosions(p_objp, variable_index);
|
||||
}
|
||||
|
||||
if (optional_string("+Special Hitpoint index:")) {
|
||||
int variable_index;
|
||||
stuff_int(&variable_index);
|
||||
fix_old_special_hits(p_objp, variable_index);
|
||||
}
|
||||
|
||||
// set max hitpoint and shield values
|
||||
if (p_objp->special_shield != -1) {
|
||||
p_objp->ship_max_shield_strength = (float) p_objp->special_shield;
|
||||
}
|
||||
else {
|
||||
p_objp->ship_max_shield_strength = Ship_info[p_objp->ship_class].max_shield_strength;
|
||||
}
|
||||
|
||||
if (p_objp->special_hitpoints > 0) {
|
||||
p_objp->ship_max_hull_strength = (float) p_objp->special_hitpoints;
|
||||
}
|
||||
else {
|
||||
p_objp->ship_max_hull_strength = Ship_info[p_objp->ship_class].max_hull_strength;
|
||||
}
|
||||
|
||||
Assert(p_objp->ship_max_hull_strength > 0.0f); // Goober5000: div-0 check (not shield because we might not have one)
|
||||
@@ -3080,6 +3165,9 @@ void parse_common_object_data(p_object *objp)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Genghis: used later for subsystem checking
|
||||
ship_info* sip = &Ship_info[objp->ship_class];
|
||||
|
||||
// set some defaults..
|
||||
objp->initial_velocity = 0;
|
||||
objp->initial_hull = 100;
|
||||
@@ -3103,6 +3191,17 @@ void parse_common_object_data(p_object *objp)
|
||||
objp->subsys_count++;
|
||||
stuff_string(Subsys_status[i].name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// Genghis: check that the subsystem name makes sense for this ship type
|
||||
if (stricmp("Pilot", Subsys_status[i].name))
|
||||
{
|
||||
int j;
|
||||
for (j=0; j < sip->n_subsystems; ++j)
|
||||
if (!stricmp(sip->subsystems[j].subobj_name, Subsys_status[i].name))
|
||||
break;
|
||||
if (j == sip->n_subsystems)
|
||||
Warning(LOCATION, "Ship \"%s\", class \"%s\"\nUnknown subsystem \"%s\" found in mission!", objp->name, sip->name, Subsys_status[i].name);
|
||||
}
|
||||
|
||||
if (optional_string("$Damage:"))
|
||||
stuff_float(&Subsys_status[i].percent);
|
||||
|
||||
@@ -3111,9 +3210,15 @@ void parse_common_object_data(p_object *objp)
|
||||
char cargo_name[NAME_LENGTH];
|
||||
stuff_string(cargo_name, F_NAME, NAME_LENGTH);
|
||||
int index = string_lookup(cargo_name, Cargo_names, Num_cargo, "cargo", 0);
|
||||
if (index == -1 && (Num_cargo < MAX_CARGO)) {
|
||||
index = Num_cargo;
|
||||
strcpy(Cargo_names[Num_cargo++], cargo_name);
|
||||
if (index == -1) {
|
||||
if (Num_cargo < MAX_CARGO) {
|
||||
index = Num_cargo;
|
||||
strcpy(Cargo_names[Num_cargo++], cargo_name);
|
||||
}
|
||||
else {
|
||||
WarningEx(LOCATION, "Maximum number of cargo names (%d) exceeded, defaulting to Nothing!", MAX_CARGO);
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
Subsys_status[i].subsys_cargo_name = index;
|
||||
}
|
||||
@@ -4805,6 +4910,9 @@ void parse_bitmaps(mission *pm)
|
||||
}
|
||||
}
|
||||
|
||||
if (z == NUM_NEBULAS)
|
||||
WarningEx(LOCATION, "Mission %s\nUnknown nebula %s!", pm->name, str);
|
||||
|
||||
if (optional_string("+Color:")) {
|
||||
stuff_string(str, F_NAME, MAX_FILENAME_LEN);
|
||||
for (z=0; z<NUM_NEBULA_COLORS; z++){
|
||||
@@ -4815,6 +4923,9 @@ void parse_bitmaps(mission *pm)
|
||||
}
|
||||
}
|
||||
|
||||
if (z == NUM_NEBULA_COLORS)
|
||||
WarningEx(LOCATION, "Mission %s\nUnknown nebula color %s!", pm->name, str);
|
||||
|
||||
if (optional_string("+Pitch:")){
|
||||
stuff_int(&Nebula_pitch);
|
||||
} else {
|
||||
@@ -5001,9 +5112,7 @@ void parse_variables()
|
||||
// if the active mission has a variable with the same name as a campaign
|
||||
// variable AND it is not a block variable, override its initial value
|
||||
// with the previous mission's value
|
||||
if (!(stricmp(Sexp_variables[k].variable_name, Campaign.missions[i].saved_variables[j].variable_name))
|
||||
&& !(Campaign.missions[i].saved_variables[j].type & SEXP_VARIABLE_BLOCK))
|
||||
{
|
||||
if (!(stricmp(Sexp_variables[k].variable_name, Campaign.missions[i].saved_variables[j].variable_name)) ) {
|
||||
Sexp_variables[k].type = Campaign.missions[i].saved_variables[j].type;
|
||||
strcpy_s(Sexp_variables[k].text, Campaign.missions[i].saved_variables[j].text);
|
||||
}
|
||||
@@ -5020,9 +5129,7 @@ void parse_variables()
|
||||
// if the active mission has a variable with the same name as a player
|
||||
// variable AND it is not a block variable, override its initial value
|
||||
// with the previous mission's value
|
||||
if (!(stricmp(Sexp_variables[j].variable_name, Player->player_variables[i].variable_name))
|
||||
&& !(Player->player_variables[i].type & SEXP_VARIABLE_BLOCK))
|
||||
{
|
||||
if (!(stricmp(Sexp_variables[j].variable_name, Player->player_variables[i].variable_name)) ) {
|
||||
Sexp_variables[j].type = Player->player_variables[i].type;
|
||||
strcpy_s(Sexp_variables[j].text, Player->player_variables[i].text);
|
||||
}
|
||||
|
||||
@@ -400,8 +400,17 @@ typedef struct p_object {
|
||||
int group; // group object is within or -1 if none.
|
||||
int persona_index;
|
||||
float kamikaze_damage; // base damage for a kamikaze attack
|
||||
int special_exp_index;
|
||||
int special_hitpoint_index;
|
||||
|
||||
bool use_special_explosion; // new special explosion/hitpoints system
|
||||
int special_exp_damage;
|
||||
int special_exp_blast;
|
||||
int special_exp_inner;
|
||||
int special_exp_outer;
|
||||
bool use_shockwave;
|
||||
int special_exp_shockwave_speed;
|
||||
int special_hitpoints;
|
||||
int special_shield;
|
||||
|
||||
ushort net_signature; // network signature this object can have
|
||||
int destroy_before_mission_time;
|
||||
|
||||
@@ -485,8 +494,15 @@ typedef struct p_object {
|
||||
group = 0;
|
||||
persona_index = 0;
|
||||
kamikaze_damage = 0.;
|
||||
special_exp_index = 0;
|
||||
special_hitpoint_index = 0;
|
||||
use_special_explosion = false;
|
||||
special_exp_damage = -1;
|
||||
special_exp_blast = -1;
|
||||
special_exp_inner = -1;
|
||||
special_exp_outer = -1;
|
||||
use_shockwave = false;
|
||||
special_exp_shockwave_speed = -1;
|
||||
special_hitpoints = 0;
|
||||
special_shield = -1;
|
||||
net_signature = 0;
|
||||
destroy_before_mission_time = 0;
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ typedef struct {
|
||||
char Training_buf[TRAINING_MESSAGE_LENGTH];
|
||||
char *Training_lines[MAX_TRAINING_MESSAGE_LINES]; // Training message split into lines
|
||||
char Training_voice_filename[NAME_LENGTH];
|
||||
int Max_directives = TRAINING_OBJ_DISPLAY_LINES;
|
||||
int Training_message_timestamp;
|
||||
int Training_line_sizes[MAX_TRAINING_MESSAGE_LINES];
|
||||
int Training_message_method = 1;
|
||||
@@ -173,8 +174,8 @@ void training_obj_display()
|
||||
|
||||
offset = 0;
|
||||
end = Training_obj_num_lines;
|
||||
if (end > TRAINING_OBJ_DISPLAY_LINES) {
|
||||
end = TRAINING_OBJ_DISPLAY_LINES;
|
||||
if (end > Max_directives) {
|
||||
end = Max_directives;
|
||||
offset = Training_obj_num_lines - end;
|
||||
}
|
||||
|
||||
@@ -302,6 +303,9 @@ void training_mission_init()
|
||||
Training_obj_num_lines = 0;
|
||||
Training_message_queue_count = 0;
|
||||
Training_failure = 0;
|
||||
if (Max_directives > TRAINING_OBJ_LINES) {
|
||||
Max_directives = TRAINING_OBJ_LINES;
|
||||
}
|
||||
for (i=0; i<TRAINING_OBJ_LINES; i++)
|
||||
Training_obj_lines[i] = -1;
|
||||
|
||||
@@ -361,7 +365,7 @@ void sort_training_objectives()
|
||||
|
||||
// get the index of the first directive that will be displayed
|
||||
// if less than 0, display all lines
|
||||
offset = Training_obj_num_lines - TRAINING_OBJ_DISPLAY_LINES;
|
||||
offset = Training_obj_num_lines - Max_directives;
|
||||
|
||||
if (offset <= 0) {
|
||||
return;
|
||||
@@ -447,7 +451,7 @@ void sort_training_objectives()
|
||||
|
||||
// find first slot that can be bumped
|
||||
// look at the last (N-4 to N) positions
|
||||
for (slot_idx=0; slot_idx<TRAINING_OBJ_DISPLAY_LINES; slot_idx++) {
|
||||
for (slot_idx=0; slot_idx<Max_directives; slot_idx++) {
|
||||
if ( Training_obj_lines[i+offset] & TRAINING_OBJ_STATUS_KNOWN ) {
|
||||
break;
|
||||
}
|
||||
@@ -785,6 +789,8 @@ void message_training_setup(int m, int length, char *special_message)
|
||||
training_process_message(Training_buf);
|
||||
Training_num_lines = split_str(Training_buf, TRAINING_LINE_WIDTH, Training_line_sizes, Training_lines, MAX_TRAINING_MESSAGE_LINES);
|
||||
|
||||
Assert( Training_num_lines >= 0 );
|
||||
|
||||
if (message_play_training_voice(Messages[m].wave_info.index) < 0) {
|
||||
if (length > 0)
|
||||
Training_message_timestamp = timestamp(length * 1000);
|
||||
@@ -853,20 +859,25 @@ void message_training_queue(char *text, int timestamp, int length)
|
||||
|
||||
// Goober5000 - removes current message from the queue
|
||||
void message_training_remove_from_queue(int idx)
|
||||
{
|
||||
Training_message_queue[idx].length = -1;
|
||||
Training_message_queue[idx].num = -1;
|
||||
Training_message_queue[idx].timestamp = -1;
|
||||
|
||||
{
|
||||
// we're overwriting all messages with the next message, but to
|
||||
// avoid memory leaks, we should free the special message entry
|
||||
if (Training_message_queue[idx].special_message != NULL)
|
||||
{
|
||||
vm_free(Training_message_queue[idx].special_message);
|
||||
Training_message_queue[idx].special_message = NULL;
|
||||
}
|
||||
|
||||
// replace current message with the one above it, etc.
|
||||
for (int j=idx+1; j<Training_message_queue_count; j++)
|
||||
Training_message_queue[j - 1] = Training_message_queue[j];
|
||||
|
||||
// delete the topmost message
|
||||
Training_message_queue_count--;
|
||||
Training_message_queue[Training_message_queue_count].length = -1;
|
||||
Training_message_queue[Training_message_queue_count].num = -1;
|
||||
Training_message_queue[Training_message_queue_count].timestamp = -1;
|
||||
Training_message_queue[Training_message_queue_count].special_message = NULL; // not a memory leak because we copied the pointer
|
||||
}
|
||||
|
||||
// check the training message queue to see if we should play a new message yet or not.
|
||||
@@ -907,7 +918,11 @@ void message_training_display()
|
||||
|
||||
Training_message_visible = 0;
|
||||
message_training_queue_check();
|
||||
training_obj_display();
|
||||
|
||||
if ( !hud_disabled_except_messages() ) {
|
||||
training_obj_display();
|
||||
}
|
||||
|
||||
|
||||
if (Training_failure){
|
||||
return;
|
||||
@@ -917,20 +932,18 @@ void message_training_display()
|
||||
return;
|
||||
}
|
||||
|
||||
// next two lines moved to message_training_setup() - taylor
|
||||
// training_process_message(Training_buf);
|
||||
// Training_num_lines = split_str(Training_buf, TRAINING_LINE_WIDTH, Training_line_sizes, Training_lines, MAX_TRAINING_MESSAGE_LINES);
|
||||
|
||||
Assert(Training_num_lines > 0);
|
||||
for (i=0; i<Training_num_lines; i++) {
|
||||
Training_lines[i][Training_line_sizes[i]] = 0;
|
||||
drop_leading_white_space(Training_lines[i]);
|
||||
}
|
||||
// the code that preps the training message and counts the number of lines
|
||||
// has been moved to message_training_setup()
|
||||
|
||||
if (Training_num_lines <= 0){
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<Training_num_lines; i++) {
|
||||
Training_lines[i][Training_line_sizes[i]] = 0;
|
||||
drop_leading_white_space(Training_lines[i]);
|
||||
}
|
||||
|
||||
height = gr_get_font_height();
|
||||
gr_set_shader(&Training_msg_glass);
|
||||
gr_shade(Training_message_window_coords[gr_screen.res][0], Training_message_window_coords[gr_screen.res][1], TRAINING_MESSAGE_WINDOW_WIDTH, Training_num_lines * height + height);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
|
||||
|
||||
extern int Max_directives;
|
||||
extern int Training_message_method;
|
||||
extern int Training_num_lines;
|
||||
extern int Training_message_visible;
|
||||
|
||||
@@ -24,17 +24,52 @@
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------------
|
||||
// MISSION FICTION VIEWER DEFINES/VARS
|
||||
//
|
||||
#define NUM_FVW_SETTINGS 2
|
||||
|
||||
char *Fiction_viewer_screen_filename[GR_NUM_RESOLUTIONS] =
|
||||
char *Fiction_viewer_screen_filename[NUM_FVW_SETTINGS][GR_NUM_RESOLUTIONS] =
|
||||
{
|
||||
"fvw", // GR_640
|
||||
"2_fvw", // GR_1024
|
||||
{
|
||||
"FictionViewer", // GR_640
|
||||
"2_FictionViewer" // GR_1024
|
||||
},
|
||||
{
|
||||
"FictionViewerb", // GR_640
|
||||
"2_FictionViewerb" // GR_1024
|
||||
}
|
||||
};
|
||||
|
||||
char *Fiction_viewer_screen_mask[GR_NUM_RESOLUTIONS] =
|
||||
char *Fiction_viewer_screen_mask[NUM_FVW_SETTINGS][GR_NUM_RESOLUTIONS] =
|
||||
{
|
||||
"fvw-m", // GR_640
|
||||
"2_fvw-m", // GR_1024
|
||||
{
|
||||
"FictionViewer-m", // GR_640
|
||||
"2_FictionViewer-m" // GR_1024
|
||||
},
|
||||
{
|
||||
"FictionViewer-mb", // GR_640
|
||||
"2_FictionViewer-mb" // GR_1024
|
||||
}
|
||||
};
|
||||
|
||||
int Fiction_viewer_text_coordinates[NUM_FVW_SETTINGS][GR_NUM_RESOLUTIONS][4] =
|
||||
{
|
||||
// standard FS2-style interface
|
||||
{
|
||||
{ // GR_640
|
||||
17, 37, 588, 344
|
||||
},
|
||||
{ // GR_1024
|
||||
25, 48, 944, 576
|
||||
}
|
||||
},
|
||||
// WCS-style interface
|
||||
{
|
||||
{ // GR_640
|
||||
44, 50, 522, 348
|
||||
},
|
||||
{ // GR_1024
|
||||
71, 80, 835, 556
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define NUM_FVW_BUTTONS 3
|
||||
@@ -45,43 +80,70 @@ char *Fiction_viewer_screen_mask[GR_NUM_RESOLUTIONS] =
|
||||
// the xt and yt fields aren't normally used for width and height,
|
||||
// but the fields would go unused here and this is more
|
||||
// convenient for initialization
|
||||
ui_button_info Fiction_viewer_buttons[GR_NUM_RESOLUTIONS][NUM_FVW_BUTTONS] =
|
||||
ui_button_info Fiction_viewer_buttons[NUM_FVW_SETTINGS][GR_NUM_RESOLUTIONS][NUM_FVW_BUTTONS] =
|
||||
{
|
||||
{ // GR_640
|
||||
ui_button_info("fvw_accept_", 105, 444, 37, 26, 0),
|
||||
ui_button_info("fvw_up_", 576, 51, 37, 33, 1),
|
||||
ui_button_info("fvw_down_", 576, 364, 37, 33, 2),
|
||||
// standard FS2-style interface
|
||||
{
|
||||
{ // GR_640
|
||||
ui_button_info("fvw_accept_", 571, 425, 69, 55, FVW_BUTTON_ACCEPT),
|
||||
ui_button_info("fvw_up_", 614, 14, 25, 31, FVW_BUTTON_SCROLL_UP),
|
||||
ui_button_info("fvw_down_", 614, 370, 25, 31, FVW_BUTTON_SCROLL_DOWN),
|
||||
// Filename x y width height
|
||||
},
|
||||
{ // GR_1024
|
||||
ui_button_info("2_fvw_accept_", 918, 688, 99, 77, FVW_BUTTON_ACCEPT),
|
||||
ui_button_info("2_fvw_up_", 981, 16, 40, 50, FVW_BUTTON_SCROLL_UP),
|
||||
ui_button_info("2_fvw_down_", 981, 606, 40, 50, FVW_BUTTON_SCROLL_DOWN),
|
||||
}
|
||||
},
|
||||
{ // GR_1024
|
||||
ui_button_info("2_fvw_accept_", 168, 710, 59, 41, 0),
|
||||
ui_button_info("2_fvw_up_", 922, 81, 59, 53, 1),
|
||||
ui_button_info("2_fvw_down_", 922, 582, 59, 53, 2),
|
||||
// WCS-style interface
|
||||
{
|
||||
{ // GR_640
|
||||
ui_button_info("fvw_accept_", 105, 444, 37, 26, FVW_BUTTON_ACCEPT),
|
||||
ui_button_info("fvw_up_", 576, 51, 37, 33, FVW_BUTTON_SCROLL_UP),
|
||||
ui_button_info("fvw_down_", 576, 364, 37, 33, FVW_BUTTON_SCROLL_DOWN),
|
||||
},
|
||||
{ // GR_1024
|
||||
ui_button_info("2_fvw_accept_", 168, 710, 59, 41, FVW_BUTTON_ACCEPT),
|
||||
ui_button_info("2_fvw_up_", 922, 81, 59, 53, FVW_BUTTON_SCROLL_UP),
|
||||
ui_button_info("2_fvw_down_", 922, 582, 59, 53, FVW_BUTTON_SCROLL_DOWN),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
char *Fiction_viewer_slider_filename[GR_NUM_RESOLUTIONS] =
|
||||
char *Fiction_viewer_slider_filename[NUM_FVW_SETTINGS][GR_NUM_RESOLUTIONS] =
|
||||
{
|
||||
"fvw_slider_",
|
||||
"2_fvw_slider_"
|
||||
};
|
||||
|
||||
int Fiction_viewer_slider_coordinates[GR_NUM_RESOLUTIONS][4] =
|
||||
{
|
||||
{ // GR_640
|
||||
589, 83, 16, 280
|
||||
// standard FS2-style interface
|
||||
{
|
||||
"slider",
|
||||
"2_slider"
|
||||
},
|
||||
{ // GR_1024
|
||||
944, 132, 25, 451
|
||||
// WCS-style interface
|
||||
{
|
||||
"fvw_slider_",
|
||||
"2_fvw_slider_"
|
||||
}
|
||||
};
|
||||
|
||||
int Fiction_viewer_text_coordinates[GR_NUM_RESOLUTIONS][4] =
|
||||
int Fiction_viewer_slider_coordinates[NUM_FVW_SETTINGS][GR_NUM_RESOLUTIONS][4] =
|
||||
{
|
||||
{ // GR_640
|
||||
44, 50, 522, 348
|
||||
// standard FS2-style interface
|
||||
{
|
||||
{ // GR_640
|
||||
618, 48, 18, 320 //Initial position x, initial position y, width, height of the slider column
|
||||
},
|
||||
{ // GR_1024
|
||||
988, 70, 28, 532
|
||||
}
|
||||
},
|
||||
{ // GR_1024
|
||||
71, 80, 835, 556
|
||||
// WCS-style interface
|
||||
{
|
||||
{ // GR_640
|
||||
589, 83, 16, 280
|
||||
},
|
||||
{ // GR_1024
|
||||
944, 132, 25, 451
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -100,6 +162,8 @@ static char Fiction_viewer_filename[MAX_FILENAME_LEN];
|
||||
static char Fiction_viewer_font_filename[MAX_FILENAME_LEN];
|
||||
static char *Fiction_viewer_text = NULL;
|
||||
|
||||
static int Fiction_viewer_ui = -1;
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------------
|
||||
// FICTION VIEWER FUNCTIONS
|
||||
//
|
||||
@@ -186,11 +250,19 @@ void fiction_viewer_init()
|
||||
// music
|
||||
common_music_init(SCORE_FICTION_VIEWER);
|
||||
|
||||
// load the background bitmap
|
||||
Fiction_viewer_bitmap = bm_load(Fiction_viewer_screen_filename[gr_screen.res]);
|
||||
|
||||
// no graphics?
|
||||
if (Fiction_viewer_bitmap < 0)
|
||||
// see if we have a background bitmap, and if so, which one
|
||||
// currently, we prioritize the UI that comes latest in the array;
|
||||
// in the future we might specify this in the mission or in a tbl
|
||||
for (Fiction_viewer_ui = NUM_FVW_SETTINGS - 1; Fiction_viewer_ui >= 0; Fiction_viewer_ui--)
|
||||
{
|
||||
// load the first available background bitmap
|
||||
Fiction_viewer_bitmap = bm_load(Fiction_viewer_screen_filename[Fiction_viewer_ui][gr_screen.res]);
|
||||
if (Fiction_viewer_bitmap >= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// no ui is valid?
|
||||
if (Fiction_viewer_ui < 0)
|
||||
{
|
||||
Warning(LOCATION, "No fiction viewer graphics -- cannot display fiction viewer!");
|
||||
return;
|
||||
@@ -208,17 +280,17 @@ void fiction_viewer_init()
|
||||
}
|
||||
|
||||
// calculate text area lines from font
|
||||
Fiction_viewer_text_max_lines = Fiction_viewer_text_coordinates[gr_screen.res][3] / gr_get_font_height();
|
||||
Fiction_viewer_text_max_lines = Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][3] / gr_get_font_height();
|
||||
|
||||
// window
|
||||
Fiction_viewer_window.create(0, 0, gr_screen.max_w_unscaled, gr_screen.max_h_unscaled, 0, Fiction_viewer_fontnum);
|
||||
Fiction_viewer_window.set_mask_bmap(Fiction_viewer_screen_mask[gr_screen.res]);
|
||||
Fiction_viewer_window.set_mask_bmap(Fiction_viewer_screen_mask[Fiction_viewer_ui][gr_screen.res]);
|
||||
|
||||
// add the buttons
|
||||
for (int i = 0; i < NUM_FVW_BUTTONS; i++)
|
||||
{
|
||||
int repeat = (i == FVW_BUTTON_SCROLL_UP || i == FVW_BUTTON_SCROLL_DOWN);
|
||||
ui_button_info *b = &Fiction_viewer_buttons[gr_screen.res][i];
|
||||
ui_button_info *b = &Fiction_viewer_buttons[Fiction_viewer_ui][gr_screen.res][i];
|
||||
|
||||
b->button.create(&Fiction_viewer_window, "", b->x, b->y, b->xt, b->yt, repeat, 1);
|
||||
b->button.set_highlight_action(common_play_highlight_sound);
|
||||
@@ -227,23 +299,23 @@ void fiction_viewer_init()
|
||||
}
|
||||
|
||||
// set up hotkeys for buttons
|
||||
Fiction_viewer_buttons[gr_screen.res][FVW_BUTTON_ACCEPT].button.set_hotkey(KEY_CTRLED | KEY_ENTER);
|
||||
Fiction_viewer_buttons[gr_screen.res][FVW_BUTTON_SCROLL_UP].button.set_hotkey(KEY_UP);
|
||||
Fiction_viewer_buttons[gr_screen.res][FVW_BUTTON_SCROLL_DOWN].button.set_hotkey(KEY_DOWN);
|
||||
Fiction_viewer_buttons[Fiction_viewer_ui][gr_screen.res][FVW_BUTTON_ACCEPT].button.set_hotkey(KEY_CTRLED | KEY_ENTER);
|
||||
Fiction_viewer_buttons[Fiction_viewer_ui][gr_screen.res][FVW_BUTTON_SCROLL_UP].button.set_hotkey(KEY_UP);
|
||||
Fiction_viewer_buttons[Fiction_viewer_ui][gr_screen.res][FVW_BUTTON_SCROLL_DOWN].button.set_hotkey(KEY_DOWN);
|
||||
|
||||
// init brief text
|
||||
brief_color_text_init(Fiction_viewer_text, Fiction_viewer_text_coordinates[gr_screen.res][2], 0, 0);
|
||||
brief_color_text_init(Fiction_viewer_text, Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][2], 0, 0);
|
||||
|
||||
// if the story is going to overflow the screen, add a slider
|
||||
if (Num_brief_text_lines[0] > Fiction_viewer_text_max_lines)
|
||||
{
|
||||
Fiction_viewer_slider.create(&Fiction_viewer_window,
|
||||
Fiction_viewer_slider_coordinates[gr_screen.res][0],
|
||||
Fiction_viewer_slider_coordinates[gr_screen.res][1],
|
||||
Fiction_viewer_slider_coordinates[gr_screen.res][2],
|
||||
Fiction_viewer_slider_coordinates[gr_screen.res][3],
|
||||
Fiction_viewer_slider_coordinates[Fiction_viewer_ui][gr_screen.res][0],
|
||||
Fiction_viewer_slider_coordinates[Fiction_viewer_ui][gr_screen.res][1],
|
||||
Fiction_viewer_slider_coordinates[Fiction_viewer_ui][gr_screen.res][2],
|
||||
Fiction_viewer_slider_coordinates[Fiction_viewer_ui][gr_screen.res][3],
|
||||
Num_brief_text_lines[0] - Fiction_viewer_text_max_lines,
|
||||
Fiction_viewer_slider_filename[gr_screen.res],
|
||||
Fiction_viewer_slider_filename[Fiction_viewer_ui][gr_screen.res],
|
||||
&fiction_viewer_scroll_up,
|
||||
&fiction_viewer_scroll_down,
|
||||
&fiction_viewer_scroll_capture);
|
||||
@@ -307,7 +379,7 @@ void fiction_viewer_do_frame(float frametime)
|
||||
|
||||
// process button presses
|
||||
for (i = 0; i < NUM_FVW_BUTTONS; i++)
|
||||
if (Fiction_viewer_buttons[gr_screen.res][i].button.pressed())
|
||||
if (Fiction_viewer_buttons[Fiction_viewer_ui][gr_screen.res][i].button.pressed())
|
||||
fiction_viewer_button_pressed(i);
|
||||
|
||||
common_music_do();
|
||||
@@ -324,14 +396,14 @@ void fiction_viewer_do_frame(float frametime)
|
||||
Fiction_viewer_window.draw();
|
||||
|
||||
// render the briefing text
|
||||
brief_render_text(Top_fiction_viewer_text_line, Fiction_viewer_text_coordinates[gr_screen.res][0], Fiction_viewer_text_coordinates[gr_screen.res][1], Fiction_viewer_text_coordinates[gr_screen.res][3], frametime);
|
||||
brief_render_text(Top_fiction_viewer_text_line, Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][0], Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][1], Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][3], frametime);
|
||||
|
||||
// maybe output the "more" indicator
|
||||
if ((Fiction_viewer_text_max_lines + Top_fiction_viewer_text_line) < Num_brief_text_lines[0])
|
||||
{
|
||||
// can be scrolled down
|
||||
int more_txt_x = Fiction_viewer_text_coordinates[gr_screen.res][0] + (Fiction_viewer_text_coordinates[gr_screen.res][2]/2) - 10;
|
||||
int more_txt_y = Fiction_viewer_text_coordinates[gr_screen.res][1] + Fiction_viewer_text_coordinates[gr_screen.res][3] - 2; // located below text, centered
|
||||
int more_txt_x = Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][0] + (Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][2]/2) - 10;
|
||||
int more_txt_y = Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][1] + Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][3]; // located below text, centered
|
||||
|
||||
gr_get_string_size(&w, &h, XSTR("more", 1469), strlen(XSTR("more", 1469)));
|
||||
gr_set_color_fast(&Color_black);
|
||||
|
||||
@@ -1302,8 +1302,7 @@ int brief_setup_closeup(brief_icon *bi)
|
||||
end_string_at_first_hash_symbol(Closeup_icon->closeup_label);
|
||||
|
||||
// Goober5000 - wcsaga doesn't want this
|
||||
if (!Cmdline_wcsaga && sip->flags & (SIF_SMALL_SHIP|SIF_BIG_SHIP|SIF_HUGE_SHIP|SIF_SENTRYGUN))
|
||||
{
|
||||
if (Ship_types[sip->class_type].hud_bools & STI_HUD_NO_CLASS_DISPLAY ) {
|
||||
strcat_s(Closeup_icon->closeup_label, XSTR( " class", 434));
|
||||
}
|
||||
|
||||
|
||||
@@ -193,7 +193,6 @@ static int Voice_ended_time;
|
||||
//static anim_instance *Cur_anim_instance = NULL;
|
||||
static generic_anim Cur_Anim;
|
||||
static char *Cur_anim_filename = "~~~~";
|
||||
static int anim_done = 0;
|
||||
|
||||
static int Last_anim_frame_num;
|
||||
|
||||
@@ -342,11 +341,6 @@ void cmd_brief_new_stage(int stage)
|
||||
|
||||
// load a new animation if it's different to what's already playing
|
||||
if (strcmp(Cur_anim_filename, Cur_cmd_brief->stage[stage].ani_filename) != 0) {
|
||||
// set stuff up
|
||||
int stream_result = -1;
|
||||
ubyte bg_type = bm_get_type(Cmd_brief_background_bitmap);
|
||||
anim_done = 0;
|
||||
|
||||
// unload the previous anim
|
||||
if(Cur_Anim.num_frames > 0) {
|
||||
generic_anim_unload(&Cur_Anim);
|
||||
@@ -355,40 +349,8 @@ void cmd_brief_new_stage(int stage)
|
||||
// save new filename
|
||||
Cur_anim_filename = Cur_cmd_brief->stage[stage].ani_filename;
|
||||
|
||||
// hi-res support
|
||||
if (gr_screen.res == GR_1024) {
|
||||
// attempt to load a hi-res animation
|
||||
memset(filename, 0, NAME_LENGTH);
|
||||
strcpy_s(filename, "2_");
|
||||
strncat(filename, Cur_anim_filename, NAME_LENGTH - 3);
|
||||
|
||||
// remove extension
|
||||
p = strchr(filename, '.');
|
||||
if(p) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
// attempt to stream the hi-res ani
|
||||
generic_anim_init(&Cur_Anim, filename);
|
||||
Cur_Anim.ani.bg_type = bg_type;
|
||||
stream_result = generic_anim_stream(&Cur_Anim);
|
||||
}
|
||||
|
||||
// we failed to stream hi-res, or we aren't running in hi-res, so try low-res
|
||||
if (stream_result < 0) {
|
||||
strcpy_s(filename, Cur_anim_filename);
|
||||
|
||||
// remove extension
|
||||
p = strchr(filename, '.');
|
||||
if(p) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
// attempt to stream the low-res ani
|
||||
generic_anim_init(&Cur_Anim, filename);
|
||||
Cur_Anim.ani.bg_type = bg_type;
|
||||
stream_result = generic_anim_stream(&Cur_Anim);
|
||||
}
|
||||
// try to load the new anim in either high or low res
|
||||
int stream_result = generic_anim_init_and_stream(&Cur_Anim, Cur_anim_filename, bm_get_type(Cmd_brief_background_bitmap), true);
|
||||
|
||||
// we've failed to load any animation
|
||||
if (stream_result < 0) {
|
||||
|
||||
@@ -2644,7 +2644,7 @@ void debrief_do_frame(float frametime)
|
||||
}
|
||||
|
||||
// maybe show skip mission popup
|
||||
if ((!Debrief_skip_popup_already_shown) && (Player->show_skip_popup) && (Game_mode & GM_NORMAL) && (Game_mode & GM_CAMPAIGN_MODE) && (Player->failures_this_session >= PLAYER_MISSION_FAILURE_LIMIT) && !(Game_mode & GM_MULTIPLAYER)) {
|
||||
if ( Must_replay_mission && (!Debrief_skip_popup_already_shown) && (Player->show_skip_popup) && (Game_mode & GM_NORMAL) && (Game_mode & GM_CAMPAIGN_MODE) && (Player->failures_this_session >= PLAYER_MISSION_FAILURE_LIMIT) && !(Game_mode & GM_MULTIPLAYER)) {
|
||||
int popup_choice = popup(0, 3, XSTR("Do Not Skip This Mission", 1473),
|
||||
XSTR("Advance To The Next Mission", 1474),
|
||||
XSTR("Don't Show Me This Again", 1475),
|
||||
|
||||
@@ -1481,7 +1481,7 @@ void ship_select_do(float frametime)
|
||||
//////////////////////////////////
|
||||
// Render and draw the 3D model //
|
||||
//////////////////////////////////
|
||||
if( Cmdline_ship_choice_3d || ((Ss_icons != NULL) && (Selected_ss_class >= 0) && (Ss_icons[Selected_ss_class].ss_anim.num_frames > 0)) )
|
||||
if( Cmdline_ship_choice_3d || ( (Selected_ss_class >= 0) && (Ss_icons[Selected_ss_class].ss_anim.num_frames == 0)) )
|
||||
{
|
||||
// check we have a valid ship class selected
|
||||
if ( (Selected_ss_class >= 0) && (ShipSelectModelNum >= 0) )
|
||||
@@ -1713,6 +1713,12 @@ void start_ship_animation(int ship_class, int play_sound)
|
||||
return;
|
||||
}
|
||||
|
||||
//Unload Anim if one was playing
|
||||
if(Ship_anim_class > 0 && Ss_icons[Ship_anim_class].ss_anim.num_frames > 0) {
|
||||
generic_anim_unload(&Ss_icons[Ship_anim_class].ss_anim);
|
||||
Ship_anim_class = -1;
|
||||
}
|
||||
|
||||
// Load the necessary model file
|
||||
ShipSelectModelNum = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
|
||||
|
||||
@@ -1733,6 +1739,12 @@ void start_ship_animation(int ship_class, int play_sound)
|
||||
|
||||
ss_icon = &Ss_icons[ship_class];
|
||||
|
||||
//If there was a model loaded for the previous ship, unload it
|
||||
if (ShipSelectModelNum >= 0 ) {
|
||||
model_unload(ShipSelectModelNum);
|
||||
ShipSelectModelNum = -1;
|
||||
}
|
||||
|
||||
//unload the previous anim
|
||||
if(Ship_anim_class > 0 && Ss_icons[Ship_anim_class].ss_anim.num_frames > 0)
|
||||
generic_anim_unload(&Ss_icons[Ship_anim_class].ss_anim);
|
||||
@@ -1764,7 +1776,6 @@ void start_ship_animation(int ship_class, int play_sound)
|
||||
// if ( play_sound ) {
|
||||
gamesnd_play_iface(SND_SHIP_ICON_CHANGE);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
void ss_unload_all_anims()
|
||||
|
||||
@@ -315,6 +315,7 @@ typedef struct bsp_info {
|
||||
bool nocollide_this_only; //SUSHI: Like no_collisions, but not recursive. For the "replacement" collision model scheme.
|
||||
bool collide_invisible; //SUSHI: If set, this submodel should allow collisions for invisible textures. For the "replacement" collision model scheme.
|
||||
bool force_turret_normal; //Wanderer: Sets the turret uvec to override any input of for turret normal.
|
||||
char lod_name[MAX_NAME_LEN]; //FUBAR: Name to be used for LOD naming comparison to preserve compatibility with older tables. Only used on LOD0
|
||||
|
||||
float dumb_turn_rate;
|
||||
|
||||
@@ -350,6 +351,7 @@ typedef struct bsp_info {
|
||||
dumb_turn_rate = 0.f;
|
||||
bsp_data = NULL;
|
||||
rad = 0.f;
|
||||
lod_name[ 0 ] = '\0';
|
||||
|
||||
/* Compound types */
|
||||
memset( live_debris, 0, sizeof( live_debris ) );
|
||||
|
||||
@@ -100,7 +100,7 @@ void triggered_rotation::start(queued_animation *q)
|
||||
if (q->accel.a1d[axis] == 0.0f)
|
||||
slow_angle.a1d[axis] = end_angle.a1d[axis];
|
||||
else
|
||||
slow_angle.a1d[axis] = end_angle.a1d[axis] - (((q->vel.a1d[axis] * q->vel.a1d[axis]) / (2.0f * q->accel.a1d[axis])) * direction.a1d[axis]);
|
||||
slow_angle.a1d[axis] = end_angle.a1d[axis] + (((q->vel.a1d[axis] * q->vel.a1d[axis]) / (2.0f * q->accel.a1d[axis])) * direction.a1d[axis]);
|
||||
}
|
||||
|
||||
nprintf(("ModelAnim", "Dir=[%f, %f, %f], End=[%f, %f, %f], Vel=[%f, %f, %f], Accel=[%f, %f, %f], Slow=[%f, %f, %f]\n", direction.a1d[0], direction.a1d[1], direction.a1d[2],
|
||||
@@ -421,7 +421,7 @@ void model_anim_submodel_trigger_rotate(model_subsystem *psub, ship_subsys *ss)
|
||||
}
|
||||
|
||||
// if we've over shot the angle, this shouldn't happen but it might if odd values are given
|
||||
if ( (trigger->current_ang.a1d[i] * trigger->direction.a1d[i]) > (trigger->end_angle.a1d[i] * trigger->direction.a1d[i]) ) {
|
||||
if ( (trigger->current_ang.a1d[i] * trigger->direction.a1d[i]) >= (trigger->end_angle.a1d[i] * trigger->direction.a1d[i]) ) {
|
||||
trigger->current_ang.a1d[i] = trigger->end_angle.a1d[i];
|
||||
trigger->current_vel.a1d[i] = 0.0f;
|
||||
not_moving_count++;
|
||||
@@ -654,6 +654,7 @@ int model_anim_get_time_type(ship_subsys *pss, int animation_type, int subtype)
|
||||
int pad = real_time - psub->triggers[i].end;
|
||||
|
||||
for (int a = 0; a < 3; a++) {
|
||||
/*
|
||||
float direction = pss->trigger.direction.a1d[a];
|
||||
|
||||
// if it's in the final slowdown phase then it really isn't _that_ bad
|
||||
@@ -687,8 +688,29 @@ int model_anim_get_time_type(ship_subsys *pss, int animation_type, int subtype)
|
||||
ani_time = a_time;
|
||||
}
|
||||
}
|
||||
*/
|
||||
// Wanderer Way -- START
|
||||
// end_angle = S(2)
|
||||
triggered_rotation tr = pss->trigger;
|
||||
float end_angle = (tr.current_ang.a1d[a] + (((tr.rot_vel.a1d[a]*tr.rot_vel.a1d[a]) - (tr.current_vel.a1d[a]*tr.current_vel.a1d[a])) / (2*tr.rot_accel.a1d[a])));
|
||||
|
||||
if (end_angle > tr.slow_angle.a1d[a]) {
|
||||
//T(total) = (2V(maximum) - V(initial))/a + (S(turnpoint) - S(initial) + (V(initial)^2 - V(maximum)^2)/2a) / V(maximum)
|
||||
a_time = fl2i(((((2*tr.rot_vel.a1d[a]) - tr.current_ang.a1d[a])/tr.rot_accel.a1d[a]) + tr.slow_angle.a1d[a] - tr.current_ang.a1d[a] + (((tr.current_vel.a1d[a]*tr.current_vel.a1d[a]) - (tr.rot_vel.a1d[a]*tr.rot_vel.a1d[a])) / (2*tr.rot_accel.a1d[a])))*1000.0f);
|
||||
if (ani_time < a_time)
|
||||
ani_time = a_time;
|
||||
} else {
|
||||
//T(total) = 2 * sqrt((S(final) - S(initial))/a - ( (V(initial)/a)^2 ) / 2 ) - V(initial)/a
|
||||
a_time = fl2i((2 * fl_sqrt(((tr.end_angle.a1d[a] - tr.current_ang.a1d[a])/tr.rot_accel.a1d[a]) - ((tr.current_vel.a1d[a] * tr.current_vel.a1d[a]) / (tr.rot_accel.a1d[a] * tr.rot_accel.a1d[a])) / 2) - (tr.current_vel.a1d[a] / tr.rot_accel.a1d[a]))*1000.0f);
|
||||
if (ani_time < a_time)
|
||||
ani_time = a_time;
|
||||
}
|
||||
|
||||
// Wanderer Way -- END
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (ani_time)
|
||||
ani_time += pad;
|
||||
} else {
|
||||
|
||||
@@ -1335,6 +1335,9 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs
|
||||
else
|
||||
pm->submodel[n].gun_rotation = false;
|
||||
|
||||
if ( (p = strstr(props, "$lod0_name")) != NULL)
|
||||
get_user_prop_value(p+10, pm->submodel[n].lod_name);
|
||||
|
||||
if ( (p = strstr(props, "$detail_box:")) != NULL ) {
|
||||
p += 12;
|
||||
while (*p == ' ') p++;
|
||||
@@ -1502,6 +1505,13 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs
|
||||
else
|
||||
pm->submodel[n].is_thruster=0;
|
||||
|
||||
// Genghis: if we have a thruster and none of the collision
|
||||
// properties were provided, then set "nocollide_this_only".
|
||||
if (pm->submodel[n].is_thruster && !(pm->submodel[n].no_collisions) && !(pm->submodel[n].nocollide_this_only) && !(pm->submodel[n].collide_invisible) )
|
||||
{
|
||||
pm->submodel[n].nocollide_this_only = true;
|
||||
}
|
||||
|
||||
if ( strstr( pm->submodel[n].name, "-destroyed") )
|
||||
pm->submodel[n].is_damaged=1;
|
||||
else
|
||||
@@ -2483,7 +2493,14 @@ int model_load(char *filename, int n_subsystems, model_subsystem *subsystems, in
|
||||
}
|
||||
|
||||
sm1->num_details = 0;
|
||||
l1 = strlen(sm1->name);
|
||||
// If a backward compatibility LOD name is declared use it
|
||||
if (strlen(sm1->lod_name) != 0) {
|
||||
l1=strlen(sm1->lod_name);
|
||||
}
|
||||
// otherwise use the name for LOD comparision
|
||||
else {
|
||||
l1 = strlen(sm1->name);
|
||||
}
|
||||
|
||||
for (j=0; j<pm->num_debris_objects;j++ ) {
|
||||
if ( i == pm->debris_objects[j] ) {
|
||||
@@ -2508,19 +2525,36 @@ int model_load(char *filename, int n_subsystems, model_subsystem *subsystems, in
|
||||
}
|
||||
|
||||
// if sm2 is a detail of sm1 and sm1 is a high detail, then add it to sm1's list
|
||||
if ((int)strlen(sm2->name)!=l1) continue;
|
||||
if ((int)strlen(sm2->name)!=l1) continue;
|
||||
|
||||
int ndiff = 0;
|
||||
int first_diff = 0;
|
||||
for ( k=0; k<l1; k++) {
|
||||
if (sm1->name[k] != sm2->name[k] ) {
|
||||
if (ndiff==0) first_diff = k;
|
||||
ndiff++;
|
||||
// If a backward compatibility LOD name is declared use it
|
||||
if (strlen(sm1->lod_name) != 0) {
|
||||
if (sm1->lod_name[k] != sm2->name[k] ) {
|
||||
if (ndiff==0) first_diff = k;
|
||||
ndiff++;
|
||||
}
|
||||
}
|
||||
// otherwise do the standard LOD comparision
|
||||
else {
|
||||
if (sm1->name[k] != sm2->name[k] ) {
|
||||
if (ndiff==0) first_diff = k;
|
||||
ndiff++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ndiff==1) { // They only differ by one character!
|
||||
int dl1, dl2;
|
||||
dl1 = tolower(sm1->name[first_diff]) - 'a';
|
||||
// If a backward compatibility LOD name is declared use it
|
||||
if (strlen(sm1->lod_name) != 0) {
|
||||
dl1 = tolower(sm1->lod_name[first_diff]) - 'a';
|
||||
}
|
||||
// otherwise do the standard LOD comparision
|
||||
else {
|
||||
dl1 = tolower(sm1->name[first_diff]) - 'a';
|
||||
}
|
||||
dl2 = tolower(sm2->name[first_diff]) - 'a';
|
||||
|
||||
if ( (dl1<0) || (dl2<0) || (dl1>=MAX_MODEL_DETAIL_LEVELS) || (dl2>=MAX_MODEL_DETAIL_LEVELS) ) continue; // invalid detail levels
|
||||
@@ -2529,7 +2563,7 @@ int model_load(char *filename, int n_subsystems, model_subsystem *subsystems, in
|
||||
dl2--; // Start from 1 up...
|
||||
if (dl2 >= sm1->num_details ) sm1->num_details = dl2+1;
|
||||
sm1->details[dl2] = j;
|
||||
//mprintf(( "Submodel '%s' is detail level %d of '%s'\n", sm2->name, dl2, sm1->name ));
|
||||
mprintf(( "Submodel '%s' is detail level %d of '%s'\n", sm2->name, dl2 + 1, sm1->name ));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2784,11 +2818,13 @@ float submodel_get_radius( int modelnum, int submodelnum )
|
||||
|
||||
polymodel * model_get(int model_num)
|
||||
{
|
||||
Assert( model_num > -1 );
|
||||
Assert( model_num >= 0 );
|
||||
if ( model_num < 0 )
|
||||
return NULL;
|
||||
|
||||
int num = model_num % MAX_POLYGON_MODELS;
|
||||
|
||||
Assert( num > -1 );
|
||||
Assert( num >= 0 );
|
||||
Assert( num < MAX_POLYGON_MODELS );
|
||||
Assert( Polygon_models[num] );
|
||||
Assert( Polygon_models[num]->id == model_num );
|
||||
|
||||
@@ -279,6 +279,9 @@ void neb2_init()
|
||||
if(Neb2_bitmap_count < MAX_NEB2_BITMAPS){
|
||||
strcpy_s(Neb2_bitmap_filenames[Neb2_bitmap_count++], name);
|
||||
}
|
||||
else {
|
||||
WarningEx(LOCATION, "nebula.tbl\nExceeded maximum number of nebulas (%d)!\nSkipping %s.", MAX_NEB2_BITMAPS, name);
|
||||
}
|
||||
}
|
||||
|
||||
// poofs
|
||||
@@ -291,6 +294,9 @@ void neb2_init()
|
||||
if(Neb2_poof_count < MAX_NEB2_POOFS){
|
||||
strcpy_s(Neb2_poof_filenames[Neb2_poof_count++], name);
|
||||
}
|
||||
else {
|
||||
WarningEx(LOCATION, "nebula.tbl\nExceeded maximum number of nebula poofs (%d)!\nSkipping %s.", MAX_NEB2_POOFS, name);
|
||||
}
|
||||
}
|
||||
|
||||
//Distance
|
||||
|
||||
@@ -1593,6 +1593,9 @@ void standalone_main_init()
|
||||
|
||||
// if this is a tracker game then we have some extra tasks to perform
|
||||
if (MULTI_IS_TRACKER_GAME) {
|
||||
// disconnect and prepare for reset if we are already connected
|
||||
fs2netd_disconnect();
|
||||
|
||||
// login (duh!)
|
||||
if ( fs2netd_login() ) {
|
||||
// validate missions
|
||||
@@ -1659,7 +1662,7 @@ void multi_standalone_reset_all()
|
||||
delete_player( idx );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// make sure we go to the proper state.
|
||||
if(gameseq_get_state() == GS_STATE_STANDALONE_MAIN){
|
||||
standalone_main_init();
|
||||
|
||||
@@ -133,7 +133,7 @@ void multi_sexp_maybe_send_packet()
|
||||
return;
|
||||
}
|
||||
|
||||
send_sexp_packet(data, packet_end + 1);
|
||||
send_sexp_packet(data, sub_packet_size);
|
||||
|
||||
j = 0;
|
||||
//Slide down any entries after the stored index to the start of the array.
|
||||
@@ -143,12 +143,21 @@ void multi_sexp_maybe_send_packet()
|
||||
j++;
|
||||
}
|
||||
|
||||
// if we have an existing argument count we need to update where to put it too
|
||||
if (current_argument_count) {
|
||||
argument_count_index -= sub_packet_size;
|
||||
packet_size = j;
|
||||
|
||||
// flush the remaining type buffer
|
||||
for (i = j ; i < MAX_PACKET_SIZE ; i++) {
|
||||
type[i] = -1;
|
||||
}
|
||||
|
||||
packet_size = j;
|
||||
// if we have an existing argument count we need to update where to put it too
|
||||
if (current_argument_count) {
|
||||
argument_count_index = argument_count_index - sub_packet_size;
|
||||
}
|
||||
|
||||
Assert(argument_count_index >=0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// flushes out the packet and sends any data still in there
|
||||
@@ -197,6 +206,8 @@ void multi_send_ship(int shipnum)
|
||||
}
|
||||
|
||||
multi_send_ship(&Ships[shipnum]);
|
||||
|
||||
multi_sexp_maybe_send_packet();
|
||||
}
|
||||
|
||||
void multi_send_ship(ship *shipp)
|
||||
|
||||
@@ -1901,7 +1901,7 @@ void multi_join_send_join_request(int as_observer)
|
||||
return;
|
||||
}
|
||||
|
||||
nprintf(("Password : %s\n",Multi_join_request.passwd));
|
||||
nprintf(("Network", "Password : %s\n", Multi_join_request.passwd));
|
||||
}
|
||||
|
||||
// fill out the join request struct
|
||||
|
||||
@@ -753,12 +753,14 @@ int weapon_will_never_hit( object *obj_weapon, object *other, obj_pair * current
|
||||
|
||||
float max_vel_weapon, max_vel_other;
|
||||
|
||||
max_vel_weapon = wp->weapon_max_vel;
|
||||
|
||||
if ((wp->lssm_stage==5))
|
||||
{
|
||||
//SUSHI: Fix bug where additive weapon velocity screws up collisions
|
||||
//Assumes that weapons which don't home don't change speed, which is currently the case.
|
||||
if (!(wip->wi_flags & WIF_TURNS))
|
||||
max_vel_weapon = obj_weapon->phys_info.speed;
|
||||
else if ((wp->lssm_stage==5))
|
||||
max_vel_weapon = wip->lssm_stage5_vel;
|
||||
}
|
||||
else
|
||||
max_vel_weapon = wp->weapon_max_vel;
|
||||
|
||||
max_vel_other = other->phys_info.max_vel.xyz.z;
|
||||
if (max_vel_other < 10.0f) {
|
||||
|
||||
@@ -790,6 +790,8 @@ void obj_move_call_physics(object *objp, float frametime)
|
||||
int points = pm->missile_banks[i].num_slots;
|
||||
int missles_left = shipp->weapons.secondary_bank_ammo[i];
|
||||
int next_point = shipp->weapons.secondary_next_slot[i];
|
||||
float fire_wait = Weapon_info[shipp->weapons.secondary_bank_weapons[i]].fire_wait;
|
||||
float reload_time = (fire_wait == 0.0f) ? 1.0f : 1.0f / fire_wait;
|
||||
|
||||
//ok so...we want to move up missles but only if there is a missle there to be moved up
|
||||
//there is a missle behind next_point, and how ever many missles there are left after that
|
||||
@@ -799,7 +801,7 @@ void obj_move_call_physics(object *objp, float frametime)
|
||||
for (int k = next_point; k < next_point+missles_left; k ++) {
|
||||
float &s_pct = shipp->secondary_point_reload_pct[i][k % points];
|
||||
if (s_pct < 1.0)
|
||||
s_pct += shipp->reload_time[i] * frametime;
|
||||
s_pct += reload_time * frametime;
|
||||
if (s_pct > 1.0)
|
||||
s_pct = 1.0f;
|
||||
}
|
||||
@@ -808,7 +810,7 @@ void obj_move_call_physics(object *objp, float frametime)
|
||||
for (int k = 0; k < points; k++) {
|
||||
float &s_pct = shipp->secondary_point_reload_pct[i][k];
|
||||
if (s_pct < 1.0)
|
||||
s_pct += shipp->reload_time[i] * frametime;
|
||||
s_pct += reload_time * frametime;
|
||||
if (s_pct > 1.0)
|
||||
s_pct = 1.0f;
|
||||
}
|
||||
@@ -1927,7 +1929,6 @@ void object_set_gliding(object *objp, bool enable)
|
||||
|
||||
if(enable) {
|
||||
objp->phys_info.flags |= PF_GLIDING;
|
||||
objp->phys_info.glide_saved_vel = Player_obj->phys_info.vel;
|
||||
} else {
|
||||
objp->phys_info.flags &= ~PF_GLIDING;
|
||||
vm_vec_rotate(&objp->phys_info.prev_ramp_vel, &objp->phys_info.vel, &objp->orient); //Backslash
|
||||
|
||||
@@ -49,7 +49,9 @@ void shield_add_strength(object *objp, float delta)
|
||||
if (delta == 0.0f)
|
||||
return;
|
||||
|
||||
if (!(Ai_info[Ships[objp->instance].ai_index].ai_profile_flags & AIPF_SMART_SHIELD_MANAGEMENT))
|
||||
|
||||
if (!(Ai_info[Ships[objp->instance].ai_index].ai_profile_flags & AIPF_SMART_SHIELD_MANAGEMENT)
|
||||
|| delta <= 0.0f) //SUSHI: We don't want smart shield management for negative delta
|
||||
{
|
||||
for (int i = 0; i < MAX_SHIELD_SECTIONS; i++)
|
||||
shield_add_quad(objp, i, delta / MAX_SHIELD_SECTIONS);
|
||||
|
||||
@@ -156,14 +156,14 @@ void save_filter_info(void)
|
||||
|
||||
void outwnd_printf2(char *format, ...)
|
||||
{
|
||||
char tmp[MAX_LINE_WIDTH*4];
|
||||
char tmp[MAX_LINE_WIDTH*4] = {'\0'};
|
||||
va_list args;
|
||||
|
||||
if (format == NULL)
|
||||
return;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf(tmp, format, args);
|
||||
vsnprintf(tmp, sizeof(tmp)-1,format, args);
|
||||
va_end(args);
|
||||
|
||||
outwnd_print("General", tmp);
|
||||
@@ -171,14 +171,14 @@ void outwnd_printf2(char *format, ...)
|
||||
|
||||
void outwnd_printf(char *id, char *format, ...)
|
||||
{
|
||||
char tmp[MAX_LINE_WIDTH*4];
|
||||
char tmp[MAX_LINE_WIDTH*4] = {'\0'};
|
||||
va_list args;
|
||||
|
||||
if ( (id == NULL) || (format == NULL) )
|
||||
return;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf(tmp, format, args);
|
||||
vsnprintf(tmp, sizeof(tmp)-1,format, args);
|
||||
va_end(args);
|
||||
|
||||
outwnd_print(id, tmp);
|
||||
@@ -297,7 +297,7 @@ void safe_point_print(char *format, ...)
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf(tmp, format, args);
|
||||
vsnprintf(tmp, sizeof(tmp)-1,format, args);
|
||||
va_end(args);
|
||||
strcpy(safe_string, tmp);
|
||||
}
|
||||
|
||||
+374
-3
@@ -43,6 +43,7 @@
|
||||
#include "sound/audiostr.h"
|
||||
#include "sound/ds.h"
|
||||
#include "weapon/weapon.h"
|
||||
#include "weapon/beam.h"
|
||||
|
||||
//*************************Lua globals*************************
|
||||
SCP_vector<ade_table_entry> Ade_table_entries;
|
||||
@@ -3725,6 +3726,18 @@ ADE_FUNC(isValid, l_Weaponclass, NULL, "Detects whether handle is valid", "boole
|
||||
return ADE_RETURN_TRUE;
|
||||
}
|
||||
|
||||
ADE_FUNC(getWeaponClassIndex, l_Weaponclass, NULL, "Gets the index valus of the weapon class", "number", "index value of the weapon class")
|
||||
{
|
||||
int idx;
|
||||
if(!ade_get_args(L, "o", l_Weaponclass.Get(&idx)))
|
||||
return ade_set_args(L, "i", -1);
|
||||
|
||||
if(idx < 0 || idx >= Num_weapon_types)
|
||||
return ade_set_args(L, "i", -1);
|
||||
|
||||
return ade_set_args(L, "i", idx);
|
||||
}
|
||||
|
||||
//**********HANDLE: Eyepoint
|
||||
struct eye_h
|
||||
{
|
||||
@@ -4092,20 +4105,27 @@ ADE_FUNC(checkRayCollision, l_Object, "vector Start Point, vector End Point, [bo
|
||||
return ADE_RETURN_NIL;
|
||||
|
||||
obj = objh->objp;
|
||||
int flags = 0;
|
||||
int submodel = -1;
|
||||
|
||||
switch(obj->type) {
|
||||
case OBJ_SHIP:
|
||||
model_num = Ship_info[Ships[obj->instance].ship_info_index].model_num;
|
||||
flags = (MC_CHECK_MODEL | MC_CHECK_RAY);
|
||||
break;
|
||||
case OBJ_WEAPON:
|
||||
model_num = Weapon_info[Weapons[obj->instance].weapon_info_index].model_num;
|
||||
flags = (MC_CHECK_MODEL | MC_CHECK_RAY);
|
||||
break;
|
||||
case OBJ_DEBRIS:
|
||||
model_num = Debris[obj->instance].model_num;
|
||||
flags = (MC_CHECK_MODEL | MC_CHECK_RAY | MC_SUBMODEL);
|
||||
submodel = Debris[obj->instance].submodel_num;
|
||||
break;
|
||||
case OBJ_ASTEROID:
|
||||
temp = Asteroids[obj->instance].asteroid_subtype;
|
||||
model_num = Asteroid_info[Asteroids[obj->instance].asteroid_type].model_num[temp];
|
||||
flags = (MC_CHECK_MODEL | MC_CHECK_RAY);
|
||||
break;
|
||||
default:
|
||||
return ADE_RETURN_NIL;
|
||||
@@ -4117,11 +4137,12 @@ ADE_FUNC(checkRayCollision, l_Object, "vector Start Point, vector End Point, [bo
|
||||
mc_info hull_check;
|
||||
|
||||
hull_check.model_num = model_num;
|
||||
hull_check.submodel_num = submodel;
|
||||
hull_check.orient = &obj->orient;
|
||||
hull_check.pos = &obj->pos;
|
||||
hull_check.p0 = v3a;
|
||||
hull_check.p1 = v3b;
|
||||
hull_check.flags = MC_CHECK_MODEL | MC_CHECK_RAY;
|
||||
hull_check.flags = flags;
|
||||
|
||||
if ( !model_collide(&hull_check) ) {
|
||||
return ADE_RETURN_NIL;
|
||||
@@ -4734,6 +4755,18 @@ ADE_FUNC(isModelLoaded, l_Shipclass, "[boolean Load = false]", "Checks if the mo
|
||||
return ADE_RETURN_FALSE;
|
||||
}
|
||||
|
||||
ADE_FUNC(getShipClassIndex, l_Shipclass, NULL, "Gets the index valus of the ship class", "number", "index value of the ship class")
|
||||
{
|
||||
int idx;
|
||||
if(!ade_get_args(L, "o", l_Shipclass.Get(&idx)))
|
||||
return ade_set_args(L, "i", -1);
|
||||
|
||||
if(idx < 0 || idx >= Num_ship_classes)
|
||||
return ade_set_args(L, "i", -1);
|
||||
|
||||
return ade_set_args(L, "i", idx);
|
||||
}
|
||||
|
||||
//**********HANDLE: Waypoint
|
||||
ade_obj<object_h> l_Waypoint("waypoint", "waypoint handle", &l_Object);
|
||||
|
||||
@@ -6222,6 +6255,7 @@ ADE_FUNC(hasShipExploded, l_Ship, NULL, "Checks if the ship explosion event has
|
||||
if (shipp->pre_death_explosion_happened == 1) {
|
||||
return ade_set_args(L, "i", 1);
|
||||
}
|
||||
return ade_set_args(L, "i", 3);
|
||||
}
|
||||
|
||||
return ade_set_args(L, "i", 0);
|
||||
@@ -6935,6 +6969,312 @@ ADE_VIRTVAR(Team, l_Weapon, "team", "Weapon's team", "team", "Weapon team, or in
|
||||
return ade_set_args(L, "o", l_Team.Set(wp->team));
|
||||
}
|
||||
|
||||
ADE_FUNC(isArmed, l_Weapon, "[boolean Hit target]", "Checks if the weapon is armed.", "boolean", "boolean value of the weapon arming status")
|
||||
{
|
||||
object_h *oh = NULL;
|
||||
bool hit_target = false;
|
||||
if(!ade_get_args(L, "o|b", l_Weapon.GetPtr(&oh), &hit_target))
|
||||
return ADE_RETURN_FALSE;
|
||||
|
||||
if(!oh->IsValid())
|
||||
return ADE_RETURN_FALSE;
|
||||
|
||||
weapon *wp = &Weapons[oh->objp->instance];
|
||||
|
||||
if(weapon_armed(wp, hit_target))
|
||||
return ADE_RETURN_TRUE;
|
||||
|
||||
return ADE_RETURN_FALSE;
|
||||
}
|
||||
|
||||
//**********HANDLE: Beam
|
||||
ade_obj<object_h> l_Beam("beam", "Beam handle", &l_Object);
|
||||
|
||||
ADE_VIRTVAR(Class, l_Beam, "weaponclass", "Weapon's class", "weaponclass", "Weapon class, or invalid weaponclass handle if beam handle is invalid")
|
||||
{
|
||||
object_h *oh=NULL;
|
||||
int nc=-1;
|
||||
if(!ade_get_args(L, "o|o", l_Beam.GetPtr(&oh), l_Weaponclass.Get(&nc)))
|
||||
return ade_set_error(L, "o", l_Weaponclass.Set(-1));
|
||||
|
||||
if(!oh->IsValid())
|
||||
return ade_set_error(L, "o", l_Weaponclass.Set(-1));
|
||||
|
||||
beam *bp = &Beams[oh->objp->instance];
|
||||
|
||||
if(ADE_SETTING_VAR && nc > -1) {
|
||||
bp->weapon_info_index = nc;
|
||||
}
|
||||
|
||||
return ade_set_args(L, "o", l_Weaponclass.Set(bp->weapon_info_index));
|
||||
}
|
||||
|
||||
ADE_VIRTVAR(LastShot, l_Beam, "vector", "End point of the beam", "vector", "vector or null vector if beam handle is not valid")
|
||||
{
|
||||
object_h *oh=NULL;
|
||||
vec3d *vec3;
|
||||
if(!ade_get_args(L, "o|o", l_Beam.GetPtr(&oh), l_Vector.GetPtr(&vec3)))
|
||||
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
|
||||
|
||||
if(!oh->IsValid())
|
||||
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
|
||||
|
||||
beam *bp = &Beams[oh->objp->instance];
|
||||
|
||||
if(ADE_SETTING_VAR) {
|
||||
bp->last_shot = *vec3;
|
||||
}
|
||||
|
||||
return ade_set_args(L, "o", l_Vector.Set(bp->last_shot));
|
||||
}
|
||||
|
||||
ADE_VIRTVAR(LastStart, l_Beam, "vector", "Start point of the beam", "vector", "vector or null vector if beam handle is not valid")
|
||||
{
|
||||
object_h *oh=NULL;
|
||||
vec3d *v3;
|
||||
if(!ade_get_args(L, "o|o", l_Beam.GetPtr(&oh), l_Vector.GetPtr(&v3)))
|
||||
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
|
||||
|
||||
if(!oh->IsValid())
|
||||
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
|
||||
|
||||
beam *bp = &Beams[oh->objp->instance];
|
||||
|
||||
if(ADE_SETTING_VAR) {
|
||||
bp->last_start = *v3;
|
||||
}
|
||||
|
||||
return ade_set_args(L, "o", l_Vector.Set(bp->last_start));
|
||||
}
|
||||
|
||||
ADE_VIRTVAR(Target, l_Beam, "object", "Target of beam. Value may also be a deriviative of the 'object' class, such as 'ship'.", "object", "Beam target, or invalid object handle if beam handle is invalid")
|
||||
{
|
||||
object_h *objh;
|
||||
object_h *newh;
|
||||
if(!ade_get_args(L, "o|o", l_Beam.GetPtr(&objh), l_Object.GetPtr(&newh)))
|
||||
return ade_set_error(L, "o", l_Object.Set(object_h()));
|
||||
|
||||
if(!objh->IsValid())
|
||||
return ade_set_error(L, "o", l_Object.Set(object_h()));
|
||||
|
||||
beam *bp = NULL;
|
||||
if(objh->objp->instance > -1)
|
||||
bp = &Beams[objh->objp->instance];
|
||||
else
|
||||
return ade_set_error(L, "o", l_Object.Set(object_h()));
|
||||
|
||||
if(ADE_SETTING_VAR)
|
||||
{
|
||||
if(newh != NULL && newh->IsValid())
|
||||
{
|
||||
if(bp->target_sig != newh->sig)
|
||||
{
|
||||
bp->target = newh->objp;
|
||||
bp->target_sig = newh->sig;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bp->target = NULL;
|
||||
bp->target_sig = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ade_set_object_with_breed(L, OBJ_INDEX(bp->target));
|
||||
}
|
||||
|
||||
ADE_VIRTVAR(TargetSubsystem, l_Beam, "subsystem", "Subsystem that beam is targeting.", "subsystem", "Target subsystem, or invalid subsystem handle if beam handle is invalid")
|
||||
{
|
||||
object_h *objh;
|
||||
ship_subsys_h *newh;
|
||||
if(!ade_get_args(L, "o|o", l_Beam.GetPtr(&objh), l_Subsystem.GetPtr(&newh)))
|
||||
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
||||
|
||||
if(!objh->IsValid())
|
||||
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
||||
|
||||
beam *bp = NULL;
|
||||
if(objh->objp->instance > -1)
|
||||
bp = &Beams[objh->objp->instance];
|
||||
else
|
||||
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
||||
|
||||
if(ADE_SETTING_VAR)
|
||||
{
|
||||
if(newh != NULL && newh->IsValid())
|
||||
{
|
||||
if(bp->target_sig != newh->sig)
|
||||
{
|
||||
bp->target = newh->objp;
|
||||
bp->target_subsys = newh->ss;
|
||||
bp->target_sig = newh->sig;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bp->target = NULL;
|
||||
bp->target_subsys = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return ade_set_args(L, "o", l_Subsystem.Set(ship_subsys_h(bp->target, bp->target_subsys)));
|
||||
}
|
||||
|
||||
ADE_VIRTVAR(ParentShip, l_Beam, "object", "Parent of the beam.", "object", "Beam parent, or invalid object handle if beam handle is invalid")
|
||||
{
|
||||
object_h *objh;
|
||||
object_h *newh;
|
||||
if(!ade_get_args(L, "o|o", l_Beam.GetPtr(&objh), l_Object.GetPtr(&newh)))
|
||||
return ade_set_error(L, "o", l_Object.Set(object_h()));
|
||||
|
||||
if(!objh->IsValid())
|
||||
return ade_set_error(L, "o", l_Object.Set(object_h()));
|
||||
|
||||
beam *bp = NULL;
|
||||
if(objh->objp->instance > -1)
|
||||
bp = &Beams[objh->objp->instance];
|
||||
else
|
||||
return ade_set_error(L, "o", l_Object.Set(object_h()));
|
||||
|
||||
if(ADE_SETTING_VAR)
|
||||
{
|
||||
if(newh != NULL && newh->IsValid())
|
||||
{
|
||||
if(bp->sig != newh->sig)
|
||||
{
|
||||
bp->objp = newh->objp;
|
||||
bp->sig = newh->sig;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bp->objp = NULL;
|
||||
bp->sig = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ade_set_object_with_breed(L, OBJ_INDEX(bp->objp));
|
||||
}
|
||||
|
||||
ADE_VIRTVAR(ParentSubsystem, l_Beam, "subsystem", "Subsystem that beam is fired from.", "subsystem", "Parent subsystem, or invalid subsystem handle if beam handle is invalid")
|
||||
{
|
||||
object_h *objh;
|
||||
ship_subsys_h *newh;
|
||||
if(!ade_get_args(L, "o|o", l_Beam.GetPtr(&objh), l_Subsystem.GetPtr(&newh)))
|
||||
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
||||
|
||||
if(!objh->IsValid())
|
||||
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
||||
|
||||
beam *bp = NULL;
|
||||
if(objh->objp->instance > -1)
|
||||
bp = &Beams[objh->objp->instance];
|
||||
else
|
||||
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
||||
|
||||
if(ADE_SETTING_VAR)
|
||||
{
|
||||
if(newh != NULL && newh->IsValid())
|
||||
{
|
||||
if(bp->sig != newh->sig)
|
||||
{
|
||||
bp->objp = newh->objp;
|
||||
bp->subsys = newh->ss;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bp->objp = NULL;
|
||||
bp->subsys = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return ade_set_args(L, "o", l_Subsystem.Set(ship_subsys_h(bp->objp, bp->subsys)));
|
||||
}
|
||||
|
||||
ADE_FUNC(getCollisionCount, l_Beam, NULL, "Get the number of collisions in frame.", "number", "Number of beam collisions")
|
||||
{
|
||||
object_h *objh;
|
||||
if(!ade_get_args(L, "o", l_Beam.GetPtr(&objh)))
|
||||
return ADE_RETURN_NIL;
|
||||
|
||||
beam *bp = NULL;
|
||||
if(objh->objp->instance > -1)
|
||||
bp = &Beams[objh->objp->instance];
|
||||
else
|
||||
return ADE_RETURN_NIL;
|
||||
|
||||
return ade_set_args(L, "i", bp->f_collision_count);
|
||||
}
|
||||
|
||||
ADE_FUNC(getCollisionPosition, l_Beam, "number", "Get the position of the defined collision.", "vector", "World vector")
|
||||
{
|
||||
object_h *objh;
|
||||
int idx;
|
||||
if(!ade_get_args(L, "oi", l_Beam.GetPtr(&objh), &idx))
|
||||
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
|
||||
|
||||
// convert from Lua to C
|
||||
idx--;
|
||||
if ((idx >= 10) || (idx < 0))
|
||||
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
|
||||
|
||||
beam *bp = NULL;
|
||||
if(objh->objp->instance > -1)
|
||||
bp = &Beams[objh->objp->instance];
|
||||
else
|
||||
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
|
||||
|
||||
// so we have valid beam and valid indexer
|
||||
return ade_set_args(L, "o", l_Vector.Set(bp->f_collisions[idx].cinfo.hit_point_world));
|
||||
}
|
||||
|
||||
ADE_FUNC(getCollisionObject, l_Beam, "number", "Get the target of the defined collision.", "object", "Object the beam collided with")
|
||||
{
|
||||
object_h *objh;
|
||||
int idx;
|
||||
if(!ade_get_args(L, "oi", l_Beam.GetPtr(&objh), &idx))
|
||||
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
|
||||
|
||||
// convert from Lua to C
|
||||
idx--;
|
||||
if ((idx >= 10) || (idx < 0))
|
||||
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
|
||||
|
||||
beam *bp = NULL;
|
||||
if(objh->objp->instance > -1)
|
||||
bp = &Beams[objh->objp->instance];
|
||||
else
|
||||
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
|
||||
|
||||
// so we have valid beam and valid indexer
|
||||
return ade_set_object_with_breed(L, bp->f_collisions[idx].c_objnum);
|
||||
}
|
||||
|
||||
ADE_FUNC(isExitCollision, l_Beam, "number", "Checks if the defined collision was exit collision.", "boolean", "True if the collision was exit collision, false if entry, nil otherwise")
|
||||
{
|
||||
object_h *objh;
|
||||
int idx;
|
||||
if(!ade_get_args(L, "oi", l_Beam.GetPtr(&objh), &idx))
|
||||
return ADE_RETURN_NIL;
|
||||
|
||||
// convert from Lua to C
|
||||
idx--;
|
||||
if ((idx >= 10) || (idx < 0))
|
||||
return ADE_RETURN_NIL;
|
||||
|
||||
beam *bp = NULL;
|
||||
if(objh->objp->instance > -1)
|
||||
bp = &Beams[objh->objp->instance];
|
||||
else
|
||||
return ADE_RETURN_NIL;
|
||||
|
||||
// so we have valid beam and valid indexer
|
||||
if (bp->f_collisions[idx].is_exit_collision)
|
||||
return ADE_RETURN_TRUE;
|
||||
|
||||
return ADE_RETURN_FALSE;
|
||||
}
|
||||
|
||||
//**********HANDLE: Wing
|
||||
ade_obj<int> l_Wing("wing", "Wing handle");
|
||||
@@ -7809,7 +8149,7 @@ ADE_FUNC(playGameSound, l_Audio, "Sound index, [Panning (-1.0 left to 1.0 right)
|
||||
if(vol > 100.0f)
|
||||
vol = 100.0f;
|
||||
|
||||
idx = snd_play(&Snds[idx], pan, vol*0.01f, pri, voice_msg);
|
||||
idx = snd_play(&Snds[gamesnd_get_by_tbl_index(idx)], pan, vol*0.01f, pri, voice_msg);
|
||||
|
||||
return ade_set_args(L, "b", idx > -1);
|
||||
}
|
||||
@@ -7820,7 +8160,7 @@ ADE_FUNC(playInterfaceSound, l_Audio, "Sound index", "Plays a sound from #Interf
|
||||
if(!ade_get_args(L, "i", &idx))
|
||||
return ade_set_error(L, "b", false);
|
||||
|
||||
gamesnd_play_iface(idx);
|
||||
gamesnd_play_iface(gamesnd_get_by_iface_tbl_index(idx));
|
||||
|
||||
return ade_set_args(L, "b", idx > -1);
|
||||
}
|
||||
@@ -10252,6 +10592,37 @@ ADE_FUNC(__len, l_Mission_Weapons, NULL, "Number of weapon objects in mission. N
|
||||
return ade_set_args(L, "i", Num_weapons);
|
||||
}
|
||||
|
||||
//****SUBLIBRARY: Mission/Beams
|
||||
ade_lib l_Mission_Beams("Beams", &l_Mission, NULL, NULL);
|
||||
|
||||
ADE_INDEXER(l_Mission_Beams, "number Index", "Gets handle to a beam object in the mission.", "beam", "Beam handle, or invalid beam handle if index is invalid")
|
||||
{
|
||||
int idx;
|
||||
if(!ade_get_args(L, "*i", &idx))
|
||||
return ade_set_error(L, "o", l_Beam.Set(object_h()));
|
||||
|
||||
//Remember, Lua indices start at 0.
|
||||
int count=1;
|
||||
|
||||
for(int i = 0; i < MAX_BEAMS; i++)
|
||||
{
|
||||
if (Beams[i].weapon_info_index < 0 || Beams[i].objnum < 0 || Objects[Beams[i].objnum].type != OBJ_BEAM)
|
||||
continue;
|
||||
|
||||
if(count == idx) {
|
||||
return ade_set_args(L, "o", l_Beam.Set(object_h(&Objects[Beams[i].objnum])));
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return ade_set_error(L, "o", l_Beam.Set(object_h()));
|
||||
}
|
||||
ADE_FUNC(__len, l_Mission_Beams, NULL, "Number of beam objects in mission. Note that this is only accurate for one frame.", "number", "Number of beam objects in mission")
|
||||
{
|
||||
return ade_set_args(L, "i", Beam_count);
|
||||
}
|
||||
|
||||
//****SUBLIBRARY: Mission/Wings
|
||||
ade_lib l_Mission_Wings("Wings", &l_Mission, NULL, NULL);
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ flag_def_list Script_actions[] =
|
||||
{"On Warp Out", CHA_WARPOUT, 0},
|
||||
{"On Death", CHA_DEATH, 0},
|
||||
{"On Mission End", CHA_MISSIONEND, 0},
|
||||
{"On Weapon Delete", CHA_ONWEAPONDELETE, 0},
|
||||
};
|
||||
|
||||
int Num_script_actions = sizeof(Script_actions)/sizeof(flag_def_list);
|
||||
|
||||
@@ -60,6 +60,7 @@ struct image_desc
|
||||
#define CHA_KEYRELEASED 18
|
||||
#define CHA_ONSTATESTART 19
|
||||
#define CHA_ONSTATEEND 20
|
||||
#define CHA_ONWEAPONDELETE 21
|
||||
|
||||
|
||||
struct script_condition
|
||||
|
||||
+581
-242
File diff suppressed because it is too large.
Load diff
+27
-6
@@ -13,6 +13,7 @@
|
||||
#define _SEXP_H
|
||||
|
||||
struct ship_subsys;
|
||||
struct ship;
|
||||
|
||||
// bumped to 30 by Goober5000
|
||||
#define OPERATOR_LENGTH 30 // if this ever exceeds TOKEN_LENGTH, let JasonH know!
|
||||
@@ -112,6 +113,7 @@ struct ship_subsys;
|
||||
#define OPF_POST_EFFECT 67 // Hery - type of post-processing effect
|
||||
#define OPF_TARGET_PRIORITIES 68 // FUBAR - Target priority groups
|
||||
#define OPF_ARMOR_TYPES 69 // FUBAR - Armor type or <none>
|
||||
#define OPF_HUD_ELEMENT 71 // A magic name of a specific HUD element
|
||||
|
||||
// Operand return types
|
||||
#define OPR_NUMBER 1 // returns number
|
||||
@@ -267,7 +269,7 @@ struct ship_subsys;
|
||||
|
||||
#define OP_SHIELDS_LEFT (0x0000 | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG)
|
||||
#define OP_HITS_LEFT (0x0001 | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG)
|
||||
#define OP_HITS_LEFT_SUBSYSTEM (0x0002 | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG)
|
||||
#define OP_HITS_LEFT_SUBSYSTEM (0x0002 | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG) // deprecated
|
||||
#define OP_SIM_HITS_LEFT (0x0003 | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG)
|
||||
#define OP_DISTANCE (0x0004 | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG)
|
||||
#define OP_DISTANCE_SUBSYSTEM (0x0005 | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG) // Goober5000
|
||||
@@ -492,7 +494,7 @@ struct ship_subsys;
|
||||
#define OP_CUTSCENES_SET_FOV (0x0085 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC
|
||||
#define OP_CUTSCENES_RESET_FOV (0x0086 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC
|
||||
#define OP_CUTSCENES_RESET_CAMERA (0x0087 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC
|
||||
#define OP_CUTSCENES_SHOW_SUBTITLE (0x0088 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC
|
||||
#define OP_CUTSCENES_SHOW_SUBTITLE (0x0088 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC / deprecated
|
||||
#define OP_CUTSCENES_SET_TIME_COMPRESSION (0x0089 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC
|
||||
#define OP_CUTSCENES_RESET_TIME_COMPRESSION (0x008a | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC
|
||||
#define OP_CUTSCENES_FORCE_PERSPECTIVE (0x008b | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC
|
||||
@@ -567,9 +569,14 @@ struct ship_subsys;
|
||||
#define OP_SET_VARIABLE_BY_INDEX (0x00cd | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Goober5000
|
||||
#define OP_SET_POST_EFFECT (0x00ce | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Hery
|
||||
#define OP_TURRET_SET_OPTIMUM_RANGE (0x00cf | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // FUBAR
|
||||
|
||||
#define OP_TURRET_SET_DIRECTION_PREFERENCE (0x00d0 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // FUBAR
|
||||
#define OP_TURRET_SET_TARGET_PRIORITIES (0x00d1 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // FUBAR
|
||||
#define OP_SET_ARMOR_TYPE (0x00d2 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // FUBAR
|
||||
#define OP_CUTSCENES_SHOW_SUBTITLE_TEXT (0x00d3 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Goober5000
|
||||
#define OP_CUTSCENES_SHOW_SUBTITLE_IMAGE (0x00d4 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Goober5000
|
||||
#define OP_MISSION_SET_SUBSPACE (0x00d5 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG)
|
||||
#define OP_HUD_DISPLAY_GAUGE (0x00d6 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG)
|
||||
|
||||
/* made obsolete by Goober5000
|
||||
// debugging sexpressions
|
||||
@@ -735,8 +742,10 @@ char *CTEXT(int n);
|
||||
#define SEXP_VARIABLE_NOT_USED (1<<7) // (0x0080)
|
||||
|
||||
#define SEXP_VARIABLE_BLOCK (1<<0) // (0x0001)
|
||||
/*
|
||||
#define SEXP_VARIABLE_BLOCK_EXP (1<<1) // (0x0002)
|
||||
#define SEXP_VARIABLE_BLOCK_HIT (1<<2) // (0x0004)
|
||||
*/
|
||||
#define SEXP_VARIABLE_PLAYER_PERSISTENT (1<<3) // (0x0008)
|
||||
|
||||
// Goober5000 - hopefully this should work and not conflict with anything
|
||||
@@ -832,6 +841,7 @@ char *CTEXT(int n);
|
||||
#define SEXP_CHECK_INVALID_PERSONA_NAME -139
|
||||
#define SEXP_CHECK_INVALID_VARIABLE_TYPE -140
|
||||
#define SEXP_CHECK_INVALID_SUBSYS_TYPE -141
|
||||
#define SEXP_CHECK_INVALID_HUD_ELEMENT -143
|
||||
|
||||
#define TRAINING_CONTEXT_SPEED (1<<0)
|
||||
#define TRAINING_CONTEXT_FLY_PATH (1<<1)
|
||||
@@ -900,6 +910,7 @@ extern int Num_sexp_nodes;
|
||||
extern sexp_node *Sexp_nodes;
|
||||
|
||||
extern sexp_variable Sexp_variables[MAX_SEXP_VARIABLES];
|
||||
extern sexp_variable Block_variables[MAX_SEXP_VARIABLES];
|
||||
|
||||
extern sexp_oper Operators[];
|
||||
extern int Num_operators;
|
||||
@@ -988,10 +999,9 @@ void sexp_variable_delete(int index);
|
||||
void sexp_variable_sort();
|
||||
void sexp_fred_modify_variable(const char *text, const char *var_name, int index, int type);
|
||||
int sexp_add_variable(const char *text, const char *var_name, int type, int index=-1);
|
||||
int sexp_variable_allocate_block(const char* block_name, int block_type);
|
||||
void sexp_variable_condense_block();
|
||||
void sexp_variable_block_free(const char *ship_name, int start_index, int block_type);
|
||||
|
||||
bool generate_special_explosion_block_variables();
|
||||
int num_block_variables();
|
||||
bool has_special_explosion_block_index(ship *shipp, int *index);
|
||||
|
||||
// Karajorma
|
||||
void set_primary_ammo (int ship_index, int requested_bank, int requested_ammo, int rearm_limit=-1, bool update=true);
|
||||
@@ -1034,4 +1044,15 @@ bool output_sexps(char *filepath);
|
||||
|
||||
void multi_sexp_eval();
|
||||
|
||||
/** Global state variables for the hud-display-gauge sexp.
|
||||
They all should be named Sexp_hud_display_*;
|
||||
They all should follow the following symantics for the value of the
|
||||
variable:
|
||||
=0 don't show
|
||||
=1 show until canceled
|
||||
>1 timestamp when gauge should stop showing (set zero when expired)
|
||||
\sa sexp_hud_display_warpout
|
||||
*/
|
||||
extern int Sexp_hud_display_warpout;
|
||||
|
||||
#endif
|
||||
+20
-27
@@ -263,7 +263,11 @@ void particle_move_all(float frametime)
|
||||
return;
|
||||
|
||||
for (SCP_vector<particle>::iterator p = Particles.begin(); p != Particles.end(); ) {
|
||||
p->age += frametime;
|
||||
if (p->age == 0.0f) {
|
||||
p->age = 0.00001f;
|
||||
} else {
|
||||
p->age += frametime;
|
||||
}
|
||||
|
||||
// if it's time expired, remove it
|
||||
if (p->age > p->max_life) {
|
||||
@@ -356,12 +360,21 @@ void particle_render_all()
|
||||
|
||||
for (SCP_vector<particle>::iterator p = Particles.begin(); p != Particles.end(); ++p) {
|
||||
// skip back-facing particles (ripped from fullneb code)
|
||||
if ( vm_vec_dot_to_point(&Eye_matrix.vec.fvec, &Eye_position, &p->pos) <= 0.0f ) {
|
||||
// Wanderer - add support for attached particles
|
||||
vec3d p_pos;
|
||||
if (p->attached_objnum >= 0) {
|
||||
vm_vec_unrotate(&p_pos, &p->pos, &Objects[p->attached_objnum].orient);
|
||||
vm_vec_add2(&p_pos, &Objects[p->attached_objnum].pos);
|
||||
} else {
|
||||
p_pos = p->pos;
|
||||
}
|
||||
|
||||
if ( vm_vec_dot_to_point(&Eye_matrix.vec.fvec, &Eye_position, &p_pos) <= 0.0f ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// calculate the alpha to draw at
|
||||
alpha = get_current_alpha(&p->pos);
|
||||
alpha = get_current_alpha(&p_pos);
|
||||
|
||||
// if it's transparent then just skip it
|
||||
if (alpha <= 0.0f) {
|
||||
@@ -373,7 +386,7 @@ void particle_render_all()
|
||||
|
||||
// if this is a tracer style particle, calculate tracer vectors
|
||||
if (p->tracer_length > 0.0f) {
|
||||
ts = p->pos;
|
||||
ts = p_pos;
|
||||
temp = p->velocity;
|
||||
vm_vec_normalize_quick(&temp);
|
||||
vm_vec_scale_add(&te, &ts, &temp, p->tracer_length);
|
||||
@@ -381,37 +394,17 @@ void particle_render_all()
|
||||
// don't bother rotating
|
||||
rotate = 0;
|
||||
}
|
||||
// if this is an "attached" particle. move it
|
||||
else if (p->attached_objnum >= 0) {
|
||||
// offset the vector, and transform to view coords
|
||||
// vm_vec_add(&te, &Objects[p->attached_objnum].pos, &p->pos);
|
||||
|
||||
vm_vec_unrotate(&temp, &p->pos, &Objects[p->attached_objnum].orient);
|
||||
vm_vec_add2(&temp, &Objects[p->attached_objnum].pos);
|
||||
|
||||
flags = g3_rotate_vertex(&pos, &temp);
|
||||
|
||||
if (flags) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Cmdline_nohtl)
|
||||
g3_transfer_vertex(&pos, &temp);
|
||||
|
||||
// don't bother rotating again
|
||||
rotate = 0;
|
||||
}
|
||||
|
||||
// rotate the vertex
|
||||
if (rotate) {
|
||||
flags = g3_rotate_vertex( &pos, &p->pos );
|
||||
flags = g3_rotate_vertex( &pos, &p_pos );
|
||||
|
||||
if ( flags ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Cmdline_nohtl)
|
||||
g3_transfer_vertex(&pos, &p->pos);
|
||||
g3_transfer_vertex(&pos, &p_pos);
|
||||
}
|
||||
|
||||
// pct complete for the particle
|
||||
@@ -429,7 +422,7 @@ void particle_render_all()
|
||||
|
||||
if (p->type == PARTICLE_DEBUG) {
|
||||
gr_set_color( 255, 0, 0 );
|
||||
g3_draw_sphere_ez( &p->pos, p->radius );
|
||||
g3_draw_sphere_ez( &p_pos, p->radius );
|
||||
} else {
|
||||
framenum = p->optional_data;
|
||||
|
||||
|
||||
+17
-13
@@ -687,7 +687,20 @@ void physics_read_flying_controls( matrix * orient, physics_info * pi, control_i
|
||||
if ( pi->flags & PF_REDUCED_DAMP ) {
|
||||
ramp_time_const *= reduced_damp_ramp_time_expansion;
|
||||
}
|
||||
pi->prev_ramp_vel.xyz.z = velocity_ramp( pi->prev_ramp_vel.xyz.z, goal_vel.xyz.z, ramp_time_const, sim_time);
|
||||
pi->prev_ramp_vel.xyz.z = velocity_ramp(pi->prev_ramp_vel.xyz.z, goal_vel.xyz.z, ramp_time_const, sim_time);
|
||||
|
||||
//Deternine the current dynamic glide cap, and ramp to it
|
||||
//This is outside the normal "glide" block since we want the cap to adjust whether or not the ship is in glide mode
|
||||
float dynamic_glide_cap_goal = 0.0;
|
||||
if (pi->flags & PF_AFTERBURNER_ON) {
|
||||
dynamic_glide_cap_goal = ( goal_vel.xyz.z >= 0.0f ) ? pi->afterburner_max_vel.xyz.z : pi->afterburner_max_reverse_vel;
|
||||
}
|
||||
else {
|
||||
//Use the maximum value in X, Y, and Z (including overclocking)
|
||||
dynamic_glide_cap_goal = MAX(MAX(pi->max_vel.xyz.x,pi->max_vel.xyz.y), pi->max_vel.xyz.z);
|
||||
}
|
||||
pi->cur_glide_cap = velocity_ramp(pi->cur_glide_cap, dynamic_glide_cap_goal, ramp_time_const, sim_time);
|
||||
|
||||
|
||||
if ( pi->flags & PF_GLIDING ) {
|
||||
pi->desired_vel = pi->vel;
|
||||
@@ -699,19 +712,10 @@ void physics_read_flying_controls( matrix * orient, physics_info * pi, control_i
|
||||
|
||||
//Having pi->glide_cap == 0 means we're using a dynamic glide cap
|
||||
float curGlideCap = 0.0f;
|
||||
if (pi->glide_cap == 0.0f) {
|
||||
//For dynamic glide capping, normal flight and afterburner have separate glide caps
|
||||
if (pi->flags & PF_AFTERBURNER_ON) {
|
||||
curGlideCap = pi->afterburner_max_vel.xyz.z;
|
||||
}
|
||||
else {
|
||||
//Take the maximum value in X, Y, and Z (including overclocking)
|
||||
curGlideCap = MAX(MAX(pi->max_vel.xyz.x,pi->max_vel.xyz.y), pi->max_vel.xyz.z);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (pi->glide_cap == 0.0f)
|
||||
curGlideCap = pi->cur_glide_cap;
|
||||
else
|
||||
curGlideCap = pi->glide_cap;
|
||||
}
|
||||
|
||||
//If we're near the (positive) glide cap, decay velocity where we aren't thrusting
|
||||
//This is a hack, but makes the flight feel a lot smoother
|
||||
|
||||
@@ -85,8 +85,8 @@ typedef struct physics_info {
|
||||
int shockwave_decay; // timestamp used to control how long ship affected after hit by shockwave
|
||||
int reduced_damp_decay; // timestamp used to control how long ship ship has reduced damp physics
|
||||
|
||||
vec3d glide_saved_vel; //WMC - the key variable for gliding. Saves the orientation that velocity will be applied on.
|
||||
float glide_cap; //Backslash - for 'newtonian'-style gliding, the cap on velocity (so that something can't accelerate to ridiculous speeds... unless allowed to)
|
||||
float cur_glide_cap; //SUSHI: Used for dynamic glide cap, so we can use the ramping function on the glide cap
|
||||
float glide_accel_mult; //SUSHI: The acceleration multiplier for glide mode. A value < 0 means use glide ramping instead
|
||||
bool use_newtonian_damp; //SUSHI: Whether or not to use newtonian dampening
|
||||
float afterburner_max_reverse_vel; //SparK: This is the reverse afterburners top speed vector
|
||||
|
||||
Loaded 100 of 170 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user