]> icculus.org git repositories - taylor/freespace2.git/blob - src/hud/hudartillery.cpp
Initial revision
[taylor/freespace2.git] / src / hud / hudartillery.cpp
1 /*
2  * $Logfile: /Freespace2/code/Hud/HudArtillery.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  *
8  * $Log$
9  * Revision 1.1  2002/05/03 03:28:09  root
10  * Initial revision
11  *  
12  * 
13  * 5     6/01/99 8:35p Dave
14  * Finished lockarm weapons. Added proper supercap weapons/damage. Added
15  * awacs-set-radius sexpression.
16  * 
17  * 4     4/28/99 11:36p Dave
18  * Tweaked up subspace missile strike a bit,
19  * 
20  * 3     4/28/99 11:13p Dave
21  * Temporary checkin of artillery code.
22  * 
23  * 2     4/20/99 6:39p Dave
24  * Almost done with artillery targeting. Added support for downloading
25  * images on the PXO screen.
26  * 
27  * 1     4/20/99 12:00a Dave
28  * 
29  * 
30  * $NoKeywords: $
31  */
32
33 #include "hudartillery.h"
34 #include "ai.h"
35 #include "player.h"
36 #include "2d.h"
37 #include "alphacolors.h"
38
39 // -----------------------------------------------------------------------------------------------------------------------
40 // ARTILLERY DEFINES/VARS
41 //
42
43
44 // -----------------------------------------------------------------------------------------------------------------------
45 // ARTILLERY FUNCTIONS
46 //
47
48 #include "linklist.h"
49 #include "timer.h"
50 #include "parselo.h"
51 #include "multi.h"
52 #include "fireballs.h"
53 #include "freespace.h"
54
55 // test code for subspace missile strike -------------------------------------------
56
57 #define MAX_SSM_TYPES                   10
58
59 // global ssm types
60 typedef struct ssm_info {
61         char                    name[NAME_LENGTH+1];                            // strike name
62         int                     count;                                                          // # of missiles in this type of strike
63         int                     weapon_info_index;                              // missile type
64         float                   warp_radius;                                            // radius of associated warp effect     
65         float                   warp_time;                                                      // how long the warp effect lasts
66         float                   radius;                                                         // radius around the shooting ship      
67         float                   offset;                                                         // offset in front of the shooting ship
68 } ssm_info;
69
70 int Ssm_info_count = 0;
71 ssm_info Ssm_info[MAX_SSM_TYPES];
72
73 #define MAX_SSM_STRIKES                 10
74 #define MAX_SSM_COUNT                   10
75
76 // creation info for the strike (useful for multiplayer)
77 typedef struct ssm_firing_info {
78         int                     delay_stamp[MAX_SSM_COUNT];     // timestamps
79         vector          start_pos[MAX_SSM_COUNT];               // start positions
80         
81         int                     ssm_index;                                                      // index info ssm_info array
82         vector          target;                                                         // target for the strike        
83 } ssm_firing_info;
84
85 // the strike itself
86 typedef struct ssm_strike {
87         int                     fireballs[MAX_SSM_COUNT];               // warpin effect fireballs
88         int                     done_flags[MAX_SSM_COUNT];              // when we've fired off the individual missiles
89         
90         // this is the info that controls how the strike behaves (just like for beam weapons)
91         ssm_firing_info         sinfo;
92
93         ssm_strike      *next, *prev;                                           // for list
94 } ssm_strike;
95
96 // list of active/free strikes
97 ssm_strike Ssm_strikes[MAX_SSM_STRIKES];
98 ssm_strike Ssm_free_list;
99 ssm_strike Ssm_used_list;
100 int Num_ssm_strikes = 0;
101
102 // game init
103 void ssm_init()
104 {       
105         ssm_info bogus, *s;
106         char weapon_name[NAME_LENGTH+1] = "";
107
108         read_file_text("ssm.tbl");
109         reset_parse();
110
111         // parse the table
112         Ssm_info_count = 0;
113         while(!optional_string("#end")){
114                 // another ssm definition
115                 if(optional_string("$SSM:")){
116                         // pointer to info struct
117                         if(Ssm_info_count >= MAX_SSM_TYPES){
118                                 s = &bogus;
119                         } else {
120                                 s = &Ssm_info[Ssm_info_count];
121                         }
122
123                         // name
124                         stuff_string(s->name, F_NAME, NULL);
125
126                         // stuff data
127                         required_string("+Weapon:");
128                         stuff_string(weapon_name, F_NAME, NULL);
129                         required_string("+Count:");
130                         stuff_int(&s->count);
131                         required_string("+WarpRadius:");
132                         stuff_float(&s->warp_radius);
133                         required_string("+WarpTime:");
134                         stuff_float(&s->warp_time);
135                         required_string("+Radius:");
136                         stuff_float(&s->radius);
137                         required_string("+Offset:");
138                         stuff_float(&s->offset);
139
140                         // see if we have a valid weapon
141                         s->weapon_info_index = -1;
142                         s->weapon_info_index = weapon_name_lookup(weapon_name);
143                         if(s->weapon_info_index >= 0){
144                                 // valid
145                                 Ssm_info_count++;
146                         }
147                 }
148         }
149 }
150
151 void ssm_get_random_start_pos(vector *out, vector *start, matrix *orient, int ssm_index)
152 {
153         vector temp;
154         ssm_info *s = &Ssm_info[ssm_index];
155
156         // get a random vector in the circle of the firing plane
157         vm_vec_random_in_circle(&temp, start, orient, s->radius, 1);
158
159         // offset it a bit
160         vm_vec_scale_add(out, &temp, &orient->fvec, s->offset);
161 }
162
163 // level init
164 void ssm_level_init()
165 {
166         int i;
167
168         Num_ssm_strikes = 0;
169         list_init( &Ssm_free_list );
170         list_init( &Ssm_used_list );
171
172         // Link all object slots into the free list
173         for (i=0; i<MAX_SSM_STRIKES; i++)       {
174                 list_append(&Ssm_free_list, &Ssm_strikes[i] );
175         }
176 }
177
178 // start a subspace missile effect
179 void ssm_create(vector *target, vector *start, int ssm_index, ssm_firing_info *override)
180 {       
181         ssm_strike *ssm;                
182         matrix dir;
183         int idx;
184
185         if (Num_ssm_strikes >= MAX_SSM_STRIKES ) {
186                 #ifndef NDEBUG
187                 mprintf(("Ssm creation failed - too many ssms!\n" ));
188                 #endif
189                 return;
190         }
191
192         // sanity
193         Assert(target != NULL);
194         if(target == NULL){
195                 return;
196         }
197         Assert(start != NULL);
198         if(start == NULL){
199                 return;
200         }
201         if((ssm_index < 0) || (ssm_index >= MAX_SSM_TYPES)){
202                 return;
203         }
204
205         // Find next available trail
206         ssm = GET_FIRST(&Ssm_free_list);
207         Assert( ssm != &Ssm_free_list );                // shouldn't have the dummy element
208
209         // remove trailp from the free list
210         list_remove( &Ssm_free_list, ssm );
211         
212         // insert trailp onto the end of used list
213         list_append( &Ssm_used_list, ssm );
214
215         // increment counter
216         Num_ssm_strikes++;      
217
218         // Init the ssm data
219
220         // override in multiplayer
221         if(override != NULL){
222                 ssm->sinfo = *override;
223         }
224         // single player or the server
225         else {
226                 // forward orientation
227                 vector temp;
228                 vm_vec_sub(&temp, target, start);
229                 vm_vec_normalize(&temp);
230                 vm_vector_2_matrix(&dir, &temp, NULL, NULL);
231
232                 // stuff info
233                 ssm->sinfo.ssm_index = ssm_index;
234                 ssm->sinfo.target = *target;
235                 for(idx=0; idx<Ssm_info[ssm_index].count; idx++){
236                         ssm->sinfo.delay_stamp[idx] = timestamp(200 + (int)frand_range(-199.0f, 1000.0f));
237                         ssm_get_random_start_pos(&ssm->sinfo.start_pos[idx], start, &dir, ssm_index);
238                 }
239
240                 // if we're the server, send a packet
241                 if(MULTIPLAYER_MASTER){
242                         //
243                 }
244         }
245
246         // clear timestamps, handles, etc
247         for(idx=0; idx<MAX_SSM_COUNT; idx++){
248                 ssm->done_flags[idx] = 0;
249                 ssm->fireballs[idx] = -1;
250         }
251 }
252
253 // delete a finished ssm effect
254 void ssm_delete(ssm_strike *ssm)
255 {
256         // remove objp from the used list
257         list_remove( &Ssm_used_list, ssm );
258
259         // add objp to the end of the free
260         list_append( &Ssm_free_list, ssm );
261
262         // decrement counter
263         Num_ssm_strikes--;
264
265         nprintf(("General", "Recycling SSM, %d left", Num_ssm_strikes));
266 }
267
268 // process subspace missile stuff
269 void ssm_process()
270 {
271         int idx, finished;
272         ssm_strike *moveup, *next_one;
273         ssm_info *si;
274         
275         // process all strikes  
276         moveup=GET_FIRST(&Ssm_used_list);
277         while ( moveup!=END_OF_LIST(&Ssm_used_list) )   {               
278                 // get the type
279                 if(moveup->sinfo.ssm_index < 0){
280                         continue;
281                 }
282                 si = &Ssm_info[moveup->sinfo.ssm_index];
283
284                 // check all the individual missiles
285                 finished = 1;
286                 for(idx=0; idx<si->count; idx++){
287                         // if this guy is not marked as done
288                         if(!moveup->done_flags[idx]){
289                                 finished = 0;                           
290
291                                 // if he already has the fireball effect
292                                 if(moveup->fireballs[idx] >= 0){
293                                         // if the warp effect is half done, fire the missile
294                                         if((1.0f - fireball_lifeleft_percent(&Objects[moveup->fireballs[idx]])) >= 0.5f){
295                                                 // get an orientation
296                                                 vector temp;
297                                                 matrix orient;
298
299                                                 vm_vec_sub(&temp, &moveup->sinfo.target, &moveup->sinfo.start_pos[idx]);
300                                                 vm_vec_normalize(&temp);
301                                                 vm_vector_2_matrix(&orient, &temp, NULL, NULL);
302
303                                                 // fire the missile and flash the screen
304                                                 weapon_create(&moveup->sinfo.start_pos[idx], &orient, si->weapon_info_index, -1, 1, -1, 1);
305
306                                                 // this makes this particular missile done
307                                                 moveup->done_flags[idx] = 1;
308                                         }
309                                 } 
310                                 // maybe create his warpin effect
311                                 else if((moveup->sinfo.delay_stamp[idx] >= 0) && timestamp_elapsed(moveup->sinfo.delay_stamp[idx])){
312                                         // get an orientation
313                                         vector temp;
314                                         matrix orient;
315
316                                         vm_vec_sub(&temp, &moveup->sinfo.target, &moveup->sinfo.start_pos[idx]);
317                                         vm_vec_normalize(&temp);
318                                         vm_vector_2_matrix(&orient, &temp, NULL, NULL);
319                                         moveup->fireballs[idx] = fireball_create(&moveup->sinfo.start_pos[idx], FIREBALL_WARP_EFFECT, -1, si->warp_radius, 0, &vmd_zero_vector, si->warp_time, 0, &orient);
320                                 }
321                         }
322                 }
323                 if(finished){
324                         next_one = GET_NEXT(moveup);                    
325                         ssm_delete(moveup);                                                                                                                     
326                         moveup = next_one;
327                         continue;
328                 }
329                 
330                 moveup=GET_NEXT(moveup);
331         }       
332 }
333
334
335 // test code for subspace missile strike -------------------------------------------
336
337 // level init
338 void hud_init_artillery()
339 {
340 }
341
342 // update all hud artillery related stuff
343 void hud_artillery_update()
344 {
345 }
346
347 // render all hud artillery related stuff
348 void hud_artillery_render()
349 {
350         // render how long the player has been painting his target      
351         if((Player_ai != NULL) && (Player_ai->artillery_objnum >= 0)){
352                 gr_set_color_fast(&Color_bright_blue);
353                 gr_printf(10, 50, "%f", Player_ai->artillery_lock_time);
354         }
355 }