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