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 __FS2_BEAM_WEAPON_HEADER_FILE 13 #define __FS2_BEAM_WEAPON_HEADER_FILE 14 15 // ------------------------------------------------------------------------------------------------ 16 // BEAM WEAPON DEFINES/VARS 17 // 18 #include "globalincs/globals.h" 19 #include "model/model.h" 20 21 // prototypes 22 class object; 23 class ship_subsys; 24 struct obj_pair; 25 struct beam_weapon_info; 26 struct vec3d; 27 28 // beam types 29 #define BEAM_TYPE_A 0 // unidirectional beam 30 #define BEAM_TYPE_B 1 // "slash" in one direction 31 #define BEAM_TYPE_C 2 // targeting lasers (only lasts one frame) 32 #define BEAM_TYPE_D 3 // similar to the type A beams, but takes multiple shots and "chases" fighters around 33 #define BEAM_TYPE_E 4 // stupid beam. like type A, only it doesn't aim. it just shoots directly out of the turret 34 #define BEAM_TYPE_F 5 // SCP type, highly flexible and configurable 35 36 // max # of "shots" an individual beam will take 37 #define MAX_BEAM_SHOTS 5 38 #define MAX_BEAMS 500 39 40 // apply damage 41 #define BEAM_DAMAGE_TIME 170 42 43 // uses to define beam behavior ahead of time - needed for multiplayer 44 typedef struct beam_info { 45 vec3d dir_a, dir_b; // direction vectors for beams 46 vec3d rot_axis; 47 ubyte shot_count; // # of shots 48 float shot_aim[MAX_BEAM_SHOTS]; // accuracy. this is a constant multiple of radius. anything < 1.0 will guarantee a hit 49 } beam_info; 50 51 #define BFIF_IS_FIGHTER_BEAM (1<<0) 52 #define BFIF_FORCE_FIRING (1<<1) 53 #define BFIF_TARGETING_COORDS (1<<2) 54 #define BFIF_FLOATING_BEAM (1<<3) 55 56 // to ensure validity of fire_info, the related fields MUST be provided 57 #define BFM_TURRET_FIRED 0 // objp, subsys, target 58 #define BFM_TURRET_FORCE_FIRED 1 // objp, subsys, target OR target_pos 59 #define BFM_FIGHTER_FIRED 2 // objp, subsys 60 #define BFM_SPAWNED 3 // starting pos, target OR target_pos 61 #define BFM_SEXP_FLOATING_FIRED 4 // starting pos, target OR target_pos 62 #define BFM_SUBSPACE_STRIKE 5 // starting pos, target 63 64 // pass to beam fire 65 typedef struct beam_fire_info { 66 int beam_info_index; // weapon info index 67 object *shooter; // whos shooting 68 vec3d local_fire_postion; // offset from the center of the object (for fighter beams only) 69 ship_subsys *turret; // where he's shooting from 70 float accuracy; // 0.0 to 1.0 (only really effects targeting on small ships) 71 object *target; // who's getting shot 72 ship_subsys *target_subsys; // (optional), specific subsystem to be targeted on the target 73 vec3d target_pos1; // if we're shooting off into space 74 vec3d target_pos2; // if we're shooting off into space (optional second point) 75 vec3d starting_pos; // starting positiong for floating beams -MageKing17 76 beam_info *beam_info_override; // (optional), pass this in to override all beam movement info (for multiplayer) 77 int num_shots; // (optional), only used for type D weapons 78 int bank; // for fighters, which bank of the primary weapons are they in 79 int point; // for fighters, which point on the bank it is from 80 int bfi_flags; 81 char team; // for floating beams, determines which team the beam is on 82 int burst_seed; // used for sharing random targets if part of the same burst 83 int fire_method; 84 float per_burst_rotation; // for type 5 beams 85 int burst_index; 86 } beam_fire_info; 87 88 typedef struct fighter_beam_fire_info { 89 int beam_info_index; // weapon info index 90 object *shooter; // whos shooting 91 vec3d local_fire_postion; // offset from the center of the object (for fighter beams only) 92 ship_subsys *turret; // where he's shooting from 93 float accuracy; // 0.0 to 1.0 (only really effects targeting on small ships) 94 object *target; // whos getting shot 95 ship_subsys *target_subsys; // (optional), specific subsystem to be targeted on the target 96 beam_info *beam_info_override; // (optional), pass this in to override all beam movement info (for multiplayer) 97 int num_shots; // (optional), only used for type D weapons 98 int fighter_beam_loop_sound; //loop sound used by fighter beams -Bobboau 99 int warmup_stamp; 100 int warmdown_stamp; 101 float life_left; 102 float life_total; 103 } fighter_beam_fire_info; 104 105 // max # of collisions we'll allow per frame 106 #define MAX_FRAME_COLLISIONS 10 107 108 // collision info 109 typedef struct beam_collision { 110 mc_info cinfo; // collision info 111 int c_objnum; // objnum of the guy we recently collided with 112 int c_sig; // object sig 113 int c_stamp; // when we should next apply damage 114 int quadrant; // shield quadrant this beam hits if any -Bobboau 115 bool is_exit_collision; //does this occur when the beam is exiting the ship 116 } beam_collision; 117 118 // beam flag defines 119 #define BF_SAFETY (1<<0) // if this is set, don't collide or render for this frame. lifetime still increases though 120 #define BF_SHRINK (1<<1) // if this is set, the beam is shrinking in width and approaching the warmdown phase 121 #define BF_FORCE_FIRING (1<<2) 122 #define BF_IS_FIGHTER_BEAM (1<<3) 123 #define BF_TARGETING_COORDS (1<<4) 124 #define BF_FLOATING_BEAM (1<<5) 125 #define BF_GROW (1<<6) // if this is set, the beam is growing in width 126 #define BF_FINISHED_GROWING (1<<7) // to stop grow from re-triggering 127 128 // beam struct (the actual weapon/object) 129 typedef struct beam { 130 // low-level data 131 int objnum; // our own objnum 132 int weapon_info_index; 133 int sig; // signature for the shooting object 134 object *objp; // the shooting object (who owns the turret that I am being fired from) 135 object *target; // target object 136 ship_subsys *target_subsys; // targeted subsys 137 vec3d target_pos1; // if we're targeting a location in space 138 vec3d target_pos2; // if we're targeting a location in space (optional second point) 139 int target_sig; // target sig 140 ship_subsys *subsys; // subsys its being fired from 141 beam *next, *prev; // link list stuff 142 vec3d local_fire_postion; // offset from the center of the object (for fighter beams only) 143 int framecount; // how many frames the beam has been active 144 int flags; // see BF_* defines 145 float current_width_factor; // applied to width due to shrink or grow 146 147 // beam info 148 int warmup_stamp; // timestamp for "warming up" 149 int warmdown_stamp; // timestamp for "warming down" 150 int type; // see BEAM_TYPE_* defines in beam.h 151 float life_left; // in seconds 152 float life_total; // total life 153 // this vector has very special meaning. BEFORE performing collision checks, it basically implies a "direction". meaning 154 // the vector between it and last_start is where the beam will be aiming. AFTER performing collision checks, it is the 155 // literal world collision point on the object (or meaningless, if we hit nothing). The function beam_move_all_pre() is 156 // responsible for then setting it up pre-collision time 157 vec3d last_shot; 158 vec3d last_start; 159 int shot_index; // for type D beam weapons 160 float beam_glow_frame; // what frame a beam glow animation is on 161 float beam_section_frame[MAX_BEAM_SECTIONS]; // what frame a beam section animation is on 162 163 // recent collisions 164 beam_collision r_collisions[MAX_FRAME_COLLISIONS]; // recent collisions 165 int r_collision_count; // # of recent collisions 166 167 // collision info for this frame 168 beam_collision f_collisions[MAX_FRAME_COLLISIONS]; // collisions for the current frame 169 int f_collision_count; // # of collisions we recorded this frame 170 171 // looping sound info, HANDLE 172 sound_handle beam_sound_loop; // invalid if none 173 174 // team 175 char team; 176 177 float range; 178 float damage_threshold; 179 180 // exactly how the beam will behave. by passing this is multiplayer from server to client, we can ensure that 181 // everything looks the same 182 beam_info binfo; 183 int bank; 184 185 int Beam_muzzle_stamp; 186 int firingpoint; 187 float beam_collide_width; 188 float beam_light_width; 189 190 float u_offset_local; 191 192 bool rotates; // type 5s only, determines whether it rotates 193 float type5_rot_speed; // how fast it rotates if it does 194 } beam; 195 196 extern std::array<beam, MAX_BEAMS> Beams; // all beams 197 extern int Beam_count; 198 199 #define BEAM_INDEX(beam) (int)((beam) - Beams.data()) 200 201 // ------------------------------------------------------------------------------------------------ 202 // BEAM WEAPON FUNCTIONS 203 // 204 205 // --------------- 206 // the next functions are probably the only ones anyone should care about calling. the rest require somewhat detailed knowledge of beam weapons 207 208 // fire a beam, returns objnum on success. the innards of the code handle all the rest, foo 209 int beam_fire(beam_fire_info *fire_info); 210 211 // fire a targeting beam, returns objnum on success. a much much simplified version of a beam weapon 212 // targeting lasers last _one_ frame. For a continuous stream - they must be created every frame. 213 // this allows it to work smoothly in multiplayer (detect "trigger down". every frame just create a targeting laser firing straight out of the 214 // object. this way you get all the advantages of nice rendering and collisions). 215 // NOTE : only references beam_info_index and shooter 216 int beam_fire_targeting(fighter_beam_fire_info *fire_info); 217 218 // return an object index of the guy who's firing this beam 219 int beam_get_parent(object *bm); 220 221 // return weapon_info_index of beam 222 int beam_get_weapon_info_index(object *bm); 223 224 // given a beam object, get the # of collisions which happened during the last collision check (typically, last frame) 225 int beam_get_num_collisions(int objnum); 226 227 // stuff collision info, returns 1 on success 228 int beam_get_collision(int objnum, int num, int *collision_objnum, mc_info **cinfo); 229 // --------------- 230 231 // init at game startup 232 void beam_init(); 233 234 // initialize beam weapons for this level 235 void beam_level_init(); 236 237 // shutdown beam weapons for this level 238 void beam_level_close(); 239 240 // collide a beam with a ship, returns 1 if we can ignore all future collisions between the 2 objects 241 int beam_collide_ship(obj_pair *pair); 242 243 // collide a beam with an asteroid, returns 1 if we can ignore all future collisions between the 2 objects 244 int beam_collide_asteroid(obj_pair *pair); 245 246 // collide a beam with a missile, returns 1 if we can ignore all future collisions between the 2 objects 247 int beam_collide_missile(obj_pair *pair); 248 249 // collide a beam with debris, returns 1 if we can ignore all future collisions between the 2 objects 250 int beam_collide_debris(obj_pair *pair); 251 252 // pre-move (before collision checking - but AFTER ALL OTHER OBJECTS HAVE BEEN MOVED) 253 void beam_move_all_pre(); 254 255 // post-collision time processing for beams 256 void beam_move_all_post(); 257 258 // render all beam weapons 259 void beam_render_all(); 260 261 // early-out function for when adding object collision pairs, return 1 if the pair should be ignored 262 int beam_collide_early_out(object *a, object *b); 263 264 // pause all looping beam sounds 265 void beam_pause_sounds(); 266 267 // unpause looping beam sounds 268 void beam_unpause_sounds(); 269 270 void beam_calc_facing_pts(vec3d *top, vec3d *bot, vec3d *fvec, vec3d *pos, float w, float z_add); 271 272 // return the amount of damage which should be applied to a ship. basically, filters friendly fire damage 273 float beam_get_ship_damage(beam *b, object *objp, vec3d* hitpos = nullptr); 274 275 276 277 #endif 278