FS2_Open
Open source remastering of the Freespace 2 engine
hudlock.cpp
Go to the documentation of this file.
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 the
6  * source.
7  *
8 */
9 
10 
11 
12 
13 #include "ai/ai.h"
14 #include "debugconsole/console.h"
15 #include "gamesnd/gamesnd.h"
16 #include "globalincs/linklist.h"
17 #include "hud/hudlock.h"
18 #include "iff_defs/iff_defs.h"
19 #include "io/timer.h"
20 #include "mission/missionparse.h"
21 #include "network/multi.h"
22 #include "object/object.h"
23 #include "playerman/player.h"
24 #include "render/3d.h"
25 #include "ship/ship.h"
26 #include "weapon/emp.h"
27 #include "weapon/weapon.h"
28 
29 
30 // Used for aspect locks. -MageKing17
31 #define VIRTUAL_FRAME_HALF_WIDTH 320.0f
32 #define VIRTUAL_FRAME_HALF_HEIGHT 240.0f
33 
34 
36 
37 static float Lock_start_dist;
38 
41 
43  19,
44  30
45 };
47  19,
48  30
49 };
50 
51 // the locked triangles (that orbit lock indicator) dimensions
53  4.0f,
54  6.5f
55 };
57  4.0f,
58  6.5f
59 };
60 
62  { 15, 24 },
63  { 17, 28 }
64 };
66  15,
67  25
68 };
69 
70 #define LOCK_GAUGE_BLINK_RATE 5 // blinks/sec
71 
73  { 16, 26 },
74  { 31, 50 }
75 };
77  { 16, 26 },
78  { 32, 52 }
79 };
80 
82 {
83  { "lock1_fs1", "2_lock1_fs1" },
84  { "lock1", "2_lock1" }
85 };
86 
88 {
89  { "lockspin_fs1", "2_lockspin_fs1" },
90  { "lockspin", "2_lockspin" }
91 };
92 
93 void hud_lock_determine_lock_point(vec3d *lock_world_pos_out);
94 
95 // hud_init_missile_lock() is called at the beginning of a mission
96 //
98 {
103 
105 }
106 
109 {
110 }
111 
113 {
116 }
117 
119 {
120  Lockspin_half_w = w;
121  Lockspin_half_h = h;
122 }
123 
125 {
127 }
128 
130 {
132 }
133 
135 {
138 }
139 
141 {
142  loop_locked_anim = loop;
143 }
144 
145 void HudGaugeLock::initBitmaps(char *lock_gauge_fname, char *lock_anim_fname)
146 {
147  hud_anim_init(&Lock_gauge, 0, 0, lock_gauge_fname);
149 
150  hud_anim_init(&Lock_anim, 0, 0, lock_anim_fname);
152 }
153 
155 {
157  Lock_gauge_draw = 0;
158  Rotate_time_id = 1;
159  Last_lock_status = false;
160 
161  Lock_anim.time_elapsed = 0.0f;
162  Lock_gauge.time_elapsed = 0.0f;
163 
165 }
166 
167 // hud_show_lock_indicator() will display the lock indicator for homing missiles.
168 // lock_point_pos should be the world coordinates of the target being locked. Assuming all the
169 // necessary locking calculations are done for this frame, this function will compute
170 // where the indicator should be relative to the player's viewpoint and will render accordingly.
171 void HudGaugeLock::render(float frametime)
172 {
173  int target_objnum, sx, sy;
174  object *targetp;
175  vertex lock_point;
176 
177  bool locked = Player_ai->current_target_is_locked ? true : false;
178  bool reset_timers = false;
179 
180  if ( locked != Last_lock_status ) {
181  // check if player lock status has changed since the last frame.
182  reset_timers = true;
183  Last_lock_status = locked;
184  }
185 
186  if (Player_ai->target_objnum == -1) {
187  return;
188  }
189 
190  if (Player->target_is_dying) {
191  return;
192  }
193 
194  if (!Players[Player_num].lock_indicator_visible){
195  return;
196  }
197 
198  target_objnum = Player_ai->target_objnum;
199  Assert(target_objnum != -1);
200  targetp = &Objects[target_objnum];
201 
202  // check to see if there are any missile to fire.. we don't want to show the
203  // lock indicator if there are missiles to fire.
205  return;
206  }
207 
208  bool in_frame = g3_in_frame() > 0;
209  if(!in_frame)
210  g3_start_frame(0);
212 
213  // Get the target's current position on the screen. If he's not on there,
214  // we're not going to draw the lock indicator even if he's in front
215  // of our ship, so bail out.
216  g3_rotate_vertex(&lock_point, &lock_world_pos);
217  g3_project_vertex(&lock_point);
218  if (lock_point.codes & PF_OVERFLOW) {
220 
221  if(!in_frame)
222  g3_end_frame();
223 
224  return;
225  }
226 
227  hud_set_iff_color(targetp);
228 // nprintf(("Alan","lockx: %d, locky: %d TargetX: %d, TargetY: %d\n", Players[Player_num].lock_indicator_x, Players[Player_num].lock_indicator_y, Player->current_target_sx, Player->current_target_sy));
229 
230  // We have the coordinates of the lock indicator relative to the target in our "virtual frame"
231  // so, we calculate where it should be drawn based on the player's viewpoint.
233  sx = fl2i(lock_point.screen.xyw.x);
234  sy = fl2i(lock_point.screen.xyw.y);
235  gr_unsize_screen_pos(&sx, &sy);
236 
237  // show the rotating triangles if target is locked
238  renderLockTriangles(sx, sy, frametime);
239 
240  if ( reset_timers ) {
241  Lock_gauge.time_elapsed = 0.0f;
242  }
243  } else {
245  sx = fl2i(lock_point.screen.xyw.x) - fl2i(i2fl(Player->current_target_sx - Players[Player_num].lock_indicator_x) * scaling_factor);
246  sy = fl2i(lock_point.screen.xyw.y) - fl2i(i2fl(Player->current_target_sy - Players[Player_num].lock_indicator_y) * scaling_factor);
247  gr_unsize_screen_pos(&sx, &sy);
248 
249  if ( reset_timers ) {
251  Lock_gauge_draw = 0;
252  Lock_anim.time_elapsed = 0.0f;
253  }
254  }
255 
256  // show locked indicator
260  hud_anim_render(&Lock_gauge, 0.0f, 1);
261  } else {
262  hud_anim_render(&Lock_gauge, frametime, 1);
263  }
264 
266  if(!in_frame)
267  g3_end_frame();
268 }
269 
270 // Reset data used for player lock indicator
271 void hud_lock_reset(float lock_time_scale)
272 {
273  weapon_info *wip;
274  ship_weapon *swp;
275 
276  swp = &Player_ship->weapons;
277 
278  if ((swp->current_secondary_bank >= 0) && (swp->secondary_bank_weapons[swp->current_secondary_bank] >= 0)) {
282  Player->lock_time_to_target = i2fl(wip->min_lock_time*lock_time_scale);
283  } else {
284  Player->lock_time_to_target = 0.0f;
285  }
286 
292  Player->locking_subsys=NULL;
296 }
297 
298 // Determine if the locking code has a point to track
300 {
302  return 1;
303  }
304  return 0;
305 }
306 
308 DCF_BOOL(nebula_sec_range, Nebula_sec_range);
309 
310 int hud_lock_world_pos_in_range(vec3d *target_world_pos, vec3d *vec_to_target)
311 {
312  float dist_to_target, weapon_range;
313  weapon_info *wip;
314  ship_weapon *swp;
315 
316  int target_in_range=1;
317 
318  swp = &Player_ship->weapons;
320 
321  vm_vec_sub(vec_to_target, target_world_pos, &Player_obj->pos);
322  dist_to_target = vm_vec_mag(vec_to_target);
323 
324  //local ssms are always in range :)
325  if (wip->wi_flags2 & WIF2_LOCAL_SSM)
326  weapon_range=wip->lssm_lock_range;
327  else
328  // calculate the range of the weapon, and only display the lead target indicator when
329  // if the weapon can actually hit the target
330  weapon_range = MIN((wip->max_speed * wip->lifetime), wip->weapon_range);
331 
332 
333 
334  // reduce firing range in nebula
336  weapon_range *= 0.8f;
337  }
338 
339  if (dist_to_target > weapon_range) {
340  target_in_range=0;
341  }
342 
343  return target_in_range;
344 }
345 
346 // Determine if point to lock on is in range
348 {
349  vec3d target_world_pos, vec_to_target;
350  object *targetp;
351 
352  if ( !hud_lock_has_homing_point() ) {
353  return 0;
354  }
355 
356  targetp = &Objects[Player_ai->target_objnum];
357 
358  if ( Player_ai->targeted_subsys != NULL ) {
359  vm_vec_unrotate(&target_world_pos, &Player_ai->targeted_subsys->system_info->pnt, &targetp->orient);
360  vm_vec_add2(&target_world_pos, &targetp->pos);
361  } else {
362  if ( Player->locking_subsys ) {
363  vm_vec_unrotate(&target_world_pos, &Player->locking_subsys->system_info->pnt, &targetp->orient);
364  vm_vec_add2(&target_world_pos, &targetp->pos);
365  } else {
367  target_world_pos = targetp->pos;
368  }
369  }
370 
371  return hud_lock_world_pos_in_range(&target_world_pos, &vec_to_target);
372 }
373 
375 {
376  int target_team;
377 
378  target_team = obj_team(&Objects[Player_ai->target_objnum]);
379 
381  return 1;
382  }
383 
385  return 1;
386  }
387 
388  // check to see if there are any missile to fire.. we don't want to show the
389  // lock indicator if there are no missiles to fire.
391  return 1;
392  }
393 
395  return 1;
396  }
397 
398  // if we're on the same team and the team doesn't attack itself, then don't lock!
399  if ((Player_ship->team == target_team) && (!iff_x_attacks_y(Player_ship->team, target_team)))
400  {
401  // if we're in multiplayer dogfight, ignore this
402  if(!MULTI_DOGFIGHT) {
403  return 1;
404  }
405  }
406 
407  return 0;
408 }
409 
410 // determine if the subsystem to lock on to has a direct line of sight
412 {
413  ship_subsys *subsys;
414  vec3d subobj_pos;
415  object *target_objp;
416  int in_sight=0;
417 
419  target_objp = &Objects[Player_ai->target_objnum];
420 
421  subsys = Player_ai->targeted_subsys;
422  if ( !subsys ) {
423  return 0;
424  }
425 
426  vm_vec_unrotate(&subobj_pos, &subsys->system_info->pnt, &target_objp->orient);
427  vm_vec_add2(&subobj_pos, &target_objp->pos);
428 
429  if ( Player->subsys_in_view < 0 ) {
430  in_sight = ship_subsystem_in_sight(target_objp, subsys, &View_position, &subobj_pos);
431  } else {
432  in_sight = Player->subsys_in_view;
433  }
434 
435  return in_sight;
436 }
437 
438 // Determine if locking point is in the locking cone
440 {
441  float dot;
442  vec3d vec_to_target;
443 
444  vm_vec_normalized_dir(&vec_to_target, &lock_world_pos, &Player_obj->pos);
445  dot = vm_vec_dot(&Player_obj->orient.vec.fvec, &vec_to_target);
446 
447  if ( dot > 0.85) {
449  } else {
451  }
452 }
453 
454 // return 1 if current secondary weapon is different than previous secondary weapon
456 {
457 
459  return 1;
460  }
461 
462  return 0;
463 /*
464  int last_wi_index = -1;
465  int current_wi_index = -1;
466 
467 
468  // do a quick out if same bank is selected
469  if ( swp->current_secondary_bank == Player_ai->last_secondary_index ) {
470  return 0;
471  }
472 
473  // bank has changed, but it still may be the same weapon type
474  if ( swp->current_secondary_bank >= 0 ) {
475  current_wi_index = swp->secondary_bank_weapons[swp->current_secondary_bank];
476  }
477 
478  if ( Player_ai->last_secondary_index >= 0 ) {
479  last_wi_index = swp->secondary_bank_weapons[Player_ai->last_secondary_index];
480  }
481 
482  if ( current_wi_index != last_wi_index ) {
483  return 1;
484  }
485 
486  return 0;
487 */
488 
489 }
490 
491 // hud_do_lock_indicator() manages missle locking, both the non-rendering calculations and the 2D HUD rendering
492 void hud_do_lock_indicator(float frametime)
493 {
494  ship_weapon *swp;
495  weapon_info *wip;
496 
497  // if i'm a multiplayer observer, bail here
499  return;
500  }
501 
503 
504  // be sure to unset this flag, then possibly set later in this function so that
505  // threat indicators work properly.
507 
508  if ( hud_abort_lock() ) {
509  hud_lock_reset();
510  return;
511  }
512 
513  // if there is an EMP effect active, never update lock
514  if(emp_active_local()){
515  hud_lock_reset();
516  return;
517  }
518 
519  swp = &Player_ship->weapons;
521 
522  Lock_start_dist = wip->min_lock_time * wip->lock_pixels_per_sec;
523 
524  // if secondary weapons change, reset the lock
526  hud_lock_reset();
527  }
528 
530 
531  object *tobjp = &Objects[Player_ai->target_objnum];
532  vec3d dir_to_target;
533  vm_vec_normalized_dir(&dir_to_target, &tobjp->pos, &Player_obj->pos);
534 
535  if ( !(wip->wi_flags & WIF_LOCKED_HOMING) ) {
536  hud_lock_reset();
537  return;
538  }
539 
540  // Allow locking on ships and bombs (only targeted weapon allowed is a bomb, so don't bother checking flags)
542  hud_lock_reset();
543  return;
544  }
545 
546  // Javelins must lock on engines if locking on a ship and those must be in sight
547  if (wip->wi_flags & WIF_HOMING_JAVELIN &&
548  tobjp->type == OBJ_SHIP &&
549  Player->locking_subsys != NULL) {
550  vec3d subobj_pos;
551  vm_vec_unrotate(&subobj_pos, &Player->locking_subsys->system_info->pnt, &tobjp->orient);
552  vm_vec_add2(&subobj_pos, &tobjp->pos);
553  int target_subsys_in_sight = ship_subsystem_in_sight(tobjp, Player->locking_subsys, &Player_obj->pos, &subobj_pos);
554 
555  if (!target_subsys_in_sight || Player->locking_subsys->system_info->type != SUBSYSTEM_ENGINE) {
558  }
559  }
560 
561  if (wip->wi_flags & WIF_HOMING_JAVELIN &&
562  tobjp->type == OBJ_SHIP &&
563  Player->locking_subsys == NULL) {
566 
567  if (Player->locking_subsys == NULL) {
568  hud_lock_reset();
569  return;
570  }
571  }
572 
573  hud_lock_determine_lock_point(&lock_world_pos);
574 
575  if ( !hud_lock_has_homing_point() ) {
577  }
578 
580 
581  // check if the target is within range of the current secondary weapon. If it is not,
582  // a lock will not be detected
583  if ( !hud_lock_target_in_range() ) {
585  }
586 
587  // If locking on a subsystem, and not in sight... can't lock
588  // Changed by MK on 4/3/98. It was confusing me that my hornets would not lock on my target.
589  // It will now be confusing that they lock, but don't home on your subsystem, but I think that's preferable.
590  // Often you really care about destroying the target, not just the subsystem.
591  /*if ( Player_ai->targeted_subsys ) {
592  if ( !hud_lock_on_subsys_ok() ) {
593  Player->target_in_lock_cone=0;
594  }
595  }*/
596 
597  if ( !Player->target_in_lock_cone ) {
600  Player->locking_subsys=NULL;
601  }
602 
603  hud_calculate_lock_position(frametime);
604 
605  if (!Players[Player_num].lock_indicator_visible)
606  return;
607 
609  if ( Missile_track_loop > -1 ) {
611  Missile_track_loop = -1;
612 
613  if (wip->hud_locked_snd >= 0)
614  {
616  }
617  else
618  {
620  }
621  }
622  }
623  else {
624  Player_ai->ai_flags |= AIF_SEEK_LOCK; // set this flag so multiplayer's properly track lock on other ships
627  Missile_lock_loop = -1;
628  }
629  }
630 }
631 
632 // hud_draw_lock_triangles() will draw the 4 rotating triangles around a lock indicator
633 // (This is done when a lock has been acquired)
634 #define ROTATE_DELAY 40
635 void HudGaugeLock::renderLockTrianglesOld(int center_x, int center_y, int radius)
636 {
637  static float ang = 0.0f;
638 
639  float end_ang = ang + PI2;
640  float x3,y3,x4,y4,xpos,ypos;
641 
644  ang += PI/12;
645  }
646 
647  for (; ang <= end_ang; ang += PI_2) {
648 
649  // draw the orbiting triangles
650 
651  //ang = atan2(target_point.y,target_point.x);
652  xpos = center_x + cosf(ang)*(radius + Lock_triangle_height + 2);
653  ypos = center_y - sinf(ang)*(radius + Lock_triangle_height + 2);
654 
655  x3 = xpos + Lock_triangle_base * sinf(ang);
656  y3 = ypos + Lock_triangle_base * cosf(ang);
657  x4 = xpos - Lock_triangle_base * sinf(ang);
658  y4 = ypos - Lock_triangle_base * cosf(ang);
659 
660  xpos = xpos - Lock_triangle_base * cosf(ang);
661  ypos = ypos + Lock_triangle_base * sinf(ang);
662 
663  hud_tri(x3, y3, xpos, ypos, x4, y4);
664  } // end for
665 }
666 
667 // draw a frame of the rotating lock triangles animation
668 void HudGaugeLock::renderLockTriangles(int center_x, int center_y, float frametime)
669 {
670  if ( Lock_anim.first_frame == -1 ) {
671  renderLockTrianglesOld(center_x, center_y, Lock_target_box_width/2);
672  } else {
673  // render the anim
674  Lock_anim.sx = center_x - Lockspin_half_w;
675  Lock_anim.sy = center_y - Lockspin_half_h;
676 
677  // if it's still animating
679  if(loop_locked_anim) {
680  hud_anim_render(&Lock_anim, frametime, 1, 1, 0);
681  } else {
682  hud_anim_render(&Lock_anim, frametime, 1, 0, 1);
683  }
684  } else {
685  // if the timestamp is unset or expired
687  // reset timestamp
689 
690  // switch between draw and don't-draw
692  }
693 
694  // maybe draw the anim
695  Lock_gauge.time_elapsed = 0.0f;
696  if(Lock_gauge_draw){
697  if ( loop_locked_anim ) {
698  hud_anim_render(&Lock_anim, frametime, 1, 1, 0);
699  } else {
700  hud_anim_render(&Lock_anim, frametime, 1, 0, 1);
701  }
702  }
703  }
704  }
705 }
706 
707 // hud_calculate_lock_position() will determine where on the screen to draw the lock
708 // indicator, and will determine when a lock has occurred. If the lock indicator is not
709 // on the screen yet, hud_calculate_lock_start_pos() is called to pick a starting location
710 void hud_calculate_lock_position(float frametime)
711 {
712  ship_weapon *swp;
713  weapon_info *wip;
714 
715  static float pixels_moved_while_locking;
716  static float pixels_moved_while_degrading;
717  static int Need_new_start_pos = 0;
718 
719  static double accumulated_x_pixels, accumulated_y_pixels;
720  double int_portion;
721 
722  static float last_dist_to_target;
723 
724  static int catching_up;
725 
726  static int maintain_lock_count = 0;
727 
728  static float catch_up_distance = 0.0f;
729 
730  double hypotenuse, delta_x, delta_y;
731 
732  swp = &Player_ship->weapons;
734 
736  if (!Players[Player_num].lock_indicator_visible) {
738  last_dist_to_target = 0.0f;
739 
743 
745  catching_up = 0;
746  }
747 
748  Need_new_start_pos = 1;
749 
753  return;
754  }
755 
758 
759  if (!delta_y && !delta_x) {
760  hypotenuse = 0;
761  }
762  else {
763  hypotenuse = _hypot(delta_y, delta_x);
764  }
765 
767 
768  if (last_dist_to_target == 0) {
769  last_dist_to_target = Players[Player_num].lock_dist_to_target;
770  }
771 
772  //nprintf(("Alan","dist to target: %.2f\n",Players[Player_num].lock_dist_to_target));
773  //nprintf(("Alan","last to target: %.2f\n\n",last_dist_to_target));
774 
775  if (catching_up) {
776  //nprintf(("Alan","IN CATCH UP MODE catch_up_dist is %.2f\n",catch_up_distance));
777  if ( Players[Player_num].lock_dist_to_target < catch_up_distance )
778  catching_up = 0;
779  }
780  else {
781  //nprintf(("Alan","IN NORMAL MODE\n"));
782  if ( (Players[Player_num].lock_dist_to_target - last_dist_to_target) > 2.0f ) {
783  catching_up = 1;
784  catch_up_distance = last_dist_to_target + wip->catchup_pixel_penalty;
785  }
786  }
787 
788  last_dist_to_target = Players[Player_num].lock_dist_to_target;
789 
790  if (!catching_up) {
791  Players[Player_num].lock_time_to_target -= frametime;
792  if (Players[Player_num].lock_time_to_target < 0.0f)
794  }
795 
796  float lock_pixels_per_sec;
797  if (Players[Player_num].lock_time_to_target > 0) {
799  } else {
800  lock_pixels_per_sec = i2fl(wip->lock_pixels_per_sec);
801  }
802 
803  if (lock_pixels_per_sec > wip->lock_pixels_per_sec) {
804  lock_pixels_per_sec = i2fl(wip->lock_pixels_per_sec);
805  }
806 
807  if (catching_up) {
808  pixels_moved_while_locking = wip->catchup_pixels_per_sec * frametime;
809  } else {
810  pixels_moved_while_locking = lock_pixels_per_sec * frametime;
811  }
812 
813  if ((delta_x != 0) && (hypotenuse != 0)) {
814  accumulated_x_pixels += pixels_moved_while_locking * delta_x/hypotenuse;
815  }
816 
817  if ((delta_y != 0) && (hypotenuse != 0)) {
818  accumulated_y_pixels += pixels_moved_while_locking * delta_y/hypotenuse;
819  }
820 
821  if (fl_abs((float)accumulated_x_pixels) > 1.0f) {
822  modf(accumulated_x_pixels, &int_portion);
823 
824  Players[Player_num].lock_indicator_x -= (int)int_portion;
825 
826  if ( fl_abs((float)Players[Player_num].lock_indicator_x - (float)Player->current_target_sx) < fl_abs((float)int_portion) )
827  Players[Player_num].lock_indicator_x = Player->current_target_sx;
828 
829  accumulated_x_pixels -= int_portion;
830  }
831 
832  if (fl_abs((float)accumulated_y_pixels) > 1.0f) {
833  modf(accumulated_y_pixels, &int_portion);
834 
835  Players[Player_num].lock_indicator_y -= (int)int_portion;
836 
837  if ( fl_abs((float)Players[Player_num].lock_indicator_y - (float)Player->current_target_sy) < fl_abs((float)int_portion) )
838  Players[Player_num].lock_indicator_y = Player->current_target_sy;
839 
840  accumulated_y_pixels -= int_portion;
841  }
842 
843  if ( Missile_track_loop == -1 ) {
844  if (wip->hud_tracking_snd >= 0)
845  {
846  Missile_track_loop = snd_play_looping( &Snds[wip->hud_tracking_snd], 0.0f , -1, -1);
847  }
848  else
849  {
851  }
852  }
853 
854  if (!Players[Player_num].lock_time_to_target) {
856  if (maintain_lock_count++ > 1) {
858  }
859  } else {
860  maintain_lock_count = 0;
861  }
862  }
863 
864  } else {
865 
866  if ( Missile_track_loop > -1 ) {
868  Missile_track_loop = -1;
869  }
870 
872 
873  if (!Players[Player_num].lock_indicator_visible) {
874  return;
875  }
876 
877  catching_up = 0;
878  last_dist_to_target = 0.0f;
879 
880  if (Need_new_start_pos) {
882  Need_new_start_pos = 0;
883  accumulated_x_pixels = 0.0f;
884  accumulated_y_pixels = 0.0f;
885  }
886 
889 
890  if (!delta_y && !delta_x) {
891  hypotenuse = 0;
892  }
893  else {
894  hypotenuse = _hypot(delta_y, delta_x);
895  }
896 
897  Players[Player_num].lock_time_to_target += frametime;
898 
899  if (Players[Player_num].lock_time_to_target > wip->min_lock_time)
901 
902  pixels_moved_while_degrading = 2.0f * wip->lock_pixels_per_sec * frametime;
903 
904  if ((delta_x != 0) && (hypotenuse != 0))
905  accumulated_x_pixels += pixels_moved_while_degrading * delta_x/hypotenuse;
906 
907  if ((delta_y != 0) && (hypotenuse != 0))
908  accumulated_y_pixels += pixels_moved_while_degrading * delta_y/hypotenuse;
909 
910  if (fl_abs((float)accumulated_x_pixels) > 1.0f) {
911  modf(accumulated_x_pixels, &int_portion);
912 
913  Players[Player_num].lock_indicator_x -= (int)int_portion;
914 
915  if ( fl_abs((float)Players[Player_num].lock_indicator_x - (float)Players[Player_num].lock_indicator_start_x) < fl_abs((float)int_portion) )
916  Players[Player_num].lock_indicator_x = Players[Player_num].lock_indicator_start_x;
917 
918  accumulated_x_pixels -= int_portion;
919  }
920 
921  if (fl_abs((float)accumulated_y_pixels) > 1.0f) {
922  modf(accumulated_y_pixels, &int_portion);
923 
924  Players[Player_num].lock_indicator_y -= (int)int_portion;
925 
926  if ( fl_abs((float)Players[Player_num].lock_indicator_y - (float)Players[Player_num].lock_indicator_start_y) < fl_abs((float)int_portion) )
927  Players[Player_num].lock_indicator_y = Players[Player_num].lock_indicator_start_y;
928 
929  accumulated_y_pixels -= int_portion;
930  }
931 
932  if ( (Players[Player_num].lock_indicator_x == Players[Player_num].lock_indicator_start_x) && (Players[Player_num].lock_indicator_y == Players[Player_num].lock_indicator_start_y) ) {
934  }
935  }
936 }
937 
938 // hud_calculate_lock_start_pos() will determine where to draw the starting location of the lock
939 // indicator. It does this by picking a location that is Lock_start_dist pixels away from the current
940 // target (in 2D). This is accomplished by finding the endpoint of a line that passes through the
941 // origin, and connects the target and lock indicator postion (and has a magnitude of Lock_start_dist)
943 {
944  double hypotenuse;
945  double delta_y;
946  double delta_x;
947  double target_mag, target_x, target_y;
948 
951 
952  if ( (delta_x == 0.0) && (delta_y == 0.0) ) {
955  return;
956  }
957 
958  hypotenuse = _hypot(delta_y, delta_x);
959 
960  if (hypotenuse >= Lock_start_dist) {
963  return;
964  }
965 
966  target_mag = Lock_start_dist - hypotenuse;
967  target_x = target_mag * (delta_x / hypotenuse);
968  target_y = target_mag * (delta_y / hypotenuse);
969 
972 
973  CLAMP(Players[Player_num].lock_indicator_start_x, gr_screen.clip_left, gr_screen.clip_right);
974  CLAMP(Players[Player_num].lock_indicator_start_y, gr_screen.clip_top, gr_screen.clip_bottom);
975 }
976 
977 // hud_stop_looped_locking_sounds() will terminate any hud related looping sounds that are playing
979 {
980  if ( Missile_track_loop > -1 ) {
982  Missile_track_loop = -1;
983  }
984 }
985 
986 // Get a new world pos for the locking point
987 void hud_lock_update_lock_pos(object *target_objp)
988 {
991 
993  get_subsystem_world_pos(target_objp, Player_ai->targeted_subsys, &lock_world_pos);
994  return;
995  }
996 
997  if ( Player->locking_on_center) {
998  lock_world_pos = target_objp->pos;
999  } else {
1001  get_subsystem_world_pos(target_objp, Player->locking_subsys, &lock_world_pos);
1002  }
1003 }
1004 
1005 // Try and find a new locking point
1006 void hud_lock_get_new_lock_pos(object *target_objp)
1007 {
1008  ship *target_shipp=NULL;
1009  int lock_in_range=0;
1010  float best_lock_dot=-1.0f, lock_dot=-1.0f;
1011  ship_subsys *ss;
1012  vec3d subsys_world_pos, vec_to_lock;
1013  ship_weapon *swp;
1014  weapon_info *wip;
1015 
1016  if ( target_objp->type == OBJ_SHIP ) {
1017  target_shipp = &Ships[target_objp->instance];
1018  }
1019 
1020  swp = &Player_ship->weapons;
1022 
1023  // if a large ship, lock to pos closest to center and within range
1024  if ( (target_shipp) && (Ship_info[target_shipp->ship_info_index].flags & (SIF_BIG_SHIP|SIF_HUGE_SHIP)) &&
1025  !(wip->wi_flags & WIF_HOMING_JAVELIN) ) {
1026  // check all the subsystems and the center of the ship
1027 
1028  // assume best lock pos is the center of the ship
1029  lock_world_pos = target_objp->pos;
1031  Player->locking_subsys=NULL;
1033  lock_in_range = hud_lock_world_pos_in_range(&lock_world_pos, &vec_to_lock);
1034  vm_vec_normalize(&vec_to_lock);
1035  if ( lock_in_range ) {
1036  best_lock_dot=vm_vec_dot(&Player_obj->orient.vec.fvec, &vec_to_lock);
1037  }
1038  // take center if reasonable dot
1039  if ( best_lock_dot > 0.95 ) {
1040  return;
1041  }
1042 
1043  // iterate through subsystems to see if we can get a better choice
1044  ss = GET_FIRST(&target_shipp->subsys_list);
1045  while ( ss != END_OF_LIST( &target_shipp->subsys_list ) ) {
1046 
1047  // get world pos of subsystem
1048  get_subsystem_world_pos(target_objp, ss, &subsys_world_pos);
1049 
1050  if ( hud_lock_world_pos_in_range(&subsys_world_pos, &vec_to_lock) ) {
1051  vm_vec_normalize(&vec_to_lock);
1052  lock_dot=vm_vec_dot(&Player_obj->orient.vec.fvec, &vec_to_lock);
1053  if ( lock_dot > best_lock_dot ) {
1054  best_lock_dot=lock_dot;
1056  Player->locking_subsys=ss;
1058  lock_world_pos = subsys_world_pos;
1059  }
1060  }
1061  ss = GET_NEXT( ss );
1062  }
1063  } else if ( (target_shipp) && (wip->wi_flags & WIF_HOMING_JAVELIN)) {
1065  if (Player->locking_subsys != NULL) {
1066  get_subsystem_world_pos(target_objp, Player->locking_subsys, &lock_world_pos);
1069  } else {
1070  hud_lock_reset();
1071  return;
1072  }
1073  } else {
1074  // if small ship (or weapon), just go for the center
1075  lock_world_pos = target_objp->pos;
1077  Player->locking_subsys=NULL;
1079  }
1080 }
1081 
1082 // Decide which point lock should be homing on
1083 void hud_lock_determine_lock_point(vec3d *lock_world_pos_out)
1084 {
1085  object *target_objp;
1086  ship_weapon *swp;
1087  weapon_info *wip;
1088 
1089  vec3d vec_to_lock_pos;
1090  vec3d lock_local_pos;
1091 
1093  target_objp = &Objects[Player_ai->target_objnum];
1094 
1095  Player->current_target_sx = -1;
1096  Player->current_target_sy = -1;
1097 
1098  swp = &Player_ship->weapons;
1100 
1101  // If subsystem is targeted, we must try to lock on that
1102  if ( Player_ai->targeted_subsys && !(wip->wi_flags & WIF_HOMING_JAVELIN) ) {
1103  hud_lock_update_lock_pos(target_objp);
1107  } else if ( (wip->wi_flags & WIF_HOMING_JAVELIN) && (target_objp->type == OBJ_SHIP)) {
1108  if (!Player->locking_subsys ||
1111  }
1112  if (Player->locking_subsys != NULL) {
1113  get_subsystem_world_pos(target_objp, Player->locking_subsys, &lock_world_pos);
1116  } else {
1117  hud_lock_reset();
1118  return;
1119  }
1120  } else {
1121  // See if we already have a successful locked point
1122  if ( hud_lock_has_homing_point() ) {
1123  hud_lock_update_lock_pos(target_objp);
1124  } else {
1125  hud_lock_get_new_lock_pos(target_objp);
1126  }
1127  }
1128 
1129  *lock_world_pos_out=lock_world_pos;
1130 
1131  vm_vec_sub(&vec_to_lock_pos,&lock_world_pos,&Player_obj->pos);
1132  vm_vec_rotate(&lock_local_pos,&vec_to_lock_pos,&Player_obj->orient);
1133 
1134  if ( lock_local_pos.xyz.z > 0.0f ) {
1135  // Get the location of our target in the "virtual frame" where the locking computation will be done
1136  float w = 1.0f / lock_local_pos.xyz.z;
1137  // Let's force our "virtual frame" to be 640x480. -MageKing17
1138  float sx = gr_screen.clip_center_x + (lock_local_pos.xyz.x * VIRTUAL_FRAME_HALF_WIDTH * w);
1139  float sy = gr_screen.clip_center_y - (lock_local_pos.xyz.y * VIRTUAL_FRAME_HALF_HEIGHT * w);
1140 
1141  Player->current_target_sx = (int)sx;
1142  Player->current_target_sy = (int)sy;
1143  }
1144 }
1145 
1147 {
1150 }
#define MAX_FILENAME_LEN
Definition: pstypes.h:324
virtual void initialize()
Definition: hud.cpp:1049
int timestamp(int delta_ms)
Definition: timer.cpp:226
struct screen3d::@234::@236 xyw
int lock_pixels_per_sec
Definition: weapon.h:402
int Rotate_time_id
Definition: hudlock.h:43
model_subsystem * system_info
Definition: ship.h:314
int Nebula_sec_range
Definition: hudlock.cpp:307
#define MIN(a, b)
Definition: pstypes.h:296
float min_lock_time
Definition: weapon.h:401
ai_info * Player_ai
Definition: ai.cpp:24
int team
Definition: ship.h:606
int Lock_gauge_half_w[NUM_HUD_RETICLE_STYLES][GR_NUM_RESOLUTIONS]
Definition: hudlock.cpp:61
vec3d View_position
Definition: 3dsetup.cpp:20
int Game_mode
Definition: systemvars.cpp:24
GLfloat GLfloat GLfloat GLfloat h
Definition: Glext.h:7280
#define MISSION_FLAG_FULLNEB
Definition: missionparse.h:70
int Missile_lock_loop
Definition: hudlock.cpp:40
int obj_team(object *objp)
Definition: object.cpp:1843
weapon_info Weapon_info[MAX_WEAPON_TYPES]
Definition: weapons.cpp:79
ship_weapon weapons
Definition: ship.h:658
char Lock_fname[NUM_HUD_RETICLE_STYLES][GR_NUM_RESOLUTIONS][MAX_FILENAME_LEN]
Definition: hudlock.cpp:81
net_player * Net_player
Definition: multi.cpp:94
SCP_vector< game_snd > Snds
Definition: gamesnd.cpp:19
float vm_vec_mag(const vec3d *v)
Definition: vecmat.cpp:325
#define WIF_LOCKED_HOMING
Definition: weapon.h:130
float lock_time_to_target
Definition: player.h:119
#define HUD_OBJECT_LOCK
Definition: hudparse.h:175
void hud_stop_looped_locking_sounds()
Definition: hudlock.cpp:978
int hud_anim_render(hud_anim *ha, float frametime, int draw_alpha, int loop, int hold_last, int reverse, int resize_mode, bool mirror)
Render out a frame of the targetbox static animation, based on how much time has elapsed.
Definition: hud.cpp:2228
int Lock_gauge_draw_stamp
Definition: hudlock.h:44
Assert(pm!=NULL)
int target_objnum
Definition: ai.h:339
Definition: pstypes.h:88
#define GR_NUM_RESOLUTIONS
Definition: 2d.h:651
#define NETINFO_FLAG_OBSERVER
Definition: multi.h:605
int subsys_in_view
Definition: player.h:168
int hud_lock_secondary_weapon_changed(ship_weapon *swp)
Definition: hudlock.cpp:455
struct vec3d::@225::@227 xyz
int base_h
Definition: hud.h:205
#define VIRTUAL_FRAME_HALF_HEIGHT
Definition: hudlock.cpp:32
GLclampf f
Definition: Glext.h:7097
int Lockspin_half_h
Definition: hudlock.h:37
int ship_subsystem_in_sight(object *objp, ship_subsys *subsys, vec3d *eye_pos, vec3d *subsys_pos, int do_facing_check, float *dot_out, vec3d *vec_out)
Definition: ship.cpp:14881
float clip_center_y
Definition: 2d.h:381
int snd_is_playing(int sig)
Definition: sound.cpp:1047
vec3d lock_world_pos
Definition: hudlock.cpp:35
vec3d * vm_vec_rotate(vec3d *dest, const vec3d *src, const matrix *m)
Definition: vecmat.cpp:933
#define ROTATE_DELAY
Definition: hudlock.cpp:634
ship_subsys * targeted_subsys
Definition: ai.h:472
#define HUD_LEAD_INDICATOR
Definition: hudgauges.h:18
int hud_lock_world_pos_in_range(vec3d *target_world_pos, vec3d *vec_to_target)
Definition: hudlock.cpp:310
void gr_set_screen_scale(int w, int h, int zoom_w, int zoom_h, int max_w, int max_h, int center_w, int center_h, bool force_stretch)
Definition: 2d.cpp:104
float max_speed
Definition: weapon.h:354
hud_anim Lock_anim
Definition: hudlock.h:30
void hud_calculate_lock_start_pos()
Definition: hudlock.cpp:942
#define AIF_SEEK_LOCK
Definition: ai.h:42
float weapon_range
Definition: weapon.h:390
int flags
Definition: multi.h:463
#define OBJ_OBSERVER
Definition: object.h:43
int current_secondary_bank
Definition: ship.h:107
#define _hypot(x, y)
Definition: config.h:281
float clip_center_x
Definition: 2d.h:381
void pageIn()
Definition: hudlock.cpp:1146
int Lock_gauge_draw
Definition: hudlock.h:45
void initBitmaps(char *lock_gauge_fname, char *lock_anim_fname)
Definition: hudlock.cpp:145
vec3d pos
Definition: object.h:152
Missle tracking to acquire a lock (looped)
Definition: gamesnd.h:68
char Lockspin_fname[NUM_HUD_RETICLE_STYLES][GR_NUM_RESOLUTIONS][MAX_FILENAME_LEN]
Definition: hudlock.cpp:87
int ai_flags
Definition: ai.h:330
float time_elapsed
Definition: hud.h:29
#define CLAMP(x, min, max)
Definition: pstypes.h:488
Definition: hud.h:201
float lifetime
Definition: weapon.h:382
int ship_secondary_bank_has_ammo(int shipnum)
Definition: ship.cpp:14741
#define VIRTUAL_FRAME_HALF_WIDTH
Definition: hudlock.cpp:31
ship_subsys subsys_list
Definition: ship.h:630
float lock_dist_to_target
Definition: player.h:120
int Lockspin_half_h[NUM_HUD_RETICLE_STYLES][GR_NUM_RESOLUTIONS]
Definition: hudlock.cpp:76
player Players[MAX_PLAYERS]
bool Last_lock_status
Definition: hudlock.h:47
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
#define MAX_SHIP_SECONDARY_BANKS
Definition: globals.h:63
void initTriHeight(float h)
Definition: hudlock.cpp:124
int instance
Definition: object.h:150
float Lock_triangle_base
Definition: hudlock.h:39
#define PF_OVERFLOW
Definition: 3d.h:22
void vm_vec_add2(vec3d *dest, const vec3d *src)
Definition: vecmat.cpp:178
const float PI2
Definition: pstypes.h:305
#define VM_DEAD_VIEW
Definition: systemvars.h:33
float Lock_triangle_height
Definition: hudlock.h:38
int target_is_dying
Definition: player.h:172
#define SIF_BIG_SHIP
Definition: ship.h:944
struct matrix::@228::@230 vec
int target_in_lock_cone
Definition: player.h:175
int first_frame
Definition: hud.h:24
screen3d screen
Definition: pstypes.h:173
#define GM_MULTIPLAYER
Definition: systemvars.h:18
void renderLockTrianglesOld(int center_x, int center_y, int radius)
Definition: hudlock.cpp:635
int Lock_target_box_width
Definition: hudlock.h:40
int sx
Definition: hud.h:27
void initTargetBoxSize(int w, int h)
Definition: hudlock.cpp:134
int ship_get_sound(object *objp, GameSoundsIndex id)
Returns a ship-specific sound index.
Definition: ship.cpp:18614
int num_secondary_banks
Definition: ship.h:100
#define OBJ_WEAPON
Definition: object.h:33
#define MAX_WEAPON_TYPES
Definition: globals.h:73
int base_w
Definition: hud.h:205
int current_target_sy
Definition: player.h:174
#define w(p)
Definition: modelsinc.h:68
void hud_lock_reset(float lock_time_scale)
Definition: hudlock.cpp:271
int Lock_gauge_half_w
Definition: hudlock.h:34
int lock_indicator_x
Definition: player.h:114
ubyte g3_rotate_vertex(vertex *dest, const vec3d *src)
Definition: 3dmath.cpp:97
int snd_play(game_snd *gs, float pan, float vol_scale, int priority, bool is_voice_msg)
Definition: sound.cpp:517
void initLoopLockedAnim(bool loop)
Definition: hudlock.cpp:140
#define fl_abs(fl)
Definition: floating.h:31
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:104
float vm_vec_normalized_dir(vec3d *dest, const vec3d *end, const vec3d *start)
Definition: vecmat.cpp:591
#define LOCK_GAUGE_BLINK_RATE
Definition: hudlock.cpp:70
#define MULTI_DOGFIGHT
Definition: multi.h:656
void hud_calculate_lock_position(float frametime)
Definition: hudlock.cpp:710
Definition: ship.h:534
int current_target_sx
Definition: player.h:173
int hud_lock_has_homing_point()
Definition: hudlock.cpp:299
void renderLockTriangles(int center_x, int center_y, float frametime)
Definition: hudlock.cpp:668
int clip_bottom
Definition: 2d.h:388
int g3_project_vertex(vertex *point)
Definition: 3dmath.cpp:202
int Lock_gauge_half_h
Definition: hudlock.h:35
vec3d * vm_vec_unrotate(vec3d *dest, const vec3d *src, const matrix *m)
Definition: vecmat.cpp:959
int last_secondary_index
Definition: ai.h:496
int clip_top
Definition: 2d.h:388
int iff_x_attacks_y(int team_x, int team_y)
Definition: iff_defs.cpp:605
int Lockspin_half_w
Definition: hudlock.h:36
int lock_indicator_y
Definition: player.h:115
object Objects[MAX_OBJECTS]
Definition: object.cpp:62
int wi_flags
Definition: weapon.h:384
void render(float frametime)
Definition: hudlock.cpp:171
ship * Player_ship
Definition: ship.cpp:124
matrix orient
Definition: object.h:153
int wi_flags2
Definition: weapon.h:385
void hud_lock_get_new_lock_pos(object *target_objp)
Definition: hudlock.cpp:1006
int catchup_pixels_per_sec
Definition: weapon.h:403
hud_anim Lock_gauge
Definition: hudlock.h:29
#define OBJ_SHIP
Definition: object.h:32
int catchup_pixel_penalty
Definition: weapon.h:404
int lock_indicator_start_y
Definition: player.h:117
#define SIF_HUGE_SHIP
Definition: ship.h:945
void hud_anim_init(hud_anim *ha, int sx, int sy, const char *filename)
Initialise the members of the hud_anim struct to default values.
Definition: hud.cpp:2169
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:168
#define SUBSYSTEM_ENGINE
Definition: model.h:53
int num_frames
Definition: hud.h:26
ship Ships[MAX_SHIPS]
Definition: ship.cpp:122
bool loop_locked_anim
Definition: hudlock.h:32
int clip_right
Definition: 2d.h:388
void hud_do_lock_indicator(float frametime)
Definition: hudlock.cpp:492
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
int Lock_gauge_half_h[GR_NUM_RESOLUTIONS]
Definition: hudlock.cpp:65
vec3d pnt
Definition: model.h:178
int hud_tracking_snd
Definition: weapon.h:552
void initSpinHalfSize(int w, int h)
Definition: hudlock.cpp:118
GLubyte GLubyte GLubyte GLubyte w
Definition: Glext.h:5679
float lssm_lock_range
Definition: weapon.h:492
int hud_abort_lock()
Definition: hudlock.cpp:374
void bm_page_in_aabitmap(int bitmapnum, int nframes)
Marks a texture as being used for this level, and is anti-aliased.
Definition: bmpman.cpp:2354
int g3_in_frame()
Definition: 3dsetup.cpp:66
#define fl2i(fl)
Definition: floating.h:33
float Lock_triangle_base[GR_NUM_RESOLUTIONS]
Definition: hudlock.cpp:52
player * Player
#define g3_end_frame()
Definition: 3d.h:49
int Lockspin_half_w[NUM_HUD_RETICLE_STYLES][GR_NUM_RESOLUTIONS]
Definition: hudlock.cpp:72
screen gr_screen
Definition: 2d.cpp:46
float total_time
Definition: hud.h:28
int sy
Definition: hud.h:27
int snd_play_looping(game_snd *gs, float pan, int start_loop, int stop_loop, float vol_scale, int scriptingUpdateVolume)
Definition: sound.cpp:822
ship_subsys * ship_get_closest_subsys_in_sight(ship *sp, int subsys_type, vec3d *attacker_pos)
Definition: ship.cpp:14963
int hud_lock_target_in_range()
Definition: hudlock.cpp:347
int hud_lock_on_subsys_ok()
Definition: hudlock.cpp:411
ship_subsys * locking_subsys
Definition: player.h:176
int hud_locked_snd
Definition: weapon.h:553
int ship_info_index
Definition: ship.h:539
An overhauled/updated debug console to allow monitoring, testing, and general debugging of new featur...
SCP_vector< ship_info > Ship_info
Definition: ship.cpp:164
void hud_lock_update_lock_pos(object *target_objp)
Definition: hudlock.cpp:987
void gr_reset_screen_scale()
Definition: 2d.cpp:176
int Missile_track_loop
Definition: hudlock.cpp:39
int hud_anim_load(hud_anim *ha)
Load a hud_anim.
Definition: hud.cpp:2193
#define timestamp_elapsed(stamp)
Definition: timer.h:102
int lock_indicator_visible
Definition: player.h:118
vec3d * get_subsystem_world_pos(object *parent_obj, ship_subsys *subsys, vec3d *world_pos)
Definition: hudtarget.cpp:4395
DCF_BOOL(nebula_sec_range, Nebula_sec_range)
void hud_lock_check_if_target_in_lock_cone()
Definition: hudlock.cpp:439
void initialize()
Definition: hudlock.cpp:154
#define PI
Definition: pstypes.h:303
bool gr_unsize_screen_pos(int *x, int *y, int *w, int *h, int resize_mode)
Definition: 2d.cpp:320
float vm_vec_dot(const vec3d *v0, const vec3d *v1)
Definition: vecmat.cpp:312
void initGaugeHalfSize(int w, int h)
Definition: hudlock.cpp:112
GLenum GLuint GLenum GLsizei length
Definition: Glext.h:5156
#define i2fl(i)
Definition: floating.h:32
int Lock_target_box_width[GR_NUM_RESOLUTIONS]
Definition: hudlock.cpp:42
const float PI_2
Definition: pstypes.h:307
void hud_lock_determine_lock_point(vec3d *lock_world_pos_out)
Definition: hudlock.cpp:1083
object * Player_obj
Definition: object.cpp:56
void hud_init_missile_lock()
Definition: hudlock.cpp:97
#define WIF_HOMING_JAVELIN
Definition: weapon.h:55
uint flags2
Definition: ship.h:645
int locking_on_center
Definition: player.h:178
int emp_active_local()
Definition: emp.cpp:428
int clip_left
Definition: 2d.h:388
ubyte codes
Definition: pstypes.h:177
false
Definition: lua.cpp:6789
void hud_tri(float x1, float y1, float x2, float y2, float x3, float y3)
Definition: hudtarget.cpp:2803
void snd_stop(int sig)
Definition: sound.cpp:875
mission The_mission
#define WIF2_LOCAL_SSM
Definition: weapon.h:87
int Lock_target_box_height[GR_NUM_RESOLUTIONS]
Definition: hudlock.cpp:46
char type
Definition: object.h:146
float Lock_triangle_height[GR_NUM_RESOLUTIONS]
Definition: hudlock.cpp:56
void hud_set_iff_color(object *objp, int is_bright)
Will set the color to the IFF color based on the team.
Definition: hud.cpp:2950
int lock_indicator_start_x
Definition: player.h:116
int locking_subsys_parent
Definition: player.h:177
#define SF2_NO_SECONDARY_LOCKON
Definition: ship.h:510
Missle lock (non-looping)
Definition: gamesnd.h:69
int current_target_is_locked
Definition: ai.h:490
int Lock_target_box_height
Definition: hudlock.h:41
#define g3_start_frame(zbuffer_flag)
Definition: 3d.h:39
float vm_vec_normalize(vec3d *v)
Definition: vecmat.cpp:460
int Player_num
void initTriBase(float length)
Definition: hudlock.cpp:129
#define NUM_HUD_RETICLE_STYLES
Definition: hudparse.h:17