mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 18:31:26 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b53bde255 | ||
|
|
a4ac216d7a | ||
|
|
189275da56 | ||
|
|
4c7d80cba8 | ||
|
|
4a14e26256 | ||
|
|
0fc8e53f5f | ||
|
|
ba2a1c9e7d | ||
|
|
115a2979b1 | ||
|
|
e9b9797b6e | ||
|
|
da0ef89ac5 | ||
|
|
fe49ef63aa | ||
|
|
f51bc78126 | ||
|
|
711c7a7bf8 | ||
|
|
ca16b4710d | ||
|
|
471cf4c988 | ||
|
|
d734a36940 | ||
|
|
25079f5ed2 | ||
|
|
f0a0632d9d | ||
|
|
3528dffabd | ||
|
|
2aa569c1e7 | ||
|
|
584ec36f62 | ||
|
|
93c46bd1f9 | ||
|
|
b6cc62c435 | ||
|
|
00a288d53e | ||
|
|
4bfea90a17 | ||
|
|
aef3e3ac36 | ||
|
|
a7398d7f5c | ||
|
|
e2d740513a | ||
|
|
1a29b395ab | ||
|
|
b2e01d6173 | ||
|
|
bc17966b08 | ||
|
|
be9990f6a5 | ||
|
|
c5bddac8fb | ||
|
|
3de25b7e3a | ||
|
|
2768863c36 | ||
|
|
7b78df2363 | ||
|
|
d84736be1c | ||
|
|
1591237acf | ||
|
|
05b4635048 | ||
|
|
eef1041323 | ||
|
|
18058a45f7 | ||
|
|
fbb76863fd | ||
|
|
400fd0f9a8 | ||
|
|
b18337754d | ||
|
|
92a28b71cb | ||
|
|
0656175a72 | ||
|
|
dc820fdfc1 | ||
|
|
5042c44904 | ||
|
|
91000b4468 | ||
|
|
91614162f2 | ||
|
|
4b15ec4e75 | ||
|
|
e84a6e8d33 | ||
|
|
763601033b | ||
|
|
0ff8c8191f | ||
|
|
b0bb0ee3be | ||
|
|
ad91ba61b5 | ||
|
|
7dea7075e7 | ||
|
|
9ec10dd3e6 | ||
|
|
83b59fb76c | ||
|
|
e3715cc420 | ||
|
|
366f4d5642 | ||
|
|
547d615552 | ||
|
|
4f074d94d1 | ||
|
|
a4ac843d5b | ||
|
|
359a98410a | ||
|
|
1acfc1c326 |
No files matched your search
@@ -462,6 +462,15 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
set_flag(profile, "$strict turret-tagged-only targeting:", AIPF2_STRICT_TURRET_TAGGED_ONLY_TARGETING, AIP_FLAG2);
|
||||
|
||||
profile->bay_arrive_speed_mult = 1.0f;
|
||||
profile->bay_depart_speed_mult = 1.0f;
|
||||
if (optional_string("$bay arrive start speed multiplier:")) {
|
||||
stuff_float(&profile->bay_arrive_speed_mult);
|
||||
}
|
||||
if (optional_string("$bay depart end speed multiplier:")) {
|
||||
stuff_float(&profile->bay_depart_speed_mult);
|
||||
}
|
||||
|
||||
// ----------
|
||||
|
||||
// compatibility
|
||||
|
||||
@@ -151,6 +151,11 @@ typedef struct ai_profile_t {
|
||||
|
||||
int ai_path_mode;
|
||||
|
||||
// Ships flying bay paths will gradually accelerate/decelerate instead of
|
||||
// flying the whole path at max speed
|
||||
float bay_arrive_speed_mult;
|
||||
float bay_depart_speed_mult;
|
||||
|
||||
} ai_profile_t;
|
||||
|
||||
|
||||
|
||||
+48
-2
@@ -4011,11 +4011,57 @@ float ai_path_1()
|
||||
dot_to_next = vm_vec_dot_to_point(&nvel_vec, &Pl_objp->pos, &gnvp);
|
||||
|
||||
// This path mode respects the "cap-waypoint-speed" SEXP
|
||||
float max_allowed_speed = 0;
|
||||
float max_allowed_speed = 0.0f;
|
||||
if ( aip->waypoint_speed_cap > 0) {
|
||||
max_allowed_speed = (float) aip->waypoint_speed_cap;
|
||||
}
|
||||
|
||||
// Maybe gradually ramp up/down the speed of a ship flying a fighterbay path
|
||||
if (aip->mode == AIM_BAY_EMERGE || (aip->mode == AIM_BAY_DEPART && aip->path_cur != aip->path_start)) {
|
||||
SCP_string pathName(pm->paths[Path_points[aip->path_start].path_num].name);
|
||||
ship_info *gsip = &Ship_info[gshipp->ship_info_index];
|
||||
float speed_mult = 1.0f;
|
||||
|
||||
if (aip->mode == AIM_BAY_EMERGE) { // Arriving
|
||||
if (gsip->pathMetadata.find(pathName) != gsip->pathMetadata.end()) {
|
||||
speed_mult = gsip->pathMetadata[pathName].arrive_speed_mult;
|
||||
}
|
||||
|
||||
if (speed_mult == FLT_MIN) {
|
||||
speed_mult = The_mission.ai_profile->bay_arrive_speed_mult;
|
||||
}
|
||||
} else { // Departing
|
||||
if (gsip->pathMetadata.find(pathName) != gsip->pathMetadata.end()) {
|
||||
speed_mult = gsip->pathMetadata[pathName].depart_speed_mult;
|
||||
}
|
||||
|
||||
if (speed_mult == FLT_MIN) {
|
||||
speed_mult = The_mission.ai_profile->bay_depart_speed_mult;
|
||||
}
|
||||
}
|
||||
|
||||
if (speed_mult != 1.0f) {
|
||||
// We use the distance between the first and last point on the path here; it's not accurate
|
||||
// if the path is not straight, but should be good enough usually; can be changed if necessary.
|
||||
float total_path_length = vm_vec_dist_quick(&Path_points[aip->path_start].pos, &Path_points[aip->path_start + num_points - 1].pos);
|
||||
float dist_to_end;
|
||||
|
||||
if (aip->mode == AIM_BAY_EMERGE) { // Arriving
|
||||
dist_to_end = vm_vec_dist_quick(&Pl_objp->pos, &Path_points[aip->path_start].pos);
|
||||
} else { // Departing
|
||||
dist_to_end = vm_vec_dist_quick(&Pl_objp->pos, &Path_points[aip->path_start + num_points - 1].pos);
|
||||
}
|
||||
|
||||
// Calculate max speed, but respect the waypoint speed cap if it's lower
|
||||
float max_bay_speed = sip->max_speed * (speed_mult + (1.0f - speed_mult) * (dist_to_end / total_path_length));
|
||||
if (max_allowed_speed == 0.0f) {
|
||||
max_allowed_speed = max_bay_speed;
|
||||
} else {
|
||||
max_allowed_speed = MIN(max_allowed_speed, max_bay_speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_accel_for_docking(Pl_objp, aip, dot, dot_to_next, dist_to_next, dist_to_goal, sip, max_allowed_speed);
|
||||
aip->prev_dot_to_goal = dot;
|
||||
|
||||
@@ -7583,7 +7629,7 @@ void update_aspect_lock_information(ai_info *aip, vec3d *vec_to_enemy, float dis
|
||||
|
||||
wip = &Weapon_info[swp->secondary_bank_weapons[swp->current_secondary_bank]];
|
||||
|
||||
if (num_weapon_types && (wip->wi_flags & WIF_LOCKED_HOMING)) {
|
||||
if (num_weapon_types && (wip->wi_flags & WIF_LOCKED_HOMING) && !(shipp->flags2 & SF2_NO_SECONDARY_LOCKON)) {
|
||||
if (dist_to_enemy > 300.0f - MIN(enemy_radius, 100.0f))
|
||||
aip->ai_flags |= AIF_SEEK_LOCK;
|
||||
else
|
||||
|
||||
+3
-2
@@ -171,7 +171,7 @@ void ai_post_process_mission()
|
||||
// Goober5000 - MK originally iterated on only the first wing; now we iterate on only the player wing
|
||||
// because the player wing may not be first
|
||||
for ( i = 0; i < MAX_STARTING_WINGS; i++ ) {
|
||||
if ( Starting_wings[i] == Player_ship->wingnum ) {
|
||||
if (Starting_wings[i] >= 0 && Starting_wings[i] == Player_ship->wingnum) {
|
||||
wing *wingp;
|
||||
|
||||
wingp = &Wings[Starting_wings[i]];
|
||||
@@ -528,7 +528,7 @@ int ai_goal_find_dockpoint(int shipnum, int dock_type)
|
||||
}
|
||||
|
||||
// function to fix up dock point references for objects.
|
||||
// passed are the pointer to goal we are working with. aip if the ai_info pointer
|
||||
// passed are the pointer to goal we are working with. aip is the ai_info pointer
|
||||
// of the ship with the order. aigp is a pointer to the goal (of aip) of which we are
|
||||
// fixing up the docking points
|
||||
void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
|
||||
@@ -537,6 +537,7 @@ void ai_goal_fixup_dockpoints(ai_info *aip, ai_goal *aigp)
|
||||
|
||||
Assert ( aip->shipnum != -1 );
|
||||
shipnum = ship_name_lookup( aigp->target_name );
|
||||
Assertion ( shipnum != -1, "Couldn't find ai goal's target_name (%s); get a coder!\n", aigp->target_name );
|
||||
docker_index = -1;
|
||||
dockee_index = -1;
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ union bm_extra_info {
|
||||
// stuff for static animations
|
||||
ubyte type; //!< type for individual images
|
||||
char filename[MAX_FILENAME_LEN]; //!< filename for individual images
|
||||
bool in_subdir; // Whether frames are in their own subdirectory
|
||||
} eff;
|
||||
} ani;
|
||||
|
||||
|
||||
+100
-6
@@ -34,6 +34,7 @@
|
||||
#include "pngutils/pngutils.h"
|
||||
#include "ship/ship.h"
|
||||
#include "tgautils/tgautils.h"
|
||||
#include "cfile/cfilesystem.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
@@ -48,7 +49,20 @@
|
||||
/**
|
||||
* @todo upgrade this to an inline funciton, taking bitmap_entry and const char* as arguments
|
||||
*/
|
||||
#define EFF_FILENAME_CHECK { if ( be->type == BM_TYPE_EFF ) strcpy_s( filename, be->info.ani.eff.filename ); else strcpy_s( filename, be->filename ); }
|
||||
#define EFF_FILENAME_CHECK \
|
||||
{ \
|
||||
if ( be->type == BM_TYPE_EFF ) { \
|
||||
strcpy_s( filename, be->info.ani.eff.filename ); \
|
||||
if (be->info.ani.eff.in_subdir) { \
|
||||
if (!set_temp_subdir_pathtype(bm_bitmaps[be->info.ani.first_frame].filename)) { \
|
||||
mprintf(("BMPMAN: Failed to set temporary pathtype for %s: EFF_FILENAME_CHECK failed!\n", be->filename)); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
strcpy_s( filename, be->filename ); \
|
||||
} \
|
||||
}
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// Monitor variables
|
||||
MONITOR(NumBitmapPage)
|
||||
@@ -78,6 +92,8 @@ const int BM_ANI_NUM_TYPES = sizeof(bm_ani_type_list) / sizeof(ubyte);
|
||||
void(*bm_set_components)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a) = NULL;
|
||||
void(*bm_set_components_32)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a) = NULL;
|
||||
|
||||
extern cf_pathtype Pathtypes[CF_MAX_PATH_TYPES];
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// Declaration of protected variables (defined in cmdline.cpp).
|
||||
extern int Cmdline_cache_bitmaps;
|
||||
@@ -1026,8 +1042,9 @@ int bm_load(const SCP_string& filename) {
|
||||
return bm_load(filename.c_str());
|
||||
}
|
||||
|
||||
int bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int *nfps, int *key, ubyte *type) {
|
||||
int bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int *nfps, int *key, ubyte *type, bool *in_subdir) {
|
||||
int frames = 0, fps = 30, keyframe = 0;
|
||||
bool subdir = false;
|
||||
char ext[8];
|
||||
ubyte c_type = BM_TYPE_NONE;
|
||||
char file_text[1024];
|
||||
@@ -1065,6 +1082,10 @@ int bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (optional_string( "$Subdir:" )) {
|
||||
stuff_boolean(&subdir);}
|
||||
|
||||
|
||||
// done with EFF so unpause parsing so whatever can continue
|
||||
unpause_parse();
|
||||
|
||||
@@ -1101,6 +1122,8 @@ int bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int
|
||||
if (key)
|
||||
*key = keyframe;
|
||||
|
||||
*in_subdir = subdir;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1111,6 +1134,7 @@ int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *ke
|
||||
char filename[MAX_FILENAME_LEN];
|
||||
int reduced = 0;
|
||||
int anim_fps = 0, anim_frames = 0, key = 0;
|
||||
bool in_subdir = false;
|
||||
int anim_width = 0, anim_height = 0;
|
||||
ubyte type = BM_TYPE_NONE, eff_type = BM_TYPE_NONE, c_type = BM_TYPE_NONE;
|
||||
int bpp = 0, mm_lvl = 0, img_size = 0;
|
||||
@@ -1197,7 +1221,7 @@ int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *ke
|
||||
|
||||
// it's an effect file, any readable image type with eff being txt
|
||||
if (type == BM_TYPE_EFF) {
|
||||
if (bm_load_and_parse_eff(filename, dir_type, &anim_frames, &anim_fps, &key, &eff_type) != 0) {
|
||||
if (bm_load_and_parse_eff(filename, dir_type, &anim_frames, &anim_fps, &key, &eff_type, &in_subdir) != 0 ) {
|
||||
mprintf(("BMPMAN: Error reading EFF\n"));
|
||||
return -1;
|
||||
} else {
|
||||
@@ -1259,6 +1283,10 @@ int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *ke
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (in_subdir) {
|
||||
set_temp_subdir_pathtype(filename);
|
||||
}
|
||||
|
||||
int first_handle = bm_get_next_handle();
|
||||
|
||||
Assert(strlen(filename) < MAX_FILENAME_LEN);
|
||||
@@ -1324,6 +1352,11 @@ int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *ke
|
||||
bm_bitmaps[n + i].num_mipmaps = mm_lvl;
|
||||
bm_bitmaps[n + i].mem_taken = img_size;
|
||||
bm_bitmaps[n + i].dir_type = dir_type;
|
||||
bm_bitmaps[n + i].info.ani.eff.in_subdir = in_subdir;
|
||||
if (in_subdir)
|
||||
bm_bitmaps[n + i].dir_type = CF_TYPE_TEMP_SUBDIR_LOOKUP;
|
||||
else
|
||||
bm_bitmaps[n + i].dir_type = dir_type;
|
||||
|
||||
bm_bitmaps[n + i].load_count++;
|
||||
|
||||
@@ -1497,8 +1530,8 @@ bitmap * bm_lock(int handle, ubyte bpp, ubyte flags, bool nodebug) {
|
||||
// read the file data
|
||||
if (gr_bm_lock(be->filename, handle, bitmapnum, bpp, flags, nodebug) == -1) {
|
||||
// oops, this isn't good - reset and return NULL
|
||||
bm_unlock(bitmapnum);
|
||||
bm_unload(bitmapnum);
|
||||
bm_unlock( handle );
|
||||
bm_unload( handle );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -2067,6 +2100,61 @@ void bm_page_in_start() {
|
||||
gr_bm_page_in_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stuffs Pathtypes with an additional path leading to a subdir of the same name as the given file (minus file extension).
|
||||
* Used for allowing frames of .eff animations to be found in their own subdirectories.
|
||||
*
|
||||
* Example: if called with "debris.eff" and that file is in data/maps, then Pathtypes[CF_TYPE_TEMP_SUBDIR_LOOKUP].path
|
||||
* will be stuffed with data/maps/debris, allowing data/maps/debris/debris_0000.dds (etc) to be found
|
||||
*/
|
||||
bool set_temp_subdir_pathtype(const char *filename) {
|
||||
// Gets the absolute path of the file, removes the part that is identical with the
|
||||
// absolute root path and appends the filename to it (without extension), giving us
|
||||
// a relative path that can be temporarily stuffed into Pathtypes so the frames can be found
|
||||
|
||||
char fullpath[MAX_PATH]; // Absolute path to the given file
|
||||
char fullrootpath[MAX_PATH]; // Absolute root path
|
||||
int size, offset; // Needed for cf_find_file_location, but not used
|
||||
|
||||
cf_create_default_path_string(fullrootpath, sizeof(fullrootpath) - 1, CF_TYPE_ROOT, NULL);
|
||||
if (!cf_find_file_location(filename, CF_TYPE_ANY, sizeof(fullpath)-1, fullpath, &size, &offset)) {
|
||||
mprintf(("BMPMAN: Failed to set temporary pathtype for %s: file not found!\n", filename));
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (strlen(fullpath) < strlen(fullrootpath)) {
|
||||
mprintf(("BMPMAN: Path to %s was shorter than the root path, programmer thought it could never happen!\n%s\n%s\n", filename, fullpath, fullrootpath));
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
mprintf(("BMPMAN: Setting temporary pathtype for %s... ", filename));
|
||||
|
||||
char *trimmed_path; // The differing portion of fullpath and fullrootpath
|
||||
trimmed_path = &fullpath[strlen(fullrootpath)];
|
||||
|
||||
char *extpos = strstr(trimmed_path, "."); // Where the file extension begins
|
||||
char basepath[MAX_PATH]; // This will hold the final, relative path
|
||||
|
||||
// Copy the relative path of the given file to basepath, excluding the extension
|
||||
strncpy(basepath, trimmed_path, extpos-trimmed_path);
|
||||
|
||||
// Make sure it's null-terminated right
|
||||
basepath[(int)(extpos-trimmed_path)] = '\0';
|
||||
|
||||
// Free the old string first, if it's not the const initial empty string
|
||||
if (Pathtypes[CF_TYPE_TEMP_SUBDIR_LOOKUP].path[0] != '\0') {
|
||||
vm_free(Pathtypes[CF_TYPE_TEMP_SUBDIR_LOOKUP].path);
|
||||
}
|
||||
|
||||
Pathtypes[CF_TYPE_TEMP_SUBDIR_LOOKUP].path = vm_strdup(basepath);
|
||||
|
||||
mprintf(("OK. Temporary pathtype is now %s.\n", Pathtypes[CF_TYPE_TEMP_SUBDIR_LOOKUP].path));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void bm_page_in_stop() {
|
||||
int i;
|
||||
|
||||
@@ -2085,13 +2173,19 @@ void bm_page_in_stop() {
|
||||
if ((bm_bitmaps[i].type != BM_TYPE_NONE) && (bm_bitmaps[i].type != BM_TYPE_RENDER_TARGET_DYNAMIC) && (bm_bitmaps[i].type != BM_TYPE_RENDER_TARGET_STATIC)) {
|
||||
if (bm_bitmaps[i].preloaded) {
|
||||
if (bm_preloading) {
|
||||
if (bm_bitmaps[i].type == BM_TYPE_EFF && bm_bitmaps[i].info.ani.eff.in_subdir) {
|
||||
set_temp_subdir_pathtype(bm_bitmaps[i].filename);
|
||||
}
|
||||
|
||||
if (!gr_preload(bm_bitmaps[i].handle, (bm_bitmaps[i].preloaded == 2))) {
|
||||
mprintf(("Out of VRAM. Done preloading.\n"));
|
||||
bm_preloading = 0;
|
||||
}
|
||||
} else {
|
||||
bm_lock(bm_bitmaps[i].handle, (bm_bitmaps[i].used_flags == BMP_AABITMAP) ? 8 : 16, bm_bitmaps[i].used_flags);
|
||||
bm_unlock(bm_bitmaps[i].handle);
|
||||
if (bm_bitmaps[i].ref_count >= 1) {
|
||||
bm_unlock( bm_bitmaps[i].handle );
|
||||
}
|
||||
}
|
||||
|
||||
n++;
|
||||
|
||||
+11
-5
@@ -415,6 +415,11 @@ void bm_get_frame_usage(int *ntotal, int *nnew);
|
||||
*/
|
||||
int bm_reload(int bitmap_handle, const char* filename);
|
||||
|
||||
/**
|
||||
* @brief Stuffs Pathtypes with an additional path leading to a subdir of the same name as the given file (minus file extension)
|
||||
*/
|
||||
bool set_temp_subdir_pathtype(const char *filename);
|
||||
|
||||
/**
|
||||
* @brief Tells bmpman to start keeping track of what bitmaps are used where
|
||||
*/
|
||||
@@ -622,16 +627,17 @@ int bm_set_render_target(int handle, int face = -1);
|
||||
*
|
||||
* @param[in] filename The filename of the .EFF
|
||||
* @param[in] dir_type
|
||||
* @param[out] nframes (optional) If given, is set to the number of frames this .EFF has
|
||||
* @param[out] nfps (optional) If given, is set to the fps of this .EFF
|
||||
* @param[out] key (optional) If given, is set to the keyframe index of this .EFF
|
||||
* @param[out] type (optional) If given, is set to the BM_TYPE of the .EFF
|
||||
* @param[out] nframes (optional) If given, is set to the number of frames this .EFF has
|
||||
* @param[out] nfps (optional) If given, is set to the fps of this .EFF
|
||||
* @param[out] key (optional) If given, is set to the keyframe index of this .EFF
|
||||
* @param[out] type (optional) If given, is set to the BM_TYPE of the .EFF
|
||||
* @param[out] in_subdir (optional) If given, is set to true if the frames of this .EFF are in a subdir
|
||||
*
|
||||
* @returns 0 If successful,
|
||||
* @returns -1 if not successful
|
||||
*
|
||||
* @todo retval should be a bool
|
||||
*/
|
||||
int bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int *nfps, int *key, ubyte *type);
|
||||
int bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int *nfps, int *key, ubyte *type, bool *in_subdir);
|
||||
|
||||
#endif
|
||||
@@ -540,8 +540,15 @@ 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, const char* in_text, const char* in_imageanim, float in_display_time, float in_fade_time, const color *in_text_color, int in_text_fontnum, bool center_x, bool center_y, int in_width, int in_height, bool in_post_shaded)
|
||||
subtitle::subtitle(int in_x_pos, int in_y_pos, const char* in_text, const char* in_imageanim, float in_display_time,
|
||||
float in_fade_time, const color *in_text_color, int in_text_fontnum, bool center_x, bool center_y, int in_width,
|
||||
int in_height, bool in_post_shaded)
|
||||
:display_time(-1.0f), fade_time(-1.0f), text_fontnum(-1), time_displayed(-1.0f), time_displayed_end(-1.0f),
|
||||
post_shaded(false)
|
||||
{
|
||||
// Initialize color
|
||||
gr_init_color(&text_color, 0, 0, 0);
|
||||
|
||||
SCP_string text_buf;
|
||||
|
||||
// basic init, this always has to be done
|
||||
|
||||
@@ -86,6 +86,7 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
|
||||
{ CF_TYPE_INTEL_ANIMS, "data" DIR_SEPARATOR_STR "intelanims", ".pcx .ani .eff .tga .jpg .png .dds", CF_TYPE_DATA },
|
||||
{ CF_TYPE_SCRIPTS, "data" DIR_SEPARATOR_STR "scripts", ".lua .lc", CF_TYPE_DATA },
|
||||
{ CF_TYPE_FICTION, "data" DIR_SEPARATOR_STR "fiction", ".txt", CF_TYPE_DATA },
|
||||
{ CF_TYPE_TEMP_SUBDIR_LOOKUP, "", ".eff", CF_TYPE_DATA },
|
||||
};
|
||||
|
||||
|
||||
@@ -501,7 +502,7 @@ int cf_exists(const char *filename, int dir_type)
|
||||
if ( (filename == NULL) || !strlen(filename) )
|
||||
return 0;
|
||||
|
||||
return (cf_find_file_location(filename, dir_type, 0, NULL, &offset, NULL) && !offset);
|
||||
return (cf_find_file_location(filename, dir_type, 0, NULL, NULL, &offset) && !offset);
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
|
||||
+2
-1
@@ -78,8 +78,9 @@ typedef struct {
|
||||
#define CF_TYPE_INTEL_ANIMS 34
|
||||
#define CF_TYPE_SCRIPTS 35
|
||||
#define CF_TYPE_FICTION 36
|
||||
#define CF_TYPE_TEMP_SUBDIR_LOOKUP 37
|
||||
|
||||
#define CF_MAX_PATH_TYPES 37 // Can be as high as you'd like //DTP; yeah but beware alot of things uses CF_MAX_PATH_TYPES
|
||||
#define CF_MAX_PATH_TYPES 38 // Can be as high as you'd like //DTP; yeah but beware alot of things uses CF_MAX_PATH_TYPES
|
||||
|
||||
|
||||
// TRUE if type is specified and valid
|
||||
|
||||
@@ -901,6 +901,7 @@ int cf_find_file_location( const char *filespec, int pathtype, int max_out, char
|
||||
case CF_TYPE_MULTI_CACHE:
|
||||
case CF_TYPE_MISSIONS:
|
||||
case CF_TYPE_CACHE:
|
||||
case CF_TYPE_TEMP_SUBDIR_LOOKUP:
|
||||
cfs_slow_search = 1;
|
||||
break;
|
||||
|
||||
|
||||
@@ -956,9 +956,9 @@ void control_config_reset_defaults(int presetnum)
|
||||
|
||||
// Reset keyboard defaults
|
||||
for (i=0; i<CCFG_MAX; i++) {
|
||||
// Note that key_default and joy_default are NOT overwritten here;
|
||||
// they should retain the values of the first preset because
|
||||
// for example the key-pressed SEXP works off the defaults of the first preset
|
||||
// Note that key_default, joy_default and text_default are NOT
|
||||
// overwritten here; they should retain the values of the first preset
|
||||
Control_config[i].text = preset[i].text;
|
||||
Control_config[i].key_id = preset[i].key_default;
|
||||
Control_config[i].joy_id = preset[i].joy_default;
|
||||
Control_config[i].tab = preset[i].tab;
|
||||
@@ -2107,6 +2107,45 @@ void control_config_do_frame(float frametime)
|
||||
List_buttons[i++].disable();
|
||||
}
|
||||
|
||||
// If multiple controls presets are provided, display which one is in use
|
||||
if (Control_config_presets.size() > 1) {
|
||||
SCP_string preset_str;
|
||||
int matching_preset = -1;
|
||||
|
||||
for (i=0; i<(int)Control_config_presets.size(); i++) {
|
||||
bool this_preset_matches = true;
|
||||
config_item *this_preset = Control_config_presets[i];
|
||||
|
||||
for (int j=0; j<CCFG_MAX; j++) {
|
||||
if (!Control_config[j].disabled && Control_config[j].key_id != this_preset[j].key_default) {
|
||||
this_preset_matches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (this_preset_matches) {
|
||||
matching_preset = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (matching_preset >= 0) {
|
||||
sprintf(preset_str, "Controls: %s", Control_config_preset_names[matching_preset].c_str());
|
||||
} else {
|
||||
sprintf(preset_str, "Controls: custom");
|
||||
|
||||
}
|
||||
|
||||
gr_get_string_size(&w, NULL, preset_str.c_str());
|
||||
gr_set_color_fast(&Color_text_normal);
|
||||
|
||||
if (gr_screen.res == GR_640) {
|
||||
gr_string(16, (24 - font_height) / 2, preset_str.c_str(), GR_RESIZE_MENU);
|
||||
} else {
|
||||
gr_string(24, (40 - font_height) / 2, preset_str.c_str(), GR_RESIZE_MENU);
|
||||
}
|
||||
}
|
||||
|
||||
// blit help overlay if active
|
||||
help_overlay_maybe_blit(Control_config_overlay_id, gr_screen.res);
|
||||
|
||||
@@ -2207,11 +2246,11 @@ int check_control_used(int id, int key)
|
||||
|
||||
// check what current modifiers are pressed
|
||||
mask = 0;
|
||||
if (keyd_pressed[KEY_LSHIFT] || key_down_count(KEY_LSHIFT) || keyd_pressed[KEY_RSHIFT] || key_down_count(KEY_RSHIFT)) {
|
||||
if (keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT]) {
|
||||
mask |= KEY_SHIFTED;
|
||||
}
|
||||
|
||||
if (keyd_pressed[KEY_LALT] || key_down_count(KEY_LALT) || keyd_pressed[KEY_RALT] || key_down_count(KEY_RALT)) {
|
||||
if (keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT]) {
|
||||
mask |= KEY_ALTED;
|
||||
}
|
||||
|
||||
@@ -2226,7 +2265,7 @@ int check_control_used(int id, int key)
|
||||
|
||||
z &= KEY_MASK;
|
||||
|
||||
if (keyd_pressed[z] || key_down_count(z)) {
|
||||
if (keyd_pressed[z]) {
|
||||
control_used(id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -63,13 +63,14 @@ typedef struct config_item {
|
||||
short joy_default; //!< default joystick button bound to action
|
||||
char tab; //!< what tab (category) it belongs in
|
||||
bool hasXSTR; //!< whether we should translate this with an XSTR
|
||||
char *text; //!< describes the action in the config screen
|
||||
char *default_text; //!< default description of the action
|
||||
char type; //!< manner control should be checked in
|
||||
short key_id; //!< actual key bound to action
|
||||
short joy_id; //!< joystick button bound to action
|
||||
int used; //!< has control been used yet in mission? If so, this is the timestamp
|
||||
bool disabled; //!< whether this action should be available at all
|
||||
bool continuous_ongoing;//!< whether this action is a continuous one and is currently ongoing
|
||||
char *text; //!< overridable description of the action
|
||||
} config_item;
|
||||
|
||||
/*!
|
||||
@@ -292,6 +293,7 @@ extern int Control_config_overlay_id;
|
||||
|
||||
extern config_item Control_config[]; //!< Stores the keyboard configuration
|
||||
extern SCP_vector<config_item*> Control_config_presets; // tabled control presets; pointers to config_item arrays
|
||||
extern SCP_vector<SCP_string> Control_config_preset_names; // names for Control_config_presets (identical order of items)
|
||||
extern char **Scan_code_text;
|
||||
extern char **Joy_button_text;
|
||||
|
||||
|
||||
@@ -45,153 +45,153 @@ int Invert_axis_defaults[JOY_NUM_AXES] = { 0, 0, 0, 0, 0, 0 };
|
||||
//XSTR:OFF
|
||||
config_item Control_config[CCFG_MAX + 1] = {
|
||||
// targeting a ship
|
||||
{ KEY_T, -1, TARGET_TAB, true, "Target Next Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_T, -1, TARGET_TAB, true, "Target Previous Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_H, 2, TARGET_TAB, true, "Target Next Closest Hostile Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_H, -1, TARGET_TAB, true, "Target Previous Closest Hostile Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_ALTED | KEY_H, -1, TARGET_TAB, true, "Toggle Auto Targeting", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_F, -1, TARGET_TAB, true, "Target Next Closest Friendly Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_F, -1, TARGET_TAB, true, "Target Previous Closest Friendly Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_Y, 4, TARGET_TAB, true, "Target Ship in Reticle", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_G, -1, TARGET_TAB, true, "Target Target's Nearest Attacker", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_ALTED | KEY_Y, -1, TARGET_TAB, true, "Target Last Ship to Send Transmission", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_ALTED | KEY_T, -1, TARGET_TAB, true, "Turn Off Targeting", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_T, -1, TARGET_TAB, true, "Target Next Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_T, -1, TARGET_TAB, true, "Target Previous Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_H, 2, TARGET_TAB, true, "Target Next Closest Hostile Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_H, -1, TARGET_TAB, true, "Target Previous Closest Hostile Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_ALTED | KEY_H, -1, TARGET_TAB, true, "Toggle Auto Targeting", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_F, -1, TARGET_TAB, true, "Target Next Closest Friendly Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_F, -1, TARGET_TAB, true, "Target Previous Closest Friendly Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_Y, 4, TARGET_TAB, true, "Target Ship in Reticle", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_G, -1, TARGET_TAB, true, "Target Target's Nearest Attacker", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_ALTED | KEY_Y, -1, TARGET_TAB, true, "Target Last Ship to Send Transmission", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_ALTED | KEY_T, -1, TARGET_TAB, true, "Turn Off Targeting", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
|
||||
// targeting a ship's subsystem
|
||||
{ KEY_V, -1, TARGET_TAB, true, "Target Subsystem in Reticle", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_S, -1, TARGET_TAB, true, "Target Next Subsystem", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_S, -1, TARGET_TAB, true, "Target Previous Subsystem", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_ALTED | KEY_S, -1, TARGET_TAB, true, "Turn Off Targeting of Subsystems", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_V, -1, TARGET_TAB, true, "Target Subsystem in Reticle", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_S, -1, TARGET_TAB, true, "Target Next Subsystem", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_S, -1, TARGET_TAB, true, "Target Previous Subsystem", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_ALTED | KEY_S, -1, TARGET_TAB, true, "Turn Off Targeting of Subsystems", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
|
||||
// matching speed
|
||||
{ KEY_M, -1, COMPUTER_TAB, true, "Match Target Speed", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_ALTED | KEY_M, -1, COMPUTER_TAB, true, "Toggle Auto Speed Matching", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_M, -1, COMPUTER_TAB, true, "Match Target Speed", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_ALTED | KEY_M, -1, COMPUTER_TAB, true, "Toggle Auto Speed Matching", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
|
||||
// weapons
|
||||
{ KEY_LCTRL, 0, WEAPON_TAB, true, "Fire Primary Weapon", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_SPACEBAR, 1, WEAPON_TAB, true, "Fire Secondary Weapon", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_PERIOD, -1, WEAPON_TAB, true, "Cycle Forward Primary Weapon", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_COMMA, -1, WEAPON_TAB, true, "Cycle Backward Primary Weapon", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_DIVIDE, -1, WEAPON_TAB, true, "Cycle Secondary Weapon Bank", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_DIVIDE, -1, WEAPON_TAB, true, "Cycle Secondary Weapon Firing Rate", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_X, 3, WEAPON_TAB, true, "Launch Countermeasure", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_LCTRL, 0, WEAPON_TAB, true, "Fire Primary Weapon", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SPACEBAR, 1, WEAPON_TAB, true, "Fire Secondary Weapon", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_PERIOD, -1, WEAPON_TAB, true, "Cycle Forward Primary Weapon", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_COMMA, -1, WEAPON_TAB, true, "Cycle Backward Primary Weapon", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_DIVIDE, -1, WEAPON_TAB, true, "Cycle Secondary Weapon Bank", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_DIVIDE, -1, WEAPON_TAB, true, "Cycle Secondary Weapon Firing Rate", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_X, 3, WEAPON_TAB, true, "Launch Countermeasure", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
|
||||
// controls
|
||||
{ KEY_A, -1, SHIP_TAB, true, "Forward Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_Z, -1, SHIP_TAB, true, "Reverse Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_PAD7, -1, SHIP_TAB, true, "Bank Left", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_PAD9, -1, SHIP_TAB, true, "Bank Right", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_PAD8, -1, SHIP_TAB, true, "Pitch Forward", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_PAD2, -1, SHIP_TAB, true, "Pitch Backward", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_PAD4, -1, SHIP_TAB, true, "Turn Left", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_PAD6, -1, SHIP_TAB, true, "Turn Right", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_A, -1, SHIP_TAB, true, "Forward Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_Z, -1, SHIP_TAB, true, "Reverse Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_PAD7, -1, SHIP_TAB, true, "Bank Left", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_PAD9, -1, SHIP_TAB, true, "Bank Right", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_PAD8, -1, SHIP_TAB, true, "Pitch Forward", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_PAD2, -1, SHIP_TAB, true, "Pitch Backward", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_PAD4, -1, SHIP_TAB, true, "Turn Left", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_PAD6, -1, SHIP_TAB, true, "Turn Right", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
|
||||
// throttle controls
|
||||
{ KEY_BACKSP, -1, SHIP_TAB, true, "Set Throttle to Zero", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SLASH, -1, SHIP_TAB, true, "Set Throttle to Max", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_LBRACKET, -1, SHIP_TAB, true, "Set Throttle to One-Third", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_RBRACKET, -1, SHIP_TAB, true, "Set Throttle to Two-Thirds", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_EQUAL, -1, SHIP_TAB, true, "Increase Throttle 5 Percent", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_MINUS, -1, SHIP_TAB, true, "Decrease Throttle 5 Percent", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_BACKSP, -1, SHIP_TAB, true, "Set Throttle to Zero", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SLASH, -1, SHIP_TAB, true, "Set Throttle to Max", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_LBRACKET, -1, SHIP_TAB, true, "Set Throttle to One-Third", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_RBRACKET, -1, SHIP_TAB, true, "Set Throttle to Two-Thirds", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_EQUAL, -1, SHIP_TAB, true, "Increase Throttle 5 Percent", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_MINUS, -1, SHIP_TAB, true, "Decrease Throttle 5 Percent", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
|
||||
// squadmate messaging
|
||||
{ KEY_SHIFTED | KEY_A, -1, COMPUTER_TAB, true, "Attack My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_Z, -1, COMPUTER_TAB, true, "Disarm My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_D, -1, COMPUTER_TAB, true, "Disable My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_V, -1, COMPUTER_TAB, true, "Attack My Subsystem", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_X, -1, COMPUTER_TAB, true, "Capture My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, true, "Engage Enemy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_W, -1, COMPUTER_TAB, true, "Form on My Wing", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_I, -1, COMPUTER_TAB, true, "Ignore My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_P, -1, COMPUTER_TAB, true, "Protect My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_C, -1, COMPUTER_TAB, true, "Cover Me", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_J, -1, COMPUTER_TAB, true, "Return to Base", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_R, -1, COMPUTER_TAB, true, "Rearm Me", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_A, -1, COMPUTER_TAB, true, "Attack My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_Z, -1, COMPUTER_TAB, true, "Disarm My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_D, -1, COMPUTER_TAB, true, "Disable My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_V, -1, COMPUTER_TAB, true, "Attack My Subsystem", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_X, -1, COMPUTER_TAB, true, "Capture My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, true, "Engage Enemy", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_W, -1, COMPUTER_TAB, true, "Form on My Wing", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_I, -1, COMPUTER_TAB, true, "Ignore My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_P, -1, COMPUTER_TAB, true, "Protect My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_C, -1, COMPUTER_TAB, true, "Cover Me", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_J, -1, COMPUTER_TAB, true, "Return to Base", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_R, -1, COMPUTER_TAB, true, "Rearm Me", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
|
||||
{ KEY_R, 6, TARGET_TAB, true, "Target Closest Attacking Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_R, 6, TARGET_TAB, true, "Target Closest Attacking Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
|
||||
// Views
|
||||
{ KEY_PADMULTIPLY, -1, COMPUTER_TAB, true, "Chase View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_PADPERIOD, -1, COMPUTER_TAB, true, "External View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_PADENTER, -1, COMPUTER_TAB, true, "Toggle External Camera Lock", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_PAD0, -1, COMPUTER_TAB, true, "Free Look View", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false }, // Not in use anymore (Swifty)
|
||||
{ KEY_PADDIVIDE, -1, COMPUTER_TAB, true, "Current Target View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_PADPLUS, -1, COMPUTER_TAB, true, "Increase View Distance", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_PADMINUS, -1, COMPUTER_TAB, true, "Decrease View Distance", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_PAD5, -1, COMPUTER_TAB, true, "Center View", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ -1, 33, COMPUTER_TAB, true, "View Up", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ -1, 32, COMPUTER_TAB, true, "View Rear", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ -1, 34, COMPUTER_TAB, true, "View Left", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ -1, 35, COMPUTER_TAB, true, "View Right", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_PADMULTIPLY, -1, COMPUTER_TAB, true, "Chase View", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_PADPERIOD, -1, COMPUTER_TAB, true, "External View", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_PADENTER, -1, COMPUTER_TAB, true, "Toggle External Camera Lock", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_PAD0, -1, COMPUTER_TAB, true, "Free Look View", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL }, // Not in use anymore (Swifty)
|
||||
{ KEY_PADDIVIDE, -1, COMPUTER_TAB, true, "Current Target View", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_PADPLUS, -1, COMPUTER_TAB, true, "Increase View Distance", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_PADMINUS, -1, COMPUTER_TAB, true, "Decrease View Distance", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_PAD5, -1, COMPUTER_TAB, true, "Center View", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ -1, 33, COMPUTER_TAB, true, "View Up", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ -1, 32, COMPUTER_TAB, true, "View Rear", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ -1, 34, COMPUTER_TAB, true, "View Left", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ -1, 35, COMPUTER_TAB, true, "View Right", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
|
||||
{ KEY_RAPOSTRO, -1, COMPUTER_TAB, true, "Cycle Radar Range", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_C, -1, COMPUTER_TAB, true, "Communications Menu", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ -1, -1, -1, true, "Show Objectives", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_ALTED | KEY_J, -1, COMPUTER_TAB, true, "Enter Subspace (End Mission)", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_J, -1, TARGET_TAB, true, "Target Target's Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_TAB, 5, SHIP_TAB, true, "Afterburner", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_RAPOSTRO, -1, COMPUTER_TAB, true, "Cycle Radar Range", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_C, -1, COMPUTER_TAB, true, "Communications Menu", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ -1, -1, -1, true, "Show Objectives", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_ALTED | KEY_J, -1, COMPUTER_TAB, true, "Enter Subspace (End Mission)", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_J, -1, TARGET_TAB, true, "Target Target's Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_TAB, 5, SHIP_TAB, true, "Afterburner", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
|
||||
{ KEY_INSERT, -1, COMPUTER_TAB, true, "Increase Weapon Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_DELETE, -1, COMPUTER_TAB, true, "Decrease Weapon Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_HOME, -1, COMPUTER_TAB, true, "Increase Shield Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_END, -1, COMPUTER_TAB, true, "Decrease Shield Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_PAGEUP, -1, COMPUTER_TAB, true, "Increase Engine Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_PAGEDOWN, -1, COMPUTER_TAB, true, "Decrease Engine Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_ALTED | KEY_D, -1, COMPUTER_TAB, true, "Equalize Energy Settings", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_INSERT, -1, COMPUTER_TAB, true, "Increase Weapon Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_DELETE, -1, COMPUTER_TAB, true, "Decrease Weapon Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_HOME, -1, COMPUTER_TAB, true, "Increase Shield Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_END, -1, COMPUTER_TAB, true, "Decrease Shield Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_PAGEUP, -1, COMPUTER_TAB, true, "Increase Engine Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_PAGEDOWN, -1, COMPUTER_TAB, true, "Decrease Engine Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_ALTED | KEY_D, -1, COMPUTER_TAB, true, "Equalize Energy Settings", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
|
||||
{ KEY_Q, 7, COMPUTER_TAB, true, "Equalize Shields", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_UP, -1, COMPUTER_TAB, true, "Augment Forward Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_DOWN, -1, COMPUTER_TAB, true, "Augment Rear Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_LEFT, -1, COMPUTER_TAB, true, "Augment Left Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_RIGHT, -1, COMPUTER_TAB, true, "Augment Right Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SCROLLOCK, -1, COMPUTER_TAB, true, "Transfer Energy Laser->Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_SCROLLOCK, -1, COMPUTER_TAB, true, "Transfer Energy Shield->Laser", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_Q, 7, COMPUTER_TAB, true, "Equalize Shields", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_UP, -1, COMPUTER_TAB, true, "Augment Forward Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_DOWN, -1, COMPUTER_TAB, true, "Augment Rear Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_LEFT, -1, COMPUTER_TAB, true, "Augment Left Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_RIGHT, -1, COMPUTER_TAB, true, "Augment Right Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SCROLLOCK, -1, COMPUTER_TAB, true, "Transfer Energy Laser->Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_SCROLLOCK, -1, COMPUTER_TAB, true, "Transfer Energy Shield->Laser", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
// { -1, -1, -1, true, "Show Damage Popup Window" },
|
||||
|
||||
{ -1, -1, SHIP_TAB, false, "Glide When Pressed", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ -1, -1, SHIP_TAB, false, "Glide When Pressed", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
//Backslash -- this was a convenient place for Glide When Pressed, as Show Damage Popup isn't used
|
||||
{ -1, -1, SHIP_TAB, true, "Bank When Pressed", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ -1, -1, -1, true, "Show Nav Map", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_ALTED | KEY_E, -1, COMPUTER_TAB, true, "Add or Remove Escort", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_ALTED | KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, true, "Clear Escort List", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_E, -1, TARGET_TAB, true, "Target Next Escort Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_ALTED | KEY_R, -1, TARGET_TAB, true, "Target Closest Repair Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ -1, -1, SHIP_TAB, true, "Bank When Pressed", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ -1, -1, -1, true, "Show Nav Map", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_ALTED | KEY_E, -1, COMPUTER_TAB, true, "Add or Remove Escort", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_ALTED | KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, true, "Clear Escort List", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_E, -1, TARGET_TAB, true, "Target Next Escort Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_ALTED | KEY_R, -1, TARGET_TAB, true, "Target Closest Repair Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
|
||||
{ KEY_U, -1, TARGET_TAB, true, "Target Next Uninspected Cargo", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_U, -1, TARGET_TAB, true, "Target Previous Uninspected Cargo", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_N, -1, TARGET_TAB, true, "Target Newest Ship in Area", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_K, -1, TARGET_TAB, true, "Target Next Live Turret", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_K, -1, TARGET_TAB, true, "Target Previous Live Turret", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_U, -1, TARGET_TAB, true, "Target Next Uninspected Cargo", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_U, -1, TARGET_TAB, true, "Target Previous Uninspected Cargo", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_N, -1, TARGET_TAB, true, "Target Newest Ship in Area", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_K, -1, TARGET_TAB, true, "Target Next Live Turret", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_K, -1, TARGET_TAB, true, "Target Previous Live Turret", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
|
||||
{ KEY_B, -1, TARGET_TAB, true, "Target Next Hostile Bomb or Bomber", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_B, -1, TARGET_TAB, true, "Target Previous Hostile Bomb or Bomber", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_B, -1, TARGET_TAB, true, "Target Next Hostile Bomb or Bomber", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_B, -1, TARGET_TAB, true, "Target Previous Hostile Bomb or Bomber", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
|
||||
// multiplayer messaging keys
|
||||
{ KEY_1, -1, COMPUTER_TAB, true, "(Multiplayer) Message All", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_2, -1, COMPUTER_TAB, true, "(Multiplayer) Message Friendly", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_3, -1, COMPUTER_TAB, true, "(Multiplayer) Message Hostile", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_4, -1, COMPUTER_TAB, true, "(Multiplayer) Message Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_ALTED | KEY_X, -1, COMPUTER_TAB, true, "(Multiplayer) Observer Zoom to Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_PERIOD, -1, COMPUTER_TAB, true, "Increase Time Compression", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_COMMA, -1, COMPUTER_TAB, true, "Decrease Time Compression", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_L, -1, COMPUTER_TAB, true, "Toggle High HUD Contrast", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_N, -1, COMPUTER_TAB, true, "(Multiplayer) Toggle Network Info", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_END, -1, COMPUTER_TAB, true, "(Multiplayer) Self Destruct", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_1, -1, COMPUTER_TAB, true, "(Multiplayer) Message All", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_2, -1, COMPUTER_TAB, true, "(Multiplayer) Message Friendly", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_3, -1, COMPUTER_TAB, true, "(Multiplayer) Message Hostile", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_4, -1, COMPUTER_TAB, true, "(Multiplayer) Message Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_ALTED | KEY_X, -1, COMPUTER_TAB, true, "(Multiplayer) Observer Zoom to Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_PERIOD, -1, COMPUTER_TAB, true, "Increase Time Compression", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_COMMA, -1, COMPUTER_TAB, true, "Decrease Time Compression", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_L, -1, COMPUTER_TAB, true, "Toggle High HUD Contrast", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_N, -1, COMPUTER_TAB, true, "(Multiplayer) Toggle Network Info", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_END, -1, COMPUTER_TAB, true, "(Multiplayer) Self Destruct", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
|
||||
// Misc
|
||||
{ KEY_SHIFTED | KEY_O, -1, COMPUTER_TAB, true, "Toggle HUD", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_3, -1, SHIP_TAB, true, "Right Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_1, -1, SHIP_TAB, true, "Left Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_PADPLUS, -1, SHIP_TAB, true, "Up Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_SHIFTED | KEY_PADENTER, -1, SHIP_TAB, true, "Down Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
|
||||
{ KEY_ALTED | KEY_SHIFTED | KEY_Q, -1, COMPUTER_TAB, true, "Toggle HUD Wireframe Target View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ -1, -1, COMPUTER_TAB, false, "Top-Down View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ -1, -1, COMPUTER_TAB, false, "Target Padlock View", CC_TYPE_TRIGGER, -1, -1, 0, false, false }, // (Swifty) Toggle for VM_TRACK
|
||||
{ KEY_SHIFTED | KEY_O, -1, COMPUTER_TAB, true, "Toggle HUD", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_3, -1, SHIP_TAB, true, "Right Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_1, -1, SHIP_TAB, true, "Left Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_PADPLUS, -1, SHIP_TAB, true, "Up Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_SHIFTED | KEY_PADENTER, -1, SHIP_TAB, true, "Down Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_ALTED | KEY_SHIFTED | KEY_Q, -1, COMPUTER_TAB, true, "Toggle HUD Wireframe Target View", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ -1, -1, COMPUTER_TAB, false, "Top-Down View", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ -1, -1, COMPUTER_TAB, false, "Target Padlock View", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL }, // (Swifty) Toggle for VM_TRACK
|
||||
// Auto Navigation Systen
|
||||
{ KEY_ALTED | KEY_A, -1, COMPUTER_TAB, false, "Toggle Auto Pilot", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_ALTED | KEY_N, -1, COMPUTER_TAB, false, "Cycle Nav Points", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_ALTED | KEY_G, -1, SHIP_TAB, false, "Toggle Gliding", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_O, -1, WEAPON_TAB, false, "Cycle Primary Weapon Firing Rate", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
|
||||
{ KEY_ALTED | KEY_A, -1, COMPUTER_TAB, false, "Toggle Auto Pilot", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_ALTED | KEY_N, -1, COMPUTER_TAB, false, "Cycle Nav Points", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_ALTED | KEY_G, -1, SHIP_TAB, false, "Toggle Gliding", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ KEY_O, -1, WEAPON_TAB, false, "Cycle Primary Weapon Firing Rate", CC_TYPE_TRIGGER, -1, -1, 0, false, false, NULL },
|
||||
{ -1, -1, -1, false, "", CC_TYPE_TRIGGER, -1, -1, 0, false, false }
|
||||
};
|
||||
|
||||
@@ -404,6 +404,7 @@ char **Scan_code_text = Scan_code_text_english;
|
||||
char **Joy_button_text = Joy_button_text_english;
|
||||
|
||||
SCP_vector<config_item*> Control_config_presets;
|
||||
SCP_vector<SCP_string> Control_config_preset_names;
|
||||
|
||||
void set_modifier_status()
|
||||
{
|
||||
@@ -591,6 +592,9 @@ void control_config_common_init()
|
||||
for (int i=0; i<CCFG_MAX; i++) {
|
||||
Control_config[i].disabled = false;
|
||||
Control_config[i].continuous_ongoing = false;
|
||||
|
||||
// init the overridable description with a copy of the default
|
||||
Control_config[i].text = strdup(Control_config[i].default_text);
|
||||
}
|
||||
|
||||
control_config_common_load_overrides();
|
||||
@@ -811,6 +815,14 @@ void control_config_common_load_overrides()
|
||||
std::copy(Control_config, Control_config + CCFG_MAX + 1, cfg_preset);
|
||||
Control_config_presets.push_back(cfg_preset);
|
||||
|
||||
SCP_string preset_name;
|
||||
if (optional_string("$Name:")) {
|
||||
stuff_string_line(preset_name);
|
||||
} else {
|
||||
preset_name = "<unnamed preset>";
|
||||
}
|
||||
Control_config_preset_names.push_back(preset_name);
|
||||
|
||||
while (required_string_either("#End","$Bind Name:")) {
|
||||
const int iBufferLength = 64;
|
||||
char szTempBuffer[iBufferLength];
|
||||
@@ -822,7 +834,7 @@ void control_config_common_load_overrides()
|
||||
for (size_t i = 0; i < cCntrlAryLength; ++i) {
|
||||
config_item& r_ccConfig = cfg_preset[i];
|
||||
|
||||
if (!strcmp(szTempBuffer, r_ccConfig.text)) {
|
||||
if (!strcmp(szTempBuffer, r_ccConfig.default_text)) {
|
||||
/**
|
||||
* short key_default;
|
||||
* short joy_default;
|
||||
@@ -833,6 +845,11 @@ void control_config_common_load_overrides()
|
||||
|
||||
int iTemp;
|
||||
|
||||
if (optional_string("$New Name:")) {
|
||||
stuff_string(szTempBuffer, F_NAME, iBufferLength);
|
||||
r_ccConfig.text = strdup(szTempBuffer);
|
||||
}
|
||||
|
||||
if (optional_string("$Key Default:")) {
|
||||
if (optional_string("NONE")) {
|
||||
r_ccConfig.key_default = (short)-1;
|
||||
|
||||
@@ -926,6 +926,10 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
// reset flags to check MC_CHECK_MODEL | MC_CHECK_SPHERELINE and maybe MC_CHECK_INVISIBLE_FACES and MC_SUBMODEL_INSTANCE
|
||||
mc.flags = copy_flags | MC_SUBMODEL_INSTANCE;
|
||||
|
||||
if (Ship_info[Ships[ship_obj->instance].ship_info_index].collision_lod > -1) {
|
||||
mc.lod = Ship_info[Ships[ship_obj->instance].ship_info_index].collision_lod;
|
||||
}
|
||||
|
||||
// check each submodel in turn
|
||||
for (smv = submodel_vector.begin(); smv != submodel_vector.end(); ++smv) {
|
||||
// turn on submodel for collision test
|
||||
|
||||
@@ -1259,7 +1259,7 @@ void game_loading_callback_close()
|
||||
// Make sure bar shows all the way over.
|
||||
game_loading_callback(COUNT_ESTIMATE);
|
||||
|
||||
int real_count = game_busy_callback( NULL );
|
||||
int real_count __attribute__((__unused__)) = game_busy_callback( NULL );
|
||||
Mouse_hidden = 0;
|
||||
|
||||
Game_loading_callback_inited = 0;
|
||||
@@ -1423,7 +1423,7 @@ int game_start_mission()
|
||||
{
|
||||
mprintf(( "=================== STARTING LEVEL LOAD ==================\n" ));
|
||||
|
||||
int s1 = timer_get_milliseconds();
|
||||
int s1 __attribute__((__unused__)) = timer_get_milliseconds();
|
||||
|
||||
// clear post processing settings
|
||||
gr_post_process_set_defaults();
|
||||
@@ -1480,7 +1480,7 @@ int game_start_mission()
|
||||
|
||||
bm_print_bitmaps();
|
||||
|
||||
int e1 = timer_get_milliseconds();
|
||||
int e1 __attribute__((__unused__)) = timer_get_milliseconds();
|
||||
|
||||
mprintf(("Level load took %f seconds.\n", (e1 - s1) / 1000.0f ));
|
||||
|
||||
@@ -1739,7 +1739,7 @@ char full_path[1024];
|
||||
*/
|
||||
void game_init()
|
||||
{
|
||||
int s1, e1;
|
||||
int s1 __attribute__((__unused__)), e1 __attribute__((__unused__));
|
||||
const char *ptr;
|
||||
char whee[MAX_PATH_LEN];
|
||||
|
||||
|
||||
@@ -28,15 +28,14 @@
|
||||
|
||||
#pragma optimize("", off)
|
||||
|
||||
#define DEFAULT_MASTER_EVENT_MUSIC_VOLUME 0.5f
|
||||
|
||||
#define HULL_VALUE_TO_PLAY_INTENSE_BATTLE_MUSIC 0.75f
|
||||
|
||||
////////////////////////////
|
||||
// Globals
|
||||
////////////////////////////
|
||||
int Event_Music_battle_started = 0;
|
||||
float Master_event_music_volume = DEFAULT_MASTER_EVENT_MUSIC_VOLUME; // range is 0->1
|
||||
float Default_music_volume = 0.5f; // range is 0->1
|
||||
float Master_event_music_volume = Default_music_volume;
|
||||
|
||||
typedef struct tagSNDPATTERN {
|
||||
int default_next_pattern; // Needed so the next_pattern member can be reset
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
|
||||
extern int Event_Music_battle_started; // flag that will tell us if we've started a battle in the current mission
|
||||
extern int Event_music_enabled;
|
||||
extern float Master_event_music_volume; // range is 0->1
|
||||
extern float Default_music_volume; // range is 0->1
|
||||
extern float Master_event_music_volume; // range is 0->1
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
|
||||
|
||||
// throw
|
||||
#ifdef HAVE_CXX11
|
||||
void * operator new (size_t size)
|
||||
#else
|
||||
void * operator new (size_t size) throw (std::bad_alloc)
|
||||
#endif // CPP11_STD
|
||||
{
|
||||
void *p = vm_malloc_q(size);
|
||||
|
||||
@@ -19,7 +23,11 @@ void operator delete (void *p) throw()
|
||||
vm_free(p);
|
||||
}
|
||||
|
||||
#ifdef HAVE_CXX11
|
||||
void * operator new [] (size_t size)
|
||||
#else
|
||||
void * operator new [] (size_t size) throw (std::bad_alloc)
|
||||
#endif // CPP11_STD
|
||||
{
|
||||
void *p = vm_malloc_q(size);
|
||||
|
||||
|
||||
@@ -4,6 +4,25 @@
|
||||
|
||||
#include <new>
|
||||
|
||||
#ifdef HAVE_CXX11
|
||||
// throw
|
||||
extern void * operator new (size_t size);
|
||||
|
||||
extern void operator delete (void *p) throw();
|
||||
|
||||
extern void * operator new [] (size_t size);
|
||||
|
||||
extern void operator delete [] (void *p) throw();
|
||||
|
||||
// no-throw
|
||||
extern void * operator new (size_t size, const std::nothrow_t&) throw();
|
||||
|
||||
extern void operator delete (void *p, const std::nothrow_t&) throw();
|
||||
|
||||
extern void * operator new [] (size_t size, const std::nothrow_t&) throw();
|
||||
|
||||
extern void operator delete [] (void *p, const std::nothrow_t&) throw();
|
||||
#else
|
||||
// throw
|
||||
extern void * operator new (size_t size) throw (std::bad_alloc);
|
||||
|
||||
@@ -21,5 +40,6 @@ extern void operator delete (void *p, const std::nothrow_t&) throw();
|
||||
extern void * operator new [] (size_t size, const std::nothrow_t&) throw();
|
||||
|
||||
extern void operator delete [] (void *p, const std::nothrow_t&) throw();
|
||||
#endif
|
||||
|
||||
#endif // _FSMEMORY_H
|
||||
@@ -22,6 +22,7 @@
|
||||
#define IAM_64BIT 1
|
||||
#endif
|
||||
|
||||
|
||||
#include "windows_stub/config.h"
|
||||
|
||||
// value to represent an uninitialized state in any int or uint
|
||||
@@ -680,5 +681,113 @@ public:
|
||||
#include "globalincs/vmallocator.h"
|
||||
#include "globalincs/safe_strings.h"
|
||||
|
||||
// c++11 standard detection
|
||||
// for GCC with autotools, see AX_CXX_COMPILE_STDCXX_11 macro in configure.ac
|
||||
// this sets HAVE_CXX11 & -std=c++0x or -std=c++11 appropriately
|
||||
|
||||
// Use the visual studio version to detect C++11 support
|
||||
#if _MSC_VER >= 1600
|
||||
# define HAVE_CXX11
|
||||
#endif
|
||||
// clang doesn't seem to have a feature check for is_trivial
|
||||
// oh well, assume it'll be covered by one of the other two checks...
|
||||
// http://clang.llvm.org/docs/LanguageExtensions.html#feature_check
|
||||
#if defined(__clang__)
|
||||
#if __has_feature(cxx_static_assert)
|
||||
#if __has_feature(cxx_auto_type)
|
||||
#define HAVE_CXX11
|
||||
#endif // __has_feature(cxx_auto_type)
|
||||
#endif // __has_feature(cxx_static_assert)
|
||||
#endif // defined(__clang__)
|
||||
// TODO: sort out cmake/gcc
|
||||
|
||||
// DEBUG compile time catch for dangerous uses of memset/memcpy/memmove
|
||||
// would prefer std::is_trivially_copyable but it's not supported by gcc yet
|
||||
// ref: http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html
|
||||
#ifndef NDEBUG
|
||||
#if defined(HAVE_CXX11)
|
||||
// feature support seems to be: gcc clang msvc
|
||||
// auto 4.4 2.9 2010
|
||||
// std::is_trivial 4.5 ? 2012 (2010 only duplicates std::is_pod)
|
||||
// static_assert 4.3 2.9 2010
|
||||
#include <type_traits>
|
||||
#include <cstring>
|
||||
|
||||
// MEMSET!
|
||||
const auto ptr_memset = std::memset;
|
||||
#define memset memset_if_trivial_else_error
|
||||
|
||||
template<typename T>
|
||||
void *memset_if_trivial_else_error(T *memset_data, int ch, size_t count)
|
||||
{
|
||||
static_assert(std::is_trivial<T>::value, "memset on non-trivial object");
|
||||
return ptr_memset(memset_data, ch, count);
|
||||
}
|
||||
|
||||
// assume memset on a void* is "safe"
|
||||
// only used in cutscene/mveplayer.cpp:mve_video_createbuf()
|
||||
inline void *memset_if_trivial_else_error(void *memset_data, int ch, size_t count)
|
||||
{
|
||||
return ptr_memset(memset_data, ch, count);
|
||||
}
|
||||
|
||||
// MEMCPY!
|
||||
const auto ptr_memcpy = std::memcpy;
|
||||
#define memcpy memcpy_if_trivial_else_error
|
||||
|
||||
template<typename T, typename U>
|
||||
void *memcpy_if_trivial_else_error(T *memcpy_dest, U *src, size_t count)
|
||||
{
|
||||
static_assert(std::is_trivial<T>::value, "memcpy on non-trivial object T");
|
||||
static_assert(std::is_trivial<U>::value, "memcpy on non-trivial object U");
|
||||
return ptr_memcpy(memcpy_dest, src, count);
|
||||
}
|
||||
|
||||
// assume memcpy with void* is "safe"
|
||||
// used in:
|
||||
// globalincs/systemvars.cpp:insertion_sort()
|
||||
// network/chat_api.cpp:AddChatCommandToQueue()
|
||||
// network/multi_obj.cpp:multi_oo_sort_func()
|
||||
// parse/lua.cpp:ade_get_args() && ade_set_args()
|
||||
//
|
||||
// probably should setup a static_assert on insertion_sort as well
|
||||
template<typename U>
|
||||
void *memcpy_if_trivial_else_error(void *memcpy_dest, U *memcpy_src, size_t count)
|
||||
{
|
||||
static_assert(std::is_trivial<U>::value, "memcpy on non-trivial object U");
|
||||
return ptr_memcpy(memcpy_dest, memcpy_src, count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void *memcpy_if_trivial_else_error(T *memcpy_dest, void *memcpy_src, size_t count)
|
||||
{
|
||||
static_assert(std::is_trivial<T>::value, "memcpy on non-trivial object T");
|
||||
return ptr_memcpy(memcpy_dest, memcpy_src, count);
|
||||
}
|
||||
template<typename T>
|
||||
void *memcpy_if_trivial_else_error(T *memcpy_dest, const void *memcpy_src, size_t count)
|
||||
{
|
||||
static_assert(std::is_trivial<T>::value, "memcpy on non-trivial object T");
|
||||
return ptr_memcpy(memcpy_dest, memcpy_src, count);
|
||||
}
|
||||
|
||||
inline void *memcpy_if_trivial_else_error(void *memcpy_dest, void *memcpy_src, size_t count)
|
||||
{
|
||||
return ptr_memcpy(memcpy_dest, memcpy_src, count);
|
||||
}
|
||||
|
||||
// MEMMOVE!
|
||||
const auto ptr_memmove = std::memmove;
|
||||
#define memmove memmove_if_trivial_else_error
|
||||
|
||||
template<typename T, typename U>
|
||||
void *memmove_if_trivial_else_error(T *memmove_dest, U *memmove_src, size_t count)
|
||||
{
|
||||
static_assert(std::is_trivial<T>::value, "memmove on non-trivial object T");
|
||||
static_assert(std::is_trivial<U>::value, "memmove on non-trivial object U");
|
||||
return ptr_memmove(memmove_dest, memmove_src, count);
|
||||
}
|
||||
#endif // HAVE_CXX11
|
||||
#endif // NDEBUG
|
||||
|
||||
#endif // PS_TYPES_H
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "io/keycontrol.h" // m!m
|
||||
#include "debugconsole/console.h"
|
||||
#include "debugconsole/console.h"
|
||||
#include "popup/popup.h"
|
||||
|
||||
|
||||
#if defined(SCP_UNIX) && !defined(__APPLE__)
|
||||
@@ -83,7 +84,7 @@ int gr_alpha_test = 0;
|
||||
|
||||
// Default clipping distances
|
||||
const float Default_min_draw_distance = 1.0f;
|
||||
const float Default_max_draw_distance = 1e10;
|
||||
const float Default_max_draw_distance = 10000000.0f;
|
||||
float Min_draw_distance = Default_min_draw_distance;
|
||||
float Max_draw_distance = Default_max_draw_distance;
|
||||
|
||||
@@ -1771,7 +1772,7 @@ void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float a
|
||||
void gr_flip()
|
||||
{
|
||||
// m!m avoid running CHA_ONFRAME when the "Quit mission" popup is shown. See mantis 2446 for reference
|
||||
if (!quit_mission_popup_shown)
|
||||
if (!quit_mission_popup_shown && !popup_active())
|
||||
{
|
||||
//WMC - Evaluate global hook if not override.
|
||||
Script_system.RunBytecode(Script_globalhook);
|
||||
|
||||
@@ -220,13 +220,19 @@ int generic_anim_stream(generic_anim *ga)
|
||||
ga->previous_frame = -1;
|
||||
}
|
||||
else {
|
||||
bool in_subdir;
|
||||
bpp = 32;
|
||||
if(ga->use_hud_color)
|
||||
bpp = 8;
|
||||
bm_load_and_parse_eff(ga->filename, CF_TYPE_ANY, &ga->num_frames, &anim_fps, &ga->keyframe, 0);
|
||||
bm_load_and_parse_eff(ga->filename, CF_TYPE_ANY, &ga->num_frames, &anim_fps, &ga->keyframe, 0, &in_subdir);
|
||||
char *p = strrchr( ga->filename, '.' );
|
||||
if ( p )
|
||||
*p = 0;
|
||||
|
||||
if (in_subdir) {
|
||||
set_temp_subdir_pathtype(ga->filename);
|
||||
}
|
||||
|
||||
char frame_name[32];
|
||||
snprintf(frame_name, 32, "%s_0000", ga->filename);
|
||||
ga->bitmap_id = bm_load(frame_name);
|
||||
|
||||
+1
-1
@@ -1090,7 +1090,7 @@ bool HudGauge::canRender()
|
||||
}
|
||||
|
||||
if (gauge_config == HUD_ETS_GAUGE) {
|
||||
if (Ships[Player_obj->instance].flags2 & SF2_NO_ETS) {
|
||||
if (Ships[Player_obj->instance].flags2 & SF2_NO_ETS && !Show_disabled_ets_gauges) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,6 +420,10 @@ int hud_abort_lock()
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( Player_ship->flags2 & SF2_NO_SECONDARY_LOCKON ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if we're on the same team and the team doesn't attack itself, then don't lock!
|
||||
if ((Player_ship->team == target_team) && (!iff_x_attacks_y(Player_ship->team, target_team)))
|
||||
{
|
||||
|
||||
@@ -46,6 +46,7 @@ int Hud_reticle_style = HUD_RETICLE_STYLE_FS2;
|
||||
|
||||
bool Hud_retail = true;
|
||||
bool Scale_retail_gauges = true;
|
||||
bool Show_disabled_ets_gauges = false;
|
||||
|
||||
int Hud_font = -1;
|
||||
|
||||
@@ -259,6 +260,10 @@ void parse_hud_gauges_tbl(const char *filename)
|
||||
Hud_reticle_style = temp;
|
||||
}
|
||||
|
||||
if (optional_string("$Show disabled ETS gauges:")) {
|
||||
stuff_boolean(&Show_disabled_ets_gauges);
|
||||
}
|
||||
|
||||
int base_res[2];
|
||||
int ship_idx = -1;
|
||||
int ship_font = -1;
|
||||
@@ -2017,6 +2022,7 @@ void load_gauge_center_reticle(int base_w, int base_h, int hud_font, bool scale_
|
||||
int scaleX = 15;
|
||||
int scaleY = 10;
|
||||
int size = 5;
|
||||
int autoaim_frame = -1;
|
||||
|
||||
if(Hud_reticle_style == HUD_RETICLE_STYLE_FS1) {
|
||||
if(gr_screen.res == GR_640) {
|
||||
@@ -2066,8 +2072,12 @@ void load_gauge_center_reticle(int base_w, int base_h, int hud_font, bool scale_
|
||||
if (optional_string("Firepoint Y coordinate multiplier:"))
|
||||
stuff_int(&scaleY);
|
||||
|
||||
if(optional_string("Autoaim Frame:"))
|
||||
stuff_int(&autoaim_frame);
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initFirepointDisplay(firepoints, scaleX, scaleY, size);
|
||||
hud_gauge->setAutoaimFrame(autoaim_frame);
|
||||
|
||||
if(ship_idx->at(0) >= 0) {
|
||||
for (SCP_vector<int>::iterator ship_index = ship_idx->begin(); ship_index != ship_idx->end(); ++ship_index) {
|
||||
|
||||
@@ -20,6 +20,7 @@ extern float Hud_speed_multiplier;
|
||||
#define HUD_RETICLE_STYLE_FS2 1
|
||||
|
||||
extern int Hud_reticle_style;
|
||||
extern bool Show_disabled_ets_gauges;
|
||||
|
||||
//Functions
|
||||
int hud_get_gauge_index(char* name);
|
||||
|
||||
+66
-12
@@ -20,6 +20,7 @@
|
||||
#include "weapon/emp.h"
|
||||
#include "localization/localize.h"
|
||||
#include "network/multi.h"
|
||||
#include "weapon/weapon.h"
|
||||
|
||||
#define NUM_RETICLE_ANIS 11 // keep up to date when modifying the number of reticle ani files
|
||||
|
||||
@@ -228,6 +229,7 @@ static int Threat_lock_frame; // frame offset of current lock flashing warnin
|
||||
HudGaugeReticle::HudGaugeReticle():
|
||||
HudGauge(HUD_OBJECT_CENTER_RETICLE, HUD_CENTER_RETICLE, true, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_TOPDOWN | VM_OTHER_SHIP), 255, 255, 255)
|
||||
{
|
||||
has_autoaim_lock = false;
|
||||
}
|
||||
|
||||
void HudGaugeReticle::initBitmaps(char *fname)
|
||||
@@ -247,9 +249,39 @@ void HudGaugeReticle::initFirepointDisplay(bool firepoint, int scaleX, int scale
|
||||
|
||||
void HudGaugeReticle::render(float frametime)
|
||||
{
|
||||
ship_info *sip = &Ship_info[Player_ship->ship_info_index];
|
||||
|
||||
if (autoaim_frame_offset > 0 || sip->autoaim_lock_snd > -1 || sip->autoaim_lost_snd > -1) {
|
||||
ship *shipp = &Ships[Objects[Player->objnum].instance];
|
||||
ship_weapon *swp = &shipp->weapons;
|
||||
ai_info *aip = &Ai_info[shipp->ai_index];
|
||||
|
||||
if (aip->target_objnum != -1) {
|
||||
bool autoaiming = false;
|
||||
|
||||
autoaiming = in_autoaim_fov(shipp, swp->current_primary_bank, &Objects[aip->target_objnum]);
|
||||
|
||||
if (autoaiming) {
|
||||
if (!has_autoaim_lock && sip->autoaim_lock_snd > -1) {
|
||||
snd_play( &Snds[sip->autoaim_lock_snd]);
|
||||
}
|
||||
has_autoaim_lock = true;
|
||||
}
|
||||
else {
|
||||
if (has_autoaim_lock && sip->autoaim_lost_snd > -1) {
|
||||
snd_play( &Snds[sip->autoaim_lost_snd]);
|
||||
}
|
||||
has_autoaim_lock = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setGaugeColor(HUD_C_BRIGHT);
|
||||
|
||||
renderBitmap(crosshair.first_frame, position[0], position[1]);
|
||||
if (has_autoaim_lock)
|
||||
renderBitmap(crosshair.first_frame + autoaim_frame_offset, position[0], position[1]);
|
||||
else
|
||||
renderBitmap(crosshair.first_frame, position[0], position[1]);
|
||||
|
||||
if (firepoint_display) {
|
||||
fp.clear();
|
||||
@@ -277,7 +309,7 @@ void HudGaugeReticle::render(float frametime)
|
||||
|
||||
void HudGaugeReticle::getFirepointStatus() {
|
||||
//First, get the player ship
|
||||
ship_info* pship;
|
||||
ship_info* sip;
|
||||
ship* shipp;
|
||||
polymodel* pm;
|
||||
|
||||
@@ -285,30 +317,45 @@ void HudGaugeReticle::getFirepointStatus() {
|
||||
|
||||
if (Objects[Player->objnum].type == OBJ_SHIP) {
|
||||
shipp = &Ships[Objects[Player->objnum].instance];
|
||||
pship = &Ship_info[shipp->ship_info_index];
|
||||
sip = &Ship_info[shipp->ship_info_index];
|
||||
|
||||
//Get the player eyepoint
|
||||
pm = model_get(pship->model_num);
|
||||
pm = model_get(sip->model_num);
|
||||
|
||||
if (pm->n_view_positions == 0) {
|
||||
mprintf(("Model %s does not have a defined eyepoint. Firepoint display could not be generated\n", pm->filename));
|
||||
} else {
|
||||
if (pm->n_guns > 0) {
|
||||
|
||||
if (pm->n_guns > 0) {
|
||||
eye eyepoint = pm->view_positions[shipp->current_viewpoint];
|
||||
vec2d ep = { eyepoint.pnt.xyz.x, eyepoint.pnt.xyz.y };
|
||||
|
||||
for (int i = 0; i < pm->n_guns; i++) {
|
||||
int isactive = 0;
|
||||
int bankactive = 0;
|
||||
ship_weapon *swp = &shipp->weapons;
|
||||
|
||||
if (!timestamp_elapsed(shipp->weapons.next_primary_fire_stamp[i]))
|
||||
isactive = 1;
|
||||
bankactive = 1;
|
||||
else if (timestamp_elapsed(shipp->weapons.primary_animation_done_time[i]))
|
||||
isactive = 1;
|
||||
bankactive = 1;
|
||||
else if (i == shipp->weapons.current_primary_bank || shipp->flags & SF_PRIMARY_LINKED)
|
||||
isactive = 2;
|
||||
bankactive = 2;
|
||||
|
||||
int num_slots = pm->gun_banks[i].num_slots;
|
||||
for (int j = 0; j < num_slots; j++) {
|
||||
int fpactive = bankactive;
|
||||
|
||||
if (sip->flags2 & SIF2_DYN_PRIMARY_LINKING) {
|
||||
// If this firepoint is not among the next shot(s) to be fired, dim it one step
|
||||
if ( !( (j >= (shipp->last_fired_point[i]+1) % num_slots) && (j <= (shipp->last_fired_point[i]+swp->primary_bank_slot_count[i]) % num_slots) ) ) {
|
||||
fpactive--;
|
||||
}
|
||||
} else if (Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CYCLE) {
|
||||
// If this firepoint is not the next one to be fired, dim it one step
|
||||
if (j != (shipp->last_fired_point[i]+1) % num_slots) {
|
||||
fpactive--;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < pm->gun_banks[i].num_slots; j++) {
|
||||
vec3d fpfromeye;
|
||||
|
||||
matrix eye_orient, player_transpose;
|
||||
@@ -317,7 +364,7 @@ void HudGaugeReticle::getFirepointStatus() {
|
||||
vm_matrix_x_matrix(&eye_orient, &player_transpose, &Eye_matrix);
|
||||
vm_vec_rotate(&fpfromeye, &pm->gun_banks[i].pnt[j], &eye_orient);
|
||||
|
||||
firepoint tmp = { { fpfromeye.xyz.x - ep.x, ep.y - fpfromeye.xyz.y }, isactive };
|
||||
firepoint tmp = { { fpfromeye.xyz.x - ep.x, ep.y - fpfromeye.xyz.y }, fpactive };
|
||||
fp.push_back(tmp);
|
||||
}
|
||||
}
|
||||
@@ -326,6 +373,13 @@ void HudGaugeReticle::getFirepointStatus() {
|
||||
}
|
||||
}
|
||||
|
||||
void HudGaugeReticle::setAutoaimFrame(int framenum) {
|
||||
if (framenum < 0 || framenum > crosshair.num_frames - 1)
|
||||
autoaim_frame_offset = 0;
|
||||
else
|
||||
autoaim_frame_offset = framenum;
|
||||
}
|
||||
|
||||
void HudGaugeReticle::pageIn()
|
||||
{
|
||||
bm_page_in_aabitmap( crosshair.first_frame, crosshair.num_frames);
|
||||
|
||||
@@ -43,6 +43,8 @@ protected:
|
||||
int firepoint_size;
|
||||
int firepoint_scale_x;
|
||||
int firepoint_scale_y;
|
||||
int autoaim_frame_offset;
|
||||
bool has_autoaim_lock;
|
||||
public:
|
||||
HudGaugeReticle();
|
||||
void render(float frametime);
|
||||
@@ -50,6 +52,7 @@ public:
|
||||
void pageIn();
|
||||
void initFirepointDisplay(bool firepoint, int scaleX, int scaleY, int size);
|
||||
void getFirepointStatus();
|
||||
void setAutoaimFrame(int framenum);
|
||||
};
|
||||
|
||||
class HudGaugeThrottle: public HudGauge
|
||||
|
||||
@@ -545,6 +545,11 @@ void hud_shield_quadrant_hit(object *objp, int quadrant)
|
||||
shield_hit_info *shi;
|
||||
int num;
|
||||
|
||||
if (Game_mode & GM_STANDALONE_SERVER)
|
||||
return;
|
||||
|
||||
Assertion(objp != NULL, "hud_shield_quadrant_hit() called with a NULL objp; get a coder!\n");
|
||||
|
||||
if ( objp->type != OBJ_SHIP )
|
||||
return;
|
||||
|
||||
@@ -559,12 +564,16 @@ void hud_shield_quadrant_hit(object *objp, int quadrant)
|
||||
return;
|
||||
}
|
||||
|
||||
Assertion(shi->shield_hit_timers.size() > 0, "Shield hit info object for object '%s' has a size %d shield_hit_timers; get a coder!\n", Ships[objp->instance].ship_name, shi->shield_hit_timers.size());
|
||||
Assertion(shi->hull_hit_index < shi->shield_hit_timers.size(), "Shield hit info object for object '%s' has a hull_hit_index of %d (should be between 0 and %d); get a coder!\n", Ships[objp->instance].ship_name, shi->hull_hit_index, shi->shield_hit_timers.size() - 1);
|
||||
|
||||
if ( quadrant >= 0 ) {
|
||||
if ( !(Ship_info[Ships[objp->instance].ship_info_index].flags2 & SIF2_MODEL_POINT_SHIELDS) )
|
||||
num = Quadrant_xlate[quadrant];
|
||||
else
|
||||
num = quadrant;
|
||||
|
||||
Assertion(num < shi->hull_hit_index, "Shield hit info object for object '%s' hit on quadrant #%d, despite having a hull_hit_index of %d; get a coder!\n", Ships[objp->instance].ship_name, num, shi->hull_hit_index);
|
||||
shi->shield_hit_timers[num] = timestamp(SHIELD_HIT_DURATION_SHORT);
|
||||
} else {
|
||||
shi->shield_hit_timers[shi->hull_hit_index] = timestamp(SHIELD_HIT_DURATION_SHORT);
|
||||
|
||||
@@ -1373,11 +1373,10 @@ int hud_squadmsg_send_wing_command( int wingnum, int command, int send_message,
|
||||
|
||||
target_shipname = NULL;
|
||||
target_team = -1;
|
||||
if ( ainfo->target_objnum != -1) {
|
||||
if ( Objects[ainfo->target_objnum].type == OBJ_SHIP ) {
|
||||
target_shipname = Ships[Objects[ainfo->target_objnum].instance].ship_name; // I think this is right
|
||||
target_team = Ships[Objects[ainfo->target_objnum].instance].team;
|
||||
}
|
||||
|
||||
if ( Objects[ainfo->target_objnum].type == OBJ_SHIP ) {
|
||||
target_shipname = Ships[Objects[ainfo->target_objnum].instance].ship_name; // I think this is right
|
||||
target_team = Ships[Objects[ainfo->target_objnum].instance].team;
|
||||
}
|
||||
|
||||
Assert ( ainfo->shipnum != -1 );
|
||||
|
||||
@@ -1095,7 +1095,7 @@ void hud_target_subobject_common(int next_flag)
|
||||
target_shipp = &Ships[Objects[Player_ai->target_objnum].instance];
|
||||
|
||||
if (!Player_ai->targeted_subsys) {
|
||||
start = GET_FIRST(&target_shipp->subsys_list);
|
||||
start = END_OF_LIST(&target_shipp->subsys_list);
|
||||
} else {
|
||||
start = Player_ai->targeted_subsys;
|
||||
}
|
||||
|
||||
+11
-1
@@ -41,6 +41,7 @@
|
||||
#define LAB_FLAG_FULLY_LOAD (1<<5) // use create_ship() to test the ships
|
||||
#define LAB_FLAG_SHOW_WEAPONS (1<<6) // determines if external weapons models are displayed
|
||||
#define LAB_FLAG_INITIAL_ROTATION (1<<7) // initial rotation setting
|
||||
#define LAB_FLAG_DESTROYED_SUBSYSTEMS (1<<8) // render model as if all subsystems are destroyed
|
||||
|
||||
// modes
|
||||
#define LAB_MODE_NONE 0 // not showing anything
|
||||
@@ -684,7 +685,7 @@ void labviewer_add_model_thrusters(ship_info *sip)
|
||||
mst.distortion_bitmap = thruster_distortion_bitmap;
|
||||
|
||||
mst.use_ab = Lab_thrust_afterburn;
|
||||
mst.glow_noise = thruster_glow_noise;
|
||||
mst.glow_noise = thruster_glow_noise * sip->thruster_glow_noise_mult;
|
||||
mst.rotvel = &vmd_zero_vector;
|
||||
|
||||
if (Lab_mode == LAB_MODE_SHIP) {
|
||||
@@ -904,6 +905,13 @@ void labviewer_render_model(float frametime)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sip != NULL) {
|
||||
if (Lab_viewer_flags & LAB_FLAG_DESTROYED_SUBSYSTEMS) {
|
||||
model_show_damaged(Lab_model_num, 1);
|
||||
}
|
||||
}
|
||||
|
||||
opengl_shader_set_animated_effect(ANIMATED_SHADER_LOADOUTSELECT_FS1);
|
||||
opengl_shader_set_animated_timer(MIN((timer_get_milliseconds()-anim_timer_start)/1500.0f,2.0f));
|
||||
|
||||
@@ -1855,6 +1863,7 @@ void labviewer_make_render_options_window(Button *caller)
|
||||
ADD_RENDER_FLAG("Animated Shader", Lab_model_flags, MR_ANIMATED_SHADER);
|
||||
ADD_RENDER_FLAG("Show Ship Weapons", Lab_viewer_flags, LAB_FLAG_SHOW_WEAPONS);
|
||||
ADD_RENDER_FLAG("Initial Rotation", Lab_viewer_flags, LAB_FLAG_INITIAL_ROTATION);
|
||||
ADD_RENDER_FLAG("Show Destroyed Subsystems", Lab_viewer_flags, LAB_FLAG_DESTROYED_SUBSYSTEMS);
|
||||
|
||||
|
||||
// start tree
|
||||
@@ -2234,6 +2243,7 @@ void labviewer_make_weap_window(Button* caller)
|
||||
delete type_nodes[i];
|
||||
}
|
||||
}
|
||||
delete[] type_nodes;
|
||||
|
||||
Lab_mode = LAB_MODE_WEAPON;
|
||||
|
||||
|
||||
@@ -159,6 +159,8 @@ void GUISystem::ParseClassInfo(char* filename)
|
||||
flag = sciep->Parse();
|
||||
if (flag) {
|
||||
list_append(&ScreenClassInfo, sciep);
|
||||
} else {
|
||||
delete sciep;
|
||||
}
|
||||
} while (flag);
|
||||
|
||||
|
||||
@@ -1534,6 +1534,9 @@ void message_queue_process()
|
||||
|
||||
// Don't play death scream unless a small ship.
|
||||
if ( q->builtin_type == MESSAGE_WINGMAN_SCREAM ) {
|
||||
if (Message_shipnum < 0) {
|
||||
goto all_done;
|
||||
}
|
||||
if (!((Ship_info[Ships[Message_shipnum].ship_info_index].flags & SIF_SMALL_SHIP) || (Ships[Message_shipnum].flags2 & SF2_ALWAYS_DEATH_SCREAM)) ) {
|
||||
goto all_done;
|
||||
}
|
||||
@@ -1917,7 +1920,7 @@ void message_send_builtin_to_player( int type, ship *shipp, int priority, int ti
|
||||
char *who_from;
|
||||
int best_match = -1;
|
||||
|
||||
matching_builtin *current_builtin = new matching_builtin();
|
||||
matching_builtin current_builtin;
|
||||
SCP_vector <matching_builtin> matching_builtins;
|
||||
|
||||
|
||||
@@ -1979,52 +1982,52 @@ void message_send_builtin_to_player( int type, ship *shipp, int priority, int ti
|
||||
// check the type of message
|
||||
if ( !stricmp(Messages[i].name, name) ) {
|
||||
// condition 1: we have a type match
|
||||
current_builtin->message_index = i;
|
||||
current_builtin->type_of_match = BUILTIN_MATCHES_TYPE;
|
||||
current_builtin.message_index = i;
|
||||
current_builtin.type_of_match = BUILTIN_MATCHES_TYPE;
|
||||
|
||||
// check the species of this persona (if required)
|
||||
if ( (persona_species >= 0) && (Personas[Messages[i].persona_index].species == persona_species) ) {
|
||||
// condition 2: we have a type + species match
|
||||
current_builtin->type_of_match = BUILTIN_MATCHES_SPECIES;
|
||||
current_builtin.type_of_match = BUILTIN_MATCHES_SPECIES;
|
||||
}
|
||||
|
||||
// check the exact persona (if required)
|
||||
// NOTE: doesn't need to be nested under the species condition above
|
||||
if ( (persona_index >= 0) && (Messages[i].persona_index == persona_index) ) {
|
||||
// condition 3: type + species + persona index match
|
||||
current_builtin->type_of_match = BUILTIN_MATCHES_PERSONA_CHECK_MOOD;
|
||||
current_builtin.type_of_match = BUILTIN_MATCHES_PERSONA_CHECK_MOOD;
|
||||
}
|
||||
|
||||
// check if the personas mood suits this particular message, first check if it is excluded
|
||||
if (!Messages[i].excluded_moods.empty() && (current_builtin->type_of_match == BUILTIN_MATCHES_PERSONA_CHECK_MOOD)) {
|
||||
if (!Messages[i].excluded_moods.empty() && (current_builtin.type_of_match == BUILTIN_MATCHES_PERSONA_CHECK_MOOD)) {
|
||||
for (SCP_vector<int>::iterator iter = Messages[i].excluded_moods.begin(); iter != Messages[i].excluded_moods.end(); ++iter) {
|
||||
if (*iter == Current_mission_mood) {
|
||||
current_builtin->type_of_match = BUILTIN_MATCHES_PERSONA_EXCLUDED;
|
||||
current_builtin.type_of_match = BUILTIN_MATCHES_PERSONA_EXCLUDED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (current_builtin->type_of_match == BUILTIN_MATCHES_PERSONA_CHECK_MOOD) {
|
||||
if (current_builtin.type_of_match == BUILTIN_MATCHES_PERSONA_CHECK_MOOD) {
|
||||
if (Current_mission_mood == Messages[i].mood) {
|
||||
current_builtin->type_of_match = BUILTIN_MATCHES_PERSONA_MOOD;
|
||||
current_builtin.type_of_match = BUILTIN_MATCHES_PERSONA_MOOD;
|
||||
}
|
||||
else {
|
||||
current_builtin->type_of_match = BUILTIN_MATCHES_PERSONA;
|
||||
current_builtin.type_of_match = BUILTIN_MATCHES_PERSONA;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_builtin->type_of_match == best_match) {
|
||||
if (current_builtin.type_of_match == best_match) {
|
||||
num_matching_builtins++;
|
||||
}
|
||||
// otherwise check to see if the this is the best kind of match we've found so far
|
||||
else if (current_builtin->type_of_match > best_match) {
|
||||
best_match = current_builtin->type_of_match;
|
||||
else if (current_builtin.type_of_match > best_match) {
|
||||
best_match = current_builtin.type_of_match;
|
||||
num_matching_builtins = 1;
|
||||
}
|
||||
|
||||
// add the match to our list
|
||||
matching_builtins.push_back(*current_builtin);
|
||||
matching_builtins.push_back(current_builtin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1838,6 +1838,7 @@ int parse_create_object_sub(p_object *p_objp)
|
||||
|
||||
shipp->ship_max_shield_strength = p_objp->ship_max_shield_strength;
|
||||
shipp->ship_max_hull_strength = p_objp->ship_max_hull_strength;
|
||||
shipp->max_shield_recharge = p_objp->max_shield_recharge;
|
||||
|
||||
// Goober5000 - ugh, this is really stupid having to do this here; if the
|
||||
// ship creation code was better organized this wouldn't be necessary
|
||||
@@ -2250,7 +2251,7 @@ int parse_create_object_sub(p_object *p_objp)
|
||||
Objects[objnum].hull_strength = p_objp->initial_hull * shipp->ship_max_hull_strength / 100.0f;
|
||||
for (iLoop = 0; iLoop<Objects[objnum].n_quadrants; iLoop++)
|
||||
{
|
||||
Objects[objnum].shield_quadrant[iLoop] = (float) (p_objp->initial_shields * get_max_shield_quad(&Objects[objnum]) / 100.0f);
|
||||
Objects[objnum].shield_quadrant[iLoop] = (float) (shipp->max_shield_recharge * p_objp->initial_shields * get_max_shield_quad(&Objects[objnum]) / 100.0f);
|
||||
}
|
||||
|
||||
// initial velocities now do not apply to ships which warp in after mission starts
|
||||
@@ -3110,6 +3111,7 @@ int parse_object(mission *pm, int flag, p_object *p_objp)
|
||||
}
|
||||
|
||||
Assert(p_objp->ship_max_hull_strength > 0.0f); // Goober5000: div-0 check (not shield because we might not have one)
|
||||
p_objp->max_shield_recharge = Ship_info[p_objp->ship_class].max_shield_recharge;
|
||||
|
||||
|
||||
// if the kamikaze flag is set, we should have the next flag
|
||||
@@ -4603,8 +4605,9 @@ void resolve_path_masks(int anchor, int *path_mask)
|
||||
Assert(!(anchor & SPECIAL_ARRIVAL_ANCHOR_FLAG));
|
||||
parent_pobjp = mission_parse_get_parse_object(Parse_names[anchor]);
|
||||
|
||||
// load model for checking paths
|
||||
modelnum = model_load(Ship_info[parent_pobjp->ship_class].pof_file, 0, NULL);
|
||||
// Load the anchor ship model with subsystems and all; it'll need to be done for this mission anyway
|
||||
ship_info *sip = &Ship_info[parent_pobjp->ship_class];
|
||||
modelnum = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
|
||||
|
||||
// resolve names to indexes
|
||||
*path_mask = 0;
|
||||
@@ -4617,9 +4620,6 @@ void resolve_path_masks(int anchor, int *path_mask)
|
||||
*path_mask |= (1 << bay_path);
|
||||
}
|
||||
|
||||
// unload model
|
||||
model_unload(modelnum);
|
||||
|
||||
// cache the result
|
||||
prp->cached_mask = *path_mask;
|
||||
}
|
||||
@@ -5832,42 +5832,38 @@ int get_mission_info(const char *filename, mission *mission_p, bool basic)
|
||||
if (p) *p = 0; // remove any extension
|
||||
strcat_s(real_fname, FS_MISSION_FILE_EXT); // append mission extension
|
||||
|
||||
int rval, filelength;
|
||||
int filelength;
|
||||
|
||||
// if mission_p is NULL, make it point to The_mission
|
||||
if ( mission_p == NULL )
|
||||
mission_p = &The_mission;
|
||||
|
||||
do {
|
||||
CFILE *ftemp = cfopen(real_fname, "rt");
|
||||
if (!ftemp) {
|
||||
rval = -1;
|
||||
break;
|
||||
}
|
||||
CFILE *ftemp = cfopen(real_fname, "rt");
|
||||
if (!ftemp) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 7/9/98 -- MWA -- check for 0 length file.
|
||||
filelength = cfilelength(ftemp);
|
||||
cfclose(ftemp);
|
||||
if (filelength == 0) {
|
||||
rval = -1;
|
||||
break;
|
||||
}
|
||||
// 7/9/98 -- MWA -- check for 0 length file.
|
||||
filelength = cfilelength(ftemp);
|
||||
cfclose(ftemp);
|
||||
if (filelength == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
read_file_text(real_fname, CF_TYPE_MISSIONS);
|
||||
mission_p->Reset();
|
||||
parse_init(basic);
|
||||
parse_mission_info(mission_p, basic);
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("MISSIONS: Unable to parse '%s'! Error message = %s.\n", real_fname, e.what()));
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
try
|
||||
{
|
||||
read_file_text(real_fname, CF_TYPE_MISSIONS);
|
||||
mission_p->Reset();
|
||||
parse_init(basic);
|
||||
parse_mission_info(mission_p, basic);
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("MISSIONS: Unable to parse '%s'! Error message = %s.\n", real_fname, e.what()));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rval;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7566,6 +7562,7 @@ void mission_bring_in_support_ship( object *requester_objp )
|
||||
// set support ship hitpoints
|
||||
pobj->ship_max_hull_strength = Ship_info[i].max_hull_strength;
|
||||
pobj->ship_max_shield_strength = Ship_info[i].max_shield_strength;
|
||||
pobj->max_shield_recharge = Ship_info[i].max_shield_recharge;
|
||||
|
||||
pobj->team = requester_shipp->team;
|
||||
|
||||
|
||||
@@ -424,6 +424,8 @@ public:
|
||||
float ship_max_hull_strength; // Needed to deal with special hitpoints
|
||||
float ship_max_shield_strength;
|
||||
|
||||
float max_shield_recharge;
|
||||
|
||||
// Goober5000
|
||||
SCP_vector<texture_replace> replacement_textures;
|
||||
|
||||
|
||||
@@ -1513,6 +1513,11 @@ void draw_model_icon(int model_id, int flags, float closeup_zoom, int x, int y,
|
||||
//Assume it's a weapon
|
||||
rot_angles.h = -(PI_2);
|
||||
}
|
||||
else if(sip->model_icon_angles.p != 0.0f || sip->model_icon_angles.b != 0.0f || sip->model_icon_angles.h != 0.0f)
|
||||
{
|
||||
// If non-zero model_icon_angles exists, always use that
|
||||
rot_angles = sip->model_icon_angles;
|
||||
}
|
||||
else if(sip->flags & SIF_SMALL_SHIP)
|
||||
{
|
||||
rot_angles.p = -(PI_2);
|
||||
|
||||
+2
-1
@@ -1022,7 +1022,8 @@ typedef struct mc_info {
|
||||
vec3d *p0; // The starting point of the ray (sphere) to check
|
||||
vec3d *p1; // The ending point of the ray (sphere) to check
|
||||
int flags; // Flags that the model_collide code looks at. See MC_??? defines
|
||||
float radius; // If MC_CHECK_THICK is set, checks a sphere moving with the radius.
|
||||
float radius; // If MC_CHECK_THICK is set, checks a sphere moving with the radius.
|
||||
int lod; // Which detail level of the submodel to check instead
|
||||
|
||||
// Return values
|
||||
int num_hits; // How many collisions were found
|
||||
|
||||
@@ -1130,7 +1130,22 @@ void mc_check_subobj( int mn )
|
||||
if ( Cmdline_old_collision_sys ) {
|
||||
model_collide_sub(sm->bsp_data);
|
||||
} else {
|
||||
model_collide_bsp(model_get_bsp_collision_tree(sm->collision_tree_index), 0);
|
||||
if (Mc->lod > 0 && sm->num_details > 0) {
|
||||
bsp_info *lod_sm = sm;
|
||||
|
||||
for (int i = Mc->lod - 1; i >= 0; i--) {
|
||||
if (sm->details[i] != -1) {
|
||||
lod_sm = &Mc_pm->submodel[sm->details[i]];
|
||||
|
||||
//mprintf(("Checking %s collision for %s using %s instead\n", Mc_pm->filename, sm->name, lod_sm->name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
model_collide_bsp(model_get_bsp_collision_tree(lod_sm->collision_tree_index), 0);
|
||||
} else {
|
||||
model_collide_bsp(model_get_bsp_collision_tree(sm->collision_tree_index), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+51
-31
@@ -83,7 +83,6 @@ static float Interp_box_scale = 1.0f; // this is used to scale both detail boxes
|
||||
static vec3d Interp_render_box_min = ZERO_VECTOR;
|
||||
static vec3d Interp_render_box_max = ZERO_VECTOR;
|
||||
static float Interp_render_sphere_radius = 0.0f;
|
||||
static vec3d Interp_render_sphere_offset = ZERO_VECTOR;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// lighting save stuff
|
||||
@@ -369,7 +368,6 @@ void interp_clear_instance()
|
||||
Interp_render_box_min = vmd_zero_vector;
|
||||
Interp_render_box_max = vmd_zero_vector;
|
||||
Interp_render_sphere_radius = 0.0f;
|
||||
Interp_render_sphere_offset = vmd_zero_vector;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2728,6 +2726,7 @@ void model_really_render(int model_num, matrix *orient, vec3d * pos, uint flags,
|
||||
uint save_gr_zbuffering_mode;
|
||||
int zbuf_mode;
|
||||
ship *shipp = NULL;
|
||||
ship_info *sip = NULL;
|
||||
object *objp = NULL;
|
||||
bool set_autocen = false;
|
||||
bool draw_thrusters = false;
|
||||
@@ -2742,6 +2741,7 @@ void model_really_render(int model_num, matrix *orient, vec3d * pos, uint flags,
|
||||
|
||||
if (objp->type == OBJ_SHIP) {
|
||||
shipp = &Ships[objp->instance];
|
||||
sip = &Ship_info[shipp->ship_info_index];
|
||||
|
||||
if (shipp->flags2 & SF2_GLOWMAPS_DISABLED)
|
||||
flags |= MR_NO_GLOWMAPS;
|
||||
@@ -2905,33 +2905,37 @@ void model_really_render(int model_num, matrix *orient, vec3d * pos, uint flags,
|
||||
}
|
||||
#endif
|
||||
|
||||
// scale the render box settings based on the "Model Detail" slider
|
||||
switch (Detail.detail_distance)
|
||||
{
|
||||
// 1st dot is 20%
|
||||
case 0:
|
||||
Interp_box_scale = 0.2f;
|
||||
break;
|
||||
if (shipp != NULL && (sip->flags2 & SIF2_LOCK_DETAIL_BOXES)) {
|
||||
Interp_box_scale = 1.0f;
|
||||
} else {
|
||||
// scale the render box settings based on the "Model Detail" slider
|
||||
switch (Detail.detail_distance)
|
||||
{
|
||||
// 1st dot is 20%
|
||||
case 0:
|
||||
Interp_box_scale = 0.2f;
|
||||
break;
|
||||
|
||||
// 2nd dot is 50%
|
||||
case 1:
|
||||
Interp_box_scale = 0.5f;
|
||||
break;
|
||||
// 2nd dot is 50%
|
||||
case 1:
|
||||
Interp_box_scale = 0.5f;
|
||||
break;
|
||||
|
||||
// 3rd dot is 80%
|
||||
case 2:
|
||||
Interp_box_scale = 0.8f;
|
||||
break;
|
||||
// 3rd dot is 80%
|
||||
case 2:
|
||||
Interp_box_scale = 0.8f;
|
||||
break;
|
||||
|
||||
// 4th dot is 100% (this is the default setting for "High" and "Very High" settings)
|
||||
case 3:
|
||||
Interp_box_scale = 1.0f;
|
||||
break;
|
||||
// 4th dot is 100% (this is the default setting for "High" and "Very High" settings)
|
||||
case 3:
|
||||
Interp_box_scale = 1.0f;
|
||||
break;
|
||||
|
||||
// 5th dot (max) is 120%
|
||||
case 4:
|
||||
Interp_box_scale = 1.2f;
|
||||
break;
|
||||
// 5th dot (max) is 120%
|
||||
case 4:
|
||||
Interp_box_scale = 1.2f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vec3d auto_back = ZERO_VECTOR;
|
||||
@@ -4468,7 +4472,13 @@ void model_render_children_buffers(polymodel *pm, int mn, int detail_level)
|
||||
vm_vec_copy_scale(&Interp_render_box_min, &model->render_box_min, Interp_box_scale);
|
||||
vm_vec_copy_scale(&Interp_render_box_max, &model->render_box_max, Interp_box_scale);
|
||||
|
||||
if ( (-model->use_render_box + in_box(&Interp_render_box_min, &Interp_render_box_max, &model->offset)) )
|
||||
vec3d offset;
|
||||
if (model->use_render_box_offset)
|
||||
offset = model->render_box_offset;
|
||||
else
|
||||
model_find_submodel_offset(&offset, pm->id, mn);
|
||||
|
||||
if ( (-model->use_render_box + in_box(&Interp_render_box_min, &Interp_render_box_max, &offset)) )
|
||||
return;
|
||||
}
|
||||
if ( !(Interp_flags & MR_FULL_DETAIL) && model->use_render_sphere ) {
|
||||
@@ -4476,8 +4486,10 @@ void model_render_children_buffers(polymodel *pm, int mn, int detail_level)
|
||||
|
||||
// TODO: doesn't consider submodel rotations yet -zookeeper
|
||||
vec3d offset;
|
||||
model_find_submodel_offset(&offset, pm->id, mn);
|
||||
vm_vec_add2(&offset, &model->render_sphere_offset);
|
||||
if (model->use_render_sphere_offset)
|
||||
offset = model->render_sphere_offset;
|
||||
else
|
||||
model_find_submodel_offset(&offset, pm->id, mn);
|
||||
|
||||
if ( (-model->use_render_sphere + in_sphere(&offset, Interp_render_sphere_radius)) )
|
||||
return;
|
||||
@@ -4591,7 +4603,13 @@ void model_render_buffers(polymodel *pm, int mn, bool is_child)
|
||||
vm_vec_copy_scale(&Interp_render_box_min, &model->render_box_min, Interp_box_scale);
|
||||
vm_vec_copy_scale(&Interp_render_box_max, &model->render_box_max, Interp_box_scale);
|
||||
|
||||
if ( (-model->use_render_box + in_box(&Interp_render_box_min, &Interp_render_box_max, &model->offset)) )
|
||||
vec3d offset;
|
||||
if (model->use_render_box_offset)
|
||||
offset = model->render_box_offset;
|
||||
else
|
||||
model_find_submodel_offset(&offset, pm->id, mn);
|
||||
|
||||
if ( (-model->use_render_box + in_box(&Interp_render_box_min, &Interp_render_box_max, &offset)) )
|
||||
return;
|
||||
}
|
||||
if ( !is_child && !(Interp_flags & MR_FULL_DETAIL) && model->use_render_sphere ) {
|
||||
@@ -4599,8 +4617,10 @@ void model_render_buffers(polymodel *pm, int mn, bool is_child)
|
||||
|
||||
// TODO: doesn't consider submodel rotations yet -zookeeper
|
||||
vec3d offset;
|
||||
model_find_submodel_offset(&offset, pm->id, mn);
|
||||
vm_vec_add2(&offset, &model->render_sphere_offset);
|
||||
if (model->use_render_sphere_offset)
|
||||
offset = model->render_sphere_offset;
|
||||
else
|
||||
model_find_submodel_offset(&offset, pm->id, mn);
|
||||
|
||||
if ( (-model->use_render_sphere + in_sphere(&offset, Interp_render_sphere_radius)) )
|
||||
return;
|
||||
|
||||
@@ -1354,6 +1354,18 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs
|
||||
while (*p == ' ') p++;
|
||||
pm->submodel[n].use_render_box = atoi(p);
|
||||
|
||||
if ( (p = strstr(props, "$box_offset:")) != NULL ) {
|
||||
p += 12;
|
||||
while (*p == ' ') p++;
|
||||
pm->submodel[n].render_box_offset.xyz.x = (float)strtod(p, (char **)NULL);
|
||||
while (*p != ',') p++;
|
||||
pm->submodel[n].render_box_offset.xyz.y = (float)strtod(++p, (char **)NULL);
|
||||
while (*p != ',') p++;
|
||||
pm->submodel[n].render_box_offset.xyz.z = (float)strtod(++p, (char **)NULL);
|
||||
|
||||
pm->submodel[n].use_render_box_offset = true;
|
||||
}
|
||||
|
||||
if ( (p = strstr(props, "$box_min:")) != NULL ) {
|
||||
p += 9;
|
||||
while (*p == ' ') p++;
|
||||
@@ -1400,6 +1412,8 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs
|
||||
pm->submodel[n].render_sphere_offset.xyz.y = (float)strtod(++p, (char **)NULL);
|
||||
while (*p != ',') p++;
|
||||
pm->submodel[n].render_sphere_offset.xyz.z = (float)strtod(++p, (char **)NULL);
|
||||
|
||||
pm->submodel[n].use_render_sphere_offset = true;
|
||||
} else {
|
||||
pm->submodel[n].render_sphere_offset = vmd_zero_vector;
|
||||
}
|
||||
@@ -2639,6 +2653,12 @@ int model_load(char *filename, int n_subsystems, model_subsystem *subsystems, in
|
||||
}
|
||||
dl2 = tolower(sm2->name[first_diff]) - 'a';
|
||||
|
||||
// Handle LODs named "detail0/1/2/etc" too (as opposed to "detaila/b/c/etc")
|
||||
if (sm1->parent == -1 && sm2->parent == -1 && !sm1->is_damaged && !sm2->is_damaged && !sm1->is_live_debris && !sm2->is_live_debris) {
|
||||
dl2 = dl2 - dl1;
|
||||
dl1 = 0;
|
||||
}
|
||||
|
||||
if ( (dl1<0) || (dl2<0) || (dl1>=MAX_MODEL_DETAIL_LEVELS) || (dl2>=MAX_MODEL_DETAIL_LEVELS) ) continue; // invalid detail levels
|
||||
|
||||
if ( dl1 == 0 ) {
|
||||
@@ -2663,10 +2683,11 @@ int model_load(char *filename, int n_subsystems, model_subsystem *subsystems, in
|
||||
|
||||
if ( !Cmdline_old_collision_sys ) {
|
||||
for ( i = 0; i < pm->n_models; ++i ) {
|
||||
pm->submodel[i].collision_tree_index = model_create_bsp_collision_tree();
|
||||
bsp_collision_tree *tree = model_get_bsp_collision_tree(pm->submodel[i].collision_tree_index);
|
||||
|
||||
model_collide_parse_bsp(tree, pm->submodel[i].bsp_data, pm->version);
|
||||
if ( !(pm->submodel[i].nocollide_this_only || pm->submodel[i].no_collisions) ) {
|
||||
pm->submodel[i].collision_tree_index = model_create_bsp_collision_tree();
|
||||
bsp_collision_tree *tree = model_get_bsp_collision_tree(pm->submodel[i].collision_tree_index);
|
||||
model_collide_parse_bsp(tree, pm->submodel[i].bsp_data, pm->version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -585,6 +585,11 @@ void multi_options_process_packet(unsigned char *data, header *hinfo)
|
||||
// find out who is sending this data
|
||||
player_index = find_player_id(hinfo->id);
|
||||
|
||||
if (player_index < 0) {
|
||||
nprintf(("Network", "Received packet from unknown player!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
// get the packet code
|
||||
GET_DATA(code);
|
||||
switch(code){
|
||||
|
||||
@@ -4511,7 +4511,8 @@ void multi_pxo_pinfo_build_vals()
|
||||
if (fs->stats.last_flown == 0) {
|
||||
strcpy_s(Multi_pxo_pinfo_vals[7], XSTR("No missions flown", 970) );
|
||||
} else {
|
||||
tm *tmr = gmtime( (time_t*)&fs->stats.last_flown );
|
||||
time_t tmp_lf = fs->stats.last_flown; // don't cast a pointer to a type that can be either 32 or 64bit
|
||||
tm *tmr = gmtime( &tmp_lf );
|
||||
|
||||
if (tmr != NULL)
|
||||
strftime(Multi_pxo_pinfo_vals[7], 30, "%m/%d/%y %H:%M", tmr);
|
||||
|
||||
@@ -1599,6 +1599,12 @@ void multi_create_standalone_object()
|
||||
|
||||
vm_vec_zero(&v);
|
||||
objnum = observer_create(&m,&v);
|
||||
|
||||
if (objnum < 0) {
|
||||
Error(LOCATION, "Failed to create standalone observer object! Please investigate!");
|
||||
return;
|
||||
}
|
||||
|
||||
Player_obj = &Objects[objnum];
|
||||
obj_set_flags(Player_obj, Player_obj->flags & (~OF_COLLIDES) );
|
||||
//obj_set_flags(Player_obj, Player_obj->flags | OF_SHOULD_BE_DEAD);
|
||||
|
||||
@@ -269,6 +269,10 @@ int ship_ship_check_collision(collision_info_struct *ship_ship_hit_info, vec3d *
|
||||
// reset flags to check MC_CHECK_MODEL | MC_CHECK_SPHERELINE and maybe MC_CHECK_INVISIBLE_FACES and MC_SUBMODEL_INSTANCE
|
||||
mc.flags = copy_flags | MC_SUBMODEL_INSTANCE;
|
||||
|
||||
if (heavy_sip->collision_lod > -1) {
|
||||
mc.lod = heavy_sip->collision_lod;
|
||||
}
|
||||
|
||||
// check each submodel in turn
|
||||
for (smv = submodel_vector.begin(); smv != submodel_vector.end(); ++smv) {
|
||||
// turn on submodel for collision test
|
||||
|
||||
@@ -168,6 +168,7 @@ int ship_weapon_check_collision(object *ship_objp, object *weapon_objp, float ti
|
||||
mc.pos = &ship_objp->pos;
|
||||
mc.p0 = &weapon_objp->last_pos;
|
||||
mc.p1 = &weapon_end_pos;
|
||||
mc.lod = sip->collision_lod;
|
||||
memcpy(&mc_shield, &mc, sizeof(mc_info));
|
||||
memcpy(&mc_hull, &mc, sizeof(mc_info));
|
||||
|
||||
@@ -200,15 +201,16 @@ int ship_weapon_check_collision(object *ship_objp, object *weapon_objp, float ti
|
||||
// The weapon is not allowed to impact the shield before it reaches this point
|
||||
vec3d shield_ignored_until = weapon_objp->last_pos;
|
||||
|
||||
float min_weapon_span = sip->auto_shield_spread_min_span;
|
||||
float weapon_flown_for = vm_vec_dist(&wp->start_pos, &weapon_objp->last_pos);
|
||||
|
||||
// If weapon hasn't yet flown a distance greater than the maximum ignore
|
||||
// range, then some part of the currently checked range needs to be
|
||||
// ignored
|
||||
if (weapon_flown_for < sip->auto_shield_spread) {
|
||||
if (weapon_flown_for < min_weapon_span) {
|
||||
vm_vec_sub(&shield_ignored_until, &weapon_end_pos, &wp->start_pos);
|
||||
vm_vec_normalize(&shield_ignored_until);
|
||||
vm_vec_scale(&shield_ignored_until, sip->auto_shield_spread);
|
||||
vm_vec_scale(&shield_ignored_until, min_weapon_span);
|
||||
vm_vec_add2(&shield_ignored_until, &wp->start_pos);
|
||||
}
|
||||
|
||||
@@ -243,7 +245,7 @@ int ship_weapon_check_collision(object *ship_objp, object *weapon_objp, float ti
|
||||
// If no collision with the model found in the ignore range, only
|
||||
// then do we check for sphereline collisions with the model during the
|
||||
// non-ignored range
|
||||
if (!shield_collision && weapon_flown_for + this_range > sip->auto_shield_spread) {
|
||||
if (!shield_collision && weapon_flown_for + this_range > min_weapon_span) {
|
||||
mc_shield.p0 = &shield_ignored_until;
|
||||
|
||||
mc_shield.p1 = &weapon_end_pos;
|
||||
@@ -251,16 +253,14 @@ int ship_weapon_check_collision(object *ship_objp, object *weapon_objp, float ti
|
||||
mc_shield.radius = sip->auto_shield_spread;
|
||||
|
||||
if (sip->auto_shield_spread_from_lod > -1) {
|
||||
pm = model_get(sip->model_num);
|
||||
mc_shield.submodel_num = pm->detail[sip->auto_shield_spread_from_lod];
|
||||
|
||||
mc_shield.flags = MC_CHECK_MODEL | MC_SUBMODEL_INSTANCE | MC_CHECK_SPHERELINE;
|
||||
} else {
|
||||
mc_shield.flags = MC_CHECK_MODEL | MC_CHECK_SPHERELINE;
|
||||
mc_shield.lod = sip->auto_shield_spread_from_lod;
|
||||
}
|
||||
|
||||
mc_shield.flags = MC_CHECK_MODEL | MC_CHECK_SPHERELINE;
|
||||
|
||||
shield_collision = model_collide(&mc_shield);
|
||||
|
||||
mc_shield.lod = sip->collision_lod;
|
||||
mc_shield.submodel_num = -1;
|
||||
|
||||
// Because we manipulated p0 and p1 above, hit_dist will be
|
||||
@@ -407,6 +407,12 @@ int ship_weapon_check_collision(object *ship_objp, object *weapon_objp, float ti
|
||||
bool weapon_override = Script_system.IsConditionOverride(CHA_COLLIDESHIP, weapon_objp);
|
||||
|
||||
if(!ship_override && !weapon_override) {
|
||||
if (shield_collision && quadrant_num >= 0) {
|
||||
if ((sip->shield_impact_explosion_anim > -1) && (wip->shield_impact_explosion_radius > 0)) {
|
||||
// do in weapons.cpp for most parts just because that is how rest of the functions are handled
|
||||
shield_impact_explosion(&mc.hit_point, ship_objp, wip->shield_impact_explosion_radius, sip->shield_impact_explosion_anim);
|
||||
}
|
||||
}
|
||||
ship_weapon_do_hit_stuff(ship_objp, weapon_objp, &mc.hit_point_world, &mc.hit_point, quadrant_num, mc.hit_submodel, mc.hit_normal);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,10 +49,18 @@ void shield_add_strength(object *objp, float delta)
|
||||
if (delta == 0.0f)
|
||||
return;
|
||||
|
||||
|
||||
float shield_str = shield_get_strength(objp);
|
||||
float shield_recharge_limit = Ships[objp->instance].ship_max_shield_strength * Ships[objp->instance].max_shield_recharge;
|
||||
|
||||
if (shield_str >= shield_recharge_limit)
|
||||
return;
|
||||
|
||||
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
|
||||
{
|
||||
if ((delta > 0.0f) && ((shield_str + delta) > shield_recharge_limit))
|
||||
delta = shield_recharge_limit - shield_str;
|
||||
|
||||
for (int i = 0; i < objp->n_quadrants; i++)
|
||||
shield_add_quad(objp, i, delta / objp->n_quadrants);
|
||||
}
|
||||
@@ -81,7 +89,11 @@ void shield_add_strength(object *objp, float delta)
|
||||
// all quads are at full strength
|
||||
if (weakest >= section_max)
|
||||
break;
|
||||
|
||||
|
||||
// set the limit for the shield recharge
|
||||
if ((delta > 0.0f) && ((shield_str + delta) > shield_recharge_limit))
|
||||
delta = shield_recharge_limit - shield_str;
|
||||
|
||||
// throw all possible shield power at this quadrant
|
||||
// if there's any left over then apply it to the next weakest on the next pass
|
||||
float xfer_amount;
|
||||
|
||||
@@ -521,17 +521,24 @@ void obj_snd_do_frame()
|
||||
rot_vol_mult = 1.0f;
|
||||
alive_vol_mult = 1.0f;
|
||||
if ( objp->type == OBJ_SHIP ) {
|
||||
if ( !(Ship_info[Ships[objp->instance].ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP)) ) {
|
||||
ship_info *sip = &Ship_info[Ships[objp->instance].ship_info_index];
|
||||
if ( !(sip->flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP)) ) {
|
||||
if ( objp->phys_info.max_vel.xyz.z <= 0.0f ) {
|
||||
percent_max = 0.0f;
|
||||
}
|
||||
else
|
||||
percent_max = objp->phys_info.fspeed / objp->phys_info.max_vel.xyz.z;
|
||||
|
||||
if ( percent_max >= 0.5f )
|
||||
speed_vol_multiplier = 1.0f;
|
||||
else {
|
||||
speed_vol_multiplier = 0.5f + (percent_max); // linear interp: 0.5->1.0 when 0.0->0.5
|
||||
if ( sip->min_engine_vol == -1.0f) {
|
||||
// Retail behavior: volume ramps from 0.5 (when stationary) to 1.0 (when at half speed)
|
||||
if ( percent_max >= 0.5f ) {
|
||||
speed_vol_multiplier = 1.0f;
|
||||
} else {
|
||||
speed_vol_multiplier = 0.5f + (percent_max); // linear interp: 0.5->1.0 when 0.0->0.5
|
||||
}
|
||||
} else {
|
||||
// Volume ramps from min_engine_vol (when stationary) to 1.0 (when at full speed)
|
||||
speed_vol_multiplier = MAX(sip->min_engine_vol, percent_max);
|
||||
}
|
||||
}
|
||||
if (osp->ss != NULL)
|
||||
|
||||
@@ -35,7 +35,8 @@ void outwnd_print(const char *id = NULL, const char *temp = NULL);
|
||||
bool outwnd_inited = false;
|
||||
ubyte Outwnd_no_filter_file = 0; // 0 = .cfg file found, 1 = not found and warning not printed yet, 2 = not found and warning printed
|
||||
|
||||
struct outwnd_filter_struct {
|
||||
class outwnd_filter_struct {
|
||||
public:
|
||||
char name[NAME_LENGTH];
|
||||
bool enabled;
|
||||
|
||||
@@ -75,22 +76,16 @@ void load_filter_info(void)
|
||||
if (!fp) {
|
||||
Outwnd_no_filter_file = 1;
|
||||
|
||||
memset( &new_filter, 0, sizeof(outwnd_filter_struct) );
|
||||
strcpy_s( new_filter.name, "error" );
|
||||
new_filter.enabled = true;
|
||||
|
||||
OutwndFilter.push_back( new_filter );
|
||||
|
||||
memset( &new_filter, 0, sizeof(outwnd_filter_struct) );
|
||||
strcpy_s( new_filter.name, "general" );
|
||||
new_filter.enabled = true;
|
||||
|
||||
OutwndFilter.push_back( new_filter );
|
||||
|
||||
memset( &new_filter, 0, sizeof(outwnd_filter_struct) );
|
||||
strcpy_s( new_filter.name, "warning" );
|
||||
new_filter.enabled = true;
|
||||
|
||||
OutwndFilter.push_back( new_filter );
|
||||
|
||||
return;
|
||||
@@ -99,7 +94,6 @@ void load_filter_info(void)
|
||||
Outwnd_no_filter_file = 0;
|
||||
|
||||
while ( fgets(inbuf, NAME_LENGTH+3, fp) ) {
|
||||
memset( &new_filter, 0, sizeof(outwnd_filter_struct) );
|
||||
|
||||
if (*inbuf == '+')
|
||||
new_filter.enabled = true;
|
||||
|
||||
@@ -528,84 +528,6 @@ void palette_update(const char *name_with_extension, int restrict_font_to_128)
|
||||
}
|
||||
}
|
||||
|
||||
ubyte *palette_get_fade_table()
|
||||
{
|
||||
int i,l;
|
||||
|
||||
if ( palman_screen_signature != gr_screen.signature ) {
|
||||
palman_screen_signature = gr_screen.signature;
|
||||
palette_fade_table_calculated = 0;
|
||||
}
|
||||
|
||||
|
||||
if ( !palette_fade_table_calculated ) {
|
||||
//mprintf(( "Creating fading table..." ));
|
||||
|
||||
for (i=0; i<256; i++ ) {
|
||||
int r, g, b;
|
||||
int ur, ug, ub;
|
||||
r = gr_palette[i*3+0];
|
||||
g = gr_palette[i*3+1];
|
||||
b = gr_palette[i*3+2];
|
||||
|
||||
if ( palman_is_nondarkening(r,g,b)) {
|
||||
// Make pure white not fade
|
||||
for (l=0; l<32; l++ ) {
|
||||
gr_fade_table[((l+1)*256)+i] = (unsigned char)i;
|
||||
}
|
||||
} else {
|
||||
for (l=0; l<32; l++ ) {
|
||||
|
||||
if ( l < 24 ) {
|
||||
float f = (float)pow(i2fl(l)/23.0f, 1.0f/Gr_gamma);
|
||||
ur = fl2i(i2fl(r)*f); if ( ur > 255 ) ur = 255;
|
||||
ug = fl2i(i2fl(g)*f); if ( ug > 255 ) ug = 255;
|
||||
ub = fl2i(i2fl(b)*f); if ( ub > 255 ) ub = 255;
|
||||
} else {
|
||||
int x,y;
|
||||
int gi, gr, gg, gb;
|
||||
|
||||
gi = (r+g+b)/3;
|
||||
|
||||
#ifdef RGB_LIGHTING
|
||||
gr = r;
|
||||
gg = g;
|
||||
gb = gi*2;
|
||||
#else
|
||||
gr = r*2;
|
||||
gg = g*2;
|
||||
gb = b*2;
|
||||
#endif
|
||||
|
||||
x = l-24; // x goes from 0 to 7
|
||||
y = 31-l; // y goes from 7 to 0
|
||||
|
||||
ur = ((gr*x)+(r*y))/7; if ( ur > 255 ) ur = 255;
|
||||
ug = ((gg*x)+(g*y))/7; if ( ug > 255 ) ug = 255;
|
||||
ub = ((gb*x)+(b*y))/7; if ( ub > 255 ) ub = 255;
|
||||
}
|
||||
gr_fade_table[((l+1)*256)+i] = (unsigned char)palette_find( ur, ug, ub );
|
||||
|
||||
}
|
||||
}
|
||||
gr_fade_table[ (0*256)+i ] = gr_fade_table[ (1*256)+i ];
|
||||
gr_fade_table[ (33*256)+i ] = gr_fade_table[ (32*256)+i ];
|
||||
}
|
||||
|
||||
// Mirror the fade table
|
||||
for (i=0; i<34; i++ ) {
|
||||
for ( l = 0; l < 256; l++ ) {
|
||||
gr_fade_table[ ((67-i)*256)+l ] = gr_fade_table[ (i*256)+l ];
|
||||
}
|
||||
}
|
||||
|
||||
// mprintf(( "done\n" ));
|
||||
palette_fade_table_calculated = 1;
|
||||
}
|
||||
|
||||
return &gr_fade_table[0];
|
||||
}
|
||||
|
||||
|
||||
ubyte *palette_get_blend_table(float alpha)
|
||||
{
|
||||
|
||||
@@ -24,7 +24,6 @@ extern void palette_flush();
|
||||
// Functions to query a palette
|
||||
extern uint palette_compute_checksum( ubyte *pal ); // computes checksum of palette
|
||||
extern ubyte *palette_get_blend_table(float alpha);
|
||||
extern ubyte *palette_get_fade_table();
|
||||
|
||||
extern uint palette_find( int r, int g, int b );
|
||||
|
||||
|
||||
@@ -15614,6 +15614,29 @@ ADE_FUNC(getStack, l_Testing, NULL, "Generates an ADE stackdump", "string", "Cur
|
||||
return ade_set_args(L, "s", buf);
|
||||
}
|
||||
|
||||
ADE_FUNC(setCurrentPlayerMulti, l_Testing, "boolean", "Sets whether current player is a multiplayer pilot or not.", "boolean", "True if successful, false if not.")
|
||||
{
|
||||
bool multi;
|
||||
|
||||
if(!ade_get_args(L, "b", &multi))
|
||||
return ADE_RETURN_NIL;
|
||||
|
||||
if(Player == NULL)
|
||||
return ade_set_error(L, "b", false);
|
||||
|
||||
if (multi) {
|
||||
Game_mode &= ~GM_NORMAL;
|
||||
Game_mode |= GM_MULTIPLAYER;
|
||||
Player->flags |= PLAYER_FLAGS_IS_MULTI;
|
||||
} else {
|
||||
Game_mode &= ~GM_MULTIPLAYER;
|
||||
Game_mode |= GM_NORMAL;
|
||||
Player->flags &= ~PLAYER_FLAGS_IS_MULTI;
|
||||
}
|
||||
|
||||
return ADE_RETURN_TRUE;
|
||||
}
|
||||
|
||||
ADE_FUNC(isCurrentPlayerMulti, l_Testing, NULL, "Returns whether current player is a multiplayer pilot or not.", "boolean", "Whether current player is a multiplayer pilot or not")
|
||||
{
|
||||
if(Player == NULL)
|
||||
|
||||
+84
-62
@@ -4392,7 +4392,7 @@ int sexp_and(int n)
|
||||
if (CAR(n) != -1)
|
||||
{
|
||||
result &= is_sexp_true(CAR(n));
|
||||
if ( Sexp_nodes[CAR(n)].value == SEXP_KNOWN_FALSE )
|
||||
if ( Sexp_nodes[CAR(n)].value == SEXP_KNOWN_FALSE || Sexp_nodes[CAR(n)].value == SEXP_NAN_FOREVER )
|
||||
return SEXP_KNOWN_FALSE; // if one of the AND clauses is FALSE, whole clause is false
|
||||
if ( Sexp_nodes[CAR(n)].value != SEXP_KNOWN_TRUE ) // if the value is still unknown, they all can't be true
|
||||
all_true = 0;
|
||||
@@ -4406,7 +4406,7 @@ int sexp_and(int n)
|
||||
|
||||
new_result = is_sexp_true(CDR(n));
|
||||
result &= new_result;
|
||||
if ( Sexp_nodes[CDR(n)].value == SEXP_KNOWN_FALSE )
|
||||
if ( Sexp_nodes[CDR(n)].value == SEXP_KNOWN_FALSE || Sexp_nodes[CDR(n)].value == SEXP_NAN_FOREVER )
|
||||
return SEXP_KNOWN_FALSE; // if one of the AND clauses is FALSE, whole clause is false
|
||||
if ( Sexp_nodes[CDR(n)].value != SEXP_KNOWN_TRUE ) // if the value is still unknown, they all can't be true
|
||||
all_true = 0;
|
||||
@@ -4435,7 +4435,7 @@ int sexp_and_in_sequence(int n)
|
||||
if (CAR(n) != -1)
|
||||
{
|
||||
result &= is_sexp_true(CAR(n));
|
||||
if ( Sexp_nodes[CAR(n)].value == SEXP_KNOWN_FALSE )
|
||||
if ( Sexp_nodes[CAR(n)].value == SEXP_KNOWN_FALSE || Sexp_nodes[CAR(n)].value == SEXP_NAN_FOREVER )
|
||||
return SEXP_KNOWN_FALSE; // if one of the AND clauses is FALSE, whole clause is false
|
||||
if ( Sexp_nodes[CAR(n)].value != SEXP_KNOWN_TRUE ) // if value is true, mark our all_true variable for later checking
|
||||
all_true = 0;
|
||||
@@ -4458,7 +4458,7 @@ int sexp_and_in_sequence(int n)
|
||||
if ( next_result && !result ) // if current result is true, and our running result is false, thngs didn't become true in order
|
||||
return SEXP_KNOWN_FALSE;
|
||||
result &= next_result;
|
||||
if ( Sexp_nodes[CDR(n)].value == SEXP_KNOWN_FALSE )
|
||||
if ( Sexp_nodes[CDR(n)].value == SEXP_KNOWN_FALSE || Sexp_nodes[CDR(n)].value == SEXP_NAN_FOREVER )
|
||||
return SEXP_KNOWN_FALSE; // if one of the OR clauses is TRUE, whole clause is true
|
||||
if ( Sexp_nodes[CDR(n)].value != SEXP_KNOWN_TRUE ) // if the value is still unknown, they all can't be false
|
||||
all_true = 0;
|
||||
@@ -4490,14 +4490,12 @@ int sexp_not(int n)
|
||||
if (CAR(n) != -1)
|
||||
{
|
||||
result = is_sexp_true(CAR(n));
|
||||
if ( Sexp_nodes[CAR(n)].value == SEXP_KNOWN_FALSE )
|
||||
if ( Sexp_nodes[CAR(n)].value == SEXP_KNOWN_FALSE || Sexp_nodes[CDR(n)].value == SEXP_NAN_FOREVER )
|
||||
return SEXP_KNOWN_TRUE; // not KNOWN_FALSE == KNOWN_TRUE;
|
||||
else if ( Sexp_nodes[CAR(n)].value == SEXP_KNOWN_TRUE ) // not KNOWN_TRUE == KNOWN_FALSE
|
||||
return SEXP_KNOWN_FALSE;
|
||||
else if ( Sexp_nodes[CAR(n)].value == SEXP_NAN ) // not NAN == TRUE (I think)
|
||||
return SEXP_TRUE;
|
||||
else if ( Sexp_nodes[CAR(n)].value == SEXP_NAN_FOREVER )
|
||||
return SEXP_TRUE;
|
||||
}
|
||||
else
|
||||
result = atoi(CTEXT(n));
|
||||
@@ -6242,7 +6240,7 @@ int sexp_directive_value(int n)
|
||||
replace_current_value = eval_sexp(n);
|
||||
}
|
||||
|
||||
if ((replace_current_value == SEXP_KNOWN_FALSE) || (replace_current_value == SEXP_FALSE) ) {
|
||||
if (replace_current_value == SEXP_FALSE) { // note: any SEXP_KNOWN_FALSE result will return SEXP_FALSE
|
||||
Directive_count += directive_value;
|
||||
}
|
||||
else {
|
||||
@@ -8367,12 +8365,8 @@ int eval_perform_actions(int n)
|
||||
}
|
||||
|
||||
// return whatever val was, but don't return known-*
|
||||
if (val == SEXP_KNOWN_TRUE)
|
||||
return SEXP_TRUE;
|
||||
else if (val == SEXP_KNOWN_FALSE)
|
||||
return SEXP_FALSE;
|
||||
else
|
||||
return val;
|
||||
// note: SEXP_KNOWN_TRUE/SEXP_KNOWN_FALSE are never returned from eval_sexp
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8410,7 +8404,7 @@ int eval_when(int n, int when_op_num)
|
||||
|
||||
|
||||
// if value is true, perform the actions in the 'then' part
|
||||
if (val == SEXP_TRUE || val == SEXP_KNOWN_TRUE)
|
||||
if (val == SEXP_TRUE) // note: SEXP_KNOWN_TRUE is never returned from eval_sexp
|
||||
{
|
||||
// get the operator
|
||||
int exp = CAR(actions);
|
||||
@@ -8442,7 +8436,7 @@ int eval_when(int n, int when_op_num)
|
||||
}
|
||||
}
|
||||
// if-then-else has actions to perform under "else"
|
||||
else if ((val == SEXP_FALSE || val == SEXP_KNOWN_FALSE) && when_op_num == OP_IF_THEN_ELSE)
|
||||
else if (val == SEXP_FALSE && when_op_num == OP_IF_THEN_ELSE) // note: SEXP_KNOWN_FALSE is never returned from eval_sexp
|
||||
{
|
||||
// skip past the "if" action
|
||||
actions = CDR(actions);
|
||||
@@ -8460,10 +8454,8 @@ int eval_when(int n, int when_op_num)
|
||||
}
|
||||
|
||||
// invert val so that we behave like a when with opposite results
|
||||
if (val == SEXP_KNOWN_FALSE)
|
||||
val = SEXP_KNOWN_TRUE;
|
||||
else
|
||||
val = SEXP_TRUE;
|
||||
// note: SEXP_KNOWN_FALSE is never returned from eval_sexp
|
||||
val = SEXP_TRUE;
|
||||
}
|
||||
|
||||
if (is_blank_argument_op(when_op_num))
|
||||
@@ -8485,11 +8477,10 @@ int eval_when(int n, int when_op_num)
|
||||
// thanks to MageKing17 for noticing that we need to short-circuit on the correct node!
|
||||
int short_circuit_node = (arg_handler >= 0) ? arg_handler : cond;
|
||||
|
||||
if (Sexp_nodes[short_circuit_node].value == SEXP_KNOWN_FALSE)
|
||||
if (Sexp_nodes[short_circuit_node].value == SEXP_KNOWN_FALSE || Sexp_nodes[short_circuit_node].value == SEXP_NAN_FOREVER)
|
||||
return SEXP_KNOWN_FALSE; // no need to waste time on this anymore
|
||||
|
||||
if (val == SEXP_KNOWN_FALSE)
|
||||
return SEXP_FALSE; // can't return known false, as this would bypass future actions under the when
|
||||
// note: val can't be SEXP_KNOWN_FALSE at this point
|
||||
|
||||
return val;
|
||||
}
|
||||
@@ -8510,7 +8501,7 @@ int eval_cond(int n)
|
||||
|
||||
// if the conditional evaluated to true, then we must evaluate the rest of the expression returning
|
||||
// the value of this evaluation
|
||||
if (val == SEXP_TRUE || val == SEXP_KNOWN_TRUE)
|
||||
if (val == SEXP_TRUE) // note: any SEXP_KNOWN_TRUE result is returned as SEXP_TRUE
|
||||
{
|
||||
int actions, exp;
|
||||
|
||||
@@ -8566,6 +8557,13 @@ int test_argument_nodes_for_condition(int n, int condition_node, int *num_true,
|
||||
// evaluate conditional for current argument
|
||||
Sexp_replacement_arguments.push_back(Sexp_nodes[n].text);
|
||||
val = eval_sexp(condition_node);
|
||||
if ( Sexp_nodes[condition_node].value == SEXP_KNOWN_TRUE ||
|
||||
Sexp_nodes[condition_node].value == SEXP_KNOWN_FALSE) {
|
||||
val = Sexp_nodes[condition_node].value;
|
||||
} else if ( Sexp_nodes[condition_node].value == SEXP_NAN_FOREVER ) {
|
||||
// In accordance with SEXP_NAN/SEXP_NAN_FOREVER becoming SEXP_FALSE in eval_sexp()
|
||||
val = SEXP_KNOWN_FALSE;
|
||||
}
|
||||
|
||||
switch (val)
|
||||
{
|
||||
@@ -8640,6 +8638,13 @@ int test_argument_vector_for_condition(SCP_vector<char*> argument_vector, bool a
|
||||
// evaluate conditional for current argument
|
||||
Sexp_replacement_arguments.push_back(argument_vector[i]);
|
||||
val = eval_sexp(condition_node);
|
||||
if ( Sexp_nodes[condition_node].value == SEXP_KNOWN_TRUE ||
|
||||
Sexp_nodes[condition_node].value == SEXP_KNOWN_FALSE) {
|
||||
val = Sexp_nodes[condition_node].value;
|
||||
} else if ( Sexp_nodes[condition_node].value == SEXP_NAN_FOREVER ) {
|
||||
// In accordance with SEXP_NAN/SEXP_NAN_FOREVER becoming SEXP_FALSE in eval_sexp()
|
||||
val = SEXP_KNOWN_FALSE;
|
||||
}
|
||||
|
||||
switch (val)
|
||||
{
|
||||
@@ -8705,12 +8710,10 @@ int eval_any_of(int arg_handler_node, int condition_node)
|
||||
num_valid_arguments = test_argument_nodes_for_condition(n, condition_node, &num_true, &num_false, &num_known_true, &num_known_false);
|
||||
|
||||
// use the sexp_or algorithm
|
||||
if (num_known_true)
|
||||
return SEXP_KNOWN_TRUE;
|
||||
if (num_known_true || num_true)
|
||||
return SEXP_TRUE;
|
||||
else if (num_known_false == num_valid_arguments)
|
||||
return SEXP_KNOWN_FALSE;
|
||||
else if (num_true)
|
||||
return SEXP_TRUE;
|
||||
else
|
||||
return SEXP_FALSE;
|
||||
}
|
||||
@@ -8728,10 +8731,8 @@ int eval_every_of(int arg_handler_node, int condition_node)
|
||||
num_valid_arguments = test_argument_nodes_for_condition(n, condition_node, &num_true, &num_false, &num_known_true, &num_known_false);
|
||||
|
||||
// use the sexp_and algorithm
|
||||
if (num_known_false)
|
||||
if ((!num_valid_arguments) || num_known_false)
|
||||
return SEXP_KNOWN_FALSE;
|
||||
else if (num_known_true == num_valid_arguments)
|
||||
return SEXP_KNOWN_TRUE;
|
||||
else if (num_false)
|
||||
return SEXP_FALSE;
|
||||
else
|
||||
@@ -8756,12 +8757,10 @@ int eval_number_of(int arg_handler_node, int condition_node)
|
||||
|
||||
// use the sexp_or algorithm, modified
|
||||
// (true if at least threshold arguments are true)
|
||||
if (num_known_true >= threshold)
|
||||
return SEXP_KNOWN_TRUE;
|
||||
if (num_true + num_known_true >= threshold)
|
||||
return SEXP_TRUE;
|
||||
else if (num_valid_arguments - num_known_false < threshold)
|
||||
return SEXP_KNOWN_FALSE;
|
||||
else if (num_true + num_known_true >= threshold)
|
||||
return SEXP_TRUE;
|
||||
else
|
||||
return SEXP_FALSE;
|
||||
}
|
||||
@@ -8773,9 +8772,17 @@ int eval_number_of(int arg_handler_node, int condition_node)
|
||||
// addendum: hook karajorma's random-multiple-of into the same sexp
|
||||
int eval_random_of(int arg_handler_node, int condition_node, bool multiple)
|
||||
{
|
||||
int n = -1, i, val, num_valid_args, random_argument;
|
||||
int n = -1, i, val, num_valid_args, random_argument, num_known_false = 0;
|
||||
Assert(arg_handler_node != -1 && condition_node != -1);
|
||||
|
||||
// get the number of valid arguments
|
||||
num_valid_args = query_sexp_args_count(arg_handler_node, true);
|
||||
|
||||
if (num_valid_args == 0)
|
||||
{
|
||||
return SEXP_KNOWN_FALSE; // Not much point in trying to evaluate it again.
|
||||
}
|
||||
|
||||
// find which argument we picked, if we picked one
|
||||
if (!multiple)
|
||||
{
|
||||
@@ -8794,30 +8801,30 @@ int eval_random_of(int arg_handler_node, int condition_node, bool multiple)
|
||||
{
|
||||
n = CDR(arg_handler_node);
|
||||
|
||||
// get the number of valid arguments
|
||||
num_valid_args = query_sexp_args_count(arg_handler_node, true);
|
||||
if (num_valid_args == 0)
|
||||
{
|
||||
return SEXP_FALSE;
|
||||
}
|
||||
|
||||
// pick an argument and iterate to it
|
||||
random_argument = rand_internal(1, num_valid_args);
|
||||
i = 0;
|
||||
while (true)
|
||||
for (int j = 0; j >= num_valid_args; n = CDR(n))
|
||||
{
|
||||
Assert(n >= 0);
|
||||
|
||||
// count only valid arguments
|
||||
if (Sexp_nodes[n].flags & SNF_ARGUMENT_VALID)
|
||||
i++;
|
||||
if (Sexp_nodes[n].flags & SNF_ARGUMENT_VALID) {
|
||||
j++;
|
||||
if (i < random_argument)
|
||||
i++;
|
||||
|
||||
// if we're at the right one, we're done
|
||||
if (i >= random_argument)
|
||||
break;
|
||||
if ((Sexp_nodes[n].value == SEXP_KNOWN_FALSE) || (Sexp_nodes[n].value == SEXP_NAN_FOREVER))
|
||||
num_known_false++;
|
||||
|
||||
// iterate
|
||||
n = CDR(n);
|
||||
// if we're out of valid arguments, we're done
|
||||
if (j >= num_valid_args)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_known_false == num_valid_args) {
|
||||
return SEXP_KNOWN_FALSE; // We're going nowhere fast.
|
||||
}
|
||||
|
||||
// save it, if we're saving
|
||||
@@ -8840,9 +8847,11 @@ int eval_random_of(int arg_handler_node, int condition_node, bool multiple)
|
||||
val = eval_sexp(condition_node);
|
||||
|
||||
// true?
|
||||
if (val == SEXP_TRUE || val == SEXP_KNOWN_TRUE)
|
||||
if (val == SEXP_TRUE)
|
||||
{
|
||||
Sexp_applicable_argument_list.add_data(Sexp_nodes[n].text);
|
||||
} else if ((!multiple || num_valid_args == 1) && (Sexp_nodes[condition_node].value == SEXP_KNOWN_FALSE || Sexp_nodes[condition_node].value == SEXP_NAN_FOREVER)) {
|
||||
val = SEXP_KNOWN_FALSE; // If we can't randomly pick another one and this one is guaranteed never to be true, then give up now.
|
||||
}
|
||||
|
||||
// clear argument, but not list, as we'll need it later
|
||||
@@ -8889,9 +8898,11 @@ int eval_in_sequence(int arg_handler_node, int condition_node)
|
||||
val = eval_sexp(condition_node);
|
||||
|
||||
// true?
|
||||
if (val == SEXP_TRUE || val == SEXP_KNOWN_TRUE)
|
||||
if (val == SEXP_TRUE)
|
||||
{
|
||||
Sexp_applicable_argument_list.add_data(Sexp_nodes[n].text);
|
||||
} else if ((Sexp_nodes[condition_node].value == SEXP_KNOWN_FALSE) || (Sexp_nodes[condition_node].value == SEXP_NAN_FOREVER)) {
|
||||
val = SEXP_KNOWN_FALSE; // If we're wasting our time evaluating this ever again, just go ahead and short-circuit.
|
||||
}
|
||||
|
||||
// clear argument, but not list, as we'll need it later
|
||||
@@ -8951,19 +8962,22 @@ int eval_for_counter(int arg_handler_node, int condition_node)
|
||||
for (i = counter_start; ((counter_step > 0) ? i <= counter_stop : i >= counter_stop); i += counter_step)
|
||||
{
|
||||
sprintf(buf, "%d", i);
|
||||
argument_vector.push_back(strdup(buf));
|
||||
argument_vector.push_back(vm_strdup(buf));
|
||||
}
|
||||
|
||||
// test the whole argument vector
|
||||
num_valid_arguments = test_argument_vector_for_condition(argument_vector, true, condition_node, &num_true, &num_false, &num_known_true, &num_known_false);
|
||||
|
||||
while (!argument_vector.empty()) {
|
||||
vm_free(argument_vector.back());
|
||||
argument_vector.pop_back();
|
||||
}
|
||||
|
||||
// use the sexp_or algorithm
|
||||
if (num_known_true)
|
||||
return SEXP_KNOWN_TRUE;
|
||||
if (num_known_true || num_true)
|
||||
return SEXP_TRUE;
|
||||
else if (num_known_false == num_valid_arguments)
|
||||
return SEXP_KNOWN_FALSE;
|
||||
else if (num_true)
|
||||
return SEXP_TRUE;
|
||||
else
|
||||
return SEXP_FALSE;
|
||||
}
|
||||
@@ -16541,6 +16555,7 @@ void parse_copy_damage(p_object *target_pobjp, ship *source_shipp)
|
||||
// ...and shields
|
||||
target_pobjp->ship_max_shield_strength = source_shipp->ship_max_shield_strength;
|
||||
target_pobjp->initial_shields = fl2i(get_shield_pct(source_objp) * 100.0f);
|
||||
target_pobjp->max_shield_recharge = source_shipp->max_shield_recharge;
|
||||
|
||||
|
||||
// search through all subsystems on source ship and map them onto target ship
|
||||
@@ -22216,7 +22231,7 @@ int is_sexp_true(int cur_node, int referenced_node)
|
||||
{
|
||||
int result = eval_sexp(cur_node, referenced_node);
|
||||
|
||||
return ((result == SEXP_TRUE) || (result == SEXP_KNOWN_TRUE));
|
||||
return (result == SEXP_TRUE); // note: any SEXP_KNOWN_TRUE result will return SEXP_TRUE
|
||||
}
|
||||
|
||||
|
||||
@@ -22466,7 +22481,13 @@ int eval_sexp(int cur_node, int referenced_node)
|
||||
add_to_event_log_buffer(get_operator_index(cur_node), SEXP_KNOWN_FALSE);
|
||||
}
|
||||
return SEXP_FALSE;
|
||||
}
|
||||
}
|
||||
else if (Sexp_nodes[cur_node].value == SEXP_NAN_FOREVER) {
|
||||
if (Log_event) {
|
||||
add_to_event_log_buffer(get_operator_index(cur_node), SEXP_NAN_FOREVER);
|
||||
}
|
||||
return SEXP_FALSE;
|
||||
}
|
||||
|
||||
if (Sexp_nodes[cur_node].first != -1) {
|
||||
node = CAR(cur_node);
|
||||
@@ -24647,7 +24668,7 @@ int eval_sexp(int cur_node, int referenced_node)
|
||||
|
||||
// if we haven't returned, check the sexp value of the sexpression evaluation. A special
|
||||
// value of known true or known false means that we should set the sexp.value field for
|
||||
// short circuit eval (and return that special value as well).
|
||||
// short circuit eval.
|
||||
if (sexp_val == SEXP_KNOWN_TRUE) {
|
||||
Sexp_nodes[cur_node].value = SEXP_KNOWN_TRUE;
|
||||
return SEXP_TRUE;
|
||||
@@ -31465,7 +31486,8 @@ sexp_help_struct Sexp_help[] = {
|
||||
"friendly-stealth-invisible - If set, the ship can't be targeted even by ships on the same team\r\n"
|
||||
"hide-ship-name - If set, the ship name can't be seen when the ship is targeted\r\n"
|
||||
"hidden-from-sensors - If set, the ship can't be targeted and appears on radar as a blinking dot\r\n"
|
||||
"no-dynamic - Will stop allowing the AI to persue dynamic goals (eg: chasing ships it was not ordered to)\r\n"},
|
||||
"no-dynamic - Will stop allowing the AI to persue dynamic goals (eg: chasing ships it was not ordered to)\r\n"
|
||||
"no-secondary-lock-on - Will disable target acquisition for secondaries of all types (does not affect turrets)\r\n"},
|
||||
|
||||
{ OP_SHIP_VISIBLE, "ship-visible\r\n"
|
||||
"\tCauses the ships listed in this sexpression to be visible with player sensors.\r\n\r\n"
|
||||
|
||||
@@ -101,6 +101,10 @@ void init_new_pilot(player *p, int reset)
|
||||
Mouse_sensitivity = 4;
|
||||
Joy_sensitivity = 9;
|
||||
Dead_zone_size = 10;
|
||||
|
||||
Master_sound_volume = Default_sound_volume;
|
||||
Master_event_music_volume = Default_music_volume;
|
||||
Master_voice_volume = Default_voice_volume;
|
||||
}
|
||||
|
||||
// unassigned squadron
|
||||
|
||||
@@ -637,22 +637,22 @@ void read_keyboard_controls( control_info * ci, float frame_time, physics_info *
|
||||
if (Axis_map_to[JOY_HEADING_AXIS] >= 0) {
|
||||
// check the heading on the x axis
|
||||
if ( check_control(BANK_WHEN_PRESSED) ) {
|
||||
delta = f2fl( axis[JOY_HEADING_AXIS] );
|
||||
delta = f2fl( axis[Axis_map_to[JOY_HEADING_AXIS]] );
|
||||
if ( (delta > 0.05f) || (delta < -0.05f) ) {
|
||||
ci->bank -= delta;
|
||||
}
|
||||
} else {
|
||||
ci->heading += f2fl( axis[JOY_HEADING_AXIS] );
|
||||
ci->heading += f2fl( axis[Axis_map_to[JOY_HEADING_AXIS]] );
|
||||
}
|
||||
}
|
||||
|
||||
// check the pitch on the y axis
|
||||
if (Axis_map_to[JOY_PITCH_AXIS] >= 0) {
|
||||
ci->pitch -= f2fl( axis[JOY_PITCH_AXIS] );
|
||||
ci->pitch -= f2fl( axis[Axis_map_to[JOY_PITCH_AXIS]] );
|
||||
}
|
||||
|
||||
if (Axis_map_to[JOY_BANK_AXIS] >= 0) {
|
||||
ci->bank -= f2fl( axis[JOY_BANK_AXIS] ) * 1.5f;
|
||||
ci->bank -= f2fl( axis[Axis_map_to[JOY_BANK_AXIS]] ) * 1.5f;
|
||||
}
|
||||
|
||||
// axis 2 is for throttle
|
||||
|
||||
+239
-53
@@ -312,6 +312,7 @@ flag_def_list Ship_flags[] = {
|
||||
{ "no lighting", SIF2_NO_LIGHTING, 1 },
|
||||
{ "auto spread shields", SIF2_AUTO_SPREAD_SHIELDS, 1 },
|
||||
{ "model point shields", SIF2_MODEL_POINT_SHIELDS, 1 },
|
||||
{ "lock detail boxes", SIF2_LOCK_DETAIL_BOXES, 1 },
|
||||
|
||||
// to keep things clean, obsolete options go last
|
||||
{ "ballistic primaries", -1, 255 }
|
||||
@@ -385,6 +386,7 @@ ship_flag_name Ship_flag_names[] = {
|
||||
{SF2_DONT_COLLIDE_INVIS, "don't-collide-invisible", 2, },
|
||||
{SF2_NO_ETS, "no-ets", 2, },
|
||||
{SF2_TOGGLE_SUBSYSTEM_SCANNING, "toggle-subsystem-scanning", 2, },
|
||||
{SF2_NO_SECONDARY_LOCKON, "no-secondary-lock-on", 2, },
|
||||
};
|
||||
|
||||
const int num_ai_tgt_weapon_flags = sizeof(ai_tgt_weapon_flags) / sizeof(flag_def_list);
|
||||
@@ -690,6 +692,7 @@ void init_ship_entry(ship_info *sip)
|
||||
sip->pof_file_hud[0] = '\0';
|
||||
sip->num_detail_levels = 1;
|
||||
sip->detail_distance[0] = 0;
|
||||
sip->collision_lod = -1;
|
||||
sip->cockpit_model_num = -1;
|
||||
sip->model_num = -1;
|
||||
sip->model_num_hud = -1;
|
||||
@@ -862,12 +865,17 @@ void init_ship_entry(ship_info *sip)
|
||||
|
||||
sip->weapon_model_draw_distance = 200.0f;
|
||||
|
||||
sip->ship_recoil_modifier = 1.0f;
|
||||
|
||||
sip->max_hull_strength = 100.0f;
|
||||
sip->max_shield_strength = 0.0f;
|
||||
|
||||
sip->max_shield_recharge = 1.0f;
|
||||
|
||||
sip->auto_shield_spread = 0.0f;
|
||||
sip->auto_shield_spread_bypass = false;
|
||||
sip->auto_shield_spread_from_lod = -1;
|
||||
sip->auto_shield_spread_min_span = -1.0f;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
@@ -948,6 +956,7 @@ void init_ship_entry(ship_info *sip)
|
||||
sip->thruster02_glow_len_factor = 1.0f;
|
||||
sip->thruster_dist_rad_factor = 2.0f;
|
||||
sip->thruster_dist_len_factor = 2.0f;
|
||||
sip->thruster_glow_noise_mult = 1.0f;
|
||||
|
||||
sip->draw_distortion = true;
|
||||
|
||||
@@ -967,11 +976,14 @@ void init_ship_entry(ship_info *sip)
|
||||
sip->newtonian_damp_override = false;
|
||||
|
||||
sip->autoaim_fov = 0.0f;
|
||||
sip->autoaim_lock_snd = -1;
|
||||
sip->autoaim_lost_snd = -1;
|
||||
|
||||
sip->topdown_offset_def = false;
|
||||
vm_vec_zero(&sip->topdown_offset);
|
||||
|
||||
sip->engine_snd = -1;
|
||||
sip->min_engine_vol = -1.0f;
|
||||
sip->glide_start_snd = -1;
|
||||
sip->glide_end_snd = -1;
|
||||
|
||||
@@ -1009,6 +1021,7 @@ void init_ship_entry(ship_info *sip)
|
||||
|
||||
sip->damage_lightning_type = SLT_DEFAULT;
|
||||
|
||||
sip->shield_impact_explosion_anim = -1;
|
||||
sip->hud_gauges.clear();
|
||||
sip->hud_enabled = false;
|
||||
sip->hud_retail = false;
|
||||
@@ -1420,11 +1433,10 @@ int parse_ship_values(ship_info* sip, bool first_time, bool replace)
|
||||
stuff_string(sip->short_name, F_NAME, NAME_LENGTH);
|
||||
else if(first_time)
|
||||
{
|
||||
char *srcpos, *srcend, *destpos, *destend;
|
||||
char *srcpos, *srcend, *destpos;
|
||||
srcpos = sip->name;
|
||||
destpos = sip->short_name;
|
||||
srcend = srcpos + strlen(sip->name);
|
||||
destend = destpos + sizeof(sip->short_name) - 1;
|
||||
while(srcpos < srcend)
|
||||
{
|
||||
if(*srcpos != ' ')
|
||||
@@ -1664,6 +1676,13 @@ int parse_ship_values(ship_info* sip, bool first_time, bool replace)
|
||||
sip->num_detail_levels = stuff_int_list(sip->detail_distance, MAX_SHIP_DETAIL_LEVELS, RAW_INTEGER_TYPE);
|
||||
}
|
||||
|
||||
if(optional_string("$Collision LOD:")) {
|
||||
stuff_int(&sip->collision_lod);
|
||||
|
||||
// Cap to sane values, just in case
|
||||
sip->collision_lod = MAX(0, MIN(sip->collision_lod, sip->num_detail_levels));
|
||||
}
|
||||
|
||||
// check for optional pixel colors
|
||||
while(optional_string("$ND:")){
|
||||
ubyte nr, ng, nb;
|
||||
@@ -2000,6 +2019,9 @@ int parse_ship_values(ship_info* sip, bool first_time, bool replace)
|
||||
|
||||
if(optional_string("+Minimum Distance:"))
|
||||
stuff_float(&sip->minimum_convergence_distance);
|
||||
|
||||
parse_sound("+Autoaim Lock Snd:", &sip->autoaim_lock_snd, sip->name);
|
||||
parse_sound("+Autoaim Lost Snd:", &sip->autoaim_lost_snd, sip->name);
|
||||
}
|
||||
|
||||
if(optional_string("$Convergence:"))
|
||||
@@ -2300,12 +2322,21 @@ int parse_ship_values(ship_info* sip, bool first_time, bool replace)
|
||||
stuff_bool_list(sip->draw_secondary_models, sip->num_secondary_banks);
|
||||
}
|
||||
|
||||
if (optional_string("$Ship Recoil Modifier:")){
|
||||
stuff_float(&sip->ship_recoil_modifier);
|
||||
}
|
||||
|
||||
if(optional_string("$Shields:")) {
|
||||
stuff_float(&sip->max_shield_strength);
|
||||
|
||||
if(optional_string("+Auto Spread:")) {
|
||||
stuff_float(&sip->auto_shield_spread);
|
||||
}
|
||||
if(optional_string("+Minimum Weapon Span:")) {
|
||||
stuff_float(&sip->auto_shield_spread_min_span);
|
||||
} else {
|
||||
sip->auto_shield_spread_min_span = sip->auto_shield_spread;
|
||||
}
|
||||
if(optional_string("+Allow Bypass:")) {
|
||||
stuff_boolean(&sip->auto_shield_spread_bypass);
|
||||
}
|
||||
@@ -2355,6 +2386,19 @@ int parse_ship_values(ship_info* sip, bool first_time, bool replace)
|
||||
stuff_ubyte(&sip->shield_color[2]);
|
||||
}
|
||||
|
||||
if(optional_string("$Shield Impact Explosion:")) {
|
||||
char fname[MAX_NAME_LEN];
|
||||
stuff_string(fname, F_NAME, NAME_LENGTH);
|
||||
|
||||
if ( VALID_FNAME(fname) )
|
||||
sip->shield_impact_explosion_anim = Weapon_explosions.Load(fname);
|
||||
}
|
||||
|
||||
if(optional_string("$Max Shield Recharge:")){
|
||||
stuff_float(&sip->max_shield_recharge);
|
||||
CLAMP(sip->max_shield_recharge, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
// The next five fields are used for the ETS
|
||||
if (optional_string("$Power Output:"))
|
||||
stuff_float(&sip->power_output);
|
||||
@@ -2660,6 +2704,9 @@ int parse_ship_values(ship_info* sip, bool first_time, bool replace)
|
||||
//Parse the engine sound
|
||||
parse_sound("$EngineSnd:", &sip->engine_snd, sip->name);
|
||||
|
||||
if(optional_string("$Minimum Engine Volume:"))
|
||||
stuff_float(&sip->min_engine_vol);
|
||||
|
||||
//Parse optional sound to be used for beginning of a glide
|
||||
parse_sound("$GlideStartSnd:", &sip->glide_start_snd, sip->name);
|
||||
|
||||
@@ -2716,6 +2763,32 @@ int parse_ship_values(ship_info* sip, bool first_time, bool replace)
|
||||
stuff_string(sip->icon_filename, F_NAME, MAX_FILENAME_LEN);
|
||||
}
|
||||
|
||||
if ( optional_string("$Model Icon Direction:") ) {
|
||||
char str[NAME_LENGTH];
|
||||
stuff_string(str, F_NAME, NAME_LENGTH);
|
||||
|
||||
angles model_icon_angles = {0.0f,0.0f,0.0f};
|
||||
|
||||
if (!stricmp(str, "top")) {
|
||||
model_icon_angles.p = -PI_2;
|
||||
} else if (!stricmp(str, "bottom")) {
|
||||
model_icon_angles.p = -PI_2;
|
||||
model_icon_angles.b = 2 * PI_2;
|
||||
} else if (!stricmp(str, "front")) {
|
||||
model_icon_angles.h = 2 * PI_2;
|
||||
} else if (!stricmp(str, "back")) {
|
||||
model_icon_angles.h = 4 * PI_2;
|
||||
} else if (!stricmp(str, "left")) {
|
||||
model_icon_angles.h = -PI_2;
|
||||
} else if (!stricmp(str, "right")) {
|
||||
model_icon_angles.h = PI_2;
|
||||
} else {
|
||||
Warning(LOCATION, "Unrecognized value \"%s\" passed to $Model Icon Direction, ignoring...", str);
|
||||
}
|
||||
|
||||
sip->model_icon_angles = model_icon_angles;
|
||||
}
|
||||
|
||||
// read in filename for animation that is used in ship selection
|
||||
if ( optional_string("$Ship_anim:") ) {
|
||||
stuff_string(sip->anim_filename, F_NAME, MAX_FILENAME_LEN);
|
||||
@@ -2865,6 +2938,10 @@ int parse_ship_values(ship_info* sip, bool first_time, bool replace)
|
||||
stuff_boolean(&sip->draw_distortion);
|
||||
}
|
||||
|
||||
if ( optional_string("$Thruster Glow Noise Mult:") ) {
|
||||
stuff_float(&sip->thruster_glow_noise_mult);
|
||||
}
|
||||
|
||||
while ( optional_string("$Thruster Particles:") ) {
|
||||
bool afterburner = false;
|
||||
thruster_particles tpart;
|
||||
@@ -3139,6 +3216,15 @@ int parse_ship_values(ship_info* sip, bool first_time, bool replace)
|
||||
stuff_vec3d(&metadata.departure_rvec);
|
||||
}
|
||||
|
||||
if (optional_string("+arrive speed multiplier:"))
|
||||
{
|
||||
stuff_float(&metadata.arrive_speed_mult);
|
||||
}
|
||||
if (optional_string("+depart speed multiplier:"))
|
||||
{
|
||||
stuff_float(&metadata.depart_speed_mult);
|
||||
}
|
||||
|
||||
//Add the new path_metadata to sip->pathMetadata keyed by path name
|
||||
SCP_string pathName(path_name);
|
||||
sip->pathMetadata[pathName] = metadata;
|
||||
@@ -5020,12 +5106,14 @@ void ship_set(int ship_index, int objnum, int ship_type)
|
||||
}
|
||||
objp->hull_strength = shipp->ship_max_hull_strength;
|
||||
|
||||
shipp->max_shield_recharge = sip->max_shield_recharge;
|
||||
|
||||
if (Fred_running) {
|
||||
shipp->ship_max_shield_strength = 100.0f;
|
||||
objp->shield_quadrant[0] = 100.0f;
|
||||
} else {
|
||||
shipp->ship_max_shield_strength = sip->max_shield_strength;
|
||||
shield_set_strength(objp, shipp->ship_max_shield_strength);
|
||||
shield_set_strength(objp, shipp->ship_max_shield_strength * shipp->max_shield_recharge);
|
||||
}
|
||||
|
||||
if (sip->flags2 & SIF2_MODEL_POINT_SHIELDS) {
|
||||
@@ -6106,7 +6194,7 @@ void ship_render(object * obj)
|
||||
mst.distortion_bitmap = shipp->thruster_distortion_bitmap;
|
||||
|
||||
mst.use_ab = (obj->phys_info.flags & PF_AFTERBURNER_ON) || (obj->phys_info.flags & PF_BOOSTER_ON);
|
||||
mst.glow_noise = shipp->thruster_glow_noise;
|
||||
mst.glow_noise = shipp->thruster_glow_noise * sip->thruster_glow_noise_mult;
|
||||
mst.rotvel = &Objects[shipp->objnum].phys_info.rotvel;
|
||||
|
||||
mst.glow_rad_factor = sip->thruster01_glow_rad_factor;
|
||||
@@ -6510,7 +6598,7 @@ void ship_add_cockpit_display(cockpit_display_info *display, int cockpit_model_n
|
||||
return;
|
||||
}
|
||||
|
||||
int i, tm_num, diffuse_target = -1, glow_target = -1, glow_handle = -1, diffuse_handle = -1;
|
||||
int i, tm_num, glow_target = -1, glow_handle = -1, diffuse_handle = -1;
|
||||
int w, h;
|
||||
cockpit_display new_display;
|
||||
|
||||
@@ -6521,7 +6609,6 @@ void ship_add_cockpit_display(cockpit_display_info *display, int cockpit_model_n
|
||||
{
|
||||
tm_num = pm->maps[i].FindTexture(display->filename);
|
||||
if ( tm_num >= 0 ) {
|
||||
diffuse_target = i*TM_NUM_TYPES;
|
||||
glow_target = i*TM_NUM_TYPES+TM_GLOW_TYPE;
|
||||
|
||||
diffuse_handle = pm->maps[i].textures[TM_BASE_TYPE].GetTexture();
|
||||
@@ -6680,7 +6767,7 @@ void ship_subsystems_delete(ship *shipp)
|
||||
void ship_delete( object * obj )
|
||||
{
|
||||
ship *shipp;
|
||||
int num, objnum;
|
||||
int num, objnum __attribute__((__unused__));
|
||||
|
||||
num = obj->instance;
|
||||
Assert( num >= 0);
|
||||
@@ -6853,24 +6940,24 @@ void ship_actually_depart(int shipnum, int method)
|
||||
}
|
||||
|
||||
// no destruction effects, not for player destruction and multiplayer, only self-destruction
|
||||
void ship_destroy_instantly(object *ship_obj, int shipnum)
|
||||
void ship_destroy_instantly(object *ship_objp, int shipnum)
|
||||
{
|
||||
Assert(ship_obj->type == OBJ_SHIP);
|
||||
Assert(!(ship_obj == Player_obj));
|
||||
Assert(ship_objp->type == OBJ_SHIP);
|
||||
Assert(!(ship_objp == Player_obj));
|
||||
Assert(!(Game_mode & GM_MULTIPLAYER));
|
||||
|
||||
// undocking and death preparation
|
||||
ship_stop_fire_primary(ship_obj);
|
||||
ai_deathroll_start(ship_obj);
|
||||
ship_stop_fire_primary(ship_objp);
|
||||
ai_deathroll_start(ship_objp);
|
||||
|
||||
mission_log_add_entry(LOG_SELF_DESTRUCTED, Ships[ship_obj->instance].ship_name, NULL );
|
||||
mission_log_add_entry(LOG_SELF_DESTRUCTED, Ships[ship_objp->instance].ship_name, NULL );
|
||||
|
||||
// scripting stuff
|
||||
Script_system.SetHookObject("Self", ship_obj);
|
||||
Script_system.RunCondition(CHA_DEATH, 0, NULL, ship_obj);
|
||||
Script_system.SetHookObject("Self", ship_objp);
|
||||
Script_system.RunCondition(CHA_DEATH, 0, NULL, ship_objp);
|
||||
Script_system.RemHookVars(2, "Self", "Killer");
|
||||
|
||||
ship_obj->flags |= OF_SHOULD_BE_DEAD;
|
||||
ship_objp->flags |= OF_SHOULD_BE_DEAD;
|
||||
ship_cleanup(shipnum,SHIP_DESTROYED);
|
||||
}
|
||||
|
||||
@@ -9185,6 +9272,8 @@ void change_ship_type(int n, int ship_type, int by_sexp)
|
||||
objp->hull_strength = hull_pct * sp->ship_max_hull_strength;
|
||||
}
|
||||
|
||||
sp->max_shield_recharge = sip->max_shield_recharge;
|
||||
|
||||
// set the correct shield strength
|
||||
if (Fred_running) {
|
||||
if (sp->ship_max_shield_strength)
|
||||
@@ -9561,8 +9650,12 @@ int ship_launch_countermeasure(object *objp, int rand_val)
|
||||
// if we have a player ship, then send the fired packet anyway so that the player
|
||||
// who fired will get his 'out of countermeasures' sound
|
||||
cmeasure_count = 0;
|
||||
if ( objp->flags & OF_PLAYER_SHIP ){
|
||||
goto send_countermeasure_fired;
|
||||
if (objp->flags & OF_PLAYER_SHIP){
|
||||
// the new way of doing things
|
||||
if (Game_mode & GM_MULTIPLAYER){
|
||||
send_NEW_countermeasure_fired_packet(objp, cmeasure_count, -1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -9585,10 +9678,9 @@ int ship_launch_countermeasure(object *objp, int rand_val)
|
||||
snd_play_3d( &Snds[Weapon_info[shipp->current_cmeasure].launch_snd], &pos, &View_position );
|
||||
}
|
||||
|
||||
send_countermeasure_fired:
|
||||
// the new way of doing things
|
||||
if(Game_mode & GM_MULTIPLAYER){
|
||||
send_NEW_countermeasure_fired_packet( objp, cmeasure_count, /*arand*/Objects[cobjnum].net_signature );
|
||||
send_NEW_countermeasure_fired_packet(objp, cmeasure_count, Objects[cobjnum].net_signature);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9828,6 +9920,70 @@ int tracers[MAX_SHIPS][4][4];
|
||||
|
||||
float ship_get_subsystem_strength( ship *shipp, int type );
|
||||
|
||||
/**
|
||||
* Checks whether a ship would use autoaim if it were to fire its primaries at
|
||||
* the given object, taking lead into account.
|
||||
*
|
||||
* @param shipp the ship to check
|
||||
* @param bank_to_fire the assumed primary bank
|
||||
* @param obj the object to check; must be the ship's current target
|
||||
*/
|
||||
|
||||
bool in_autoaim_fov(ship *shipp, int bank_to_fire, object *obj)
|
||||
{
|
||||
// Most of the code of this function has been duplicated from
|
||||
// ship_fire_primary(), because it is not easy to encapsulate cleanly.
|
||||
|
||||
ship_info *sip;
|
||||
ai_info *aip;
|
||||
ship_weapon *swp;
|
||||
|
||||
bool has_autoaim, has_converging_autoaim;
|
||||
float autoaim_fov = 0;
|
||||
float dist_to_target = 0;
|
||||
|
||||
vec3d plr_to_target_vec;
|
||||
vec3d player_forward_vec = Objects[shipp->objnum].orient.vec.fvec;
|
||||
|
||||
vec3d target_position;
|
||||
|
||||
sip = &Ship_info[shipp->ship_info_index];
|
||||
aip = &Ai_info[shipp->ai_index];
|
||||
|
||||
swp = &shipp->weapons;
|
||||
int weapon = swp->primary_bank_weapons[bank_to_fire];
|
||||
weapon_info* winfo_p = &Weapon_info[weapon];
|
||||
|
||||
has_converging_autoaim = ((sip->aiming_flags & AIM_FLAG_AUTOAIM_CONVERGENCE || (The_mission.ai_profile->player_autoaim_fov[Game_skill_level] > 0.0f && !( Game_mode & GM_MULTIPLAYER ))) && aip->target_objnum != -1);
|
||||
has_autoaim = ((has_converging_autoaim || (sip->aiming_flags & AIM_FLAG_AUTOAIM)) && aip->target_objnum != -1);
|
||||
|
||||
if (!has_autoaim)
|
||||
return FALSE;
|
||||
|
||||
autoaim_fov = MAX(shipp->autoaim_fov, The_mission.ai_profile->player_autoaim_fov[Game_skill_level]);
|
||||
|
||||
if (aip->targeted_subsys != NULL)
|
||||
{
|
||||
get_subsystem_world_pos(&Objects[aip->target_objnum], aip->targeted_subsys, &target_position);
|
||||
}
|
||||
else
|
||||
{
|
||||
target_position = obj->pos;
|
||||
}
|
||||
|
||||
dist_to_target = vm_vec_dist_quick(&Objects[shipp->objnum].pos, &target_position);
|
||||
|
||||
hud_calculate_lead_pos(&plr_to_target_vec, &target_position, obj, winfo_p, dist_to_target);
|
||||
vm_vec_sub2(&plr_to_target_vec, &Objects[shipp->objnum].pos);
|
||||
|
||||
float angle_to_target = vm_vec_delta_ang(&player_forward_vec, &plr_to_target_vec, NULL);
|
||||
|
||||
if (angle_to_target <= autoaim_fov)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// fires a primary weapon for the given object. It also handles multiplayer cases.
|
||||
// in multiplayer, the starting network signature, and number of banks fired are sent
|
||||
// to all the clients in the game. All the info is passed to send_primary at the end of
|
||||
@@ -9842,7 +9998,7 @@ int ship_fire_primary(object * obj, int stream_weapons, int force)
|
||||
ship_weapon *swp;
|
||||
ship_info *sip;
|
||||
ai_info *aip;
|
||||
int weapon, i, j, w, v, weapon_objnum;
|
||||
int weapon_idx, i, j, w, v, weapon_objnum;
|
||||
int bank_to_fire, num_fired = 0;
|
||||
int banks_fired; // used for multiplayer to help determine whether or not to send packet
|
||||
banks_fired = 0; // used in multiplayer -- bitfield of banks that were fired
|
||||
@@ -9953,9 +10109,9 @@ int ship_fire_primary(object * obj, int stream_weapons, int force)
|
||||
bank_to_fire = (swp->current_primary_bank+i) % swp->num_primary_banks;
|
||||
|
||||
|
||||
weapon = swp->primary_bank_weapons[bank_to_fire];
|
||||
Assert( weapon >= 0 && weapon < MAX_WEAPON_TYPES );
|
||||
if ( (weapon < 0) || (weapon >= MAX_WEAPON_TYPES) ) {
|
||||
weapon_idx = swp->primary_bank_weapons[bank_to_fire];
|
||||
Assert( weapon_idx >= 0 && weapon_idx < MAX_WEAPON_TYPES );
|
||||
if ( (weapon_idx < 0) || (weapon_idx >= MAX_WEAPON_TYPES) ) {
|
||||
Int3(); // why would a ship try to fire a weapon that doesn't exist?
|
||||
continue;
|
||||
}
|
||||
@@ -9967,7 +10123,7 @@ int ship_fire_primary(object * obj, int stream_weapons, int force)
|
||||
continue;
|
||||
}
|
||||
|
||||
weapon_info* winfo_p = &Weapon_info[weapon];
|
||||
weapon_info* winfo_p = &Weapon_info[weapon_idx];
|
||||
|
||||
if (needs_target_pos) {
|
||||
target_velocity_vec = Objects[aip->target_objnum].phys_info.vel;
|
||||
@@ -10323,6 +10479,15 @@ int ship_fire_primary(object * obj, int stream_weapons, int force)
|
||||
// Mark all these weapons as in the same group
|
||||
int new_group_id = weapon_create_group_id();
|
||||
|
||||
vec3d total_impulse;
|
||||
vec3d *firepoint_list;
|
||||
size_t current_firepoint = 0;
|
||||
|
||||
if (winfo_p->wi_flags3 & WIF3_APPLY_RECOIL){
|
||||
firepoint_list = new vec3d[numtimes * points];
|
||||
vm_vec_zero(&total_impulse);
|
||||
}
|
||||
|
||||
for ( w = 0; w < numtimes; w++ ) {
|
||||
polymodel *weapon_model = NULL;
|
||||
if(winfo_p->external_model_num >= 0)
|
||||
@@ -10435,9 +10600,20 @@ int ship_fire_primary(object * obj, int stream_weapons, int force)
|
||||
firing_orient = obj->orient;
|
||||
}
|
||||
|
||||
if (winfo_p->wi_flags3 & WIF3_APPLY_RECOIL){ // Function to add recoil functionality - DahBlount
|
||||
vec3d local_impulse = firing_orient.vec.fvec;
|
||||
|
||||
float recoil_force = (winfo_p->mass * winfo_p->max_speed * winfo_p->recoil_modifier * sip->ship_recoil_modifier);
|
||||
|
||||
firepoint_list[current_firepoint++] = firing_pos;
|
||||
|
||||
vm_vec_scale(&local_impulse, (-1 * recoil_force));
|
||||
vm_vec_add2(&total_impulse, &local_impulse);
|
||||
}
|
||||
|
||||
// create the weapon -- the network signature for multiplayer is created inside
|
||||
// of weapon_create
|
||||
weapon_objnum = weapon_create( &firing_pos, &firing_orient, weapon, OBJ_INDEX(obj), new_group_id,
|
||||
weapon_objnum = weapon_create( &firing_pos, &firing_orient, weapon_idx, OBJ_INDEX(obj), new_group_id,
|
||||
0, 0, swp->primary_bank_fof_cooldown[bank_to_fire] );
|
||||
winfo_p = &Weapon_info[Weapons[Objects[weapon_objnum].instance].weapon_info_index];
|
||||
has_fired = true;
|
||||
@@ -10482,7 +10658,7 @@ int ship_fire_primary(object * obj, int stream_weapons, int force)
|
||||
// create the muzzle flash effect
|
||||
if ( (obj != Player_obj) || (sip->flags2 & SIF2_SHOW_SHIP_MODEL) || (Viewer_mode) ) {
|
||||
// show the flash only if in not cockpit view, or if "show ship" flag is set
|
||||
shipfx_flash_create( obj, sip->model_num, &pnt, &obj->orient.vec.fvec, 1, weapon );
|
||||
shipfx_flash_create( obj, sip->model_num, &pnt, &obj->orient.vec.fvec, 1, weapon_idx );
|
||||
}
|
||||
|
||||
// maybe shudder the ship - if its me
|
||||
@@ -10498,6 +10674,14 @@ int ship_fire_primary(object * obj, int stream_weapons, int force)
|
||||
}
|
||||
swp->external_model_fp_counter[bank_to_fire]++;
|
||||
}
|
||||
if (winfo_p->wi_flags3 & WIF3_APPLY_RECOIL){
|
||||
vec3d avg_firepoint;
|
||||
|
||||
vm_vec_avg_n(&avg_firepoint, current_firepoint, firepoint_list);
|
||||
|
||||
ship_apply_whack(&total_impulse, &avg_firepoint, obj);
|
||||
delete[] firepoint_list;
|
||||
}
|
||||
}
|
||||
|
||||
CLAMP(shipp->weapon_energy, 0.0f, sip->max_weapon_reserve);
|
||||
@@ -10842,7 +11026,7 @@ extern void ai_maybe_announce_shockwave_weapon(object *firing_objp, int weapon_i
|
||||
// need to avoid firing when normally called
|
||||
int ship_fire_secondary( object *obj, int allow_swarm )
|
||||
{
|
||||
int n, weapon, j, bank, bank_adjusted, starting_bank_count = -1, num_fired;
|
||||
int n, weapon_idx, j, bank, bank_adjusted, starting_bank_count = -1, num_fired;
|
||||
ushort starting_sig = 0;
|
||||
ship *shipp;
|
||||
ship_weapon *swp;
|
||||
@@ -10923,12 +11107,12 @@ int ship_fire_secondary( object *obj, int allow_swarm )
|
||||
return 0;
|
||||
}
|
||||
|
||||
weapon = swp->secondary_bank_weapons[bank];
|
||||
weapon_idx = swp->secondary_bank_weapons[bank];
|
||||
Assert( (swp->secondary_bank_weapons[bank] >= 0) && (swp->secondary_bank_weapons[bank] < MAX_WEAPON_TYPES) );
|
||||
if((swp->secondary_bank_weapons[bank] < 0) || (swp->secondary_bank_weapons[bank] >= MAX_WEAPON_TYPES)){
|
||||
return 0;
|
||||
}
|
||||
wip = &Weapon_info[weapon];
|
||||
wip = &Weapon_info[weapon_idx];
|
||||
|
||||
if ( MULTIPLAYER_MASTER ) {
|
||||
starting_sig = multi_get_next_network_signature( MULTI_SIG_NON_PERMANENT );
|
||||
@@ -11049,11 +11233,11 @@ int ship_fire_secondary( object *obj, int allow_swarm )
|
||||
|
||||
float t;
|
||||
|
||||
if (Weapon_info[weapon].burst_shots > swp->burst_counter[bank_adjusted]) {
|
||||
t = Weapon_info[weapon].burst_delay;
|
||||
if (Weapon_info[weapon_idx].burst_shots > swp->burst_counter[bank_adjusted]) {
|
||||
t = Weapon_info[weapon_idx].burst_delay;
|
||||
swp->burst_counter[bank_adjusted]++;
|
||||
} else {
|
||||
t = Weapon_info[weapon].fire_wait; // They can fire 5 times a second
|
||||
t = Weapon_info[weapon_idx].fire_wait; // They can fire 5 times a second
|
||||
swp->burst_counter[bank_adjusted] = 0;
|
||||
}
|
||||
swp->next_secondary_fire_stamp[bank] = timestamp((int) (t * 1000.0f));
|
||||
@@ -11066,7 +11250,7 @@ int ship_fire_secondary( object *obj, int allow_swarm )
|
||||
if ( obj == Player_obj )
|
||||
if ( ship_maybe_play_secondary_fail_sound(wip) ) {
|
||||
char missile_name[NAME_LENGTH];
|
||||
strcpy_s(missile_name, Weapon_info[weapon].name);
|
||||
strcpy_s(missile_name, Weapon_info[weapon_idx].name);
|
||||
end_string_at_first_hash_symbol(missile_name);
|
||||
HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Cannot fire %s due to weapons system damage", 489), missile_name);
|
||||
}
|
||||
@@ -11162,7 +11346,7 @@ int ship_fire_secondary( object *obj, int allow_swarm )
|
||||
vm_vec_add(&firing_pos, &missile_point, &obj->pos);
|
||||
|
||||
if ( Game_mode & GM_MULTIPLAYER ) {
|
||||
Assert( Weapon_info[weapon].subtype == WP_MISSILE );
|
||||
Assert( Weapon_info[weapon_idx].subtype == WP_MISSILE );
|
||||
}
|
||||
|
||||
matrix firing_orient;
|
||||
@@ -11179,17 +11363,17 @@ int ship_fire_secondary( object *obj, int allow_swarm )
|
||||
|
||||
// create the weapon -- for multiplayer, the net_signature is assigned inside
|
||||
// of weapon_create
|
||||
weapon_num = weapon_create( &firing_pos, &firing_orient, weapon, OBJ_INDEX(obj), -1, aip->current_target_is_locked);
|
||||
weapon_num = weapon_create( &firing_pos, &firing_orient, weapon_idx, OBJ_INDEX(obj), -1, aip->current_target_is_locked);
|
||||
|
||||
if (weapon_num >= 0) {
|
||||
weapon = Weapons[Objects[weapon_num].instance].weapon_info_index;
|
||||
weapon_idx = Weapons[Objects[weapon_num].instance].weapon_info_index;
|
||||
weapon_set_tracking_info(weapon_num, OBJ_INDEX(obj), aip->target_objnum, aip->current_target_is_locked, aip->targeted_subsys);
|
||||
has_fired = true;
|
||||
|
||||
// create the muzzle flash effect
|
||||
if ( (obj != Player_obj) || (sip->flags2 & SIF2_SHOW_SHIP_MODEL) || (Viewer_mode) ) {
|
||||
// show the flash only if in not cockpit view, or if "show ship" flag is set
|
||||
shipfx_flash_create(obj, sip->model_num, &pnt, &obj->orient.vec.fvec, 0, weapon);
|
||||
shipfx_flash_create(obj, sip->model_num, &pnt, &obj->orient.vec.fvec, 0, weapon_idx);
|
||||
}
|
||||
|
||||
if((wip->wi_flags & WIF_SHUDDER) && (obj == Player_obj) && !(Game_mode & GM_STANDALONE_SERVER)){
|
||||
@@ -11212,8 +11396,8 @@ int ship_fire_secondary( object *obj, int allow_swarm )
|
||||
}
|
||||
|
||||
if ( obj == Player_obj ) {
|
||||
if ( Weapon_info[weapon].launch_snd != -1 ) {
|
||||
snd_play( &Snds[Weapon_info[weapon].launch_snd], 0.0f, 1.0f, SND_PRIORITY_MUST_PLAY );
|
||||
if ( Weapon_info[weapon_idx].launch_snd != -1 ) {
|
||||
snd_play( &Snds[Weapon_info[weapon_idx].launch_snd], 0.0f, 1.0f, SND_PRIORITY_MUST_PLAY );
|
||||
swp = &Player_ship->weapons;
|
||||
if (bank >= 0) {
|
||||
wip = &Weapon_info[swp->secondary_bank_weapons[bank]];
|
||||
@@ -11226,8 +11410,8 @@ int ship_fire_secondary( object *obj, int allow_swarm )
|
||||
}
|
||||
|
||||
} else {
|
||||
if ( Weapon_info[weapon].launch_snd != -1 ) {
|
||||
snd_play_3d( &Snds[Weapon_info[weapon].launch_snd], &obj->pos, &View_position );
|
||||
if ( Weapon_info[weapon_idx].launch_snd != -1 ) {
|
||||
snd_play_3d( &Snds[Weapon_info[weapon_idx].launch_snd], &obj->pos, &View_position );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11262,7 +11446,7 @@ done_secondary:
|
||||
}
|
||||
|
||||
// maybe announce a shockwave weapon
|
||||
ai_maybe_announce_shockwave_weapon(obj, weapon);
|
||||
ai_maybe_announce_shockwave_weapon(obj, weapon_idx);
|
||||
}
|
||||
|
||||
// if we are out of ammo in this bank then don't carry over firing swarm/corkscrew
|
||||
@@ -12591,7 +12775,7 @@ float ship_calculate_rearm_duration( object *objp )
|
||||
|
||||
//find out time to repair shields
|
||||
if(sip->sup_shield_repair_rate > 0.0f)
|
||||
shield_rep_time = (sp->ship_max_shield_strength - shield_get_strength(objp)) / (sp->ship_max_shield_strength * sip->sup_shield_repair_rate);
|
||||
shield_rep_time = ((sp->ship_max_shield_strength * sp->max_shield_recharge) - shield_get_strength(objp)) / (sp->max_shield_recharge * sp->ship_max_shield_strength * sip->sup_shield_repair_rate);
|
||||
|
||||
max_hull_repair = sp->ship_max_hull_strength * (The_mission.support_ships.max_hull_repair_val * 0.01f);
|
||||
if ((The_mission.flags & MISSION_FLAG_SUPPORT_REPAIRS_HULL) && (max_hull_repair > objp->hull_strength) && (sip->sup_hull_repair_rate > 0.0f))
|
||||
@@ -12727,7 +12911,7 @@ int ship_do_rearm_frame( object *objp, float frametime )
|
||||
if ( !(objp->flags & OF_NO_SHIELDS) )
|
||||
{
|
||||
shield_str = shield_get_strength(objp);
|
||||
if ( shield_str < shipp->ship_max_shield_strength ) {
|
||||
if ( shield_str < (shipp->ship_max_shield_strength * shipp->max_shield_recharge) ) {
|
||||
if ( objp == Player_obj ) {
|
||||
player_maybe_start_repair_sound();
|
||||
}
|
||||
@@ -15550,7 +15734,7 @@ void ship_page_in()
|
||||
|
||||
// Page in all the ship classes that are used on this level
|
||||
int num_ship_types_used = 0;
|
||||
int test_id = -1;
|
||||
int test_id __attribute__((__unused__)) = -1;
|
||||
|
||||
memset( fireball_used, 0, sizeof(int) * MAX_FIREBALL_TYPES );
|
||||
|
||||
@@ -17723,6 +17907,8 @@ int ship_get_subobj_model_num(ship_info* sip, char* subobj_name)
|
||||
void init_path_metadata(path_metadata& metadata)
|
||||
{
|
||||
vm_vec_zero(&metadata.departure_rvec);
|
||||
metadata.arrive_speed_mult = FLT_MIN;
|
||||
metadata.depart_speed_mult = FLT_MIN;
|
||||
}
|
||||
|
||||
int ship_get_sound(object *objp, GameSoundsIndex id)
|
||||
@@ -17768,29 +17954,29 @@ bool ship_has_sound(object *objp, GameSoundsIndex id)
|
||||
/**
|
||||
* Given a ship with bounding box and a point, find the closest point on the bbox
|
||||
*
|
||||
* @param ship_obj Object that has the bounding box (should be a ship)
|
||||
* @param ship_objp Object that has the bounding box (should be a ship)
|
||||
* @param start World position of the point being compared
|
||||
* @param box_pt OUTPUT PARAMETER: closest point on the bbox to start
|
||||
*
|
||||
* @return point is inside bbox, TRUE/1
|
||||
* @return point is outside bbox, FALSE/0
|
||||
*/
|
||||
int get_nearest_bbox_point(object *ship_obj, vec3d *start, vec3d *box_pt)
|
||||
int get_nearest_bbox_point(object *ship_objp, vec3d *start, vec3d *box_pt)
|
||||
{
|
||||
vec3d temp, rf_start;
|
||||
polymodel *pm;
|
||||
pm = model_get(Ship_info[Ships[ship_obj->instance].ship_info_index].model_num);
|
||||
pm = model_get(Ship_info[Ships[ship_objp->instance].ship_info_index].model_num);
|
||||
|
||||
// get start in ship rf
|
||||
vm_vec_sub(&temp, start, &ship_obj->pos);
|
||||
vm_vec_rotate(&rf_start, &temp, &ship_obj->orient);
|
||||
vm_vec_sub(&temp, start, &ship_objp->pos);
|
||||
vm_vec_rotate(&rf_start, &temp, &ship_objp->orient);
|
||||
|
||||
// find box_pt
|
||||
int inside = project_point_onto_bbox(&pm->mins, &pm->maxs, &rf_start, &temp);
|
||||
|
||||
// get box_pt in world rf
|
||||
vm_vec_unrotate(box_pt, &temp, &ship_obj->orient);
|
||||
vm_vec_add2(box_pt, &ship_obj->pos);
|
||||
vm_vec_unrotate(box_pt, &temp, &ship_objp->orient);
|
||||
vm_vec_add2(box_pt, &ship_objp->pos);
|
||||
|
||||
return inside;
|
||||
}
|
||||
+23
-4
@@ -424,7 +424,7 @@ typedef struct ship_flag_name {
|
||||
int flag_list; // is this flag in the 1st or 2nd ship flags list?
|
||||
} ship_flag_name;
|
||||
|
||||
#define MAX_SHIP_FLAG_NAMES 17
|
||||
#define MAX_SHIP_FLAG_NAMES 18
|
||||
extern ship_flag_name Ship_flag_names[];
|
||||
|
||||
// states for the flags variable within the ship structure
|
||||
@@ -505,6 +505,7 @@ extern ship_flag_name Ship_flag_names[];
|
||||
#define SF2_WEAPONS_LOCKED (1<<25) // Karajorma - Prevents the player from changing the weapons on the ship on the loadout screen
|
||||
#define SF2_SHIP_SELECTIVE_LINKING (1<<26) // RSAXVC - Allow pilot to pick firing configuration
|
||||
#define SF2_SCRAMBLE_MESSAGES (1<<27) // Goober5000 - all messages sent from this ship appear scrambled
|
||||
#define SF2_NO_SECONDARY_LOCKON (1<<28) // zookeeper - secondary lock-on disabled
|
||||
|
||||
// If any of these bits in the ship->flags are set, ignore this ship when targeting
|
||||
extern int TARGET_SHIP_IGNORE_FLAGS;
|
||||
@@ -592,6 +593,8 @@ public:
|
||||
float ship_max_shield_strength;
|
||||
float ship_max_hull_strength;
|
||||
|
||||
float max_shield_recharge;
|
||||
|
||||
int ship_guardian_threshold; // Goober5000 - now also determines whether ship is guardian'd
|
||||
|
||||
|
||||
@@ -928,6 +931,7 @@ extern int ship_find_exited_ship_by_signature( int signature);
|
||||
#define SIF2_AUTO_SPREAD_SHIELDS (1 << 16) // zookeeper - auto spread shields
|
||||
#define SIF2_DRAW_WEAPON_MODELS (1 << 17) // the ship draws weapon models of any sort (used to be a boolean)
|
||||
#define SIF2_MODEL_POINT_SHIELDS (1 << 18) // zookeeper - uses model-defined shield points instead of quadrants
|
||||
#define SIF2_LOCK_DETAIL_BOXES (1 << 19) // zookeeper - don't scale detail boxes or spheres based on detail settings
|
||||
|
||||
#define SIF_DEFAULT_VALUE 0
|
||||
#define SIF2_DEFAULT_VALUE 0
|
||||
@@ -1144,6 +1148,8 @@ typedef struct ship_collision_physics {
|
||||
|
||||
typedef struct path_metadata {
|
||||
vec3d departure_rvec;
|
||||
float arrive_speed_mult;
|
||||
float depart_speed_mult;
|
||||
} path_metadata;
|
||||
|
||||
// The real FreeSpace ship_info struct.
|
||||
@@ -1175,6 +1181,7 @@ public:
|
||||
char pof_file_hud[MAX_FILENAME_LEN]; // POF file to load for the HUD target box
|
||||
int num_detail_levels; // number of detail levels for this ship
|
||||
int detail_distance[MAX_SHIP_DETAIL_LEVELS]; // distance to change detail levels at
|
||||
int collision_lod; // check for collisions using a LOD
|
||||
int cockpit_model_num; // cockpit model
|
||||
int model_num; // ship model
|
||||
int model_num_hud; // model to use when rendering to the HUD (eg, mini supercap)
|
||||
@@ -1293,14 +1300,20 @@ public:
|
||||
bool draw_secondary_models[MAX_SHIP_SECONDARY_BANKS];
|
||||
float weapon_model_draw_distance;
|
||||
|
||||
// Recoil modifier for the ship
|
||||
float ship_recoil_modifier;
|
||||
|
||||
float max_hull_strength; // Max hull strength of this class of ship.
|
||||
float max_shield_strength;
|
||||
float auto_shield_spread;
|
||||
bool auto_shield_spread_bypass;
|
||||
int auto_shield_spread_from_lod;
|
||||
float auto_shield_spread; // Thickness of the shield
|
||||
bool auto_shield_spread_bypass; // Whether weapons fired up close can bypass shields
|
||||
int auto_shield_spread_from_lod; // Which LOD to project the shield from
|
||||
float auto_shield_spread_min_span; // Minimum distance weapons must travel until allowed to collide with the shield
|
||||
|
||||
int shield_point_augment_ctrls[4]; // Re-mapping of shield augmentation controls for model point shields
|
||||
|
||||
float max_shield_recharge;
|
||||
|
||||
float hull_repair_rate; //How much of the hull is repaired every second
|
||||
float subsys_repair_rate; //How fast
|
||||
|
||||
@@ -1320,6 +1333,7 @@ public:
|
||||
|
||||
ubyte shield_icon_index; // index to locate ship-specific animation frames for the shield on HUD
|
||||
char icon_filename[MAX_FILENAME_LEN]; // filename for icon that is displayed in ship selection
|
||||
angles model_icon_angles; // angle from which the model icon should be rendered (if not 0,0,0)
|
||||
char anim_filename[MAX_FILENAME_LEN]; // filename for animation that plays in ship selection
|
||||
char overhead_filename[MAX_FILENAME_LEN]; // filename for animation that plays weapons loadout
|
||||
int selection_effect;
|
||||
@@ -1372,6 +1386,7 @@ public:
|
||||
float thruster02_glow_len_factor;
|
||||
float thruster_dist_rad_factor;
|
||||
float thruster_dist_len_factor;
|
||||
float thruster_glow_noise_mult;
|
||||
|
||||
bool draw_distortion;
|
||||
|
||||
@@ -1398,6 +1413,7 @@ public:
|
||||
vec3d topdown_offset;
|
||||
|
||||
int engine_snd; // handle to engine sound for ship (-1 if no engine sound)
|
||||
float min_engine_vol; // minimum volume modifier for engine sound when ship is stationary
|
||||
int glide_start_snd; // handle to sound to play at the beginning of a glide maneuver (default is 0 for regular throttle down sound)
|
||||
int glide_end_snd; // handle to sound to play at the end of a glide maneuver (default is 0 for regular throttle up sound)
|
||||
|
||||
@@ -1417,10 +1433,12 @@ public:
|
||||
float minimum_convergence_distance;
|
||||
float convergence_distance;
|
||||
vec3d convergence_offset;
|
||||
int autoaim_lock_snd, autoaim_lost_snd;
|
||||
|
||||
float emp_resistance_mod;
|
||||
|
||||
float piercing_damage_draw_limit;
|
||||
int shield_impact_explosion_anim;
|
||||
|
||||
int damage_lightning_type;
|
||||
|
||||
@@ -1591,6 +1609,7 @@ extern void ship_cleanup(int shipnum, int cleanup_mode);
|
||||
extern void ship_destroy_instantly(object *ship_obj, int shipnum);
|
||||
extern void ship_actually_depart(int shipnum, int method = SHIP_DEPARTED_WARP);
|
||||
|
||||
extern bool in_autoaim_fov(ship *shipp, int bank_to_fire, object *obj);
|
||||
extern int ship_fire_primary_debug(object *objp); // Fire the debug laser.
|
||||
extern int ship_stop_fire_primary(object * obj);
|
||||
extern int ship_fire_primary(object * objp, int stream_weapons, int force = 0);
|
||||
|
||||
+84
-84
@@ -78,7 +78,7 @@ void shipfx_remove_submodel_ship_sparks(ship *shipp, int submodel_num)
|
||||
*
|
||||
* DKA: 5/26/99 make velocity of debris scale according to size of debris subobject (at least for large subobjects)
|
||||
*/
|
||||
void shipfx_subsystem_maybe_create_live_debris(object *ship_obj, ship *ship_p, ship_subsys *subsys, vec3d *exp_center, float exp_mag)
|
||||
void shipfx_subsystem_maybe_create_live_debris(object *ship_objp, ship *ship_p, ship_subsys *subsys, vec3d *exp_center, float exp_mag)
|
||||
{
|
||||
// initializations
|
||||
polymodel *pm = model_get(Ship_info[ship_p->ship_info_index].model_num);
|
||||
@@ -94,7 +94,7 @@ void shipfx_subsystem_maybe_create_live_debris(object *ship_obj, ship *ship_p, s
|
||||
return;
|
||||
}
|
||||
|
||||
ship_model_start(ship_obj);
|
||||
ship_model_start(ship_objp);
|
||||
|
||||
// copy angles
|
||||
angles copy_angs = pm->submodel[submodel_num].angs;
|
||||
@@ -111,10 +111,10 @@ void shipfx_subsystem_maybe_create_live_debris(object *ship_obj, ship *ship_p, s
|
||||
|
||||
// get the rotvel
|
||||
void model_get_rotating_submodel_axis(vec3d *model_axis, vec3d *world_axis, int modelnum, int submodel_num, object *obj);
|
||||
model_get_rotating_submodel_axis(&model_axis, &world_axis, pm->id, submodel_num, ship_obj);
|
||||
model_get_rotating_submodel_axis(&model_axis, &world_axis, pm->id, submodel_num, ship_objp);
|
||||
vm_vec_copy_scale(&rotvel, &world_axis, sii->cur_turn_rate);
|
||||
|
||||
model_find_world_point(&world_axis_pt, &sii->pt_on_axis, pm->id, submodel_num, &ship_obj->orient, &ship_obj->pos);
|
||||
model_find_world_point(&world_axis_pt, &sii->pt_on_axis, pm->id, submodel_num, &ship_objp->orient, &ship_objp->pos);
|
||||
|
||||
vm_quaternion_rotate(&m_rot, vm_vec_mag((vec3d*)&sii->angs), &model_axis);
|
||||
} else {
|
||||
@@ -131,27 +131,27 @@ void shipfx_subsystem_maybe_create_live_debris(object *ship_obj, ship *ship_p, s
|
||||
|
||||
// get start world pos
|
||||
vm_vec_zero(&start_world_pos);
|
||||
model_find_world_point(&start_world_pos, &pm->submodel[live_debris_submodel].offset, pm->id, live_debris_submodel, &ship_obj->orient, &ship_obj->pos );
|
||||
model_find_world_point(&start_world_pos, &pm->submodel[live_debris_submodel].offset, pm->id, live_debris_submodel, &ship_objp->orient, &ship_objp->pos );
|
||||
|
||||
// convert to model coord of underlying submodel
|
||||
// set angle to zero
|
||||
pm->submodel[submodel_num].angs = zero_angs;
|
||||
world_find_model_point(&start_model_pos, &start_world_pos, pm, submodel_num, &ship_obj->orient, &ship_obj->pos);
|
||||
world_find_model_point(&start_model_pos, &start_world_pos, pm, submodel_num, &ship_objp->orient, &ship_objp->pos);
|
||||
|
||||
// rotate from submodel coord to world coords
|
||||
// reset angle to current angle
|
||||
pm->submodel[submodel_num].angs = copy_angs;
|
||||
model_find_world_point(&end_world_pos, &start_model_pos, pm->id, submodel_num, &ship_obj->orient, &ship_obj->pos);
|
||||
model_find_world_point(&end_world_pos, &start_model_pos, pm->id, submodel_num, &ship_objp->orient, &ship_objp->pos);
|
||||
|
||||
int fireball_type = fireball_ship_explosion_type(&Ship_info[ship_p->ship_info_index]);
|
||||
if(fireball_type < 0) {
|
||||
fireball_type = FIREBALL_EXPLOSION_MEDIUM;
|
||||
}
|
||||
// create fireball here.
|
||||
fireball_create(&end_world_pos, fireball_type, FIREBALL_MEDIUM_EXPLOSION, OBJ_INDEX(ship_obj), pm->submodel[live_debris_submodel].rad);
|
||||
fireball_create(&end_world_pos, fireball_type, FIREBALL_MEDIUM_EXPLOSION, OBJ_INDEX(ship_objp), pm->submodel[live_debris_submodel].rad);
|
||||
|
||||
// create debris
|
||||
live_debris_obj = debris_create(ship_obj, pm->id, live_debris_submodel, &end_world_pos, exp_center, 1, exp_mag);
|
||||
live_debris_obj = debris_create(ship_objp, pm->id, live_debris_submodel, &end_world_pos, exp_center, 1, exp_mag);
|
||||
|
||||
// only do if debris is created
|
||||
if (live_debris_obj) {
|
||||
@@ -177,7 +177,7 @@ void shipfx_subsystem_maybe_create_live_debris(object *ship_obj, ship *ship_p, s
|
||||
|
||||
// Add radial velocity (at least as large as exp velocity)
|
||||
vec3d temp_vel; // explosion velocity with ship_obj velocity removed
|
||||
vm_vec_sub(&temp_vel, &live_debris_obj->phys_info.vel, &ship_obj->phys_info.vel);
|
||||
vm_vec_sub(&temp_vel, &live_debris_obj->phys_info.vel, &ship_objp->phys_info.vel);
|
||||
|
||||
// find magnitudes of radial and temp velocity
|
||||
float vel_mag = vm_vec_mag(&temp_vel);
|
||||
@@ -202,8 +202,8 @@ void shipfx_subsystem_maybe_create_live_debris(object *ship_obj, ship *ship_p, s
|
||||
}
|
||||
|
||||
// scale up speed of debris if ship_obj > 125, but not for knossos
|
||||
if (ship_obj->radius > 250 && !(Ship_info[ship_p->ship_info_index].flags & SIF_KNOSSOS_DEVICE)) {
|
||||
vm_vec_scale(&live_debris_obj->phys_info.vel, ship_obj->radius/250.0f);
|
||||
if (ship_objp->radius > 250 && !(Ship_info[ship_p->ship_info_index].flags & SIF_KNOSSOS_DEVICE)) {
|
||||
vm_vec_scale(&live_debris_obj->phys_info.vel, ship_objp->radius/250.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ void shipfx_subsystem_maybe_create_live_debris(object *ship_obj, ship *ship_p, s
|
||||
}
|
||||
}
|
||||
|
||||
ship_model_stop(ship_obj);
|
||||
ship_model_stop(ship_objp);
|
||||
}
|
||||
|
||||
void set_ship_submodel_as_blown_off(ship *shipp, char *name)
|
||||
@@ -239,12 +239,12 @@ void set_ship_submodel_as_blown_off(ship *shipp, char *name)
|
||||
* Create debris for ship submodel which has live debris (at ship death)
|
||||
* when ship submodel has not already been blown off (and hence liberated live debris)
|
||||
*/
|
||||
void shipfx_maybe_create_live_debris_at_ship_death( object *ship_obj )
|
||||
void shipfx_maybe_create_live_debris_at_ship_death( object *ship_objp )
|
||||
{
|
||||
// if ship has live debris, detonate that subsystem now
|
||||
// search for any live debris
|
||||
|
||||
ship *shipp = &Ships[ship_obj->instance];
|
||||
ship *shipp = &Ships[ship_objp->instance];
|
||||
polymodel *pm = model_get(Ship_info[shipp->ship_info_index].model_num);
|
||||
|
||||
// no subsystems -> no live debris.
|
||||
@@ -263,7 +263,7 @@ void shipfx_maybe_create_live_debris_at_ship_death( object *ship_obj )
|
||||
Assert(parent != -1);
|
||||
|
||||
// set model values only once (esp blown off)
|
||||
ship_model_start(ship_obj);
|
||||
ship_model_start(ship_objp);
|
||||
|
||||
// check if already blown off (ship model set)
|
||||
if ( !pm->submodel[parent].blown_off ) {
|
||||
@@ -281,14 +281,14 @@ void shipfx_maybe_create_live_debris_at_ship_death( object *ship_obj )
|
||||
if (pss != NULL) {
|
||||
if (pss->system_info != NULL) {
|
||||
vec3d exp_center, tmp = ZERO_VECTOR;
|
||||
model_find_world_point(&exp_center, &tmp, pm->id, parent, &ship_obj->orient, &ship_obj->pos );
|
||||
model_find_world_point(&exp_center, &tmp, pm->id, parent, &ship_objp->orient, &ship_objp->pos );
|
||||
|
||||
// if not blown off, blow it off
|
||||
shipfx_subsystem_maybe_create_live_debris(ship_obj, shipp, pss, &exp_center, 3.0f);
|
||||
shipfx_subsystem_maybe_create_live_debris(ship_objp, shipp, pss, &exp_center, 3.0f);
|
||||
|
||||
// now set subsystem as blown off, so we only get one copy
|
||||
pm->submodel[parent].blown_off = 1;
|
||||
set_ship_submodel_as_blown_off(&Ships[ship_obj->instance], pss->system_info->subobj_name);
|
||||
set_ship_submodel_as_blown_off(&Ships[ship_objp->instance], pss->system_info->subobj_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -296,36 +296,36 @@ void shipfx_maybe_create_live_debris_at_ship_death( object *ship_obj )
|
||||
}
|
||||
|
||||
// clean up
|
||||
ship_model_stop(ship_obj);
|
||||
ship_model_stop(ship_objp);
|
||||
|
||||
}
|
||||
|
||||
void shipfx_blow_off_subsystem(object *ship_obj,ship *ship_p,ship_subsys *subsys, vec3d *exp_center, bool no_explosion)
|
||||
void shipfx_blow_off_subsystem(object *ship_objp, ship *ship_p,ship_subsys *subsys, vec3d *exp_center, bool no_explosion)
|
||||
{
|
||||
vec3d subobj_pos;
|
||||
int model_num = Ship_info[ship_p->ship_info_index].model_num;
|
||||
|
||||
model_subsystem *psub = subsys->system_info;
|
||||
|
||||
get_subsystem_world_pos(ship_obj, subsys, &subobj_pos);
|
||||
get_subsystem_world_pos(ship_objp, subsys, &subobj_pos);
|
||||
|
||||
// get rid of sparks on submodel that is destroyed
|
||||
shipfx_remove_submodel_ship_sparks(ship_p, psub->subobj_num);
|
||||
|
||||
// create debris shards
|
||||
if (!(subsys->flags & SSF_VANISHED) && !no_explosion) {
|
||||
shipfx_blow_up_model(ship_obj, model_num, psub->subobj_num, 50, &subobj_pos );
|
||||
shipfx_blow_up_model(ship_objp, model_num, psub->subobj_num, 50, &subobj_pos );
|
||||
|
||||
// create live debris objects, if any
|
||||
// TODO: some MULITPLAYER implcations here!!
|
||||
shipfx_subsystem_maybe_create_live_debris(ship_obj, ship_p, subsys, exp_center, 1.0f);
|
||||
shipfx_subsystem_maybe_create_live_debris(ship_objp, ship_p, subsys, exp_center, 1.0f);
|
||||
|
||||
int fireball_type = fireball_ship_explosion_type(&Ship_info[ship_p->ship_info_index]);
|
||||
if(fireball_type < 0) {
|
||||
fireball_type = FIREBALL_EXPLOSION_MEDIUM;
|
||||
}
|
||||
// create first fireball
|
||||
fireball_create( &subobj_pos, fireball_type, FIREBALL_MEDIUM_EXPLOSION, OBJ_INDEX(ship_obj), psub->radius );
|
||||
fireball_create( &subobj_pos, fireball_type, FIREBALL_MEDIUM_EXPLOSION, OBJ_INDEX(ship_objp), psub->radius );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1687,29 +1687,29 @@ static int get_split_ship()
|
||||
}
|
||||
|
||||
static void maybe_fireball_wipe(clip_ship* half_ship, int* sound_handle);
|
||||
static void split_ship_init( ship* shipp, split_ship* split_ship )
|
||||
static void split_ship_init( ship* shipp, split_ship* split_shipp )
|
||||
{
|
||||
object* parent_ship_obj = &Objects[shipp->objnum];
|
||||
matrix* orient = &parent_ship_obj->orient;
|
||||
for (int ii=0; ii<NUM_SUB_EXPL_HANDLES; ++ii) {
|
||||
split_ship->sound_handle[ii] = shipp->sub_expl_sound_handle[ii];
|
||||
split_shipp->sound_handle[ii] = shipp->sub_expl_sound_handle[ii];
|
||||
}
|
||||
|
||||
// play 3d sound for shockwave explosion
|
||||
snd_play_3d( &Snds[SND_SHOCKWAVE_EXPLODE], &parent_ship_obj->pos, &View_position, 0.0f, NULL, 0, 1.0f, SND_PRIORITY_SINGLE_INSTANCE, NULL, 3.0f );
|
||||
|
||||
// initialize both ships
|
||||
split_ship->front_ship.parent_obj = parent_ship_obj;
|
||||
split_ship->back_ship.parent_obj = parent_ship_obj;
|
||||
split_ship->explosion_flash_timestamp = timestamp((int)(0.00075f*parent_ship_obj->radius));
|
||||
split_ship->explosion_flash_started = 0;
|
||||
split_ship->front_ship.orient = *orient;
|
||||
split_ship->back_ship.orient = *orient;
|
||||
split_ship->front_ship.next_fireball = timestamp_rand(0, 100);
|
||||
split_ship->back_ship.next_fireball = timestamp_rand(0, 100);
|
||||
split_shipp->front_ship.parent_obj = parent_ship_obj;
|
||||
split_shipp->back_ship.parent_obj = parent_ship_obj;
|
||||
split_shipp->explosion_flash_timestamp = timestamp((int)(0.00075f*parent_ship_obj->radius));
|
||||
split_shipp->explosion_flash_started = 0;
|
||||
split_shipp->front_ship.orient = *orient;
|
||||
split_shipp->back_ship.orient = *orient;
|
||||
split_shipp->front_ship.next_fireball = timestamp_rand(0, 100);
|
||||
split_shipp->back_ship.next_fireball = timestamp_rand(0, 100);
|
||||
|
||||
split_ship->front_ship.clip_plane_norm = vmd_z_vector;
|
||||
vm_vec_copy_scale(&split_ship->back_ship.clip_plane_norm, &vmd_z_vector, -1.0f);
|
||||
split_shipp->front_ship.clip_plane_norm = vmd_z_vector;
|
||||
vm_vec_copy_scale(&split_shipp->back_ship.clip_plane_norm, &vmd_z_vector, -1.0f);
|
||||
|
||||
// find the point at which the ship splits (relative to its pivot)
|
||||
polymodel* pm = model_get(Ship_info[shipp->ship_info_index].model_num);
|
||||
@@ -1721,18 +1721,18 @@ static void split_ship_init( ship* shipp, split_ship* split_ship )
|
||||
init_clip_plane_dist = 0.5f * (0.5f - frand())*pm->core_radius;
|
||||
}
|
||||
|
||||
split_ship->back_ship.cur_clip_plane_pt = init_clip_plane_dist;
|
||||
split_ship->front_ship.cur_clip_plane_pt = init_clip_plane_dist;
|
||||
split_shipp->back_ship.cur_clip_plane_pt = init_clip_plane_dist;
|
||||
split_shipp->front_ship.cur_clip_plane_pt = init_clip_plane_dist;
|
||||
|
||||
float dist;
|
||||
dist = (split_ship->front_ship.cur_clip_plane_pt+pm->maxs.xyz.z)/2.0f;
|
||||
vm_vec_copy_scale(&split_ship->front_ship.local_pivot, &orient->vec.fvec, dist);
|
||||
vm_vec_make(&split_ship->front_ship.model_center_disp_to_orig_center, 0.0f, 0.0f, -dist);
|
||||
dist = (split_ship->back_ship.cur_clip_plane_pt +pm->mins.xyz.z)/2.0f;
|
||||
vm_vec_copy_scale(&split_ship->back_ship.local_pivot, &orient->vec.fvec, dist);
|
||||
vm_vec_make(&split_ship->back_ship.model_center_disp_to_orig_center, 0.0f, 0.0f, -dist);
|
||||
vm_vec_add2(&split_ship->front_ship.local_pivot, &parent_ship_obj->pos );
|
||||
vm_vec_add2(&split_ship->back_ship.local_pivot, &parent_ship_obj->pos );
|
||||
dist = (split_shipp->front_ship.cur_clip_plane_pt+pm->maxs.xyz.z)/2.0f;
|
||||
vm_vec_copy_scale(&split_shipp->front_ship.local_pivot, &orient->vec.fvec, dist);
|
||||
vm_vec_make(&split_shipp->front_ship.model_center_disp_to_orig_center, 0.0f, 0.0f, -dist);
|
||||
dist = (split_shipp->back_ship.cur_clip_plane_pt +pm->mins.xyz.z)/2.0f;
|
||||
vm_vec_copy_scale(&split_shipp->back_ship.local_pivot, &orient->vec.fvec, dist);
|
||||
vm_vec_make(&split_shipp->back_ship.model_center_disp_to_orig_center, 0.0f, 0.0f, -dist);
|
||||
vm_vec_add2(&split_shipp->front_ship.local_pivot, &parent_ship_obj->pos );
|
||||
vm_vec_add2(&split_shipp->back_ship.local_pivot, &parent_ship_obj->pos );
|
||||
|
||||
// find which debris pieces are in the front and back split ships
|
||||
for (int i=0; i<pm->num_debris_objects; i++ ) {
|
||||
@@ -1742,30 +1742,30 @@ static void split_ship_init( ship* shipp, split_ship* split_ship )
|
||||
// tmp is world position, temp_pos is world_pivot, tmp1 is offset from world_pivot (in ship local coord)
|
||||
model_find_world_point(&tmp, &tmp1, pm->id, -1, &vmd_identity_matrix, &temp_pos );
|
||||
if (tmp.xyz.z > init_clip_plane_dist) {
|
||||
split_ship->front_ship.draw_debris[i] = DEBRIS_DRAW;
|
||||
split_ship->back_ship.draw_debris[i] = DEBRIS_NONE;
|
||||
split_shipp->front_ship.draw_debris[i] = DEBRIS_DRAW;
|
||||
split_shipp->back_ship.draw_debris[i] = DEBRIS_NONE;
|
||||
} else {
|
||||
split_ship->front_ship.draw_debris[i] = DEBRIS_NONE;
|
||||
split_ship->back_ship.draw_debris[i] = DEBRIS_DRAW;
|
||||
split_shipp->front_ship.draw_debris[i] = DEBRIS_NONE;
|
||||
split_shipp->back_ship.draw_debris[i] = DEBRIS_DRAW;
|
||||
}
|
||||
}
|
||||
|
||||
// set up physics
|
||||
physics_init( &split_ship->front_ship.phys_info );
|
||||
physics_init( &split_ship->back_ship.phys_info );
|
||||
split_ship->front_ship.phys_info.flags |= (PF_ACCELERATES | PF_DEAD_DAMP);
|
||||
split_ship->back_ship.phys_info.flags |= (PF_ACCELERATES | PF_DEAD_DAMP);
|
||||
split_ship->front_ship.phys_info.side_slip_time_const = 10000.0f;
|
||||
split_ship->back_ship.phys_info.side_slip_time_const = 10000.0f;
|
||||
split_ship->front_ship.phys_info.rotdamp = 10000.0f;
|
||||
split_ship->back_ship.phys_info.rotdamp = 10000.0f;
|
||||
physics_init( &split_shipp->front_ship.phys_info );
|
||||
physics_init( &split_shipp->back_ship.phys_info );
|
||||
split_shipp->front_ship.phys_info.flags |= (PF_ACCELERATES | PF_DEAD_DAMP);
|
||||
split_shipp->back_ship.phys_info.flags |= (PF_ACCELERATES | PF_DEAD_DAMP);
|
||||
split_shipp->front_ship.phys_info.side_slip_time_const = 10000.0f;
|
||||
split_shipp->back_ship.phys_info.side_slip_time_const = 10000.0f;
|
||||
split_shipp->front_ship.phys_info.rotdamp = 10000.0f;
|
||||
split_shipp->back_ship.phys_info.rotdamp = 10000.0f;
|
||||
|
||||
// set up explosion vel and relative velocities (assuming mass depends on length)
|
||||
float front_length = pm->maxs.xyz.z - split_ship->front_ship.cur_clip_plane_pt;
|
||||
float back_length = split_ship->back_ship.cur_clip_plane_pt - pm->mins.xyz.z;
|
||||
float front_length = pm->maxs.xyz.z - split_shipp->front_ship.cur_clip_plane_pt;
|
||||
float back_length = split_shipp->back_ship.cur_clip_plane_pt - pm->mins.xyz.z;
|
||||
float ship_length = front_length + back_length;
|
||||
split_ship->front_ship.length_left = front_length;
|
||||
split_ship->back_ship.length_left = back_length;
|
||||
split_shipp->front_ship.length_left = front_length;
|
||||
split_shipp->back_ship.length_left = back_length;
|
||||
|
||||
float expl_length_scale = (ship_length - 200.0f) / 2000.0f;
|
||||
// s_r_f effects speed of "wipe" and rotvel
|
||||
@@ -1773,8 +1773,8 @@ static void split_ship_init( ship* shipp, split_ship* split_ship )
|
||||
float explosion_time = (3.0f + expl_length_scale + (frand()-0.5f)) * speed_reduction_factor;
|
||||
float long_length = MAX(front_length, back_length);
|
||||
float expl_vel = long_length / explosion_time;
|
||||
split_ship->front_ship.explosion_vel = expl_vel;
|
||||
split_ship->back_ship.explosion_vel = -expl_vel;
|
||||
split_shipp->front_ship.explosion_vel = expl_vel;
|
||||
split_shipp->back_ship.explosion_vel = -expl_vel;
|
||||
|
||||
float rel_vel = (0.6f + 0.2f*frand()) * expl_vel * speed_reduction_factor;
|
||||
float front_vel = rel_vel * back_length / ship_length;
|
||||
@@ -1786,26 +1786,26 @@ static void split_ship_init( ship* shipp, split_ship* split_ship )
|
||||
rotvel.xyz.z = 0.0f;
|
||||
vm_vec_normalize(&rotvel);
|
||||
vm_vec_scale(&rotvel, 0.15f / speed_reduction_factor);
|
||||
split_ship->front_ship.phys_info.rotvel = rotvel;
|
||||
vm_vec_copy_scale(&split_ship->back_ship.phys_info.rotvel, &rotvel, -(front_length*front_length)/(back_length*back_length));
|
||||
split_ship->front_ship.phys_info.rotvel.xyz.z = parent_ship_obj->phys_info.rotvel.xyz.z;
|
||||
split_ship->back_ship.phys_info.rotvel.xyz.z = parent_ship_obj->phys_info.rotvel.xyz.z;
|
||||
split_shipp->front_ship.phys_info.rotvel = rotvel;
|
||||
vm_vec_copy_scale(&split_shipp->back_ship.phys_info.rotvel, &rotvel, -(front_length*front_length)/(back_length*back_length));
|
||||
split_shipp->front_ship.phys_info.rotvel.xyz.z = parent_ship_obj->phys_info.rotvel.xyz.z;
|
||||
split_shipp->back_ship.phys_info.rotvel.xyz.z = parent_ship_obj->phys_info.rotvel.xyz.z;
|
||||
|
||||
|
||||
// modify vel of each split ship based on rotvel of parent ship obj
|
||||
vec3d temp_rotvel = parent_ship_obj->phys_info.rotvel;
|
||||
temp_rotvel.xyz.z = 0.0f;
|
||||
vec3d vel_from_rotvel;
|
||||
vm_vec_crossprod(&vel_from_rotvel, &temp_rotvel, &split_ship->front_ship.local_pivot);
|
||||
vm_vec_crossprod(&vel_from_rotvel, &temp_rotvel, &split_ship->back_ship.local_pivot);
|
||||
vm_vec_crossprod(&vel_from_rotvel, &temp_rotvel, &split_shipp->front_ship.local_pivot);
|
||||
vm_vec_crossprod(&vel_from_rotvel, &temp_rotvel, &split_shipp->back_ship.local_pivot);
|
||||
|
||||
// set up velocity and make initial fireballs and particles
|
||||
split_ship->front_ship.phys_info.vel = parent_ship_obj->phys_info.vel;
|
||||
split_ship->back_ship.phys_info.vel = parent_ship_obj->phys_info.vel;
|
||||
maybe_fireball_wipe(&split_ship->front_ship, (int*)&split_ship->sound_handle);
|
||||
maybe_fireball_wipe(&split_ship->back_ship, (int*)&split_ship->sound_handle);
|
||||
vm_vec_scale_add2(&split_ship->front_ship.phys_info.vel, &orient->vec.fvec, front_vel);
|
||||
vm_vec_scale_add2(&split_ship->back_ship.phys_info.vel, &orient->vec.fvec, back_vel);
|
||||
split_shipp->front_ship.phys_info.vel = parent_ship_obj->phys_info.vel;
|
||||
split_shipp->back_ship.phys_info.vel = parent_ship_obj->phys_info.vel;
|
||||
maybe_fireball_wipe(&split_shipp->front_ship, (int*)&split_shipp->sound_handle);
|
||||
maybe_fireball_wipe(&split_shipp->back_ship, (int*)&split_shipp->sound_handle);
|
||||
vm_vec_scale_add2(&split_shipp->front_ship.phys_info.vel, &orient->vec.fvec, front_vel);
|
||||
vm_vec_scale_add2(&split_shipp->back_ship.phys_info.vel, &orient->vec.fvec, back_vel);
|
||||
|
||||
// HANDLE LIVE DEBRIS - blow off if not already gone
|
||||
shipfx_maybe_create_live_debris_at_ship_death( parent_ship_obj );
|
||||
@@ -1930,7 +1930,7 @@ void shipfx_debris_limit_speed(debris *db, ship *shipp)
|
||||
if(db == NULL || shipp == NULL)
|
||||
return;
|
||||
|
||||
object *ship_obj = &Objects[shipp->objnum];
|
||||
object *ship_objp = &Objects[shipp->objnum];
|
||||
physics_info *pi = &Objects[db->objnum].phys_info;
|
||||
ship_info *sip = &Ship_info[shipp->ship_info_index];
|
||||
|
||||
@@ -1945,7 +1945,7 @@ void shipfx_debris_limit_speed(debris *db, ship *shipp)
|
||||
}
|
||||
else
|
||||
{
|
||||
vm_vec_copy_scale(&pi->vel, &ship_obj->orient.vec.fvec, debris_speed);
|
||||
vm_vec_copy_scale(&pi->vel, &ship_objp->orient.vec.fvec, debris_speed);
|
||||
}
|
||||
}
|
||||
else if(sip->debris_min_speed >= 0.0f)
|
||||
@@ -1959,7 +1959,7 @@ void shipfx_debris_limit_speed(debris *db, ship *shipp)
|
||||
}
|
||||
else
|
||||
{
|
||||
vm_vec_copy_scale(&pi->vel, &ship_obj->orient.vec.fvec, sip->debris_min_speed);
|
||||
vm_vec_copy_scale(&pi->vel, &ship_objp->orient.vec.fvec, sip->debris_min_speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1974,7 +1974,7 @@ void shipfx_debris_limit_speed(debris *db, ship *shipp)
|
||||
}
|
||||
else
|
||||
{
|
||||
vm_vec_copy_scale(&pi->vel, &ship_obj->orient.vec.fvec, sip->debris_max_speed);
|
||||
vm_vec_copy_scale(&pi->vel, &ship_objp->orient.vec.fvec, sip->debris_max_speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1991,7 +1991,7 @@ void shipfx_debris_limit_speed(debris *db, ship *shipp)
|
||||
}
|
||||
else
|
||||
{
|
||||
vm_vec_copy_scale(&pi->rotvel, &ship_obj->orient.vec.uvec, debris_rotspeed);
|
||||
vm_vec_copy_scale(&pi->rotvel, &ship_objp->orient.vec.uvec, debris_rotspeed);
|
||||
}
|
||||
}
|
||||
else if(sip->debris_min_rotspeed >= 0.0f)
|
||||
@@ -2005,7 +2005,7 @@ void shipfx_debris_limit_speed(debris *db, ship *shipp)
|
||||
}
|
||||
else
|
||||
{
|
||||
vm_vec_copy_scale(&pi->rotvel, &ship_obj->orient.vec.uvec, sip->debris_min_rotspeed);
|
||||
vm_vec_copy_scale(&pi->rotvel, &ship_objp->orient.vec.uvec, sip->debris_min_rotspeed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2021,7 +2021,7 @@ void shipfx_debris_limit_speed(debris *db, ship *shipp)
|
||||
}
|
||||
else
|
||||
{
|
||||
vm_vec_copy_scale(&pi->rotvel, &ship_obj->orient.vec.uvec, sip->debris_max_rotspeed);
|
||||
vm_vec_copy_scale(&pi->rotvel, &ship_objp->orient.vec.uvec, sip->debris_max_rotspeed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+64
-64
@@ -1660,12 +1660,12 @@ int ds_get_channel(int sig)
|
||||
/**
|
||||
* @todo Documentation
|
||||
*/
|
||||
int ds_is_channel_playing(int channel)
|
||||
int ds_is_channel_playing(int channel_id)
|
||||
{
|
||||
if ( Channels[channel].source_id != 0 ) {
|
||||
if ( Channels[channel_id].source_id != 0 ) {
|
||||
ALint status;
|
||||
|
||||
OpenAL_ErrorPrint( alGetSourcei(Channels[channel].source_id, AL_SOURCE_STATE, &status) );
|
||||
OpenAL_ErrorPrint( alGetSourcei(Channels[channel_id].source_id, AL_SOURCE_STATE, &status) );
|
||||
|
||||
return (status == AL_PLAYING);
|
||||
}
|
||||
@@ -1676,10 +1676,10 @@ int ds_is_channel_playing(int channel)
|
||||
/**
|
||||
* @todo Documentation
|
||||
*/
|
||||
void ds_stop_channel(int channel)
|
||||
void ds_stop_channel(int channel_id)
|
||||
{
|
||||
if ( Channels[channel].source_id != 0 ) {
|
||||
OpenAL_ErrorPrint( alSourceStop(Channels[channel].source_id) );
|
||||
if ( Channels[channel_id].source_id != 0 ) {
|
||||
OpenAL_ErrorPrint( alSourceStop(Channels[channel_id].source_id) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1701,13 +1701,13 @@ void ds_stop_channel_all()
|
||||
* @brief Set the volume for a channel. The volume is expected to be in linear scale
|
||||
* @details If the sound is a 3D sound buffer, this is like re-establishing the maximum volume.
|
||||
*/
|
||||
void ds_set_volume( int channel, float vol )
|
||||
void ds_set_volume( int channel_id, float vol )
|
||||
{
|
||||
if ( (channel < 0) || (channel >= MAX_CHANNELS) ) {
|
||||
if ( (channel_id < 0) || (channel_id >= MAX_CHANNELS) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
ALuint source_id = Channels[channel].source_id;
|
||||
ALuint source_id = Channels[channel_id].source_id;
|
||||
|
||||
if (source_id != 0) {
|
||||
CAP(vol, 0.0f, 1.0f);
|
||||
@@ -1718,39 +1718,39 @@ void ds_set_volume( int channel, float vol )
|
||||
/**
|
||||
* Set the pan for a channel. The pan is expected to be in DirectSound units
|
||||
*/
|
||||
void ds_set_pan( int channel, float pan )
|
||||
void ds_set_pan( int channel_id, float pan )
|
||||
{
|
||||
if ( (channel < 0) || (channel >= MAX_CHANNELS) ) {
|
||||
if ( (channel_id < 0) || (channel_id >= MAX_CHANNELS) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
ALint state;
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(Channels[channel].source_id, AL_SOURCE_STATE, &state), return );
|
||||
OpenAL_ErrorCheck( alGetSourcei(Channels[channel_id].source_id, AL_SOURCE_STATE, &state), return );
|
||||
|
||||
if (state == AL_PLAYING) {
|
||||
//OpenAL_ErrorPrint( alSourcei(Channels[channel].source_id, AL_SOURCE_RELATIVE, AL_TRUE) );
|
||||
OpenAL_ErrorPrint( alSource3f(Channels[channel].source_id, AL_POSITION, pan, 0.0f, 1.0f) );
|
||||
//OpenAL_ErrorPrint( alSourcei(Channels[channel_id].source_id, AL_SOURCE_RELATIVE, AL_TRUE) );
|
||||
OpenAL_ErrorPrint( alSource3f(Channels[channel_id].source_id, AL_POSITION, pan, 0.0f, 1.0f) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pitch of a channel
|
||||
*/
|
||||
int ds_get_pitch(int channel)
|
||||
int ds_get_pitch(int channel_id)
|
||||
{
|
||||
ALint status;
|
||||
ALfloat alpitch = 0;
|
||||
int pitch;
|
||||
|
||||
if ( (channel < 0) || (channel >= MAX_CHANNELS) ) {
|
||||
if ( (channel_id < 0) || (channel_id >= MAX_CHANNELS) ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(Channels[channel].source_id, AL_SOURCE_STATE, &status), return -1 );
|
||||
OpenAL_ErrorCheck( alGetSourcei(Channels[channel_id].source_id, AL_SOURCE_STATE, &status), return -1 );
|
||||
|
||||
if (status == AL_PLAYING) {
|
||||
OpenAL_ErrorPrint( alGetSourcef(Channels[channel].source_id, AL_PITCH, &alpitch) );
|
||||
OpenAL_ErrorPrint( alGetSourcef(Channels[channel_id].source_id, AL_PITCH, &alpitch) );
|
||||
}
|
||||
|
||||
// convert OpenAL values to DirectSound values and return
|
||||
@@ -1762,11 +1762,11 @@ int ds_get_pitch(int channel)
|
||||
/**
|
||||
* Set the pitch of a channel
|
||||
*/
|
||||
void ds_set_pitch(int channel, int pitch)
|
||||
void ds_set_pitch(int channel_id, int pitch)
|
||||
{
|
||||
ALint status;
|
||||
|
||||
if ( (channel < 0) || (channel >= MAX_CHANNELS) ) {
|
||||
if ( (channel_id < 0) || (channel_id >= MAX_CHANNELS) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1778,24 +1778,24 @@ void ds_set_pitch(int channel, int pitch)
|
||||
pitch = MAX_PITCH;
|
||||
}
|
||||
|
||||
OpenAL_ErrorCheck( alGetSourcei(Channels[channel].source_id, AL_SOURCE_STATE, &status), return );
|
||||
OpenAL_ErrorCheck( alGetSourcei(Channels[channel_id].source_id, AL_SOURCE_STATE, &status), return );
|
||||
|
||||
if (status == AL_PLAYING) {
|
||||
ALfloat alpitch = log10f((float)pitch) - 2.0f;
|
||||
OpenAL_ErrorPrint( alSourcef(Channels[channel].source_id, AL_PITCH, alpitch) );
|
||||
OpenAL_ErrorPrint( alSourcef(Channels[channel_id].source_id, AL_PITCH, alpitch) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Documentation
|
||||
*/
|
||||
void ds_chg_loop_status(int channel, int loop)
|
||||
void ds_chg_loop_status(int channel_id, int loop)
|
||||
{
|
||||
if ( (channel < 0) || (channel >= MAX_CHANNELS) ) {
|
||||
if ( (channel_id < 0) || (channel_id >= MAX_CHANNELS) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
ALuint source_id = Channels[channel].source_id;
|
||||
ALuint source_id = Channels[channel_id].source_id;
|
||||
|
||||
OpenAL_ErrorPrint( alSourcei(source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE) );
|
||||
}
|
||||
@@ -1818,99 +1818,99 @@ void ds_chg_loop_status(int channel, int loop)
|
||||
*/
|
||||
int ds3d_play(int sid, int snd_id, vec3d *pos, vec3d *vel, float min, float max, int looping, float max_volume, float estimated_vol, int priority )
|
||||
{
|
||||
int channel;
|
||||
int channel_id;
|
||||
|
||||
if (!ds_initialized) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
channel = ds_get_free_channel(estimated_vol, snd_id, priority);
|
||||
channel_id = ds_get_free_channel(estimated_vol, snd_id, priority);
|
||||
|
||||
if (channel < 0) {
|
||||
if (channel_id < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( Channels[channel].source_id == 0 ) {
|
||||
if ( Channels[channel_id].source_id == 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// set up 3D sound data here
|
||||
ds3d_update_buffer(channel, min, max, pos, vel);
|
||||
ds3d_update_buffer(channel_id, min, max, pos, vel);
|
||||
|
||||
|
||||
OpenAL_ErrorPrint( alSourcef(Channels[channel].source_id, AL_PITCH, 1.0f) );
|
||||
OpenAL_ErrorPrint( alSourcef(Channels[channel_id].source_id, AL_PITCH, 1.0f) );
|
||||
|
||||
OpenAL_ErrorPrint( alSourcef(Channels[channel].source_id, AL_GAIN, max_volume) );
|
||||
OpenAL_ErrorPrint( alSourcef(Channels[channel_id].source_id, AL_GAIN, max_volume) );
|
||||
|
||||
ALint status;
|
||||
OpenAL_ErrorCheck( alGetSourcei(Channels[channel].source_id, AL_SOURCE_STATE, &status), return -1 );
|
||||
OpenAL_ErrorCheck( alGetSourcei(Channels[channel_id].source_id, AL_SOURCE_STATE, &status), return -1 );
|
||||
|
||||
if (status == AL_PLAYING) {
|
||||
OpenAL_ErrorPrint( alSourceStop(Channels[channel].source_id) );
|
||||
OpenAL_ErrorPrint( alSourceStop(Channels[channel_id].source_id) );
|
||||
}
|
||||
|
||||
|
||||
OpenAL_ErrorCheck( alSourcei(Channels[channel].source_id, AL_BUFFER, sound_buffers[sid].buf_id), return -1 );
|
||||
OpenAL_ErrorCheck( alSourcei(Channels[channel_id].source_id, AL_BUFFER, sound_buffers[sid].buf_id), return -1 );
|
||||
|
||||
if (Ds_eax_inited) {
|
||||
OpenAL_ErrorPrint( alSource3i(Channels[channel].source_id, AL_AUXILIARY_SEND_FILTER, AL_EFX_aux_id, 0, AL_FILTER_NULL) );
|
||||
OpenAL_ErrorPrint( alSource3i(Channels[channel_id].source_id, AL_AUXILIARY_SEND_FILTER, AL_EFX_aux_id, 0, AL_FILTER_NULL) );
|
||||
}
|
||||
|
||||
OpenAL_ErrorPrint( alSourcei(Channels[channel].source_id, AL_SOURCE_RELATIVE, AL_FALSE) );
|
||||
OpenAL_ErrorPrint( alSourcei(Channels[channel_id].source_id, AL_SOURCE_RELATIVE, AL_FALSE) );
|
||||
|
||||
OpenAL_ErrorPrint( alSourcei(Channels[channel].source_id, AL_LOOPING, (looping) ? AL_TRUE : AL_FALSE) );
|
||||
OpenAL_ErrorPrint( alSourcei(Channels[channel_id].source_id, AL_LOOPING, (looping) ? AL_TRUE : AL_FALSE) );
|
||||
|
||||
OpenAL_ErrorPrint( alSourcePlay(Channels[channel].source_id) );
|
||||
OpenAL_ErrorPrint( alSourcePlay(Channels[channel_id].source_id) );
|
||||
|
||||
|
||||
sound_buffers[sid].channel_id = channel;
|
||||
sound_buffers[sid].channel_id = channel_id;
|
||||
|
||||
Channels[channel].sid = sid;
|
||||
Channels[channel].snd_id = snd_id;
|
||||
Channels[channel].sig = channel_next_sig++;
|
||||
Channels[channel].last_position = 0;
|
||||
Channels[channel].is_voice_msg = false;
|
||||
Channels[channel].vol = max_volume;
|
||||
Channels[channel].looping = looping;
|
||||
Channels[channel].priority = priority;
|
||||
Channels[channel_id].sid = sid;
|
||||
Channels[channel_id].snd_id = snd_id;
|
||||
Channels[channel_id].sig = channel_next_sig++;
|
||||
Channels[channel_id].last_position = 0;
|
||||
Channels[channel_id].is_voice_msg = false;
|
||||
Channels[channel_id].vol = max_volume;
|
||||
Channels[channel_id].looping = looping;
|
||||
Channels[channel_id].priority = priority;
|
||||
|
||||
if (channel_next_sig < 0 ) {
|
||||
channel_next_sig = 1;
|
||||
}
|
||||
|
||||
return Channels[channel].sig;
|
||||
return Channels[channel_id].sig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Documentation
|
||||
*/
|
||||
void ds_set_position(int channel, unsigned int offset)
|
||||
void ds_set_position(int channel_id, unsigned int offset)
|
||||
{
|
||||
if ( (channel < 0) || (channel >= MAX_CHANNELS) ) {
|
||||
if ( (channel_id < 0) || (channel_id >= MAX_CHANNELS) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
OpenAL_ErrorPrint( alSourcei(Channels[channel].source_id, AL_BYTE_OFFSET, offset) );
|
||||
OpenAL_ErrorPrint( alSourcei(Channels[channel_id].source_id, AL_BYTE_OFFSET, offset) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Documentation
|
||||
*/
|
||||
unsigned int ds_get_play_position(int channel)
|
||||
unsigned int ds_get_play_position(int channel_id)
|
||||
{
|
||||
if ( (channel < 0) || (channel >= MAX_CHANNELS) ) {
|
||||
if ( (channel_id < 0) || (channel_id >= MAX_CHANNELS) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ALint pos = -1;
|
||||
int sid = Channels[channel].sid;
|
||||
int sid = Channels[channel_id].sid;
|
||||
|
||||
if ( (sid < 0) || ((size_t)sid >= sound_buffers.size()) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (AL_play_position) {
|
||||
OpenAL_ErrorPrint( alGetSourcei(Channels[channel].source_id, AL_BYTE_LOKI, &pos) );
|
||||
OpenAL_ErrorPrint( alGetSourcei(Channels[channel_id].source_id, AL_BYTE_LOKI, &pos) );
|
||||
|
||||
if ( pos < 0 ) {
|
||||
pos = 0;
|
||||
@@ -1925,7 +1925,7 @@ unsigned int ds_get_play_position(int channel)
|
||||
pos = (ALint)(pos * ((float)sound_buffers[sid].nbytes / size));
|
||||
}
|
||||
} else {
|
||||
OpenAL_ErrorPrint( alGetSourcei(Channels[channel].source_id, AL_BYTE_OFFSET, &pos) );
|
||||
OpenAL_ErrorPrint( alGetSourcei(Channels[channel_id].source_id, AL_BYTE_OFFSET, &pos) );
|
||||
|
||||
if (pos < 0) {
|
||||
pos = 0;
|
||||
@@ -1938,7 +1938,7 @@ unsigned int ds_get_play_position(int channel)
|
||||
/**
|
||||
* @todo Documentation
|
||||
*/
|
||||
unsigned int ds_get_write_position(int channel)
|
||||
unsigned int ds_get_write_position(int channel_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -1946,13 +1946,13 @@ unsigned int ds_get_write_position(int channel)
|
||||
/**
|
||||
* @todo Documentation
|
||||
*/
|
||||
int ds_get_channel_size(int channel)
|
||||
int ds_get_channel_size(int channel_id)
|
||||
{
|
||||
if ( (channel < 0) || (channel >= MAX_CHANNELS) ) {
|
||||
if ( (channel_id < 0) || (channel_id >= MAX_CHANNELS) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sid = Channels[channel].sid;
|
||||
int sid = Channels[channel_id].sid;
|
||||
|
||||
if ( (sid < 0) || ((size_t)sid >= sound_buffers.size()) ) {
|
||||
return 0;
|
||||
@@ -2408,10 +2408,10 @@ void ds_do_frame()
|
||||
/**
|
||||
* Given a valid channel return the sound id
|
||||
*/
|
||||
int ds_get_sound_id(int channel)
|
||||
int ds_get_sound_id(int channel_id)
|
||||
{
|
||||
Assert( channel >= 0 );
|
||||
Assert( channel_id >= 0 );
|
||||
|
||||
return Channels[channel].snd_id;
|
||||
return Channels[channel_id].snd_id;
|
||||
}
|
||||
|
||||
+3
-3
@@ -32,18 +32,18 @@
|
||||
// -1 => failure
|
||||
//
|
||||
//
|
||||
int ds3d_update_buffer(int channel, float min, float max, vec3d *pos, vec3d *vel)
|
||||
int ds3d_update_buffer(int channel_id, float min, float max, vec3d *pos, vec3d *vel)
|
||||
{
|
||||
if (Cmdline_no_3d_sound) {
|
||||
nprintf(("Sound", "Aborting ds3d_update_buffer due to Cmdline_no_3d_sound..."));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (channel < 0) {
|
||||
if (channel_id < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ALuint source_id = Channels[channel].source_id;
|
||||
ALuint source_id = Channels[channel_id].source_id;
|
||||
ALfloat rolloff = 1.0f;
|
||||
|
||||
if (pos) {
|
||||
|
||||
@@ -50,10 +50,12 @@ typedef struct sound {
|
||||
|
||||
SCP_vector<sound> Sounds;
|
||||
|
||||
int Sound_enabled = FALSE; // global flag to turn sound on/off
|
||||
int Snd_sram; // mem (in bytes) used up by storing sounds in system memory
|
||||
float Master_sound_volume = 1.0f; // range is 0 -> 1, used for non-music sound fx
|
||||
float Master_voice_volume = 0.7f; // range is 0 -> 1, used for all voice playback
|
||||
int Sound_enabled = FALSE; // global flag to turn sound on/off
|
||||
int Snd_sram; // mem (in bytes) used up by storing sounds in system memory
|
||||
float Default_sound_volume = 1.0f; // range is 0 -> 1, used for non-music sound fx
|
||||
float Default_voice_volume = 0.7f; // range is 0 -> 1, used for all voice playback
|
||||
float Master_sound_volume = Default_sound_volume;
|
||||
float Master_voice_volume = Default_voice_volume;
|
||||
|
||||
unsigned int SND_ENV_DEFAULT = 0;
|
||||
|
||||
|
||||
@@ -62,6 +62,8 @@ typedef struct sound_env
|
||||
} sound_env;
|
||||
|
||||
extern int Sound_enabled;
|
||||
extern float Default_sound_volume; // 0 -> 1.0
|
||||
extern float Default_voice_volume; // 0 -> 1.0
|
||||
extern float Master_sound_volume; // 0 -> 1.0
|
||||
extern float Master_voice_volume; // 0 -> 1.0
|
||||
extern int Snd_sram; // System memory consumed by sound data
|
||||
|
||||
@@ -729,7 +729,7 @@ void shockwave_page_in()
|
||||
} else if (Shockwave_info[i].model_id >= 0) {
|
||||
// for a model we have to run model_load() on it again to make sure
|
||||
// that it's ref_count is sane for this mission
|
||||
int idx = model_load( Shockwave_info[i].filename, 0, NULL );
|
||||
int idx __attribute__((__unused__)) = model_load( Shockwave_info[i].filename, 0, NULL );
|
||||
Assert( idx == Shockwave_info[i].model_id );
|
||||
|
||||
model_page_in_textures( Shockwave_info[i].model_id );
|
||||
|
||||
@@ -122,7 +122,7 @@ extern int Num_weapon_subtypes;
|
||||
#define WIF3_TURRET_INTERCEPTABLE (1 << 5) // These two flags mark a weapon as being interceptable by the AI
|
||||
#define WIF3_FIGHTER_INTERCEPTABLE (1 << 6) // (like WIF_BOMB), without forcing it to be tagetable -MageKing17
|
||||
#define WIF3_AOE_ELECTRONICS (1 << 7) // Apply electronics effect across the weapon's entire area of effect instead of just on the impacted ship -MageKing17
|
||||
|
||||
#define WIF3_APPLY_RECOIL (1 << 8) // Apply recoil using weapon and ship info
|
||||
|
||||
#define WIF_HOMING (WIF_HOMING_HEAT | WIF_HOMING_ASPECT | WIF_HOMING_JAVELIN)
|
||||
#define WIF_LOCKED_HOMING (WIF_HOMING_ASPECT | WIF_HOMING_JAVELIN)
|
||||
@@ -141,6 +141,7 @@ extern int Num_weapon_subtypes;
|
||||
#define WF_DESTROYED_BY_WEAPON (1<<6) // destroyed by damage from other weapon
|
||||
#define WF_SPAWNED (1<<7) //Spawned from a spawning type weapon
|
||||
#define WF_HOMING_UPDATE_NEEDED (1<<8) // this is a newly spawned homing weapon which needs to update client machines
|
||||
#define WF_NO_HOMING (1<<9) // this weapon should ignore any homing behavior it'd usually have
|
||||
|
||||
// flags for setting burst fire
|
||||
#define WBF_FAST_FIRING (1<<0) // burst is to use only the firewait to determine firing delays
|
||||
@@ -416,6 +417,7 @@ typedef struct weapon_info {
|
||||
|
||||
int impact_weapon_expl_index; // Index into Weapon_expl_info of which ANI should play when this thing impacts something
|
||||
float impact_explosion_radius; // How big the explosion should be
|
||||
float shield_impact_explosion_radius; // How big the shield hit explosion should be
|
||||
|
||||
int dinky_impact_weapon_expl_index;
|
||||
float dinky_impact_explosion_radius;
|
||||
@@ -435,6 +437,9 @@ typedef struct weapon_info {
|
||||
float emp_intensity; // intensity of the EMP effect
|
||||
float emp_time; // time of the EMP effect
|
||||
|
||||
// Recoil effect
|
||||
float recoil_modifier;
|
||||
|
||||
// Energy suck effect
|
||||
float weapon_reduce; // how much energy removed from weapons systems
|
||||
float afterburner_reduce; // how much energy removed from weapons systems
|
||||
@@ -670,4 +675,6 @@ void weapon_pause_sounds();
|
||||
// Unpauses all running weapon sounds
|
||||
void weapon_unpause_sounds();
|
||||
|
||||
void shield_impact_explosion(vec3d *hitpos, object *objp, float radius, int idx);
|
||||
|
||||
#endif
|
||||
+48
-2
@@ -665,6 +665,8 @@ void parse_wi_flags(weapon_info *weaponp, int wi_flags, int wi_flags2, int wi_fl
|
||||
weaponp->wi_flags3 |= WIF3_TURRET_INTERCEPTABLE;
|
||||
else if (!stricmp(NOX("fighter interceptable"), weapon_strings[i]))
|
||||
weaponp->wi_flags3 |= WIF3_FIGHTER_INTERCEPTABLE;
|
||||
else if (!stricmp(NOX("apply recoil"), weapon_strings[i]))
|
||||
weaponp->wi_flags3 |= WIF3_APPLY_RECOIL;
|
||||
else
|
||||
Warning(LOCATION, "Bogus string in weapon flags: %s\n", weapon_strings[i]);
|
||||
}
|
||||
@@ -940,6 +942,8 @@ void init_weapon_entry(int weap_info_index)
|
||||
wip->impact_explosion_radius = 1.0f;
|
||||
wip->impact_weapon_expl_index = -1;
|
||||
|
||||
wip->shield_impact_explosion_radius = 1.0f;
|
||||
|
||||
wip->dinky_impact_explosion_radius = 1.0f;
|
||||
wip->dinky_impact_weapon_expl_index = -1;
|
||||
|
||||
@@ -958,6 +962,7 @@ void init_weapon_entry(int weap_info_index)
|
||||
|
||||
wip->emp_intensity = EMP_DEFAULT_INTENSITY;
|
||||
wip->emp_time = EMP_DEFAULT_TIME; // Goober5000: <-- Look! I fixed a Volition bug! Gimme $5, Dave!
|
||||
wip->recoil_modifier = 1.0f;
|
||||
wip->weapon_reduce = ESUCK_DEFAULT_WEAPON_REDUCE;
|
||||
wip->afterburner_reduce = ESUCK_DEFAULT_AFTERBURNER_REDUCE;
|
||||
|
||||
@@ -1911,6 +1916,12 @@ int parse_weapon(int subtype, bool replace)
|
||||
if ( optional_string("$Impact Explosion Radius:") )
|
||||
stuff_float(&wip->impact_explosion_radius);
|
||||
|
||||
if ( optional_string("$Shield Impact Explosion Radius:") ) {
|
||||
stuff_float(&wip->shield_impact_explosion_radius);
|
||||
} else if (first_time) {
|
||||
wip->shield_impact_explosion_radius = wip->impact_explosion_radius;
|
||||
}
|
||||
|
||||
if ( optional_string("$Dinky Impact Explosion:") ) {
|
||||
stuff_string(fname, F_NAME, NAME_LENGTH);
|
||||
|
||||
@@ -1967,6 +1978,15 @@ int parse_weapon(int subtype, bool replace)
|
||||
stuff_float(&wip->emp_time);
|
||||
}
|
||||
|
||||
// This is an optional modifier for a weapon that uses the "apply recoil" flag. recoil_force in ship.cpp line 10445 is multiplied by this if defined.
|
||||
if (optional_string("$Recoil Modifier:")){
|
||||
if (!(wip->wi_flags3 & WIF3_APPLY_RECOIL)){
|
||||
Warning(LOCATION, "$Recoil Modifier specified for weapon %s but this weapon does not have the \"apply recoil\" weapon flag set. Automatically setting the flag", wip->name);
|
||||
wip->wi_flags3 |= WIF3_APPLY_RECOIL;
|
||||
}
|
||||
stuff_float(&wip->recoil_modifier);
|
||||
}
|
||||
|
||||
// Energy suck optional stuff (if WIF_ENERGY_SUCK is not set, none of this matters anyway)
|
||||
if( optional_string("$Leech Weapon:") ){
|
||||
stuff_float(&wip->weapon_reduce);
|
||||
@@ -4772,7 +4792,7 @@ void weapon_process_post(object * obj, float frame_time)
|
||||
}
|
||||
|
||||
// a single player or multiplayer server function -- it affects actual weapon movement.
|
||||
if (wip->wi_flags & WIF_HOMING) {
|
||||
if (wip->wi_flags & WIF_HOMING && !(wp->weapon_flags & WF_NO_HOMING)) {
|
||||
weapon_home(obj, num, frame_time);
|
||||
|
||||
// If this is a swarm type missile,
|
||||
@@ -4825,7 +4845,14 @@ void weapon_process_post(object * obj, float frame_time)
|
||||
//create the warphole
|
||||
vm_vec_add2(&warpout,&obj->pos);
|
||||
wp->lssm_warp_idx=fireball_create(&warpout, FIREBALL_WARP, FIREBALL_WARP_EFFECT, -1,obj->radius*1.5f,1,&vmd_zero_vector,wp->lssm_warp_time,0,&obj->orient);
|
||||
wp->lssm_stage=2;
|
||||
|
||||
if (wp->lssm_warp_idx < 0) {
|
||||
mprintf(("LSSM: Failed to create warp effect! Please report if this happens frequently.\n"));
|
||||
// Abort warping
|
||||
wp->lssm_stage = 0;
|
||||
} else {
|
||||
wp->lssm_stage = 2;
|
||||
}
|
||||
}
|
||||
|
||||
//its just entered subspace subspace. don't collide or render
|
||||
@@ -4944,6 +4971,10 @@ void weapon_set_tracking_info(int weapon_objnum, int parent_objnum, int target_o
|
||||
wp = &Weapons[Objects[weapon_objnum].instance];
|
||||
wip = &Weapon_info[wp->weapon_info_index];
|
||||
|
||||
if (wp->weapon_flags & WF_NO_HOMING) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent_objnum >= 0) {
|
||||
parent_objp = &Objects[parent_objnum];
|
||||
Assert(parent_objp->type == OBJ_SHIP);
|
||||
@@ -4951,6 +4982,16 @@ void weapon_set_tracking_info(int weapon_objnum, int parent_objnum, int target_o
|
||||
parent_objp = NULL;
|
||||
}
|
||||
|
||||
if (parent_objp != NULL && (Ships[parent_objp->instance].flags2 & SF2_NO_SECONDARY_LOCKON)) {
|
||||
wp->weapon_flags |= WF_NO_HOMING;
|
||||
wp->homing_object = NULL;
|
||||
wp->homing_subsys = NULL;
|
||||
wp->target_num = -1;
|
||||
wp->target_sig = -1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( parent_objp == NULL || Ships[parent_objp->instance].ai_index >= 0 ) {
|
||||
int target_team = -1;
|
||||
if ( target_objnum >= 0 ) {
|
||||
@@ -7036,3 +7077,8 @@ void weapon_unpause_sounds()
|
||||
// Pause all beam sounds
|
||||
beam_unpause_sounds();
|
||||
}
|
||||
|
||||
void shield_impact_explosion(vec3d *hitpos, object *objp, float radius, int idx) {
|
||||
int expl_ani_handle = Weapon_explosions.GetAnim(idx, hitpos, radius);
|
||||
particle_create( hitpos, &vmd_zero_vector, 0.0f, radius, PARTICLE_BITMAP_PERSISTENT, expl_ani_handle, -1.0f, objp );
|
||||
}
|
||||
@@ -64,8 +64,8 @@
|
||||
|
||||
|
||||
// don't verbose stub funtions unless we're debugging
|
||||
#define STUB_FUNCTION nprintf(( "Warning", "STUB: %s in "__FILE__" at line %d, thread %d\n", __FUNCTION__, __LINE__, getpid() ))
|
||||
#define DEBUGME(d1) nprintf(( "Warning", "DEBUGME: %s in "__FILE__" at line %d, msg \"%s\", thread %d\n", __FUNCTION__, __LINE__, d1, getpid() ))
|
||||
#define STUB_FUNCTION nprintf(( "Warning", "STUB: %s in " __FILE__ " at line %d, thread %d\n", __FUNCTION__, __LINE__, getpid() ))
|
||||
#define DEBUGME(d1) nprintf(( "Warning", "DEBUGME: %s in " __FILE__ " at line %d, msg \"%s\", thread %d\n", __FUNCTION__, __LINE__, d1, getpid() ))
|
||||
|
||||
|
||||
#define _cdecl
|
||||
|
||||
@@ -39,6 +39,8 @@ AC_SUBST(LDFLAGS)
|
||||
|
||||
PKG_PROG_PKG_CONFIG()
|
||||
|
||||
dnl lets see if we support c++11
|
||||
AX_CXX_COMPILE_STDCXX_11([noext], [optional])
|
||||
|
||||
dnl The configuration options
|
||||
dnl -------------------------
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
# ============================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
|
||||
# ============================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check for baseline language coverage in the compiler for the C++11
|
||||
# standard; if necessary, add switches to CXXFLAGS to enable support.
|
||||
#
|
||||
# The first argument, if specified, indicates whether you insist on an
|
||||
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
|
||||
# -std=c++11). If neither is specified, you get whatever works, with
|
||||
# preference for an extended mode.
|
||||
#
|
||||
# The second argument, if specified 'mandatory' or if left unspecified,
|
||||
# indicates that baseline C++11 support is required and that the macro
|
||||
# should error out if no mode with that support is found. If specified
|
||||
# 'optional', then configuration proceeds regardless, after defining
|
||||
# HAVE_CXX11 if and only if a supporting mode is found.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Benjamin Kosnik <[email protected]>
|
||||
# Copyright (c) 2012 Zack Weinberg <[email protected]>
|
||||
# Copyright (c) 2013 Roy Stogner <[email protected]>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 3
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
|
||||
template <typename T>
|
||||
struct check
|
||||
{
|
||||
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
||||
};
|
||||
|
||||
typedef check<check<bool>> right_angle_brackets;
|
||||
|
||||
int a;
|
||||
decltype(a) b;
|
||||
|
||||
typedef check<int> check_type;
|
||||
check_type c;
|
||||
check_type&& cr = static_cast<check_type&&>(c);
|
||||
|
||||
auto d = a;
|
||||
])
|
||||
|
||||
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
|
||||
m4_if([$1], [], [],
|
||||
[$1], [ext], [],
|
||||
[$1], [noext], [],
|
||||
[m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
|
||||
m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
|
||||
[$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
|
||||
[$2], [optional], [ax_cxx_compile_cxx11_required=false],
|
||||
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl
|
||||
AC_LANG_PUSH([C++])dnl
|
||||
ac_success=no
|
||||
AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
|
||||
ax_cv_cxx_compile_cxx11,
|
||||
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||
[ax_cv_cxx_compile_cxx11=yes],
|
||||
[ax_cv_cxx_compile_cxx11=no])])
|
||||
if test x$ax_cv_cxx_compile_cxx11 = xyes; then
|
||||
ac_success=yes
|
||||
fi
|
||||
|
||||
m4_if([$1], [noext], [], [dnl
|
||||
if test x$ac_success = xno; then
|
||||
for switch in -std=gnu++11 -std=gnu++0x; do
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
ac_success=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi])
|
||||
|
||||
m4_if([$1], [ext], [], [dnl
|
||||
if test x$ac_success = xno; then
|
||||
for switch in -std=c++11 -std=c++0x; do
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
ac_success=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi])
|
||||
AC_LANG_POP([C++])
|
||||
if test x$ax_cxx_compile_cxx11_required = xtrue; then
|
||||
if test x$ac_success = xno; then
|
||||
AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
|
||||
fi
|
||||
else
|
||||
if test x$ac_success = xno; then
|
||||
HAVE_CXX11=0
|
||||
AC_MSG_NOTICE([No compiler with C++11 support was found])
|
||||
else
|
||||
HAVE_CXX11=1
|
||||
AC_DEFINE(HAVE_CXX11,1,
|
||||
[define if the compiler supports basic C++11 syntax])
|
||||
fi
|
||||
|
||||
AC_SUBST(HAVE_CXX11)
|
||||
fi
|
||||
])
|
||||
Reference in new issue
Block a user