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