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 _WEAPON_H
13 #define _WEAPON_H
14 
15 #include "globalincs/globals.h"
16 #include "globalincs/systemvars.h"
17 
18 #include "actions/Program.h"
19 #include "decals/decals.h"
20 #include "gamesnd/gamesnd.h"
21 #include "graphics/2d.h"
22 #include "graphics/generic.h"
23 #include "model/model.h"
24 #include "particle/ParticleManager.h"
25 #include "weapon/shockwave.h"
26 #include "weapon/swarm.h"
27 #include "weapon/trails.h"
28 #include "weapon/weapon_flags.h"
29 
30 class object;
31 class ship_subsys;
32 
33 #define	WP_UNUSED			-1
34 #define	WP_LASER			0		// PLEASE NOTE that this flag specifies ballistic primaries as well - Goober5000
35 #define	WP_MISSILE			1
36 #define	WP_BEAM				2
37 extern const char *Weapon_subtype_names[];
38 extern int Num_weapon_subtypes;
39 
40 #define WRT_NONE	-1
41 #define	WRT_LASER	1
42 #define	WRT_POF		2
43 
44 // constants for weapon lock acquire methods
45 #define WLOCK_PIXEL		0
46 #define WLOCK_TIMER		1
47 
48 // constants for weapon lock restrictions
49 #define LR_CURRENT_TARGET				0		// Only lock current target and subsystem
50 #define LR_CURRENT_TARGET_SUBSYS		1		//
51 #define LR_ANY_TARGETS					2
52 
53 //particle names go here -nuke
54 #define PSPEW_NONE		-1			//used to disable a spew, useful for xmts
55 #define PSPEW_DEFAULT	0			//std fs2 pspew
56 #define PSPEW_HELIX		1			//q2 style railgun trail
57 #define PSPEW_SPARKLER	2			//random particles in every direction, can be sperical or ovoid
58 #define PSPEW_RING		3			//outward expanding ring
59 #define PSPEW_PLUME		4			//spewers arrayed within a radius for thruster style effects, may converge or scatter
60 
61 #define MAX_PARTICLE_SPEWERS	4	//i figure 4 spewers should be enough for now -nuke
62 
63 // scale factor for supercaps taking damage from weapons which are not "supercap" weapons
64 #define SUPERCAP_DAMAGE_SCALE			0.25f
65 
66 // default amount of time to wait after firing before a remote detonated missile can be detonated
67 #define DEFAULT_REMOTE_DETONATE_TRIGGER_WAIT  0.5f
68 
69 // default value weapon max range is set to if there's not a tabled range value.
70 #define WEAPON_DEFAULT_TABLED_MAX_RANGE 999999999.9f
71 
72 #define MAX_SPAWN_TYPES_PER_WEAPON 5
73 
74 enum class WeaponState : uint32_t
75 {
76 	INVALID,
77 
78 	// States for laser weapons
79 	NORMAL, //!< For laser weapons that have only one state
80 
81 	// Missile states following
82 	FREEFLIGHT, //!< The initial flight state where the missile is "unpowered"
83 	IGNITION, //!< The moment when the missile comes out of free flight
84 	HOMED_FLIGHT, //!< The missile is homing in on its target
85 	UNHOMED_FLIGHT, //!< The missile does not currently target an object
86 };
87 struct WeaponStateHash {
operatorWeaponStateHash88 	size_t operator()(const WeaponState& state) const {
89 		return static_cast<size_t>(state);
90 	}
91 };
92 
93 typedef struct weapon {
94 	int		weapon_info_index;			// index into weapon_info array
95 	int		objnum;							// object number for this weapon
96 	int		model_instance_num;				// model instance number, if we have any intrinsic-rotating submodels
97 	int		team;								// The team of the ship that fired this
98 	int		species;							// The species of the ship that fired thisz
99 	float		lifeleft;						// life left on this weapon
100 	vec3d	start_pos;
101 
102 	int		target_num;						//	Object index of target
103 	int		target_sig;						//	So we know if the target is the same one we've been tracking
104 	fix		creation_time;					//	time at which created, stuffed Missiontime
105 	flagset<Weapon::Weapon_Flags> weapon_flags;					//	bit flags defining behavior, see WF_xxxx
106 	object*	homing_object;					//	object this weapon is homing on.
107 	ship_subsys*	homing_subsys;			// subsystem this weapon is homing on
108 	vec3d	homing_pos;						// world position missile is homing on
109 	std::unique_ptr<swarm_info>		swarm_info_ptr;	// index into swarm missile info, -1 if not WIF_SWARM
110 	int		missile_list_index;			// index for missiles into Missile_obj_list, -1 weapon not missile
111 	trail		*trail_ptr;						// NULL if no trail, otherwise a pointer to its trail
112 	ship_subsys *turret_subsys;			// points to turret that fired weapon, otherwise NULL
113 	int		group_id;						// Which group this is in.
114 	float	det_range;					//How far from start_pos it blows up
115 
116 	// Stuff for thruster glows
117 	int		thruster_bitmap;					// What frame the current thruster bitmap is at for this weapon
118 	float		thruster_frame;					// Used to keep track of which frame the animation should be on.
119 	int		thruster_glow_bitmap;			// What frame the current thruster engine glow bitmap is at for this weapon
120 	float		thruster_glow_frame;				// Used to keep track of which frame the engine glow animation should be on.
121 	float		thruster_glow_noise;				// Noise for current frame
122 
123 	// laser stuff
124 	float	laser_bitmap_frame;				// used to keep track of which frame the animation should be on
125 	float	laser_glow_bitmap_frame;		// used to keep track of which frame the glow animation should be on
126 
127 	int		pick_big_attack_point_timestamp;	//	Timestamp at which to pick a new point to attack.
128 	vec3d	big_attack_point;				//	Target-relative location of attack point.
129 
130 	SCP_vector<int>* cmeasure_ignore_list;
131 	int		cmeasure_timer;
132 
133 	// corkscrew info (taken out for now)
134 	short	cscrew_index;						// corkscrew info index
135 
136 	// particle spew info
137 	int		particle_spew_time[MAX_PARTICLE_SPEWERS];			// time to spew next bunch of particles
138 	float	particle_spew_rand;				// per weapon randomness value used by some particle spew types -nuke
139 
140 	// flak info
141 	short flak_index;							// flak info index
142 
143 	//local ssm stuff
144 	fix lssm_warpout_time;		//time at which the missile warps out
145 	fix lssm_warpin_time;		//time at which the missile warps back in
146 	int lssm_stage;				//what stage its in 1=just launched, 2=warping out. 3=warped out, 4=warping back in, 5=terminal dive
147 	int lssm_warp_idx;			//warphole index
148 	float lssm_warp_time;		//length of time warphole stays open
149 	float lssm_warp_pct;		//how much of the warphole's life should be dedicated to stage 2
150 	vec3d lssm_target_pos;
151 
152 	// weapon transparency info
153 	ubyte alpha_backward;		// 1 = move in reverse (ascending in value)
154 	float alpha_current;		// the current alpha value
155 
156 	float weapon_max_vel;		// might just as well store the data here
157 	float launch_speed;			// the initial forward speed (can vary due to additive velocity or acceleration)
158 								// currently only gets set when weapon_info->acceleration_time is used
159 
160 	int next_spawn_time[MAX_SPAWN_TYPES_PER_WEAPON];		// used for continuous child spawn
161 
162 	mc_info* collisionInfo; // The last collision of this weapon or NULL if it had none
163 
164 	sound_handle hud_in_flight_snd_sig; // Signature of the sound played while the weapon is in flight
165 
166 	WeaponState weapon_state; // The current state of the weapon
167 
168 	float beam_per_shot_rot; // for type 5 beams
169 } weapon;
170 
171 
172 // info specific to beam weapons
173 typedef struct beam_weapon_section_info {
174 	float width;							// width of the section
175 	float flicker;							// how much it flickers (0.0 to 1.0)
176 	float z_add;							// is this necessary?
177 	float tile_factor;						// texture tile factor -Bobboau
178 	int tile_type;							// is this beam tiled by it's length, or not
179 	float translation;						// makes the beam texture move -Bobboau
180 	generic_anim texture;					// texture anim/bitmap
181 } beam_weapon_section_info;
182 
183 enum class Type5BeamRotAxis {
184 	STARTPOS_OFFSET,
185 	ENDPOS_OFFSET,
186 	STARTPOS_NO_OFFSET,
187 	ENDPOS_NO_OFFSET,
188 	CENTER,
189 	UNSPECIFIED
190 };
191 
192 enum class Type5BeamPos {
193 	RANDOM_OUTSIDE,
194 	RANDOM_INSIDE,
195 	CENTER,
196 	SAME_RANDOM
197 };
198 
199 typedef struct type5_beam_info {
200 	bool no_translate;                           // true if the end pos parameters were left unspecified
201 	Type5BeamPos start_pos;						 // whether it starts from the center or a type 0 or 1 beam kind of random
202 	Type5BeamPos end_pos;						 // same as above but but with an extra 'same random as start' option
203 	vec3d start_pos_offset;                      // position simply added to start pos (possibly manipulated by the bools below)
204 	vec3d end_pos_offset;                        // position simply added to end pos (possibly manipulated by the bools below)
205 	vec3d start_pos_rand;                        // same as above but a randomly chosen between defined value for each axis and its negative
206 	vec3d end_pos_rand;
207 	bool target_orient_positions;                // if true, offsets are oriented relative to the target, else the shooter's pov
208 	bool target_scale_positions;                 // if true, offsets are scaled by target radius, else its a fixed span from the shooters pov
209 	                                             // regardless of distance
210 	float continuous_rot;                        // radians per sec rotation over beam lifetime
211 	Type5BeamRotAxis continuous_rot_axis;		 // axis around which do continuous rotation
212 	SCP_vector<float> burst_rot_pattern;         // radians to rotate for each beam in a burst, will also make spawned and ssb beams fire
213 	                                             // this many beams simultaneously with the defined rotations
214 	Type5BeamRotAxis burst_rot_axis;			 // axis around which to do burst rotation
215 	float per_burst_rot;                         // radians to rotate for each burst, or each shot if no burst
216 	Type5BeamRotAxis per_burst_rot_axis;		 // axis around which to do per burst rotation
217 } type5_beam_info;
218 
219 typedef struct beam_weapon_info {
220 	int beam_type;						// beam type
221 	float beam_life;					// how long it lasts
222 	int beam_warmup;					// how long it takes to warmup (in ms)
223 	int beam_warmdown;					// how long it takes to warmdown (in ms)
224 	float beam_muzzle_radius;			// muzzle glow radius
225 	int beam_particle_count;			// beam spew particle count
226 	float beam_particle_radius;			// radius of beam particles
227 	float beam_particle_angle;			// angle of beam particle spew cone
228 	generic_anim beam_particle_ani;		// particle_ani
229 	float beam_iff_miss_factor[MAX_IFFS][NUM_SKILL_LEVELS];	// magic # which makes beams miss more. by parent iff and player skill level
230 	gamesnd_id beam_loop_sound;				// looping beam sound
231 	gamesnd_id beam_warmup_sound;				// warmup sound
232 	gamesnd_id beam_warmdown_sound;			// warmdown sound
233 	int beam_num_sections;				// the # of visible "sections" on the beam
234 	generic_anim beam_glow;				// muzzle glow bitmap
235 	float glow_length;					// (DahBlount) determines the length the muzzle glow when using a directional glow
236 	bool directional_glow;				// (DahBlount) makes the muzzle glow render to a poly that is oriented along the direction of fire
237 	int beam_shots;						// # of shots the beam takes
238 	float beam_shrink_factor;			// what percentage of total beam lifetime when the beam starts shrinking
239 	float beam_shrink_pct;				// what percent/second the beam shrinks at
240 	float beam_initial_width;		    // what percentage of total beam width the beam has initially
241 	float beam_grow_factor;			    // what percentage of total beam lifetime when the beam starts growing
242 	float beam_grow_pct;				// what percent/second the beam grows at
243 	beam_weapon_section_info sections[MAX_BEAM_SECTIONS];	// info on the visible sections of the beam
244 	float range;						// how far it will shoot-Bobboau
245 	float damage_threshold;				// point at wich damage will start being atenuated from 0.0 to 1.0
246 	float beam_width;					// width of the beam (for certain collision checks)
247 	flagset<Weapon::Beam_Info_Flags> flags;
248 	type5_beam_info t5info;              // type 5 beams only
249 } beam_weapon_info;
250 
251 typedef struct particle_spew_info {	//this will be used for multi spews
252 	// particle spew stuff
253 	int particle_spew_type;			//added pspew type field -nuke
254 	int particle_spew_count;
255 	int particle_spew_time;
256 	float particle_spew_vel;
257 	float particle_spew_radius;
258 	float particle_spew_lifetime;
259 	float particle_spew_scale;
260 	float particle_spew_z_scale;	//length value for some effects -nuke
261 	float particle_spew_rotation_rate;	//rotation rate for some particle effects -nuke
262 	vec3d particle_spew_offset;			//offsets and normals, yay!
263 	vec3d particle_spew_velocity;
264 	generic_anim particle_spew_anim;
265 } particle_spew_info;
266 
267 typedef struct spawn_weapon_info
268 {
269 	short	spawn_type;							//	Type of weapon to spawn when detonated.
270 	short	spawn_count;						//	Number of weapons of spawn_type to spawn.
271 	float	spawn_angle;						//  Angle to spawn the child weapons in.  default is 180
272 	float	spawn_min_angle;					//  Angle of spawning 'deadzone' inside spawn angle. Default 0.
273 	float	spawn_interval;						//  How often to do continuous spawn, negative is no continuous spawn
274 	float   spawn_interval_delay;               //  A delay before starting continuous spawn
275 	float   spawn_chance;						//  Liklihood of spawning on every spawn interval
276 	particle::ParticleEffectHandle spawn_effect; // Effect for continuous spawnings
277 } spawn_weapon_info;
278 
279 // use this to extend a beam to "infinity"
280 #define BEAM_FAR_LENGTH				30000.0f
281 
282 
283 extern weapon Weapons[MAX_WEAPONS];
284 
285 #define WEAPON_TITLE_LEN			48
286 
287 enum InFlightSoundType
288 {
289 	TARGETED,
290 	UNTARGETED,
291 	ALWAYS
292 };
293 
294 #define MAX_SUBSTITUTION_PATTERNS	10
295 
296 enum class LockRestrictionType
297 {
298 	TYPE, CLASS, SPECIES, IFF
299 };
300 
301 typedef std::pair<LockRestrictionType, int> lock_restriction;
302 
303 enum class HomingAcquisitionType {
304 	CLOSEST,
305 	RANDOM,
306 };
307 
308 struct weapon_info
309 {
310 	char	name[NAME_LENGTH];				// name of this weapon
311 	char	display_name[NAME_LENGTH];		// display name of this weapon
312 	char	title[WEAPON_TITLE_LEN];		// official title of weapon (used by tooltips)
313 	char	*desc;								// weapon's description (used by tooltips)
314 
315 	char	pofbitmap_name[MAX_FILENAME_LEN];	// Name of the pof representing this if POF, or bitmap filename if bitmap
316 	int		model_num;							// modelnum of weapon -- -1 if no model
317 	char	external_model_name[MAX_FILENAME_LEN];					//the model rendered on the weapon points of a ship
318 	int		external_model_num;					//the model rendered on the weapon points of a ship
319 
320 	char	*tech_desc;								// weapon's description (in tech database)
321 	char	tech_anim_filename[MAX_FILENAME_LEN];	// weapon's tech room animation
322 	char	tech_title[NAME_LENGTH];			// weapon's name (in tech database)
323 	char	tech_model[MAX_FILENAME_LEN];		//Image to display in the techroom (TODO) or the weapon selection screen if the ANI isn't specified/missing
324 
325 	int		hud_target_lod;						// LOD to use when rendering weapon model to the hud targetbox
326 	int		num_detail_levels;					// number of LODs defined in table (optional)
327 	int		detail_distance[MAX_MODEL_DETAIL_LEVELS]; // LOD distances define in table (optional)
328 	int		subtype;								// one of the WP_* macros above
329 	int		render_type;						//	rendering method, laser, pof, avi
330 
331 	vec3d	closeup_pos;						// position for camera to set an offset for viewing the weapon model
332 	float	closeup_zoom;						// zoom when using weapon model in closeup view in loadout selection
333 
334 	char hud_filename[MAX_FILENAME_LEN];			//Name of image to display on HUD in place of text
335 	int hud_image_index;					//teh index of the image
336 
337 	generic_anim laser_bitmap;				// bitmap for a laser
338 	generic_anim laser_glow_bitmap;			// optional laser glow bitmap
339 
340 	float laser_length;
341 	color	laser_color_1;						// for cycling between glow colors
342 	color	laser_color_2;						// for cycling between glow colors
343 	float	laser_head_radius, laser_tail_radius;
344 	float	collision_radius_override;          // overrides the radius for the purposes of collision
345 
346 	float	max_speed;							// max speed of the weapon
347 	float	acceleration_time;					// how many seconds to reach max speed (secondaries only)
348 	float	vel_inherit_amount;					// how much of the parent ship's velocity is inherited (0.0..1.0)
349 	float	free_flight_time;
350 	float	free_flight_speed_factor;
351 	float mass;									// mass of the weapon
352 	float fire_wait;							// fire rate -- amount of time before you can refire the weapon
353 	float max_delay;							// max time to delay a shot (DahBlount)
354 	float min_delay;							// min time to delay a shot	(DahBlount)
355 
356 	float	damage;								//	damage of weapon (for missile, damage within inner radius)
357 	float	damage_time;						// point in the lifetime of the weapon at which damage starts to attenuate. This applies to non-beam primaries. (DahBlount)
358 	float	atten_damage;							// The damage to attenuate to. (DahBlount)
359 	float	damage_incidence_max;				// dmg multipler when weapon hits dead-on (perpindicular)
360 	float	damage_incidence_min;				// dmg multipler when weapon hits glancing (parallel)
361 
362 	shockwave_create_info shockwave;
363 	shockwave_create_info dinky_shockwave;
364 
365 	fix arm_time;
366 	float arm_dist;
367 	float arm_radius;
368 	float det_range;
369 	float det_radius;					//How far from target or target subsystem it blows up
370 	float flak_detonation_accuracy;		//How far away from a target a flak shell will blow up. Standard is 65.0f
371 	float flak_targeting_accuracy;		//Determines the amount of jitter applied to flak targeting. USE WITH CAUTION!
372 	float untargeted_flak_range_penalty; //Untargeted flak shells detonate after travelling max range - this parameter. Default 20.0f
373 
374 	float	armor_factor, shield_factor, subsystem_factor;	//	in 0.0..2.0, scale of damage done to type of thing
375 
376 	float life_min;
377 	float life_max;
378 	float max_lifetime ;						// How long this weapon will actually live for
379 	float	lifetime;						// How long the AI thinks this thing lives (used for distance calculations etc)
380 
381 	float energy_consumed;					// Energy used up when weapon is fired
382 
383 	flagset<Weapon::Info_Flags>	wi_flags;							//	bit flags defining behavior, see WIF_xxxx
384 
385 	float turn_time;
386 	float turn_accel_time;
387 	float	cargo_size;							// cargo space taken up by individual weapon (missiles only)
388 	float rearm_rate;							// rate per second at which secondary weapons are loaded during rearming
389 	int		reloaded_per_batch;				    // number of munitions rearmed per batch
390 	float	weapon_range;						// max range weapon can be effectively fired.  (May be less than life * speed)
391 	float	optimum_range;						// causes ai fighters to prefer this distance when attacking with the weapon
392 	float weapon_min_range;           // *Minimum weapon range, default is 0 -Et1
393 
394 	bool pierce_objects;
395 	bool spawn_children_on_pierce;
396 
397     // spawn weapons
398     int num_spawn_weapons_defined;
399     int maximum_children_spawned;		// An upper bound for the total number of spawned children, used by multi
400     spawn_weapon_info spawn_info[MAX_SPAWN_TYPES_PER_WEAPON];
401 
402 	// swarm count
403 	short swarm_count;						// how many swarm missiles are fired for this weapon
404 	int SwarmWait;                  // *Swarm firewait, default is 150  -Et1
405 
406 	int target_restrict;
407 	bool multi_lock;
408 	int max_seeking;						// how many seekers can be active at a time if multilock is enabled. A value of one will lock stuff up one by one.
409 	int max_seekers_per_target;			// how many seekers can be attached to a target.
410 
411 	SCP_vector<lock_restriction> ship_restrict;                     // list of pairs of types of restrictions, and the specific restriction of that type
412 	SCP_vector<std::pair<LockRestrictionType, SCP_string>> ship_restrict_strings;    // the above but the specific restrictions are the parsed strings (instead of looked up indicies)
413 
414 	bool trigger_lock;						// Trigger must be held down and released to lock and fire.
415 	bool launch_reset_locks;				// Lock indicators reset after firing
416 
417 	HomingAcquisitionType auto_target_method;
418 
419 	//	Specific to ASPECT homing missiles.
420 	int acquire_method;
421 	float	min_lock_time;						// minimum time (in seconds) to achieve lock
422 	int	lock_pixels_per_sec;				// pixels/sec moved while locking
423 	int	catchup_pixels_per_sec;			// pixels/sec moved while catching-up for a lock
424 	int	catchup_pixel_penalty;			// number of extra pixels to move while locking as a penalty for catching up for a lock
425 	float lock_fov;
426 
427 	//	Specific to HEAT homing missiles.
428 	float	fov;
429 
430 	// Seeker strength - for countermeasures overhaul.
431 	float seeker_strength;
432 
433 	gamesnd_id pre_launch_snd;
434 	int	pre_launch_snd_min_interval;	//Minimum interval in ms between the last time the pre-launch sound was played and the next time it can play, as a limiter in case the player is pumping the trigger
435 	gamesnd_id	launch_snd;
436 	gamesnd_id	impact_snd;
437 	gamesnd_id disarmed_impact_snd;
438 	gamesnd_id	flyby_snd;							//	whizz-by sound, transmitted through weapon's portable atmosphere.
439 	gamesnd_id	ambient_snd;
440 
441 	gamesnd_id hud_tracking_snd; // Sound played when the player is tracking a target with this weapon
442 	gamesnd_id hud_locked_snd; // Sound played when the player is locked onto a target with this weapon
443 	gamesnd_id hud_in_flight_snd; // Sound played while the player has this weapon in flight
444 	InFlightSoundType in_flight_play_type; // The status when the sound should be played
445 
446 	// Specific to weapons with TRAILS:
447 	trail_info tr_info;
448 
449 	char	icon_filename[MAX_FILENAME_LEN];	// filename for icon that is displayed in weapon selection
450 	char	anim_filename[MAX_FILENAME_LEN];	// filename for animation that plays in weapon selection
451 	int 	selection_effect;
452 
453 	float shield_impact_explosion_radius;
454 
455 	particle::ParticleEffectHandle impact_weapon_expl_effect; // Impact particle effect
456 	particle::ParticleEffectHandle dinky_impact_weapon_expl_effect; // Dinky impact particle effect
457 	particle::ParticleEffectHandle flash_impact_weapon_expl_effect;
458 
459 	particle::ParticleEffectHandle piercing_impact_effect;
460 	particle::ParticleEffectHandle piercing_impact_secondary_effect;
461 
462 	// Particle effect for the various states, WeaponState::NORMAL is the state for the whole lifetime, even for missiles
463 	SCP_unordered_map<WeaponState, particle::ParticleEffectHandle, WeaponStateHash> state_effects;
464 
465 	// EMP effect
466 	float emp_intensity;					// intensity of the EMP effect
467 	float emp_time;						// time of the EMP effect
468 
469 	// Recoil effect
470 	float recoil_modifier;
471 
472 	// Energy suck effect
473 	float weapon_reduce;					// how much energy removed from weapons systems
474 	float afterburner_reduce;			// how much energy removed from weapons systems
475 
476 	// tag stuff
477 	float	tag_time;						// how long the tag lasts
478 	int tag_level;							// tag level (1 - 3)
479 
480 	// muzzle flash
481 	int muzzle_flash;						// muzzle flash stuff
482 
483 	float field_of_fire;			//cone the weapon will fire in, 0 is strait all the time-Bobboau
484 	float fof_spread_rate;			//How quickly the FOF will spread for each shot (primary weapons only, this doesn't really make sense for turrets)
485 	float fof_reset_rate;			//How quickly the FOF spread will reset over time (primary weapons only, this doesn't really make sense for turrets)
486 	float max_fof_spread;			//The maximum fof increase that the shots can spread to
487 	int	  shots;					//the number of shots that will be fired at a time,
488 									//only realy usefull when used with FOF to make a shot gun effect
489 									//now also used for weapon point cycleing
490 
491 	// Corkscrew info - phreak 11/9/02
492 	int cs_num_fired;
493 	float cs_radius;
494 	float cs_twist;
495 	int cs_crotate;
496 	int cs_delay;
497 
498 	//electronics info - phreak 5/3/03
499 	int elec_time;				//how long it lasts, in milliseconds
500 	float elec_eng_mult;		//multiplier on engine subsystem
501 	float elec_weap_mult;		//multiplier on weapon subsystem and turrets
502 	float elec_beam_mult;		//used instead of elec_weap_mult if turret is a beam turret
503 	float elec_sensors_mult;	//multiplier on sensors and awacs
504 	int elec_randomness;		//disruption time lasts + or - this value from whats calculated.  time in milliseconds
505 	int elec_use_new_style;		//use new style electronics parameters
506 
507 	// SSM
508 	int SSM_index;							// wich entry in the SSM,tbl it uses -Bobboau
509 
510 	//local ssm info
511 	int lssm_warpout_delay;			//delay between launch and warpout (ms)
512 	int lssm_warpin_delay;			//delay between warpout and warpin (ms)
513 	float lssm_stage5_vel;			//velocity during final stage
514 	float lssm_warpin_radius;
515 	float lssm_lock_range;
516 	int lssm_warpeffect;		//Which fireballtype is used for the warp effect
517 
518 	// Beam weapon effect
519 	beam_weapon_info	b_info;			// this must be valid if the weapon is a beam weapon WIF_BEAM or WIF_BEAM_SMALL
520 
521 	// now using new particle spew struct -nuke
522 	particle_spew_info particle_spewers[MAX_PARTICLE_SPEWERS];
523 
524 	// Countermeasure information
525 	float cm_aspect_effectiveness;
526 	float cm_heat_effectiveness;
527 	float cm_effective_rad;
528 	float cm_detonation_rad;
529 	bool  cm_kill_single;       // should the countermeasure kill just the single decoyed missile within CMEASURE_DETONATE_DISTANCE?
530 	int   cmeasure_timer_interval;	// how many milliseconds between pulses
531 	int cmeasure_firewait;						// delay in milliseconds between countermeasure firing --wookieejedi
532 	bool cmeasure_use_firewait;					// if set to true, then countermeasure will use specified firewait instead of default --wookieejedi
533 	int cmeasure_failure_delay_multiplier_ai;	// multiplier for firewait between failed countermeasure launches, next launch try = this value * firewait  --wookieejedi
534 	int cmeasure_sucess_delay_multiplier_ai;	// multiplier for firewait between successful countermeasure launches, next launch try = this value * firewait  --wookieejedi
535 
536 	float weapon_submodel_rotate_accell;
537 	float weapon_submodel_rotate_vel;
538 
539 	int damage_type_idx;
540 	int damage_type_idx_sav;	// stored value from table used to reset damage_type_idx
541 
542 	int armor_type_idx;	// Weapon armor type
543 
544 
545 	// transparency/alpha info
546 	float alpha_max;			// maximum alpha value to use
547 	float alpha_min;			// minimum alpha value to use
548 	float alpha_cycle;			// cycle between max and min by this much each frame
549 
550 	int weapon_hitpoints;
551 
552 	int	burst_shots;	// always 1 less than the actual burst length; 0 = no burst, 1 = two-shot burst, 2 = 3-shot, etc
553 	float burst_delay;
554 	flagset<Weapon::Burst_Flags> burst_flags;
555 
556 	// Thruster effects
557 	generic_anim	thruster_flame;
558 	generic_anim	thruster_glow;
559 	float			thruster_glow_factor;
560 
561 	float			target_lead_scaler;
562 	int				num_targeting_priorities;
563 	int				targeting_priorities[32];
564 
565 	// Optional weapon failures
566 	float failure_rate;
567 	SCP_string failure_sub_name;
568 	int failure_sub;
569 
570 	// the optional pattern of weapons that this weapon will fire
571 	size_t			num_substitution_patterns;
572 	int				weapon_substitution_pattern[MAX_SUBSTITUTION_PATTERNS]; //weapon_indexes
573 	char			weapon_substitution_pattern_names[MAX_SUBSTITUTION_PATTERNS][NAME_LENGTH]; // weapon names so that we can generate the indexs after sort
574 
575 	int			score; //Optional score for destroying the weapon
576 
577 	decals::creation_info impact_decal;
578 
579 	actions::ProgramSet on_create_program;
580 
581 public:
582 	weapon_info();
583 
is_homingweapon_info584     inline bool is_homing()        { return wi_flags[Weapon::Info_Flags::Homing_heat, Weapon::Info_Flags::Homing_aspect, Weapon::Info_Flags::Homing_javelin]; }
is_locked_homingweapon_info585     inline bool is_locked_homing() { return wi_flags[Weapon::Info_Flags::Homing_aspect, Weapon::Info_Flags::Homing_javelin]; }
hurts_big_shipsweapon_info586     inline bool hurts_big_ships()  { return wi_flags[Weapon::Info_Flags::Bomb, Weapon::Info_Flags::Beam, Weapon::Info_Flags::Huge, Weapon::Info_Flags::Big_only]; }
is_interceptableweapon_info587     inline bool is_interceptable() { return wi_flags[Weapon::Info_Flags::Fighter_Interceptable, Weapon::Info_Flags::Turret_Interceptable]; }
588 
589 	const char* get_display_name() const;
590 	bool has_display_name() const;
591 
592 	void reset();
593 };
594 
595 extern flag_def_list_new<Weapon::Info_Flags> Weapon_Info_Flags[];
596 extern const size_t num_weapon_info_flags;
597 
598 // Data structure to track the active missiles
599 typedef struct missile_obj {
600 	missile_obj *next, *prev;
601 	int			flags, objnum;
602 } missile_obj;
603 extern missile_obj Missile_obj_list;
604 
605 // WEAPON EXPLOSION INFO
606 #define MAX_WEAPON_EXPL_LOD						4
607 
608 typedef struct weapon_expl_lod {
609 	char	filename[MAX_FILENAME_LEN];
610 	int	bitmap_id;
611 	int	num_frames;
612 	int	fps;
613 
weapon_expl_lodweapon_expl_lod614 	weapon_expl_lod( )
615 		: bitmap_id( -1 ), num_frames( 0 ), fps( 0 )
616 	{
617 		filename[ 0 ] = 0;
618 	}
619 } weapon_expl_lod;
620 
621 typedef struct weapon_expl_info	{
622 	int					lod_count;
623 	weapon_expl_lod		lod[MAX_WEAPON_EXPL_LOD];
624 } weapon_expl_info;
625 
626 class weapon_explosions
627 {
628 private:
629 	SCP_vector<weapon_expl_info> ExplosionInfo;
630 	int GetIndex(char *filename);
631 
632 public:
633 	weapon_explosions();
634 
635 	int Load(char *filename = NULL, int specified_lods = MAX_WEAPON_EXPL_LOD);
636 	int GetAnim(int weapon_expl_index, vec3d *pos, float size);
637 	void PageIn(int idx);
638 };
639 
640 extern weapon_explosions Weapon_explosions;
641 
642 extern SCP_vector<weapon_info> Weapon_info;
643 
644 extern int Num_weapons;
645 extern int First_secondary_index;
646 extern int Default_cmeasure_index;
647 
648 extern int Num_player_weapon_precedence;				// Number of weapon types in Player_weapon_precedence
649 extern int Player_weapon_precedence[MAX_WEAPON_TYPES];	// Array of weapon types, precedence list for player weapon selection
650 
651 #define WEAPON_INDEX(wp)			(int)(wp-Weapons)
652 
653 
654 int weapon_info_lookup(const char *name);
655 int weapon_info_get_index(weapon_info *wip);
656 
weapon_info_size()657 inline int weapon_info_size()
658 {
659 	return static_cast<int>(Weapon_info.size());
660 }
661 
662 void weapon_init();					// called at game startup
663 void weapon_close();				// called at game shutdown
664 void weapon_level_init();			// called before the start of each level
665 void weapon_render(object* obj, model_draw_list *scene);
666 void weapon_delete( object * obj );
667 void weapon_process_pre( object *obj, float frame_time);
668 void weapon_process_post( object *obj, float frame_time);
669 
670 //Call before weapons_page_in to mark a weapon as used
671 void weapon_mark_as_used(int weapon_id);
672 
673 // Helper functions for l_Weaponclass.isWeaponUsed
674 bool weapon_page_in(int weapon_type);
675 bool weapon_used(int weapon_type);
676 
677 // Group_id:  If you should quad lasers, they should all have the same group id.
678 // This will be used to optimize lighting, since each group only needs to cast one light.
679 // Call this to get a new group id, then pass it to each weapon_create call for all the
680 // weapons in the group.   Number will be between 0 and WEAPON_MAX_GROUP_IDS and will
681 // get reused.
682 int weapon_create_group_id();
683 
684 // How many unique groups of weapons there can be at one time.
685 #define WEAPON_MAX_GROUP_IDS 256
686 
687 // Passing a group_id of -1 means it isn't in a group.  See weapon_create_group_id for more
688 // help on weapon groups.
689 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);
690 void weapon_set_tracking_info(int weapon_objnum, int parent_objnum, int target_objnum, int target_is_locked = 0, ship_subsys *target_subsys = NULL);
691 
692 // gets the substitution pattern pointer for a given weapon
693 // src_turret may be null
694 size_t* get_pointer_to_weapon_fire_pattern_index(int weapon_type, int ship_idx, ship_subsys* src_turret);
695 
696 // for weapons flagged as particle spewers, spew particles. wheee
697 void weapon_maybe_spew_particle(object *obj);
698 
699 bool weapon_armed(weapon *wp, bool hit_target);
700 void weapon_hit( object * weapon_obj, object * other_obj, vec3d * hitpos, int quadrant = -1, vec3d* hitnormal = NULL );
701 void spawn_child_weapons( object *objp, int spawn_index_override = -1);
702 
703 // call to detonate a weapon. essentially calls weapon_hit() with other_obj as NULL, and sends a packet in multiplayer
704 void weapon_detonate(object *objp);
705 
706 void	weapon_area_apply_blast(vec3d *force_apply_pos, object *ship_objp, vec3d *blast_pos, float blast, int make_shockwave);
707 int	weapon_area_calc_damage(object *objp, vec3d *pos, float inner_rad, float outer_rad, float max_blast, float max_damage,
708 										float *blast, float *damage, float limit);
709 
710 missile_obj *missile_obj_return_address(int index);
711 void find_homing_object_cmeasures(const SCP_vector<object*> &cmeasure_list);
712 
713 // THE FOLLOWING FUNCTION IS IN SHIP.CPP!!!!
714 // JAS - figure out which thruster bitmap will get rendered next
715 // time around.  ship_render needs to have shipp->thruster_bitmap set to
716 // a valid bitmap number, or -1 if we shouldn't render thrusters.
717 // This does basically the same thing as ship_do_thruster_frame, except it
718 // operates on a weapon.   This is in the ship code because it needs
719 // the same thruster animation info as the ship stuff, and I would
720 // rather extern this one function than all the thruster animation stuff.
721 void ship_do_weapon_thruster_frame( weapon *weaponp, object *objp, float frametime );
722 
723 // call to get the "color" of the laser at the given moment (since glowing lasers can cycle colors)
724 void weapon_get_laser_color(color *c, object *objp);
725 
726 void weapon_hit_do_sound(object *hit_obj, weapon_info *wip, vec3d *hitpos, bool is_armed, int quadrant);
727 
728 void weapon_do_electronics_effect(object *ship_objp, vec3d *blast_pos, int wi_index);
729 
730 int weapon_get_random_player_usable_weapon();
731 
732 // return a scale factor for damage which should be applied for 2 collisions
733 float weapon_get_damage_scale(weapon_info *wip, object *wep, object *target);
734 
735 // Pauses all running weapon sounds
736 void weapon_pause_sounds();
737 
738 // Unpauses all running weapon sounds
739 void weapon_unpause_sounds();
740 
741 // Called by hudartillery.cpp after SSMs have been parsed to make sure that $SSM: entries defined in weapons are valid.
742 void validate_SSM_entries();
743 
744 void shield_impact_explosion(vec3d *hitpos, object *objp, float radius, int idx);
745 
746 // Swifty - return number of max simultaneous locks
747 int weapon_get_max_missile_seekers(weapon_info *wip);
748 
749 // return if this weapon can lock on this target, based on its type, class, species or iff
750 bool weapon_target_satisfies_lock_restrictions(weapon_info *wip, object* target);
751 
752 // return if this weapon has iff restrictions, and should ignore normal iff targeting restrictions
753 bool weapon_has_iff_restrictions(weapon_info* wip);
754 
755 // whether secondary weapon wip on shooter is in range of target_world_pos
756 bool weapon_secondary_world_pos_in_range(object* shooter, weapon_info* wip, vec3d* target_world_pos);
757 
758 // Return whether shooter is in range, fov, etc of target_subsys, for multilock
759 // also returns the dot to the subsys in out_dot
760 // While single target missiles will check these properties as well separately, this function is ONLY used by multilock
761 bool weapon_multilock_can_lock_on_subsys(object* shooter, object* target, ship_subsys* target_subsys, weapon_info* wip, float* out_dot = nullptr);
762 
763 // Return whether shooter is in fov, etc of a target, for multilock
764 // does NOT check range
765 // also returns the dot to the subsys in out_dot
766 // While single target missiles will check these properties as well separately, this function is ONLY used by multilock
767 bool weapon_multilock_can_lock_on_target(object* shooter, object* target_objp, weapon_info* wip, float* out_dot = nullptr);
768 
769 
770 #endif
771