1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
|
/*
* 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;
enum class WeaponState : uint32_t
{
INVALID,
// States for laser weapons
NORMAL, //!< For laser weapons that have only one state
// Missile states following
FREEFLIGHT, //!< The initial flight state where the missile is "unpowered"
IGNITION, //!< The moment when the missile comes out of free flight
HOMED_FLIGHT, //!< The missile is homing in on its target
UNHOMED_FLIGHT, //!< The missile does not currently target an object
// Beam states following
WARMUP, //!< The beam is charging up
FIRING, //!< The beam is firing, and there's a beam and everything
PAUSED, //!< The beam is technically firing, but it's in between bursts
WARMDOWN, //!< The beam is cooling down
};
struct WeaponStateHash {
size_t operator()(const WeaponState& state) const {
return static_cast<size_t>(state);
}
};
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
WeaponState weapon_state;
} 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
|