1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 #ifndef _SHIP_H
13 #define _SHIP_H
14 
15 
16 
17 #include "ai/ai.h"
18 #include "fireball/fireballs.h"
19 #include "globalincs/globals.h"		// for defintions of token lengths -- maybe move this elsewhere later (Goober5000 - moved to globals.h)
20 #include "globalincs/pstypes.h"
21 #include "graphics/2d.h"			// for color def
22 #include "hud/hud.h"
23 #include "hud/hudparse.h"
24 #include "model/model.h"
25 #include "model/modelanim.h"
26 #include "model/modelanimation.h"
27 #include "network/multi_obj.h"
28 #include "radar/radarsetup.h"
29 #include "render/3d.h"
30 #include "species_defs/species_defs.h"
31 #include "weapon/shockwave.h"
32 #include "weapon/trails.h"
33 #include "ship/ship_flags.h"
34 #include "weapon/weapon_flags.h"
35 #include "ai/ai.h"
36 
37 #include <string>
38 #include <particle/ParticleManager.h>
39 
40 class object;
41 class WarpEffect;
42 
43 //	Part of the player died system.
44 extern vec3d	Original_vec_to_deader;
45 
46 //	States for player death sequence, stuffed in Player_died_state.
47 #define	PDS_NONE		1
48 #define	PDS_DIED		2
49 #define	PDS_EJECTED	3
50 
51 #define SHIP_GUARDIAN_THRESHOLD_DEFAULT	1	// Goober5000
52 
53 #define	HULL_DAMAGE_THRESHOLD_PERCENT	0.25f	//	Apply damage to hull, not shield if shield < this
54 
55 // the #defines below are to avoid round-off errors
56 #define WEAPON_RESERVE_THRESHOLD		0.01f	// energy threshold where ship is considered to have no weapon energy system
57 #define SUBSYS_MAX_HITS_THRESHOLD		0.01f	// max_hits threshold where subsys is considered to take damage
58 
59 #define	HP_SCALE						1.2			//	1.2 means die when 20% of hits remaining
60 #define	MAX_SHIP_HITS				8				// hits to kill a ship
61 #define	MAX_SHIP_DETAIL_LEVELS	5				// maximum detail levels that a ship can render at
62 #define	MAX_REINFORCEMENTS		32
63 
64 
65 // defines for 'direction' parameter of ship_select_next_primary()
66 #define CYCLE_PRIMARY_NEXT		0
67 #define CYCLE_PRIMARY_PREV		1
68 
69 #define BANK_1		0
70 #define BANK_2		1
71 #define BANK_3		2
72 #define BANK_4		3
73 #define BANK_5		4
74 #define BANK_6		5
75 #define BANK_7		6
76 #define BANK_8		7
77 #define BANK_9		8
78 
79 #define TYPE_ATTACK_PROTECT	0
80 #define TYPE_REPAIR_REARM		1
81 
82 #define MAX_REINFORCEMENT_MESSAGES	5
83 
84 #define RF_IS_AVAILABLE			(1<<0)			// reinforcement is now available
85 
86 typedef struct {
87 	char	name[NAME_LENGTH];	// ship or wing name (ship and wing names don't collide)
88 	int	type;						// what operations this reinforcement unit can perform
89 	int	uses;						// number of times reinforcemnt unit can be used
90 	int	num_uses;				// number of times this reinforcement was actually used
91 	int	arrival_delay;			// how long after called does this reinforcement appear
92 	int	flags;
93 	char	no_messages[MAX_REINFORCEMENT_MESSAGES][NAME_LENGTH];		// list of messages to possibly send when calling for reinforcement not available
94 	char	yes_messages[MAX_REINFORCEMENT_MESSAGES][NAME_LENGTH];	// list of messages to acknowledge reinforcement on the way
95 } reinforcements;
96 
97 class ship_weapon {
98 public:
99 	int num_primary_banks;					// Number of primary banks (same as model)
100 	int num_secondary_banks;				// Number of secondary banks (same as model)
101 	int num_tertiary_banks;
102 
103 	int primary_bank_weapons[MAX_SHIP_PRIMARY_BANKS];			// Weapon_info[] index for the weapon in the bank
104 	int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS];		// Weapon_info[] index for the weapon in the bank
105 
106 	int primary_bank_external_model_instance[MAX_SHIP_PRIMARY_BANKS];
107 	bool primary_bank_model_instance_check[MAX_SHIP_PRIMARY_BANKS];
108 
109 	int current_primary_bank;			// currently selected primary bank
110 	int current_secondary_bank;		// currently selected secondary bank
111 	int current_tertiary_bank;
112 
113 	int previous_primary_bank;
114 	int previous_secondary_bank;		// currently selected secondary bank
115 
116 	int next_primary_fire_stamp[MAX_SHIP_PRIMARY_BANKS];			// next time this primary bank can fire
117 	int last_primary_fire_stamp[MAX_SHIP_PRIMARY_BANKS];			// last time this primary bank fired (mostly used by SEXPs)
118 	int next_secondary_fire_stamp[MAX_SHIP_SECONDARY_BANKS];		// next time this secondary bank can fire
119 	int last_secondary_fire_stamp[MAX_SHIP_SECONDARY_BANKS];		// last time this secondary bank fired (mostly used by SEXPs)
120 	int next_tertiary_fire_stamp;
121 	int last_primary_fire_sound_stamp[MAX_SHIP_PRIMARY_BANKS];		// trailing end of the last time this primary bank was fired, for purposes of timing the pre-launch sound
122 
123 	// ballistic primary support - by Goober5000
124 	int primary_bank_ammo[MAX_SHIP_PRIMARY_BANKS];			// Number of missiles left in primary bank
125 	int primary_bank_start_ammo[MAX_SHIP_PRIMARY_BANKS];	// Number of missiles starting in primary bank
126 	int primary_bank_capacity[MAX_SHIP_PRIMARY_BANKS];		// Max number of projectiles in bank
127 	int primary_next_slot[MAX_SHIP_PRIMARY_BANKS];			// Next slot to fire in the bank
128 	int primary_bank_rearm_time[MAX_SHIP_PRIMARY_BANKS];	// timestamp which indicates when bank can get new projectile
129 	// end ballistic primary support
130 
131 	float primary_bank_fof_cooldown[MAX_SHIP_PRIMARY_BANKS];      // SUSHI: Current FOF cooldown level for the primary weapon
132 
133 	// dynamic weapon linking - by RSAXVC
134 	int primary_bank_slot_count[MAX_SHIP_PRIMARY_BANKS];	// Fire this many slots at a time
135 	// end dynamic weapon linking
136 
137 	int secondary_bank_ammo[MAX_SHIP_SECONDARY_BANKS];			// Number of missiles left in secondary bank
138 	int secondary_bank_start_ammo[MAX_SHIP_SECONDARY_BANKS];	// Number of missiles starting in secondary bank -- Every time the secondary bank changes, this must change too!
139 	int secondary_bank_capacity[MAX_SHIP_SECONDARY_BANKS];		// Max number of missiles in bank
140 	int secondary_next_slot[MAX_SHIP_SECONDARY_BANKS];			// Next slot to fire in the bank
141 	int secondary_bank_rearm_time[MAX_SHIP_SECONDARY_BANKS];	// timestamp which indicates when bank can get new missile
142 
143 	int tertiary_bank_ammo;			// Number of shots left tertiary bank
144 	int tertiary_bank_start_ammo;	// Number of shots starting in tertiary bank
145 	int tertiary_bank_capacity;		// Max number of shots in bank
146 	int tertiary_bank_rearm_time;	// timestamp which indicates when bank can get new something (used for ammopod or boostpod)
147 
148 	int remote_detonaters_active;
149 	int detonate_weapon_time;			//	time at which last fired weapon can be detonated
150 	int ai_class;
151 
152 	flagset<Ship::Weapon_Flags> flags;
153 
154 	EModelAnimationPosition primary_animation_position[MAX_SHIP_PRIMARY_BANKS];
155 	EModelAnimationPosition secondary_animation_position[MAX_SHIP_SECONDARY_BANKS];
156 	int primary_animation_done_time[MAX_SHIP_PRIMARY_BANKS];
157 	int  secondary_animation_done_time[MAX_SHIP_SECONDARY_BANKS];
158 
159 	int	burst_counter[MAX_SHIP_PRIMARY_BANKS + MAX_SHIP_SECONDARY_BANKS];
160 	int	burst_seed[MAX_SHIP_PRIMARY_BANKS + MAX_SHIP_SECONDARY_BANKS];    // A random seed, recalculated only when the weapon's burst resets
161 	int external_model_fp_counter[MAX_SHIP_PRIMARY_BANKS + MAX_SHIP_SECONDARY_BANKS];
162 
163 	size_t primary_bank_pattern_index[MAX_SHIP_PRIMARY_BANKS];
164 	size_t secondary_bank_pattern_index[MAX_SHIP_SECONDARY_BANKS];
165 
166 	// for type5 beams, keeps track of accumulated per burst rotation, added to with each shot (or burst)
167 	float per_burst_rot;
168 
169 	/**
170 	 * @brief Constructor. Calls clear()
171 	 */
172     ship_weapon();
173 
174 	/**
175 	 * @brief Inits ship_weapon
176 	 */
177 	void clear();
178 };
179 
180 //**************************************************************
181 //WMC - Damage type handling code
182 
183 int damage_type_add(char *name);
184 
185 //**************************************************************
186 //WMC - Armor stuff
187 
188 // Nuke: some defines for difficulty scaling type
189 #define ADT_DIFF_SCALE_BAD_VAL	-1 // error mode
190 #define ADT_DIFF_SCALE_FIRST	0
191 #define ADT_DIFF_SCALE_LAST		1
192 #define ADT_DIFF_SCALE_MANUAL	2 // this is the user defined mode where the modder has to handle difficulty scaling in their calculations
193 
194 // Nuke: +value: replacing constants
195 // these are stored as altArguments, positive values mean storage idxes and -1 means not used, anything below that is fair game
196 #define AT_CONSTANT_NOT_USED	-1	// will probibly never get used
197 #define AT_CONSTANT_BAD_VAL		-2	// this conveys table error to the user
198 #define AT_CONSTANT_BASE_DMG	-3	// what the damage was at start of calculations
199 #define AT_CONSTANT_CURRENT_DMG	-4	// what the damage currently is
200 #define AT_CONSTANT_DIFF_FACTOR	-5	// difficulty factor (by default 0.2 (easy) to 1.0 (insane))
201 #define AT_CONSTANT_RANDOM		-6	// number between 0 and 1 (redundant but saves a calculation)
202 #define AT_CONSTANT_PI			-7	// because everyone likes pi
203 
204 struct ArmorDamageType
205 {
206 	friend class ArmorType;
207 private:
208 	//Rather than make an extra struct,
209 	//I just made two arrays
210 	int					DamageTypeIndex;
211 	SCP_vector<int>	Calculations;
212 	SCP_vector<float>	Arguments;
213 	SCP_vector<int>		altArguments;		// Nuke: to facilitate optional importation of data in place of +value: tag -nuke
214 	float				shieldpierce_pct;
215 
216 	// piercing effect data
217 	float				piercing_start_pct;
218 	int					piercing_type;
219 	// Nuke: difficulty scale type
220 	int					difficulty_scale_type;
221 
222 public:
223 	void clear();
224 };
225 
226 class ArmorType
227 {
228 private:
229 	char Name[NAME_LENGTH];
230 
231 	SCP_vector<ArmorDamageType> DamageTypes;
232 public:
233 	ArmorType(const char* in_name);
234 	int flags;
235 
236 	//Get
GetNamePtr()237 	char *GetNamePtr(){return Name;}
IsName(const char * in_name)238 	bool IsName(const char* in_name) { return (stricmp(in_name, Name) == 0); }
239 	float GetDamage(float damage_applied, int in_damage_type_idx, float diff_dmg_scale, int is_beam = 0);
240 	float GetShieldPiercePCT(int damage_type_idx);
241 	int GetPiercingType(int damage_type_idx);
242 	float GetPiercingLimit(int damage_type_idx);
243 
244 	//Set
245 	void ParseData();
246 };
247 
248 extern SCP_vector<ArmorType> Armor_types;
249 
250 //**************************************************************
251 //WMC - Damage type handling code
252 
253 typedef struct DamageTypeStruct
254 {
255 	char name[NAME_LENGTH];
256 } DamageTypeStruct;
257 
258 extern SCP_vector<DamageTypeStruct>	Damage_types;
259 
260 #define SAF_IGNORE_SS_ARMOR			(1 << 0)		// hull armor is applied regardless of the subsystem armor for hull damage
261 
262 #define SADTF_PIERCING_NONE			0				// no piercing effects, no beam tooling
263 #define SADTF_PIERCING_DEFAULT		1				// piercing effects, beam tooling
264 #define SADTF_PIERCING_RETAIL		2				// no piercing effects, beam tooling
265 
266 //SUSHI: Damage lightning types. SLT = Ship Lighting Type.
267 #define SLT_NONE	0
268 #define SLT_DEFAULT	1
269 
270 #define NUM_TURRET_ORDER_TYPES		3
271 extern const char *Turret_target_order_names[NUM_TURRET_ORDER_TYPES];	//aiturret.cpp
272 
273 // Swifty: Cockpit displays
274 typedef struct cockpit_display {
275 	int target;
276 	int source;
277 	int foreground;
278 	int background;
279 	int offset[2];
280 	int size[2];
281 	char name[MAX_FILENAME_LEN];
282 } cockpit_display;
283 
284 extern SCP_vector<cockpit_display> Player_displays;
285 
286 typedef struct cockpit_display_info {
287 	char name[MAX_FILENAME_LEN];
288 	char filename[MAX_FILENAME_LEN];
289 	char fg_filename[MAX_FILENAME_LEN];
290 	char bg_filename[MAX_FILENAME_LEN];
291 	int offset[2];
292 	int size[2];
293 } cockpit_display_info;
294 
295 // structure to keep track of ship locks
296 typedef struct lock_info {
297 	object *obj;
298 	ship_subsys *subsys;
299 
300 	vec3d world_pos;
301 
302 	int current_target_sx;
303 	int current_target_sy;
304 
305 	bool locked;
306 	int maintain_lock_count;
307 	int indicator_x;
308 	int indicator_y;
309 	int indicator_start_x;
310 	int indicator_start_y;
311 	bool indicator_visible;
312 	float time_to_lock;
313 	float dist_to_lock;
314 	int catching_up;
315 	float catch_up_distance;
316 	float last_dist_to_target;
317 	double accumulated_x_pixels;
318 	double accumulated_y_pixels;
319 	bool need_new_start_pos;
320 	bool target_in_lock_cone;
321 
322 	float lock_gauge_time_elapsed;
323 	float lock_anim_time_elapsed;
324 } lock_info;
325 
326 // structure definition for a linked list of subsystems for a ship.  Each subsystem has a pointer
327 // to the static data for the subsystem.  The obj_subsystem data is defined and read in the model
328 // code.  Other dynamic data (such as current_hits) should remain in this structure.
329 class ship_subsys
330 {
331 public:
332 	class ship_subsys *next, *prev;				//	Index of next and previous objects in list.
333 	model_subsystem *system_info;					// pointer to static data for this subsystem -- see model.h for definition
334 
335 	int			parent_objnum;						// objnum of the parent ship
336 
337 	char		sub_name[NAME_LENGTH];					//WMC - Name that overrides name of original
338 	float		current_hits;							// current number of hits this subsystem has left.
339 	float		max_hits;
340 
341 	flagset<Ship::Subsystem_Flags> flags;						// Goober5000
342 
343 	int subsys_guardian_threshold;	// Goober5000
344 	int armor_type_idx;				// FUBAR
345 
346 	// turret info
347 	//Important -WMC
348 	//With the new turret code, indexes run from 0 to MAX_SHIP_WEAPONS; a value of MAX_SHIP_PRIMARY_WEAPONS
349 	//or higher, an index into the turret weapons is considered to be an index into the secondary weapons
350 	//for much of the code. See turret_next_weap_fire_stamp.
351 
352 	vec3d	turret_last_fire_direction;		//	direction pointing last time this turret fired
353 	int		turret_next_enemy_check_stamp;	//	time at which to next look for a new enemy.
354 	int		turret_next_fire_stamp;				// next time this turret can fire
355 	int		turret_enemy_objnum;					//	object index of ship this turret is firing upon
356 	int		turret_enemy_sig;						//	signature of object ship this turret is firing upon
357 	int		turret_next_fire_pos;				// counter which tells us which gun position to fire from next
358 	float	turret_time_enemy_in_range;		//	Number of seconds enemy in view cone, accuracy improves over time.
359 	int		turret_targeting_order[NUM_TURRET_ORDER_TYPES];	//Order that turrets target different types of things.
360 	float	optimum_range;
361 	float	favor_current_facing;
362 	ship_subsys	*targeted_subsys;					//	subsystem this turret is attacking
363 	bool	scripting_target_override;
364 	int		last_fired_weapon_info_index;		// which weapon class was last fired
365 
366 	int		turret_pick_big_attack_point_timestamp;	//	Next time to pick an attack point for this turret
367 	vec3d	turret_big_attack_point;			//	local coordinate of point for this turret to attack on enemy
368 
369 	float   turret_inaccuracy;						// additional SEXP inaccuracy, field of fire degrees
370 
371 	EModelAnimationPosition	turret_animation_position;
372 	int		turret_animation_done_time;
373 
374 	// swarm (rapid fire) info
375 	int		turret_swarm_info_index[MAX_TFP];
376 	int		turret_swarm_num;
377 
378 	// awacs info
379 	float		awacs_intensity;
380 	float		awacs_radius;
381 
382 	ship_weapon	weapons;
383 
384 	// Data the renderer needs for ship instance specific data, like
385 	// angles and if it is blown off or not.
386 	// There are 2 of these because turrets need one for the turret and one for the barrel.
387 	// Things like radar dishes would only use one.
388 	submodel_instance *submodel_instance_1;		// Instance data for main turret or main object
389 	submodel_instance *submodel_instance_2;		// Instance data for turret guns, if there is one
390 
391 	int disruption_timestamp;							// time at which subsystem isn't disrupted
392 
393 	int subsys_cargo_name;			// cap ship cargo on subsys
394 	fix time_subsys_cargo_revealed;	// added by Goober5000
395 
396 	int triggered_rotation_index;		//the actual currently running animation and assosiated states
397 
398 	float points_to_target;
399 	float base_rotation_rate_pct;
400 	float gun_rotation_rate_pct;
401 
402 	// still going through these...
403 	flagset<Ship::Subsys_Sound_Flags> subsys_snd_flags;
404 
405 	int      rotation_timestamp;
406 
407 	// target priority setting for turrets
408 	int      target_priority[32];
409 	int      num_target_priorities;
410 
411 	//SUSHI: Fields for max_turret_aim_update_delay
412 	//Only used when targeting small ships
413 	fix		next_aim_pos_time;
414 	vec3d	last_aim_enemy_pos;
415 	vec3d	last_aim_enemy_vel;
416 
417 	//scaler for setting adjusted turret rof
418 	float	rof_scaler;
419 	float	turn_rate;
420 
421 	//Per-turret ownage settings - SUSHI
422 	int turret_max_bomb_ownage;
423 	int turret_max_target_ownage;
424 
ship_subsys()425 	ship_subsys()
426 		: next(NULL), prev(NULL)
427 	{}
428 
429 	void clear();
430 };
431 
432 // structure for subsystems which tells us the total count of a particular type of subsystem (i.e.
433 // we might have 3 engines), and the relative strength of the subsystem.  The #defines in model.h
434 // for SUBSYSTEM_xxx will be used as indices into this array.
435 typedef struct ship_subsys_info {
436 	int	type_count;					// number of subsystems of type on this ship;
437 	float aggregate_max_hits;		// maximum number of hits for all subsystems of this type.
438 	float aggregate_current_hits;	// current count of hits for all subsystems of this type.
439 } ship_subsys_info;
440 
441 // Karajorma - Used by the alter-ship-flag SEXP as an alternative to having lots of ship flag SEXPs
442 typedef struct ship_flag_name {
443 	Ship::Ship_Flags flag;							// the actual ship flag constant as given by the define below
444 	char flag_name[TOKEN_LENGTH];		// the name written to the mission file for its corresponding parse_object flag
445 } ship_flag_name;
446 
447 #define MAX_SHIP_FLAG_NAMES					19
448 extern ship_flag_name Ship_flag_names[];
449 
450 #define DEFAULT_SHIP_PRIMITIVE_SENSOR_RANGE		10000	// Goober5000
451 
452 #define MAX_DAMAGE_SLOTS	32
453 #define MAX_SHIP_ARCS		2		// How many "arcs" can be active at once... Must be less than MAX_ARC_EFFECTS in model.h.
454 #define NUM_SUB_EXPL_HANDLES	2	// How many different big ship sub explosion sounds can be played.
455 
456 #define MAX_SHIP_CONTRAILS		24
457 #define MAX_MAN_THRUSTERS	128
458 
459 typedef struct ship_spark {
460 	vec3d pos;			// position of spark in the submodel's RF
461 	int submodel_num;	// which submodel is making the spark
462 	int end_time;
463 } ship_spark;
464 
465 template <class T>
466 struct reload_pct
467 {
initreload_pct468 	void init(int num_banks, int points_per_bank, T value)
469 	{
470 		_points_per_bank = points_per_bank;
471 		_buffer.clear();
472 		_buffer.resize(num_banks * points_per_bank, value);
473 		_value = value;
474 	}
475 
getreload_pct476 	T& get(int bank, int point)
477 	{
478 		int pos = bank * _points_per_bank + point;
479 
480 		// this can happen with mismatched ships.tbl and models
481 		if (pos >= (int)_buffer.size())
482 			return _value;
483 
484 		return _buffer[pos];
485 	}
486 
setreload_pct487 	void set(int bank, int point, T value)
488 	{
489 		int pos = bank * _points_per_bank + point;
490 
491 		// this can happen with mismatched ships.tbl and models
492 		if (pos >= (int)_buffer.size())
493 			return;
494 
495 		_buffer[pos] = value;
496 	}
497 
498 private:
499 	int _points_per_bank = 0;
500 	T _value;
501 	SCP_vector<T> _buffer;
502 };
503 
504 // NOTE: Can't be treated as a struct anymore, since it has STL data structures in its object tree!
505 class ship
506 {
507 public:
508 	int	objnum;
509 	int	ai_index;			// Index in Ai_info of ai_info associated with this ship.
510 	int	ship_info_index;	// Index in ship_info for this ship
511 	int	hotkey;
512 	int	escort_priority;
513 	int	score;
514 	float assist_score_pct;
515 	int	respawn_priority;
516 
517 	// BEGIN PACK ubytes and chars
518 	ubyte	pre_death_explosion_happened;		// If set, it means the 4 or 5 smaller explosions
519 	ubyte wash_killed;
520 	char	cargo1;
521 
522 	// ship wing status info
523 	char	wing_status_wing_index;			// wing index (0-4) in wingman status gauge
524 	char	wing_status_wing_pos;			// wing position (0-5) in wingman status gauge
525 
526 	// alternate indexes
527 	int	 alt_type_index;								// only used for display purposes (read : safe)
528 	int	 callsign_index;								// ditto
529 
530 	// targeting laser info
531 	char targeting_laser_bank;						// -1 if not firing, index into polymodel gun points if it _is_ firing
532 	int targeting_laser_objnum;					// -1 if invalid, beam object # otherwise
533 
534 	// corkscrew missile stuff
535 	ubyte num_corkscrew_to_fire;						// # of corkscrew missiles lef to fire
536 	int corkscrew_missile_bank;
537 	int next_corkscrew_fire;						// next time to fire a corkscrew missile
538 	// END PACK
539 
540 	int	final_death_time;				// Time until big fireball starts
541 	int	death_time;				// Time until big fireball starts
542 	int	end_death_time;				// Time until big fireball starts
543 	int	really_final_death_time;	// Time until ship breaks up and disappears
544 	vec3d	deathroll_rotvel;			// Desired death rotational velocity
545 
546 	WarpEffect *warpin_effect;
547 	WarpEffect *warpout_effect;
548 
549 	int warpin_params_index;
550 	int warpout_params_index;
551 
552 	int	next_fireball;
553 
554 	int	next_hit_spark;
555 	int	num_hits;			//	Note, this is the number of spark emitter positions!
556 	ship_spark	sparks[MAX_SHIP_HITS];
557 
558 	bool use_special_explosion;
559 	int special_exp_damage;					// new special explosion/hitpoints system
560 	int special_exp_blast;
561 	int special_exp_inner;
562 	int special_exp_outer;
563 	bool use_shockwave;
564 	int special_exp_shockwave_speed;
565 	int special_exp_deathroll_time;
566 
567 	int	special_hitpoints;
568 	int	special_shield;
569 
570 	float ship_max_shield_strength;
571 	float ship_max_hull_strength;
572 
573 	float max_shield_recharge;
574 	float max_shield_regen_per_second;		// wookieejedi - make this a ship object variable
575 	float max_weapon_regen_per_second;		// wookieejedi - make this a ship object variable
576 
577 	int ship_guardian_threshold;	// Goober5000 - now also determines whether ship is guardian'd
578 
579 
580 	char	ship_name[NAME_LENGTH];
581 	SCP_string display_name;
582 
583 	int	team;				//	Which team it's on, HOSTILE, FRIENDLY, UNKNOWN, NEUTRAL
584 
585 	fix	time_cargo_revealed;					// time at which the cargo was revealed
586 
587 	int	arrival_location;
588 	int	arrival_distance;		// how far away this ship should arrive
589 	int	arrival_anchor;			// name of object this ship arrives near (or in front of)
590 	int	arrival_path_mask;		// Goober5000 - possible restrictions on which bay paths to use
591 	int	arrival_cue;
592 	int	arrival_delay;
593 
594 	int	departure_location;		// depart to hyperspace or someplace else (like docking bay)
595 	int	departure_anchor;		// when docking bay -- index of ship to use
596 	int departure_path_mask;	// Goober5000 - possible restrictions on which bay paths to use
597 	int	departure_cue;			// sexpression to eval when departing
598 	int	departure_delay;		// time in seconds after sexp is true that we delay.
599 
600 	int	wingnum;								// wing number this ship is in.  -1 if in no wing, Wing array index otherwise
601 	int	orders_accepted;					// set of orders this ship will accept from the player.
602 
603 	// Subsystem fields.  The subsys_list is a list of all subsystems (which might include multiple types
604 	// of a particular subsystem, like engines).  The subsys_info struct is information for particular
605 	// types of subsystems.  (i.e. the list might contain 3 engines.  There will be one subsys_info entry
606 	// describing the state of all engines combined) -- MWA 4/1/97
607 	ship_subsys	subsys_list;									//	linked list of subsystems for this ship.
608 	ship_subsys	*last_targeted_subobject[MAX_PLAYERS];	// Last subobject that has been targeted.  NULL if none;(player specific)
609 	ship_subsys_info	subsys_info[SUBSYSTEM_MAX];		// info on particular generic types of subsystems
610 
611 	// ETS fields
612 	int	shield_recharge_index;			// index into array holding the shield recharge rate
613 	int	weapon_recharge_index;			// index into array holding the weapon recharge rate
614 	int	engine_recharge_index;			// index into array holding the engine recharge rate
615 	float	weapon_energy;						// Number of EUs in energy reserves
616 	float	current_max_speed;				// Max ship speed (based on energy diverted to engines)
617 	int	next_manage_ets;					// timestamp for when ai can next modify ets ( -1 means never )
618 
619 	flagset<Ship::Ship_Flags>	flags;		// flag variable to contain ship state
620 	int	reinforcement_index;				// index into reinforcement struct or -1
621 
622 	float	afterburner_fuel;					// amount of afterburner fuel remaining (capacity is stored
623 												// as afterburner_fuel_capacity in ship_info).
624 	float   afterburner_last_engage_fuel;      // the fuel level when the afterburners were last engaged
625 	int   afterburner_last_end_time;         // timestamp when the ship last stopped its afterburner
626 
627 	int cmeasure_count;						//	Number of charges of countermeasures this ship can hold.
628 	int current_cmeasure;					//	Currently selected countermeasure.
629 
630 	int cmeasure_fire_stamp;				//	Time at which can fire countermeasure.
631 
632 	float	target_shields_delta;			//	Target for shield recharge system.
633 	float	target_weapon_energy_delta;	//	Target for recharge system.
634 	ship_weapon	weapons;
635 
636 	int	shield_hits;						//	Number of hits on shield this frame.
637 
638 	SCP_vector<vec3d>	shield_points;
639 
640 	float		wash_intensity;
641 	vec3d	wash_rot_axis;
642 	int		wash_timestamp;
643 
644 	SCP_vector<lock_info> missile_locks;
645 	SCP_vector<lock_info> missile_locks_firing;
646 
647 	int	num_swarm_missiles_to_fire;	// number of swarm missiles that need to be launched
648 	int	next_swarm_fire;					// timestamp of next swarm missile to fire
649 	int	num_turret_swarm_info;			// number of turrets in process of launching swarm
650 	int swarm_missile_bank;				// The missilebank the swarm was originally launched from
651 
652 	int	group;								// group ship is in, or -1 if none.  Fred thing
653 	sound_handle death_roll_snd;            // id of death roll sound, may need to be stopped early
654 	int	ship_list_index;					// index of ship in Ship_objs[] array
655 
656 	int	thruster_bitmap;					// What frame the current thruster bitmap is at for this ship
657 	float	thruster_frame;					// Used to keep track of which frame the animation should be on.
658 
659 	int	thruster_glow_bitmap;			// What frame the current thruster engine glow bitmap is at for this ship
660 	float	thruster_glow_frame;				// Used to keep track of which frame the engine glow animation should be on.
661 	float	thruster_glow_noise;				// Noise for current frame
662 
663 	int	thruster_secondary_glow_bitmap;		// Bobboau
664 	int	thruster_tertiary_glow_bitmap;		// Bobboau
665 	int	thruster_distortion_bitmap;			// Valathil
666 
667 	int	next_engine_stutter;				// timestamp to time the engine stuttering when a ship dies
668 
669 	fix base_texture_anim_frametime;		// Goober5000 - zero mark for texture animations
670 
671 	float total_damage_received;        // total damage received (for scoring purposes)
672 	float damage_ship[MAX_DAMAGE_SLOTS];    // damage applied from each player
673 	int   damage_ship_id[MAX_DAMAGE_SLOTS]; // signature of the damager (corresponds to each entry in damage_ship)
674 	int	persona_index;						// which persona is this guy.
675 
676 	int	subsys_disrupted_flags;					// bitflags used to check if SUBYSTEM_* is disrupted or not
677 	int	subsys_disrupted_check_timestamp;	// timer to control how oftern flags are set/cleared in subsys_disrupted_flags
678 
679 	uint	create_time;						// time ship was created, set by gettime()
680 
681 	// keep multiplayer specific stuff below this point
682 	int	ts_index;							// index into the team select and Wss_slots array (or -1 if not in one of those arrays)
683 
684 	int	large_ship_blowup_index;			// -1 if not a large ship exploding, else this is an index used by the shipfx large ship exploding code.
685 	std::array<sound_handle, NUM_SUB_EXPL_HANDLES> sub_expl_sound_handle;
686 
687 	// Stuff for showing electrical arcs on damaged ships
688 	vec3d	arc_pts[MAX_SHIP_ARCS][2];			// The endpoints of each arc
689 	int		arc_timestamp[MAX_SHIP_ARCS];		// When this times out, the spark goes away.  -1 is not used
690 	ubyte		arc_type[MAX_SHIP_ARCS];			// see MARC_TYPE_* defines in model.h
691 	int		arc_next_time;							// When the next arc will be created.
692 
693 	// emp missile stuff
694 	float emp_intensity;								// <= 0.0f if no emp effect present
695 	float emp_decr;									// how much to decrement EMP effect per second for this ship
696 
697 	// contrail stuff
698 	trail *trail_ptr[MAX_SHIP_CONTRAILS];
699 
700 	// tag stuff
701 	float tag_total;									// total tag time
702 	float tag_left;									// total tag remaining
703 	fix	time_first_tagged;
704 	float level2_tag_total;							// total tag time
705 	float level2_tag_left;							// total tag remaining
706 
707 	// lightning timestamp
708 	int lightning_stamp;
709 
710 	// AWACS warning flag
711 	flagset<Ship::Awacs_Warning_Flags>	awacs_warning_flag;
712 
713 	// Special warp objnum (warping at knossos)
714 	int special_warpin_objnum;
715 	int special_warpout_objnum;
716 
717 	ship_subsys fighter_beam_turret_data;		//a fake subsystem that pretends to be a turret for fighter beams
718 	model_subsystem beam_sys_info;
719 	int was_firing_last_frame[MAX_SHIP_PRIMARY_BANKS];
720 
721 	// Goober5000 - range of primitive sensors
722 	int primitive_sensor_range;
723 
724 	// Goober5000 - revised nameplate implementation
725 	int *ship_replacement_textures;
726 
727 	// Goober5000 - index into pm->view_positions[]
728 	// apparently, early in FS1 development, there was a field called current_eye_index
729 	// that had this same functionality
730 	int current_viewpoint;
731 
732 	trail *ABtrail_ptr[MAX_SHIP_CONTRAILS];		//after burner trails -Bobboau
733 	trail_info ab_info[MAX_SHIP_CONTRAILS];
734 	int ab_count;
735 
736 	// glow points
737 	std::deque<bool> glow_point_bank_active;
738 
739 	//Animated Shader effects
740 	int shader_effect_num;
741 	int shader_effect_duration;
742 	int shader_effect_start_time;
743 	bool shader_effect_active;
744 
745 	int last_fired_point[MAX_SHIP_PRIMARY_BANKS]; //for fire point cylceing
746 	ship_subsys *last_fired_turret; // which turret has fired last
747 
748 	// fighter bay door stuff, parent side
749 	int bay_doors_anim_done_time;		// ammount of time to transition from one animation state to another
750 	EModelAnimationPosition bay_doors_status;			// anim status of the bay doors (closed/not-animating, opening, open/not-animating)
751 	int bay_doors_wanting_open;		// how many ships want/need the bay door open
752 
753 	// figther bay door stuff, client side
754 	ubyte bay_doors_launched_from;	// the bay door that I launched from
755 	bool bay_doors_need_open;		// keep track of whether I need the door open or not
756 	int bay_doors_parent_shipnum;	// our parent ship, what we are entering/leaving
757 
758 	reload_pct<float> secondary_point_reload_pct;	//after fireing a secondary it takes some time for that secondary weapon to reload, this is how far along in that proces it is (from 0 to 1)
759 	float primary_rotate_rate[MAX_SHIP_PRIMARY_BANKS];
760 	float primary_rotate_ang[MAX_SHIP_PRIMARY_BANKS];
761 
762 	int thrusters_start[MAX_MAN_THRUSTERS];		//Timestamp of when thrusters started
763 	int thrusters_sounds[MAX_MAN_THRUSTERS];	//Sound index for thrusters
764 
765 	SCP_vector<alt_class> s_alt_classes;
766 
767 	int ship_iff_color[MAX_IFFS][MAX_IFFS];
768 
769 	int ammo_low_complaint_count;				// number of times this ship has complained about low ammo
770 	int armor_type_idx;
771 	int shield_armor_type_idx;
772 	int collision_damage_type_idx;
773 	int debris_damage_type_idx;
774 	ushort debris_net_sig;						// net signiture of the first piece of debris this ship has
775 
776 	int model_instance_num;
777 
778 	fix time_created;
779 
780 	fix radar_visible_since; // The first time this ship was visible on the radar. Gets reset when ship is not visible anymore
781 	fix radar_last_contact; // The last time this ship appeared on the radar. When it is currently visible this has the value if Missiontime
782 
783 	RadarVisibility radar_last_status; // Last radar status
784 	RadarVisibility radar_current_status; // Current radar status
785 
786 	SCP_string team_name;
787 	SCP_string secondary_team_name;	//If the change-team-color sexp is used, these fields control the fading behaviour
788 	fix team_change_timestamp;
789 	int team_change_time;
790 
791 	float autoaim_fov;
792 
793 	enum warpstage {
794 		STAGE1 = 0,
795 		STAGE2,
796 		BOTH,
797 	};
798 
799 	// reset to a completely blank ship
800 	void clear();
801 
802     //Helper functions
803 	bool is_arriving(ship::warpstage stage = ship::warpstage::BOTH, bool dock_leader_or_single = false);
is_departing()804 	inline bool is_departing() { return flags[Ship::Ship_Flags::Depart_warp, Ship::Ship_Flags::Depart_dockbay]; }
cannot_warp_flags()805 	inline bool cannot_warp_flags() { return flags[Ship::Ship_Flags::Warp_broken, Ship::Ship_Flags::Warp_never, Ship::Ship_Flags::Disabled, Ship::Ship_Flags::No_subspace_drive]; }
is_dying_or_departing()806 	inline bool is_dying_or_departing() { return is_departing() || flags[Ship::Ship_Flags::Dying]; }
807 
808 	const char* get_display_name() const;
809 	bool has_display_name() const;
810 
811 	void apply_replacement_textures(SCP_vector<texture_replace> &replacements);
812 };
813 
814 struct ai_target_priority {
815 	char name[NAME_LENGTH];
816 
817 	int obj_type;
818 	SCP_vector <int> ship_type;
819 	SCP_vector <int> ship_class;
820 	SCP_vector <int> weapon_class;
821 
822 	flagset<Object::Object_Flags> obj_flags;
823     flagset<Ship::Info_Flags> sif_flags;
824 	flagset<Weapon::Info_Flags> wif_flags;
825 };
826 
827 extern SCP_vector <ai_target_priority> Ai_tp_list;
828 
829 void parse_ai_target_priorities();
830 void parse_weapon_targeting_priorities();
831 ai_target_priority init_ai_target_priorities();
832 
833 // structure and array def for ships that have exited the game.  Keeps track of certain useful
834 // information.
835 
836 typedef struct exited_ship {
837 	char	ship_name[NAME_LENGTH];
838 	SCP_string display_name;
839 	int		obj_signature;
840 	int		ship_class;
841 	int		team;
842 	flagset<Ship::Exit_Flags> flags;
843 	fix		time;
844 	int		hull_strength;
845 	fix		time_cargo_revealed;
846 	char	cargo1;
847 	float damage_ship[MAX_DAMAGE_SLOTS];		// A copy of the arrays from the ship so that we can figure out what damaged it
848 	int   damage_ship_id[MAX_DAMAGE_SLOTS];
849 } exited_ship;
850 
851 extern SCP_vector<exited_ship> Ships_exited;
852 
853 // a couple of functions to get at the data
854 extern void ship_add_exited_ship( ship *shipp, Ship::Exit_Flags reason );
855 extern int ship_find_exited_ship_by_name( const char *name );
856 extern int ship_find_exited_ship_by_signature( int signature);
857 
858 // Stuff for overall ship status, useful for reference by sexps and scripts.  Status changes occur in the same frame as mission log entries.
859 enum ShipStatus
860 {
861 	// A ship is on the arrival list as a parse object
862 	NOT_YET_PRESENT,
863 
864 	// A ship is currently in-mission, and its objp and shipp pointers are valid
865 	PRESENT,
866 
867 	// A ship is destroyed, departed, or vanished.  Note however that for destroyed ships,
868 	// ship_cleanup is not called until the death roll is complete, which means there is a
869 	// period of time where the ship is "exited", but objp and shipp are still valid and
870 	// exited_index is not yet assigned.
871 	EXITED
872 };
873 
874 struct ship_registry_entry
875 {
876 	ShipStatus status = ShipStatus::NOT_YET_PRESENT;
877 	char name[NAME_LENGTH];
878 
879 	p_object *p_objp = nullptr;
880 	object *objp = nullptr;
881 	ship *shipp = nullptr;
882 	int cleanup_mode = 0;
883 	int exited_index = -1;
884 
ship_registry_entryship_registry_entry885 	ship_registry_entry(const char *_name)
886 	{
887 		strcpy_s(name, _name);
888 	}
889 };
890 
891 extern SCP_vector<ship_registry_entry> Ship_registry;
892 extern SCP_unordered_map<SCP_string, int, SCP_string_lcase_hash, SCP_string_lcase_equal_to> Ship_registry_map;
893 
894 extern const ship_registry_entry *ship_registry_get(const char *name);
895 
896 #define REGULAR_WEAPON	(1<<0)
897 #define DOGFIGHT_WEAPON (1<<1)
898 
899 typedef struct thruster_particles {
900 	generic_anim thruster_bitmap;
901 	float		min_rad;
902 	float		max_rad;
903 	int			n_high;
904 	int			n_low;
905 	float		variance;
906 } thruster_particles;
907 
908 typedef struct particle_effect {
909 	int				n_low;
910 	int				n_high;
911 	float			min_rad;
912 	float			max_rad;
913 	float			min_life;
914 	float			max_life;
915 	float			min_vel;
916 	float			max_vel;
917 	float			variance;
918 } particle_effect;
919 
920 typedef struct ship_type_info {
921 	char name[NAME_LENGTH];
922 
923     flagset<Ship::Type_Info_Flags> flags;
924 
925 	float debris_max_speed;
926 
927 	float ff_multiplier;
928 	float emp_multiplier;
929 
930 	//Fog
931 	float fog_start_dist;
932 	float fog_complete_dist;
933 
934 	//AI
935 	int	ai_valid_goals;
936 	int ai_player_orders;
937 	int ai_active_dock;
938 	int ai_passive_dock;
939 	SCP_vector<int> ai_actively_pursues;
940 	SCP_vector<int> ai_cripple_ignores;
941 
942 	//Explosions
943 	float vaporize_chance;
944 
945 	//Resources
946 	SCP_vector<int> explosion_bitmap_anims;
947 
948 	//Regen values - need to be converted after all types have loaded
949 	SCP_vector<SCP_string> ai_actively_pursues_temp;
950 	SCP_vector<SCP_string> ai_cripple_ignores_temp;
951 
ship_type_infoship_type_info952 	ship_type_info( )
953 		: debris_max_speed( 0.f ),
954 		  ff_multiplier( 0.f ), emp_multiplier( 0.f ),
955 		  fog_start_dist( 0.f ), fog_complete_dist( 0.f ),
956 		  ai_valid_goals( 0 ), ai_player_orders( 0 ), ai_active_dock( 0 ), ai_passive_dock( 0 ),
957 		  vaporize_chance( 0.f )
958 
959 	{
960         flags.reset();
961 		name[ 0 ] = '\0';
962 	}
963 } ship_type_info;
964 
965 extern SCP_vector<ship_type_info> Ship_types;
966 
967 class man_thruster {
968     public:
969 	flagset<Ship::Thruster_Flags> use_flags;
970 
971 	gamesnd_id start_snd;
972 	gamesnd_id loop_snd;
973 	gamesnd_id stop_snd;
974 
975 	int tex_id;
976 	int tex_nframes;
977 	int tex_fps;
978 	float length;
979 	float radius;
980 
981 	vec3d pos, norm;
982 
reset()983     void reset() {
984         length = 0;
985         norm.xyz.x = norm.xyz.y = norm.xyz.z = 0.0f; // I wanted to do norm = ZERO_VECTOR here, but apparently that breaks the MSVC 2015 compiler....
986         pos.xyz.x = pos.xyz.y = pos.xyz.z = 0.0f;
987         radius = 0.0f;
988         tex_fps = 0;
989         tex_nframes = 0;
990         use_flags.reset();
991 
992         start_snd = gamesnd_id();
993         loop_snd = gamesnd_id();
994         stop_snd = gamesnd_id();
995         tex_id = -1;
996     }
997 };
998 
999 // Holds variables for collision physics (Gets its own struct purely for clarity purposes)
1000 // Most of this only really applies properly to small ships
1001 typedef struct ship_collision_physics {
1002 	// Collision physics definitions: how a ship responds to collisions
1003 	float both_small_bounce{};	// Bounce factor when both ships are small
1004 								// This currently only comes into play if one ship is the player...
1005 								// blame retail for that.
1006 	float bounce{};				// Bounce factor for all other cases
1007 	float friction{};				// Controls lateral velocity lost when colliding with a large ship
1008 	float rotation_factor{};		// Affects the rotational energy of collisions... TBH not sure how.
1009 
1010 	// Speed & angle constraints for a smooth landing
1011 	// Note that all angles are stored as a dotproduct between normalized vectors instead. This saves us from having
1012 	// to do a lot of dot product calculations later.
1013 	float landing_max_z{};
1014 	float landing_min_z{};
1015 	float landing_min_y{};
1016 	float landing_max_x{};
1017 	float landing_max_angle{};
1018 	float landing_min_angle{};
1019 	float landing_max_rot_angle{};
1020 
1021 	// Speed & angle constraints for a "rough" landing (one with normal collision consequences, but where
1022 	// the ship is still reoriented towards its resting orientation)
1023 	float reorient_max_z{};
1024 	float reorient_min_z{};
1025 	float reorient_min_y{};
1026 	float reorient_max_x{};
1027 	float reorient_max_angle{};
1028 	float reorient_min_angle{};
1029 	float reorient_max_rot_angle{};
1030 
1031 	// Landing response parameters
1032 	float reorient_mult{};		// How quickly the ship will reorient towards it's resting position
1033 	float landing_rest_angle{};	// The vertical angle where the ship's orientation comes to rest
1034 	gamesnd_id landing_sound_idx;		//Sound to play on successful landing collisions
1035 
1036 	// Collision sounds
1037 	gamesnd_id collision_sound_light_idx;
1038 	gamesnd_id collision_sound_heavy_idx;
1039 	gamesnd_id collision_sound_shielded_idx;
1040 
1041 } ship_collision_physics;
1042 
1043 typedef struct path_metadata {
1044 	vec3d departure_rvec;
1045 	float arrive_speed_mult;
1046 	float depart_speed_mult;
1047 } path_metadata;
1048 
1049 class allowed_weapon_bank
1050 {
1051 public:
1052 	SCP_vector<std::pair<int, ubyte>> weapon_and_flags;
1053 
1054 	ubyte find_flags(int weapon_info_index) const;
1055 	void set_flag(int weapon_info_index, ubyte flag);
1056 	void clear_flag(int weapon_info_index, ubyte flag);
1057 	void clear_flag(ubyte flag);
1058 
1059 	void clear();
1060 
1061 	ubyte operator[](int index) const;
1062 	ubyte operator[](size_t index) const;
1063 };
1064 
1065 // The real FreeSpace ship_info struct.
1066 // NOTE: Can't be treated as a struct anymore, since it has STL data structures in its object tree!
1067 class ship_info
1068 {
1069 public:
1070 	char		name[NAME_LENGTH];				// name for the ship
1071 	char		display_name[NAME_LENGTH];		// display another name for the ship
1072 	char		short_name[NAME_LENGTH];		// short name, for use in the editor?
1073 	int			species;								// which species this craft belongs to
1074 	int			class_type;						//For type table
1075 
1076 	char		*type_str;							// type string used by tooltips
1077 	char		*maneuverability_str;			// string used by tooltips
1078 	char		*armor_str;							// string used by tooltips
1079 	char		*manufacturer_str;				// string used by tooltips
1080 	char		*desc;								// string used by tooltips
1081 	char		*tech_desc;							// string used by tech database
1082 	char		tech_title[NAME_LENGTH];			// ship's name (in tech database)
1083 
1084 	char     *ship_length;						// string used by multiplayer ship desc
1085 	char     *gun_mounts;			         // string used by multiplayer ship desc
1086 	char     *missile_banks;					// string used by multiplayer ship desc
1087 
1088 	char		cockpit_pof_file[MAX_FILENAME_LEN];	// POF file for cockpit view
1089 	vec3d		cockpit_offset;
1090 	char		pof_file[MAX_FILENAME_LEN];			// POF file to load/associate with ship
1091 	char		pof_file_hud[MAX_FILENAME_LEN];		// POF file to load for the HUD target box
1092 	char		pof_file_tech[MAX_FILENAME_LEN];	// POF file to load for the techroom
1093 	int		num_detail_levels;				// number of detail levels for this ship
1094 	int		detail_distance[MAX_SHIP_DETAIL_LEVELS];					// distance to change detail levels at
1095 	int		collision_lod;						// check for collisions using a LOD
1096 	int		cockpit_model_num;					// cockpit model
1097 	int		model_num;							// ship model
1098 	int		model_num_hud;						// model to use when rendering to the HUD (eg, mini supercap)
1099 	int		hud_target_lod;						// LOD to use for rendering to the HUD targetbox (if not already using special HUD model)
1100 	float		density;								// density of the ship in g/cm^3 (water  = 1)
1101 	float		damp;									// drag
1102 	float		rotdamp;								// rotational drag
1103 	float		delta_bank_const;
1104 	vec3d	max_vel;								//	max velocity of the ship in the linear directions -- read from ships.tbl
1105 	vec3d	min_vel;								//	min velocity of the ship in the linear directions -- read from ships.tbl
1106 	vec3d	max_rotvel;							// maximum rotational velocity
1107 	vec3d	rotation_time;						// time to rotate in x/y/z dimension traveling at max rotvel
1108 	float		srotation_time;					//	scalar, computed at runtime as (rotation_time.x + rotation_time.y)/2
1109 	float		max_rear_vel;						// max speed ship can go backwards.
1110 	float		forward_accel;
1111 	float		forward_decel;
1112 	float		slide_accel;
1113 	float		slide_decel;
1114 
1115 	int warpin_params_index;
1116 	int warpout_params_index;
1117 
1118 	flagset<Ship::Info_Flags> flags;							//	See SIF_xxxx - changed to uint by Goober5000, changed back by Zacam, and changed to something entirely different by The E!
1119 	int		ai_class;							//	Index into Ai_classes[].  Defined in ai.tbl
1120 	float		max_speed, min_speed, max_accel;
1121 
1122 	//Collision
1123 	int						collision_damage_type_idx;
1124 	ship_collision_physics	collision_physics;
1125 
1126 	// ship explosion info
1127 	shockwave_create_info shockwave;
1128 	int	explosion_propagates;				// If true, then the explosion propagates
1129 	bool explosion_splits_ship;				// If true, then the ship 'splits in two' when it blows up
1130 	float big_exp_visual_rad;				//SUSHI: The visual size of the main explosion
1131 	float prop_exp_rad_mult;				// propagating explosions radius multiplier
1132 	float death_roll_r_mult;
1133 	float death_fx_r_mult;
1134 	float death_roll_time_mult;
1135 	float death_roll_rotation_mult;
1136 	float death_roll_xrotation_cap;         // max rotation around x-axis in radians-per-sec (aka pitch)
1137 	float death_roll_yrotation_cap;         // max rotation around y-axis in radians-per-sec (aka yaw)
1138 	float death_roll_zrotation_cap;         // max rotation around z-axis in radians-per-sec (aka roll)
1139 	int death_roll_base_time;
1140 	int death_fx_count;
1141 	int	shockwave_count;					// the # of total shockwaves
1142 	SCP_vector<int> explosion_bitmap_anims;
1143 	float vaporize_chance;
1144 
1145 	particle_effect		impact_spew;
1146 	particle_effect		damage_spew;
1147 	particle_effect		split_particles;
1148 	particle_effect		knossos_end_particles;
1149 	particle_effect		regular_end_particles;
1150 
1151 	particle::ParticleEffectHandle death_effect;
1152 
1153 	//Debris stuff
1154 	float			debris_min_lifetime;
1155 	float			debris_max_lifetime;
1156 	float			debris_min_speed;
1157 	float			debris_max_speed;
1158 	float			debris_min_rotspeed;
1159 	float			debris_max_rotspeed;
1160 	int				debris_damage_type_idx;
1161 	float			debris_min_hitpoints;
1162 	float			debris_max_hitpoints;
1163 	float			debris_damage_mult;
1164 	float			debris_arc_percent;
1165 	gamesnd_id		debris_ambient_sound;
1166 	gamesnd_id		debris_collision_sound_light;
1167 	gamesnd_id		debris_collision_sound_heavy;
1168 	gamesnd_id		debris_explosion_sound;
1169 	char			generic_debris_pof_file[MAX_FILENAME_LEN]; // smaller debris bits thrown around willy-nilly on death
1170 	int				generic_debris_model_num;
1171 	int				generic_debris_num_submodels;
1172 	int			    generic_debris_spew_num;
1173 
1174 	// subsystem information
1175 	int		n_subsystems;						// this number comes from ships.tbl
1176     model_subsystem *subsystems;				// see model.h for structure definition
1177 
1178 	// Energy Transfer System fields
1179 	float		power_output;					// power output of ships reactor (EU/s)
1180 	float		max_overclocked_speed;			// max speed when 100% power output sent to engines
1181 	float		max_weapon_reserve;				// maximum energy that can be stored for primary weapon usage
1182 	float		max_shield_regen_per_second;	// Goober5000 - max percent/100 of shield energy regenerated per second
1183 	float       shield_regen_hit_delay;			// Asteroth - delay after being hit before shield will start recharging again
1184 	float		max_weapon_regen_per_second;	// Goober5000 - max percent/100 of weapon energy regenerated per second
1185 
1186 	// Fields for tuning the ETS' direct shield<->weapon transfer feature
1187 	float		shield_weap_amount;				// fraction of shield capacity to transfer
1188 	float		shield_weap_efficiency;			// efficiency multiplier for output into weapons capacitor
1189 	float		shield_weap_speed;				// rate that energy will be added to the weap capacitor
1190 	float		weap_shield_amount;				// ...
1191 	float		weap_shield_efficiency;			// ditto, but reverse the direction
1192 	float		weap_shield_speed;				// ...
1193 
1194 	// Afterburner fields
1195 	vec3d		afterburner_max_vel;				//	max velocity of the ship in the linear directions when afterburners are engaged -- read from ships.tbl
1196 	float		afterburner_forward_accel;		// forward acceleration with afterburner engaged
1197 	float		afterburner_fuel_capacity;		// maximum afterburner fuel that can be stored
1198 	float		afterburner_burn_rate;			// rate in fuel/second that afterburner consumes fuel
1199 	float		afterburner_recover_rate;		//	rate in fuel/second that afterburner recovers fuel
1200 	float       afterburner_min_start_fuel;     // must have at least this much fuel to start
1201 	float       afterburner_min_fuel_to_burn;   // consumes at least this much fuel before allowing to stop
1202 	float       afterburner_cooldown_time;      // minimum time between last afterburner finish and next start
1203 	//SparK: reverse afterburner
1204 	float		afterburner_max_reverse_vel;
1205 	float		afterburner_reverse_accel;
1206 
1207 	int		cmeasure_type;						// Type of countermeasures this ship carries
1208 	int		cmeasure_max;						//	Number of charges of countermeasures this ship can hold.
1209 
1210 	int num_primary_banks;										// Actual number of primary banks (property of model)
1211 	int primary_bank_weapons[MAX_SHIP_PRIMARY_BANKS];			// Weapon_info[] index for the weapon in the bank
1212 	// Goober5000's ballistic conversion
1213 	int primary_bank_ammo_capacity[MAX_SHIP_PRIMARY_BANKS];	// Capacity of primary ballistic bank
1214 
1215 	int num_secondary_banks;									//	Actual number of secondary banks (property of model)
1216 	int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS];	// Weapon_info[] index for the weapon in the bank
1217 	int secondary_bank_ammo_capacity[MAX_SHIP_SECONDARY_BANKS];	// Capacity of bank (not number of missiles)
1218 
1219 	bool draw_primary_models[MAX_SHIP_PRIMARY_BANKS];
1220 	bool draw_secondary_models[MAX_SHIP_SECONDARY_BANKS];
1221 	float weapon_model_draw_distance;
1222 
1223 	// Recoil modifier for the ship
1224 	float ship_recoil_modifier;
1225 
1226 	float	max_hull_strength;				// Max hull strength of this class of ship.
1227 	float	max_shield_strength;
1228 	float	auto_shield_spread;				// Thickness of the shield
1229 	bool	auto_shield_spread_bypass;		// Whether weapons fired up close can bypass shields
1230 	int		auto_shield_spread_from_lod;	// Which LOD to project the shield from
1231 	float	auto_shield_spread_min_span;	// Minimum distance weapons must travel until allowed to collide with the shield
1232 
1233 	int		shield_point_augment_ctrls[4];	// Re-mapping of shield augmentation controls for model point shields
1234 
1235 	float	max_shield_recharge;
1236 
1237 	float	hull_repair_rate;				//How much of the hull is repaired every second
1238 	float	subsys_repair_rate;		//How fast
1239 
1240 	float	sup_hull_repair_rate;
1241 	float	sup_shield_repair_rate;
1242 	float	sup_subsys_repair_rate;
1243 
1244 	vec3d	closeup_pos;					// position for camera when using ship in closeup view (eg briefing and techroom)
1245 	float	closeup_zoom;					// zoom when using ship in closeup view (eg briefing and techroom)
1246 
1247 	vec3d	closeup_pos_targetbox;			// position for camera when using ship in closeup view for hud target monitor
1248 	float	closeup_zoom_targetbox;			// zoom when using ship in closeup view for hud target monitor
1249 
1250 	vec3d	chase_view_offset;				// special offset for chase view
1251 	float	chase_view_rigidity;			// how 'floaty' this ship is when viewed in chase view
1252 
1253 	allowed_weapon_bank allowed_weapons;	// specifies which weapons can be loaded out by the
1254 											// player during weapons loadout.
1255 
1256 	// Goober5000 - fix for restricted banks mod
1257 	SCP_vector<ubyte> restricted_loadout_flag;
1258 	SCP_vector<allowed_weapon_bank> allowed_bank_restricted_weapons;
1259 
1260 	ubyte	shield_icon_index;				// index to locate ship-specific animation frames for the shield on HUD
1261 	char	icon_filename[MAX_FILENAME_LEN];	// filename for icon that is displayed in ship selection
1262 	angles	model_icon_angles;					// angle from which the model icon should be rendered (if not 0,0,0)
1263 	char	anim_filename[MAX_FILENAME_LEN];	// filename for animation that plays in ship selection
1264 	char	overhead_filename[MAX_FILENAME_LEN];	// filename for animation that plays weapons loadout
1265 	int 	selection_effect;
1266 
1267 	int bii_index_ship;						// if this ship has a briefing icon that overrides the normal icon set
1268 	int bii_index_ship_with_cargo;
1269 	int bii_index_wing;
1270 	int bii_index_wing_with_cargo;
1271 
1272 	int	score;								// default score for this ship
1273 
1274 	int	scan_time;							// time to scan this ship (in ms)
1275 	float scan_range_normal;                // this ship can scan other normal/small ships at this range
1276 	float scan_range_capital;               // this ship can scan other capital/large ships at this range
1277 
1278 	float ask_help_shield_percent;
1279 	float ask_help_hull_percent;
1280 
1281 	// contrail info
1282 	trail_info ct_info[MAX_SHIP_CONTRAILS];
1283 	int ct_count;
1284 
1285 	// rgb shield color
1286 	ubyte shield_color[3];
1287 
1288 	// HW2-style team coloring
1289 	bool uses_team_colors;
1290 	SCP_string default_team_name;
1291 
1292 	// optional afterburner trail values
1293 	generic_bitmap afterburner_trail;
1294 	float afterburner_trail_tex_stretch;
1295 	float afterburner_trail_width_factor;
1296 	float afterburner_trail_alpha_factor;
1297 	float afterburner_trail_alpha_end_factor;
1298 	float afterburner_trail_alpha_decay_exponent;
1299 	float afterburner_trail_life;
1300 	float afterburner_trail_spread;
1301 	int afterburner_trail_faded_out_sections;
1302 
1303 	// thruster particles
1304 	SCP_vector<thruster_particles> normal_thruster_particles;
1305 	SCP_vector<thruster_particles> afterburner_thruster_particles;
1306 
1307 	// Bobboau's extra thruster stuff
1308 	thrust_pair			thruster_flame_info;
1309 	thrust_pair			thruster_glow_info;
1310 	thrust_pair_bitmap	thruster_secondary_glow_info;
1311 	thrust_pair_bitmap	thruster_tertiary_glow_info;
1312 	thrust_pair_bitmap	thruster_distortion_info;
1313 
1314 	float		thruster01_glow_rad_factor;
1315 	float		thruster02_glow_rad_factor;
1316 	float		thruster03_glow_rad_factor;
1317 	float		thruster02_glow_len_factor;
1318 	float		thruster_dist_rad_factor;
1319 	float		thruster_dist_len_factor;
1320 	float		thruster_glow_noise_mult;
1321 
1322 	bool		draw_distortion;
1323 
1324 	int splodeing_texture;
1325 	char splodeing_texture_name[MAX_FILENAME_LEN];
1326 
1327 	// Goober5000
1328 	SCP_vector<texture_replace> replacement_textures;
1329 
1330 
1331 	int armor_type_idx;
1332 	int shield_armor_type_idx;
1333 
1334 	bool can_glide;
1335 	float glide_cap;	//Backslash - for 'newtonian'-style gliding, the cap on velocity
1336 	bool glide_dynamic_cap;	//SUSHI: Whether or not we are using a dynamic glide cap
1337 	float glide_accel_mult;	//SUSHI: acceleration multiplier for glide mode
1338 	bool use_newtonian_damp; //SUSHI: Whether or not to use newtonian dampening for this ship
1339 	bool newtonian_damp_override;
1340 
1341 	float autoaim_fov;
1342 
1343 	bool topdown_offset_def;
1344 	vec3d topdown_offset;
1345 
1346 	gamesnd_id engine_snd;							// handle to engine sound for ship (-1 if no engine sound)
1347 	float min_engine_vol;					// minimum volume modifier for engine sound when ship is stationary
1348 	gamesnd_id glide_start_snd;					// handle to sound to play at the beginning of a glide maneuver (default is 0 for regular throttle down sound)
1349 	gamesnd_id glide_end_snd;						// handle to sound to play at the end of a glide maneuver (default is 0 for regular throttle up sound)
1350 	gamesnd_id flyby_snd;					// handle to sound to play with ship flyby
1351 
1352 	SCP_map<GameSounds, gamesnd_id> ship_sounds;			// specifies ship-specific sound indexes
1353 
1354 	int num_maneuvering;
1355 	man_thruster maneuvering[MAX_MAN_THRUSTERS];
1356 
1357 	int radar_image_2d_idx;
1358 	int radar_color_image_2d_idx;
1359 	int radar_image_size;
1360 	float radar_projection_size_mult;
1361 
1362 	int ship_iff_info[MAX_IFFS][MAX_IFFS];
1363 
1364 	flagset<Ship::Aiming_Flags> aiming_flags;
1365 	float minimum_convergence_distance;
1366 	float convergence_distance;
1367 	vec3d convergence_offset;
1368 	gamesnd_id autoaim_lock_snd;
1369 	gamesnd_id autoaim_lost_snd;
1370 
1371 	float emp_resistance_mod;
1372 
1373 	float piercing_damage_draw_limit;
1374 	int shield_impact_explosion_anim;
1375 
1376 	int damage_lightning_type;
1377 
1378 	SCP_vector<std::unique_ptr<HudGauge>> hud_gauges;
1379 	bool hud_enabled;
1380 	bool hud_retail;
1381 
1382 	SCP_vector<cockpit_display_info> displays;
1383 
1384 	SCP_map<SCP_string, path_metadata> pathMetadata;
1385 
1386 	SCP_unordered_map<int, void*> glowpoint_bank_override_map;
1387 
1388 	animation::ModelAnimationSet animations;
1389 
1390 	ship_info();
1391 	~ship_info();
1392 	void clone(const ship_info& other);
1393 
1394 	ship_info(ship_info&& other) noexcept;
1395 
1396 	ship_info &operator=(ship_info&& other) noexcept;
1397 
1398 	void free_strings();
1399 
1400     //Helper functions
1401 
is_small_ship()1402     inline bool is_small_ship() const { return flags[Ship::Info_Flags::Fighter, Ship::Info_Flags::Bomber, Ship::Info_Flags::Support, Ship::Info_Flags::Escapepod]; }
is_big_ship()1403     inline bool is_big_ship() const { return flags[Ship::Info_Flags::Cruiser, Ship::Info_Flags::Freighter, Ship::Info_Flags::Transport, Ship::Info_Flags::Corvette, Ship::Info_Flags::Gas_miner, Ship::Info_Flags::Awacs]; }
is_huge_ship()1404     inline bool is_huge_ship() const  { return flags[Ship::Info_Flags::Capital, Ship::Info_Flags::Supercap, Ship::Info_Flags::Drydock, Ship::Info_Flags::Knossos_device]; }
is_flyable()1405     inline bool is_flyable() const { return !(flags[Ship::Info_Flags::Cargo, Ship::Info_Flags::Navbuoy, Ship::Info_Flags::Sentrygun]); }	// AL 11-24-97: this useful to know for targeting reasons
1406 // note: code that previously used is_harmless() / SIF_HARMLESS now uses several flags defined in objecttypes.tbl
1407 //	inline bool is_harmless() const { return flags[Ship::Info_Flags::Cargo, Ship::Info_Flags::Navbuoy, Ship::Info_Flags::Escapepod]; }		// AL 12-3-97: ships that are not a threat
is_fighter_bomber()1408     inline bool is_fighter_bomber() const { return flags[Ship::Info_Flags::Fighter, Ship::Info_Flags::Bomber]; }
is_big_or_huge()1409     inline bool is_big_or_huge() const { return is_big_ship() || is_huge_ship(); }
avoids_shockwaves()1410     inline bool avoids_shockwaves() const { return is_small_ship(); }
1411 
1412 	const char* get_display_name() const;
1413 	bool has_display_name() const;
1414 
1415 private:
1416 	void move(ship_info&& other);
1417 
1418 	// Private and unimplemented so nobody tries to use them by accident.
1419 	ship_info(const ship_info& other);
1420 	const ship_info &operator=(const ship_info& other);
1421 };
1422 
1423 extern flag_def_list_new<Ship::Info_Flags> Ship_flags[];
1424 extern const size_t Num_ship_flags;
1425 
1426 extern int Num_wings;
1427 extern ship Ships[MAX_SHIPS];
1428 extern ship	*Player_ship;
1429 extern int	*Player_cockpit_textures;
1430 
1431 // Data structure to track the active missiles
1432 typedef struct ship_obj {
1433 	ship_obj		 *next, *prev;
1434 	int			flags, objnum;
1435 } ship_obj;
1436 extern ship_obj Ship_obj_list;
1437 
1438 typedef struct engine_wash_info
1439 {
1440 	char		name[NAME_LENGTH];
1441 	float		angle;			// half angle of cone around engine thruster
1442 	float		radius_mult;	// multiplier for radius
1443 	float		length;			// length of engine wash, measured from thruster
1444 	float		intensity;		// intensity of engine wash
1445 
1446 } engine_wash_info;
1447 
1448 extern SCP_vector<engine_wash_info> Engine_wash_info;
1449 
1450 
1451 //	Defines a wing of ships.
1452 typedef struct wing {
1453 	char	name[NAME_LENGTH];
1454 	char	wing_squad_filename[MAX_FILENAME_LEN];	// Goober5000
1455 	int	reinforcement_index;					// index in reinforcement struct or -1
1456 	int	hotkey;
1457 
1458 	int	num_waves, current_wave;			// members for dealing with waves
1459 	int	threshold;								// when number of ships in the wing reaches this number -- new wave
1460 
1461 	fix	time_gone;								// time into the mission when this wing is officially gone.
1462 
1463 	int	wave_count;								// max ships per wave (as defined by the number of ships in the ships list)
1464 	int	total_arrived_count;					// count of number of ships that we have created, regardless of wave
1465 	int red_alert_skipped_ships;				// Goober5000 - if we skipped over any indexes while creating red-alert ships
1466 	int	current_count;							// count of number of ships actually in this wing -- used for limit in next array
1467 	int	ship_index[MAX_SHIPS_PER_WING];	// index into ships array of all ships currently in the wing
1468 
1469 	int	total_destroyed;						// total number of ships destroyed in the wing (including all waves)
1470 	int	total_departed;						// total number of ships departed in this wing (including all waves)
1471 	int total_vanished;						// total number of ships vanished in this wing (including all waves)
1472 
1473 	int	special_ship;							// the leader of the wing.  An index into ship_index[].
1474 
1475 	int	arrival_location;						// arrival and departure information for wings -- similar to info for ships
1476 	int	arrival_distance;						// distance from some ship where this ship arrives
1477 	int	arrival_anchor;						// name of object this ship arrives near (or in front of)
1478 	int	arrival_path_mask;					// Goober5000 - possible restrictions on which bay paths to use
1479 	int	arrival_cue;
1480 	int	arrival_delay;
1481 
1482 	int	departure_location;
1483 	int	departure_anchor;						// name of object that we depart to (in case of dock bays)
1484 	int departure_path_mask;				// Goober5000 - possible restrictions on which bay paths to use
1485 	int	departure_cue;
1486 	int	departure_delay;
1487 
1488 	int	wave_delay_min;						// minimum number of seconds before new wave can arrive
1489 	int	wave_delay_max;						// maximum number of seconds before new wave can arrive
1490 	int	wave_delay_timestamp;				// timestamp used for delaying arrival of next wave
1491 
1492 	flagset<Ship::Wing_Flags> flags;
1493 
1494 	ai_goal	ai_goals[MAX_AI_GOALS];			// goals for the wing -- converted to ai_goal struct
1495 
1496 	ushort	net_signature;						// starting net signature for ships in this wing. assiged at mission load time
1497 
1498 	// Goober5000 - if this wing has a unique squad logo
1499 	// it's specified for the wing rather than each individual ship to cut down on the amount
1500 	// of stuff that needs to be sitting in memory at once - each ship uses the wing texture;
1501 	// and it also makes practical sense: no wing has two different squadrons in it :)
1502 	int wing_insignia_texture;
1503 
1504 	// if -1, retail formation, else a custom one defined in ships.tbl
1505 	int formation;
1506 } wing;
1507 
1508 extern wing Wings[MAX_WINGS];
1509 
1510 extern int Starting_wings[MAX_STARTING_WINGS];
1511 extern int Squadron_wings[MAX_SQUADRON_WINGS];
1512 extern int TVT_wings[MAX_TVT_WINGS];
1513 
1514 extern char Starting_wing_names[MAX_STARTING_WINGS][NAME_LENGTH];
1515 extern char Squadron_wing_names[MAX_SQUADRON_WINGS][NAME_LENGTH];
1516 extern bool Squadron_wing_names_found[MAX_SQUADRON_WINGS];
1517 extern char TVT_wing_names[MAX_TVT_WINGS][NAME_LENGTH];
1518 
1519 extern int ai_paused;
1520 
1521 extern int Num_reinforcements;
1522 extern SCP_vector<ship_info> Ship_info;
1523 extern reinforcements Reinforcements[MAX_REINFORCEMENTS];
1524 
1525 // structure definition for ship type counts.  Used to give a count of the number of ships
1526 // of a particular type, and the number of times that a ship of that particular type has been
1527 // killed.  When changing any info here, be sure to update the ship_type_names array in Ship.cpp
1528 // the order of the types here MUST match the order of the types in the array
1529 typedef struct ship_counts {
1530 	int	total;
1531 	int	killed;
ship_countsship_counts1532 	ship_counts(){total=0;killed=0;}
1533 } ship_counts;
1534 
1535 extern SCP_vector<ship_counts> Ship_type_counts;
1536 
1537 
1538 // Formations
1539 typedef struct wing_formation {
1540 	char name[NAME_LENGTH];
1541 	std::array<vec3d, MAX_SHIPS_PER_WING - 1> positions;	// does NOT include wing leader, so index 0 for each formation is the second in the wing, 1 is third, etc
1542 } wing_formation;
1543 
1544 extern SCP_vector<wing_formation> Wing_formations;
1545 
1546 
1547 // Use the below macros when you want to find the index of an array element in the
1548 // Wings[] or Ships[] arrays.
1549 #define WING_INDEX(wingp) ((int)(wingp-Wings))
1550 #define SHIP_INDEX(shipp) ((int)(shipp-Ships))
1551 
1552 
1553 extern void ship_init();				// called once	at game start
1554 extern void ship_level_init();		// called before the start of each level
1555 
1556 //returns -1 if failed
1557 extern int ship_create(matrix* orient, vec3d* pos, int ship_type, const char* ship_name = nullptr);
1558 extern void change_ship_type(int n, int ship_type, int by_sexp = 0);
1559 extern void ship_process_pre( object * objp, float frametime );
1560 extern void ship_process_post( object * objp, float frametime );
1561 extern void ship_render( object * obj, model_draw_list * scene );
1562 extern void ship_render_cockpit( object * objp);
1563 extern void ship_render_show_ship_cockpit( object * objp);
1564 extern void ship_delete( object * objp );
1565 extern int ship_check_collision_fast( object * obj, object * other_obj, vec3d * hitpos );
1566 extern int ship_get_num_ships();
1567 
1568 #define SHIP_VANISHED			(1<<0)
1569 #define SHIP_DESTROYED			(1<<1)
1570 #define SHIP_DEPARTED_WARP		(1<<2)
1571 #define SHIP_DEPARTED_BAY		(1<<3)
1572 #define SHIP_DEPARTED			( SHIP_DEPARTED_BAY | SHIP_DEPARTED_WARP )
1573 #define SHIP_DESTROYED_REDALERT	(1<<4)
1574 #define SHIP_DEPARTED_REDALERT	(1<<5)
1575 
1576 /**
1577  * @brief Deletes and de-inits a ship.
1578  *
1579  * @param[in] shipnum      Index of this ship in Ships[]
1580  * @param[in] cleanup_mode Flags describing how this ship is to be removed. See SHIP_VANISHED, SHIP_DESTROYED, etc.
1581  *
1582  * @details This is the deconstructor of a ship, it does all the necassary processes to remove the ship from the Ships
1583  *   array, and frees the slot for use by others. De-init of its Objects[] slot is handled by obj_delete_all_that_should_be_dead().
1584  *
1585  * @author Goober5000
1586  * @sa obj_delete_all_that_should_be_dead()
1587  */
1588 extern void ship_cleanup(int shipnum, int cleanup_mode);
1589 
1590 // Goober5000
1591 extern void ship_destroy_instantly(object *ship_obj);
1592 extern void ship_actually_depart(int shipnum, int method = SHIP_DEPARTED_WARP);
1593 
1594 extern bool in_autoaim_fov(ship *shipp, int bank_to_fire, object *obj);
1595 extern int ship_stop_fire_primary(object * obj);
1596 extern int ship_fire_primary(object * objp, int stream_weapons, int force = 0, bool rollback_shot = false);
1597 extern int ship_fire_secondary(object * objp, int allow_swarm = 0, bool rollback_shot = false );
1598 bool ship_start_secondary_fire(object* objp);
1599 bool ship_stop_secondary_fire(object* objp);
1600 extern int ship_launch_countermeasure(object *objp, int rand_val = -1);
1601 
1602 // for special targeting lasers
1603 extern void ship_process_targeting_lasers();
1604 
1605 extern int ship_select_next_primary(object *objp, int direction);
1606 extern int  ship_select_next_secondary(object *objp);
1607 
1608 // Goober5000
1609 extern int get_available_primary_weapons(object *objp, int *outlist, int *outbanklist);
1610 
1611 extern int get_available_secondary_weapons(object *objp, int *outlist, int *outbanklist);
1612 extern void ship_recalc_subsys_strength( ship *shipp );
1613 extern void physics_ship_init(object *objp);
1614 
1615 //	Note: This is not a general purpose routine.
1616 //	It is specifically used for targeting.
1617 //	Return true/false for subsystem found/not found.
1618 //	Stuff vector *pos with absolute position.
1619 extern int get_subsystem_pos(vec3d *pos, object *objp, ship_subsys *subsysp);
1620 
1621 extern int ship_info_lookup(const char *name);
1622 extern int ship_name_lookup(const char *name, int inc_players = 0);	// returns the index into Ship array of name
1623 extern int ship_type_name_lookup(const char *name);
1624 
ship_info_size()1625 inline int ship_info_size()
1626 {
1627 	return static_cast<int>(Ship_info.size());
1628 }
1629 
1630 extern int wing_lookup(const char *name);
1631 extern int wing_formation_lookup(const char *formation_name);
1632 
1633 // returns 0 if no conflict, 1 if conflict, -1 on some kind of error with wing struct
1634 extern int wing_has_conflicting_teams(int wing_index);
1635 
1636 // next function takes optional second parameter which says to ignore the current count of ships
1637 // in the wing -- used to tell is the wing exists or not, not whether it exists and has ships currently
1638 // present.
1639 extern int wing_name_lookup(const char *name, int ignore_count = 0);
1640 
1641 extern bool wing_has_yet_to_arrive(const wing *wingp);
1642 
1643 // for generating a ship name for arbitrary waves/indexes of that wing... correctly handles the # character
1644 extern void wing_bash_ship_name(char *ship_name, const char *wing_name, int index, bool *needs_display_name = nullptr);
1645 extern int Player_ship_class;
1646 
1647 //	Do the special effect for energy dissipating into the shield for a hit.
1648 //	model_num	= index in Polygon_models[]
1649 //	centerp		= pos of object, sort of the center of the shield
1650 //	tcp			= hit point, probably the global hit_point set in polygon_check_face
1651 //	tr0			= index of polygon in shield pointer in polymodel.
1652 extern void create_shield_explosion(int objnum, int model_num, matrix *orient, vec3d *centerp, vec3d *tcp, int tr0);
1653 
1654 //	Initialize shield hit system.
1655 extern void shield_hit_init();
1656 extern void create_shield_explosion_all(object *objp);
1657 extern void shield_frame_init();
1658 extern void add_shield_point(int objnum, int tri_num, vec3d *hit_pos);
1659 extern void add_shield_point_multi(int objnum, int tri_num, vec3d *hit_pos);
1660 extern void shield_point_multi_setup();
1661 extern void shield_hit_close();
1662 
1663 // Returns true if the shield presents any opposition to something
1664 // trying to force through it.
1665 // If quadrant is -1, looks at entire shield, otherwise
1666 // just one quadrant
1667 int ship_is_shield_up( object *obj, int quadrant );
1668 
1669 //=================================================
1670 void ship_model_update_instance(object *objp);
1671 
1672 //============================================
1673 extern int ship_find_num_crewpoints(object *objp);
1674 extern int ship_find_num_turrets(object *objp);
1675 
1676 extern void compute_slew_matrix(matrix *orient, angles *a);
1677 extern void ship_get_eye( vec3d *eye_pos, matrix *eye_orient, object *obj, bool do_slew = true, bool from_origin = false);		// returns in eye the correct viewing position for the given object
1678 //extern camid ship_get_followtarget_eye(object *obj);
1679 extern ship_subsys *ship_get_indexed_subsys( ship *sp, int index, vec3d *attacker_pos = NULL );	// returns index'th subsystem of this ship
1680 extern int ship_get_index_from_subsys(ship_subsys *ssp, int objnum);
1681 extern int ship_get_subsys_index(ship *sp, const char* ss_name);		// returns numerical index in linked list of subsystems
1682 extern int ship_get_subsys_index(ship *shipp, ship_subsys *subsys);
1683 extern float ship_get_subsystem_strength( ship *shipp, int type, bool skip_dying_check = false );
1684 extern ship_subsys *ship_get_subsys(const ship *shipp, const char *subsys_name);
1685 extern int ship_get_num_subsys(ship *shipp);
1686 extern ship_subsys *ship_get_closest_subsys_in_sight(ship *sp, int subsys_type, vec3d *attacker_pos);
1687 
1688 //WMC
1689 char *ship_subsys_get_name(ship_subsys *ss);
1690 bool ship_subsys_has_instance_name(ship_subsys *ss);
1691 void ship_subsys_set_name(ship_subsys* ss, const char* n_name);
1692 
1693 // subsys disruption
1694 extern int ship_subsys_disrupted(ship_subsys *ss);
1695 extern int ship_subsys_disrupted(ship *sp, int type);
1696 extern void ship_subsys_set_disrupted(ship_subsys *ss, int time);
1697 
1698 extern int	ship_do_rearm_frame( object *objp, float frametime );
1699 extern float ship_calculate_rearm_duration( object *objp );
1700 extern void	ship_wing_cleanup( int shipnum, wing *wingp );
1701 
1702 extern int ship_find_repair_ship( object *requester_obj, object **ship_we_found = NULL );
1703 extern void ship_close();	// called in game_shutdown() to free malloced memory
1704 
1705 
1706 extern void ship_assign_sound_all();
1707 extern void ship_assign_sound(ship *sp);
1708 
1709 extern void ship_clear_ship_type_counts();
1710 extern void ship_add_ship_type_count( int ship_info_index, int num );
1711 
1712 extern int ship_get_type(char* output, ship_info* sip);
1713 extern int ship_get_default_orders_accepted( ship_info *sip );
1714 extern int ship_query_general_type(int ship);
1715 extern int ship_class_query_general_type(int ship_class);
1716 extern int ship_query_general_type(ship *shipp);
1717 extern int ship_docking_valid(int docker, int dockee);
1718 extern int get_quadrant(vec3d *hit_pnt, object *shipobjp = NULL);	//	Return quadrant num of given hit point.
1719 
1720 int ship_secondary_bank_has_ammo(int shipnum);	// check if current secondary bank has ammo
1721 
1722 int ship_engine_ok_to_warp(ship *sp);		// check if ship has engine power to warp
1723 int ship_navigation_ok_to_warp(ship *sp);	// check if ship has navigation power to warp
1724 bool ship_can_warp_full_check(ship *sp);		// checks both the warp flags and ship_engine_ok_to_warp() and ship_navigation_ok_to_warp() --wookieejedi
1725 bool ship_can_bay_depart(ship *sp);			// checks to see if a ship has a departure location as a bay and if the mothership is present
1726 
1727 int ship_return_subsys_path_normal(ship *sp, ship_subsys *ss, vec3d *gsubpos, vec3d *norm);
1728 int ship_subsystem_in_sight(object* objp, ship_subsys* subsys, vec3d *eye_pos, vec3d* subsys_pos, int do_facing_check=1, float *dot_out=NULL, vec3d *vec_out=NULL);
1729 ship_subsys *ship_return_next_subsys(ship *shipp, int type, vec3d *attacker_pos);
1730 
1731 // defines and definition for function to get a random ship of a particular team (any ship,
1732 // any ship but player ships, or only players)
1733 #define SHIP_GET_ANY_SHIP				0
1734 #define SHIP_GET_NO_PLAYERS				1
1735 #define SHIP_GET_ONLY_PLAYERS			2
1736 #define SHIP_GET_UNSILENCED				3	// Karajorma - Returns no_players that can send builtin messages.
1737 
1738 
1739 extern int ship_get_random_team_ship(int team_mask, int flags = SHIP_GET_ANY_SHIP, float max_dist = 0.0f);
1740 extern int ship_get_random_player_wing_ship(int flags = SHIP_GET_ANY_SHIP, float max_dist = 0.0f, int persona_index = -1, int get_first = 0, int multi_team = -1);
1741 extern int ship_get_random_ship_in_wing(int wingnum, int flags = SHIP_GET_ANY_SHIP, float max_dist = 0.0f, int get_first = 0);
1742 
1743 // return ship index
1744 int ship_get_random_targetable_ship();
1745 
1746 extern int ship_get_by_signature(int signature);
1747 
1748 #ifndef NDEBUG
1749 extern int Ai_render_debug_flag;
1750 extern int Show_shield_mesh;
1751 extern int Ship_auto_repair;	// flag to indicate auto-repair of subsystem should occur
1752 #endif
1753 
1754 void ship_subsystem_delete(ship *shipp);
1755 float ship_quadrant_shield_strength(object *hit_objp, int quadrant_num);
1756 
1757 int ship_dumbfire_threat(ship *sp);
1758 int ship_lock_threat(ship *sp);
1759 
1760 int	bitmask_2_bitnum(int num);
1761 SCP_string ship_return_orders(ship *sp);
1762 char	*ship_return_time_to_goal(char *outbuf, ship *sp);
1763 int	ship_return_seconds_to_goal(ship *sp);
1764 
1765 void	ship_maybe_warn_player(ship *enemy_sp, float dist);
1766 void	ship_maybe_praise_player(ship *deader_sp);
1767 void	ship_maybe_praise_self(ship *deader_sp, ship *killer_sp);
1768 void	ship_maybe_ask_for_help(ship *sp);
1769 void	ship_scream(ship *sp);
1770 void	ship_maybe_scream(ship *sp);
1771 void	ship_maybe_tell_about_rearm(ship *sp);
1772 void	ship_maybe_tell_about_low_ammo(ship *sp);
1773 void	ship_maybe_lament();
1774 
1775 void ship_primary_changed(ship *sp);
1776 void ship_secondary_changed(ship *sp);
1777 
1778 // get the Ship_info flags for a given ship
1779 flagset<Ship::Info_Flags> ship_get_SIF(ship *shipp);
1780 flagset<Ship::Info_Flags> ship_get_SIF(int sh);
1781 
1782 // get the ship type info (objecttypes.tbl)
1783 ship_type_info *ship_get_type_info(object *objp);
1784 
1785 extern void ship_do_cargo_revealed( ship *shipp, int from_network = 0 );
1786 extern void ship_do_cargo_hidden( ship *shipp, int from_network = 0 );
1787 extern void ship_do_cap_subsys_cargo_revealed( ship *shipp, ship_subsys *subsys, int from_network = 0);
1788 extern void ship_do_cap_subsys_cargo_hidden( ship *shipp, ship_subsys *subsys, int from_network = 0);
1789 
1790 float ship_get_secondary_weapon_range(ship *shipp);
1791 
1792 // Goober5000
1793 int get_max_ammo_count_for_primary_bank(int ship_class, int bank, int ammo_type);
1794 
1795 int get_max_ammo_count_for_bank(int ship_class, int bank, int ammo_type);
1796 int get_max_ammo_count_for_turret_bank(ship_weapon *swp, int bank, int ammo_type);
1797 
1798 int is_support_allowed(object *objp, bool do_simple_check = false);
1799 
1800 // Given an object and a turret on that object, return the actual firing point of the gun
1801 // and its normal.   This uses the current turret angles.  We are keeping track of which
1802 // gun to fire next in the ship specific info for this turret subobject.  Use this info
1803 // to determine which position to fire from next.
1804 //	Stuffs:
1805 //		*gpos: absolute position of gun firing point
1806 //		*gvec: vector fro *gpos to *targetp
1807 void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos, vec3d *gvec, int use_angles, vec3d *targetp);
1808 
1809 //	Given an object and a turret on that object, return the global position and forward vector
1810 //	of the turret.   The gun normal is the unrotated gun normal, (the center of the FOV cone), not
1811 // the actual gun normal given using the current turret heading.  But it _is_ rotated into the model's orientation
1812 //	in global space.
1813 void ship_get_global_turret_info(const object *objp, const model_subsystem *tp, vec3d *gpos, vec3d *gvec);
1814 
1815 // return 1 if objp is in fov of the specified turret, tp.  Otherwise return 0.
1816 //	dist = distance from turret to center point of object
1817 bool object_in_turret_fov(object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos, float dist);
1818 
1819 // functions for testing fov.. returns true if fov test is passed.
1820 bool turret_std_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mod = 0);
1821 bool turret_adv_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mod = 0);
1822 bool turret_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mod = 0);
1823 
1824 // function for checking adjusted turret rof
1825 float get_adjusted_turret_rof(ship_subsys *ss);
1826 
1827 // forcible jettison cargo from a ship
1828 void object_jettison_cargo(object *objp, object *cargo_objp, float jettison_speed, bool jettison_new);
1829 
1830 // get damage done by exploding ship, takes into account mods for individual ship
1831 float ship_get_exp_damage(object* objp);
1832 
1833 // get outer radius of damage, takes into account mods for individual ship
1834 float ship_get_exp_outer_rad(object *ship_objp);
1835 
1836 // externed by Goober5000
1837 extern 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 );
1838 
1839 // determine turret status of a given subsystem, returns 0 for no turret, 1 for "fixed turret", 2 for "rotating" turret
1840 int ship_get_turret_type(ship_subsys *subsys);
1841 
1842 // get ship by object signature, returns OBJECT INDEX
1843 int ship_get_by_signature(int sig);
1844 
1845 // get the team of a reinforcement item
1846 int ship_get_reinforcement_team(int r_index);
1847 
1848 // page in bitmaps for all ships on a given level
1849 void ship_page_in();
1850 
1851 // Goober5000 - helper for above
1852 void ship_page_in_textures(int ship_index = -1);
1853 
1854 // fixer for above - taylor
1855 void ship_page_out_textures(int ship_index, bool release = false);
1856 
1857 // replaces a texture on a ship with a different texture
1858 void ship_replace_active_texture(int ship_index, const char* old_name, const char* new_name);
1859 
1860 // update artillery lock info
1861 void ship_update_artillery_lock();
1862 
1863 // checks if a world point is inside the extended bounding box of a ship
1864 int check_world_pt_in_expanded_ship_bbox(vec3d *world_pt, object *objp, float delta_box);
1865 
1866 // returns true if objp is ship and is tagged
1867 int ship_is_tagged(object *objp);
1868 
1869 // returns max normal speed of ship (overclocked / afterburned)
1870 float ship_get_max_speed(ship *shipp);
1871 
1872 // returns warpout speed of ship
1873 float ship_get_warpout_speed(object *objp, ship_info *sip = nullptr, float half_length = 0.0f, float warping_dist = 0.0f);
1874 
1875 // returns true if ship is beginning to speed up in warpout
1876 int ship_is_beginning_warpout_speedup(object *objp);
1877 
1878 // return the length of the ship class
1879 float ship_class_get_length(const ship_info *sip);
1880 
1881 // return the actual center of the ship class
1882 void ship_class_get_actual_center(const ship_info *sip, vec3d *center_pos);
1883 
1884 // Goober5000 - used by change-ai-class
1885 extern void ship_set_new_ai_class(ship *shipp, int new_ai_class);
1886 extern void ship_subsystem_set_new_ai_class(ship *shipp, const char *subsystem, int new_ai_class);
1887 
1888 // wing squad logos - Goober5000
1889 extern void wing_load_squad_bitmap(wing *w);
1890 
1891 // Goober5000 - needed by new hangar depart code
1892 extern bool ship_has_dock_bay(int shipnum);
1893 extern bool ship_useful_for_departure(int shipnum, int path_mask = 0);
1894 extern int ship_get_ship_for_departure(int team);
1895 
1896 // Goober5000
1897 extern bool ship_fighterbays_all_destroyed(ship *shipp);
1898 
1899 // Goober5000
1900 extern bool ship_subsys_takes_damage(ship_subsys *ss);
1901 
1902 // Goober5000 - handles submodel rotation, incorporating conditions such as gun barrels when firing
1903 extern void ship_do_submodel_rotation(ship *shipp, model_subsystem *psub, ship_subsys *pss);
1904 
1905 // Goober5000 - shortcut hud stuff
1906 extern int ship_has_energy_weapons(ship *shipp);
1907 extern int ship_has_engine_power(ship *shipp);
1908 
1909 // Swifty - Cockpit displays
1910 void ship_init_cockpit_displays(ship *shipp);
1911 void ship_clear_cockpit_displays();
1912 int ship_start_render_cockpit_display(size_t cockpit_display_num);
1913 void ship_end_render_cockpit_display(size_t cockpit_display_num);
1914 
1915 // Goober5000
1916 int ship_starting_wing_lookup(const char *wing_name);
1917 int ship_squadron_wing_lookup(const char *wing_name);
1918 int ship_tvt_wing_lookup(const char *wing_name);
1919 
1920 // Goober5000
1921 int ship_class_compare(int ship_class_1, int ship_class_2);
1922 
1923 int armor_type_get_idx(const char* name);
1924 
1925 void armor_init();
1926 
1927 // Sushi - Path metadata
1928 void init_path_metadata(path_metadata& metadata);
1929 
1930 
1931 typedef struct ship_effect {
1932 	char name[NAME_LENGTH];
1933 	bool disables_rendering;
1934 	bool invert_timer;
1935 	int shader_effect;
1936 } ship_effect;
1937 
1938 extern SCP_vector<ship_effect> Ship_effects;
1939 
1940 /**
1941  *  @brief Returns a ship-specific sound index
1942  *
1943  *  @param objp An object pointer. Has to be of type OBJ_SHIP
1944  *  @param id A sound id as defined in gamsesnd.h. If the given id is unknown then the game_snd with the id as index is returned.
1945  *
1946  *  @return An index into the Snds vector, if the specified index could not be found then the id itself will be returned
1947  */
1948 gamesnd_id ship_get_sound(object *objp, GameSounds id);
1949 
1950 /**
1951  *  @brief Specifies if a ship has a custom sound for the specified id
1952  *
1953  *  @param objp An object pointer. Has to be of type OBJ_SHIP
1954  *  @param id A sound id as defined in gamsesnd.h
1955  *
1956  *  @return True if this object has the specified sound, false otherwise
1957  */
1958 bool ship_has_sound(object *objp, GameSounds id);
1959 
1960 /**
1961  * @brief Returns the index of the default player ship
1962  *
1963  * @return An index into Ship_info[], location of the default player ship.
1964  */
1965 int get_default_player_ship_index();
1966 
1967 /**
1968  * Given a ship with bounding box and a point, find the closest point on the bbox
1969  *
1970  * @param ship_obj Object that has the bounding box (should be a ship)
1971  * @param start World position of the point being compared
1972  * @param box_pt OUTPUT PARAMETER: closest point on the bbox to start
1973  *
1974  * @return point is inside bbox, TRUE/1
1975  * @return point is outside bbox, FALSE/0
1976  */
1977 int get_nearest_bbox_point(object *ship_obj, vec3d *start, vec3d *box_pt);
1978 
1979 extern flagset<Ship::Ship_Flags> Ignore_List;
should_be_ignored(ship * shipp)1980 inline bool should_be_ignored(ship* shipp) {
1981     return (shipp->flags & Ignore_List).any_set();
1982 }
1983 
1984 extern void set_default_ignore_list();
1985 
1986 extern void toggle_ignore_list_flag(Ship::Ship_Flags flag);
1987 
1988 ship_subsys* ship_get_subsys_for_submodel(ship* shipp, int submodel);
1989 
1990 // Clears a lock_info struct with defaults
1991 void ship_clear_lock(lock_info *slot);
1992 
1993 // queues up locks
1994 void ship_queue_missile_locks(ship *shipp);
1995 
1996 // snoops missile locks to see if any are ready to fire.
1997 bool ship_lock_present(ship *shipp);
1998 
1999 #endif
2000