FS2_Open
Open source remastering of the Freespace 2 engine
corkscrew.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 "debugconsole/console.h"
13 #include "freespace2/freespace.h" // for Missiontime
14 #include "io/timer.h"
15 #include "object/object.h"
16 #include "ship/ship.h"
17 #include "weapon/corkscrew.h"
18 #include "weapon/weapon.h"
19 
20 
21 
22 // corkscrew structure flags
23 #define CS_FLAG_USED (1<<0) // this structure is in use
24 #define CS_FLAG_COUNTER (1<<1) // counterrotate this guy
25 
26 // corkscrew settings
27 int Corkscrew_missile_delay = 30; // delay between missile firings
28 int Corkscrew_num_missiles_fired = 4; // # of missiles fire in one shot
29 float Corkscrew_radius = 1.25f; // radius of the corkscrew itself
30 float Corkscrew_twist = 5.0f; // in degrees/second
31 int Corkscrew_helix = 1; // attempt to point the missile in the right direction
32 int Corkscrew_counterrotate = 1; // counterrotate every other missile
33 int Corkscrew_shrink = 0; // shrink the radius of every successive missile
34 float Corkscrew_shrink_val = 0.3f; // rate at which the radius shrinks
35 int Corkscrew_down_first = 1; // have the corkscrew go "down" first
36 
37 // current counterrotation and radius shrink values
39 
40 typedef struct cscrew_info {
41  int flags; // flags for the missile
42 
43  // info about the corkscrew effect for this missile
44  vec3d cen_p; // vector pointing to the "center" of the corkscrew
45  float radius; // radius of the corkscrew
46  matrix real_orient; // the orientation used when calling physics (bashed before rendering)
47  vec3d last_corkscrew_pos; // last position along the corkscrew
48 } cscrew_info;
49 
50 #define MAX_CORKSCREW_MISSILES 200
52 
53 // ------------------------------------------------------------------
54 // cscrew_level_init()
55 //
56 // Called at the start of each new mission
57 //
59 {
60  memset(Corkscrew_missiles, 0, sizeof(cscrew_info) * MAX_CORKSCREW_MISSILES);
61 }
62 
63 // ------------------------------------------------------------------
64 // cscrew_maybe_fire_missile()
65 //
66 // Check if there are any swarm missiles to fire, and if enough time
67 // has elapsed since last one fired, go ahead and fire it.
68 //
69 // This is called once per ship frame in ship_move()
70 //
71 void cscrew_maybe_fire_missile(int shipnum)
72 {
73  ship *sp;
74  ship_weapon *swp;
75  int weapon_info_index;
76 
77  Assert(shipnum >= 0 && shipnum < MAX_SHIPS );
78  sp = &Ships[shipnum];
79 
80  // make sure we're supposed to be firing some missiles
81  if ( sp->num_corkscrew_to_fire <= 0 ){
82  sp->corkscrew_missile_bank = -1;
83  return;
84  }
85 
86  // make sure we have a valid weapon bank
87  swp = &sp->weapons;
88  if ( sp->corkscrew_missile_bank == -1 ) {
89  sp->num_corkscrew_to_fire = 0;
90  return;
91  }
92 
93  weapon_info_index = swp->secondary_bank_weapons[sp->corkscrew_missile_bank];
94  Assert( weapon_info_index >= 0 && weapon_info_index < MAX_WEAPON_TYPES );
95 
96  // if current secondary bank is not a corkscrew missile, return
97  if ( !(Weapon_info[weapon_info_index].wi_flags & WIF_CORKSCREW) ) {
98  sp->num_corkscrew_to_fire = 0;
99  sp->corkscrew_missile_bank = -1;
100  return;
101  }
102 
104  sp->next_corkscrew_fire = timestamp(Weapon_info[weapon_info_index].cs_delay);
105  ship_fire_secondary( &Objects[sp->objnum], 1 );
106  sp->num_corkscrew_to_fire--;
107  }
108 }
109 
110 // ------------------------------------------------------------------
111 // cscrew_create()
112 //
113 // Get a free corkscrew missile entry, and initialize the struct members
114 //
115 int cscrew_create(object *obj)
116 {
117  int i;
118  cscrew_info *cscrewp = NULL;
119  weapon_info *wip;
120 
122 
123  for ( i = 0; i < MAX_CORKSCREW_MISSILES; i++ ) {
124  cscrewp = &Corkscrew_missiles[i];
125  if ( !(cscrewp->flags & CS_FLAG_USED) ) {
126  break;
127  }
128  }
129 
130  if ( i >= MAX_CORKSCREW_MISSILES ) {
131  nprintf(("Warning","No more corkscrew missiles are available\n"));
132  return -1;
133  }
134 
135  // mark the guy as "used"
136  cscrewp->flags = CS_FLAG_USED;
137 
138  // determine if he is counterrotating
139  if(wip->cs_crotate){
140  if(frand_range(0.0f, 1.0f) < 0.5f){
141  cscrewp->flags |= CS_FLAG_COUNTER;
142  }
143  }
144 
145  // get the "center" pointing vector
146  vec3d neg;
147  neg = obj->orient.vec.uvec;
149  vm_vec_negate(&neg);
150  }
151  vm_vec_scale_add2(&cscrewp->cen_p, &neg, wip->cs_radius);
152 
153  // move the missile up so that the corkscrew point is at the muzzle of the gun
154  // vm_vec_scale_add2(&obj->pos, &obj->orient.vec.uvec, Corkscrew_radius);
155 
156  // store some initial helix params
157  cscrewp->real_orient = obj->orient;
158  cscrewp->last_corkscrew_pos = obj->pos;
159 
160  return i;
161 }
162 
163 // ------------------------------------------------------------------
164 // cscrew_delete()
165 //
166 //
167 void cscrew_delete(int i)
168 {
169  if ( !(Corkscrew_missiles[i].flags & CS_FLAG_USED) ) {
170  Int3();
171  }
172 
173  memset(&Corkscrew_missiles[i], 0, sizeof(cscrew_info));
174 }
175 
176 // pre process the corkscrew weapon by putting him in the "center" of his corkscrew
178 {
179  cscrew_info *ci;
180 
181  // check stuff
182  Assert(objp->type == OBJ_WEAPON);
183  Assert(Weapons[objp->instance].cscrew_index >= 0);
184  Assert(Corkscrew_missiles[Weapons[objp->instance].cscrew_index].flags & CS_FLAG_USED);
185 
186  ci = &Corkscrew_missiles[Weapons[objp->instance].cscrew_index];
187 
188  // unrotate the missile itself
189  if(Corkscrew_helix){
190  // restore the "real" matrix now
191  objp->orient = ci->real_orient;
192  }
193  // move the missile back to the center of the corkscrew
194  vm_vec_add2(&objp->pos, &ci->cen_p);
195 }
196 
197 // post process the corkscrew weapon by putting him back to the right spot on his corkscrew
199 {
200  vec3d cen, neg;
201  vec3d new_pt;
202  weapon *wp;
203  weapon_info *wip;
204  cscrew_info *ci;
205  float twist_val;
206 
207  // check stuff
208  Assert(objp->type == OBJ_WEAPON);
209  Assert(Weapons[objp->instance].cscrew_index >= 0);
210  Assert(Corkscrew_missiles[Weapons[objp->instance].cscrew_index].flags & CS_FLAG_USED);
211 
212  // get various useful pointers
213  wp = &Weapons[objp->instance];
214  wip = &Weapon_info[wp->weapon_info_index];
215  ci = &Corkscrew_missiles[wp->cscrew_index];
216 
217  // move to the outside of the corkscrew
218  neg = ci->cen_p;
219  cen = objp->pos;
220  vm_vec_negate(&neg);
221  vm_vec_add2(&objp->pos, &neg);
222 
223  // determine what direction (clockwise or counterclockwise) the missile will spin
224  twist_val = ci->flags & CS_FLAG_COUNTER ? -wip->cs_twist : wip->cs_twist;
225  twist_val *= flFrametime;
226 
227  // rotate the missile position
228  vm_rot_point_around_line(&new_pt, &objp->pos, twist_val, &cen, &objp->orient.vec.fvec);
229  objp->pos = new_pt;
230 
231  // rotate the missile itself
232  if(Corkscrew_helix){
233  vec3d dir;
234 
235  // compute a "fake" orient and store the old one for safekeeping
236  ci->real_orient = objp->orient;
237  vm_vec_sub(&dir, &objp->pos, &ci->last_corkscrew_pos);
238  vm_vec_normalize(&dir);
239  vm_vector_2_matrix(&objp->orient, &dir, NULL, NULL);
240 
241  // mark down this position so we can orient nicely _next_ frame
242  ci->last_corkscrew_pos = objp->pos;
243  }
244 
245  // get the new center pointing vector
246  vm_vec_sub(&ci->cen_p, &cen, &objp->pos);
247 
248  // do trail stuff here
249  if ( wp->trail_ptr != NULL ) {
250  if (trail_stamp_elapsed(wp->trail_ptr)) {
251  trail_add_segment( wp->trail_ptr, &objp->pos );
253  } else {
254  trail_set_segment( wp->trail_ptr, &objp->pos );
255  }
256  }
257 }
258 
259 // debug console functionality
261 {
262  dc_printf("Corkscrew settings\n\n");
263  dc_printf("Delay (cscrew_delay) : %d\n",Corkscrew_missile_delay);
264  dc_printf("Count (cscrew_count) : %d\n",Corkscrew_num_missiles_fired);
265  dc_printf("Radius (cscrew_radius) : %f\n",Corkscrew_radius);
266  dc_printf("Twist (cscrew_twist) : %f\n",Corkscrew_twist);
267  if(Corkscrew_helix){
268  dc_printf("Helix (cscrew_helix): ON\n");
269  } else {
270  dc_printf("Helix (cscrew_helix): OFF\n");
271  }
273  dc_printf("Counterrotate (cscrew_counter): ON\n");
274  } else {
275  dc_printf("Counterrotate (cscrew_counter): OFF\n");
276  }
277  if(Corkscrew_shrink){
278  dc_printf("Shrink (cscrew_shrink): ON\n");
279  } else {
280  dc_printf("Shrink (cscrew_shrink): OFF\n");
281  }
282  dc_printf("Corkscrew shrink (cscrew_shrinkval): %f\n", Corkscrew_shrink_val);
284  dc_printf("Corkscrew down first : ON\n");
285  } else {
286  dc_printf("Corkscrew down first : OFF\n");
287  }
288 }
289 
290 DCF(cscrew, "Listing of corkscrew missile debug console functions")
291 {
293 }
294 
295 DCF(cscrew_delay, "Change the delay between corkscrew firing")
296 {
299 }
300 
301 DCF(cscrew_count, "Change the # of corkscrew missiles fired")
302 {
305 }
306 
307 DCF(cscrew_radius, "Change the radius of corkscrew missiles")
308 {
311 }
312 
313 DCF(cscrew_twist, "Change the rate of the corkscrew twist")
314 {
317 }
318 
319 DCF(cscrew_helix, "Attempt to orient missile nicely along the corkscrew")
320 {
322 
324 }
325 
326 DCF(cscrew_counter, "Counterrotate every other missile")
327 {
329 
331 }
332 
333 DCF(cscrew_shrink, "Shrink the radius of every other missile")
334 {
336 
338 }
339 
340 DCF(cscrew_shrinkval, "Change the rate at which the radii shrink")
341 {
344 }
345 
346 DCF(cscrew_down, "Cause the missile to spiral down first")
347 {
349 
351 }
void cscrew_delete(int i)
Definition: corkscrew.cpp:167
short cscrew_index
Definition: weapon.h:204
int timestamp(int delta_ms)
Definition: timer.cpp:226
int i
Definition: multi_pxo.cpp:466
weapon Weapons[MAX_WEAPONS]
Definition: weapons.cpp:78
struct cscrew_info cscrew_info
int objnum
Definition: ship.h:537
float frand_range(float min, float max)
Return a floating point number in the range min..max.
Definition: floating.cpp:50
weapon_info Weapon_info[MAX_WEAPON_TYPES]
Definition: weapons.cpp:79
ship_weapon weapons
Definition: ship.h:658
matrix real_orient
Definition: corkscrew.cpp:46
int Corkscrew_num_missiles_fired
Definition: corkscrew.cpp:28
float flFrametime
Definition: fredstubs.cpp:22
Definition: weapon.h:163
int trail_stamp_elapsed(trail *trailp)
Definition: trails.cpp:572
#define MAX_SHIPS
Definition: globals.h:37
#define CS_FLAG_USED
Definition: corkscrew.cpp:23
void cscrew_level_init()
Definition: corkscrew.cpp:58
int corkscrew_missile_bank
Definition: ship.h:565
Assert(pm!=NULL)
Definition: pstypes.h:88
#define WIF_CORKSCREW
Definition: weapon.h:71
void cscrew_process_post(object *objp)
Definition: corkscrew.cpp:198
GLclampf f
Definition: Glext.h:7097
int cs_crotate
Definition: weapon.h:475
vec3d cen_p
Definition: corkscrew.cpp:44
void vm_vec_scale_add2(vec3d *dest, const vec3d *src, float k)
Definition: vecmat.cpp:284
int ship_fire_secondary(object *obj, int allow_swarm)
Definition: ship.cpp:11799
object * objp
Definition: lua.cpp:3105
#define Int3()
Definition: pstypes.h:292
vec3d pos
Definition: object.h:152
float Corkscrew_shrink_val
Definition: corkscrew.cpp:34
#define MAX_CORKSCREW_MISSILES
Definition: corkscrew.cpp:50
int weapon_info_index
Definition: weapon.h:164
ubyte num_corkscrew_to_fire
Definition: ship.h:564
#define CS_FLAG_COUNTER
Definition: corkscrew.cpp:24
int instance
Definition: object.h:150
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
struct matrix::@228::@230 vec
#define nprintf(args)
Definition: pstypes.h:239
trail * trail_ptr
Definition: weapon.h:182
int Corkscrew_missile_delay
Definition: corkscrew.cpp:27
#define OBJ_WEAPON
Definition: object.h:33
#define MAX_WEAPON_TYPES
Definition: globals.h:73
void vm_rot_point_around_line(vec3d *out, const vec3d *in, float angle, const vec3d *line_point, const vec3d *line_dir)
Definition: vecmat.cpp:1395
#define vm_vec_negate(v)
Definition: vecmat.h:70
float cs_twist
Definition: weapon.h:474
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:104
Definition: ship.h:534
object Objects[MAX_OBJECTS]
Definition: object.cpp:62
void trail_add_segment(trail *trailp, vec3d *pos)
Definition: trails.cpp:480
int next_corkscrew_fire
Definition: ship.h:566
int Corkscrew_shrink
Definition: corkscrew.cpp:33
matrix orient
Definition: object.h:153
void dc_stuff_float(float *f)
Stuffs a float to the given variable.
GLbitfield flags
Definition: Glext.h:6722
float Corkscrew_radius_cur
Definition: corkscrew.cpp:38
void dc_stuff_int(int *i)
Stuffs an int to the given variable. Supports binary (0b), hexadecimal (0x), and octal (0o) formats...
int Corkscrew_down_first
Definition: corkscrew.cpp:35
vec3d last_corkscrew_pos
Definition: corkscrew.cpp:47
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:168
int cscrew_create(object *obj)
Definition: corkscrew.cpp:115
ship Ships[MAX_SHIPS]
Definition: ship.cpp:122
float cs_radius
Definition: weapon.h:473
DCF(cscrew,"Listing of corkscrew missile debug console functions")
Definition: corkscrew.cpp:290
void trail_set_stamp(trail *trailp)
Definition: trails.cpp:577
float Corkscrew_radius
Definition: corkscrew.cpp:29
void cscrew_process_pre(object *objp)
Definition: corkscrew.cpp:177
An overhauled/updated debug console to allow monitoring, testing, and general debugging of new featur...
#define timestamp_elapsed(stamp)
Definition: timer.h:102
void cscrew_display_dcf()
Definition: corkscrew.cpp:260
GLsizei GLsizei GLuint * obj
Definition: Glext.h:5619
void trail_set_segment(trail *trailp, vec3d *pos)
Definition: trails.cpp:498
cscrew_info Corkscrew_missiles[MAX_CORKSCREW_MISSILES]
Definition: corkscrew.cpp:51
void dc_printf(const char *format,...)
Prints the given char string to the debug console.
Definition: console.cpp:358
int Corkscrew_helix
Definition: corkscrew.cpp:31
void cscrew_maybe_fire_missile(int shipnum)
Definition: corkscrew.cpp:71
char type
Definition: object.h:146
#define wp(p)
Definition: modelsinc.h:69
int Corkscrew_counterrotate
Definition: corkscrew.cpp:32
float Corkscrew_twist
Definition: corkscrew.cpp:30
float vm_vec_normalize(vec3d *v)
Definition: vecmat.cpp:460
float radius
Definition: corkscrew.cpp:45