Files
Asteroth 76046d8aee Clean up beam type naming scheme (#3670)
* clean up beam type naming scheme

* appease clang tidy

* cast to int for printing

* address feedback
2021-10-02 02:42:21 +09:00

279 lines
11 KiB
C++

/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
#ifndef __FS2_BEAM_WEAPON_HEADER_FILE
#define __FS2_BEAM_WEAPON_HEADER_FILE
// ------------------------------------------------------------------------------------------------
// BEAM WEAPON DEFINES/VARS
//
#include "globalincs/globals.h"
#include "model/model.h"
// prototypes
class object;
class ship_subsys;
struct obj_pair;
struct beam_weapon_info;
struct vec3d;
typedef enum class BeamType {
DIRECT_FIRE, // unidirectional beam; used to be BEAM_TYPE_A
SLASHING, // "slash" in one direction; used to be BEAM_TYPE_B
TARGETING, // targeting lasers (only lasts one frame); used to be BEAM_TYPE_C
ANTIFIGHTER, // similar to the type A beams, but takes multiple shots and "chases" fighters around; used to be BEAM_TYPE_D
NORMAL_FIRE, // stupid beam. like type A, only it doesn't aim. it just shoots directly out of the turret; used to be BEAM_TYPE_E
OMNI // SCP type, highly flexible and configurable; used to be BEAM_TYPE_F
} BeamType;
// max # of "shots" an individual beam will take
#define MAX_BEAM_SHOTS 5
#define MAX_BEAMS 500
// apply damage
#define BEAM_DAMAGE_TIME 170
// uses to define beam behavior ahead of time - needed for multiplayer
typedef struct beam_info {
vec3d dir_a, dir_b; // direction vectors for beams
vec3d rot_axis;
ubyte shot_count; // # of shots
float shot_aim[MAX_BEAM_SHOTS]; // accuracy. this is a constant multiple of radius. anything < 1.0 will guarantee a hit
} beam_info;
#define BFIF_IS_FIGHTER_BEAM (1<<0)
#define BFIF_FORCE_FIRING (1<<1)
#define BFIF_TARGETING_COORDS (1<<2)
#define BFIF_FLOATING_BEAM (1<<3)
// to ensure validity of fire_info, the related fields MUST be provided
#define BFM_TURRET_FIRED 0 // objp, subsys, target
#define BFM_TURRET_FORCE_FIRED 1 // objp, subsys, target OR target_pos
#define BFM_FIGHTER_FIRED 2 // objp, subsys
#define BFM_SPAWNED 3 // starting pos, target OR target_pos
#define BFM_SEXP_FLOATING_FIRED 4 // starting pos, target OR target_pos
#define BFM_SUBSPACE_STRIKE 5 // starting pos, target
// pass to beam fire
typedef struct beam_fire_info {
int beam_info_index; // weapon info index
object *shooter; // whos shooting
vec3d local_fire_postion; // offset from the center of the object (for fighter beams only)
ship_subsys *turret; // where he's shooting from
float accuracy; // 0.0 to 1.0 (only really effects targeting on small ships)
object *target; // who's getting shot
ship_subsys *target_subsys; // (optional), specific subsystem to be targeted on the target
vec3d target_pos1; // if we're shooting off into space
vec3d target_pos2; // if we're shooting off into space (optional second point)
vec3d starting_pos; // starting positiong for floating beams -MageKing17
beam_info *beam_info_override; // (optional), pass this in to override all beam movement info (for multiplayer)
int num_shots; // (optional), only used for type D weapons
int bank; // for fighters, which bank of the primary weapons are they in
int point; // for fighters, which point on the bank it is from
int bfi_flags;
char team; // for floating beams, determines which team the beam is on
int burst_seed; // used for sharing random targets if part of the same burst
int fire_method;
float per_burst_rotation; // for type 5 beams
int burst_index;
} beam_fire_info;
typedef struct fighter_beam_fire_info {
int beam_info_index; // weapon info index
object *shooter; // whos shooting
vec3d local_fire_postion; // offset from the center of the object (for fighter beams only)
ship_subsys *turret; // where he's shooting from
float accuracy; // 0.0 to 1.0 (only really effects targeting on small ships)
object *target; // whos getting shot
ship_subsys *target_subsys; // (optional), specific subsystem to be targeted on the target
beam_info *beam_info_override; // (optional), pass this in to override all beam movement info (for multiplayer)
int num_shots; // (optional), only used for type D weapons
int fighter_beam_loop_sound; //loop sound used by fighter beams -Bobboau
int warmup_stamp;
int warmdown_stamp;
float life_left;
float life_total;
} fighter_beam_fire_info;
// max # of collisions we'll allow per frame
#define MAX_FRAME_COLLISIONS 10
// collision info
typedef struct beam_collision {
mc_info cinfo; // collision info
int c_objnum; // objnum of the guy we recently collided with
int c_sig; // object sig
int c_stamp; // when we should next apply damage
int quadrant; // shield quadrant this beam hits if any -Bobboau
bool is_exit_collision; //does this occur when the beam is exiting the ship
} beam_collision;
// beam flag defines
#define BF_SAFETY (1<<0) // if this is set, don't collide or render for this frame. lifetime still increases though
#define BF_SHRINK (1<<1) // if this is set, the beam is shrinking in width and approaching the warmdown phase
#define BF_FORCE_FIRING (1<<2)
#define BF_IS_FIGHTER_BEAM (1<<3)
#define BF_TARGETING_COORDS (1<<4)
#define BF_FLOATING_BEAM (1<<5)
#define BF_GROW (1<<6) // if this is set, the beam is growing in width
#define BF_FINISHED_GROWING (1<<7) // to stop grow from re-triggering
// beam struct (the actual weapon/object)
typedef struct beam {
// low-level data
int objnum; // our own objnum
int weapon_info_index;
int sig; // signature for the shooting object
object *objp; // the shooting object (who owns the turret that I am being fired from)
object *target; // target object
ship_subsys *target_subsys; // targeted subsys
vec3d target_pos1; // if we're targeting a location in space
vec3d target_pos2; // if we're targeting a location in space (optional second point)
int target_sig; // target sig
ship_subsys *subsys; // subsys its being fired from
beam *next, *prev; // link list stuff
vec3d local_fire_postion; // offset from the center of the object (for fighter beams only)
int framecount; // how many frames the beam has been active
int flags; // see BF_* defines
float current_width_factor; // applied to width due to shrink or grow
// beam info
int warmup_stamp; // timestamp for "warming up"
int warmdown_stamp; // timestamp for "warming down"
BeamType type; // the type of beam, direct-fire, slashing, etc
float life_left; // in seconds
float life_total; // total life
// this vector has very special meaning. BEFORE performing collision checks, it basically implies a "direction". meaning
// the vector between it and last_start is where the beam will be aiming. AFTER performing collision checks, it is the
// literal world collision point on the object (or meaningless, if we hit nothing). The function beam_move_all_pre() is
// responsible for then setting it up pre-collision time
vec3d last_shot;
vec3d last_start;
int shot_index; // for type D beam weapons
float beam_glow_frame; // what frame a beam glow animation is on
float beam_section_frame[MAX_BEAM_SECTIONS]; // what frame a beam section animation is on
// recent collisions
beam_collision r_collisions[MAX_FRAME_COLLISIONS]; // recent collisions
int r_collision_count; // # of recent collisions
// collision info for this frame
beam_collision f_collisions[MAX_FRAME_COLLISIONS]; // collisions for the current frame
int f_collision_count; // # of collisions we recorded this frame
// looping sound info, HANDLE
sound_handle beam_sound_loop; // invalid if none
// team
char team;
float range;
float damage_threshold;
// exactly how the beam will behave. by passing this is multiplayer from server to client, we can ensure that
// everything looks the same
beam_info binfo;
int bank;
int Beam_muzzle_stamp;
int firingpoint;
float beam_collide_width;
float beam_light_width;
float u_offset_local;
bool rotates; // type 5s only, determines whether it rotates
float type5_rot_speed; // how fast it rotates if it does
} beam;
extern std::array<beam, MAX_BEAMS> Beams; // all beams
extern int Beam_count;
#define BEAM_INDEX(beam) (int)((beam) - Beams.data())
// ------------------------------------------------------------------------------------------------
// BEAM WEAPON FUNCTIONS
//
// ---------------
// the next functions are probably the only ones anyone should care about calling. the rest require somewhat detailed knowledge of beam weapons
// fire a beam, returns objnum on success. the innards of the code handle all the rest, foo
int beam_fire(beam_fire_info *fire_info);
// fire a targeting beam, returns objnum on success. a much much simplified version of a beam weapon
// targeting lasers last _one_ frame. For a continuous stream - they must be created every frame.
// this allows it to work smoothly in multiplayer (detect "trigger down". every frame just create a targeting laser firing straight out of the
// object. this way you get all the advantages of nice rendering and collisions).
// NOTE : only references beam_info_index and shooter
int beam_fire_targeting(fighter_beam_fire_info *fire_info);
// return an object index of the guy who's firing this beam
int beam_get_parent(object *bm);
// return weapon_info_index of beam
int beam_get_weapon_info_index(object *bm);
// given a beam object, get the # of collisions which happened during the last collision check (typically, last frame)
int beam_get_num_collisions(int objnum);
// stuff collision info, returns 1 on success
int beam_get_collision(int objnum, int num, int *collision_objnum, mc_info **cinfo);
// ---------------
// init at game startup
void beam_init();
// initialize beam weapons for this level
void beam_level_init();
// shutdown beam weapons for this level
void beam_level_close();
// collide a beam with a ship, returns 1 if we can ignore all future collisions between the 2 objects
int beam_collide_ship(obj_pair *pair);
// collide a beam with an asteroid, returns 1 if we can ignore all future collisions between the 2 objects
int beam_collide_asteroid(obj_pair *pair);
// collide a beam with a missile, returns 1 if we can ignore all future collisions between the 2 objects
int beam_collide_missile(obj_pair *pair);
// collide a beam with debris, returns 1 if we can ignore all future collisions between the 2 objects
int beam_collide_debris(obj_pair *pair);
// pre-move (before collision checking - but AFTER ALL OTHER OBJECTS HAVE BEEN MOVED)
void beam_move_all_pre();
// post-collision time processing for beams
void beam_move_all_post();
// render all beam weapons
void beam_render_all();
// early-out function for when adding object collision pairs, return 1 if the pair should be ignored
int beam_collide_early_out(object *a, object *b);
// pause all looping beam sounds
void beam_pause_sounds();
// unpause looping beam sounds
void beam_unpause_sounds();
void beam_calc_facing_pts(vec3d *top, vec3d *bot, vec3d *fvec, vec3d *pos, float w, float z_add);
// return the amount of damage which should be applied to a ship. basically, filters friendly fire damage
float beam_get_ship_damage(beam *b, object *objp, vec3d* hitpos = nullptr);
#endif