2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
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
10 * $Logfile: /Freespace2/code/Hud/HudArtillery.cpp $
17 * Revision 1.6 2005/10/01 22:04:58 taylor
18 * fix FS1 (de)briefing voices, the directory names are different in FS1
19 * hard code the table values so that the fs1.vp file isn't needed
20 * hard code a mission fix for sm2-08a since a have no idea how to fix it otherwise
21 * generally cleanup some FS1 code
22 * fix volume sliders in the options screen that never went all the way up
24 * Revision 1.5 2002/06/17 06:33:09 relnev
25 * ryan's struct patch for gcc 2.95
27 * Revision 1.4 2002/06/09 04:41:21 relnev
28 * added copyright header
30 * Revision 1.3 2002/05/07 03:16:45 theoddone33
31 * The Great Newline Fix
33 * Revision 1.2 2002/05/03 13:34:33 theoddone33
36 * Revision 1.1.1.1 2002/05/03 03:28:09 root
40 * 5 6/01/99 8:35p Dave
41 * Finished lockarm weapons. Added proper supercap weapons/damage. Added
42 * awacs-set-radius sexpression.
44 * 4 4/28/99 11:36p Dave
45 * Tweaked up subspace missile strike a bit,
47 * 3 4/28/99 11:13p Dave
48 * Temporary checkin of artillery code.
50 * 2 4/20/99 6:39p Dave
51 * Almost done with artillery targeting. Added support for downloading
52 * images on the PXO screen.
54 * 1 4/20/99 12:00a Dave
60 #include "hudartillery.h"
64 #include "alphacolors.h"
66 // -----------------------------------------------------------------------------------------------------------------------
67 // ARTILLERY DEFINES/VARS
71 // -----------------------------------------------------------------------------------------------------------------------
72 // ARTILLERY FUNCTIONS
79 #include "fireballs.h"
80 #include "freespace.h"
82 // test code for subspace missile strike -------------------------------------------
85 int Ssm_info_count = 0;
86 ssm_info Ssm_info[MAX_SSM_TYPES];
88 // list of active/free strikes
89 ssm_strike Ssm_strikes[MAX_SSM_STRIKES];
90 ssm_strike Ssm_free_list;
91 ssm_strike Ssm_used_list;
92 int Num_ssm_strikes = 0;
99 char weapon_name[NAME_LENGTH+1] = "";
102 read_file_text("ssm.tbl");
107 while(!optional_string("#end")){
108 // another ssm definition
109 if(optional_string("$SSM:")){
110 // pointer to info struct
111 if(Ssm_info_count >= MAX_SSM_TYPES){
114 s = &Ssm_info[Ssm_info_count];
118 stuff_string(s->name, F_NAME, NULL);
121 required_string("+Weapon:");
122 stuff_string(weapon_name, F_NAME, NULL);
123 required_string("+Count:");
124 stuff_int(&s->count);
125 required_string("+WarpRadius:");
126 stuff_float(&s->warp_radius);
127 required_string("+WarpTime:");
128 stuff_float(&s->warp_time);
129 required_string("+Radius:");
130 stuff_float(&s->radius);
131 required_string("+Offset:");
132 stuff_float(&s->offset);
134 // see if we have a valid weapon
135 s->weapon_info_index = -1;
136 s->weapon_info_index = weapon_name_lookup(weapon_name);
137 if(s->weapon_info_index >= 0){
143 } catch (parse_error_t rval) {
144 Error(LOCATION, "Unable to parse ssm.tbl! Code = %i.\n", (int)rval);
153 void ssm_get_random_start_pos(vector *out, vector *start, matrix *orient, int ssm_index)
156 ssm_info *s = &Ssm_info[ssm_index];
158 // get a random vector in the circle of the firing plane
159 vm_vec_random_in_circle(&temp, start, orient, s->radius, 1);
162 vm_vec_scale_add(out, &temp, &orient->v.fvec, s->offset);
166 void ssm_level_init()
171 list_init( &Ssm_free_list );
172 list_init( &Ssm_used_list );
174 // Link all object slots into the free list
175 for (i=0; i<MAX_SSM_STRIKES; i++) {
176 list_append(&Ssm_free_list, &Ssm_strikes[i] );
180 // start a subspace missile effect
181 void ssm_create(vector *target, vector *start, int ssm_index, ssm_firing_info *override)
187 if (Num_ssm_strikes >= MAX_SSM_STRIKES ) {
189 mprintf(("Ssm creation failed - too many ssms!\n" ));
195 SDL_assert(target != NULL);
199 SDL_assert(start != NULL);
203 if((ssm_index < 0) || (ssm_index >= MAX_SSM_TYPES)){
207 // Find next available trail
208 ssm = GET_FIRST(&Ssm_free_list);
209 SDL_assert( ssm != &Ssm_free_list ); // shouldn't have the dummy element
211 // remove trailp from the free list
212 list_remove( &Ssm_free_list, ssm );
214 // insert trailp onto the end of used list
215 list_append( &Ssm_used_list, ssm );
222 // override in multiplayer
223 if(override != NULL){
224 ssm->sinfo = *override;
226 // single player or the server
228 // forward orientation
230 vm_vec_sub(&temp, target, start);
231 vm_vec_normalize(&temp);
232 vm_vector_2_matrix(&dir, &temp, NULL, NULL);
235 ssm->sinfo.ssm_index = ssm_index;
236 ssm->sinfo.target = *target;
237 for(idx=0; idx<Ssm_info[ssm_index].count; idx++){
238 ssm->sinfo.delay_stamp[idx] = timestamp(200 + (int)frand_range(-199.0f, 1000.0f));
239 ssm_get_random_start_pos(&ssm->sinfo.start_pos[idx], start, &dir, ssm_index);
242 // if we're the server, send a packet
243 if(MULTIPLAYER_MASTER){
248 // clear timestamps, handles, etc
249 for(idx=0; idx<MAX_SSM_COUNT; idx++){
250 ssm->done_flags[idx] = 0;
251 ssm->fireballs[idx] = -1;
255 // delete a finished ssm effect
256 void ssm_delete(ssm_strike *ssm)
258 // remove objp from the used list
259 list_remove( &Ssm_used_list, ssm );
261 // add objp to the end of the free
262 list_append( &Ssm_free_list, ssm );
267 nprintf(("General", "Recycling SSM, %d left", Num_ssm_strikes));
270 // process subspace missile stuff
274 ssm_strike *moveup, *next_one;
277 // process all strikes
278 moveup=GET_FIRST(&Ssm_used_list);
279 while ( moveup!=END_OF_LIST(&Ssm_used_list) ) {
281 if(moveup->sinfo.ssm_index < 0){
284 si = &Ssm_info[moveup->sinfo.ssm_index];
286 // check all the individual missiles
288 for(idx=0; idx<si->count; idx++){
289 // if this guy is not marked as done
290 if(!moveup->done_flags[idx]){
293 // if he already has the fireball effect
294 if(moveup->fireballs[idx] >= 0){
295 // if the warp effect is half done, fire the missile
296 if((1.0f - fireball_lifeleft_percent(&Objects[moveup->fireballs[idx]])) >= 0.5f){
297 // get an orientation
301 vm_vec_sub(&temp, &moveup->sinfo.target, &moveup->sinfo.start_pos[idx]);
302 vm_vec_normalize(&temp);
303 vm_vector_2_matrix(&orient, &temp, NULL, NULL);
305 // fire the missile and flash the screen
306 weapon_create(&moveup->sinfo.start_pos[idx], &orient, si->weapon_info_index, -1, 1, -1, 1);
308 // this makes this particular missile done
309 moveup->done_flags[idx] = 1;
312 // maybe create his warpin effect
313 else if((moveup->sinfo.delay_stamp[idx] >= 0) && timestamp_elapsed(moveup->sinfo.delay_stamp[idx])){
314 // get an orientation
318 vm_vec_sub(&temp, &moveup->sinfo.target, &moveup->sinfo.start_pos[idx]);
319 vm_vec_normalize(&temp);
320 vm_vector_2_matrix(&orient, &temp, NULL, NULL);
321 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);
326 next_one = GET_NEXT(moveup);
332 moveup=GET_NEXT(moveup);
337 // test code for subspace missile strike -------------------------------------------
340 void hud_init_artillery()
344 // update all hud artillery related stuff
345 void hud_artillery_update()
349 // render all hud artillery related stuff
350 void hud_artillery_render()
352 // render how long the player has been painting his target
353 if((Player_ai != NULL) && (Player_ai->artillery_objnum >= 0)){
354 gr_set_color_fast(&Color_bright_blue);
355 gr_printf(10, 50, "%f", Player_ai->artillery_lock_time);