FS2_Open
Open source remastering of the Freespace 2 engine
supernova.cpp
Go to the documentation of this file.
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 #include "cmdline/cmdline.h"
13 #include "debugconsole/console.h"
14 #include "freespace2/freespace.h"
16 #include "gamesnd/gamesnd.h"
17 #include "io/timer.h"
18 #include "math/vecmat.h"
20 #include "particle/particle.h"
21 #include "popup/popupdead.h"
22 #include "ship/ship.h"
23 #include "starfield/starfield.h"
24 #include "starfield/supernova.h"
25 
26 // --------------------------------------------------------------------------------------------------------------------------
27 // SUPERNOVA DEFINES/VARS
28 //
29 
30 // supernova time 1
31 #define SUPERNOVA_SOUND_1_TIME 15.0f
32 #define SUPERNOVA_SOUND_2_TIME 5.0f
35 
36 // countdown for supernova
37 static float Supernova_time_total = -1.0f;
38 static float Supernova_time = -1.0f;
39 static int Supernova_finished = 0;
40 static int Supernova_popup = 0;
41 static float Supernova_fade_to_white = 0.0f;
42 static int Supernova_particle_stamp = -1;
43 
45 
46 // --------------------------------------------------------------------------------------------------------------------------
47 // SUPERNOVA FUNCTIONS
48 //
49 
50 // level init
52 {
53  Supernova_time_total = -1.0f;
54  Supernova_time = -1.0f;
55  Supernova_finished = 0;
56  Supernova_fade_to_white = 0.0f;
57  Supernova_popup = 0;
58  Supernova_particle_stamp = -1;
59 
62 
64 }
65 
66 // start a supernova
67 void supernova_start(int seconds)
68 {
69  // bogus time
70  if((float)seconds < SUPERNOVA_CUT_TIME) {
71  return;
72  }
73 
74  // no supernova in multiplayer
76  return;
77  }
78 
79  Supernova_time_total = (float)seconds;
80  Supernova_time = (float)seconds;
81  Supernova_finished = 0;
82  Supernova_fade_to_white = 0.0f;
83  Supernova_popup = 0;
84  Supernova_particle_stamp = -1;
85 
87 }
88 
90 {
91  // There's no currently active supernova
93  {
94  return;
95  }
96 
97  // We're too late.
99  {
100  return;
101  }
102 
103  // A supernova? In MY multiplayer?
104  if(Game_mode & GM_MULTIPLAYER) {
105  return;
106  }
107 
108  Supernova_time_total = -1.0f;
109  Supernova_time = -1.0f;
110  Supernova_finished = 0;
111  Supernova_popup = 0;
112  Supernova_fade_to_white = 0.0f;
113  Supernova_particle_stamp = -1;
114 
116 }
117 
118 
119 int sn_particles = 100;
120 DCF_INT2(sn_part, sn_particles, 0, INT_MAX, "Sets number of supernova particles (default is 100)");
121 
123 {
124  int idx;
125  vec3d a, b, ta, tb;
126  vec3d norm, sun_temp;
127 
128  // no player ship
129  if((Player_obj == NULL) || (Player_ship == NULL)) {
130  return;
131  }
132 
133  // timestamp
134  if((Supernova_particle_stamp == -1) || timestamp_elapsed(Supernova_particle_stamp)) {
135  Supernova_particle_stamp = timestamp(sn_particles);
136 
137  // get particle norm
138  stars_get_sun_pos(0, &sun_temp);
139  vm_vec_add2(&sun_temp, &Player_obj->pos);
140  vm_vec_sub(&norm, &Player_obj->pos, &sun_temp);
141  vm_vec_normalize(&norm);
142 
143  particle_emitter whee;
144  whee.max_life = 1.0f;
145  whee.min_life = 0.6f;
146  whee.max_vel = 50.0f;
147  whee.min_vel = 25.0f;
148  whee.normal_variance = 0.75f;
149  whee.num_high = 5;
150  whee.num_low = 2;
151  whee.min_rad = 0.5f;
152  whee.max_rad = 1.25f;
153 
154  // emit
155  for(idx=0; idx<10; idx++) {
158  } else {
160  }
161 
162  // rotate into world space
163  vm_vec_unrotate(&a, &ta, &Player_obj->orient);
164  vm_vec_add2(&a, &Player_obj->pos);
165  whee.pos = a;
166  whee.vel = norm;
167  vm_vec_scale(&whee.vel, 30.0f);
169  whee.normal = norm;
170  particle_emit(&whee, PARTICLE_FIRE, 0);
171 
172  vm_vec_unrotate(&b, &tb, &Player_obj->orient);
173  vm_vec_add2(&b, &Player_obj->pos);
174  whee.pos = b;
175  particle_emit(&whee, PARTICLE_FIRE, 0);
176  }
177  }
178 }
179 
180 // call once per frame
181 float sn_shudder = 0.45f;
182 DCF_FLOAT2(sn_shud, sn_shudder, 0.0, FLT_MAX, "Sets camera shudder rate for being in supernova shockwave (default is 0.45)");
183 
185 {
186  int sn_stage;
187 
188  // if the supernova is running
189  sn_stage = supernova_active();
190  if(sn_stage) {
191  Supernova_time -= flFrametime;
192 
193  // sound stuff
194  if((Supernova_time <= SUPERNOVA_SOUND_1_TIME) && !Supernova_sound_1_played) {
197  }
198  if((Supernova_time <= SUPERNOVA_SOUND_2_TIME) && !Supernova_sound_2_played) {
201  }
202 
203  // if we've crossed from stage 1 to stage 2 kill all particles and stick a bunch on the player ship
204  if((sn_stage == 1) && (supernova_active() == 2)) {
205  // first kill all active particles so we have a bunch of free ones
207  }
208 
209  // if we're in stage 2, emit particles
210  if((sn_stage >= 2) && (sn_stage != 5)) {
212  }
213 
214  // if we've got negative. the supernova is done
215  if(Supernova_time < 0.0f) {
216  Supernova_finished = 1;
217  Supernova_fade_to_white += flFrametime;
218 
219  // start the dead popup
220  if(Supernova_fade_to_white >= SUPERNOVA_FADE_TO_WHITE_TIME) {
221  if(!Supernova_popup) {
222  // main freespace 2 campaign? if so - end it now
223  //
224  // don't actually check for a specific campaign here since others may want to end this way but we
225  // should test positive here if in campaign mode and sexp_end_campaign() got called - taylor
226  if (Campaign_ending_via_supernova && (Game_mode & GM_CAMPAIGN_MODE) /*&& !stricmp(Campaign.filename, "freespace2")*/) {
228  } else {
229  popupdead_start();
230  }
231  Supernova_popup = 1;
232  }
233  Supernova_finished = 2;
234  }
235  }
236  }
237 }
238 
239 // is there a supernova active
241 {
242  // if not supernova has been set then just bail now
244  return 0;
245  }
246 
247  // if the supernova has "finished". fade to white and dead popup
248  if(Supernova_finished == 1) {
250  return 4;
251  }
252  if(Supernova_finished == 2) {
254  return 5;
255  }
256 
257  // no supernova
258  if( (Supernova_time_total <= 0.0f) || (Supernova_time <= 0.0f) ) {
259  return 0;
260  }
261 
262  // final stage,
263  if(Supernova_time < (SUPERNOVA_CUT_TIME - SUPERNOVA_CAMERA_MOVE_TIME)) {
265  return 3;
266  }
267 
268  // 2nd stage
269  if(Supernova_time < SUPERNOVA_CUT_TIME) {
271  return 2;
272  }
273 
274  // first stage
275  return 1;
276 }
277 
278 // time left before the supernova hits
280 {
281  return Supernova_time;
282 }
283 
284 // pct complete the supernova (0.0 to 1.0)
286 {
287  // bogus
288  if(!supernova_active()) {
289  return -1.0f;
290  }
291 
292  return (Supernova_time_total - Supernova_time) / Supernova_time_total;
293 }
294 
295 // if the camera should cut to the "you-are-toast" cam
297 {
298  // if we're not in a supernova
299  if(!supernova_active()) {
300  return 0;
301  }
302 
303  // if we're past the critical time
304  if(Supernova_time <= SUPERNOVA_CUT_TIME) {
305  return 1;
306  }
307 
308  // no cut yet
309  return 0;
310 }
311 
312 // get view params from supernova
313 float sn_distance = 300.0f; // shockwave moving at 1000/ms ?
314 float sn_cam_distance = 25.0f;
315 DCF_FLOAT2(sn_dist, sn_distance, 0.0, FLT_MAX, "Sets supernova shockwave distance (default is 300.0f)");
316 
317 
318 DCF_FLOAT2(sn_cam_dist, sn_cam_distance, 0.0, FLT_MAX, "Sets supernova camera distance (default is 25.0f)");
319 
321 {
322  // supernova camera pos
323  vec3d Supernova_camera_pos;
324  static matrix Supernova_camera_orient;
325 
326  vec3d at;
327  vec3d sun_temp, sun_vec;
328  vec3d view;
329 
330  // set the controls for the heart of the sun
331  stars_get_sun_pos(0, &sun_temp);
332  vm_vec_add2(&sun_temp, &Player_obj->pos);
333  vm_vec_sub(&sun_vec, &sun_temp, &Player_obj->pos);
334  vm_vec_normalize(&sun_vec);
335 
336  // always set the camera pos
337  vec3d move;
338  matrix whee;
339  vm_vector_2_matrix(&whee, &move, NULL, NULL);
340  vm_vec_scale_add(&Supernova_camera_pos, &Player_obj->pos, &whee.vec.rvec, sn_cam_distance);
341  vm_vec_scale_add2(&Supernova_camera_pos, &whee.vec.uvec, 30.0f);
342  //cam->set_position(&Supernova_camera_pos);
343  *eye_pos = Supernova_camera_pos;
344 
345  // if we're no longer moving the camera
346  if(Supernova_time < (SUPERNOVA_CUT_TIME - SUPERNOVA_CAMERA_MOVE_TIME)) {
347  // *eye_pos = Supernova_camera_pos;
348  //cam->set_rotation(&Supernova_camera_orient);
349  *eye_orient = Supernova_camera_orient;
350  }
351  // otherwise move it
352  else {
353  // get a vector somewhere between the supernova shockwave and the player ship
354  at = Player_obj->pos;
355  vm_vec_scale_add2(&at, &sun_vec, sn_distance);
356  vm_vec_sub(&move, &Player_obj->pos, &at);
357  vm_vec_normalize(&move);
358 
359  // linearly move towards the player pos
360  float pct = ((SUPERNOVA_CUT_TIME - Supernova_time) / SUPERNOVA_CAMERA_MOVE_TIME);
361  vm_vec_scale_add2(&at, &move, sn_distance * pct);
362 
363  vm_vec_sub(&view, &at, &Supernova_camera_pos);
364  vm_vec_normalize(&view);
365  vm_vector_2_matrix(&Supernova_camera_orient, &view, NULL, NULL);
366  //cam->set_rotation(&Supernova_camera_orient);
367  *eye_orient = Supernova_camera_orient;
368  }
369  //return supernova_camera;
370 }
int timestamp(int delta_ms)
Definition: timer.cpp:226
int Cmdline_old_collision_sys
Definition: cmdline.cpp:489
int sn_particles
Definition: supernova.cpp:119
#define SUPERNOVA_CUT_TIME
Definition: supernova.h:24
int Game_mode
Definition: systemvars.cpp:24
float supernova_pct_complete()
Definition: supernova.cpp:285
void vm_vec_scale_add(vec3d *dest, const vec3d *src1, const vec3d *src2, float k)
Definition: vecmat.cpp:266
SCP_vector< game_snd > Snds
Definition: gamesnd.cpp:19
void popupdead_start()
Definition: popupdead.cpp:129
float flFrametime
Definition: fredstubs.cpp:22
physics_info phys_info
Definition: object.h:157
#define SUPERNOVA_STARTED
Definition: supernova.h:33
SuperNova (distant)
Definition: gamesnd.h:246
Definition: pstypes.h:88
void particle_kill_all()
Definition: particle.cpp:304
void supernova_stop()
Definition: supernova.cpp:89
GLclampf f
Definition: Glext.h:7097
#define SUPERNOVA_SOUND_1_TIME
Definition: supernova.cpp:31
void supernova_level_init()
Definition: supernova.cpp:51
DCF_INT2(sn_part, sn_particles, 0, INT_MAX,"Sets number of supernova particles (default is 100)")
void vm_vec_scale_add2(vec3d *dest, const vec3d *src, float k)
Definition: vecmat.cpp:284
vec3d pos
Definition: object.h:152
void particle_emit(particle_emitter *pe, int type, int optional_data, float range)
Definition: particle.cpp:495
#define SUPERNOVA_SOUND_2_TIME
Definition: supernova.cpp:32
void supernova_get_eye(vec3d *eye_pos, matrix *eye_orient)
Definition: supernova.cpp:320
int Supernova_sound_1_played
Definition: supernova.cpp:33
DCF_FLOAT2(sn_shud, sn_shudder, 0.0, FLT_MAX,"Sets camera shudder rate for being in supernova shockwave (default is 0.45)")
SuperNova (shockwave)
Definition: gamesnd.h:247
float supernova_time_left()
Definition: supernova.cpp:279
matrix * vm_vector_2_matrix(matrix *m, const vec3d *fvec, const vec3d *uvec, const vec3d *rvec)
Definition: vecmat.cpp:850
void vm_vec_add2(vec3d *dest, const vec3d *src)
Definition: vecmat.cpp:178
int supernova_camera_cut()
Definition: supernova.cpp:296
#define PARTICLE_FIRE
Definition: particle.h:51
void supernova_process()
Definition: supernova.cpp:184
struct matrix::@228::@230 vec
void vm_vec_scale(vec3d *dest, float s)
Definition: vecmat.cpp:248
#define GM_MULTIPLAYER
Definition: systemvars.h:18
float sn_cam_distance
Definition: supernova.cpp:314
GLboolean GLboolean GLboolean GLboolean a
Definition: Glext.h:5781
#define SUPERNOVA_NONE
Definition: supernova.h:32
int snd_play(game_snd *gs, float pan, float vol_scale, int priority, bool is_voice_msg)
Definition: sound.cpp:517
matrix eye_orient
Definition: fredrender.cpp:112
vec3d eye_pos
Definition: fredrender.cpp:103
int idx
Definition: multiui.cpp:761
vec3d * vm_vec_unrotate(vec3d *dest, const vec3d *src, const matrix *m)
Definition: vecmat.cpp:959
void submodel_get_two_random_points(int model_num, int submodel_num, vec3d *v1, vec3d *v2, vec3d *n1=NULL, vec3d *n2=NULL)
ship * Player_ship
Definition: ship.cpp:124
matrix orient
Definition: object.h:153
#define SND_PRIORITY_MUST_PLAY
Definition: sound.h:26
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:168
vec3d vel
Definition: physics.h:77
void supernova_start(int seconds)
Definition: supernova.cpp:67
GLboolean GLboolean GLboolean b
Definition: Glext.h:5781
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
float sn_shudder
Definition: supernova.cpp:181
void stars_get_sun_pos(int sun_n, vec3d *pos)
Definition: starfield.cpp:1016
float sn_distance
Definition: supernova.cpp:313
void submodel_get_two_random_points_better(int model_num, int submodel_num, vec3d *v1, vec3d *v2)
int Campaign_ending_via_supernova
int ship_info_index
Definition: ship.h:539
An overhauled/updated debug console to allow monitoring, testing, and general debugging of new featur...
SCP_vector< ship_info > Ship_info
Definition: ship.cpp:164
#define timestamp_elapsed(stamp)
Definition: timer.h:102
float normal_variance
Definition: particle.h:114
object * Player_obj
Definition: object.cpp:56
int Supernova_status
Definition: supernova.cpp:44
int supernova_active()
Definition: supernova.cpp:240
void gameseq_post_event(int event)
#define GM_CAMPAIGN_MODE
Definition: systemvars.h:29
#define SUPERNOVA_FADE_TO_WHITE_TIME
Definition: supernova.h:26
int Supernova_sound_2_played
Definition: supernova.cpp:34
void supernova_do_particles()
Definition: supernova.cpp:122
#define SUPERNOVA_CAMERA_MOVE_TIME
Definition: supernova.h:25
#define SUPERNOVA_HIT
Definition: supernova.h:34
float vm_vec_normalize(vec3d *v)
Definition: vecmat.cpp:460