87 #define NUM_SHIP_SUBSYSTEM_SETS 20 // number of subobject sets to use (because of the fact that it's a linked list,
90 #define NUM_SHIP_SUBSYSTEMS_PER_SET 200 // Reduced from 1000 to 400 by MK on 4/1/98. DTP; bumped from 700 to 2100
97 static int Num_ship_subsystems = 0;
98 static int Num_ship_subsystems_allocated = 0;
111 #define SHIP_REPAIR_SUBSYSTEM_RATE 0.01f
159 #define SHIP_OBJ_USED (1<<0) // flag used in ship_obj struct
160 #define MAX_SHIP_OBJS MAX_SHIPS // max number of ships tracked in ship list
319 {
"ballistic primaries", -1, 255 }
398 static int Laser_energy_out_snd_timer;
399 static int Missile_out_snd_timer;
406 static int Ship_cargo_check_timer;
408 static int Thrust_anim_inited = 0;
473 if ( i == MAX_SHIP_OBJS ) {
474 Error(
LOCATION,
"Fatal Error: Ran out of ship object nodes\n");
516 return &Ship_objs[
index];
552 bool create_if_not_found =
true;
560 Warning(
LOCATION,
"+nocreate flag used for engine wash in non-modular table");
562 create_if_not_found =
false;
573 nprintf((
"Warning",
"More than one version of engine wash %s exists; using newer version.", ewt.
name));
577 Error(
LOCATION,
"Error: Engine wash %s already exists. All engine wash names must be unique.", ewt.
name);
583 if(!create_if_not_found && replace)
590 Engine_wash_info.push_back(ewt);
653 if(!
stricmp(Lightning_types[i], p))
661 #define SHIP_MULTITEXT_LENGTH 4096
662 #define DEFAULT_DELTA_BANK_CONST 0.5f
664 #define CHECK_THEN_COPY(attribute) \
666 if (other.attribute != NULL)\
667 attribute = vm_strdup( other.attribute );\
979 std::swap(
name, other.name);
980 std::swap(
alt_name, other.alt_name);
985 std::swap(
type_str, other.type_str);
989 std::swap(
desc, other.desc);
1000 std::swap(
pof_file, other.pof_file);
1015 std::swap(
max_vel, other.max_vel);
1046 flags = other.flags;
1156 score = other.score;
1160 std::swap(
ct_info, other.ct_info);
1249 std::swap(
displays, other.displays);
1256 #define CHECK_THEN_FREE(attribute) \
1258 if (attribute != NULL) {\
1259 vm_free(attribute);\
1279 if (
this != &other) {
1280 move(std::move(other));
1301 move(std::move(other));
1513 for (i = 0; i < 4; i++)
1692 bool create_if_not_found =
true;
1700 Warning(
LOCATION,
"+nocreate flag used for ship in non-modular table");
1702 create_if_not_found =
false;
1713 if ( buf[0] ==
'@' ) {
1720 bool first_time =
false;
1725 sip = &Ship_info[ship_id];
1728 Warning(
LOCATION,
"Error: Ship name %s already exists in %s. All ship class names must be unique.", sip->
name, filename);
1738 if(!create_if_not_found && replace)
1754 sip = &Ship_info.back();
1762 if ( !create_if_not_found ) {
1763 Warning(
LOCATION,
"Both '+nocreate' and '+Use Template:' were specified for ship class '%s', ignoring '+Use Template:'\n", buf);
1769 if ( template_id != -1 ) {
1771 sip->
clone(Ship_templates[template_id]);
1775 Warning(
LOCATION,
"Unable to find ship template '%s' requested by ship class '%s', ignoring template request...", template_name, buf);
1793 bool first_time =
true;
1799 Warning(
LOCATION,
"+nocreate flag used on ship template. Ship templates can not be modified. Ignoring +nocreate.");
1807 if( template_id != -1 ) {
1808 sip = &Ship_templates[template_id];
1809 Warning(
LOCATION,
"WARNING: Ship template %s already exists. All ship template names must be unique.", sip->
name);
1811 error_display(1,
"Missing [#End] or [$Template] after duplicate entry for %s", sip->
name);
1818 sip = &Ship_templates.back();
1827 if ( template_id != -1 ) {
1829 sip->
clone(Ship_templates[template_id]);
1833 Warning(
LOCATION,
"Unable to find ship template '%s' requested by ship template '%s', ignoring template request...", template_name, buf);
1847 int temp_index = -1;
1851 if (temp_index >= 0)
1852 sip->
ship_sounds.insert(std::pair<GameSoundsIndex, int>(
id, temp_index));
1892 Warning(
LOCATION,
"Bad value %i, defined as %s particle number (max) in ship '%s'.\nValue should be a non-negative integer.\n", temp, id_string, sip->
name);
1897 mprintf((
"Particle effect for %s disabled on ship '%s'.\n", id_string, sip->
name));
1905 Warning(
LOCATION,
"Bad value %i, defined as %s particle number (min) in ship '%s'.\nValue should be a non-negative integer.\n", temp, id_string, sip->
name);
1916 if (tempf <= 0.0
f) {
1917 Warning(
LOCATION,
"Bad value %f, defined as %s particle radius (max) in ship '%s'.\nValue should be a positive float.\n", tempf, id_string, sip->
name);
1926 Warning(
LOCATION,
"Bad value %f, defined as %s particle radius (min) in ship '%s'.\nValue should be a non-negative float.\n", tempf, id_string, sip->
name);
1937 if (tempf <= 0.0
f) {
1938 Warning(
LOCATION,
"Bad value %f, defined as %s particle lifetime (max) in ship '%s'.\nValue should be a positive float.\n", tempf, id_string, sip->
name);
1947 Warning(
LOCATION,
"Bad value %f, defined as %s particle lifetime (min) in ship '%s'.\nValue should be a non-negative float.\n", tempf, id_string, sip->
name);
1959 Warning(
LOCATION,
"Bad value %f, defined as %s particle velocity (max) in ship '%s'.\nValue should be a non-negative float.\n", tempf, id_string, sip->
name);
1968 Warning(
LOCATION,
"Bad value %f, defined as %s particle velocity (min) in ship '%s'.\nValue should be a non-negative float.\n", tempf, id_string, sip->
name);
1979 if ((tempf >= 0.0
f) && (tempf <= 2.0
f)) {
1982 Warning(
LOCATION,
"Bad value %f, defined as %s particle normal variance in ship '%s'.\nValue should be a float from 0.0 to 2.0.\n", tempf, id_string, sip->
name);
1994 const char *allowed_banks_str = is_primary ? (is_dogfight ?
"$Allowed Dogfight PBanks:" :
"$Allowed PBanks:")
1995 : (is_dogfight ?
"$Allowed Dogfight SBanks:" :
"$Allowed SBanks:");
1996 const char *bank_type_str = is_primary ?
"primary" :
"secondary";
2007 for (bank = 0; bank < max_banks; bank++) {
2022 if (bank >= max_banks)
2024 Warning(
LOCATION,
"%s bank-specific loadout for %s exceeds permissible number of %s banks. Ignoring the rest...", allowed_banks_str, sip->
name, bank_type_str);
2032 for ( i = 0; i < num_allowed; i++ )
2034 if ( allowed_weapons[i] >= 0 )
2044 for (i=0; i<=bank; i++)
2059 Assert(bank_default_weapons != NULL);
2060 Assert(bank_capacities != NULL);
2062 const char *default_banks_str = is_primary ?
"$Default PBanks:" :
"$Default SBanks:";
2063 const char *bank_capacities_str = is_primary ?
"$PBank Capacity:" :
"$SBank Capacity:";
2066 int num_bank_capacities = num_banks != NULL ? *num_banks : 0;
2071 if (num_banks != NULL)
2084 if ((num_banks != NULL) && (*num_banks != num_bank_capacities))
2087 if (is_primary && num_bank_capacities != 0)
2089 Warning(
LOCATION,
"Ship class '%s' has %d primary banks, but %d primary capacities... fix this!!", sip->
name, *num_banks, num_bank_capacities);
2095 Warning(
LOCATION,
"Ship class '%s' has %d secondary banks, but %d secondary capacities... fix this!!", sip->
name, *num_banks, num_bank_capacities);
2125 bii_index = (
int) icon;
2151 char* info_type_name;
2157 if ( ! is_template ) {
2158 info_type_name =
"Ship Class";
2159 type_name =
"$Name";
2162 info_type_name =
"Ship Template";
2163 type_name =
"$Template";
2171 else if (first_time)
2173 char *srcpos, *srcend, *destpos;
2176 srcend = srcpos + strlen(sip->
name);
2177 while(srcpos <= srcend)
2180 *destpos++ = *srcpos++;
2194 if (!
stricmp(temp, sii->species_name)) {
2202 Error(
LOCATION,
"Invalid Species %s defined in table entry for ship %s.\n", temp, sip->
name);
2255 else if (!
stricmp(effect,
"FS1"))
2257 else if (!
stricmp(effect,
"off"))
2291 display.
name[0] = 0;
2315 if ( display.
offset[0] < 0 || display.
offset[1] < 0 ) {
2316 Warning(
LOCATION,
"Negative display offsets given for cockpit display on %s, skipping entry", sip->
name);
2320 if( display.
size[0] <= 0 || display.
size[1] <= 0 ) {
2321 Warning(
LOCATION,
"Negative or zero display size given for cockpit display on %s, skipping entry", sip->
name);
2368 mprintf((
"Extraneous extension found on replacement texture %s!\n", tr.
old_texture));
2374 mprintf((
"Extraneous extension found on replacement texture %s!\n", tr.
new_texture));
2382 mprintf((
"Too many replacement textures specified for ship '%s'!\n", sip->
name));
2453 Warning(
LOCATION,
"Team name %s is invalid. Teams must be defined in colors.tbl.\n", temp);
2584 Warning(
LOCATION,
"Debris min lifetime on %s '%s' is below 0 and will be ignored", info_type_name, sip->
name);
2589 Warning(
LOCATION,
"Debris max lifetime on %s '%s' is below 0 and will be ignored", info_type_name, sip->
name);
2594 Warning(
LOCATION,
"Debris min speed on %s '%s' is below 0 and will be ignored", info_type_name, sip->
name);
2599 Warning(
LOCATION,
"Debris max speed on %s '%s' is below 0 and will be ignored", info_type_name, sip->
name);
2604 Warning(
LOCATION,
"Debris min speed on %s '%s' is below 0 and will be ignored", info_type_name, sip->
name);
2609 Warning(
LOCATION,
"Debris max speed on %s '%s' is below 0 and will be ignored", info_type_name, sip->
name);
2618 Warning(
LOCATION,
"Debris min hitpoints on %s '%s' is below 0 and will be ignored", info_type_name, sip->
name);
2623 Warning(
LOCATION,
"Debris max hitpoints on %s '%s' is below 0 and will be ignored", info_type_name, sip->
name);
2628 Warning(
LOCATION,
"Debris damage multiplier on %s '%s' is below 0 and will be ignored", info_type_name, sip->
name);
2690 Warning(
LOCATION,
"Rotation time must have non-zero values in each of the three variables.\nFix this in %s %s\n", info_type_name, sip->
name);
2745 if (fov_temp < 0.0
f)
2748 if (fov_temp > 180.0
f)
2792 Warning(
LOCATION,
"Invalid warpin type '%s' specified for %s '%s'", buf, info_type_name, sip->
name);
2811 Warning(
LOCATION,
"Warp-in time specified as 0 or less on %s '%s'; value ignored", info_type_name, sip->
name);
2819 Warning(
LOCATION,
"Warp-in deceleration exponent specified as less than 0 on %s '%s'; value ignored", info_type_name, sip->
name);
2828 Warning(
LOCATION,
"Warp-in radius specified as 0 or less on %s '%s'; value ignored", info_type_name, sip->
name);
2844 Warning(
LOCATION,
"Invalid warpout type '%s' specified for %s '%s'", buf, info_type_name, sip->
name);
2859 Warning(
LOCATION,
"Warp-out engage time specified as 0 or less on %s '%s'; value ignored", info_type_name, sip->
name);
2875 Warning(
LOCATION,
"Warp-out time specified as 0 or less on %s '%s'; value ignored", info_type_name, sip->
name);
2883 Warning(
LOCATION,
"Warp-out acceleration exponent specified as less than 0 on %s '%s'; value ignored", info_type_name, sip->
name);
2892 Warning(
LOCATION,
"Warp-out radius specified as 0 or less on %s '%s'; value ignored", info_type_name, sip->
name);
2906 Warning(
LOCATION,
"Player warp-out speed cannot be 0; value ignored.");
2936 Warning(
LOCATION,
"Propagating explosion radius multiplier was set to non-positive value.\nDefaulting multiplier to 1.0 on %s '%s'.\n", info_type_name, sip->
name);
3096 for (i = 0; i < num_strings; i++) {
3097 const char *str = ctrl_strings[
i].c_str();
3101 else if (!
stricmp(str,
"rear"))
3103 else if (!
stricmp(str,
"left"))
3105 else if (!
stricmp(str,
"right"))
3107 else if (!
stricmp(str,
"none"))
3110 Warning(
LOCATION,
"Unrecognized value \"%s\" passed to $Model Point Shield Controls, ignoring...", str);
3141 else if (first_time)
3155 else if (first_time)
3160 else if (first_time)
3171 Warning(
LOCATION,
"Max hull strength on %s '%s' cannot be less than 0. Defaulting to 100.\n", info_type_name, sip->
name);
3225 Warning(
LOCATION,
"Invalid armor name %s specified for hull in %s '%s'", buf, info_type_name, sip->
name);
3234 Warning(
LOCATION,
"Invalid armor name %s specified for shield in %s '%s'", buf, info_type_name, sip->
name);
3243 int ship_type_index = -1;
3252 for (i = 0; i < num_strings; i++)
3255 char *ship_type = ship_strings[
i];
3256 bool flag_found =
false;
3261 if (!
stricmp(ship_type,
"sentrygun"))
3262 ship_type =
"sentry gun";
3263 else if (!
stricmp(ship_type,
"escapepod"))
3264 ship_type =
"escape pod";
3265 else if (!
stricmp(ship_type,
"repair_rearm"))
3266 ship_type =
"support";
3267 else if (!
stricmp(ship_type,
"supercap"))
3268 ship_type =
"super cap";
3269 else if (!
stricmp(ship_type,
"knossos"))
3270 ship_type =
"knossos device";
3276 if ((ship_type_index >= 0) && (sip->
class_type < 0))
3284 if (Ship_flags[
idx].var == 255)
3285 Warning(
LOCATION,
"Use of '%s' flag for %s '%s' - this flag is no longer needed.", Ship_flags[
idx].name, info_type_name, sip->
name);
3286 else if (Ship_flags[
idx].var == 0)
3288 else if (Ship_flags[
idx].var == 1)
3293 if ( !flag_found && (ship_type_index < 0) )
3294 Warning(
LOCATION,
"Bogus string in ship flags: %s\n", ship_strings[i]);
3344 int has_afterburner = 0;
3349 if ( has_afterburner == 1 )
3382 Warning(
LOCATION,
"%s '%s' has an afterburner but has no afterburner fuel. Setting fuel to 1", info_type_name, sip->
name);
3388 bool trails_warning =
true;
3391 trails_warning =
false;
3397 trails_warning =
false;
3402 trails_warning =
false;
3407 trails_warning =
false;
3412 trails_warning =
false;
3417 Warning(
LOCATION,
"%s %s entry has $Trails field specified, but no properties given.", info_type_name, sip->
name);
3424 Warning(
LOCATION,
"Could not find weapon type '%s' to use as countermeasure on %s '%s'", buf, info_type_name, sip->
name);
3426 Warning(
LOCATION,
"Attempt made to set a beam weapon as a countermeasure on %s '%s'", info_type_name, sip->
name);
3458 else if (first_time && strlen(sip->
pof_file))
3482 mprintf((
"Warning! Ship '%s' has a $Closeup_zoom value that is less than or equal to 0 (%f). Setting to default value.\n", sip->
name, sip->
closeup_zoom));
3506 angles model_icon_angles = {0.0f,0.0f,0.0f};
3509 model_icon_angles.
p = -
PI_2;
3510 }
else if (!
stricmp(str,
"bottom")) {
3511 model_icon_angles.
p = -
PI_2;
3512 model_icon_angles.
b = 2 *
PI_2;
3513 }
else if (!
stricmp(str,
"front")) {
3514 model_icon_angles.
h = 2 *
PI_2;
3515 }
else if (!
stricmp(str,
"back")) {
3516 model_icon_angles.
h = 4 *
PI_2;
3517 }
else if (!
stricmp(str,
"left")) {
3518 model_icon_angles.
h = -
PI_2;
3519 }
else if (!
stricmp(str,
"right")) {
3520 model_icon_angles.
h =
PI_2;
3522 Warning(
LOCATION,
"Unrecognized value \"%s\" passed to $Model Icon Direction, ignoring...", str);
3550 Warning(
LOCATION,
"%s '%s' has a wing-with-cargo briefing icon but is missing a wing briefing icon or a ship-with-cargo briefing icon!", info_type_name, sip->
name);
3552 Warning(
LOCATION,
"%s '%s' has both a wing briefing icon and a ship-with-cargo briefing icon but does not have a wing-with-cargo briefing icon!", info_type_name, sip->
name);
3625 Warning(
LOCATION,
"Deprecated spelling: \"$Thruster01 Length factor:\". Use \"$Thruster02 Length factor:\" instead.");
3682 bool afterburner =
false;
3686 afterburner =
false;
3690 Error(
LOCATION,
"formatting error in the thruster's particle section for %s '%s'\n", info_type_name, sip->
name );
3723 Warning(
LOCATION,
"%s '%s' is missing the colon after \"$Stealth\". Note that you may also use the ship flag \"stealth\".", info_type_name, sip->
name);
3730 WarningEx(
LOCATION,
"The decal system has been deactivated in FSO builds. Entries will be discarded.\n");
3731 mprintf((
"WARNING: The decal system has been deactivated in FSO builds. Entries will be discarded.\n"));
3791 if(idx >= 0 && idx < sip->num_maneuvering) {
3793 }
else if(idx < 0) {
3801 Warning(
LOCATION,
"Invalid index (%d) specified for maneuvering thruster on %s '%s'", idx, info_type_name, sip->
name);
3819 int tex_fps=0, tex_nframes=0, tex_id=-1;;
3855 seppos = token->find_first_of(
':');
3856 if(seppos == SCP_string::npos) {
3857 Warning(
LOCATION,
"Couldn't find ':' seperator in Glowpoint override for ship %s ignoring token", sip->
name);
3860 name = token->substr(0, seppos);
3861 banks = token->substr(seppos+1);
3864 Warning(
LOCATION,
"Couldn't find preset %s in glowpoints.tbl when parsing ship: %s", name.data(), sip->
name);
3875 end = banks.find_first_of(
',', ++start);
3876 banktoken = banks.substr(start, end);
3880 fromtopos = banktoken.find_first_of(
'-');
3881 if(fromtopos != SCP_string::npos) {
3884 from = banktoken.substr(0, fromtopos);
3885 to = banktoken.substr(fromtopos+1);
3886 ifrom = atoi(from.data()) - 1;
3887 ito = atoi(to.data()) - 1;
3888 for(
int bank = ifrom; bank <= ito; ++bank) {
3892 int bank = atoi(banktoken.data()) - 1;
3921 int iff_color_data[3];
3933 if (iff_data[0] == -1)
3934 WarningEx(
LOCATION,
"%s '%s'\nIFF colour seen by \"%s\" invalid!", info_type_name, sip->
name, iff_1);
3936 if (iff_data[1] == -1)
3937 WarningEx(
LOCATION,
"%s '%s'\nIFF colour when IFF is \"%s\" invalid!", info_type_name, sip->
name, iff_2);
3948 int num_groups = Ai_tp_list.size();
3949 bool override_strings =
false;
3952 override_strings =
true;
3955 for(j = 0; j < num_strings; j++) {
3956 for(i = 0; i < num_groups; i++) {
3957 if ( !
stricmp(target_group_strings[j].c_str(), Ai_tp_list[i].
name) ) {
3960 if (override_strings) {
3961 Ai_tp_list[
i].ship_class.clear();
3962 override_strings =
false;
3964 for (
auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it) {
3966 if (it->name == sip->
name) {
3967 Ai_tp_list[
i].ship_class.push_back(std::distance(Ship_info.cbegin(), it));
3975 if (i == num_groups) {
3976 Warning(
LOCATION,
"Unidentified priority group '%s' set for %s '%s'\n", target_group_strings[j].c_str(), info_type_name, sip->
name);
4019 int n_subsystems = 0;
4026 float hull_percentage_of_hits = 100.0f;
4042 float percentage_of_hits;
4043 bool turret_has_base_fov =
false;
4058 if( sip->
n_subsystems + n_subsystems >= MAX_MODEL_SUBSYSTEMS )
4060 Warning(
LOCATION,
"Number of subsystems for %s '%s' (%d) exceeds max of %d; only the first %d will be used", info_type_name, sip->
name, sip->
n_subsystems, n_subsystems, MAX_MODEL_SUBSYSTEMS);
4063 sp = &subsystems[n_subsystems++];
4108 for (i = 0; i < 32; i++) {
4122 hull_percentage_of_hits -= percentage_of_hits;
4131 if ( turning_rate > 0.0
f ){
4139 Error(
LOCATION,
"Malformed $Subsystem entry '%s' in %s '%s'.\n\n"
4140 "Specify a turning rate or remove the trailing comma.",
4214 turret_has_base_fov =
true;
4239 if (num_strings > 32)
4242 int num_groups = Ai_tp_list.size();
4244 for(i = 0; i < num_strings; i++) {
4245 for(j = 0; j < num_groups; j++) {
4246 if ( !
stricmp(Ai_tp_list[j].
name, tgt_priorities[i].c_str())) {
4252 if (j == num_groups) {
4253 Warning(
LOCATION,
"Unidentified target priority '%s' set for\nsubsystem '%s' in %s '%s'.", tgt_priorities[i].c_str(), sp->
subobj_name, info_type_name, sip->
name);
4276 mprintf((
"RoF multiplier clamped to 0 for subsystem '%s' in %s '%s'.\n", sp->
subobj_name, info_type_name, sip->
name));
4298 for (i = 0; i < num_strings; i++)
4301 bool flag_found =
false;
4307 if (Subsystem_flags[
idx].var == 0)
4309 else if (Subsystem_flags[
idx].var == 1)
4315 Warning(
LOCATION,
"Bogus string in subsystem flags: %s\n", flag_strings[i]);
4323 if (turret_has_base_fov)
4327 Warning(
LOCATION,
"Grammar error in table file. Please change \"+non-targetable\" to \"+untargetable\".");
4331 bool old_flags =
false;
4353 Warning(
LOCATION,
"\"fixed firingpoints\" flag used without \"use multiple guns\" flag on a subsystem on %s '%s'.\n\"use multiple guns\" flags added by default\n", info_type_name, sip->
name);
4358 Warning(
LOCATION,
"\"autorepair if disabled\" flag used with \"don't autorepair if disabled\" flag on a subsystem on %s '%s'.\nWhichever flag would be default behavior anyway for this ship has been removed.\n", info_type_name, sip->
name);
4367 mprintf((
"Use of deprecated subsystem syntax. Please use the $Flags: field for subsystem flags.\n\n" \
4368 "At least one of the following tags was used on %s '%s', subsystem %s:\n" \
4369 "\t+untargetable\n" \
4370 "\t+carry-no-damage\n" \
4371 "\t+use-multiple-guns\n" \
4372 "\t+fire-down-normals\n", info_type_name, sip->
name, sp->
subobj_name));
4378 if(!
stricmp(name_tmp,
"triggered"))
4415 current_trigger->
start = 0;
4458 current_trigger->
end = 0;
4464 current_trigger->
start = 0;
4500 current_trigger->
accel.
xyz.x = 0.0f;
4501 current_trigger->
accel.
xyz.y = 0.0f;
4502 current_trigger->
accel.
xyz.z = 0.0f;
4508 current_trigger->
end = 0;
4530 else if(!
stricmp(name_tmp,
"linked"))
4532 mprintf((
"TODO: set up linked animation\n"));
4544 Assertion(
false,
"This should never happen.\n");
4551 if (hull_percentage_of_hits <= 0.0
f )
4557 if ( n_subsystems > 0 ) {
4567 for ( i = 0; i < n_subsystems; i++ ){
4581 if(!
stricmp(engine_wash_name, Engine_wash_info[
i].
name))
4583 return &Engine_wash_info[
i];
4594 bool nocreate =
false;
4607 stp = &Ship_types[
idx];
4615 char *ship_type = NULL;
4617 ship_type =
"sentry gun";
4619 ship_type =
"escape pod";
4621 ship_type =
"support";
4623 ship_type =
"super cap";
4625 ship_type =
"knossos device";
4628 if (ship_type != NULL) {
4629 Warning(
LOCATION,
"Bad ship type name in objecttypes.tbl\n\nUsed ship type is redirected to another ship type.\nReplace \"%s\" with \"%s\"\nin objecttypes.tbl to fix this.\n", stp->
name, ship_type);
4640 int num_groups = Ai_tp_list.size();
4642 bool override_strings =
false;
4645 override_strings =
true;
4648 for(j = 0; j < num_strings; j++) {
4649 for(i = 0; i < num_groups; i++) {
4650 if ( !
stricmp(target_group_strings[j].c_str(), Ai_tp_list[i].
name) ) {
4653 if (override_strings) {
4654 Ai_tp_list[
i].ship_type.clear();
4655 override_strings =
false;
4662 if (i == num_groups) {
4663 Warning(
LOCATION,
"Unidentified priority group '%s' set for objecttype '%s'\n", target_group_strings[j].c_str(), stp->
name);
4813 Ship_types.push_back(stp_buf);
4820 if (filename != NULL)
4856 mprintf((
"TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
4866 for (
auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it)
4869 return std::distance(Ship_info.cbegin(), it);
4884 for(
auto it = Ship_info.cbegin(); it != Ship_info.end(); ++it)
4894 for(
auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it)
4904 if(!Ship_info.empty())
4970 mprintf((
"TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
4978 DCF_BOOL( show_velocity_dot, ship_show_velocity_dot )
4988 for (
auto sip = Ship_info.begin(); sip != Ship_info.end(); ++sip)
4992 bool pbank_capacity_specified =
false;
4995 for (j = 0; j < sip->num_primary_banks; j++) {
4996 if (sip->primary_bank_ammo_capacity[j] > 0) {
4997 pbank_capacity_specified =
true;
5003 if (pbank_capacity_specified) {
5005 Warning(
LOCATION,
"Pbank capacity specified for non-ballistic-primary-enabled ship %s.\nResetting capacities to 0.\nTo fix this, add a ballistic primary to the list of allowed primaries.\n", sip->name);
5008 sip->primary_bank_ammo_capacity[j] = 0;
5013 Warning(
LOCATION,
"Pbank capacity not specified for ballistic-primary-enabled ship %s.\nDefaulting to capacity of 1 per bank.\n", sip->name);
5016 sip->primary_bank_ammo_capacity[j] = 1;
5024 if ( (sip->shield_icon_index == 255) && (sip->flags &
SIF_AFTERBURNER)
5027 Warning(
LOCATION,
"Compatibility warning:\nNo shield icon specified for '%s' but the \"generate icon\" flag is not specified.\nEnabling flag by default.\n", sip->name);
5040 Warning(
LOCATION,
"Ship %s is a copy, but base ship %s couldn't be found.", sip->name, name_tmp);
5046 Warning(
LOCATION,
"Ship %s is defined as a copy (ship flag 'ship copy' is set), but is not named like one (no '#').\n", sip->name);
5056 Warning(
LOCATION,
"$Rotation time: too low; this will disable rotational collisions. All three variables should be >= 1.39.\nFix this in ship '%s'\n", sip->name);
5061 int n_tgt_groups = Ai_tp_list.size();
5063 if (n_tgt_groups > 0) {
5064 for(i = 0; i < n_tgt_groups; i++) {
5065 if (!(Ai_tp_list[i].obj_flags || Ai_tp_list[i].sif_flags || Ai_tp_list[i].sif2_flags || Ai_tp_list[i].wif2_flags || Ai_tp_list[i].wif_flags)) {
5067 if (Ai_tp_list[i].obj_type == -1) {
5069 if (!(Ai_tp_list[i].ship_class.size() || Ai_tp_list[
i].ship_type.size() || Ai_tp_list[
i].weapon_class.size())) {
5071 Warning(
LOCATION,
"Target priority group '%s' had no targeting rules issued for it.\n", Ai_tp_list[i].
name);
5079 Ship_templates.clear();
5104 for(i = 0; i < Ship_types.size(); i++)
5106 stp = &Ship_types[
i];
5146 Ship_subsystems[i] = NULL;
5154 static void ship_clear_subsystems()
5159 if (Ship_subsystems[i] != NULL) {
5160 delete[] Ship_subsystems[
i];
5161 Ship_subsystems[
i] = NULL;
5165 Num_ship_subsystems = 0;
5166 Num_ship_subsystems_allocated = 0;
5171 static int ship_allocate_subsystems(
int num_so,
bool page_in =
false)
5174 int num_subsystems_save = 0;
5185 num_subsystems_save = Num_ship_subsystems;
5187 Num_ship_subsystems += num_so;
5190 if ( Num_ship_subsystems < Num_ship_subsystems_allocated )
5193 mprintf((
"Allocating space for at least %i new ship subsystems ... ", num_so));
5198 if (Ship_subsystems[idx] == NULL)
5203 if (idx == NUM_SHIP_SUBSYSTEM_SETS) {
5211 list_append( &ship_subsys_free_list, &Ship_subsystems[idx][i] );
5214 }
while ( (Num_ship_subsystems - Num_ship_subsystems_allocated) > 0 );
5217 Num_ship_subsystems = num_subsystems_save;
5219 mprintf((
" a total of %i is now available (%i in-use).\n", Num_ship_subsystems_allocated, Num_ship_subsystems));
5231 Ships_exited.clear();
5232 Ships_exited.reserve(100);
5278 ship_clear_subsystems();
5281 Laser_energy_out_snd_timer = 1;
5282 Missile_out_snd_timer = 1;
5286 Ship_cargo_check_timer = 1;
5290 Man_thruster_reset_timestamp =
timestamp(0);
5306 entry.
flags = reason;
5332 Ships_exited.push_back(entry);
5342 for (i = 0; i < (
int)Ships_exited.size(); i++) {
5343 if ( !
stricmp(name, Ships_exited[i].ship_name) )
5357 for (i = 0; i < (
int)Ships_exited.size(); i++) {
5358 if ( signature == Ships_exited[i].obj_signature )
5380 float vmass=size.
xyz.x*size.
xyz.y*size.
xyz.z;
5381 float amass=4.65f*(
float)pow(vmass,(2.0
f/3.0
f));
5383 nprintf((
"Physics",
"pi->mass==0.0f. setting to %f\n",amass));
5395 nprintf((
"Physics",
"pm->moment_of_inertia is invalid for %s!\n", pm->
filename));
5467 strcpy(output,
"Unknown");
5471 strcpy(output, Ship_types[sip->
class_type].name);
5483 return Ship_types[sip->
class_type].ai_player_orders;
5869 void ship_set(
int ship_index,
int objnum,
int ship_type)
5874 ship_info *sip = &(Ship_info[ship_type]);
5880 oo_arrive_time_count[shipp -
Ships] = 0;
5881 oo_interp_count[shipp -
Ships] = 0;
5923 sprintf (err_msg,
"Unable to allocate ship subsystems. Maximum is %d. No subsystems have been assigned to %s.", (NUM_SHIP_SUBSYSTEM_SETS* NUM_SHIP_SUBSYSTEMS_PER_SET), shipp->
ship_name);
5975 if ( weapon_size > 0.0
f )
6040 Assert ( (type >= 0) && (type < SUBSYSTEM_MAX) );
6136 for (
auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it ) {
6139 if ( (it->model_num != model_num) || (&(*it) == sip) ){
6147 source_msp = &it->subsystems[0];
6232 for (i = 0; i < 32; i++)
6266 if (!ship_allocate_subsystems( sinfo->
n_subsystems )) {
6274 Warning (
LOCATION,
"Invalid subobj_num or model_num in subsystem '%s' on ship type '%s'.\nNot linking into ship!\n\n(This warning means that a subsystem was present in the table entry and not present in the model\nit should probably be removed from the table or added to the model.)\n", model_system->
subobj_name, sinfo->
name );
6279 ship_system =
GET_FIRST( &ship_subsys_free_list );
6280 Assert ( ship_system != &ship_subsys_free_list );
6281 list_remove( ship_subsys_free_list, ship_system );
6283 ship_system->
clear();
6299 for (j = 0; j < 32; j++) {
6306 ship_system->
flags = 0;
6381 int number_of_weapons = 0;
6394 number_of_weapons += j;
6408 number_of_weapons += j;
6420 Warning (
LOCATION,
"\"salvo mode\" flag used with \"fixed firingpoints\" flag\nsubsystem '%s' on ship type '%s'.\n\"salvo mode\" flag is ignored\n", model_system->
subobj_name, sinfo->
name );
6426 Warning (
LOCATION,
"\"salvo mode\" flag used with turret which has less than two firingpoints\nsubsystem '%s' on ship type '%s'.\n\"salvo mode\" flag is ignored\n", model_system->
subobj_name, sinfo->
name );
6432 Warning (
LOCATION,
"\"fixed firingpoints\" flag used with turret which has less than two firingpoints\nsubsystem '%s' on ship type '%s'.\n\"fixed firingpoints\" flag is ignored\n", model_system->
subobj_name, sinfo->
name );
6438 Warning (
LOCATION,
"\"salvo mode\" flag used with \"use multiple guns\" flag\nsubsystem '%s' on ship type '%s'.\n\"use multiple guns\" flag is ignored\n", model_system->
subobj_name, sinfo->
name );
6444 Warning (
LOCATION,
"\"fixed firingpoints\" flag used without \"use multiple guns\" flag\nsubsystem '%s' on ship type '%s'.\n\"use multiple guns\" guns added by default\n", model_system->
subobj_name, sinfo->
name );
6450 Warning (
LOCATION,
"\"salvo mode\" flag used with turret which has more than one weapon defined for it\nsubsystem '%s' on ship type '%s'.\nonly single weapon will be used\n", model_system->
subobj_name, sinfo->
name );
6455 Warning (
LOCATION,
"\"fixed firingpoint\" flag used with turret which has more weapons defined for it than it has firingpoints\nsubsystem '%s' on ship type '%s'.\nweapons will share firingpoints\n", model_system->
subobj_name, sinfo->
name );
6460 Warning (
LOCATION,
"\"fixed firingpoint\" flag used with turret which has less weapons defined for it than it has firingpoints\nsubsystem '%s' on ship type '%s'.\nsome of the firingpoints will be left unused\n", model_system->
subobj_name, sinfo->
name );
6465 Warning(
LOCATION,
"\"share fire direction\" flag used with turret which does not have the \"salvo mode\" flag set\nsubsystem '%s' on ship type '%s'.\nsetting the \"salvo mode\" flag\n", model_system->
subobj_name, sinfo->
name);
6482 if (weapon_size > 0.0
f) {
6506 float turn_accel = 0.5f;
6522 if ( !ignore_subsys_info ) {
6552 t1.
h = 0.0f; t1.
b = 0.0f;
6553 t2.
p = 0.0f; t2.
b = 0.0f;
6616 DCF_BOOL( ship_shadows, Ship_shadows )
6621 DCF_BOOL( show_shield_hits, Show_shield_hits )
6624 DCF_BOOL( show_tnorms, Show_tnorms )
6630 DCF_BOOL( show_fpaths, Show_fpaths )
6643 if (infop->maintained_variables.bool_value)
6651 infop->maintained_variables.bool_value =
true;
6652 infop->maintained_variables.objp_value =
objp;
6656 infop->early_return_condition =
true;
6671 size_t mant_size = Man_thrusters.size();
6676 for(
size_t i = 0; i < mant_size; i++)
6678 mtr = &Man_thrusters[
i];
6686 if(
timestamp() - Man_thruster_reset_timestamp > 10000)
6688 Man_thrusters.clear();
6689 Man_thruster_reset_timestamp =
timestamp();
6708 size_t mant_size = Man_thrusters.size();
6710 for(
size_t mi = 0; mi < mant_size; mi++)
6712 mtr = &Man_thrusters[mi];
6713 if(mtr->
bmap_id == bmap_frame)
6716 for(
size_t mj = 0; mj < mant_size; mj++)
6718 mtr = &Man_thrusters[mj];
6727 return &Man_thrusters[Man_thrusters.size()-1];
6738 ship *warp_shipp = NULL;
6740 bool is_first_stage_arrival =
false;
6765 if ( obj ==
Viewer_obj && !Rendering_to_shadow_map)
6767 if (ship_show_velocity_dot && (obj==
Player_obj) )
6787 shipp = &Ships[
num];
6817 is_first_stage_arrival =
false;
6823 if ( !(is_first_stage_arrival) )
6854 if(!Rendering_to_shadow_map)
6857 float render_amount;
6864 render_amount = 0.0f;
6901 render_amount = 0.0f;
6903 if(render_amount > 0.0
f)
6949 fx_batcher.
draw_beam(&start, &end, rad, 1.0
f);
6951 int bmap_frame = mtp->
tex_id;
7033 int clip_started = 0;
7037 if ( warp_shipp != NULL )
7047 if(!Rendering_to_shadow_map)
7096 timer =
MAX(timer,0.0
f);
7120 if(Rendering_to_shadow_map)
7129 int save_flags = render_flags;
7149 int num_secondaries_rendered = 0;
7150 vec3d secondary_weapon_pos;
7164 num_secondaries_rendered = 0;
7168 secondary_weapon_pos = bank->
pnt[k];
7176 num_secondaries_rendered++;
7185 render_flags = save_flags;
7193 if(fog_val >= 0.6
f){
7213 if ( clip_started ) {
7220 if (shipp->
shield_hits && !Rendering_to_shadow_map) {
7324 vec3d cockpit_eye_pos;
7326 ship_get_eye(&cockpit_eye_pos, &dummy, objp,
true,
true);
7356 if ( cockpit_model_num < 0 ) {
7378 for ( i = 0; i < (
int)sip->
displays.size(); i++ ) {
7387 for (
int i = 0; i < (
int)Player_displays.size(); i++ ) {
7388 if ( Player_displays[i].background >= 0 ) {
7392 if ( Player_displays[i].foreground >= 0 ) {
7396 if ( Player_displays[i].
target >= 0 ) {
7401 Player_displays.clear();
7411 if ( strlen(display->
filename) <= 0 ) {
7415 if( cockpit_model_num < 0 ) {
7419 int i, tm_num, glow_target = -1, glow_handle = -1, diffuse_handle = -1;
7429 if ( tm_num >= 0 ) {
7471 new_display.
size[0] = display->
size[0];
7472 new_display.
size[1] = display->
size[1];
7473 new_display.
source = glow_handle;
7476 Player_displays.push_back(new_display);
7487 for (
int i = 0; i < (
int)hud.size(); i++ ) {
7488 for (
int j = 0; j < (
int)Player_displays.size(); j++ ) {
7489 hud[
i]->setCockpitTarget(&Player_displays[j]);
7497 if ( Ship_info[Player_ship->
ship_info_index].cockpit_model_num < 0 ) {
7506 if ( cockpit_display_num >= (
int)Player_displays.size() || cockpit_display_num < 0 ) {
7512 if ( display->
target < 0 ) {
7524 if ( display->
source >= 0 ) {
7542 if ( Ship_info[Player_ship->
ship_info_index].cockpit_model_num < 0 ) {
7551 if ( cockpit_display_num >= (
int)Player_displays.size() || cockpit_display_num < 0 ) {
7579 Num_ship_subsystems--;
7594 Assert( Ships[num].objnum == objnum );
7596 shipp = &Ships[
num];
7902 if ( dist > outer_rad )
7905 if ( dist < inner_rad ) {
7907 *damage = max_damage;
7911 float fraction = 1.0f - (dist - inner_rad) / (outer_rad - inner_rad);
7912 *damage = fraction * max_damage;
7913 *blast = fraction * max_blast;
7919 static const float MAX_SHOCK_ANGLE_RANGE = 1.99f *
PI;
7930 float inner_rad, outer_rad, max_damage, max_blast, shockwave_speed;
7937 Assert( exp_objp != NULL );
7941 shipp = &Ships[exp_objp->
instance];
7944 Assert( (shipp != NULL) && (sip != NULL) );
7949 inner_rad = exp_objp->
radius*2.0f;
7950 outer_rad = exp_objp->
radius*4.0f;
7951 max_damage =
i2fl(
override);
7952 max_blast =
override * 5.0f;
7953 shockwave_speed = 100.0f;
7971 if ( (max_damage < 0.1
f) && (max_blast < 0.1
f) ){
7975 if ( shockwave_speed > 0 ) {
7980 sci.
blast = max_blast;
7982 sci.
speed = shockwave_speed;
7990 float damage = 0.0f;
7996 if ( objp == exp_objp ){
8011 switch ( objp->
type ) {
8014 vec3d force, vec_ship_to_impact;
8043 object *docked_objp;
8048 vec3d impulse_norm, impulse_vec,
pos;
8156 vec3d outpnt, pnt1, pnt2;
8168 float rad = objp->
radius*0.1f;
8174 if(fireball_type < 0) {
8197 vec3d rand_vec, outpnt;
8206 float rad = objp->
radius*0.2f;
8209 if(fireball_type < 0) {
8260 for (
int zz=0; zz<zz_max; zz++ ) {
8271 vec3d tmp, outpnt, pnt1, pnt2;
8283 float rad = objp->
radius*0.40f;
8288 if(fireball_type < 0) {
8350 if ((!knossos_ship) && (pe.
num_high > 0)) {
8367 int fireball_objnum, fireball_type, default_fireball_type;
8368 float explosion_life;
8369 big_rad = objp->
radius*1.75f;
8373 big_rad = objp->
radius * 1.2f;
8381 if(fireball_type < 0) {
8382 fireball_type = default_fireball_type;
8385 if ( fireball_objnum >= 0 ) {
8388 explosion_life = 0.0f;
8481 if (delta < -shipp->target_shields_delta)
8497 if (delta < -shipp->target_weapon_energy_delta)
8516 Warning(
LOCATION,
"Couldn't load thruster glow animation '%s'\nPrimary glow type effect does not accept .EFF or .ANI effects", ga->
filename);
8532 if ( Thrust_anim_inited == 1 )
8557 Thrust_anim_inited = 1;
8571 int secondary_glow_bitmap, tertiary_glow_bitmap, distortion_bitmap;
8575 if ( !Thrust_anim_inited ) {
8686 if (!Thrust_anim_inited)
8719 if ( framenum < 0 ) framenum = 0;
8741 if ( framenum < 0 ) framenum = 0;
8761 #define SHIP_REPAIR_SUBSYSTEM_RATE 0.01f // percent repair per second for a subsystem
8762 #define SUBSYS_REPAIR_THRESHOLD 0.1 // only repair subsystems that have > 10% strength
8770 float real_repair_rate;
8778 sp = &Ships[shipnum];
8856 #define PLAYER_MAX_DIST_WARNING 700000 // distance in KM at which player gets warning to return to battle
8857 #define PLAYER_DISTANCE_MAX_WARNINGS 3 // maximum number of warnings player can receive before mission ends
8858 #define PLAYER_MAX_DIST_END 750000 // distance from starting loc at which we end mission
8859 #define PLAYER_WARN_DELTA_TIME 10000 //ms
8860 #define PLAYER_DEATH_DELTA_TIME 5000 //ms
8872 int give_warning_to_player = 0;
8875 give_warning_to_player = 1;
8878 give_warning_to_player = 1;
8883 if ( give_warning_to_player ) {
8991 int engines_disabled=0;
9007 if ( engines_disabled ) {
9063 if ( time_left < 0 ) {
9094 DCF(
lethality_decay,
"Sets ship lethality_decay, or the time in sec to go from 100 to 0 health (default is 1/120)")
9097 dc_printf(
"Decay rate is currently %f\n", Decay_rate);
9115 int num_turrets = 0;
9122 nprintf((
"lethality",
"Player lethality: %.1f, num turrets targeting player: %d\n", aip->
lethality, num_turrets));
9130 if ( (objp == NULL) || !frametime )
9142 shipp->radar_last_status = shipp->radar_current_status;
9148 if (shipp->radar_last_contact < 0 && shipp->radar_visible_since < 0)
9150 shipp->radar_visible_since = -1;
9151 shipp->radar_last_contact = -1;
9155 shipp->radar_visible_since = -1;
9161 if (shipp->radar_visible_since < 0)
9169 shipp->radar_current_status = visibility;
9187 nprintf((
"Network",
"Ignoring non-ship object in ship_process_post()\n"));
9198 shipp = &Ships[
num];
9365 if ( Ships[num].ai_index >= 0 ){
9379 ai_process( obj, Ships[num].ai_index, frametime );
9417 Error(
LOCATION,
"There are %d primary banks in the model file,\nbut only %d primary banks specified for %s.\nThis must be fixed, as it will cause crashes.\n", pm->
n_guns, sip->
num_primary_banks, sip->
name);
9421 Assertion((
Player_weapon_precedence[j] > 0),
"Error reading player weapon precedence list. Check weapons.tbl for $Player Weapon Precedence entry, and correct as necessary.\n");
9444 Assertion((
Player_weapon_precedence[j] > 0),
"Error reading player weapon precedence list. Check weapons.tbl for $Player Weapon Precedence entry, and correct as necessary.\n");
9473 float capacity,
size;
9537 mc.
p1 = &other_obj->
pos;
9552 static int last_smctu_initial_time = -1;
9553 static int last_smctu_final_time = -1;
9554 int sanity_counter = 0, collision;
9555 ship *compare_shipp;
9557 uint new_create_time;
9568 if ( compare_shipp == shipp ) {
9572 if ( compare_shipp->
create_time == new_create_time )
9574 if((
unsigned int)sanity_counter == 0 && (
unsigned int)last_smctu_initial_time == shipp->
create_time)
9579 new_create_time = last_smctu_final_time + 1;
9592 last_smctu_final_time = new_create_time;
9619 if (count > Ship_subsys_hwm) {
9620 Ship_subsys_hwm =
count;
9692 int i,
n, objnum, j, k,
t;
9709 Error(
LOCATION,
XSTR(
"There is a limit of %d ships in the mission at once. Please be sure that you do not have more than %d ships present in the mission at the same time.", 1495),
SHIPS_LIMIT,
SHIPS_LIMIT );
9715 if (Ships[n].objnum == -1){
9720 if (n == MAX_SHIPS){
9724 Assert((ship_type >= 0) && (ship_type < static_cast<int>(Ship_info.size())));
9725 sip = &(Ship_info[ship_type]);
9729 sip->model_num =
model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
9730 if(strlen(sip->cockpit_pof_file))
9732 sip->cockpit_model_num =
model_load(sip->cockpit_pof_file, 0, NULL);
9736 if(strlen(sip->pof_file_hud)){
9738 for(
auto it = Ship_info.begin(); it != Ship_info.end(); ++it){
9739 if(!
stricmp(it->pof_file, sip->pof_file_hud)){
9740 it->model_num =
model_load(it->pof_file, it->n_subsystems, &it->subsystems[0]);
9745 sip->model_num_hud =
model_load(sip->pof_file_hud, 0, NULL);
9762 nprintf((
"Warning",
"For ship '%s', detail level mismatch. Table has %d, POF has %d.", sip->name, sip->num_detail_levels, pm->
n_detail_levels ));
9766 pm->
detail_depth[i] = (i < sip->num_detail_levels) ?
i2fl(sip->detail_distance[i]) : 0.0f;
9787 int name_len =
MIN(
NAME_LENGTH - strlen(suffix) - 1, strlen(Ship_info[ship_type].
name));
9790 strncpy(shipp->
ship_name, Ship_info[ship_type].name, name_len);
9791 strcpy(shipp->
ship_name + name_len, suffix);
9829 for ( i = 0; i < pm->
n_paths; i++ )
9842 while ( ss !=
END_OF_LIST( &Ships[n].subsys_list ) ) {
9852 Warning(
LOCATION,
"Couldn't fix up turret indices in spline path\n\nModel: %s\nPath: %s\nVertex: %d\nTurret model id:%d\n\nThis probably means that the turret was not specified in the ship table(s).", sip->pof_file, pm->
paths[i].
name, j, ptindex );
9898 sip = &(Ship_info[ship_type]);
9993 float hull_pct, shield_pct;
10004 sip = &(Ship_info[ship_type]);
10033 Assert(hull_pct > 0.0
f && hull_pct <= 1.0
f);
10039 }
else if (Ship_info[sp->
ship_info_index].max_shield_strength > 0.0f) {
10046 Assert(shield_pct >= 0.0
f && shield_pct <= 1.0
f);
10047 CLAMP(shield_pct, 0.0
f, 1.0
f);
10049 shield_pct = hull_pct = 1.0f;
10053 int num_saved_subsystems = 0;
10054 char **subsys_names =
new char *[sip_orig->
n_subsystems];
10055 float *subsys_pcts =
new float[sip_orig->
n_subsystems];
10062 Error(
LOCATION,
"Subsystem mismatch while changing ship class from '%s' to '%s'!", sip_orig->
name, sip->
name);
10067 subsys_names[num_saved_subsystems] =
new char[
NAME_LENGTH];
10073 subsys_pcts[num_saved_subsystems] = ss->
max_hits;
10076 Assert(subsys_pcts[num_saved_subsystems] >= 0.0
f && subsys_pcts[num_saved_subsystems] <= 1.0
f);
10077 CLAMP(subsys_pcts[num_saved_subsystems], 0.0
f, 1.0
f);
10079 num_saved_subsystems++;
10159 for (i = 0; i < num_saved_subsystems; i++)
10174 delete[] subsys_names[i];
10176 delete [] subsys_names;
10177 delete [] subsys_pcts;
10347 if (old_defaults != new_defaults)
10427 int check_count, cmeasure_count;
10483 cmeasure_count = 0;
10518 return (cobjnum >= 0);
10542 Laser_energy_out_snd_timer =
timestamp(stampval);
10557 Missile_out_snd_timer =
timestamp(500);
10575 float weapons_subsys_str;
10589 if ( (
frand()-0.2
f) > weapons_subsys_str )
10609 DCF(t_rad,
"Sets weapon tracer radius")
10618 DCF(t_len,
"Sets weapon tracer length")
10627 DCF(t_vel,
"Sets weapon tracer velocity")
10690 if(Ship_info[shipp->
ship_info_index].draw_primary_models[bank_to_stop]){
10713 int i, num_primary_banks = 0, bank_to_stop = 0;
10736 for ( i = 0; i < num_primary_banks; i++ ) {
10762 vec3d gun_point, pnt, firing_pos, target_position, target_velocity_vec;
10768 int weapon_idx,
i, j,
w,
v, weapon_objnum;
10769 int bank_to_fire, num_fired = 0;
10772 bool has_fired =
false;
10773 bool has_autoaim, has_converging_autoaim, needs_target_pos;
10774 float autoaim_fov = 0;
10775 float dist_to_target = 0;
10828 int num_primary_banks;
10836 Assert(num_primary_banks > 0);
10837 if (num_primary_banks < 1){
10846 if(num_primary_banks == 1)
10856 if (needs_target_pos) {
10874 for ( i = 0; i < num_primary_banks; i++ ) {
10895 if (needs_target_pos) {
10937 float next_fire_delay;
10938 bool fast_firing =
false;
10940 next_fire_delay = winfo_p->
burst_delay * 1000.0f;
10943 fast_firing =
true;
10947 next_fire_delay = winfo_p->
fire_wait * 1000.0f;
10963 int effective_primary_banks = 0;
10964 for (
int it = 0; it < num_primary_banks; it++)
10967 effective_primary_banks++;
10969 Assert(effective_primary_banks >= 1);
10971 next_fire_delay *= 1.0f + (effective_primary_banks - 1) * 0.5
f;
10986 if ((next_fire_delay > 0.0
f)) {
10992 tx = (
float) t/-1000.0
f;
10996 next_fire_delay -= tx;
10999 if ((
int) next_fire_delay < 1){
11000 next_fire_delay = 1.0f;
11035 vec3d predicted_target_pos, plr_to_target_vec;
11037 bool in_automatic_aim_fov =
false;
11038 float dist_to_aim = 0;
11042 if (needs_target_pos) {
11043 float time_to_target, angle_to_target;
11044 vec3d last_delta_vec;
11046 time_to_target = 0.0f;
11050 time_to_target = dist_to_target / winfo_p->
max_speed;
11053 vm_vec_scale_add(&predicted_target_pos, &target_position, &target_velocity_vec, time_to_target);
11055 vm_vec_sub(&plr_to_target_vec, &predicted_target_pos, &obj->
pos);
11058 angle_to_target =
vm_vec_delta_ang(&player_forward_vec, &plr_to_target_vec, NULL);
11059 if (angle_to_target < autoaim_fov)
11060 in_automatic_aim_fov =
true;
11089 points = num_slots;
11094 points = num_slots;
11129 fbfire_info.
target = NULL;
11133 fbfire_info.
bank = bank_to_fire;
11135 for ( v = 0; v <
points; v++ ){
11147 fbfire_info.
point = j;
11156 int points = 0, numtimes = 1;
11165 points =
MIN(num_slots, winfo_p->
shots);
11167 numtimes = winfo_p->
shots;
11168 points = num_slots;
11207 int check_ammo = 1;
11251 vec3d total_impulse;
11252 vec3d *firepoint_list;
11253 size_t current_firepoint = 0;
11259 firepoint_list =
nullptr;
11262 for ( w = 0; w < numtimes; w++ ) {
11271 for ( j = 0; j <
points; j++ ) {
11281 if (weapon_model && weapon_model->
n_guns)
11285 for(
int s = 0;
s<sub_shots;
s++){
11288 if (weapon_model && weapon_model->
n_guns) {
11308 if (has_autoaim && in_automatic_aim_fov) {
11311 if (has_converging_autoaim) {
11313 vm_vec_sub(&firing_vec, &predicted_target_pos, &firing_pos);
11322 vec3d target_vec, firing_vec, convergence_offset;
11341 vm_vec_sub(&firing_vec, &target_vec, &firing_pos);
11347 vec3d target_vec, firing_vec, convergence_offset;
11360 vm_vec_sub(&firing_vec, &target_vec, &firing_pos);
11371 firing_orient = obj->
orient;
11375 vec3d local_impulse = firing_orient.
vec.fvec;
11379 firepoint_list[current_firepoint++] = firing_pos;
11397 vec3d predicted_pos;
11399 float range_to_target = flak_range;
11408 if (target != NULL) {
11414 if ( (target != NULL) && (range_to_target < flak_range) )
11417 flak_pick_range(&Objects[weapon_objnum], &firing_pos, &predicted_pos,wepstr);
11449 vec3d avg_firepoint;
11451 vm_vec_avg_n(&avg_firepoint, current_firepoint, firepoint_list);
11454 delete[] firepoint_list;
11460 banks_fired |= (1<<bank_to_fire);
11469 if ( sound_played != winfo_p->
launch_snd ) {
11496 sw_pl = &Player_ship->
weapons;
11539 Assert ( player_num != -1 );
11570 int bank0_laser = 0;
11571 int bank1_laser = 0;
11655 fire_info.
target = NULL;
11657 fire_info.
turret = NULL;
11770 for (i=0; i<ns; i++) {
11801 int n, weapon_idx, j, bank, bank_adjusted, starting_bank_count = -1, num_fired;
11802 ushort starting_sig = 0;
11809 vec3d missile_point, pnt, firing_pos;
11810 bool has_fired =
false;
11921 goto done_secondary;
12029 goto done_secondary;
12039 nprintf((
"WARNING",
"WARNING ==> Tried to fire bank %d, but ship has only %d banks\n", bank+1, pm->
n_missiles));
12063 goto done_secondary;
12066 int start_slot, end_slot;
12072 end_slot = start_slot;
12074 end_slot = start_slot+1;
12081 end_slot = start_slot;
12084 int pnt_index=start_slot;
12086 for ( j = start_slot; j <= end_slot; j++ ) {
12094 if ( pnt_index >= num_slots ){
12105 if (weapon_model && weapon_model->
n_guns) {
12127 firing_orient = obj->
orient;
12140 if (weapon_num >= 0) {
12171 if (
Weapon_info[weapon_idx].launch_snd != -1 ) {
12185 if (
Weapon_info[weapon_idx].launch_snd != -1 ) {
12197 Assert(starting_sig != 0);
12211 Assert ( player_num != -1 );
12324 unsigned int original_link_flag;
12556 int original_bank, new_bank,
i;
12691 if ((p != NULL) && (p != wing_name) && (*(p+1) !=
'\0'))
12693 size_t len = (p - wing_name);
12694 strncpy(ship_name, wing_name, len);
12695 sprintf(ship_name + len,
NOX(
" %d"), index);
12696 strcat(ship_name, p);
12700 sprintf(ship_name,
NOX(
"%s %d"), wing_name, index);
12719 for (i=0; i<wing_limit; i++)
12720 if (Wings[i].wave_count && !
stricmp(Wings[i].name, name))
12724 for (i=0; i<wing_limit; i++)
12725 if (Wings[i].current_count && !
stricmp(Wings[i].name, name))
12740 if(
stricmp(Wings[idx].name,name)==0)
12751 for (
auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it)
12752 if (!
stricmp(token, it->name))
12753 return std::distance(Ship_info.cbegin(), it);
12763 for (
auto it = Ship_templates.cbegin(); it != Ship_templates.cend(); ++it ) {
12764 if ( !
stricmp(token, it->name) ) {
12765 return std::distance(Ship_templates.cbegin(), it);
12793 if (!
stricmp(token,
"GTD Orion#1 (Galatea)"))
12805 else if (!
stricmp(token,
"GTD Orion#2 (Bastion)"))
12817 else if (!
stricmp(token,
"SF Dragon#2 (weakened)"))
12829 else if (!
stricmp(token,
"SF Dragon#3 (Player)"))
12841 else if (!
stricmp(token,
"GTSC Faustus#2 (big blast)"))
12849 else if (!
stricmp(token,
"GTF Loki (stealth)"))
12870 Warning(
LOCATION,
"Token [%s] is too long to be parenthesized by ship_info_lookup()!\n", token);
12874 sprintf(name,
"%s (%s)", temp1, temp2);
12877 else if (*p ==
'(')
12880 char *p2 = strchr(temp2,
')');
12884 sprintf(name,
"%s#%s", temp1, temp2);
12889 Warning(
LOCATION,
"Unrecognized hash symbol. Contact a programmer!");
12910 if (Ships[i].objnum >= 0){
12912 if (!
stricmp(name, Ships[i].ship_name)){
12926 if(name == NULL || !strlen(name)){
12931 uint max_size = Ship_types.size();
12932 for(
uint idx=0; idx < max_size; idx++){
12933 if(!
stricmp(name, Ship_types[idx].name)){
12956 if (Ships[i].objnum >= 0){
12958 if (!
stricmp(name, Ships[i].ship_name)){
12977 if (subsysp == NULL) {
13029 switch (psub->
type) {
13092 switch (psub->
type) {
13141 switch (psub->
type) {
13177 switch (psub->
type) {
13236 *eye_pos = obj->
pos;
13237 *eye_orient = obj->
orient;
13255 *eye_orient = obj->
orient;
13277 #define MAX_SUBSYS_ATTACKERS 3
13281 ship_subsys *best_in_sight_subsys, *lowest_attacker_subsys, *ss_return;
13282 int lowest_num_attackers, lowest_in_sight_attackers, num_attackers;
13286 lowest_in_sight_attackers = lowest_num_attackers = 1000;
13287 ss_return = best_in_sight_subsys = lowest_attacker_subsys = NULL;
13307 if ( num_attackers < lowest_num_attackers ) {
13308 lowest_num_attackers = num_attackers;
13309 lowest_attacker_subsys = ss;
13313 if ( num_attackers < lowest_in_sight_attackers ) {
13314 lowest_in_sight_attackers = num_attackers;
13315 best_in_sight_subsys = ss;
13321 if ( best_in_sight_subsys == NULL ) {
13323 ss_return = lowest_attacker_subsys;
13326 ss_return = lowest_attacker_subsys;
13328 ss_return = best_in_sight_subsys;
13351 subsys_type = -
index;
13355 if ( attacker_pos != NULL ) {
13376 if ( count == index )
13383 Warning(
LOCATION,
"In ship_get_indexed_subsys, unable to get a subsystem of index %d on ship %s, due to a broken subsystem reference! This is most likely due to a table/model mismatch.", index, sp->
ship_name);
13412 if ( !error_bypass )
13502 float total_current_hits, diff;
13509 total_current_hits = 0.0f;
13527 #define SHIELD_REPAIR_RATE 0.20f // Percent of shield repaired per second.
13528 #define HULL_REPAIR_RATE 0.15f // Percent of hull repaired per second.
13529 #define SUBSYS_REPAIR_RATE 0.10f // Percent of subsystems repaired per second.
13531 #define REARM_NUM_MISSILES_PER_BATCH 4 // how many missiles are dropped in per load sound
13532 #define REARM_NUM_BALLISTIC_PRIMARIES_PER_BATCH 100 // how many bullets are dropped in per load sound
13545 float shield_rep_time = 0;
13546 float subsys_rep_time = 0;
13547 float hull_rep_time = 0;
13548 float prim_rearm_time = 0;
13549 float sec_rearm_time = 0;
13551 float max_hull_repair;
13552 float max_subsys_repair;
13557 bool found_first_empty;
13589 found_first_empty =
false;
13609 if (num_reloads < 0)
continue;
13613 found_first_empty =
true;
13617 prim_rearm_time += num_reloads * wip->
rearm_rate;
13623 found_first_empty =
false;
13640 if (num_reloads < 0)
continue;
13644 found_first_empty =
true;
13648 sec_rearm_time += num_reloads * wip->
rearm_rate;
13653 return shield_rep_time + hull_rep_time + subsys_rep_time + prim_rearm_time + sec_rearm_time + 1.2f;
13666 int i, banks_full, primary_banks_full, subsys_type, subsys_all_ok, last_ballistic_idx = 0;
13667 float shield_str, repair_delta, repair_allocated, max_hull_repair, max_subsys_repair;
13748 repair_allocated = 0.0f;
13761 if ( ssp->
current_hits < max_subsys_repair && repair_allocated > 0 ) {
13770 if ( repair_delta > repair_allocated ) {
13771 repair_delta = repair_allocated;
13773 repair_allocated -= repair_delta;
13774 Assert(repair_allocated >= 0.0
f);
13803 primary_banks_full = 0;
13804 if ( subsys_all_ok )
13863 last_ballistic_idx =
i;
13884 if (i == last_ballistic_idx)
13920 primary_banks_full++;
13926 primary_banks_full++;
13954 int shields_full = 0;
14011 int num_support_ships = 0;
14012 float min_dist = -1.0f;
14013 object *nearest_support_ship = NULL;
14014 float min_time_till_available = -1.0f;
14015 object *soonest_available_support_ship = NULL;
14019 "requester_obj does not have a valid pointer to a ship. Pointer is %d, which is smaller than 0 or bigger than %d",
14022 ship *requester_ship = &Ships[requester_obj->
instance];
14032 "objp does not have a valid pointer to a ship. Pointer is %d, which is smaller than 0 or bigger than %d",
14037 if ( shipp->
team != requester_ship->
team ) {
14042 "Ship '%s' does not have a valid pointer to a ship class. Pointer is %d, which is smaller than 0 or bigger than %d",
14052 num_support_ships++;
14061 "Ship '%s' doesn't have a valid ai pointer. Pointer is %d, which is smaller than 0 or larger than %d",
14088 if ( min_time_till_available < 0.0
f || howlong < min_time_till_available ) {
14089 min_time_till_available = howlong;
14090 soonest_available_support_ship =
objp;
14096 if ( min_dist < 0.0
f || dist < min_dist )
14099 nearest_support_ship =
objp;
14107 if (num_support_ships == 0) {
14111 else if (nearest_support_ship != NULL) {
14113 if (ship_we_found != NULL)
14114 *ship_we_found = nearest_support_ship;
14127 else if (soonest_available_support_ship != NULL) {
14130 if (ship_we_found != NULL)
14131 *ship_we_found = soonest_available_support_ship;
14173 ship_clear_subsystems();
14178 for (i = 0; i < (
int)Ship_types.size(); i++) {
14179 Ship_types[
i].ai_actively_pursues.clear();
14180 Ship_types[
i].ai_actively_pursues_temp.clear();
14182 Ship_types.clear();
14277 for(idx=0; idx<objp->
objsnd_num.size(); idx++){
14297 DCF(set_shield,
"Change player ship shield strength")
14302 dc_printf (
"Usage: set_shield [num]\n");
14303 dc_printf (
"[num] -- shield percentage 0.0 -> 1.0 of max\n");
14323 DCF(set_hull,
"Change player ship hull strength")
14329 dc_printf (
"[num] -- hull percentage 0.0 -> 1.0 of max\n");
14349 DCF(set_subsys,
"Set the strength of a particular subsystem on player ship" )
14356 dc_printf(
"Usage: set_subsys <type> [--status] <strength>\n");
14357 dc_printf(
"<type> is any of the following:\n");
14365 dc_printf(
"[--status] will display status of that subsystem\n\n");
14367 dc_printf(
"<strength> is any value between 0 and 1.0\n");
14373 if (arg ==
"weapons") {
14376 }
else if (arg ==
"engine") {
14379 }
else if (arg ==
"sensors") {
14382 }
else if (arg ==
"communication") {
14385 }
else if (arg ==
"navigation") {
14388 }
else if (arg ==
"radar") {
14391 }
else if ((arg ==
"status") || (arg ==
"--status") || (arg ==
"?") || (arg ==
"--?")) {
14392 dc_printf(
"Error: Must specify a subsystem.\n");
14396 dc_printf(
"Error: Unknown argument '%s'\n", arg.c_str());
14407 CLAMP(val_f, 0.0, 1.0);
14439 Ship_type_counts.resize(Ship_types.size());
14442 for (
size_t i = 0; i < Ship_type_counts.size(); i++)
14444 Ship_type_counts[
i].killed = 0;
14445 Ship_type_counts[
i].total = 0;
14459 Ship_type_counts[
type].total +=
num;
14472 Ship_type_counts[
type].killed++;
14488 return Ship_info[ship_class].class_type;
14512 int i, j, ship_index,
count;
14513 int slist[MAX_SIZE], which_one;
14519 if (count >= MAX_SIZE)
14525 if(multi_team >= 0){
14541 if ( wingnum == -1 ) {
14550 if ( wingnum == -1 ){
14556 if (count >= MAX_SIZE)
14560 Assert( ship_index != -1 );
14562 if ( Ships[ship_index].flags &
SF_DYING ) {
14576 if(multi_team < 0){
14577 if ( Player_ship->
team != Ships[ship_index].
team ){
14583 if ( (max_dist > 1.0
f) && (multi_team < 0) ) {
14586 if ( dist > max_dist ) {
14592 if ( persona_index != -1 ) {
14593 if ( Ships[ship_index].persona_index != persona_index ){
14603 slist[
count] = ship_index;
14613 which_one = (rand() %
count);
14614 ship_index = slist[which_one];
14616 Assert ( Ships[ship_index].objnum != -1 );
14630 Assert( ship_index != -1 );
14632 if ( Ships[ship_index].flags &
SF_DYING ) {
14646 if ( max_dist > 0 ) {
14649 if ( dist > max_dist ) {
14659 slist[
count] = ship_index;
14663 if ( count == 0 ) {
14668 which_one = (rand() %
count);
14669 ship_index = slist[which_one];
14671 Assert ( Ships[ship_index].objnum != -1 );
14684 int num, which_one;
14711 if ( max_dist > 0 ) {
14714 if ( dist > max_dist ) {
14726 which_one = (rand() %
num);
14727 objp = obj_list[which_one];
14746 swp = &Ships[shipnum].
weapons;
14769 swp = &Ships[shipnum].
weapons;
14795 if (engine_strength <= 0.0
f)
14818 if (navigation_strength <= 0.0
f)
14853 if ( mp->
nverts >= 2 ) {
14885 vec3d terminus, eye_to_pos, subsys_fvec, subsys_to_eye_vec;
14891 if ( do_facing_check ) {
14898 dot =
vm_vec_dot(&subsys_fvec, &subsys_to_eye_vec);
14904 *vec_out = subsys_to_eye_vec;
14934 if ( dist <= subsys->system_info->radius ) {
14974 float closest_dist;
14977 closest_in_sight_subsys = NULL;
14978 closest_dist = FLT_MAX;
14990 if ( ss_dist < closest_dist ) {
14991 closest_dist = ss_dist;
14992 closest_in_sight_subsys = ss;
14998 return closest_in_sight_subsys;
15032 int quadrant_num,
i;
15033 float max_quadrant;
15034 vec3d tmpv1, tmpv2;
15042 for ( i = 0; i < 4; i++ ) {
15056 if ( quadrant_num < 0 )
15060 if ( max_quadrant <= 0 ) {
15065 mprintf((
"Warning: \"%s\" has shield quadrant strength of %f out of %f\n",
15094 object *locked_objp, *
A;
15141 float dist, wep_range;
15144 if ( wep_range > dist ) {
15145 nprintf((
"Alan",
"AI ship is seeking lock\n"));
15182 for (i=0; i<32; i++)
15183 if (num & (1 << i))
15205 const char *order_text;
15212 aigp = &aip->
goals[0];
15218 if ( order_text == NULL )
15221 strcpy(outbuf, order_text);
15233 strcat(outbuf, ship_name);
15234 strcat(outbuf,
XSTR(
"'s Wing", 494));
15236 strcpy(outbuf,
XSTR(
"no orders", 495));
15249 strcat(outbuf, ship_name);
15251 strcpy(outbuf,
XSTR(
"no orders", 495));
15260 sprintf(outbuf,
XSTR(
"atk %s %s", 496), ship_name, subsys_name);
15262 strcpy(outbuf,
XSTR(
"no orders", 495) );
15273 strcpy(outbuf,
"Flying to ship");
15297 int time, seconds, minutes;
15300 float min_speed, max_speed;
15314 min_speed = 0.9f * max_speed;
15320 vec3d *prev_vec = NULL;
15322 if (prev_vec != NULL) {
15325 prev_vec = ii->get_pos();
15329 if ( dist < 1.0
f) {
15340 if (speed < min_speed)
15342 time =
fl2i(dist/speed);
15355 if ( minutes > 99 ) {
15359 sprintf(outbuf,
NOX(
"%02d:%02d"), minutes, seconds);
15361 strcpy( outbuf,
XSTR(
"Unknown", 497) );
15453 #define PLAYER_CHECK_WARN_INTERVAL 300 // how often we check for warnings
15454 #define PLAYER_MIN_WARN_DIST 100 // minimum distance attacking ship can be from player and still allow warning
15455 #define PLAYER_MAX_WARN_DIST 1000 // maximum distance attacking ship can be from plyaer and still allow warning
15460 vec3d vec_to_target;
15494 if ( fdot > -0.7 ) {
15508 if ( msg_type != -1 ) {
15518 if ( ship_index >= 0 ) {
15554 if ( deader_sp->
team == Player_ship->
team ) {
15575 bool wingman =
false;
15600 if (killer_sp->
wingnum == -1) {
15629 #define ASK_HELP_SHIELD_PERCENT 0.1 // percent shields at which ship will ask for help
15630 #define ASK_HELP_HULL_PERCENT 0.3 // percent hull at which ship will ask for help
15631 #define AWACS_HELP_HULL_HI 0.75 // percent hull at which ship will ask for help
15632 #define AWACS_HELP_HULL_LOW 0.25 // percent hull at which ship will ask for help
15660 if (message >= 0) {
15671 int multi_team_filter = -1;
15693 multi_team_filter = sp->
team;
15708 goto play_ask_help;
15746 if (rand() % 4 == 0)
15749 if (ship_index >= 0)
15759 int multi_team_filter = -1;
15767 multi_team_filter = sp->
team;
15820 if (Player_ship->
team != sp->
team)
15829 #define PLAYER_LOW_AMMO_MSG_INTERVAL 250000
15830 #define PLAYER_REQUEST_REPAIR_MSG_INTERVAL 240000
15831 #define PLAYER_MAX_LOW_AMMO_MSGS 5
15842 int multi_team_filter = -1;
15889 multi_team_filter = sp->
team;
15930 int message_type = -1;
15977 int multi_team_filter = -1;
15981 multi_team_filter = sp->
team;
15984 if (message_type >= 0)
16168 nprintf((
"Network",
"Revealing cap ship subsys cargo for %s\n", shipp->
ship_name));
16218 nprintf((
"Network",
"Hiding cap ship subsys cargo for %s\n", shipp->
ship_name));
16264 float capacity,
size;
16271 capacity = (
float) Ship_info[ship_class].primary_bank_ammo_capacity[bank];
16273 return fl2i((capacity / size)+0.5
f);
16281 float capacity,
size;
16283 Assertion(ship_class < static_cast<int>(Ship_info.size()),
"Invalid ship_class of %d is >= Ship_info.size() (%d); get a coder!\n", ship_class, static_cast<int>(Ship_info.size()));
16285 Assertion(ammo_type < Num_weapon_types, "Invalid ammo_type of %d is >=
Num_weapon_types (%d);
get a coder!
\n", ammo_type, Num_weapon_types);
16287 if (ship_class < 0 || bank < 0 || ammo_type < 0) {
16290 capacity = (float) Ship_info[ship_class].secondary_bank_ammo_capacity[bank];
16291 size = (float) Weapon_info[ammo_type].cargo_size;
16292 return (int) (capacity / size);
16299 int get_max_ammo_count_for_turret_bank(ship_weapon *swp, int bank, int ammo_type)
16301 float capacity, size;
16303 Assertion(bank < MAX_SHIP_SECONDARY_BANKS, "Invalid secondary bank of %d (max is %d);
get a coder!
\n", bank, MAX_SHIP_SECONDARY_BANKS - 1);
16304 Assertion(ammo_type < Num_weapon_types, "Invalid ammo_type of %d is >=
Num_weapon_types (%d);
get a coder!
\n", ammo_type, Num_weapon_types);
16306 if (!swp || bank < 0 || ammo_type < 0) {
16309 capacity = (float) swp->secondary_bank_capacity[bank];
16310 size = (float) Weapon_info[ammo_type].cargo_size;
16311 return (int) (capacity / size);
16318 void ship_page_in()
16321 int num_subsystems_needed = 0;
16323 int *ship_class_used = NULL;
16325 ship_class_used = new int[Ship_info.size()];
16327 Verify( ship_class_used != NULL );
16329 // Mark all ship classes as not used
16330 memset( ship_class_used, 0, Ship_info.size() * sizeof(int) );
16332 // Mark any support ship types as used
16333 for (auto sip = Ship_info.begin(); sip != Ship_info.end(); ++sip) {
16334 if (sip->flags & SIF_SUPPORT) {
16335 nprintf(( "Paging
", "Found support
ship '%s'\n", sip->name ));
16336 i = std::distance(Ship_info.begin(), sip);
16337 ship_class_used[i]++;
16339 num_subsystems_needed += sip->n_subsystems;
16341 // load the darn model and page in textures
16342 sip->model_num = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
16344 if (sip->model_num >= 0) {
16345 model_page_in_textures(sip->model_num, i);
16350 // Mark any ships in the mission as used
16351 for (i = 0; i < MAX_SHIPS; i++) {
16352 if (Ships[i].objnum < 0)
16355 nprintf(( "Paging
","Found
ship '%s'\n", Ships[i].ship_name ));
16356 ship_class_used[Ships[i].ship_info_index]++;
16358 // check if we are going to use a Knossos device and make sure the special warp ani gets pre-loaded
16359 if ( Ship_info[Ships[i].ship_info_index].flags & SIF_KNOSSOS_DEVICE )
16360 Knossos_warp_ani_used = 1;
16362 // mark any weapons as being used, saves memory and time if we don't load them all
16363 ship_weapon *swp = &Ships[i].weapons;
16365 for (j = 0; j < swp->num_primary_banks; j++)
16366 weapon_mark_as_used(swp->primary_bank_weapons[j]);
16368 for (j = 0; j < swp->num_secondary_banks; j++)
16369 weapon_mark_as_used(swp->secondary_bank_weapons[j]);
16371 // get weapons for all capship subsystems (turrets)
16372 ship_subsys *ptr = GET_FIRST(&Ships[i].subsys_list);
16374 while (ptr != END_OF_LIST(&Ships[i].subsys_list)) {
16375 for (k = 0; k < MAX_SHIP_PRIMARY_BANKS; k++)
16376 weapon_mark_as_used(ptr->weapons.primary_bank_weapons[k]);
16378 for (k = 0; k < MAX_SHIP_SECONDARY_BANKS; k++)
16379 weapon_mark_as_used(ptr->weapons.secondary_bank_weapons[k]);
16381 ptr = GET_NEXT(ptr);
16384 ship_info *sip = &Ship_info[Ships[i].ship_info_index];
16386 // page in all of the textures if the model is already loaded
16387 if (sip->model_num >= 0) {
16388 nprintf(( "Paging
", "Paging
in textures for ship '%s'\n", Ships[i].ship_name ));
16389 model_page_in_textures(sip->model_num, Ships[i].ship_info_index);
16390 // need to make sure and do this again, after we are sure that all of the textures are ready
16391 ship_init_afterburners( &Ships[i] );
16394 //WMC - Since this is already in-mission, ignore the warpin effect.
16395 Ships[i].warpout_effect->pageIn();
16397 // don't need this one anymore, it's already been accounted for
16398 // num_subsystems_needed += Ship_info[Ships[i].ship_info_index].n_subsystems;
16401 // Mark any ships that might warp in in the future as used
16402 for (p_object *p_objp = GET_FIRST(&Ship_arrival_list); p_objp != END_OF_LIST(&Ship_arrival_list); p_objp = GET_NEXT(p_objp)) {
16403 nprintf(( "Paging
", "Found future arrival
ship '%s'\n", p_objp->name ));
16404 ship_class_used[p_objp->ship_class]++;
16406 // This will go through Subsys_index[] and grab all weapons: primary, secondary, and turrets
16407 for (i = p_objp->subsys_index; i < (p_objp->subsys_index + p_objp->subsys_count); i++) {
16408 for (j = 0; j < MAX_SHIP_PRIMARY_BANKS; j++) {
16409 if (Subsys_status[i].primary_banks[j] >= 0)
16410 weapon_mark_as_used(Subsys_status[i].primary_banks[j]);
16413 for (j = 0; j < MAX_SHIP_SECONDARY_BANKS; j++) {
16414 if (Subsys_status[i].secondary_banks[j] >= 0)
16415 weapon_mark_as_used(Subsys_status[i].secondary_banks[j]);
16419 // page in any replacement textures
16420 if (Ship_info[p_objp->ship_class].model_num >= 0) {
16421 nprintf(( "Paging
", "Paging
in textures for future arrival
ship '%s'\n", p_objp->name ));
16422 model_page_in_textures(Ship_info[p_objp->ship_class].model_num, p_objp->ship_class);
16425 num_subsystems_needed += Ship_info[p_objp->ship_class].n_subsystems;
16428 // pre-allocate the subsystems, this really only needs to happen for ships
16429 // which don't exist yet (ie, ships NOT in Ships[])
16430 if (!ship_allocate_subsystems(num_subsystems_needed, true)) {
16431 Error(LOCATION, "Attempt to page
in new subsystems subsystems failed because
mission file contains more than %d subsystems
", (NUM_SHIP_SUBSYSTEM_SETS* NUM_SHIP_SUBSYSTEMS_PER_SET));
16434 mprintf(("About to page
in ships!
\n"));
16436 // Page in all the ship classes that are used on this level
16437 int num_ship_types_used = 0;
16438 int test_id __UNUSED = -1;
16440 memset( fireball_used, 0, sizeof(int) * MAX_FIREBALL_TYPES );
16443 for (auto sip = Ship_info.begin(); sip != Ship_info.end(); i++, ++sip) {
16444 if ( !ship_class_used[i] )
16447 int model_previously_loaded = -1;
16448 int ship_previously_loaded = -1;
16450 num_ship_types_used++;
16452 // Page in the small hud icons for each ship
16453 hud_ship_icon_page_in(&(*sip));
16455 // See if this model was previously loaded by another ship
16456 for (auto it = Ship_info.begin(); it != Ship_info.end(); ++it) {
16457 if ( (it->model_num > -1) && !stricmp(sip->pof_file, it->pof_file) ) {
16458 // Model already loaded
16459 model_previously_loaded = it->model_num;
16461 if ((sip->n_subsystems > 0) && (sip->subsystems[0].model_num > -1)) {
16462 ship_previously_loaded = std::distance(Ship_info.begin(), it);
16464 // It is possible in some cases for sip->model_num to change, and for subsystems->model_num
16465 // to still point to the old model index; this makes sure it doesn't happen. -zookeeper
16466 for (k = 0; k < sip->n_subsystems; k++) {
16467 if (sip->model_num != sip->subsystems[k].model_num) {
16468 mprintf(("Ship %
s has
model_num %i but its subsystem %
s has
model_num %
i, fixing...\n
", sip->name, sip->model_num, sip->subsystems[k].name, sip->subsystems[k].model_num));
16469 sip->subsystems[k].model_num = sip->model_num;
16474 // the model should already be loaded so this wouldn't take long, but
16475 // we need to make sure that the load count for the model is correct
16476 test_id = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
16477 Assert( test_id == model_previously_loaded );
16483 // If the model is previously loaded...
16484 if (model_previously_loaded >= 0) {
16485 // If previously loaded model isn't the same ship class...)
16486 if (ship_previously_loaded != i) {
16487 // update the model number.
16488 sip->model_num = model_previously_loaded;
16490 for (j = 0; j < sip->n_subsystems; j++)
16491 sip->subsystems[j].model_num = -1;
16493 ship_copy_subsystem_fixup(&(*sip));
16496 for (j = 0; j < sip->n_subsystems; j++) {
16497 if (sip->subsystems[j].model_num != sip->model_num) {
16498 polymodel *sip_pm = (sip->model_num >= 0) ? model_get(sip->model_num) : NULL;
16499 polymodel *subsys_pm = (sip->subsystems[j].model_num >= 0) ? model_get(sip->subsystems[j].model_num) : NULL;
16500 Warning(LOCATION, "After
ship_copy_subsystem_fixup,
ship '%s' does not have subsystem
'%s' linked into the model file,
'%s'.\n\n(Ship_info model is
'%s' and subsystem model is
'%s'.)
", sip->name, sip->subsystems[j].subobj_name, sip->pof_file, (sip_pm != NULL) ? sip_pm->filename : "NULL
", (subsys_pm != NULL) ? subsys_pm->filename : "NULL
");
16505 // Just to be safe (I mean to check that my code works...)
16506 Assert( sip->model_num >= 0 );
16507 Assert( sip->model_num == model_previously_loaded );
16510 for (j = 0; j < sip->n_subsystems; j++) {
16511 if (sip->subsystems[j].model_num != sip->model_num) {
16512 polymodel *sip_pm = (sip->model_num >= 0) ? model_get(sip->model_num) : NULL;
16513 polymodel *subsys_pm = (sip->subsystems[j].model_num >= 0) ? model_get(sip->subsystems[j].model_num) : NULL;
16514 Warning(LOCATION, "Without
ship_copy_subsystem_fixup,
ship '%s' does not have subsystem
'%s' linked into the model file,
'%s'.\n\n(Ship_info model is
'%s' and subsystem model is
'%s'.)
", sip->name, sip->subsystems[j].subobj_name, sip->pof_file, (sip_pm != NULL) ? sip_pm->filename : "NULL
", (subsys_pm != NULL) ? subsys_pm->filename : "NULL
");
16520 // Model not loaded, so load it
16521 sip->model_num = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
16523 Assert( sip->model_num >= 0 );
16526 // Verify that all the subsystem model numbers are updated
16527 for (j = 0; j < sip->n_subsystems; j++)
16528 Assertion( sip->subsystems[j].model_num == sip->model_num, "Model reference
for subsystem %
s (model
num: %d) on model %
s (model
num: %d) is invalid.\n
", sip->subsystems[j].name, sip->subsystems[j].model_num, sip->pof_file, sip->model_num ); // JAS
16532 // more weapon marking, the weapon info in Ship_info[] is the default
16533 // loadout which isn't specified by missionparse unless it's different
16534 for (j = 0; j < sip->num_primary_banks; j++)
16535 weapon_mark_as_used(sip->primary_bank_weapons[j]);
16537 for (j = 0; j < sip->num_secondary_banks; j++)
16538 weapon_mark_as_used(sip->secondary_bank_weapons[j]);
16540 weapon_mark_as_used(sip->cmeasure_type);
16542 for (j = 0; j < sip->n_subsystems; j++) {
16543 model_subsystem *msp = &sip->subsystems[j];
16545 for (k = 0; k < MAX_SHIP_PRIMARY_BANKS; k++)
16546 weapon_mark_as_used(msp->primary_banks[k]);
16548 for (k = 0; k < MAX_SHIP_SECONDARY_BANKS; k++)
16549 weapon_mark_as_used(msp->secondary_banks[k]);
16552 // Page in the shockwave stuff. -C
16553 shockwave_create_info_load(&sip->shockwave);
16554 if(sip->explosion_bitmap_anims.size() > 0) {
16555 int num_fireballs = sip->explosion_bitmap_anims.size();
16556 for(j = 0; j < num_fireballs; j++){
16557 fireball_used[sip->explosion_bitmap_anims[j]] = 1;
16559 } else if(sip->class_type >= 0 && Ship_types[sip->class_type].explosion_bitmap_anims.size() > 0) {
16560 int num_fireballs = Ship_types[sip->class_type].explosion_bitmap_anims.size();
16561 for(j = 0; j < num_fireballs; j++){
16562 fireball_used[Ship_types[sip->class_type].explosion_bitmap_anims[j]] = 1;
16567 nprintf(( "Paging
", "There are %d
ship classes used
in this mission.\n
", num_ship_types_used ));
16570 // Page in the thruster effects
16571 // Make sure thrusters are loaded
16572 if (!Thrust_anim_inited)
16573 ship_init_thrusters();
16575 thrust_info *thruster;
16576 for (i = 0; i < (int)Species_info.size(); i++) {
16577 thruster = &Species_info[i].thruster_info;
16579 bm_page_in_texture( thruster->flames.normal.first_frame, thruster->flames.normal.num_frames );
16580 bm_page_in_texture( thruster->flames.afterburn.first_frame, thruster->flames.afterburn.num_frames );
16582 // glows are really not anims
16583 bm_page_in_texture( thruster->glow.normal.first_frame );
16584 bm_page_in_texture( thruster->glow.afterburn.first_frame );
16587 // page in insignia bitmaps
16588 if(Game_mode & GM_MULTIPLAYER){
16589 for(i=0; i<MAX_PLAYERS; i++){
16590 if(MULTI_CONNECTED(Net_players[i]) && (Net_players[i].m_player != NULL) && (Net_players[i].m_player->insignia_texture >= 0)){
16591 bm_page_in_xparent_texture(Net_players[i].m_player->insignia_texture);
16595 if((Player != NULL) && (Player->insignia_texture >= 0)){
16596 bm_page_in_xparent_texture(Player->insignia_texture);
16600 // page in wing insignia bitmaps - Goober5000
16601 for (i = 0; i < MAX_WINGS; i++)
16603 if (Wings[i].wing_insignia_texture >= 0)
16604 bm_page_in_xparent_texture(Wings[i].wing_insignia_texture);
16607 // page in replacement textures - Goober5000
16608 for (i = 0; i < MAX_SHIPS; i++)
16610 // is this a valid ship?
16611 if (Ships[i].objnum >= 0)
16613 // do we have any textures?
16614 if (Ships[i].ship_replacement_textures != NULL)
16616 // page in replacement textures
16617 for (j=0; j<MAX_REPLACEMENT_TEXTURES; j++)
16619 if (Ships[i].ship_replacement_textures[j] > -1)
16621 bm_page_in_texture( Ships[i].ship_replacement_textures[j] );
16628 // should never be NULL, this entire function wouldn't work
16629 delete[] ship_class_used;
16630 ship_class_used = NULL;
16634 // Goober5000 - called from ship_page_in()
16635 void ship_page_in_textures(int ship_index)
16640 if ( (ship_index < 0) || (ship_index >= static_cast<int>(Ship_info.size())) )
16644 sip = &Ship_info[ship_index];
16647 if ( !generic_bitmap_load(&sip->afterburner_trail) )
16648 bm_page_in_texture(sip->afterburner_trail.bitmap_id);
16650 // Wanderer - just copying over Bobboau's code...
16651 if ( !generic_anim_load(&sip->thruster_flame_info.normal) )
16652 bm_page_in_texture(sip->thruster_flame_info.normal.first_frame);
16654 if ( !generic_anim_load(&sip->thruster_flame_info.afterburn) )
16655 bm_page_in_texture(sip->thruster_flame_info.afterburn.first_frame);
16657 // Bobboau's thruster bitmaps
16658 // the first set has to be loaded a special way
16659 if ( !thruster_glow_anim_load(&sip->thruster_glow_info.normal) )
16660 bm_page_in_texture(sip->thruster_glow_info.normal.first_frame);
16662 if ( !thruster_glow_anim_load(&sip->thruster_glow_info.afterburn) )
16663 bm_page_in_texture(sip->thruster_glow_info.afterburn.first_frame);
16665 // everything else is loaded normally
16666 if ( !generic_bitmap_load(&sip->thruster_secondary_glow_info.normal) )
16667 bm_page_in_texture(sip->thruster_secondary_glow_info.normal.bitmap_id);
16669 if ( !generic_bitmap_load(&sip->thruster_secondary_glow_info.afterburn) )
16670 bm_page_in_texture(sip->thruster_secondary_glow_info.afterburn.bitmap_id);
16672 if ( !generic_bitmap_load(&sip->thruster_tertiary_glow_info.normal) )
16673 bm_page_in_texture(sip->thruster_tertiary_glow_info.normal.bitmap_id);
16675 if ( !generic_bitmap_load(&sip->thruster_tertiary_glow_info.afterburn) )
16676 bm_page_in_texture(sip->thruster_tertiary_glow_info.afterburn.bitmap_id);
16678 // splodeing bitmap
16679 if ( VALID_FNAME(sip->splodeing_texture_name) ) {
16680 sip->splodeing_texture = bm_load(sip->splodeing_texture_name);
16681 bm_page_in_texture(sip->splodeing_texture);
16684 // thruster/particle bitmaps
16685 for (i = 0; i < (int)sip->normal_thruster_particles.size(); i++) {
16686 generic_anim_load(&sip->normal_thruster_particles[i].thruster_bitmap);
16687 bm_page_in_texture(sip->normal_thruster_particles[i].thruster_bitmap.first_frame);
16690 for (i = 0; i < (int)sip->afterburner_thruster_particles.size(); i++) {
16691 generic_anim_load(&sip->afterburner_thruster_particles[i].thruster_bitmap);
16692 bm_page_in_texture(sip->afterburner_thruster_particles[i].thruster_bitmap.first_frame);
16697 #define PAGE_OUT_TEXTURE(x) { \
16698 if ( (x) >= 0 ) { \
16700 bm_release( (x) ); \
16703 bm_unload( (x) ); \
16711 void ship_page_out_textures(int ship_index, bool release)
16716 if ( (ship_index < 0) || (ship_index >= static_cast<int>(Ship_info.size())) )
16720 sip = &Ship_info[ship_index];
16723 PAGE_OUT_TEXTURE(sip->afterburner_trail.bitmap_id);
16725 // thruster bitmaps
16726 PAGE_OUT_TEXTURE(sip->thruster_flame_info.normal.first_frame);
16727 PAGE_OUT_TEXTURE(sip->thruster_flame_info.afterburn.first_frame);
16728 PAGE_OUT_TEXTURE(sip->thruster_glow_info.normal.first_frame);
16729 PAGE_OUT_TEXTURE(sip->thruster_glow_info.afterburn.first_frame);
16730 PAGE_OUT_TEXTURE(sip->thruster_secondary_glow_info.normal.bitmap_id);
16731 PAGE_OUT_TEXTURE(sip->thruster_secondary_glow_info.afterburn.bitmap_id);
16732 PAGE_OUT_TEXTURE(sip->thruster_tertiary_glow_info.normal.bitmap_id);
16733 PAGE_OUT_TEXTURE(sip->thruster_tertiary_glow_info.afterburn.bitmap_id);
16736 PAGE_OUT_TEXTURE(sip->splodeing_texture);
16738 // thruster/particle bitmaps
16739 for (i = 0; i < (int)sip->normal_thruster_particles.size(); i++)
16740 PAGE_OUT_TEXTURE(sip->normal_thruster_particles[i].thruster_bitmap.first_frame);
16742 for (i = 0; i < (int)sip->afterburner_thruster_particles.size(); i++)
16743 PAGE_OUT_TEXTURE(sip->afterburner_thruster_particles[i].thruster_bitmap.first_frame);
16746 // function to return true if support ships are allowed in the mission for the given object.
16747 // In single player, must be friendly and not Shivan. (Goober5000 - Shivans can now have support)
16748 // In multiplayer -- to be coded by Mark Allender after 5/4/98 -- MK, 5/4/98
16749 int is_support_allowed(object *objp, bool do_simple_check)
16753 // check updated mission conditions to allow support
16755 // If running under autopilot support is not allowed
16756 if ( AutoPilotEngaged )
16760 if (The_mission.support_ships.max_support_ships == 0)
16763 // ship_find_repair_ship is a little expensive, so let's not do it every frame
16764 if (!do_simple_check)
16766 // check if all support ships are departing or dying
16767 result = ship_find_repair_ship(objp);
16772 // restricted number allowed
16773 if (The_mission.support_ships.max_support_ships > 0)
16775 // if all the allowed ships have been used up, can't rearm unless something's available in-mission or arriving
16776 if ((The_mission.support_ships.tally >= The_mission.support_ships.max_support_ships))
16778 // this shouldn't happen because we've reached one of the limits
16779 Assert(result != 2);
16781 // nothing arriving and no ships available in mission
16782 if ((Arriving_support_ship == NULL) && (result == 0 || result == 3))
16788 ship *shipp = &Ships[objp->instance];
16790 // this also looks a little more expensive
16791 if (!do_simple_check)
16793 // make sure, if exiting from bay, that parent ship is in the mission!
16794 if ((result == 0 || result == 2) && (The_mission.support_ships.arrival_location == ARRIVE_FROM_DOCK_BAY))
16796 Assert(The_mission.support_ships.arrival_anchor != -1);
16798 // ensure it's in-mission
16799 int temp = ship_name_lookup(Parse_names[The_mission.support_ships.arrival_anchor]);
16805 // make sure it's not leaving or blowing up
16806 if (Ships[temp].flags & (SF_DYING | SF_DEPARTING))
16811 // also make sure that parent ship's fighterbay hasn't been destroyed
16812 if (ship_fighterbays_all_destroyed(&Ships[temp]))
16819 if (Game_mode & GM_NORMAL)
16821 if ( !(Iff_info[shipp->team].flags & IFFF_SUPPORT_ALLOWED) )
16828 // multiplayer version behaves differently. Depending on mode:
16829 // 1) coop mode -- only available to friendly
16830 // 2) team v team mode -- availble to either side
16831 // 3) dogfight -- never
16833 if(Netgame.type_flags & NG_TYPE_DOGFIGHT)
16838 if (IS_MISSION_MULTI_COOP)
16840 if ( !(Iff_info[shipp->team].flags & IFFF_SUPPORT_ALLOWED) )
16847 // Goober5000 - extra check for existence of support ship
16848 if ( (The_mission.support_ships.ship_class < 0) &&
16849 !(The_mission.support_ships.support_available_for_species & (1 << Ship_info[shipp->ship_info_index].species)) )
16854 // this is also somewhat expensive
16855 if (!do_simple_check)
16857 // Goober5000 - extra check to make sure this guy has a rearming dockpoint
16858 if (model_find_dock_index(Ship_info[shipp->ship_info_index].model_num, DOCK_TYPE_REARM) < 0)
16860 static bool warned_about_rearm_dockpoint = false;
16861 if (!warned_about_rearm_dockpoint)
16863 Warning(LOCATION, "Support not allowed
for %
s because its model lacks
a rearming dockpoint!
", shipp->ship_name);
16864 warned_about_rearm_dockpoint = true;
16870 // Goober5000 - if we got this far, we can request support
16874 // returns random index of a visible ship
16875 // if no visible ships are generated in num_ships iterations, it returns -1
16876 int ship_get_random_targetable_ship()
16879 int idx = 0, target_list[MAX_SHIPS];
16882 for ( so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so) ) {
16883 // make sure the instance is valid
16884 if ( (Objects[so->objnum].instance < 0) || (Objects[so->objnum].instance >= MAX_SHIPS) )
16887 // skip if we aren't supposed to target it
16888 if ( Ships[Objects[so->objnum].instance].flags & TARGET_SHIP_IGNORE_FLAGS )
16891 if (idx >= MAX_SHIPS) {
16896 target_list[idx] = Objects[so->objnum].instance;
16903 rand_ship = (rand() % idx);
16905 return target_list[rand_ship];
16911 void object_jettison_cargo(object *objp, object *cargo_objp)
16913 // make sure we are docked
16914 Assert((objp != NULL) && (cargo_objp != NULL));
16915 Assert(dock_check_find_direct_docked_object(objp, cargo_objp));
16917 vec3d impulse, pos;
16918 ship *shipp = &Ships[objp->instance];
16919 ship *cargo_shipp = &Ships[cargo_objp->instance];
16920 int docker_index = dock_find_dockpoint_used_by_object(objp, cargo_objp);
16921 int dockee_index = dock_find_dockpoint_used_by_object(cargo_objp, objp);
16923 // undo all the docking animations
16924 model_anim_start_type(shipp, TRIGGER_TYPE_DOCKED, docker_index, -1);
16925 model_anim_start_type(shipp, TRIGGER_TYPE_DOCKING_STAGE_3, docker_index, -1);
16926 model_anim_start_type(shipp, TRIGGER_TYPE_DOCKING_STAGE_2, docker_index, -1);
16927 model_anim_start_type(shipp, TRIGGER_TYPE_DOCKING_STAGE_1, docker_index, -1);
16928 model_anim_start_type(cargo_shipp, TRIGGER_TYPE_DOCKED, dockee_index, -1);
16929 model_anim_start_type(cargo_shipp, TRIGGER_TYPE_DOCKING_STAGE_3, dockee_index, -1);
16930 model_anim_start_type(cargo_shipp, TRIGGER_TYPE_DOCKING_STAGE_2, dockee_index, -1);
16931 model_anim_start_type(cargo_shipp, TRIGGER_TYPE_DOCKING_STAGE_1, dockee_index, -1);
16933 // undock the objects
16934 ai_do_objects_undocked_stuff(objp, cargo_objp);
16936 // Goober5000 - add log
16937 mission_log_add_entry(LOG_SHIP_UNDOCKED, shipp->ship_name, cargo_shipp->ship_name);
16940 vm_vec_sub(&pos, &cargo_objp->pos, &objp->pos);
16942 vm_vec_scale(&impulse, 100.0f);
16943 vm_vec_normalize(&pos);
16946 physics_apply_whack(&impulse, &pos, &cargo_objp->phys_info, &cargo_objp->orient, cargo_objp->phys_info.mass);
16949 float ship_get_exp_damage(object* objp)
16951 Assert(objp->type == OBJ_SHIP);
16954 ship *shipp = &Ships[objp->instance];
16956 if (shipp->special_exp_damage >= 0) {
16957 damage = i2fl(shipp->special_exp_damage);
16959 damage = Ship_info[shipp->ship_info_index].shockwave.damage;
16965 int ship_get_exp_propagates(ship *sp)
16967 return Ship_info[sp->ship_info_index].explosion_propagates;
16970 float ship_get_exp_outer_rad(object *ship_objp)
16973 Assert(ship_objp->type == OBJ_SHIP);
16975 if (Ships[ship_objp->instance].special_exp_outer == -1) {
16976 outer_rad = Ship_info[Ships[ship_objp->instance].ship_info_index].shockwave.outer_rad;
16978 outer_rad = (float)Ships[ship_objp->instance].special_exp_outer;
16984 int valid_cap_subsys_cargo_list(char *subsys)
16986 // Return 1 for all subsystems now, due to Mantis #2524.
16989 if (stristr(subsys, "nav
")
16990 || stristr(subsys, "comm
")
16991 || stristr(subsys, "engine
")
16992 || stristr(subsys, "fighter
") // fighter bays
16993 || stristr(subsys, "sensors
")
16994 || stristr(subsys, "weapons
")) {
17008 int ship_get_turret_type(ship_subsys *subsys)
17010 // not a turret at all
17011 if(subsys->system_info->type != SUBSYSTEM_TURRET){
17016 if(subsys->system_info->turret_turning_rate > 0.0f){
17024 ship_subsys *ship_get_subsys(ship *shipp, char *subsys_name)
17027 if ((shipp == NULL) || (subsys_name == NULL)) {
17031 ship_subsys *ss = GET_FIRST(&shipp->subsys_list);
17032 while (ss != END_OF_LIST(&shipp->subsys_list)) {
17033 // check subsystem name
17034 if (!subsystem_stricmp(ss->system_info->subobj_name, subsys_name)) {
17046 int ship_get_num_subsys(ship *shipp)
17048 Assert(shipp != NULL);
17050 return Ship_info[shipp->ship_info_index].n_subsystems;
17053 // returns 0 if no conflict, 1 if conflict, -1 on some kind of error with wing struct
17054 int wing_has_conflicting_teams(int wing_index)
17056 int first_team, idx;
17059 Assert((wing_index >= 0) && (wing_index < Num_wings) && (Wings[wing_index].wave_count > 0));
17060 if((wing_index < 0) || (wing_index >= Num_wings) || (Wings[wing_index].wave_count <= 0)){
17065 Assert(Wings[wing_index].ship_index[0] >= 0);
17066 if(Wings[wing_index].ship_index[0] < 0){
17069 first_team = Ships[Wings[wing_index].ship_index[0]].team;
17070 for(idx=1; idx<Wings[wing_index].wave_count; idx++){
17071 // more sanity checks
17072 Assert(Wings[wing_index].ship_index[idx] >= 0);
17073 if(Wings[wing_index].ship_index[idx] < 0){
17077 // if we've got a team conflict
17078 if(first_team != Ships[Wings[wing_index].ship_index[idx]].team){
17090 int ship_get_reinforcement_team(int r_index)
17096 Assert((r_index >= 0) && (r_index < Num_reinforcements));
17097 if ((r_index < 0) || (r_index >= Num_reinforcements))
17100 // if the reinforcement is a ship
17101 p_objp = mission_parse_get_arrival_ship(Reinforcements[r_index].name);
17102 if (p_objp != NULL)
17103 return p_objp->team;
17105 // if the reinforcement is a ship
17106 wing_index = wing_lookup(Reinforcements[r_index].name);
17107 if (wing_index >= 0)
17109 // go through the ship arrival list and find any ship in this wing
17110 for (p_objp = GET_FIRST(&Ship_arrival_list); p_objp != END_OF_LIST(&Ship_arrival_list); p_objp = GET_NEXT(p_objp))
17112 // check by wingnum
17113 if (p_objp->wingnum == wing_index)
17114 return p_objp->team;
17125 int ship_get_texture(int bitmap)
17127 // check all ship types
17128 for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it) {
17129 if ((it->model_num >= 0) && model_find_texture(it->model_num, bitmap) == 1) {
17130 return std::distance(Ship_info.cbegin(), it);
17134 // couldn't find the texture
17138 // update artillery lock info
17139 #define CLEAR_ARTILLERY_AND_CONTINUE() { if(aip != NULL){ aip->artillery_objnum = -1; aip->artillery_sig = -1; aip->artillery_lock_time = 0.0f;} continue; }
17140 float artillery_dist = 10.0f;
17141 DCF(art, "Sets artillery disance
")
17143 dc_stuff_float(&artillery_dist);
17146 void ship_update_artillery_lock()
17148 ai_info *aip = NULL;
17149 mc_info *cinfo = NULL;
17151 vec3d temp, local_hit;
17155 // update all ships
17156 for ( so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so) ){
17158 if((so->objnum >= 0) && (Objects[so->objnum].type == OBJ_SHIP) && (Objects[so->objnum].instance >= 0)){
17159 shipp = &Ships[Objects[so->objnum].instance];
17165 if(shipp->ai_index >= 0){
17166 aip = &Ai_info[shipp->ai_index];
17169 // if the ship has no targeting laser firing
17170 if((shipp->targeting_laser_objnum < 0) || (shipp->targeting_laser_bank < 0)){
17171 CLEAR_ARTILLERY_AND_CONTINUE();
17174 // if he didn't hit any objects this frame
17175 if(beam_get_num_collisions(shipp->targeting_laser_objnum) <= 0){
17176 CLEAR_ARTILLERY_AND_CONTINUE();
17179 // get weapon info for the targeting laser he's firing
17180 Assert((shipp->weapons.current_primary_bank >= 0) && (shipp->weapons.current_primary_bank < 2));
17181 if((shipp->weapons.current_primary_bank < 0) || (shipp->weapons.current_primary_bank >= 2)){
17184 Assert(shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank] >= 0);
17185 if(shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank] < 0){
17188 Assert((Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]].wi_flags & WIF_BEAM) && (Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]].b_info.beam_type == BEAM_TYPE_C));
17189 if(!(Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]].wi_flags & WIF_BEAM) || (Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]].b_info.beam_type != BEAM_TYPE_C)){
17193 // get collision info
17194 if(!beam_get_collision(shipp->targeting_laser_objnum, 0, &c_objnum, &cinfo)){
17195 CLEAR_ARTILLERY_AND_CONTINUE();
17197 if((c_objnum < 0) || (cinfo == NULL)){
17198 CLEAR_ARTILLERY_AND_CONTINUE();
17201 // get the position we hit this guy with in his local coords
17202 vm_vec_sub(&temp, &cinfo->hit_point_world, &Objects[c_objnum].pos);
17203 vm_vec_rotate(&local_hit, &temp, &Objects[c_objnum].orient);
17205 // if we are hitting a different guy now, reset the lock
17206 if((c_objnum != aip->artillery_objnum) || (Objects[c_objnum].signature != aip->artillery_sig)){
17207 aip->artillery_objnum = c_objnum;
17208 aip->artillery_sig = Objects[c_objnum].signature;
17209 aip->artillery_lock_time = 0.0f;
17210 aip->artillery_lock_pos = local_hit;
17216 // otherwise we're hitting the same guy. check to see if we've strayed too far
17217 if(vm_vec_dist_quick(&local_hit, &aip->artillery_lock_pos) > artillery_dist){
17218 // hmmm. reset lock time, but don't reset the lock itself
17219 aip->artillery_lock_time = 0.0f;
17223 // finally - just increment the lock time
17224 aip->artillery_lock_time += flFrametime;
17227 if(aip->artillery_objnum >= 0 && aip->artillery_lock_time >= 2.0f){
17228 ssm_create(&Objects[aip->artillery_objnum], &cinfo->hit_point_world, 0, NULL, shipp->team);
17230 // reset the artillery
17231 aip->artillery_lock_time = 0.0f;
17241 int check_world_pt_in_expanded_ship_bbox(vec3d *world_pt, object *objp, float delta_box)
17243 Assert(objp->type == OBJ_SHIP);
17245 vec3d temp, ship_pt;
17247 vm_vec_sub(&temp, world_pt, &objp->pos);
17248 vm_vec_rotate(&ship_pt, &temp, &objp->orient);
17250 pm = model_get(Ship_info[Ships[objp->instance].ship_info_index].model_num);
17253 (ship_pt.xyz.x > pm->mins.xyz.x - delta_box) && (ship_pt.xyz.x < pm->maxs.xyz.x + delta_box)
17254 && (ship_pt.xyz.y > pm->mins.xyz.y - delta_box) && (ship_pt.xyz.y < pm->maxs.xyz.y + delta_box)
17255 && (ship_pt.xyz.z > pm->mins.xyz.z - delta_box) && (ship_pt.xyz.z < pm->maxs.xyz.z + delta_box)
17263 int ship_is_tagged(object *objp)
17266 if (objp->type == OBJ_SHIP) {
17267 shipp = &Ships[objp->instance];
17268 if ( (shipp->tag_left > 0) || (shipp->level2_tag_left > 0) ) {
17279 float ship_get_max_speed(ship *shipp)
17282 ship_info *sip = &Ship_info[shipp->ship_info_index];
17284 // Goober5000 - maybe we're using cap-waypoint-speed
17285 ai_info *aip = &Ai_info[shipp->ai_index];
17286 if ((aip->mode == AIM_WAYPOINTS || aip->mode == AIM_FLY_TO_SHIP) && aip->waypoint_speed_cap > 0)
17287 return i2fl(aip->waypoint_speed_cap);
17290 max_speed = sip->max_overclocked_speed;
17292 // normal max speed
17293 max_speed = MAX(max_speed, sip->max_vel.xyz.z);
17295 // afterburn if not locked
17296 if (!(shipp->flags2 & SF2_AFTERBURNER_LOCKED)) {
17297 max_speed = MAX(max_speed, sip->afterburner_max_vel.xyz.z);
17306 float ship_get_warpout_speed(object *objp)
17308 Assert(objp->type == OBJ_SHIP);
17310 ship_info *sip = &Ship_info[Ships[objp->instance].ship_info_index];
17311 //WMC - Any speed is good for in place anims (aka BSG FTL effect)
17312 if(sip->warpout_type == WT_IN_PLACE_ANIM && sip->warpout_speed <= 0.0f)
17314 return objp->phys_info.speed;
17316 else if(sip->warpout_type == WT_SWEEPER || sip->warpout_type == WT_IN_PLACE_ANIM)
17318 return sip->warpout_speed;
17320 else if(sip->warpout_type == WT_HYPERSPACE)
17322 if (objp->phys_info.speed > sip->warpout_speed)
17323 return objp->phys_info.speed;
17325 return sip->warpout_speed;
17328 return shipfx_calculate_warp_dist(objp) / shipfx_calculate_warp_time(objp, WD_WARP_OUT);
17334 int ship_is_beginning_warpout_speedup(object *objp)
17336 Assert(objp->type == OBJ_SHIP);
17340 aip = &Ai_info[Ships[objp->instance].ai_index];
17342 if (aip->mode == AIM_WARP_OUT) {
17343 if ( (aip->submode == AIS_WARP_3) || (aip->submode == AIS_WARP_4) || (aip->submode == AIS_WARP_5) ) {
17354 float ship_class_get_length(ship_info *sip)
17356 Assert(sip->model_num >= 0);
17357 polymodel *pm = model_get(sip->model_num);
17358 return (pm->maxs.xyz.z - pm->mins.xyz.z);
17362 void ship_set_new_ai_class(int ship_num, int new_ai_class)
17364 Assert(ship_num >= 0 && ship_num < MAX_SHIPS);
17365 Assert(new_ai_class >= 0);
17367 ai_info *aip = &Ai_info[Ships[ship_num].ai_index];
17369 // we hafta change a bunch of stuff here...
17370 aip->ai_class = new_ai_class;
17371 aip->behavior = AIM_NONE;
17372 init_aip_from_class_and_profile(aip, &Ai_classes[new_ai_class], The_mission.ai_profile);
17374 Ships[ship_num].weapons.ai_class = new_ai_class;
17376 // I think that's everything!
17380 void ship_subsystem_set_new_ai_class(int ship_num, char *subsystem, int new_ai_class)
17382 Assert(ship_num >= 0 && ship_num < MAX_SHIPS);
17384 Assert(new_ai_class >= 0);
17388 // find the ship subsystem by searching ship's subsys_list
17389 ss = GET_FIRST( &Ships[ship_num].subsys_list );
17390 while ( ss != END_OF_LIST( &Ships[ship_num].subsys_list ) )
17392 // if we found the subsystem
17393 if ( !subsystem_stricmp(ss->system_info->subobj_name, subsystem))
17396 ss->weapons.ai_class = new_ai_class;
17400 ss = GET_NEXT( ss );
17404 // Goober5000 - will attempt to load an insignia bitmap and set it as active for the wing
17405 // copied more or less from managepilot.cpp
17406 void wing_load_squad_bitmap(wing *w)
17414 // make sure one is not already set?!?
17415 Assert (w->wing_insignia_texture == -1);
17417 // try and set the new one
17418 if( w->wing_squad_filename[0] != '\0' )
17420 // load duplicate because it might be the same as the player's squad,
17421 // and we don't want to overlap and breed nasty errors when we unload
17422 w->wing_insignia_texture = bm_load_duplicate(w->wing_squad_filename);
17424 // lock is as a transparent texture
17425 if(w->wing_insignia_texture != -1)
17427 bm_lock(w->wing_insignia_texture, 16, BMP_TEX_XPARENT);
17428 bm_unlock(w->wing_insignia_texture);
17433 // Goober5000 - needed by new hangar depart code
17434 // check whether this ship has a docking bay
17435 bool ship_has_dock_bay(int shipnum)
17437 Assert(shipnum >= 0 && shipnum < MAX_SHIPS);
17441 pm = model_get( Ship_info[Ships[shipnum].ship_info_index].model_num );
17444 return ( pm->ship_bay && (pm->ship_bay->num_paths > 0) );
17448 bool ship_useful_for_departure(int shipnum, int path_mask)
17450 Assert( shipnum >= 0 && shipnum < MAX_SHIPS );
17452 // not valid if dying or departing
17453 if (Ships[shipnum].flags & (SF_DYING | SF_DEPARTING))
17456 // no dockbay, can't depart to it
17457 if (!ship_has_dock_bay(shipnum))
17460 // make sure that the bays are not all destroyed
17461 if (ship_fighterbays_all_destroyed(&Ships[shipnum]))
17464 // in the future, we might want to check bay paths against destroyed fighterbays,
17465 // but that capability doesn't currently exist
17466 // (note, a mask of 0 indicates all paths are valid)
17467 //if (path_mask != 0)
17475 // Goober5000 - needed by new hangar depart code
17476 // get first ship in ship list with docking bay
17477 int ship_get_ship_for_departure(int team)
17479 for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
17481 Assert(so->objnum >= 0);
17482 int shipnum = Objects[so->objnum].instance;
17483 Assert(shipnum >= 0);
17485 if ( (Ships[shipnum].team == team) && ship_useful_for_departure(shipnum) )
17489 // we didn't find anything
17493 // Goober5000 - check if all fighterbays on a ship have been destroyed
17494 bool ship_fighterbays_all_destroyed(ship *shipp)
17497 ship_subsys *subsys;
17498 int num_fighterbay_subsystems = 0;
17500 // check all fighterbay systems
17501 subsys = GET_FIRST(&shipp->subsys_list);
17502 while(subsys != END_OF_LIST(&shipp->subsys_list))
17504 // look for fighterbays
17505 if (ship_subsys_is_fighterbay(subsys))
17507 num_fighterbay_subsystems++;
17509 // if fighterbay doesn't take damage, we're good
17510 if (!ship_subsys_takes_damage(subsys))
17513 // if fighterbay isn't destroyed, we're good
17514 if (subsys->current_hits > 0)
17519 subsys = GET_NEXT(subsys);
17522 // if the ship has no fighterbay subsystems at all, it must be an unusual case,
17523 // like the Faustus, so pretend it's okay...
17524 if (num_fighterbay_subsystems == 0)
17527 // if we got this far, the ship has at least one fighterbay subsystem,
17528 // and all the ones it has are destroyed
17532 // moved here by Goober5000
17533 bool ship_subsys_is_fighterbay(ship_subsys *ss)
17537 if ( !strnicmp(NOX("fighter
"), ss->system_info->name, 7) ) {
17545 bool ship_subsys_takes_damage(ship_subsys *ss)
17549 return (ss->max_hits > SUBSYS_MAX_HITS_THRESHOLD);
17553 void ship_do_submodel_rotation(ship *shipp, model_subsystem *psub, ship_subsys *pss)
17559 // check if we actually can rotate
17560 if ( !(pss->flags & SSF_ROTATES) ){
17564 if (psub->flags & MSS_FLAG_TRIGGERED && pss->triggered_rotation_index >= 0) {
17565 Triggered_rotations[pss->triggered_rotation_index].process_queue();
17566 model_anim_submodel_trigger_rotate(psub, pss );
17571 // check for rotating artillery
17572 if ( psub->flags & MSS_FLAG_ARTILLERY )
17574 ship_weapon *swp = &shipp->weapons;
17576 // rotate only if trigger is down
17577 if ( !(shipp->flags & SF_TRIGGER_DOWN) )
17581 if ( shipp->flags & SF_PRIMARY_LINKED )
17583 int i, ammo_tally = 0;
17586 for (i=0; i<swp->num_primary_banks; i++)
17587 ammo_tally += swp->primary_bank_ammo[i];
17589 // do not rotate if out of ammo
17590 if (ammo_tally <= 0)
17596 // do not rotate if this is not the firing bank or if we have no ammo in this bank
17597 if ((psub->weapon_rotation_pbank != swp->current_primary_bank) || (swp->primary_bank_ammo[swp->current_primary_bank] <= 0))
17602 // if we got this far, we can rotate - so choose which method to use
17603 if (psub->flags & MSS_FLAG_STEPPED_ROTATE ) {
17604 submodel_stepped_rotate(psub, &pss->submodel_info_1);
17606 submodel_rotate(psub, &pss->submodel_info_1 );
17611 int ship_has_energy_weapons(ship *shipp)
17613 // (to avoid round-off errors, weapon reserve is not tested for zero)
17614 return (Ship_info[shipp->ship_info_index].max_weapon_reserve > WEAPON_RESERVE_THRESHOLD);
17618 int ship_has_engine_power(ship *shipp)
17620 return (Ship_info[shipp->ship_info_index].max_speed > 0 );
17624 int ship_starting_wing_lookup(const char *wing_name)
17626 for (int i = 0; i < MAX_STARTING_WINGS; i++)
17628 if (!stricmp(Starting_wing_names[i], wing_name))
17636 int ship_squadron_wing_lookup(const char *wing_name)
17638 // TvT uses a different set of wing names from everything else
17641 for (int i = 0; i < MAX_TVT_WINGS; i++)
17643 if (!stricmp(TVT_wing_names[i], wing_name))
17649 for (int i = 0; i < MAX_SQUADRON_WINGS; i++)
17651 if (!stricmp(Squadron_wing_names[i], wing_name))
17660 int ship_tvt_wing_lookup(const char *wing_name)
17662 for (int i = 0; i < MAX_TVT_WINGS; i++)
17664 if (!stricmp(TVT_wing_names[i], wing_name))
17672 int ship_class_get_priority(int ship_class)
17674 ship_info *sip = &Ship_info[ship_class];
17676 // biggest to smallest
17677 if (sip->flags & SIF_KNOSSOS_DEVICE)
17679 else if (sip->flags & SIF_SUPERCAP)
17681 else if (sip->flags & SIF_DRYDOCK)
17683 else if (sip->flags & SIF_CAPITAL)
17685 else if (sip->flags & SIF_CORVETTE)
17687 else if (sip->flags & SIF_CRUISER)
17689 else if (sip->flags & SIF_GAS_MINER)
17691 else if (sip->flags & SIF_AWACS)
17693 else if (sip->flags & SIF_FREIGHTER)
17695 else if (sip->flags & SIF_TRANSPORT)
17697 else if (sip->flags & SIF_BOMBER)
17699 else if (sip->flags & (SIF_FIGHTER | SIF_STEALTH))
17701 else if (sip->flags & SIF_ESCAPEPOD)
17703 else if (sip->flags & SIF_SENTRYGUN)
17705 else if (sip->flags & SIF_CARGO)
17707 else if (sip->flags & SIF_NAVBUOY)
17710 Warning(LOCATION, "Unknown priority
for ship class '%
s'!", sip->name);
17711 return 17 + ship_class;
17715 int ship_class_compare(int ship_class_1, int ship_class_2)
17718 int priority1 = ship_class_get_priority(ship_class_1);
17719 int priority2 = ship_class_get_priority(ship_class_2);
17721 // standard compare
17722 if (priority1 < priority2)
17724 else if (priority1 > priority2)
17734 int damage_type_get_idx(char *name)
17736 //This should never be bigger than INT_MAX anyway
17737 for(int i = 0; i < (int)Damage_types.size(); i++)
17739 if(!stricmp(name, Damage_types[i].name))
17749 int damage_type_add(char *name)
17751 int i = damage_type_get_idx(name);
17755 DamageTypeStruct dts;
17757 strncpy(dts.name, name, NAME_LENGTH-1);
17759 if(strlen(name) > NAME_LENGTH - 1)
17761 Warning(LOCATION, "Damage type name '%
s' is too long and has been truncated to '%
s'", name, dts.name);
17764 Damage_types.push_back(dts);
17765 return Damage_types.size()-1;
17768 void ArmorDamageType::clear()
17770 DamageTypeIndex = -1;
17772 Calculations.clear();
17774 altArguments.clear(); // Nuke: don't forget to
delete it
17795 return PiercingTypes[
i].
def;
17815 return DifficultyScaleTypes[
i].
def;
17837 return ArmorTypeConstants[
i].
def;
17852 #define AT_TYPE_ADDITIVE 0
17853 #define AT_TYPE_MULTIPLICATIVE 1
17854 #define AT_TYPE_EXPONENTIAL 2
17855 #define AT_TYPE_EXPONENTIAL_BASE 3
17856 #define AT_TYPE_CUTOFF 4
17857 #define AT_TYPE_REVERSE_CUTOFF 5
17858 #define AT_TYPE_INSTANT_CUTOFF 6
17859 #define AT_TYPE_INSTANT_REVERSE_CUTOFF 7
17861 #define AT_TYPE_CAP 8
17862 #define AT_TYPE_INSTANT_CAP 9
17863 #define AT_TYPE_SET 10
17864 #define AT_TYPE_STORE 11
17865 #define AT_TYPE_LOAD 12
17866 #define AT_TYPE_RANDOM 13
17869 #define AT_NUM_STORAGE_LOCATIONS 8
17876 "exponential base",
17880 "instant reverse cutoff",
17915 if(!
stricmp(TypeNames[i], str))
17926 if (in_damage_type_idx < 0) {
17928 return (damage_applied * diff_dmg_scale);
17936 num = DamageTypes.size();
17937 for(i = 0; i <
num; i++)
17939 if(DamageTypes[i].DamageTypeIndex == in_damage_type_idx)
17941 adtp = &DamageTypes[
i];
17953 num = adtp->Calculations.size();
17956 bool end_now =
false;
17960 bool using_storage =
false;
17962 float constant_val;
17964 bool using_constant =
false;
17973 damage_applied *= diff_dmg_scale;
17977 base_damage = damage_applied;
17979 for (i = 0; i <
num; i++) {
17980 storage_idx = adtp->altArguments[
i];
17983 if ( (storage_idx >= 0) && (storage_idx < AT_NUM_STORAGE_LOCATIONS) ) {
17984 curr_arg = storage[storage_idx];
17985 using_storage =
true;
17988 curr_arg = adtp->Arguments[
i];
17991 curr_arg = base_damage;
17992 using_constant =
true;
17994 curr_arg = damage_applied;
17995 using_constant =
true;
17997 curr_arg = diff_dmg_scale;
17998 using_constant =
true;
18000 constant_val =
frand();
18001 curr_arg = constant_val;
18002 using_constant =
true;
18005 curr_arg = constant_val;
18006 using_constant =
true;
18008 constant_val = 0.0f;
18009 curr_arg = constant_val;
18012 switch(adtp->Calculations[i])
18015 damage_applied += curr_arg;
18018 damage_applied *= curr_arg;
18021 damage_applied = powf(damage_applied, curr_arg);
18024 damage_applied = powf(curr_arg, damage_applied);
18027 if(damage_applied < curr_arg)
18028 damage_applied = 0;
18031 if(damage_applied > curr_arg)
18032 damage_applied = 0;
18035 if(damage_applied < curr_arg)
18037 damage_applied = 0;
18042 if(damage_applied > curr_arg)
18044 damage_applied = 0;
18049 if (damage_applied > curr_arg)
18050 damage_applied = curr_arg;
18053 if (damage_applied > curr_arg) {
18054 damage_applied = curr_arg;
18059 damage_applied = curr_arg;
18062 if (using_storage || using_constant) {
18063 Warning(
LOCATION,
"Cannot use +Stored Value: or +Constant: with +Store:, that would be bad. Skipping calculation.");
18065 storage_idx =
int(floorf(curr_arg));
18067 if ( (storage_idx < 0) || (storage_idx >= AT_NUM_STORAGE_LOCATIONS) ) {
18068 Warning(
LOCATION,
"+Value: for +Store: calculation out of range. Should be between 0 and %i. Read: %i, Skipping calculation.", AT_NUM_STORAGE_LOCATIONS, storage_idx);
18071 storage[storage_idx] = damage_applied;
18076 if (using_storage || using_constant) {
18077 Warning(
LOCATION,
"Cannot use +Stored Value: or +Constant: with +Load:, that would be bad. Skipping calculation.");
18079 storage_idx =
int(floorf(curr_arg));
18081 if ( (storage_idx < 0) || (storage_idx >= AT_NUM_STORAGE_LOCATIONS) ) {
18082 Warning(
LOCATION,
"+Value: for +Load: calculation out of range. Should be between 0 and %i. Read: %i, Skipping calculation.", AT_NUM_STORAGE_LOCATIONS, storage_idx);
18085 damage_applied = storage[storage_idx];
18090 if (damage_applied > curr_arg) {
18091 damage_applied =
frand_range( curr_arg, damage_applied );
18093 damage_applied =
frand_range( damage_applied, curr_arg );
18103 damage_applied *= diff_dmg_scale;
18105 return damage_applied;
18108 return (damage_applied * diff_dmg_scale);
18113 if(damage_type_idx < 0)
18121 num = DamageTypes.size();
18122 for(i = 0; i <
num; i++)
18124 if(DamageTypes[i].DamageTypeIndex == damage_type_idx)
18126 adtp = &DamageTypes[
i];
18131 return adtp->shieldpierce_pct;
18139 if(damage_type_idx < 0)
18147 num = DamageTypes.size();
18148 for(i = 0; i <
num; i++)
18150 if(DamageTypes[i].DamageTypeIndex == damage_type_idx)
18152 adtp = &DamageTypes[
i];
18157 return adtp->piercing_type;
18165 if(damage_type_idx < 0)
18173 num = DamageTypes.size();
18174 for(i = 0; i <
num; i++)
18176 if(DamageTypes[i].DamageTypeIndex == damage_type_idx)
18178 adtp = &DamageTypes[
i];
18183 return adtp->piercing_start_pct;
18207 int calc_type = -1;
18219 bool no_content =
true;
18230 if(calc_type == -1)
18232 Warning(
LOCATION,
"Armor '%s': Armor calculation type '%s' is invalid, and has been skipped", Name, buf);
18245 adt.Calculations.push_back(calc_type);
18254 adt.altArguments.push_back(temp_int);
18255 adt.Arguments.push_back(0.0
f);
18261 Error(
LOCATION,
"Invalid +Constant: name, '%s'. Using value 0.", buf);
18264 adt.altArguments.push_back(temp_int);
18265 adt.Arguments.push_back(0.0
f);
18270 adt.Arguments.push_back(temp_float);
18272 no_content =
false;
18276 adt.shieldpierce_pct = 0.0f;
18280 CLAMP(temp_float, 0.0
f, 1.0
f);
18281 adt.shieldpierce_pct = temp_float;
18282 no_content =
false;
18285 adt.piercing_start_pct = 0.1f;
18286 adt.piercing_type = -1;
18290 CLAMP(temp_float, 0.0
f, 100.0
f);
18291 temp_float /= 100.0f;
18292 adt.piercing_start_pct = temp_float;
18293 no_content =
false;
18299 no_content =
false;
18309 Error(
LOCATION,
"Invalid +Difficulty Scale Type: name: '%s'. Reverting to default behavior.", buf);
18312 adt.difficulty_scale_type = temp_int;
18314 no_content =
false;
18320 if(adt.Calculations.size() != adt.Arguments.size())
18323 Name, DamageTypes.size(), adt.Calculations.size(), adt.Arguments.size());
18325 DamageTypes.push_back(adt);
18335 num = Armor_types.size();
18336 for(i = 0; i <
num; i++)
18338 if(Armor_types[i].IsName(name))
18364 Armor_types.push_back(tat);
18389 mprintf((
"TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
18410 int i, j, num_strings;
18411 int n_entries = Ai_tp_list.size();
18414 bool first_time =
false;
18415 int already_exists = -1;
18417 if (n_entries == 0)
18424 if (first_time ==
false) {
18425 for (i = 0; i < n_entries; i++) {
18427 already_exists =
i;
18437 if ( !
stricmp(ai_tgt_objects[j].
name, tempname) ) {
18444 temp_strings.clear();
18447 for(i = 0; i < num_strings; i++) {
18454 if (j == MAX_WEAPON_TYPES) {
18455 Warning(
LOCATION,
"Unidentified weapon class '%s' set for target priority group '%s'\n", temp_strings[i].c_str(), temp_priority.
name);
18461 temp_strings.clear();
18464 for (i = 0; i < num_strings; i++) {
18466 if ( !
stricmp(ai_tgt_obj_flags[j].
name, temp_strings[i].c_str()) ) {
18471 if (j == num_ai_tgt_obj_flags) {
18472 Warning(
LOCATION,
"Unidentified object flag '%s' set for target priority group '%s'\n", temp_strings[i].c_str(), temp_priority.
name);
18478 temp_strings.clear();
18481 for (i = 0; i < num_strings; i++) {
18483 if ( !
stricmp(ai_tgt_ship_flags[j].
name, temp_strings[i].c_str()) ) {
18484 if (ai_tgt_ship_flags[j].var == 0) {
18492 if (j == num_ai_tgt_ship_flags) {
18493 Warning(
LOCATION,
"Unidentified ship class flag '%s' set for target priority group '%s'\n", temp_strings[i].c_str(), temp_priority.
name);
18499 temp_strings.clear();
18502 for (i = 0; i < num_strings; i++) {
18504 if ( !
stricmp(ai_tgt_weapon_flags[j].
name, temp_strings[i].c_str()) ) {
18505 if (ai_tgt_weapon_flags[j].var == 0) {
18506 temp_priority.
wif_flags |= ai_tgt_weapon_flags[j].
def;
18513 if (j == num_ai_tgt_weapon_flags) {
18514 Warning(
LOCATION,
"Unidentified weapon class flag '%s' set for target priority group '%s'\n", temp_strings[i].c_str(), temp_priority.
name);
18519 temp_strings.clear();
18521 if (already_exists == -1) {
18522 Ai_tp_list.push_back(temp_priority);
18524 Ai_tp_list[already_exists] = temp_priority;
18542 temp_priority.
name[0] =
'\0';
18545 return temp_priority;
18571 if (num_strings > 32)
18574 int num_groups = Ai_tp_list.size();
18576 for(i = 0; i < num_strings; i++) {
18577 for(j = 0; j < num_groups; j++) {
18578 if ( !
stricmp(Ai_tp_list[j].name, tgt_priorities[i].c_str())) {
18584 if(j == num_groups)
18585 Warning(
LOCATION,
"Unrecognized string '%s' found when setting weapon targeting priorities.\n", tgt_priorities[i].c_str());
18592 if(k == MAX_WEAPON_TYPES)
18593 Warning(
LOCATION,
"Unrecognized weapon '%s' found when setting weapon targeting priorities.\n", tempname);
18617 Assert(
id >= 0 &&
id < (
int)
Snds.size() );
18633 return (*element).second;
18639 Assert(
id >= 0 &&
id < (
int)
Snds.size() );
18727 if ( Rendering_to_shadow_map )
return;
18730 float render_amount;
18736 render_amount = 0.0f;
18773 render_amount = 0.0f;
18776 if ( render_amount > 0.0
f ) {
18800 if ( mtp->
tex_id >= 0 ) {
18801 float rad = mtp->
radius;
18820 fx_batcher.
draw_beam(&start, &end, rad, 1.0
f);
18822 int bmap_frame = mtp->
tex_id;
18878 for ( k = 0; k < bank->
num_slots; k++ ) {
18892 int num_secondaries_rendered = 0;
18893 vec3d secondary_weapon_pos;
18910 num_secondaries_rendered = 0;
18912 for ( k = 0; k < bank->
num_slots; k++ ) {
18913 secondary_weapon_pos = bank->
pnt[k];
18923 num_secondaries_rendered++;
18939 if ( Rendering_to_shadow_map ) {
18985 timer =
MAX(timer,0.0
f);
19008 ship *warp_shipp = NULL;
19009 bool is_first_stage_arrival =
false;
19029 is_first_stage_arrival =
false;
19033 if ( is_first_stage_arrival ) {
19047 if ( obj ==
Viewer_obj && !Rendering_to_shadow_map ) {
19099 if ( warp_shipp != NULL ) {
19118 if ( team_color_set ) {
19127 if ( Rendering_to_shadow_map ) {
19148 if ( fog_val >= 0.6
f ) {
19156 if (shipp->
shield_hits && !Rendering_to_shadow_map) {
void ct_ship_process(ship *shipp)
#define SF2_TOGGLE_SUBSYSTEM_SCANNING
void model_update_instance(int model_instance_num, int sub_model_num, submodel_instance_info *sii, int flags)
void mc_info_init(mc_info *mc)
#define BMP_FLAG_RENDER_TARGET_DYNAMIC
Texture is a dynamic type (animation)
const int Num_player_orders
void ship_wing_cleanup(int shipnum, wing *wingp)
const int Num_subsystem_flags
#define SSF_MISSILES_IGNORE_IF_DEAD
char fg_filename[MAX_FILENAME_LEN]
float debris_max_rotspeed
int num_swarm_missiles_to_fire
void parse_shiptype_tbl(const char *filename)
int model_collide(mc_info *mc_info_obj)
void armor_parse_table(const char *filename)
void radar_plot_object(object *objp)
int oo_interp_count[MAX_SHIPS]
#define MESSAGE_PRIORITY_NORMAL
void hud_set_wingman_status_none(int wing_index, int wing_pos)
#define REARM_REPAIR_ME_ITEM
bool model_anim_start_type(ship_subsys *pss, int animation_type, int subtype, int direction, bool instant)
char Starting_wing_names[MAX_STARTING_WINGS][NAME_LENGTH]
#define SHIP_GET_UNSILENCED
void ship_maybe_warn_player(ship *enemy_sp, float dist)
int shader_effect_duration
#define MESSAGE_TIME_IMMEDIATE
int thruster_tertiary_glow_bitmap
int timestamp(int delta_ms)
#define SIF2_SURFACE_SHIELDS
#define CYCLE_PRIMARY_PREV
#define MULTIPLAYER_CLIENT
int ship_info_lookup(const char *token)
void wing_bash_ship_name(char *ship_name, const char *wing_name, int index)
#define MY_NET_PLAYER_NUM
fix time_subsys_cargo_revealed
void parse_ship_sound(char *name, GameSoundsIndex id, ship_info *sip)
#define SUBSYSTEM_NAVIGATION
int thruster_secondary_glow_bitmap
void ship_obj_list_init()
void obj_set_flags(object *obj, uint new_flags)
#define STI_AI_TURRETS_ATTACK
thrust_pair_bitmap thruster_secondary_glow_info
float get_max_shield_quad(object *objp)
char wing_status_wing_pos
#define MSS_FLAG_NO_SS_TARGETING
#define STI_HUD_SHOW_ATTACK_DIRECTION
#define TRIGGER_TYPE_DOCKING_STAGE_2
SCP_vector< HudGauge * > hud_gauges
ubyte pre_death_explosion_happened
float minimum_convergence_distance
#define STI_SHIP_WARP_PUSHES
fix team_change_timestamp
geometry_batcher fx_batcher
int stuff_string_list(SCP_vector< SCP_string > &slp)
model_subsystem * system_info
weapon Weapons[MAX_WEAPONS]
int primary_bank_weapons[MAX_SHIP_PRIMARY_BANKS]
SCP_vector< ArmorType > Armor_types
#define STI_AI_PROTECTED_ON_CRIPPLE
#define SIF2_SHOW_SHIP_MODEL
void ship_init_thrusters()
void hud_gauge_popup_start(int gauge_index, int time)
Start a gauge to pop-up.
int last_primary_fire_sound_stamp[MAX_SHIP_PRIMARY_BANKS]
#define AIM_FLAG_AUTO_CONVERGENCE
Fully visible on the radar.
#define AIPF_NAVIGATION_SUBSYS_GOVERNS_WARP
tried to fire lasers when not enough energy left
#define AT_CONSTANT_BASE_DMG
#define MAX_SHIP_PRIMARY_BANKS
#define SIF2_NO_PAIN_FLASH
EModelAnimationPosition turret_animation_position
geometry_batcher man_batcher
SCP_string secondary_team_name
int previous_primary_bank
int Cmdline_old_collision_sys
void ship_assign_sound_all()
void model_find_world_point(vec3d *outpnt, vec3d *mpnt, int model_num, int submodel_num, const matrix *objorient, const vec3d *objpos)
#define NUM_SUB_EXPL_HANDLES
char * ship_subsys_get_name(ship_subsys *ss)
const int num_ai_tgt_ship_flags
#define MSS_FLAG_ALLOW_LANDING
int ship_obj_list_add(int objnum)
SCP_vector< man_thruster_renderer > Man_thrusters
float vm_vec_mag_quick(const vec3d *v)
int ship_engine_ok_to_warp(ship *sp)
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
matrix * vm_matrix_x_matrix(matrix *dest, const matrix *src0, const matrix *src1)
float max_overclocked_speed
#define INTIAL_WEAPON_RECHARGE_INDEX
void ship_init_afterburners(ship *shipp)
#define AT_TYPE_INSTANT_CUTOFF
thrust_pair_bitmap thruster_tertiary_glow_info
int thrusters_sounds[MAX_MAN_THRUSTERS]
bool draw_primary_models[MAX_SHIP_PRIMARY_BANKS]
#define SSF_FOV_EDGE_CHECK
void mission_log_add_entry(int type, char *pname, char *sname, int info_index)
np_update np_updates[MAX_PLAYERS]
int num_target_priorities
int Man_thruster_reset_timestamp
int check_for_string(const char *pstr)
#define INTIAL_SHIELD_RECHARGE_INDEX
#define PROTECT_TARGET_ITEM
float afterburner_trail_width_factor
int parse_string_flag_list(int *dest, flag_def_list defs[], int defs_size)
GLfloat GLfloat GLfloat GLfloat h
void ship_model_stop(object *objp)
shockwave_create_info shockwave
void vm_vec_scale_add(vec3d *dest, const vec3d *src1, const vec3d *src2, float k)
#define MISSION_FLAG_FULLNEB
const int Num_difficulty_scale_types
int ship_render_get_insignia(object *obj, ship *shipp)
#define ADT_DIFF_SCALE_FIRST
int bii_index_ship_with_cargo
#define SSF_AUTOREPAIR_IF_DISABLED
void ship_set_thruster_info(mst_info *mst, object *obj, ship *shipp, ship_info *sip)
float frand_range(float min, float max)
Return a floating point number in the range min..max.
#define AIM_FLAG_STD_CONVERGENCE
float debris_min_lifetime
SCP_vector< thruster_particles > normal_thruster_particles
void model_set_instance(int model_num, int sub_model_num, submodel_instance_info *sii, int flags=0)
#define MSS_FLAG2_TURRET_USE_AMMO
polymodel * model_get(int model_num)
ubyte bay_doors_launched_from
weapon_info Weapon_info[MAX_WEAPON_TYPES]
void render_path_points(object *objp)
int ship_find_num_crewpoints(object *objp)
float thruster_glow_noise
#define SF2_SHIP_SELECTIVE_LINKING
void ship_render_show_ship_cockpit(object *objp)
float shield_get_strength(object *objp)
int ai_find_goal_index(ai_goal *aigp, int mode, int submode=-1, int priority=-1)
float radar_projection_size_mult
void do_dying_undock_physics(object *dying_objp, ship *dying_shipp)
void RemHookVar(char *name)
SCP_vector< game_snd > Snds
#define SIF_IN_TECH_DATABASE_M
#define SIF2_SUBSYS_REPAIR_WHEN_DISABLED
char ship_name[NAME_LENGTH]
char default_player_ship[255]
void send_NEW_countermeasure_fired_packet(object *objp, int cmeasure_count, int rand_val)
#define SIF_DEFAULT_VALUE
void g3_stop_user_clip_plane()
float vm_vec_mag(const vec3d *v)
#define gr_end_view_matrix
generic_anim laser_bitmap
#define PLAYER_LOW_AMMO_MSG_INTERVAL
#define SF2_NO_DISABLED_SELF_DESTRUCT
submodel_instance_info submodel_info_1
#define FIREBALL_LARGE_EXPLOSION
void model_copy_subsystems(int n_subsystems, model_subsystem *d_sp, model_subsystem *s_sp)
#define SHIP_GET_NO_PLAYERS
float thruster_glow_noise
float warpout_player_speed
GLsizei const GLfloat * value
RadarVisibility radar_current_status
int last_primary_fire_stamp[MAX_SHIP_PRIMARY_BANKS]
#define SF2_NO_SUBSPACE_DRIVE
char icon_filename[MAX_FILENAME_LEN]
int required_string_one_of(int arg_count,...)
Checks for one of any of the given required strings.
#define REARM_NUM_MISSILES_PER_BATCH
#define MESSAGE_REPAIR_REQUEST
char wing_status_wing_index
float afterburner_forward_accel_time_const
#define CHECK_THEN_COPY(attribute)
#define AI_GOAL_CHASE_WING
#define SSF_PLAY_SOUND_FOR_PLAYER
void show_ship_subsys_count()
ushort multi_get_next_network_signature(int what_kind)
int weapon_create(vec3d *pos, matrix *orient, int weapon_type, int parent_obj, int group_id=-1, int is_locked=0, int is_spawned=0, float fof_cooldown=0.0f, ship_subsys *src_turret=NULL)
void set_thruster_info(mst_info &info)
missile threat indicator flashes
matrix * vm_angles_2_matrix(matrix *m, const angles *a)
void ship_model_change(int n, int ship_type)
#define AI_GOAL_WAYPOINTS
beam_info * beam_info_override
int get_quadrant(vec3d *hit_pnt, object *shipobjp)
ship_obj Ship_objs[MAX_SHIP_OBJS]
#define PLAYER_CHECK_WARN_INTERVAL
int turret_gun_rotation_snd
int piercing_type_get(char *str)
void ai_maybe_announce_shockwave_weapon(object *firing_objp, int weapon_index)
#define SF_AMMO_COUNT_RECORDED
#define SIF2_GENERATE_HUD_ICON
#define MSS_FLAG2_COLLIDE_SUBMODEL
ship_subsys fighter_beam_turret_data
SCP_vector< texture_replace > replacement_textures
int ship_explode_area_calc_damage(vec3d *pos1, vec3d *pos2, float inner_rad, float outer_rad, float max_damage, float max_blast, float *damage, float *blast)
bool ship_subsys_has_instance_name(ship_subsys *ss)
#define STI_MSG_COUNTS_FOR_ALONE
#define PLAYER_MAX_DIST_WARNING
#define MULTI_PRIMARY_CHANGED
GLsizei const GLfloat * points
void obj_snd_delete(int objnum, int index)
int turret_max_target_ownage
void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, int use_angles, vec3d *targetp)
int corkscrew_missile_bank
float ship_max_shield_strength
proximity warning (aspect)
thrust_pair thruster_glow_info
void shipfx_do_shockwave_stuff(ship *shipp, shockwave_create_info *sci)
int next_primary_fire_stamp[MAX_SHIP_PRIMARY_BANKS]
float thruster_glow_noise_mult
void shipfx_warpin_frame(object *objp, float frametime)
#define MSS_FLAG2_DESTROYED_ROTATION
int ship_iff_color[MAX_IFFS][MAX_IFFS]
void ship_add_exited_ship(ship *sp, int reason)
void stuff_malloc_string(char **dest, int type, char *terminators)
int allowed_bank_restricted_weapons[MAX_SHIP_WEAPONS][MAX_WEAPON_TYPES]
void ct_ship_create(ship *shipp)
int weapon_info_lookup(const char *name=NULL)
#define MULTI_STANDALONE(np)
ship_type_info * ship_get_type_info(object *objp)
float vm_vec_normalize_quick(vec3d *src)
#define MULTI_SECONDARY_CHANGED
int next_secondary_fire_stamp[MAX_SHIP_SECONDARY_BANKS]
#define PLAYER_MAX_LOW_AMMO_MSGS
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
int generic_anim_load(generic_anim *ga)
int get_available_primary_weapons(object *objp, int *outlist, int *outbanklist)
#define STI_AI_AUTO_ATTACKS
SCP_vector< vec3d > shield_points
#define MAX_MODEL_TEXTURES
void _cdecl void void _cdecl void _cdecl void _cdecl WarningEx(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
engine_wash_info * get_engine_wash_pointer(char *engine_wash_name)
thrust_pair_bitmap thruster_distortion_info
int detail[MAX_MODEL_DETAIL_LEVELS]
void send_secondary_fired_packet(ship *shipp, ushort starting_sig, int starting_count, int num_fired, int allow_swarm)
float detail_depth[MAX_MODEL_DETAIL_LEVELS]
#define MESSAGE_PRIMARIES_LOW
submodel_instance_info submodel_info_2
void generic_bitmap_init(generic_bitmap *gb, const char *filename)
void dock_dead_undock_objects(object *objp1, object *objp2)
RadarVisibility radar_is_visible(object *objp)
Return if the specified object is visible on the radar.
#define MISSION_FLAG_SUPPORT_REPAIRS_HULL
#define TRIGGER_TYPE_DOCKING_STAGE_1
#define PLAYER_REQUEST_REPAIR_MSG_INTERVAL
void stuff_boolean_flag(int *i, int flag, bool a_to_eol)
SCP_vector< triggered_rotation > Triggered_rotations
int Player_weapon_precedence[MAX_WEAPON_TYPES]
#define NETINFO_FLAG_OBSERVER
char sub_name[NAME_LENGTH]
int ship_fire_primary(object *obj, int stream_weapons, int force)
#define SSF_NO_LIVE_DEBRIS
#define MSS_FLAG_DAMAGE_AS_HULL
#define SF_ARRIVING_STAGE_2
float side_slip_time_const
int weapon_recharge_index
flag_def_list ai_tgt_objects[]
void ship_subsys_set_disrupted(ship_subsys *ss, int time)
#define list_append(head, elem)
vec3d turret_big_attack_point
#define MSS_FLAG_TRIGGERED
int subsystem_stricmp(const char *str1, const char *str2)
float player_autoaim_fov[NUM_SKILL_LEVELS]
void ship_destroy_instantly(object *ship_objp, int shipnum)
int ship_stop_fire_primary(object *obj)
#define MSS_FLAG_NO_AGGREGATE
unsigned int mp_shots_fired
int stuff_float_optional(float *f, bool raw)
#define SAF_IGNORE_SS_ARMOR
void ship_render_set_animated_effect(model_render_params *render_info, ship *shipp, uint *render_flags)
#define STAY_NEAR_TARGET_ITEM
char wing_squad_filename[MAX_FILENAME_LEN]
void obj_snd_delete_type(int objnum, int sndnum, ship_subsys *ss)
void send_cargo_hidden_packet(ship *shipp)
int turret_next_enemy_check_stamp
#define LOG_WING_DEPARTED
void send_subsystem_cargo_revealed_packet(ship *shipp, int index)
float untargeted_flak_range_penalty
int bm_get_info(int handle, int *w, int *h, ubyte *flags, int *nframes, int *fps)
Gets info on the bitmap indexed by handle.
char name[MAX_FILENAME_LEN]
int subsys_guardian_threshold
const int Num_armor_calculation_types
void set_flags(uint flags)
#define AT_TYPE_INSTANT_CAP
int get_nearest_bbox_point(object *ship_objp, vec3d *start, vec3d *box_pt)
const char * Ai_goal_text(int goal)
int secondary_bank_start_ammo[MAX_SHIP_SECONDARY_BANKS]
struct vec3d::@225::@227 xyz
flag_def_list ai_tgt_ship_flags[]
int generic_bitmap_load(generic_bitmap *gb)
int afterburner_trail_faded_out_sections
#define TMAP_HTL_3D_UNLIT
#define SIF2_DYN_PRIMARY_LINKING
ship_subsys * target_subsys
void model_render_immediate(model_render_params *render_info, int model_num, matrix *orient, vec3d *pos, int render, bool sort)
#define STAY_NEAR_ME_ITEM
#define STI_HUD_HOTKEY_ON_LIST
void model_collide_preprocess(matrix *orient, int model_instance_num, int detail=0)
int distance_warning_count
#define SF2_DONT_COLLIDE_INVIS
float tertiary_glow_rad_factor
#define LOG_SHIP_DEPARTED
char pof_file_hud[MAX_FILENAME_LEN]
vec3d * vm_vec_avg_n(vec3d *dest, int n, const vec3d src[])
#define MSS_FLAG_NO_REPLACE
#define MSS_FLAG_TURRET_ANIM_WAIT
const char * defaults_get_file(const char *filename)
void polish_predicted_target_pos(weapon_info *wip, object *targetp, vec3d *enemy_pos, vec3d *predicted_enemy_pos, float dist_to_enemy, vec3d *last_delta_vec, int num_polish_steps)
stepped_rotation_t * stepped_rotation
int ship_subsystem_in_sight(object *objp, ship_subsys *subsys, vec3d *eye_pos, vec3d *subsys_pos, int do_facing_check, float *dot_out, vec3d *vec_out)
int * Player_cockpit_textures
void ship_obj_list_reset_slot(int index)
int subsys_disrupted_check_timestamp
#define CAPTURE_TARGET_ITEM
#define NUM_SHIP_SUBSYSTEM_SETS
#define WIF2_EXTERNAL_WEAPON_LNCH
void ship_do_cargo_revealed(ship *shipp, int from_network)
#define NUM_TURRET_ORDER_TYPES
int ship_has_homing_missile_locked(ship *shipp)
#define SF2_FRIENDLY_STEALTH_INVIS
#define STI_WEAP_BEAMS_EASILY_HIT
void send_NEW_primary_fired_packet(ship *shipp, int banks_fired)
ai_info Ai_info[MAX_AI_INFO]
int Num_ship_subobj_types
float afterburner_fuel_capacity
vec3d * vm_vec_rotate(vec3d *dest, const vec3d *src, const matrix *m)
void ship_process_pre(object *objp, float frametime)
#define Assertion(expr, msg,...)
void hud_set_wingman_status_departed(int wing_index, int wing_pos)
#define END_OF_LIST(head)
void model_add_arc(int model_num, int sub_model_num, vec3d *v1, vec3d *v2, int arc_type)
EModelAnimationPosition bay_doors_status
#define STI_AI_GUARDS_ATTACK
#define AI_GOAL_DISARM_SHIP
model_subsystem * subsystems
void awacs_maybe_ask_for_help(ship *sp, int multi_team_filter)
void init_ai_object(int objnum)
bool Rendering_to_shadow_map
void set_detail_level_lock(int detail_level_lock)
virtual int warpShipRender()
ship_subsys * targeted_subsys
#define MR_DEPRECATED_ATTACHED_MODEL
float ship_get_secondary_weapon_range(ship *shipp)
angles Viewer_slew_angles
float ship_quadrant_shield_strength(object *hit_objp, vec3d *hitpos)
int ship_is_tagged(object *objp)
int ship_find_exited_ship_by_name(char *name)
float piercing_damage_draw_limit
#define NUM_SUBSYSTEM_FLAGS
#define KAMIKAZE_HULL_ON_DEATH
int wing_insignia_texture
#define SHIP_MIN_ENGINES_TO_WARP
void set_insignia_bitmap(int bitmap)
void vm_vec_scale_add2(vec3d *dest, const vec3d *src, float k)
void ship_process_post(object *obj, float frametime)
void update_ets(object *objp, float fl_frametime)
#define SIF2_INTRINSIC_NO_SHIELDS
GLenum GLuint GLenum GLsizei const GLchar * message
float afterburner_reverse_accel
void ship_do_cap_subsys_cargo_revealed(ship *shipp, ship_subsys *subsys, int from_network)
#define FIREBALL_EXPLOSION_LARGE1
void ship_make_create_time_unique(ship *shipp)
void ship_obj_list_rebuild()
#define AIPF2_ADVANCED_TURRET_FOV_EDGE_CHECKS
int restricted_loadout_flag[MAX_SHIP_WEAPONS]
int ship_fire_secondary(object *obj, int allow_swarm)
#define AIPF2_PERFORM_FEWER_SCREAM_CHECKS
int turret_next_fire_stamp
int primary_bank_weapons[MAX_SHIP_PRIMARY_BANKS]
#define STI_HUD_TARGET_AS_THREAT
#define WIF_HOMING_ASPECT
void ai_clear_ship_goals(ai_info *aip)
int g3_draw_line(vertex *p0, vertex *p1)
virtual int warpShipClip()
#define MAX_SHIPS_PER_WING
flag_def_list Dock_type_names[]
std::basic_string< char, std::char_traits< char >, std::allocator< char > > SCP_string
char ship_name[NAME_LENGTH]
#define AIPF_USE_ADDITIVE_WEAPON_VELOCITY
float debris_max_hitpoints
float primary_rotate_rate[MAX_SHIP_PRIMARY_BANKS]
#define PLAYER_MAX_DIST_END
int ship_navigation_ok_to_warp(ship *sp)
int primary_bank_capacity[MAX_SHIP_PRIMARY_BANKS]
#define PLAYER_FLAGS_FORCE_MISSION_OVER
int red_alert_mission(void)
#define ADT_DIFF_SCALE_LAST
GLenum GLenum GLenum GLenum GLenum scale
void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
GLfloat GLfloat GLfloat v2
int current_secondary_bank
float ai_endangered_by_weapon(ai_info *aip)
int dock_find_dead_dockpoint_used_by_object(object *objp, object *other_objp)
#define AT_TYPE_EXPONENTIAL
#define MAX_SUBSYS_ATTACKERS
void ai_object_init(object *obj, int ai_index)
int difficulty_scale_type_get(char *str)
void HUD_sourced_printf(int source, const char *format,...)
SCP_vector< ship_counts > Ship_type_counts
int tracers[MAX_SHIPS][4][4]
float Noise[NOISE_NUM_FRAMES]
int required_string_either(char *str1, char *str2)
Checks for one of two required strings.
#define MAX_SQUADRON_WINGS
int detail_distance[MAX_SHIP_DETAIL_LEVELS]
int get_default_player_ship_index()
Returns the index of the default player ship.
int turret_base_rotation_snd
int special_warpin_objnum
int auto_shield_spread_from_lod
int Default_ship_select_effect
#define MAX_FIREBALL_TYPES
Missle tracking to acquire a lock (looped)
GLenum GLuint GLenum GLsizei const GLchar * buf
char pof_name[MAX_FILENAME_LEN]
ship_subsys_info subsys_info[SUBSYSTEM_MAX]
void ship_apply_whack(vec3d *force, vec3d *hit_pos, object *objp)
#define DEFAULT_SHIP_PRIMITIVE_SENSOR_RANGE
int armor_type_constants_get(char *str)
void parse_weapon_bank(ship_info *sip, bool is_primary, int *num_banks, int *bank_default_weapons, int *bank_capacities)
char tech_title[NAME_LENGTH]
#define SUBSYSTEM_GAS_COLLECT
flag_def_list Subsystem_flags[]
int bm_release(int handle, int clear_render_targets)
Frees both a bitmap's data and it's associated slot.
vec3d turret_firing_point[MAX_TFP]
void ship_find_warping_ship_helper(object *objp, dock_function_info *infop)
#define TRIGGER_TYPE_DOCKING_STAGE_3
void obj_remove_collider(int obj_index)
float gun_submodel_rotation
float vm_vec_mag_squared(const vec3d *v)
void particle_emit(particle_emitter *pe, int type, int optional_data, float range)
int maybe_detonate_weapon(ship_weapon *swp, object *src)
thruster_bank * thrusters
int calculation_type_get(char *str)
void ship_set_eye(object *obj, int eye_index)
script_state Script_system("FS2_Open Scripting")
#define gr_end_proj_matrix
float TypeDefaultValues[]
float base_rotation_rate_pct
ship_subsys * last_fired_turret
float turret_base_rotation_snd_mult
void ship_get_eye(vec3d *eye_pos, matrix *eye_orient, object *obj, bool do_slew, bool from_origin)
flag_def_list ai_tgt_weapon_flags[]
void do_sub_expl_sound(float radius, vec3d *sound_pos, int *sound_handle)
std::deque< bool > glow_point_bank_active
int parse_ship(const char *filename, bool replace)
void shipfx_do_damaged_arcs_frame(ship *shipp)
void ship_set(int ship_index, int objnum, int ship_type)
void stuff_float(float *f)
float thruster03_glow_rad_factor
int primary_banks[MAX_SHIP_PRIMARY_BANKS]
#define SHIP_GET_ONLY_PLAYERS
char * ship_return_time_to_goal(char *outbuf, ship *sp)
int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *keyframe, int can_drop_frames, int dir_type)
Loads a bitmap sequance so we can draw with it.
#define COLLISION_ROTATION_FACTOR
int obj_snd_assign(int objnum, int sndnum, vec3d *pos, int main, int flags, ship_subsys *associated_sub)
#define WIF2_CAPITAL_PLUS
void send_cargo_revealed_packet(ship *shipp)
#define CLAMP(x, min, max)
int Load(char *filename=NULL, int specified_lods=MAX_WEAPON_EXPL_LOD)
float forward_decel_time_const
int lightningtype_match(char *p)
void init_path_metadata(path_metadata &metadata)
void ship_actually_depart(int shipnum, int method)
int turret_max_bomb_ownage
int hud_get_dock_time(object *docker_objp)
Get the number of seconds until repair ship will dock with ther player.
#define INTIAL_ENGINE_RECHARGE_INDEX
void backspace(char *src)
#define SIF2_DEFAULT_IN_TECH_DATABASE
#define MSS_FLAG_TURRET_LOCKED
int beam_fire_targeting(fighter_beam_fire_info *fire_info)
float GetShieldPiercePCT(int damage_type_idx)
#define SUBSYSTEM_COMMUNICATION
reinforcements Reinforcements[MAX_REINFORCEMENTS]
void g3_done_instance(bool set_api=false)
void gr_set_color(int r, int g, int b)
int get_available_secondary_weapons(object *objp, int *outlist, int *outbanklist)
SCP_vector< waypoint > & get_waypoints()
int ship_secondary_bank_has_ammo(int shipnum)
SCP_vector< cockpit_display > Player_displays
int ship_type_name_lookup(const char *name)
ubyte num_corkscrew_to_fire
void ship_render_cockpit(object *objp)
#define STI_HUD_NO_CLASS_DISPLAY
#define OF_TARGETABLE_AS_BOMB
int Squadron_wings[MAX_SQUADRON_WINGS]
#define COLLISION_FRICTION_FACTOR
void ship_maybe_praise_player(ship *deader_sp)
void ship_set_default_player_ship()
#define MESSAGE_PLAYER_DIED
#define DISARM_TARGET_ITEM
int turret_pick_big_attack_point_timestamp
int object_is_docked(object *objp)
int ship_stop_fire_primary_bank(object *obj, int bank_to_stop)
#define gr_set_view_matrix
char alt_dmg_sub_name[NAME_LENGTH]
#define IGNORE_TARGET_ITEM
unsigned int ms_shots_fired
thrust_pair_bitmap thruster_tertiary_glow_info
int low_ammo_complaint_count
void ship_check_player_distance_sub(player *p, int multi_target=-1)
#define CHA_ONWPDESELECTED
thrust_info thruster_info
void model_render_queue(model_render_params *interp, draw_list *scene, int model_num, matrix *orient, vec3d *pos)
bool use_special_explosion
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
#define MAX_SHIP_SECONDARY_BANKS
EModelAnimationPosition secondary_animation_position[MAX_SHIP_SECONDARY_BANKS]
void ship_do_weapon_thruster_frame(weapon *weaponp, object *objp, float frametime)
void obj_add_pairs(int objnum)
SCP_vector< glow_point_bank_override > glowpoint_bank_overrides
missle start load (during rearm/repair)
void turret_swarm_maybe_fire_missile(int shipnum)
void lethality_decay(ai_info *aip)
#define FIREBALL_MEDIUM_EXPLOSION
#define WT_DEFAULT_THEN_KNOSSOS
void model_interp_set_team_color(const SCP_string &team, const SCP_string &secondaryteam, fix timestamp, int fadetime)
#define ATTACK_TARGET_ITEM
void shipfx_large_blowup_queue_render(draw_list *scene, ship *shipp)
matrix * vm_vector_2_matrix(matrix *m, const vec3d *fvec, const vec3d *uvec, const vec3d *rvec)
int previous_secondary_bank
float ship_get_subsystem_strength(ship *shipp, int type)
void ship_actually_depart_helper(object *objp, dock_function_info *infop)
const int Num_armor_flags
p_object * mission_parse_get_arrival_ship(const char *name)
Returns the parse object on the ship arrival list associated with the given name. ...
void find_submodel_instance_point_orient(vec3d *outpnt, matrix *outorient, int model_instance_num, int submodel_num, const vec3d *submodel_pnt, const matrix *submodel_orient)
void parse_sound(const char *tag, int *idx_dest, const char *object_name, parse_sound_flags flags)
void weapon_set_tracking_info(int weapon_objnum, int parent_objnum, int target_objnum, int target_is_locked=0, ship_subsys *target_subsys=NULL)
void vm_vec_add2(vec3d *dest, const vec3d *src)
#define GR_ALPHABLEND_FILTER
#define MSS_FLAG_TURRET_FIXED_FP
char pof_file[MAX_FILENAME_LEN]
int shader_effect_start_time
WarpEffect * warpout_effect
#define SIF2_ALLOW_LANDINGS
#define gr_set_proj_matrix
ubyte arc_type[MAX_SHIP_ARCS]
void joy_ff_play_primary_shoot(int gain)
void flak_muzzle_flash(vec3d *pos, vec3d *dir, physics_info *pip, int turret_weapon_class)
#define SIF2_NO_THRUSTER_GEO_NOISE
void model_delete_instance(int model_instance_num)
ship_subsys * ship_get_indexed_subsys(ship *sp, int index, vec3d *attacker_pos)
void obj_add_collider(int obj_index)
GLdouble GLdouble GLdouble r
void ship_set_subsystem_strength(ship *shipp, int type, float strength)
ship_spark sparks[MAX_SHIP_HITS]
void ship_check_player_distance()
void ship_maybe_tell_about_low_ammo(ship *sp)
object * dock_get_first_dead_docked_object(object *objp)
#define AT_CONSTANT_RANDOM
int ship_class_query_general_type(int ship_class)
missle load (during rearm/repair)
void queued_animation_init(queued_animation *qa)
#define STI_WEAP_NO_HUGE_IMPACT_EFF
#define MSS_FLAG2_NO_AUTOREPAIR_IF_DISABLED
SCP_vector< alt_class > s_alt_classes
void afterburners_update(object *objp, float fl_frametime)
struct matrix::@228::@230 vec
bool auto_shield_spread_bypass
#define ANIMATION_SUBTYPE_ALL
#define NETINFO_FLAG_AM_MASTER
void model_anim_set_initial_states(ship *shipp)
float neb2_get_fog_intensity(object *obj)
void model_anim_fix_reverse_times(ship_info *sip)
#define LOG_WING_DESTROYED
int bii_index_wing_with_cargo
void observer_process_post(object *objp)
#define ENGAGE_ENEMY_ITEM
int GetPiercingType(int damage_type_idx)
void swarm_maybe_fire_missile(int shipnum)
float ship_max_hull_strength
#define AT_CONSTANT_NOT_USED
#define AIPF2_REQUIRE_TURRET_TO_HAVE_TARGET_IN_FOV
void vm_vec_scale(vec3d *dest, float s)
#define AWACS_HELP_HULL_LOW
void ship_start_targeting_laser(ship *shipp)
int timestamp_until(int stamp)
float afterburner_forward_accel
void ship_end_render_cockpit_display(int cockpit_display_num)
float thruster_dist_rad_factor
#define TMAP_FLAG_GOURAUD
int g3_draw_sphere(vertex *pnt, float rad)
#define SIF2_GUN_CONVERGENCE
float afterburner_reverse_accel
SCP_vector< ship_info > Ship_templates
int parse_ship_values(ship_info *sip, const bool is_template, const bool first_time, const bool replace)
int ship_in_my_squadron(ship *shipp)
void ship_render_batch_thrusters(object *obj)
void cmeasure_set_ship_launch_vel(object *objp, object *parent_objp, int arand)
#define MSS_FLAG_TURRET_RESET_IDLE
int primary_bank_ammo[MAX_SHIP_PRIMARY_BANKS]
ai_goal_list Ai_goal_names[]
int primary_out_of_ammo(ship_weapon *swp, int bank)
void parse_ship_particle_effect(ship_info *sip, particle_effect *pe, char *id_string)
SCP_vector< briefing_icon_info > Briefing_icon_info
#define SW_FLAG_TURRET_LOCK
#define SHIP_DEPARTED_BAY
int * ship_replacement_textures
#define AIPF_DISABLE_LINKED_FIRE_PENALTY
SCP_vector< int > ai_cripple_ignores
GLboolean GLboolean GLboolean GLboolean a
int secondary_bank_capacity[MAX_SHIP_SECONDARY_BANKS]
int pre_launch_snd_min_interval
int fireball_ship_explosion_type(ship_info *sip)
#define SF2_NO_DEATH_SCREAM
#define OS_TURRET_BASE_ROTATION
int cf_exists_full(const char *filename, int dir_type)
ai_target_priority init_ai_target_priorities()
int obj_create(ubyte type, int parent_obj, int instance, matrix *orient, vec3d *pos, float radius, uint flags)
int shipfx_large_blowup_do_frame(ship *shipp, float frametime)
#define TRIGGER_TYPE_DOCKED
int armor_type_get_idx(char *name)
int get_max_ammo_count_for_bank(int ship_class, int bank, int ammo_type)
int ship_subsys_disrupted(ship_subsys *ss)
#define SADTF_PIERCING_DEFAULT
ai_profile_t * ai_profile
#define MSS_FLAG2_AUTOREPAIR_IF_DISABLED
float get_hull_pct(object *objp)
void model_clear_instance(int model_num)
char name[MAX_FILENAME_LEN]
struct engine_wash_info * engine_wash_pointer
float slide_decel_time_const
int ship_get_index_from_subsys(ship_subsys *ssp, int objnum, int error_bypass)
#define strnicmp(s1, s2, n)
#define SIF2_DRAW_WEAPON_MODELS
void joy_ff_play_reload_effect()
#define AIM_FLAG_AUTOAIM_CONVERGENCE
int bay_doors_anim_done_time
int ship_get_sound(object *objp, GameSoundsIndex id)
Returns a ship-specific sound index.
float target_shields_delta
char Squadron_wing_names[MAX_SQUADRON_WINGS][NAME_LENGTH]
#define WF_WING_DEPARTING
void obj_remove_pairs(object *a)
float max_hull_repair_val
#define MAX_STARTING_WINGS
int ship_iff_info[MAX_IFFS][MAX_IFFS]
ship_info & operator=(ship_info &&other) NOEXCEPT
ai_goal goals[MAX_AI_GOALS]
int snd_play_3d(game_snd *gs, vec3d *source_pos, vec3d *listen_pos, float radius, vec3d *source_vel, int looping, float vol_scale, int priority, vec3d *sound_fvec, float range_factor, int force, bool is_ambient)
void ship_stop_targeting_laser(ship *shipp)
int allow_praise_timestamp
texture_map maps[MAX_MODEL_TEXTURES]
heat-seeker launch warning
thrust_pair_bitmap thruster_secondary_glow_info
int subsys_disrupted_flags
#define SF2_HIDE_SHIP_NAME
void ship_maybe_ask_for_help(ship *sp)
void ship_auto_repair_frame(int shipnum, float frametime)
generic_anim thruster_glow
void stuff_string(char *outstr, int type, int len, char *terminators)
int ship_get_SIF(ship *shipp)
#define MULTI_SIG_NON_PERMANENT
#define MESSAGE_REARM_REQUEST
int FindTexture(int bm_handle)
#define SSF_DAMAGE_AS_HULL
int secondary_banks[MAX_SHIP_SECONDARY_BANKS]
#define SIF_SHIP_CLASS_DONT_COLLIDE_INVIS
int praise_delay_timestamp
void render_dock_bays(object *objp)
int bitmask_2_bitnum(int num)
void ship_render_weapon_models(model_render_params *ship_render_info, draw_list *scene, object *obj, int render_flags)
void engine_wash_ship_process(ship *shipp)
int ship_get_random_player_wing_ship(int flags, float max_dist, int persona_index, int get_first, int multi_team)
int primary_animation_done_time[MAX_SHIP_PRIMARY_BANKS]
void vm_orthogonalize_matrix(matrix *m_src)
void game_shudder_apply(int, float)
void ship_subsys_set_name(ship_subsys *ss, char *n_name)
#define MAX_MODEL_SUBSYSTEMS
float ai_ship_fire_delay_scale_friendly
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
void vm_set_identity(matrix *m)
ship_subsys ship_subsys_free_list
void set_team_color(team_color &clr)
#define WIF3_APPLY_RECOIL
float damage_ship[MAX_DAMAGE_SLOTS]
#define AT_TYPE_EXPONENTIAL_BASE
trail_info ab_info[MAX_SHIP_CONTRAILS]
flag_def_list Player_orders[]
SCP_string default_team_name
void batch_render_man_thrusters()
int object_is_dead_docked(object *objp)
void ship_assign_sound(ship *sp)
int next_tertiary_fire_stamp
char name[MAX_FILENAME_LEN]
void shipfx_warpout_frame(object *objp, float frametime)
int num_turret_swarm_info
#define SF_HIDDEN_FROM_SENSORS
#define SSSF_TURRET_ROTATION
#define REARM_NUM_BALLISTIC_PRIMARIES_PER_BATCH
generic_bitmap afterburner_trail
void ship_delete(object *obj)
float favor_current_facing
int sub_expl_sound_handle[NUM_SUB_EXPL_HANDLES]
void event_music_hostile_ship_destroyed()
#define AT_CONSTANT_CURRENT_DMG
#define MULTI_OBSERVER(np)
int iff_lookup(char *iff_name)
float debris_max_lifetime
#define DEFAULT_DELTA_BANK_CONST
int special_exp_deathroll_time
trail * ABtrail_ptr[MAX_SHIP_CONTRAILS]
float distortion_length_factor
float weapon_submodel_rotate_accell
#define SSF_CARGO_REVEALED
#define NETINFO_FLAG_INGAME_JOIN
ubyte g3_rotate_vertex(vertex *dest, const vec3d *src)
void physics_init(physics_info *pi)
void emp_process_ship(ship *shipp)
#define HUD_SOURCE_HIDDEN
EModelAnimationPosition primary_animation_position[MAX_SHIP_PRIMARY_BANKS]
float reorient_max_rot_angle
model_subsystem beam_sys_info
vec3d norm[MAX_DOCK_SLOTS]
void add_allocate(int quad, int n_tri=0)
void engine_wash_info_init(engine_wash_info *ewi)
#define SEF_RED_ALERT_CARRY
int required_string(const char *pstr)
float primary_rotate_ang[MAX_SHIP_PRIMARY_BANKS]
queued_animation * triggers
int secondary_bank_capacity[MAX_SHIP_SECONDARY_BANKS]
int snd_play(game_snd *gs, float pan, float vol_scale, int priority, bool is_voice_msg)
int ship_primary_bank_has_ammo(int shipnum)
int engine_recharge_index
#define SF_PRIMARY_LINKED
float max_shield_strength
void ai_ship_destroy(int shipnum, int method)
fix game_get_overall_frametime()
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
void hud_start_flash_weapon(int index)
void parse_allowed_weapons(ship_info *sip, const bool is_primary, const bool is_dogfight, const bool first_time)
int arc_timestamp[MAX_SHIP_ARCS]
void model_anim_handle_multiplayer(ship *shipp)
int get_max_ammo_count_for_primary_bank(int ship_class, int bank, int ammo_type)
int model_anim_get_time_type(ship_subsys *pss, int animation_type, int subtype)
char * get_pointer_to_first_hash_symbol(char *src)
float thruster_glow_frame
#define SIF2_DEFAULT_VALUE
int ship_show_velocity_dot
ship_subsys * ship_return_next_subsys(ship *shipp, int type, vec3d *attacker_pos)
float vm_vec_normalized_dir(vec3d *dest, const vec3d *end, const vec3d *start)
void model_set_fog_level(float l)
int bay_doors_wanting_open
float vm_vec_dist(const vec3d *v0, const vec3d *v1)
#define DISABLE_TARGET_ITEM
void ship_primary_changed(ship *sp)
int optional_string(const char *pstr)
void send_ship_weapon_change(ship *shipp, int what, int new_bank, int link_status)
#define LOG_CAP_SUBSYS_CARGO_REVEALED
float aggregate_current_hits
void ship_maybe_scream(ship *sp)
float fireball_lifeleft(object *obj)
const int num_ai_tgt_objects
int collision_damage_type_idx
void ship_subsystems_delete(ship *shipp)
#define SIF2_DEFAULT_IN_TECH_DATABASE_M
bool dc_optional_string_either(const char *str1, const char *str2)
Searches for an optional string and it's alias.
#define MONITOR(function_name)
void player_maybe_start_repair_sound()
#define DEFAULT_SHIELD_SECTIONS
void model_do_intrinsic_rotations(int model_instance_num=-1)
int turret_targeting_order[NUM_TURRET_ORDER_TYPES]
#define SADTF_PIERCING_RETAIL
proximity warning (heat seeker)
bool scripting_target_override
#define ASK_HELP_HULL_PERCENT
int large_ship_blowup_index
int secondary_bank_ammo_capacity[MAX_SHIP_SECONDARY_BANKS]
set 1/3 or 2/3 throttle (up)
particle_effect regular_end_particles
void ship_cleanup(int shipnum, int cleanup_mode)
#define SIF_BALLISTIC_PRIMARIES
int model_load(char *filename, int n_subsystems, model_subsystem *subsystems, int ferror=1, int duplicate=0)
int ship_get_random_ship_in_wing(int wingnum, int flags, float max_dist, int get_first)
void fs2netd_add_table_validation(const char *tblname)
void hud_targetbox_truncate_subsys_name(char *outstr)
char filename[MAX_FILENAME_LEN]
int ship_maybe_play_secondary_fail_sound(weapon_info *wip)
void read_file_text(const char *filename, int mode, char *processed_text, char *raw_text)
void SetHookObject(char *name, object *objp)
#define STI_SHIP_SCANNABLE
#define AI_GOAL_EVADE_SHIP
int really_final_death_time
#define PLAYER_FLAGS_DIST_TO_BE_KILLED
float max_subsys_strength
int skip_to_start_of_string_either(char *pstr1, char *pstr2, char *end)
#define ADT_DIFF_SCALE_BAD_VAL
__inline void gr_bitmap_ex(int x, int y, int w, int h, int sx, int sy, int resize_mode=GR_RESIZE_FULL)
#define MSS_FLAG_TURRET_ALT_MATH
ship_subsys * ship_get_best_subsys_to_attack(ship *sp, int subsys_type, vec3d *attacker_pos)
bool bm_set_render_target(int handle, int face)
(GR function) Calls gr_bm_set_render target for the given bitmap indexed by handle ...
SCP_vector< vec3d > shield_points
char bg_filename[MAX_FILENAME_LEN]
const int Num_armor_type_constants
SCP_vector< texture_replace > replacement_textures
int beam_fire(beam_fire_info *fire_info)
void model_page_in_textures(int modelnum, int ship_info_index=-1)
tried to fire a missle when none are left
#define MAX_NONDARK_COLORS
float sup_subsys_repair_rate
bool Parsing_modular_table
#define SIF_DEFAULT_PLAYER_SHIP
#define SIF2_AUTO_SPREAD_SHIELDS
void flak_set_range(object *objp, float range)
int turret_num_firing_points
CJumpNode * jumpnode_get_which_in(object *objp)
#define AIF_AWAITING_REPAIR
trail_info ct_info[MAX_SHIP_CONTRAILS]
void model_set_insignia_bitmap(int bmap)
int secondary_bank_ammo[MAX_SHIP_SECONDARY_BANKS]
beam_info * beam_info_override
void ship_set_new_ai_class(int ship_num, int new_ai_class)
int primary_bank_ammo_capacity[MAX_SHIP_PRIMARY_BANKS]
#define SIF_IN_TECH_DATABASE
#define MSS_FLAG_CARRY_NO_DAMAGE
#define SUBSYSTEM_WEAPONS
char cockpit_pof_file[MAX_FILENAME_LEN]
void ship_recalc_subsys_strength(ship *shipp)
#define MSS_FLAG_FIRE_ON_TARGET
builtin_message Builtin_messages[]
trail * trail_ptr[MAX_SHIP_CONTRAILS]
#define WIF2_EXTERNAL_WEAPON_FP
vec3d * vm_vec_unrotate(vec3d *dest, const vec3d *src, const matrix *m)
int Num_engine_wash_types
float turret_gun_rotation_snd_mult
void parse_shiptbl(const char *filename)
void ship_subsys_disrupted_check(ship *sp)
float vm_vec_dist_squared(const vec3d *v0, const vec3d *v1)
void ship_apply_global_damage(object *ship_objp, object *other_obj, vec3d *force_center, float damage)
SCP_vector< thruster_particles > afterburner_thruster_particles
int ship_query_state(char *name)
#define MESSAGE_PRAISE_SELF
int num_targeting_priorities
#define PLAYER_DISTANCE_MAX_WARNINGS
int iff_x_attacks_y(int team_x, int team_y)
#define AI_GOAL_FLY_TO_SHIP
int get_subsystem_pos(vec3d *pos, object *objp, ship_subsys *subsysp)
int num_target_priorities
int ship_select_next_primary(object *objp, int direction)
man_thruster_renderer * man_thruster_get_slot(int bmap_frame)
int primary_bank_capacity[MAX_SHIP_PRIMARY_BANKS]
void ship_subsys_disrupted_maybe_check(ship *shipp)
int damage_ship_id[MAX_DAMAGE_SLOTS]
flag_def_list ai_tgt_obj_flags[]
int snd_get_duration(int snd_id)
const size_t INVALID_WAYPOINT_POSITION
int shield_impact_explosion_anim
#define MSS_FLAG2_TURRET_ONLY_TARGET_IF_CAN_FIRE
int was_firing_last_frame[MAX_SHIP_PRIMARY_BANKS]
set 1/3 or 2/3 throttle (down)
object Objects[MAX_OBJECTS]
for(int idx=0;idx< i;idx++)
char alt_sub_name[NAME_LENGTH]
int turret_max_bomb_ownage
float sup_hull_repair_rate
void submodel_get_two_random_points(int model_num, int submodel_num, vec3d *v1, vec3d *v2, vec3d *n1=NULL, vec3d *n2=NULL)
#define MSS_FLAG2_SHARE_FIRE_DIRECTION
#define MR_SHOW_THRUSTERS
#define MONITOR_INC(function_name, inc)
void ets_init_ship(object *obj)
int radar_color_image_2d_idx
int Countermeasures_enabled
void ship_copy_subsystem_fixup(ship_info *sip)
void shield_add_strength(object *objp, float delta)
void stuff_vec3d(vec3d *vp)
vec3d afterburner_max_vel
vec3d targeting_laser_offset
Destroyed by a beam (vaporized)
int parse_and_add_briefing_icon_info()
#define SF_ARRIVING_STAGE_1
SCP_vector< SCP_string > ai_actively_pursues_temp
#define AIM_FLAG_CONVERGENCE_OFFSET
int ship_create(matrix *orient, vec3d *pos, int ship_type, char *ship_name)
float primary_bank_fof_cooldown[MAX_SHIP_PRIMARY_BANKS]
const char * XSTR(const char *str, int index)
void set_replacement_textures(int *textures)
void read_file_text_from_array(const char *array, char *processed_text, char *raw_text)
#define AI_GOAL_WAYPOINTS_ONCE
#define WF_DEPARTURE_ORDERED
char warpin_anim[MAX_FILENAME_LEN]
int shield_armor_type_idx
SCP_map< SCP_string, path_metadata > pathMetadata
const int num_ai_tgt_obj_flags
void ship_maybe_praise_self(ship *deader_sp, ship *killer_sp)
int ship_query_general_type(int ship)
void parse_ship_sounds(ship_info *sip)
int damage_ship_id[MAX_DAMAGE_SLOTS]
void stuff_boolean(int *i, bool a_to_eol)
RadarVisibility radar_last_status
int ship_find_repair_ship(object *requester_obj, object **ship_we_found)
#define SIF2_NO_PRIMARY_LINKING
int ship_guardian_threshold
#define AT_NUM_STORAGE_LOCATIONS
int last_secondary_fire_stamp[MAX_SHIP_SECONDARY_BANKS]
#define SND_PRIORITY_MUST_PLAY
int warptype_match(char *p)
vec3d targeting_laser_offset
#define FIREBALL_NUM_LARGE_EXPLOSIONS
bool end_string_at_first_hash_symbol(char *src)
void ship_render_DEPRECATED(object *obj)
int do_facing_check(const vec3d *norm, vertex **vertlist, const vec3d *p)
SCP_unordered_map< int, void * > glowpoint_bank_override_map
int TVT_wings[MAX_TVT_WINGS]
ship_subsys * target_subsys
void vm_vec_copy_scale(vec3d *dest, const vec3d *src, float s)
#define SADTF_PIERCING_NONE
float target_weapon_energy_delta
#define MR_DEPRECATED_ANIMATED_SHADER
void _cdecl void void _cdecl Error(const char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
#define GM_STANDALONE_SERVER
float thruster01_glow_rad_factor
int targeting_laser_objnum
#define TMAP_FLAG_CORRECT
int rearm_first_ballistic_primary
flag_def_list PiercingTypes[]
#define AI_GOAL_GUARD_WING
int special_warpout_objnum
void dc_stuff_float(float *f)
Stuffs a float to the given variable.
void create_shield_explosion_all(object *objp)
void vm_vec_rand_vec_quick(vec3d *rvec)
int collision_damage_type_idx
int ship_check_collision_fast(object *obj, object *other_obj, vec3d *hitpos)
int shield_point_augment_ctrls[4]
#define WIF3_NO_LINKED_PENALTY
bool newtonian_damp_override
void allocate(int quad, int n_tri=0)
#define WIF2_PIERCE_SHIELDS
#define SF2_NO_BUILTIN_MESSAGES
int wing_name_lookup(const char *name, int ignore_count)
int turret_animation_done_time
typedef void(APIENTRY *PFNGLARRAYELEMENTEXTPROC)(GLint i)
int Starting_wings[MAX_STARTING_WINGS]
#define MSS_FLAG2_PLAYER_TURRET_SOUND
void reset_parse(char *text)
#define AIF_BEING_REPAIRED
#define MSS_FLAG2_NO_DISAPPEAR
char warpout_anim[MAX_FILENAME_LEN]
void hud_anim_init(hud_anim *ha, int sx, int sy, const char *filename)
Initialise the members of the hud_anim struct to default values.
void ship_radar_process(object *obj, ship *shipp, ship_info *sip)
GLuint const GLchar * name
int RunCondition(int condition, char format='\0', void *data=NULL, class object *objp=NULL, int more_data=0)
void joy_ff_play_secondary_shoot(int gain)
int secondary_bank_rearm_time[MAX_SHIP_SECONDARY_BANKS]
void process_subobjects(int objnum)
vec3d turret_last_fire_direction
float death_roll_time_mult
#define AT_TYPE_INSTANT_REVERSE_CUTOFF
void SetHookObjects(int num,...)
man_thruster maneuvering[MAX_MAN_THRUSTERS]
#define CYCLE_PRIMARY_NEXT
float thruster02_glow_len_factor
void ship_clear_ship_type_counts()
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
#define SF_RED_ALERT_STORE_STATUS
float gun_rotation_rate_pct
#define vm_realloc(ptr, size)
p_object * Arriving_support_ship
float total_damage_received
#define MISSION_TYPE_TRAINING
#define SF2_PRIMARIES_LOCKED
int ship_fire_secondary_detonate(object *obj, ship_weapon *swp)
ship_flag_name Ship_flag_names[]
void dc_stuff_string_white(char *out_str, size_t maxlen)
Stuffs a whitespace delimited string to out_str from the command line, stopping at the end of the com...
SCP_vector< SCP_string > ai_cripple_ignores_temp
#define AWACS_HELP_HULL_HI
int bm_load(const char *real_filename)
Loads a bitmap so we can draw with it later.
#define MSS_FLAG_TURRET_HULL_CHECK
thrust_pair thruster_flame_info
SCP_vector< cockpit_display_info > displays
int iff_init_color(int r, int g, int b)
int ship_info_lookup_sub(const char *token)
int weapon_rotation_pbank
int allow_scream_timestamp
#define SSF_NO_AUTOREPAIR_IF_DISABLED
int stuff_int_list(int *ilp, int max_ints, int lookup_type)
__inline void gr_fog_set(int fog_mode, int r, int g, int b, float fog_near=-1.0f, float fog_far=-1.0f)
float turret_turning_rate
void send_ship_depart_packet(object *objp, int method)
#define MESSAGE_PRIORITY_HIGH
float turret_time_enemy_in_range
#define STI_AI_CAN_FORM_WING
vec3d get_submodel_offset(int model, int submodel)
#define SHIP_MIN_NAV_TO_WARP
SCP_vector< ship_effect > Ship_effects
#define MR_DEPRECATED_NO_TEXTURING
void shipfx_do_lightning_frame(ship *shipp)
int ship_get_by_signature(int signature)
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
#define SIF2_DISABLE_WEAPON_DAMAGE_SCALING
#define WING_INDEX(wingp)
char alt_name[NAME_LENGTH]
void shockwave_create_info_init(shockwave_create_info *sci)
int ship_select_next_valid_secondary_bank(ship_weapon *swp)
#define MAX_REPLACEMENT_TEXTURES
int damage_lightning_type
#define MR_DEPRECATED_NORMAL
int allow_ask_help_timestamp
void hud_shield_assign_info(ship_info *sip, char *filename)
#define DCF_BOOL(function_name, bool_variable)
int ship_get_subobj_model_num(ship_info *sip, char *subobj_name)
int primitive_sensor_range
int ship_launch_countermeasure(object *objp, int rand_val)
fix base_texture_anim_frametime
void ship_model_start(object *objp)
int ship_dumbfire_threat(ship *sp)
#define BFIF_IS_FIGHTER_BEAM
void CAP(T &v, T mn, T mx)
int secondary_next_slot[MAX_SHIP_SECONDARY_BANKS]
int ship_find_num_turrets(object *objp)
int turret_max_target_ownage
float vm_vec_delta_ang(const vec3d *v0, const vec3d *v1, const vec3d *fvec)
float favor_current_facing
float vm_vec_dist_quick(const vec3d *v0, const vec3d *v1)
char anim_filename[MAX_FILENAME_LEN]
#define MSS_FLAG_UNTARGETABLE
char old_texture[MAX_FILENAME_LEN]
void model_render_DEPRECATED(int model_num, matrix *orient, vec3d *pos, uint flags=MR_DEPRECATED_NORMAL, int objnum=-1, int lighting_skip=-1, int *replacement_textures=NULL, int render=MODEL_RENDER_ALL, const bool is_skybox=false)
int ship_get_exp_propagates(ship *sp)
float frand()
Return random value in range 0.0..1.0- (1.0- means the closest number less than 1.0)
#define SF_SECONDARY_DUAL_FIRE
char splodeing_texture_name[MAX_FILENAME_LEN]
#define AI_GOAL_DISABLE_SHIP
int ship_docking_valid(int docker, int dockee)
int request_repair_timestamp
bool shipfx_in_shadow(object *src_obj)
float ai_ship_fire_delay_scale_hostile
int Cmdline_freespace_no_sound
#define STI_TURRET_TGT_SHIP_TGT
int ship_weapon_maybe_fail(ship *sp)
void submodel_get_two_random_points_better(int model_num, int submodel_num, vec3d *v1, vec3d *v2)
void ship_render(object *obj, draw_list *scene)
void ship_init_cockpit_displays(ship *shipp)
#define KEEP_SAFE_DIST_ITEM
#define SUBSYSTEM_SENSORS
int ship_template_lookup(const char *token)
#define MULTI_CONNECTED(np)
#define SUBSYSTEM_UNKNOWN
#define AIPF_USE_NEWTONIAN_DAMPENING
char short_name[NAME_LENGTH]
void ship_scream(ship *sp)
#define MESSAGE_REARM_PRIMARIES
int distance_warning_time
p_object * mission_parse_get_parse_object(ushort net_signature)
void shipfx_flash_light_model(object *objp, int model_num)
void message_send_builtin_to_player(int type, ship *shipp, int priority, int timing, int group, int delay, int multi_target, int multi_team_filter)
#define AT_CONSTANT_DIFF_FACTOR
#define MESSAGE_STRAY_WARNING
int last_fired_point[MAX_SHIP_PRIMARY_BANKS]
int external_model_fp_counter[MAX_SHIP_PRIMARY_BANKS+MAX_SHIP_SECONDARY_BANKS]
void ship_do_thruster_frame(ship *shipp, object *objp, float frametime)
struct dock_function_info::@258 parameter_variables
#define HUD_WEAPONS_GAUGE
struct dock_function_info::@258 maintained_variables
void ship_maybe_tell_about_rearm(ship *sp)
#define STI_MSG_PRAISE_DESTRUCTION
void generic_anim_init(generic_anim *ga)
float forward_accel_time_const
float weapon_model_draw_distance
int ship_do_rearm_frame(object *objp, float frametime)
void model_set_instance_info(submodel_instance_info *sii, float turn_rate, float turn_accel)
ship_subsys * ship_get_closest_subsys_in_sight(ship *sp, int subsys_type, vec3d *attacker_pos)
void ai_deathroll_start(object *ship_obj)
void ship_chase_shield_energy_targets(ship *shipp, object *obj, float frametime)
void ship_dying_frame(object *objp, int ship_num)
#define SF2_GLOWMAPS_DISABLED
void shipfx_blow_up_model(object *obj, int model, int submodel, int ndebris, vec3d *exp_center)
void hud_set_wingman_status_dead(int wing_index, int wing_pos)
ubyte nondark_colors[MAX_NONDARK_COLORS][3]
ship_subsys * targeted_subsys
void ship_obj_list_remove(int index)
char subobj_name[MAX_NAME_LEN]
float max_weapon_regen_per_second
afterburner fail (no fuel when aburn pressed)
int ship_return_subsys_path_normal(ship *shipp, ship_subsys *ss, vec3d *gsubpos, vec3d *norm)
void ship_do_cargo_hidden(ship *shipp, int from_network)
float vm_vec_copy_normalize(vec3d *dest, const vec3d *src)
void clone(const ship_info &other)
float model_get_radius(int modelnum)
void physics_apply_whack(vec3d *impulse, vec3d *pos, physics_info *pi, matrix *orient, float mass)
bool shader_effect_active
float thruster_glow_frame
void dock_evaluate_all_docked_objects(object *objp, dock_function_info *infop, void(*function)(object *, dock_function_info *))
void RemHookVars(unsigned int num,...)
void ship_secondary_changed(ship *sp)
float slide_accel_time_const
#define MULTIPLAYER_MASTER
#define MAX_REINFORCEMENTS
void queued_animation_correct(queued_animation *qa)
An overhauled/updated debug console to allow monitoring, testing, and general debugging of new featur...
texture_info textures[TM_NUM_TYPES]
SCP_vector< ship_info > Ship_info
void ship_clear_cockpit_displays()
#define MSS_FLAG_TURRET_SALVO
void ship_add_cockpit_display(cockpit_display_info *display, int cockpit_model_num)
#define SIF_KNOSSOS_DEVICE
int secondary_animation_done_time[MAX_SHIP_SECONDARY_BANKS]
#define ASK_HELP_SHIELD_PERCENT
vec3d * vm_vec_avg(vec3d *dest, const vec3d *src0, const vec3d *src1)
vec3d afterburner_max_vel
ship_subsys * last_targeted_subobject[MAX_PLAYERS]
int bay_doors_parent_shipnum
int MessageBox(HWND h, const char *s1, const char *s2, int i)
#define SF2_AFTERBURNER_LOCKED
float afterburner_max_reverse_vel
void g3_start_instance_matrix(const vec3d *pos, const matrix *orient, bool set_api=true)
int num_turrets_attacking(object *turret_parent, int target_objnum)
#define TMAP_FLAG_TEXTURED
particle_effect damage_spew
#define NUM_SHIP_SUBSYSTEMS_PER_SET
char TVT_wing_names[MAX_TVT_WINGS][NAME_LENGTH]
void gamesnd_play_error_beep()
int model_anim_match_type(char *p)
#define MSS_FLAG_FOV_EDGE_CHECK
#define CHA_SECONDARYFIRE
int static_rand(int num)
Return a pseudo random 32 bit value given a reasonably small number.
void model_set_thrust(int model_num=-1, mst_info *mst=NULL)
#define MESSAGE_WINGMAN_SCREAM
#define timestamp_elapsed(stamp)
SCP_vector< DamageTypeStruct > Damage_types
float debris_min_hitpoints
SCP_vector< float > shield_quadrant
SCP_vector< species_info > Species_info
float GetPiercingLimit(int damage_type_idx)
void draw_beam(vec3d *start, vec3d *end, float width, float intensity=1.0f, float offset=0.0f)
DCF(t_rad,"Sets weapon tracer radius")
#define LOG_CARGO_REVEALED
#define MAX_MAN_THRUSTERS
#define OF_SHOULD_BE_DEAD
SCP_vector< exited_ship > Ships_exited
vec3d * get_subsystem_world_pos(object *parent_obj, ship_subsys *subsys, vec3d *world_pos)
float afterburner_max_reverse_vel
void model_interp_set_animated_effect_and_timer(int effect_num=0, float effect_timer=0.0f)
int ship_get_default_orders_accepted(ship_info *sip)
int ship_is_getting_locked(ship *shipp)
void ship_add_ship_type_kill_count(int ship_info_index)
#define STI_SHIP_WARP_PUSHABLE
#define PLAYER_FLAGS_DIST_WARNING
char * maneuverability_str
#define list_remove(head, elem)
void error_display(int error_level, char *format,...)
void parse_weapon_targeting_priorities()
int secondary_glow_bitmap
#define SIF2_MODEL_POINT_SHIELDS
void ship_draw_shield(object *objp)
#define SF2_ALWAYS_DEATH_SCREAM
GLsizei GLsizei GLuint * obj
float ship_recoil_modifier
float thruster_dist_len_factor
#define SWARM_DEFAULT_NUM_MISSILES_FIRED
int debris_damage_type_idx
void parse_engine_wash(bool replace)
ship_obj * get_ship_obj_ptr_from_index(int index)
#define SND_PRIORITY_TRIPLE_INSTANCE
void change_ship_type(int n, int ship_type, int by_sexp)
void ship_process_targeting_lasers()
float vm_vec_dot(const vec3d *v0, const vec3d *v1)
void ai_process(object *obj, int ai_index, float frametime)
void shield_set_strength(object *objp, float strength)
#define ETS_RECHARGE_RATE
void ship_add_ship_type_count(int ship_info_index, int num)
#define STI_AI_ACCEPT_PLAYER_ORDERS
const int Num_piercing_effect_types
void asteroid_hit(object *pasteroid_obj, object *other_obj, vec3d *hitpos, float damage)
void vm_vec_scale_sub2(vec3d *dest, const vec3d *src, float k)
particle_effect knossos_end_particles
void model_clear_submodel_instances(int model_instance_num)
char * ship_return_orders(char *outbuf, ship *sp)
bool draw_secondary_models[MAX_SHIP_SECONDARY_BANKS]
#define MAX_SHIP_CONTRAILS
int parse_modular_table(const char *name_check, void(*parse_callback)(const char *filename), int path_type, int sort_type)
SCP_vector< int > ai_actively_pursues
#define timestamp_rand(a, b)
void ai_free_slot(int ai_index)
Frees a currently used AI slot.
void gr_bitmap(int _x, int _y, int resize_mode)
flag_def_list DifficultyScaleTypes[]
#define GR_BITBLT_MODE_NORMAL
#define MSS_FLAG_ALLOW_VANISHING
int ai_get_slot(int shipnum)
Returns index of free AI slot.
#define MSS_FLAG_IGNORE_IF_DEAD
float shockwave_shake_amp
float secondary_glow_rad_factor
#define AT_TYPE_REVERSE_CUTOFF
SCP_vector< int > weapon_class
eye view_positions[MAX_EYES]
int ammo_low_complaint_count
SCP_vector< int > ship_type
weapon_explosions Weapon_explosions
flag_def_list ArmorTypeConstants[]
matrix world_to_turret_matrix
void player_stop_repair_sound()
void set_animated_effect(int effect_num, float timer)
#define SUBSYSTEM_ACTIVATION
void flak_pick_range(object *objp, vec3d *firing_pos, vec3d *predicted_target_pos, float weapon_subsys_strength)
int triggered_rotation_index
float damage_ship[MAX_DAMAGE_SLOTS]
void shipfx_large_blowup_level_init()
int thruster_glow_anim_load(generic_anim *ga)
#define SF_CARGO_REVEALED
#define WIF_HOMING_JAVELIN
#define AI_GOAL_REARM_REPAIR
#define MSS_FLAG_FOV_REQUIRED
vec3d arc_pts[MAX_SHIP_ARCS][2]
char filename[MAX_FILENAME_LEN]
bool ship_has_sound(object *objp, GameSoundsIndex id)
Specifies if a ship has a custom sound for the specified id.
void dc_printf(const char *format,...)
Prints the given char string to the debug console.
#define PF_AFTERBURNER_ON
void stuff_ubyte(ubyte *i)
void render(int flags, float radius=0.0f)
int ship_index[MAX_SHIPS_PER_WING]
SCP_vector< int > explosion_bitmap_anims
ship_collision_physics collision_physics
#define P2_OF_FORCE_SHIELDS_ON
bool is_minimum_GLSL_version()
void model_clear_instance_info(submodel_instance_info *sii)
void find_and_stuff_optional(char *id, int *addr, int f_type, char *strlist[], int max, char *description)
WarpEffect * warpin_effect
void shipfx_large_blowup_render(ship *shipp)
int primary_bank_rearm_time[MAX_SHIP_PRIMARY_BANKS]
int ship_get_subsys_index(ship *sp, char *ss_name, int error_bypass)
int stuff_bool_list(bool *blp, int max_bools)
#define MR_DEPRECATED_NO_LIGHTING
int thruster_distortion_bitmap
void ship_set_warp_effects(object *objp, ship_info *sip)
SCP_map< SCP_string, team_color > Team_Colors
#define OS_TURRET_GUN_ROTATION
int iff_matches_mask(int team, int mask)
char filename[MAX_FILENAME_LEN]
#define SF2_PRIMITIVE_SENSORS
SCP_vector< int > explosion_bitmap_anims
void light_set_shadow(int state)
int primary_bank_start_ammo[MAX_SHIP_PRIMARY_BANKS]
int subsys_set(int objnum, int ignore_subsys_info)
int bm_unload(int handle, int clear_render_targets, bool nodebug)
Unloads a bitmap's data, but not the bitmap info.
char filename[MAX_FILENAME_LEN]
int turret_swarm_info_index[MAX_TFP]
char targeting_laser_bank
int parse_ship_template()
void cscrew_maybe_fire_missile(int shipnum)
int shield_armor_type_idx
void shipfx_flash_create(object *objp, int model_num, vec3d *gun_pos, vec3d *gun_dir, int is_primary, int weapon_info_index)
float afterburner_trail_life
#define DISABLE_SUBSYSTEM_ITEM
int ship_name_lookup(const char *name, int inc_players)
void ship_model_update_instance(object *objp)
void ship_do_cap_subsys_cargo_hidden(ship *shipp, ship_subsys *subsys, int from_network)
#define FIREBALL_EXPLOSION_MEDIUM
#define OS_SUBSYS_ROTATION
#define SHIP_MULTITEXT_LENGTH
void ship_fire_tracer(int weapon_objnum)
#define ABORT_REARM_REPAIR_ITEM
int ship_get_random_team_ship(int team_mask, int flags, float max_dist)
#define TRIGGER_TYPE_PRIMARY_BANK
int last_fired_weapon_signature
#define SF_SHIP_HAS_SCREAMED
particle * particle_create(particle_info *pinfo)
int current_tertiary_bank
int ship_find_exited_ship_by_signature(int signature)
void set_predicted_enemy_pos(vec3d *predicted_enemy_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, ai_info *aip)
int model_create_instance(bool is_ship, int model_num)
#define PLAYER_DEATH_DELTA_TIME
#define TRIGGER_TYPE_SECONDARY_BANK
missile_obj Missile_obj_list
#define MSS_FLAG_CARRY_SHOCKWAVE
int ship_select_next_secondary(object *objp)
#define SHIP_REPAIR_SUBSYSTEM_RATE
#define AI_GOAL_DESTROY_SUBSYSTEM
void ct_ship_delete(ship *shipp)
int bm_make_render_target(int width, int height, int flags)
Creates a render target as close to the desired resolution as possible.
void set_object_number(int num)
int ship_lock_threat(ship *sp)
int stuff_float_list(float *flp, int max_floats)
flag_def_list Armor_flags[]
void find_submodel_instance_world_point(vec3d *outpnt, int model_instance_num, int submodel_num, const matrix *objorient, const vec3d *objpos)
void compute_slew_matrix(matrix *orient, angles *a)
#define MSS_FLAG_USE_MULTIPLE_GUNS
void parse_ai_target_priorities()
support_ship_info support_ships
float distortion_rad_factor
void diag_printf(char *format,...)
int ship_start_render_cockpit_display(int cockpit_display_num)
SCP_vector< int > objsnd_num
void ship_set_hud_cockpit_targets()
int oo_arrive_time_count[MAX_SHIPS]
#define STI_AI_ATTEMPT_BROADSIDE
char overhead_filename[MAX_FILENAME_LEN]
#define SF_FROM_PLAYER_WING
float afterburner_recover_rate
float landing_max_rot_angle
int multi_find_player_by_object(object *objp)
char filename[FILESPEC_LENGTH]
#define SF2_SECONDARIES_LOCKED
#define MSS_FLAG_TURRET_MATRIX
void ship_parse_post_cleanup()
#define PLAYER_MAX_WARN_DIST
net_player Net_players[MAX_PLAYERS]
float max_shield_recharge
#define AT_TYPE_MULTIPLICATIVE
int targeting_priorities[32]
int timer_get_milliseconds()
SCP_vector< ai_target_priority > Ai_tp_list
void gameseq_post_event(int event)
#define CHECK_THEN_FREE(attribute)
#define SUBSYS_WEAPONS_STR_FIRE_OK
float max_shield_recharge
vec3d pnt[MAX_DOCK_SLOTS]
void ship_blow_up_area_apply_blast(object *exp_objp)
int shield_recharge_index
particle_effect impact_spew
int burst_counter[MAX_SHIP_PRIMARY_BANKS+MAX_SHIP_SECONDARY_BANKS]
float ship_calculate_rearm_duration(object *objp)
void vm_vec_add(vec3d *dest, const vec3d *src0, const vec3d *src1)
int weapon_create_group_id()
SCP_vector< glow_point_bank_override >::iterator get_glowpoint_bank_override_by_name(const char *name)
void ship_reset_disabled_physics(object *objp, int ship_class)
int primary_bank_slot_count[MAX_SHIP_PRIMARY_BANKS]
matrix vmd_identity_matrix
flag_def_list Man_types[]
void weapon_detonate(object *objp)
#define timestamp_valid(stamp)
const int num_ai_tgt_weapon_flags
#define AI_GOAL_FORM_ON_WING
float max_subsys_repair_val
SCP_vector< engine_wash_info > Engine_wash_info
int wing_lookup(const char *name)
float weapon_submodel_rotate_vel
int praise_self_timestamp
int damage_type_add(char *name)
char ship_name[NAME_LENGTH]
int allowed_weapons[MAX_WEAPON_TYPES]
#define MR_DEPRECATED_SHOW_THRUSTERS
#define PLAYER_WARN_DELTA_TIME
int special_exp_shockwave_speed
void push_transform(vec3d *pos, matrix *orient)
float afterburner_burn_rate
bool model_get_team_color(team_color *clr, const SCP_string &team, const SCP_string &secondaryteam, fix timestamp, int fadetime)
#define SF2_NO_SECONDARY_LOCKON
generic_anim thruster_flame
thrust_pair_bitmap thruster_distortion_info
int last_fired_weapon_index
int Num_player_weapon_precedence
void physics_ship_init(object *objp)
#define SUBSYS_WEAPONS_STR_FIRE_FAIL
float GetDamage(float damage_applied, int in_damage_type_idx, float diff_dmg_scale)
float thruster02_glow_rad_factor
SCP_vector< ship_type_info > Ship_types
void model_set_detail_level(int n)
#define TRIGGER_TYPE_INITIAL
void hud_save_restore_camera_data(int save)
Called to save and restore the 3D camera settings.
float sup_shield_repair_rate
#define LOG_SELF_DESTRUCTED
float convergence_distance
int debris_damage_type_idx
int Default_cmeasure_index
int thrusters_start[MAX_MAN_THRUSTERS]
void shipfx_large_blowup_init(ship *shipp)
int last_fired_weapon_info_index
Missle lock (non-looping)
engine sound (as heard in cockpit)
#define SSF_NO_SS_TARGETING
int ship_fire_primary_debug(object *objp)
SCP_map< GameSoundsIndex, int > ship_sounds
#define ADT_DIFF_SCALE_MANUAL
void model_unload(int modelnum, int force=0)
particle_effect split_particles
float secondary_point_reload_pct[MAX_SHIP_SECONDARY_BANKS][MAX_SLOTS]
void send_subsystem_cargo_hidden_packet(ship *shipp, int index)
char sub_name[NAME_LENGTH]
float afterburner_trail_alpha_factor
int current_target_is_locked
float auto_shield_spread_min_span
int project_point_onto_bbox(const vec3d *mins, const vec3d *maxs, const vec3d *start, vec3d *box_pt)
char new_texture[MAX_FILENAME_LEN]
Not visible on the radar.
#define MESSAGE_TIME_SOON
float max_shield_regen_per_second
afterburner burn sound (looped)
#define MSS_FLAG_FIRE_ON_NORMAL
#define AT_CONSTANT_BAD_VAL
#define MESSAGE_STRAY_WARNING_FINAL
#define MSS_FLAG_NO_LIVE_DEBRIS
float vm_vec_normalize(vec3d *v)
int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_obj, float size, int reverse, vec3d *velocity, float warp_lifetime, int ship_class, matrix *orient_override, int low_res, int extra_flags, int warp_open_sound, int warp_close_sound)
void ship_set_default_weapons(ship *shipp, ship_info *sip)
flag_def_list Ship_flags[]
void ship_maybe_play_primary_fail_sound()
int ship_get_type(char *output, ship_info *sip)
generic_anim thruster_bitmap
#define MAX_SHIP_DETAIL_LEVELS
float debris_min_rotspeed
#define MSS_FLAG_CREWPOINT
void shipfx_emit_spark(int n, int sn)
SCP_vector< int > ship_class