2 * $Logfile: /Freespace2/code/Hud/HudArtillery.cpp $
9 * Revision 1.1 2002/05/03 03:28:09 root
13 * 5 6/01/99 8:35p Dave
14 * Finished lockarm weapons. Added proper supercap weapons/damage. Added
15 * awacs-set-radius sexpression.
17 * 4 4/28/99 11:36p Dave
18 * Tweaked up subspace missile strike a bit,
20 * 3 4/28/99 11:13p Dave
21 * Temporary checkin of artillery code.
23 * 2 4/20/99 6:39p Dave
24 * Almost done with artillery targeting. Added support for downloading
25 * images on the PXO screen.
27 * 1 4/20/99 12:00a Dave
33 #include "hudartillery.h"
37 #include "alphacolors.h"
39 // -----------------------------------------------------------------------------------------------------------------------
40 // ARTILLERY DEFINES/VARS
44 // -----------------------------------------------------------------------------------------------------------------------
45 // ARTILLERY FUNCTIONS
52 #include "fireballs.h"
53 #include "freespace.h"
55 // test code for subspace missile strike -------------------------------------------
57 #define MAX_SSM_TYPES 10
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
70 int Ssm_info_count = 0;
71 ssm_info Ssm_info[MAX_SSM_TYPES];
73 #define MAX_SSM_STRIKES 10
74 #define MAX_SSM_COUNT 10
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
81 int ssm_index; // index info ssm_info array
82 vector target; // target for the strike
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
90 // this is the info that controls how the strike behaves (just like for beam weapons)
91 ssm_firing_info sinfo;
93 ssm_strike *next, *prev; // for list
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;
106 char weapon_name[NAME_LENGTH+1] = "";
108 read_file_text("ssm.tbl");
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){
120 s = &Ssm_info[Ssm_info_count];
124 stuff_string(s->name, F_NAME, NULL);
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);
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){
151 void ssm_get_random_start_pos(vector *out, vector *start, matrix *orient, int ssm_index)
154 ssm_info *s = &Ssm_info[ssm_index];
156 // get a random vector in the circle of the firing plane
157 vm_vec_random_in_circle(&temp, start, orient, s->radius, 1);
160 vm_vec_scale_add(out, &temp, &orient->fvec, s->offset);
164 void ssm_level_init()
169 list_init( &Ssm_free_list );
170 list_init( &Ssm_used_list );
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] );
178 // start a subspace missile effect
179 void ssm_create(vector *target, vector *start, int ssm_index, ssm_firing_info *override)
185 if (Num_ssm_strikes >= MAX_SSM_STRIKES ) {
187 mprintf(("Ssm creation failed - too many ssms!\n" ));
193 Assert(target != NULL);
197 Assert(start != NULL);
201 if((ssm_index < 0) || (ssm_index >= MAX_SSM_TYPES)){
205 // Find next available trail
206 ssm = GET_FIRST(&Ssm_free_list);
207 Assert( ssm != &Ssm_free_list ); // shouldn't have the dummy element
209 // remove trailp from the free list
210 list_remove( &Ssm_free_list, ssm );
212 // insert trailp onto the end of used list
213 list_append( &Ssm_used_list, ssm );
220 // override in multiplayer
221 if(override != NULL){
222 ssm->sinfo = *override;
224 // single player or the server
226 // forward orientation
228 vm_vec_sub(&temp, target, start);
229 vm_vec_normalize(&temp);
230 vm_vector_2_matrix(&dir, &temp, NULL, NULL);
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);
240 // if we're the server, send a packet
241 if(MULTIPLAYER_MASTER){
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;
253 // delete a finished ssm effect
254 void ssm_delete(ssm_strike *ssm)
256 // remove objp from the used list
257 list_remove( &Ssm_used_list, ssm );
259 // add objp to the end of the free
260 list_append( &Ssm_free_list, ssm );
265 nprintf(("General", "Recycling SSM, %d left", Num_ssm_strikes));
268 // process subspace missile stuff
272 ssm_strike *moveup, *next_one;
275 // process all strikes
276 moveup=GET_FIRST(&Ssm_used_list);
277 while ( moveup!=END_OF_LIST(&Ssm_used_list) ) {
279 if(moveup->sinfo.ssm_index < 0){
282 si = &Ssm_info[moveup->sinfo.ssm_index];
284 // check all the individual missiles
286 for(idx=0; idx<si->count; idx++){
287 // if this guy is not marked as done
288 if(!moveup->done_flags[idx]){
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
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);
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);
306 // this makes this particular missile done
307 moveup->done_flags[idx] = 1;
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
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);
324 next_one = GET_NEXT(moveup);
330 moveup=GET_NEXT(moveup);
335 // test code for subspace missile strike -------------------------------------------
338 void hud_init_artillery()
342 // update all hud artillery related stuff
343 void hud_artillery_update()
347 // render all hud artillery related stuff
348 void hud_artillery_render()
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);