FS2_Open
Open source remastering of the Freespace 2 engine
missionweaponchoice.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 #include "anim/animplay.h"
13 #include "anim/packunpack.h"
14 #include "cfile/cfile.h"
15 #include "cmdline/cmdline.h"
16 #include "gamehelp/contexthelp.h"
17 #include "gamesnd/gamesnd.h"
18 #include "globalincs/alphacolors.h"
19 #include "hud/hudbrackets.h"
20 #include "io/mouse.h"
21 #include "io/timer.h"
22 #include "lighting/lighting.h"
23 #include "localization/localize.h"
24 #include "menuui/snazzyui.h"
25 #include "missionui/chatbox.h"
26 #include "missionui/missionbrief.h"
30 #include "model/model.h"
31 #include "network/multi.h"
32 #include "network/multi_pmsg.h"
33 #include "network/multimsgs.h"
35 #include "network/multiui.h"
36 #include "network/multiutil.h"
37 #include "parse/parselo.h"
38 #include "popup/popup.h"
39 #include "render/3d.h"
40 #include "ship/ship.h"
41 #include "weapon/weapon.h"
42 
43 
44 #define IS_BANK_PRIMARY(x) (x < MAX_SHIP_PRIMARY_BANKS)
45 #define IS_BANK_SECONDARY(x) (x >= MAX_SHIP_PRIMARY_BANKS)
46 
47 #define IS_LIST_PRIMARY(x) (Weapon_info[x].subtype != WP_MISSILE)
48 #define IS_LIST_SECONDARY(x) (Weapon_info[x].subtype == WP_MISSILE)
49 
50 extern int Multi_ping_timestamp;
51 
53 // Game-wide globals
55 
56 // This game-wide global flag is set to 1 to indicate that the weapon
57 // select screen has been opened and memory allocated. This flag
58 // is needed so we can know if weapon_select_close() needs to called if
59 // restoring a game from the Options screen invoked from weapon select
61 
63 // UI Data
65 
66 typedef struct wl_bitmap_group
67 {
71 
72 #define WEAPON_ANIM_LOOP_FRAME 52 // frame (from 0) to loop weapon anim
73 
74 #define WEAPON_ICON_FRAME_NORMAL 0
75 #define WEAPON_ICON_FRAME_HOT 1
76 #define WEAPON_ICON_FRAME_SELECTED 2
77 #define WEAPON_ICON_FRAME_DISABLED 3
78 
79 
80 #define NUM_WEAPON_SETTINGS 2
81 
82 #define MAX_WEAPON_BUTTONS 8
83 #define MIN_WEAPON_BUTTONS 7
84 #define NUM_WEAPON_BUTTONS (Uses_apply_all_button ? MAX_WEAPON_BUTTONS : MIN_WEAPON_BUTTONS)
85 
86 // Weapn loadout specific buttons
87 #define WL_BUTTON_SCROLL_PRIMARY_UP 0
88 #define WL_BUTTON_SCROLL_PRIMARY_DOWN 1
89 #define WL_BUTTON_SCROLL_SECONDARY_UP 2
90 #define WL_BUTTON_SCROLL_SECONDARY_DOWN 3
91 #define WL_BUTTON_RESET 4
92 #define WL_BUTTON_DUMMY 5
93 #define WL_BUTTON_MULTI_LOCK 6
94 #define WL_BUTTON_APPLY_ALL 7
95 
96 extern int anim_timer_start;
97 
99 
100 // convenient struct for handling all button controls
101 struct wl_buttons {
102  char *filename;
103  int x, y, xt, yt;
104  int hotspot;
105  UI_BUTTON button; // because we have a class inside this struct, we need the constructor below..
106 
107  wl_buttons(char *name, int x1, int y1, int xt1, int yt1, int h) : filename(name), x(x1), y(y1), xt(xt1), yt(yt1), hotspot(h) {}
108 };
109 
111  {
112  wl_buttons("WLB_27", 24, 276, -1, -1, 27), // WL_BUTTON_SCROLL_PRIMARY_UP
113  wl_buttons("WLB_26", 24, 125, -1, -1, 26), // WL_BUTTON_SCROLL_PRIMARY_DOWN
114  wl_buttons("WLB_09", 24, 454, -1, -1, 9), // WL_BUTTON_SCROLL_SECONDARY_UP
115  wl_buttons("WLB_08", 24, 303, -1, -1, 8), // WL_BUTTON_SCROLL_SECONDARY_DOWN
116  wl_buttons("ssb_39", 571, 347, -1, -1, 39), // WL_BUTTON_RESET
117  wl_buttons("ssb_39", 0, 0, -1, -1, 99), // WL_BUTTON_DUMMY
118  wl_buttons("TSB_34", 603, 374, -1, -1, 34), // WL_BUTTON_MULTI_LOCK
119  wl_buttons("WLB_40", 0, 90, -1, -1, 40) // WL_BUTTON_APPLY_ALL
120  },
121  {
122  wl_buttons("2_WLB_27", 39, 442, -1, -1, 27),
123  wl_buttons("2_WLB_26", 39, 200, -1, -1, 26),
124  wl_buttons("2_WLB_09", 39, 727, -1, -1, 9),
125  wl_buttons("2_WLB_08", 39, 485, -1, -1, 8),
126  wl_buttons("2_ssb_39", 913, 556, -1, -1, 39),
127  wl_buttons("2_ssb_39", 0, 0, -1, -1, 99),
128  wl_buttons("2_TSB_34", 966, 599, -1, -1, 34),
129  wl_buttons("2_WLB_40", 0, 138, -1, -1, 40)
130  }
131 };
132 
133 
134 static char *Wl_mask_single[NUM_WEAPON_SETTINGS][GR_NUM_RESOLUTIONS] = {
135  {
136  "weaponloadout-m",
137  "2_weaponloadout-m"
138  },
139  {
140  "weaponloadout-mb",
141  "2_weaponloadout-mb"
142  }
143 };
144 
145 static char *Wl_mask_multi[NUM_WEAPON_SETTINGS][GR_NUM_RESOLUTIONS] = {
146  {
147  "weaponloadoutmulti-m",
148  "2_weaponloadoutmulti-m"
149  },
150 
151  {
152  "weaponloadoutmulti-mb",
153  "2_weaponloadoutmulti-mb"
154  }
155 };
156 
157 static char *Wl_loadout_select_mask[NUM_WEAPON_SETTINGS][GR_NUM_RESOLUTIONS] = {
158  {
159  "weaponloadout-m",
160  "2_weaponloadout-m"
161  },
162  {
163  "weaponloadout-mb",
164  "2_weaponloadout-mb"
165  }
166 };
167 
168 
169 static char *Weapon_select_background_fname[NUM_WEAPON_SETTINGS][GR_NUM_RESOLUTIONS] = {
170  {
171  "WeaponLoadout",
172  "2_WeaponLoadout"
173  },
174  {
175  "WeaponLoadoutb",
176  "2_WeaponLoadoutb"
177  }
178 };
179 
180 static char *Weapon_select_multi_background_fname[NUM_WEAPON_SETTINGS][GR_NUM_RESOLUTIONS] = {
181  {
182  "WeaponLoadoutMulti",
183  "2_WeaponLoadoutMulti"
184  },
185  {
186  "WeaponLoadoutMultib",
187  "2_WeaponLoadoutMultib"
188  }
189 };
190 
191 static int Uses_apply_all_button = 0;
192 
193 int Weapon_select_background_bitmap; // bitmap for weapon select brackground
194 
195 static MENU_REGION Weapon_select_region[NUM_COMMON_REGIONS + 27]; // see initialization
196 static int Num_weapon_select_regions;
197 
198 // Mask bitmap pointer and Mask bitmap_id
199 static bitmap* WeaponSelectMaskPtr; // bitmap pointer to the weapon select mask bitmap
200 static ubyte* WeaponSelectMaskData; // pointer to actual bitmap data
201 static int Weaponselect_mask_w, Weaponselect_mask_h;
202 static int WeaponSelectMaskBitmap; // bitmap id of the weapon select mask bitmap
203 static int Weapon_slot_bitmap;
204 
206 
207 static int Weapon_button_scrollable[MAX_WEAPON_BUTTONS] = {0, 0, 0, 0, 0, 0, 0, 0};
208 
209 #define MAX_WEAPON_ICONS_ON_SCREEN 8
210 
211 // X and Y locations of the weapon icons in the scrollable lists
212 static int Wl_weapon_icon_coords[GR_NUM_RESOLUTIONS][MAX_WEAPON_ICONS_ON_SCREEN][2] = {
213  {
214  {27, 152},
215  {27, 182},
216  {27, 212},
217  {27, 242},
218  {36, 331},
219  {36, 361},
220  {36, 391},
221  {36, 421}
222  },
223  {
224  {59, 251},
225  {59, 299},
226  {59, 347},
227  {59, 395},
228  {59, 538},
229  {59, 586},
230  {59, 634},
231  {59, 682}
232  }
233 };
234 
235 static int Wl_bank_coords[GR_NUM_RESOLUTIONS][MAX_SHIP_WEAPONS][2] = {
236  {
237  {106,127},
238  {106,158},
239  {106,189},
240  {322,127},
241  {322,158},
242  {322,189},
243  {322,220},
244  },
245  {
246  {170,203},
247  {170,246},
248  {170,290},
249  {552,203},
250  {552,246},
251  {552,290},
252  {552,333},
253  }
254 };
255 
256 static int Wl_bank_count_draw_flags[MAX_SHIP_WEAPONS] = {
257  0, 0, 0, // primaries -- don't draw counts
258  1, 1, 1, 1 // secondaries -- do draw counts
259 };
260 
261 
262 static int Weapon_anim_class = -1;
263 static int Last_wl_ship_class;
264 
265 static int Wl_overhead_coords[GR_NUM_RESOLUTIONS][2] = {
266  {
267  // GR_640
268  91, 117
269  },
270  {
271  // GR_1024
272  156, 183
273  }
274 };
275 
276 static int Wl_weapon_ani_coords[GR_NUM_RESOLUTIONS][2] = {
277  {
278  408, 82 // GR_640
279  },
280  {
281  648, 128 // GR_1024
282  }
283 };
284 
285 static int Wl_weapon_ani_coords_multi[GR_NUM_RESOLUTIONS][2] = {
286  {
287  408, 143 // GR_640
288  },
289  {
290  648, 226 // GR_1024
291  }
292 };
293 
294 
295 static int Wl_weapon_desc_coords[GR_NUM_RESOLUTIONS][2] = {
296  {
297  508, 283 // GR_640
298  },
299  {
300  813, 453 // GR_1024
301  }
302 };
303 
304 static int Wl_delta_x, Wl_delta_y;
305 
306 static int Wl_ship_name_coords[GR_NUM_RESOLUTIONS][2] = {
307  {
308  85, 106
309  },
310  {
311  136, 170
312  }
313 };
314 
315 
317 // UI data structs
319 typedef struct wl_ship_class_info
320 {
325 
327 
328 typedef struct wl_icon_info
329 {
333  int can_use;
335 } wl_icon_info;
336 
339 
340 int Plist[MAX_WEAPON_TYPES]; // used to track scrolling of primary icon list
342 
343 int Slist[MAX_WEAPON_TYPES]; // used to track scrolling of primary icon list
345 
346 static int Selected_wl_slot = -1; // Currently selected ship slot
347 static int Selected_wl_class = -1; // Class of weapon that is selected
348 static int Hot_wl_slot = -1; // Ship slot that mouse is over (0..MAX_WSS_SLOTS-1)
349 static int Hot_weapon_icon = -1; // Icon number (0-7) which has mouse over it
350 static int Hot_weapon_bank = -1; // index (0-7) for weapon slot on ship that has a droppable icon over it
351 static int Hot_weapon_bank_icon = -1;
352 static generic_anim Cur_Anim;
353 
354 static int Wl_mouse_down_on_region = -1;
355 
356 
357 // weapon desc stuff
358 #define WEAPON_DESC_WIPE_TIME 1.5f // time in seconds for wipe to occur (over WEAPON_DESC_MAX_LENGTH number of chars)
359 #define WEAPON_DESC_MAX_LINES 7 // max lines in the description incl. title
360 #define WEAPON_DESC_MAX_LENGTH 50 // max chars per line of description text
361 static int Weapon_desc_wipe_done = 0;
362 static float Weapon_desc_wipe_time_elapsed = 0.0f;
363 static char Weapon_desc_lines[WEAPON_DESC_MAX_LINES][WEAPON_DESC_MAX_LENGTH]; // 1st 2 lines are title, rest are desc
364 
365 // maximum width the weapon title can be -- used in the line breaking
367 
368 static int Wl_new_weapon_title_coords[GR_NUM_RESOLUTIONS][2] = {
369  {
370  408, 75 // GR_640
371  },
372  {
373  648, 118 // GR_1024
374  }
375 };
376 
377 static int Wl_new_weapon_title_coords_multi[GR_NUM_RESOLUTIONS][2] = {
378  {
379  408, 136 // GR_640
380  },
381  {
382  648, 216 // GR_1024
383  }
384 };
385 
386 static int Wl_new_weapon_desc_coords[GR_NUM_RESOLUTIONS][2] = {
387  {
388  408, 247 // GR_640
389  },
390  {
391  648, 395 // GR_1024
392  }
393 };
394 
395 static int Wl_new_weapon_desc_coords_multi[GR_NUM_RESOLUTIONS][2] = {
396  {
397  408, 308 // GR_640
398  },
399  {
400  648, 493 // GR_1024
401  }
402 };
403 
404 // ship select text
405 #define WEAPON_SELECT_NUM_TEXT 2
407  { // GR_640
408  { "Reset", 1337, 580, 337, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][WL_BUTTON_RESET].button },
409  { "Lock", 1270, 602, 364, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][WL_BUTTON_MULTI_LOCK].button }
410  },
411  { // GR_1024
412  { "Reset", 1337, 938, 546, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][WL_BUTTON_RESET].button },
413  { "Lock", 1270, 964, 584, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][WL_BUTTON_MULTI_LOCK].button }
414  }
415 };
416 
417 
419 // Carried Icon
421 typedef struct carried_icon
422 {
423  int weapon_class; // index Wl_icons[] for carried icon (-1 if carried from bank)
424  int num; // number of units of weapon
425  int from_bank; // bank index that icon came from (0..2 primary, 3..6 secondary). -1 if from list
426  int from_slot; // ship slot that weapon is part of
428 } carried_icon;
429 
430 static carried_icon Carried_wl_icon;
431 
432 // forward declarations
433 void draw_wl_icons();
434 void wl_draw_ship_weapons(int index);
435 void wl_pick_icon_from_list(int index);
436 void pick_from_ship_slot(int num);
437 void start_weapon_animation(int weapon_class);
438 void stop_weapon_animation();
440 
441 void wl_reset_to_defaults();
442 
443 void wl_set_selected_slot(int slot_num);
446 
447 void wl_render_icon_count(int num, int x, int y);
448 void wl_render_weapon_desc();
449 
451 
452 // carry icon functions
453 void wl_reset_carried_icon();
455 void wl_set_carried_icon(int from_bank, int from_slot, int weapon_class);
456 
457 
458 const char *wl_tooltip_handler(const char *str)
459 {
460  if (Selected_wl_class < 0)
461  return NULL;
462 
463  if (!stricmp(str, "@weapon_desc")) {
464  char *str2;
465  int x, y, w, h;
466 
467  str2 = Weapon_info[Selected_wl_class].desc;
468  gr_get_string_size(&w, &h, str2);
469  x = Wl_weapon_desc_coords[gr_screen.res][0] - w / 2;
470  y = Wl_weapon_desc_coords[gr_screen.res][1] - h / 2;
471 
473  gr_rect(x - 5, y - 5, w + 10, h + 10, GR_RESIZE_MENU);
474 
476  gr_string(x, y, str2, GR_RESIZE_MENU);
477  return NULL;
478  }
479 
480  return NULL;
481 }
482 
487 {
488  Carried_wl_icon.weapon_class = -1;
489  Carried_wl_icon.num = 0;
490  Carried_wl_icon.from_bank = -1;
491  Carried_wl_icon.from_slot = -1;
492 }
493 
498 {
499  if ( Carried_wl_icon.weapon_class >= 0 ) {
500  return 1;
501  }
502 
503  return 0;
504 }
505 
509 void wl_set_carried_icon(int from_bank, int from_slot, int weapon_class)
510 {
511  int mx,my;
512 
513  Carried_wl_icon.from_bank = from_bank;
514  Carried_wl_icon.from_slot = from_slot;
515  Carried_wl_icon.weapon_class = weapon_class;
516 
517  mouse_get_pos_unscaled( &mx, &my );
518  Carried_wl_icon.from_x=mx;
519  Carried_wl_icon.from_y=my;
520 
522 }
523 
528 {
529  int mx, my;
530  mouse_get_pos_unscaled( &mx, &my );
531  if ( Carried_wl_icon.from_x != mx || Carried_wl_icon.from_y != my) {
532  return 1;
533  }
534 
535  return 0;
536 }
537 
542 {
543  int pilot_index, start_index, end_index, i;
544 
545  // see if there is a PILOT subystem
546  start_index = pobjp->subsys_index;
547  end_index = start_index + pobjp->subsys_count;
548  pilot_index = -1;
549  for ( i = start_index; i < end_index; i++ ) {
550  if ( !subsystem_stricmp(Subsys_status[i].name, NOX("pilot") ) ) {
551  pilot_index = i;
552  break;
553  }
554  }
555 
556  if ( pilot_index == -1 ) {
557  Error(LOCATION,"Parse object doesn't have a pilot subsystem\n");
558  return -1;
559  }
560 
561  return pilot_index;
562 }
563 
564 // ---------------------------------------------------------------------------------
565 // weapon_button_do()
566 //
568 {
569  switch ( i ) {
573  } else {
575  }
576  break;
577 
581  } else {
583  }
584  break;
585 
589  } else {
591  }
592  break;
593 
597  } else {
599  }
600  break;
601 
602  case WL_BUTTON_RESET:
604  break;
605 
608  // the "lock" button has been pressed
610 
611  // disable the button if it is now locked
612  if(multi_ts_is_locked()){
614  }
615  break;
616 
617  case WL_BUTTON_APPLY_ALL:
619  break;
620 
621  default:
622  popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "Button %d is not yet implemented", i);
623  break;
624  }
625 }
626 
632 {
633  int i;
634  wl_buttons *b;
635 
636  for ( i = 0; i < NUM_WEAPON_BUTTONS; i++ ) {
637  b = &Buttons[gr_screen.res][i];
638 
639  if ( b->button.pressed() ) {
640  weapon_button_do(i);
641  }
642  }
643 }
644 
651 {
652  int i;
653  wl_buttons *b;
654 
656 
657  for ( i = 0; i < NUM_WEAPON_BUTTONS; i++ ) {
658  b = &Buttons[gr_screen.res][i];
659  if ( b->button.button_down() ) {
660  b->button.draw_forced(2);
661  }
662  }
663 }
664 
665 // ---------------------------------------------------------------------------------
666 // weapon_buttons_init()
667 //
669 {
670  wl_buttons *b;
671  int i;
672 
673  for ( i = 0; i < NUM_WEAPON_BUTTONS; i++ ) {
674  b = &Buttons[gr_screen.res][i];
675  b->button.create( &Weapon_ui_window, "", Buttons[gr_screen.res][i].x, Buttons[gr_screen.res][i].y, 60, 30, Weapon_button_scrollable[i]);
676  // set up callback for when a mouse first goes over a button
678  b->button.set_bmaps(Buttons[gr_screen.res][i].filename);
679  b->button.link_hotspot(Buttons[gr_screen.res][i].hotspot);
680  }
681 
682  if ( Game_mode & GM_MULTIPLAYER ) {
685 
686  // if we're not the host of the game (or a team captain in team vs. team mode), disable the lock button
690  }
691  } else {
694  }
695  }
696  } else {
699  }
700 
701  // add all xstrs
702  for(i=0; i<WEAPON_SELECT_NUM_TEXT; i++) {
703  Weapon_ui_window.add_XSTR(&Weapon_select_text[gr_screen.res][i]);
704  }
705 
708 }
709 
710 // ---------------------------------------------------------------------------------
711 // wl_render_overhead_view()
712 //
713 void wl_render_overhead_view(float frametime)
714 {
715  //For 3d ships
716  static float WeapSelectScreenShipRot = 0.0f;
717  int new_ship = 0;
718  static int display_type = -1;
719 
720  if ( Selected_wl_slot == -1 ) {
721  return;
722  }
723 
724  wl_ship_class_info *wl_ship;
725  int ship_class;
726 
727  Assert( Wss_slots != NULL );
728 
729  ship_class = Wss_slots[Selected_wl_slot].ship_class;
730  if (ship_class < 0 || ship_class >= static_cast<int>(Ship_info.size()))
731  {
732  Warning(LOCATION, "Invalid ship class (%d) passed for render_overhead_view", ship_class);
733  return;
734  }
735  ship_info * sip = &Ship_info[ship_class];
736 
737  // check if ship class has changed and maybe play sound
738  if (Last_wl_ship_class != ship_class) {
739  if (Last_wl_ship_class != -1) {
741  }
742  Last_wl_ship_class = ship_class;
743  new_ship = 1;
744  }
745 
746  wl_ship = &Wl_ships[ship_class];
747  ship_class = Wss_slots[Selected_wl_slot].ship_class;
748 
749  if (new_ship)
750  {
751  display_type = -1;
752 
753  if(Cmdline_ship_choice_3d || !strlen(sip->overhead_filename))
754  {
755  if (wl_ship->model_num < 0)
756  {
757  wl_ship->model_num = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
758  model_page_in_textures(wl_ship->model_num, ship_class);
759  }
760 
761  if(wl_ship->model_num > -1)
762  {
764  {
765  display_type = 2;
766  }
767  else
768  {
769  display_type = 1;
770  }
771  }
772  }
773 
774  if(display_type < 0)
775  {
776  if ( wl_ship->overhead_bitmap < 0 )
777  {
778  //Load the anim?
779  if (gr_screen.res == GR_640)
780  {
781  // lo-res
782  wl_ship->overhead_bitmap = bm_load_animation(sip->overhead_filename, NULL, NULL, 0, CF_TYPE_INTERFACE);
783  } else {
784  // high-res
785  char filename[NAME_LENGTH+2] = "2_";
786  strcat_s(filename, sip->overhead_filename);
787  wl_ship->overhead_bitmap = bm_load_animation(sip->overhead_filename, NULL, NULL, 0, CF_TYPE_INTERFACE);
788  }
789 
790  // load the bitmap
791  if (gr_screen.res == GR_640)
792  {
793  // lo-res
794  wl_ship->overhead_bitmap = bm_load(sip->overhead_filename);
795  } else {
796  // high-res
797  char filename[NAME_LENGTH+2] = "2_";
798  strcat_s(filename, sip->overhead_filename);
799  wl_ship->overhead_bitmap = bm_load(filename);
800  }
801  }
802 
803  //Did we load anything?
804  if ( wl_ship->overhead_bitmap < 0 )
805  {
806  Warning(LOCATION, "Unable to load overhead image for ship '%s', generating one instead", sip->name);
807  display_type = 1;
808  } else {
809  display_type = 0;
810  }
811  }
812  }
813 
814  //Maybe do 2D
815  if(display_type == 0 && wl_ship->overhead_bitmap > -1)
816  {
817  gr_set_bitmap(wl_ship->overhead_bitmap);
818  gr_bitmap(Wl_overhead_coords[gr_screen.res][0], Wl_overhead_coords[gr_screen.res][1], GR_RESIZE_MENU);
819  }
820  else
821  {
822  // Load the necessary model file, if necessary
823  if (wl_ship->model_num < 0)
824  {
825  wl_ship->model_num = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
826  model_page_in_textures(wl_ship->model_num, ship_class);
827  }
828 
829  if (wl_ship->model_num < 0)
830  {
831  mprintf(("Couldn't load model file in missionweaponchoice.cpp\n"));
832  }
833  else
834  {
835  matrix object_orient = IDENTITY_MATRIX;
836  angles rot_angles;
837  float zoom;
838  zoom = sip->closeup_zoom * 1.3f;
839 
841  {
842  rot_angles.p = -(PI_2);
843  rot_angles.b = 0.0f;
844  rot_angles.h = 0.0f;
845  vm_angles_2_matrix(&object_orient, &rot_angles);
846  }
847  else
848  {
849  float rev_rate;
850  rev_rate = REVOLUTION_RATE;
851  if (sip->flags & SIF_BIG_SHIP) {
852  rev_rate *= 1.7f;
853  }
854  if (sip->flags & SIF_HUGE_SHIP) {
855  rev_rate *= 3.0f;
856  }
857 
858  WeapSelectScreenShipRot += PI2 * frametime / rev_rate;
859  while (WeapSelectScreenShipRot > PI2){
860  WeapSelectScreenShipRot -= PI2;
861  }
862 
863  rot_angles.p = -0.6f;
864  rot_angles.b = 0.0f;
865  rot_angles.h = 0.0f;
866  vm_angles_2_matrix(&object_orient, &rot_angles);
867 
868  rot_angles.p = 0.0f;
869  rot_angles.b = 0.0f;
870  rot_angles.h = WeapSelectScreenShipRot;
871  vm_rotate_matrix_by_angles(&object_orient, &rot_angles);
872  }
873 
874  model_render_params render_info;
875 
876  gr_set_clip(Wl_overhead_coords[gr_screen.res][0], Wl_overhead_coords[gr_screen.res][1], gr_screen.res == 0 ? 291 : 467, gr_screen.res == 0 ? 226 : 362, GR_RESIZE_MENU);
877  g3_start_frame(1);
878  g3_set_view_matrix( &sip->closeup_pos, &Eye_matrix, zoom);
879  render_info.set_detail_level_lock(0);
880 
881 
882  light_reset();
883  vec3d light_dir = vmd_zero_vector;
884  light_dir.xyz.x = 0.5;
885  light_dir.xyz.y = 2.0f;
886  light_dir.xyz.z = -2.0f;
887  light_add_directional(&light_dir, 0.65f, 1.0f, 1.0f, 1.0f);
889 
891 
893  polymodel *pm = model_get(wl_ship->model_num);
894 
896  {
897  gr_reset_clip();
899  -sip->closeup_pos.xyz.z + pm->rad + 200.0f, -sip->closeup_pos.xyz.z + pm->rad + 2000.0f, -sip->closeup_pos.xyz.z + pm->rad + 10000.0f);
900 
902 
903  model_render_immediate(&render_info, wl_ship->model_num, &object_orient, &vmd_zero_vector);
905  gr_set_clip(Wl_overhead_coords[gr_screen.res][0], Wl_overhead_coords[gr_screen.res][1], gr_screen.res == 0 ? 291 : 467, gr_screen.res == 0 ? 226 : 362, GR_RESIZE_MENU);
906  }
907 
908  if (!Cmdline_nohtl) {
911  }
912 
913  render_info.set_flags(MR_AUTOCENTER | MR_NO_FOGGING);
914 
915  model_render_immediate(&render_info, wl_ship->model_num, &object_orient, &vmd_zero_vector);
916 
918 
920 
921  //NOW render the lines for weapons
922  gr_reset_clip();
923  vertex draw_point;
924  vec3d subobj_pos;
925  int x, y;
926  int xc, yc;
927  int num_found = 2;
928 
929  //Render selected primary lines
930  for(x = 0; x < pm->n_guns; x++)
931  {
932  if((Wss_slots[Selected_wl_slot].wep[x] == Selected_wl_class && Hot_weapon_bank < 0) || x == Hot_weapon_bank)
933  {
934  Assert(num_found < NUM_ICON_FRAMES);
936  gr_circle(Wl_bank_coords[gr_screen.res][x][0] + 106, Wl_bank_coords[gr_screen.res][x][1] + 12, 5, GR_RESIZE_MENU);
937  for(y = 0; y < pm->gun_banks[x].num_slots; y++)
938  {
939  //Stuff
940  vm_vec_unrotate(&subobj_pos,&pm->gun_banks[x].pnt[y],&object_orient);
941  g3_rotate_vertex(&draw_point, &subobj_pos);
942  g3_project_vertex(&draw_point);
943  gr_unsize_screen_posf(&draw_point.screen.xyw.x, &draw_point.screen.xyw.y, NULL, NULL, GR_RESIZE_MENU_NO_OFFSET);
944 
945  xc = fl2i(draw_point.screen.xyw.x + Wl_overhead_coords[gr_screen.res][0]);
946  yc = fl2i(draw_point.screen.xyw.y +Wl_overhead_coords[gr_screen.res][1]);
947 
948  //get the curve right.
949  int curve;
950  if ((xc > Wl_bank_coords[gr_screen.res][x][0] + 106) && (Wl_bank_coords[gr_screen.res][x][1] + 12 < yc))
951  curve = 1;
952  else if ((xc < Wl_bank_coords[gr_screen.res][x][0] + 106) && (Wl_bank_coords[gr_screen.res][x][1] + 12 < yc))
953  curve = 0;
954  else if ((xc > Wl_bank_coords[gr_screen.res][x][0] + 106) && (Wl_bank_coords[gr_screen.res][x][1] + 12 > yc))
955  curve = 3;
956  else
957  curve = 2;
958 
959  int lineendx;
960  int lineendy;
961  if (curve == 0) {
962  lineendx = xc + 4;
963  } else {
964  lineendx = xc - 4;
965  }
966 
967  gr_line(Wl_bank_coords[gr_screen.res][x][0] + 106, Wl_bank_coords[gr_screen.res][x][1] + 12, lineendx, Wl_bank_coords[gr_screen.res][x][1] + 12, GR_RESIZE_MENU);
968 
969  if (curve == 0 || curve == 2)
970  lineendx = xc;
971 
972  if (curve == 0 || curve == 1) {
973  lineendy = Wl_bank_coords[gr_screen.res][x][1] + 12;
974  } else {
975  lineendy = Wl_bank_coords[gr_screen.res][x][1] + 7;
976  }
977 
978  gr_curve(lineendx, lineendy, 5, curve, GR_RESIZE_MENU);
979 
980  if (curve == 0 || curve == 1) {
981  lineendy = Wl_bank_coords[gr_screen.res][x][1] + 17;
982  } else {
983  lineendy = Wl_bank_coords[gr_screen.res][x][1] + 7;
984  }
985 
986  gr_line(xc, lineendy, xc, yc, GR_RESIZE_MENU);
987  gr_circle(xc, yc, 5, GR_RESIZE_MENU);
988  }
989  num_found++;
990  }
991  }
992 
993  num_found = 2;
994  //Render selected secondary lines
995  for(x = 0; x < pm->n_missiles; x++)
996  {
997  if((Wss_slots[Selected_wl_slot].wep[x + MAX_SHIP_PRIMARY_BANKS] == Selected_wl_class && Hot_weapon_bank < 0) || x + MAX_SHIP_PRIMARY_BANKS == Hot_weapon_bank)
998  {
999  Assert(num_found < NUM_ICON_FRAMES);
1001  gr_circle(Wl_bank_coords[gr_screen.res][x + MAX_SHIP_PRIMARY_BANKS][0] - 50, Wl_bank_coords[gr_screen.res][x + MAX_SHIP_PRIMARY_BANKS][1] + 12, 5, GR_RESIZE_MENU);
1002  for(y = 0; y < pm->missile_banks[x].num_slots; y++)
1003  {
1004  vm_vec_unrotate(&subobj_pos,&pm->missile_banks[x].pnt[y],&object_orient);
1005  g3_rotate_vertex(&draw_point, &subobj_pos);
1006  g3_project_vertex(&draw_point);
1007  gr_unsize_screen_posf(&draw_point.screen.xyw.x, &draw_point.screen.xyw.y, NULL, NULL, GR_RESIZE_MENU_NO_OFFSET);
1008 
1009  xc = fl2i(draw_point.screen.xyw.x + Wl_overhead_coords[gr_screen.res][0]);
1010  yc = fl2i(draw_point.screen.xyw.y +Wl_overhead_coords[gr_screen.res][1]);
1011 
1012  //get the curve right.
1013  int curve;
1014  if ((xc > Wl_bank_coords[gr_screen.res][x + MAX_SHIP_PRIMARY_BANKS][0] - 50) && (Wl_bank_coords[gr_screen.res][x + MAX_SHIP_PRIMARY_BANKS][1] + 12 < yc))
1015  curve = 1;
1016  else if ((xc < Wl_bank_coords[gr_screen.res][x + MAX_SHIP_PRIMARY_BANKS][0] - 50) && (Wl_bank_coords[gr_screen.res][x + MAX_SHIP_PRIMARY_BANKS][1] + 12 < yc))
1017  curve = 0;
1018  else if ((xc > Wl_bank_coords[gr_screen.res][x + MAX_SHIP_PRIMARY_BANKS][0] - 50) && (Wl_bank_coords[gr_screen.res][x + MAX_SHIP_PRIMARY_BANKS][1] + 12 > yc))
1019  curve = 3;
1020  else
1021  curve = 2;
1022 
1023  int lineendx;
1024  int lineendy;
1025  if (curve == 1 || curve == 3)
1026  lineendx = xc - 4;
1027  else
1028  lineendx = xc + 4;
1029 
1030  gr_line(Wl_bank_coords[gr_screen.res][x + MAX_SHIP_PRIMARY_BANKS][0] - 50, Wl_bank_coords[gr_screen.res][x + MAX_SHIP_PRIMARY_BANKS][1] + 12, lineendx, Wl_bank_coords[gr_screen.res][x + MAX_SHIP_PRIMARY_BANKS][1] + 12, GR_RESIZE_MENU);
1031 
1032  if (curve == 1 || curve == 2) {
1033  lineendy = Wl_bank_coords[gr_screen.res][x + MAX_SHIP_PRIMARY_BANKS][1] + 7;
1034  } else {
1035  lineendy = Wl_bank_coords[gr_screen.res][x + MAX_SHIP_PRIMARY_BANKS][1] + 12;
1036  }
1037  gr_curve(xc, lineendy, 5, curve, GR_RESIZE_MENU);
1038 
1039  if (curve == 1 || curve == 2) {
1040  lineendy = Wl_bank_coords[gr_screen.res][x + MAX_SHIP_PRIMARY_BANKS][1] + 7;
1041  } else {
1042  lineendy = Wl_bank_coords[gr_screen.res][x + MAX_SHIP_PRIMARY_BANKS][1] + 17;
1043  }
1044 
1045  gr_line(xc, lineendy, xc, yc, GR_RESIZE_MENU);
1046  gr_circle(xc, yc, 5, GR_RESIZE_MENU);
1047  }
1048 
1049  num_found++;
1050  }
1051  }
1052 
1053  //Cleanup
1054  if (!Cmdline_nohtl)
1055  {
1058  }
1059 
1060  g3_end_frame();
1061 
1062  }
1063  }
1064 
1065  //Draw ship name
1066  char name[NAME_LENGTH + CALLSIGN_LEN];
1067 
1068  ss_return_name(Selected_wl_slot/MAX_WING_SLOTS, Selected_wl_slot%MAX_WING_SLOTS, name);
1070  gr_string(Wl_ship_name_coords[gr_screen.res][0], Wl_ship_name_coords[gr_screen.res][1], name, GR_RESIZE_MENU);
1071 }
1072 
1073 // ---------------------------------------------------------------------------------
1074 // wl_get_ship_class()
1075 //
1076 //
1077 int wl_get_ship_class(int wl_slot)
1078 {
1079  Assert( Wss_slots != NULL );
1080 
1081  return Wss_slots[wl_slot].ship_class;
1082 }
1083 
1089 int eval_weapon_flag_for_game_type(int weapon_flags)
1090 {
1091  int rval = 0;
1092 
1093  if (MULTI_DOGFIGHT) {
1094  if (weapon_flags & DOGFIGHT_WEAPON)
1095  rval = 1;
1096  }
1097  else
1098  if (weapon_flags & REGULAR_WEAPON)
1099  rval = 1;
1100 
1101  return rval;
1102 }
1103 
1109 void wl_set_disabled_weapons(int ship_class)
1110 {
1111  int i;
1112  ship_info *sip;
1113 
1114  if ( ship_class == - 1 )
1115  return;
1116 
1117  Assert(ship_class >= 0 && ship_class < static_cast<int>(Ship_info.size()));
1118  Assert( Wl_icons != NULL );
1119 
1120  sip = &Ship_info[ship_class];
1121 
1122  for ( i = 0; i < MAX_WEAPON_TYPES; i++ )
1123  {
1124  // Determine whether weapon #i is allowed on this ship class in the current type of mission.
1125  // As of 9/6/99, the only difference is dogfight missions have a different list of legal weapons.
1127 
1128  // Goober5000: ballistic primaries
1129  if (Weapon_info[i].wi_flags2 & WIF2_BALLISTIC)
1130  {
1131  // not allowed if this ship is not ballistic
1132  if (!(sip->flags & SIF_BALLISTIC_PRIMARIES))
1133  {
1134  Wl_icons[i].can_use = 0;
1135  }
1136  }
1137  }
1138 }
1139 
1143 void maybe_select_wl_slot(int block, int slot)
1144 {
1145  int sidx;
1146 
1147  if ( Wss_num_wings <= 0 )
1148  return;
1149 
1150  Assert( Wss_slots != NULL );
1151 
1152  sidx = block*MAX_WING_SLOTS + slot;
1153  if ( Wss_slots[sidx].ship_class < 0 ) {
1154  return;
1155  }
1156 
1157  wl_set_selected_slot(sidx);
1158 }
1159 
1165 {
1166  int weapon_class;
1167 
1168  // if a weapon is being carried, do nothing
1169  if ( wl_icon_being_carried() ) {
1170  return;
1171  }
1172 
1173  int region_index = ICON_PRIMARY_0+index;
1174  if ( index > 3 ) {
1175  region_index = ICON_SECONDARY_0 + (index - 4);
1176  }
1177 
1178  if ( Wl_mouse_down_on_region != region_index ) {
1179  return;
1180  }
1181 
1182  if ( index < 4 ) {
1183  weapon_class = Plist[Plist_start+index];
1184  } else {
1185  weapon_class = Slist[Slist_start+index-4];
1186  }
1187 
1188  if ( weapon_class >= 0 ) {
1189  Selected_wl_class = weapon_class;
1190  wl_pick_icon_from_list(index);
1191  }
1192 }
1193 
1199 {
1200  int *wep, *wep_count;
1201 
1202  if ( Selected_wl_slot == -1 )
1203  return;
1204 
1205  if ( wl_icon_being_carried() ) {
1206  return;
1207  }
1208 
1209  Assert( Wss_slots != NULL );
1210 
1211  wep = Wss_slots[Selected_wl_slot].wep;
1212  wep_count = Wss_slots[Selected_wl_slot].wep_count;
1213 
1214  if ( wep[index] < 0 || wep_count[index] <= 0 ) {
1215  return;
1216  }
1217 
1218  if ( Wl_mouse_down_on_region != (ICON_SHIP_PRIMARY_0+index) ) {
1219  return;
1220  }
1221 
1222  Selected_wl_class = wep[index];
1223 }
1224 
1229 {
1230  int i;
1231 
1232  Assert( Wl_pool != NULL );
1233 
1234  for ( i = 0; i < MAX_WEAPON_TYPES; i++ ) {
1235  Wl_pool[i] = 0;
1236  }
1237 
1238  for ( i = 0; i < td->num_weapon_choices; i++ ) {
1239  Wl_pool[td->weaponry_pool[i]] += td->weaponry_count[i]; // read from mission
1240  }
1241 }
1242 
1247 {
1248  if(Cur_Anim.num_frames > 0)
1249  generic_anim_unload(&Cur_Anim);
1250 }
1251 
1255 void wl_load_icons(int weapon_class)
1256 {
1257  wl_icon_info *icon;
1258  int first_frame = -1;
1259  int num_frames = 0, i;
1260  weapon_info *wip = &Weapon_info[weapon_class];
1261 
1262  Assert( Wl_icons != NULL );
1263 
1264  icon = &Wl_icons[weapon_class];
1265 
1266  if(!Cmdline_weapon_choice_3d || (wip->render_type == WRT_LASER && !strlen(wip->tech_model)))
1267  {
1268  first_frame = bm_load_animation(Weapon_info[weapon_class].icon_filename, &num_frames, NULL, 0, CF_TYPE_INTERFACE);
1269 
1270  for ( i = 0; (i < num_frames) && (i < NUM_ICON_FRAMES); i++ ) {
1271  icon->icon_bmaps[i] = first_frame+i;
1272  }
1273  }
1274 
1276 
1277  if ( first_frame == -1 && icon->model_index == -1)
1278  {
1279  if(strlen(wip->tech_model))
1280  {
1281  icon->model_index = model_load(wip->tech_model, 0, NULL, 0);
1282  }
1283  if(wip->render_type != WRT_LASER && icon->model_index == -1)
1284  {
1285  icon->model_index = model_load(wip->pofbitmap_name, 0, NULL);
1286  }
1287  }
1288 }
1289 
1294 {
1295 
1296  int i, j;
1297 
1298  Assert( (Wl_icons != NULL) && (Wl_pool != NULL) );
1299 
1300  for ( i = 0; i < MAX_WEAPON_TYPES; i++ ) {
1301  // clear out data
1302  generic_anim_init(&Wl_icons[i].animation, NULL);
1303  for ( j = 0; j < NUM_ICON_FRAMES; j++ ) {
1304  Wl_icons[i].icon_bmaps[j] = -1;
1305  }
1306  Wl_icons[i].model_index = -1;
1307  Wl_icons[i].laser_bmap = -1;
1308 
1309  if ( Wl_pool[i] > 0 ) {
1310  wl_load_icons(i);
1311  }
1312  }
1313 }
1314 
1319 {
1320  int i,j;
1321  wl_icon_info *icon;
1322 
1323  Assert( Wl_icons != NULL );
1324 
1325  for ( i = 0; i < MAX_WEAPON_TYPES; i++ ) {
1326  icon = &Wl_icons[i];
1327 
1328  for ( j = 0; j < NUM_ICON_FRAMES; j++ ) {
1329  if ( icon->icon_bmaps[j] >= 0 ) {
1330  bm_release(icon->icon_bmaps[j]);
1331  icon->icon_bmaps[j] = -1;
1332  }
1333  }
1334 
1335  if(icon->model_index >= 0) {
1336  model_unload(icon->model_index);
1337  icon->model_index = -1;
1338  }
1339  if(icon->laser_bmap >= 0) {
1340  bm_unload(icon->laser_bmap);
1341  icon->laser_bmap = -1;
1342  }
1343  if(Cur_Anim.num_frames > 0)
1344  generic_anim_unload(&Cur_Anim);
1345  }
1346 }
1347 
1352 {
1353  int i;
1354  wl_ship_class_info *wl_ship;
1355 
1356  for ( i = 0; i < static_cast<int>(Ship_info.size()); i++ ) {
1357  wl_ship = &Wl_ships[i];
1358  wl_ship->overhead_bitmap = -1;
1359  wl_ship->model_num = -1;
1360  generic_anim_init(&wl_ship->animation, NULL);
1361  }
1362 }
1363 
1368 {
1369  int i;
1370  wl_ship_class_info *wl_ship;
1371 
1372  for ( i = 0; i < static_cast<int>(Ship_info.size()); i++ ) {
1373  wl_ship = &Wl_ships[i];
1374 
1375  if ( wl_ship->overhead_bitmap != -1 ) {
1376  bm_release(wl_ship->overhead_bitmap);
1377  wl_ship->overhead_bitmap = -1;
1378  }
1379 
1380  if ( wl_ship->model_num != -1 ) {
1381  // this should unload the model from memory only if it's not used in the mission
1382  model_unload(wl_ship->model_num);
1383  wl_ship->model_num = -1;
1384  }
1385 
1386  if(wl_ship->animation.num_frames)
1387  generic_anim_unload(&wl_ship->animation);
1388  }
1389 }
1390 
1395 {
1396  int i;
1397  Selected_wl_slot = -1;
1398 
1399  Assert( Wss_slots != NULL );
1400 
1401  // in multiplayer, select the slot of the player's ship by default
1404  return;
1405  }
1406 
1407  for ( i=0; i<MAX_WSS_SLOTS; i++ ) {
1408  if ( !ss_disabled_slot(i, false) ) {
1409  if ( ss_wing_slot_is_console_player(i) && (Wss_slots[i].ship_class >= 0) ) {
1411  return;
1412  }
1413  }
1414  }
1415 
1416  // Didn't locate player ship, so just select the first ship we find
1417  for ( i=0; i<MAX_WSS_SLOTS; i++ ) {
1418  if ( Wss_slots[i].ship_class >= 0 ) {
1420  break;
1421  }
1422  }
1423 }
1424 
1429 {
1430  int reset=0;
1431 
1432  Assert( Wss_slots != NULL );
1433 
1434  if ( Selected_wl_slot == -1 ) {
1435  reset = 1;
1436  }
1437 
1438  if ( Wss_slots[Selected_wl_slot].ship_class < 0 ) {
1439  reset = 1;
1440  }
1441 
1442  if ( reset ) {
1444  }
1445 }
1446 
1452 {
1453  int i;
1454 
1455  if ( Selected_wl_class >= 0 )
1456  return;
1457 
1458  Assert( Wss_slots != NULL );
1459 
1460  // try to locate a weapon class to show animation for
1461  // first check for a weapon on the ship
1462  for (i=0; i<MAX_SHIP_WEAPONS; i++) {
1463  // if player has a weapon in bank i, set it as the selected type
1464  if (Wss_slots[0].wep_count[i] >= 0) {
1465  Selected_wl_class = Wss_slots[0].wep[i];
1466  return;
1467  }
1468  }
1469 
1470  // then check for a primary weapon in the pool
1471  for ( i = 0; i < Plist_size; i++ ) {
1472  if ( Plist[i] >= 0 ) {
1473  Selected_wl_class = Plist[i];
1474  return;
1475  }
1476  }
1477 
1478  // finally, if no others found yet, check for a secondary weapon in the pool
1479  for ( i = 0; i < Slist_size; i++ ) {
1480  if ( Slist[i] >= 0 ) {
1481  Selected_wl_class = Slist[i];
1482  return;
1483  }
1484  }
1485 }
1486 
1490 void wl_set_selected_slot(int slot_num)
1491 {
1492  Selected_wl_slot = slot_num;
1493  if ( Selected_wl_slot >= 0 ) {
1494  Assert( Wss_slots != NULL );
1495  wl_set_disabled_weapons(Wss_slots[slot_num].ship_class);
1496  }
1497 }
1498 
1502 int wl_calc_ballistic_fit(int wi_index, int capacity)
1503 {
1504  if ( wi_index < 0 ) {
1505  return 0;
1506  }
1507 
1508  Assert(Weapon_info[wi_index].subtype == WP_LASER);
1509 
1510  Assert(Weapon_info[wi_index].wi_flags2 & WIF2_BALLISTIC);
1511 
1512  return fl2i( capacity / Weapon_info[wi_index].cargo_size + 0.5f );
1513 }
1514 
1518 int wl_calc_missile_fit(int wi_index, int capacity)
1519 {
1520  if ( wi_index < 0 ) {
1521  return 0;
1522  }
1523 
1524  Assert(Weapon_info[wi_index].subtype == WP_MISSILE);
1525  return fl2i( capacity / Weapon_info[wi_index].cargo_size + 0.5f );
1526 }
1527 
1531 void wl_get_ship_class_weapons(int ship_class, int *wep, int *wep_count)
1532 {
1533  ship_info *sip;
1534  int i;
1535 
1536  Assert(ship_class >= 0 && ship_class < static_cast<int>(Ship_info.size()));
1537  sip = &Ship_info[ship_class];
1538 
1539  // reset weapons arrays
1540  for ( i=0; i < MAX_SHIP_WEAPONS; i++ ) {
1541  wep[i] = -1;
1542  wep_count[i] = -1; // -1 means weapon bank doesn't exist.. 0 just means it is empty
1543  }
1544 
1545  for ( i = 0; i < sip->num_primary_banks; i++ )
1546  {
1547  wep[i] = sip->primary_bank_weapons[i];
1548  wep_count[i] = 1;
1549  }
1550 
1551  for ( i = 0; i < sip->num_secondary_banks; i++ )
1552  {
1555  }
1556 }
1557 
1561 void wl_get_ship_weapons(int ship_index, int *wep, int *wep_count)
1562 {
1563  int i;
1564  ship_weapon *swp;
1565 
1566  Assert(ship_index >= 0);
1567 
1568  Assert(Ships[ship_index].wingnum >= 0);
1569  swp = &Ships[ship_index].weapons;
1570 
1571  for ( i = 0; i < swp->num_primary_banks; i++ )
1572  {
1573  wep[i] = swp->primary_bank_weapons[i];
1574  wep_count[i] = 1;
1575 
1576  if ( wep[i] == -1 ) {
1577  wep_count[i] = 0;
1578  }
1579  }
1580 
1581  for ( i = 0; i < swp->num_secondary_banks; i++ )
1582  {
1584  wep_count[i+MAX_SHIP_PRIMARY_BANKS] = swp->secondary_bank_ammo[i];
1585 
1586  if ( wep[i+MAX_SHIP_PRIMARY_BANKS] == -1 ) {
1587  wep_count[i+MAX_SHIP_PRIMARY_BANKS] = 0;
1588  }
1589  }
1590 }
1591 
1595 void wl_get_parseobj_weapons(int sa_index, int ship_class, int *wep, int *wep_count)
1596 {
1597  int i, pilot_index;
1598  subsys_status *ss;
1599  ship_info *sip;
1600  p_object *pobjp;
1601 
1602  pobjp = &Parse_objects[sa_index];
1603  sip = &Ship_info[ship_class];
1604 
1605  pilot_index = wl_get_pilot_subsys_index(pobjp);
1606 
1607  if ( pilot_index == -1 )
1608  return;
1609 
1610  ss = &Subsys_status[pilot_index];
1611 
1612  if ( ss->primary_banks[0] != SUBSYS_STATUS_NO_CHANGE ) {
1613  for ( i=0; i < MAX_SHIP_PRIMARY_BANKS; i++ ) {
1614  wep[i] = ss->primary_banks[i];
1615  }
1616  }
1617 
1618  if ( ss->secondary_banks[0] != SUBSYS_STATUS_NO_CHANGE ) {
1619  for ( i=0; i < MAX_SHIP_SECONDARY_BANKS; i++ ) {
1620  wep[i+MAX_SHIP_PRIMARY_BANKS] = ss->secondary_banks[i];
1621  }
1622  }
1623 
1624  // ammo counts could still be modified
1625  for ( i=0; i < MAX_SHIP_SECONDARY_BANKS; i++ )
1626  {
1627  if ( wep[i+MAX_SHIP_PRIMARY_BANKS] >= 0 )
1628  {
1630  }
1631  }
1632 }
1633 
1637 void wl_cull_illegal_weapons(int ship_class, int *wep, int *wep_count)
1638 {
1639  int i, check_flag;
1640  for ( i=0; i < MAX_SHIP_WEAPONS; i++ )
1641  {
1642  if ( wep[i] < 0 ) {
1643  continue;
1644  }
1645 
1646  check_flag = Ship_info[ship_class].allowed_weapons[wep[i]];
1647 
1648  // possibly change flag if it's restricted
1649  if (eval_weapon_flag_for_game_type(Ship_info[ship_class].restricted_loadout_flag[i]))
1650  {
1651  check_flag = Ship_info[ship_class].allowed_bank_restricted_weapons[i][wep[i]];
1652  }
1653 
1654 
1655  if ( !eval_weapon_flag_for_game_type(check_flag) ) {
1656 // wep[i] = -1;
1657  wep_count[i] = 0;
1658  }
1659  }
1660 }
1661 
1665 void wl_get_default_weapons(int ship_class, int slot_num, int *wep, int *wep_count)
1666 {
1667  int original_ship_class, i;
1668 
1669  Assert(slot_num >= 0 && slot_num < MAX_WSS_SLOTS);
1670 
1671  // clear out wep and wep_count
1672  for ( i = 0; i < MAX_SHIP_WEAPONS; i++ ) {
1673  wep[i] = -1;
1674  wep_count[i] = -1;
1675  }
1676 
1677  if ( ship_class < 0 )
1678  return;
1679 
1680  original_ship_class = ss_return_original_ship_class(slot_num);
1681 
1682  if ( original_ship_class != ship_class ) {
1683  wl_get_ship_class_weapons(ship_class, wep, wep_count);
1684  } else {
1685  int sa_index; // ship arrival index
1686  sa_index = ss_return_saindex(slot_num);
1687 
1688  if ( sa_index >= 0 ) {
1689  // still a parse object
1690  wl_get_ship_class_weapons(ship_class, wep, wep_count);
1691  wl_get_parseobj_weapons(sa_index, ship_class, wep, wep_count);
1692  } else {
1693  // ship has been created
1694  int ship_index = -1;
1695  p_object *pobjp;
1696  ss_return_ship(slot_num/MAX_WING_SLOTS, slot_num%MAX_WING_SLOTS, &ship_index, &pobjp);
1697  Assert(ship_index != -1);
1698  wl_get_ship_weapons(ship_index, wep, wep_count);
1699  }
1700  }
1701 
1702  // ensure that there aren't any bogus weapons assigned by default
1703  wl_cull_illegal_weapons(ship_class, wep, wep_count);
1704 }
1705 
1709 void wl_add_index_to_list(int wi_index)
1710 {
1711  int i;
1712  if ( Weapon_info[wi_index].subtype == WP_MISSILE ) {
1713 
1714  for ( i=0; i<Slist_size; i++ ) {
1715  if ( Slist[i] == wi_index )
1716  break;
1717  }
1718 
1719  if ( i == Slist_size )
1720  Slist[Slist_size++] = wi_index;
1721 
1722  } else {
1723  for ( i=0; i<Plist_size; i++ ) {
1724  if ( Plist[i] == wi_index )
1725  break;
1726  }
1727 
1728  if ( i == Plist_size )
1729  Plist[Plist_size++] = wi_index;
1730  }
1731 }
1732 
1736 void wl_remove_weps_from_pool(int *wep, int *wep_count, int ship_class)
1737 {
1738  int i, wi_index;
1739 
1740  Assert( Wl_pool != NULL );
1741 
1742  for ( i = 0; i < MAX_SHIP_WEAPONS; i++ ) {
1743  wi_index = wep[i];
1744  if ( wi_index >= 0 ) {
1745  if ( (wep_count[i] > 0) && ((Wl_pool[wi_index] - wep_count[i]) >= 0) ) {
1746  Wl_pool[wi_index] -= wep_count[i];
1747  } else {
1748  // not enough weapons in pool
1749  // TEMP HACK: FRED doesn't fill in a weapons pool if there are no starting wings... so
1750  // add to the pool. This should be fixed.
1751  if ( Wss_num_wings <= 0 ) {
1752  wl_add_index_to_list(wi_index);
1753  } else {
1754 
1755  if ( (Wl_pool[wi_index] <= 0) || (wep_count[i] == 0) ) {
1756  // fresh out of this weapon, pick an alternate pool weapon if we can
1757  int wep_pool_index, wep_precedence_index, new_wi_index = -1;
1758  for ( wep_pool_index = 0; wep_pool_index < MAX_WEAPON_TYPES; wep_pool_index++ ) {
1759 
1760  if ( Wl_pool[wep_pool_index] <= 0 ) {
1761  continue;
1762  }
1763 
1764  // AL 3-31-98: Only pick another primary if primary, etc
1765  if ( Weapon_info[wi_index].subtype != Weapon_info[wep_pool_index].subtype ) {
1766  continue;
1767  }
1768 
1769  if ( !eval_weapon_flag_for_game_type(Ship_info[ship_class].allowed_weapons[wep_pool_index]) ) {
1770  continue;
1771  }
1772 
1773  for ( wep_precedence_index = 0; wep_precedence_index < Num_player_weapon_precedence; wep_precedence_index++ ) {
1774  if ( wep_pool_index == Player_weapon_precedence[wep_precedence_index] ) {
1775  new_wi_index = wep_pool_index;
1776  break;
1777  }
1778  }
1779 
1780  if ( new_wi_index >= 0 ) {
1781  break;
1782  }
1783  }
1784 
1785  if ( new_wi_index >= 0 ) {
1786  wep[i] = new_wi_index;
1787  wi_index = new_wi_index;
1788  }
1789  }
1790 
1791  int new_wep_count = wep_count[i];
1792  if ( Weapon_info[wi_index].subtype == WP_MISSILE )
1793  {
1794  int secondary_bank_index;
1795  secondary_bank_index = i-3;
1796  if ( secondary_bank_index < 0 ) {
1797  Int3();
1798  secondary_bank_index = 0;
1799  }
1800  new_wep_count = wl_calc_missile_fit(wi_index, Ship_info[ship_class].secondary_bank_ammo_capacity[secondary_bank_index]);
1801  }
1802 
1803  wep_count[i] = MIN(new_wep_count, Wl_pool[wi_index]);
1804  Assert(wep_count[i] >= 0);
1805  Wl_pool[wi_index] -= wep_count[i];
1806  if ( wep_count[i] <= 0 ) {
1807  wep[i] = -1;
1808  }
1809  }
1810  }
1811  }
1812  }
1813 }
1814 
1820 {
1821  int i, j;
1822  int wep[MAX_SHIP_WEAPONS];
1823  int wep_count[MAX_SHIP_WEAPONS];
1824 
1825  Assert( Wss_slots != NULL );
1826 
1827  for ( i = 0; i < MAX_WSS_SLOTS; i++ ) {
1828  if ( Wss_slots[i].ship_class < 0 ){
1829  continue;
1830  }
1831 
1832  // get the weapons info that should be on ship by default
1833  wl_get_default_weapons(Wss_slots[i].ship_class, i, wep, wep_count);
1834  wl_remove_weps_from_pool(wep, wep_count, Wss_slots[i].ship_class);
1835 
1836  // copy to Wss_slots[]
1837  for ( j = 0; j < MAX_SHIP_WEAPONS; j++ ) {
1838  Wss_slots[i].wep[j] = wep[j];
1839  Wss_slots[i].wep_count[j] = wep_count[j];
1840  }
1841  }
1842 }
1843 
1848 {
1849  int i;
1850 
1851  Assert( Wl_pool != NULL );
1852 
1853  Plist_start = 0; // offset into Plist[]
1854  Slist_start = 0;
1855 
1856  Plist_size = 0; // number of active elements in Plist[]
1857  Slist_size = 0;
1858 
1859  for ( i = 0; i < MAX_WEAPON_TYPES; i++ ) {
1860  Plist[i] = -1;
1861  Slist[i] = -1;
1862  }
1863 
1864  for ( i = 0; i < MAX_WEAPON_TYPES; i++ ) {
1865  if ( Wl_pool[i] > 0 ) {
1866  if ( Weapon_info[i].subtype == WP_MISSILE ) {
1867  Slist[Slist_size++] = i;
1868  } else {
1869  Plist[Plist_size++] = i;
1870  }
1871  }
1872  }
1873 }
1874 
1879 {
1880  Assert( (team >= 0) && (team < MAX_TVT_TEAMS) );
1881 
1882  Wl_icons = Wl_icons_teams[team];
1883 }
1884 
1889 {
1891 
1892  if ( Weapon_select_open )
1893  return;
1894 
1895  Wl_icons = NULL;
1896 }
1897 
1901 void weapon_select_init_team(int team_num)
1902 {
1903  common_set_team_pointers(team_num);
1904 
1905  wl_init_pool(&Team_data[team_num]);
1908 
1910 
1911  wl_fill_slots();
1912 }
1913 
1919 {
1920  if (Weapon_select_open)
1921  return;
1922 
1923  wl_unload_icons();
1925 }
1926 
1932 {
1933  int idx;
1934 
1935  if(MULTI_TEAM){
1936  // initialize for all teams
1937  for(idx=0;idx<MULTI_TS_MAX_TVT_TEAMS;idx++){
1939  }
1940 
1941  // re-initialize for me specifically
1943  } else {
1944  // initialize for my own team
1946  }
1947 
1951 }
1952 
1961 {
1962  common_set_interface_palette("WeaponPalette");
1964 
1965  // for multiplayer, change the state in my netplayer structure
1966  if ( Game_mode & GM_MULTIPLAYER )
1968 
1969  Weapon_anim_class = -1;
1970 
1971  set_active_ui(&Weapon_ui_window);
1973  Last_wl_ship_class = -1;
1974 
1976  Assert( Wss_slots != NULL );
1977  wl_set_disabled_weapons(Wss_slots[Selected_wl_slot].ship_class);
1978 
1981 
1982  if ( Weapon_select_open ) {
1984  common_buttons_maybe_reload(&Weapon_ui_window); // AL 11-21-97: this is necessary since we may returning from the hotkey
1985  // screen, which can release common button bitmaps.
1987  nprintf(("Alan","weapon_select_init() returning without doing anything\n"));
1988 
1989  // if we're in multiplayer always select the player's ship
1991 
1992  return;
1993  }
1994 
1995  nprintf(("Alan","entering weapon_select_init()\n"));
1997 
1998 
1999  // Goober5000
2000  // first determine which layout to use
2001  Uses_apply_all_button = 1; // assume true
2002  Weapon_select_background_bitmap = mission_ui_background_load(Briefing->weapon_select_background[gr_screen.res], Weapon_select_background_fname[Uses_apply_all_button][gr_screen.res], Weapon_select_multi_background_fname[Uses_apply_all_button][gr_screen.res]);
2003  if (Weapon_select_background_bitmap < 0) // failed to load
2004  {
2005  Uses_apply_all_button = 0; // nope, sorry
2006  Weapon_select_background_bitmap = mission_ui_background_load(NULL, Weapon_select_background_fname[Uses_apply_all_button][gr_screen.res], Weapon_select_multi_background_fname[Uses_apply_all_button][gr_screen.res]);
2007  }
2008 
2009 
2010  WeaponSelectMaskBitmap = bm_load(Wl_loadout_select_mask[Uses_apply_all_button][gr_screen.res]);
2011  if (WeaponSelectMaskBitmap < 0) {
2012  if (gr_screen.res == GR_640) {
2013  Error(LOCATION,"Could not load in 'weaponloadout-m'!");
2014  } else if (gr_screen.res == GR_1024) {
2015  Error(LOCATION,"Could not load in '2_weaponloadout-m'!");
2016  } else {
2017  Error(LOCATION,"Could not load in 'weaponloadout-m'!");
2018  }
2019  }
2020 
2021  Weaponselect_mask_w = -1;
2022  Weaponselect_mask_h = -1;
2023 
2024  // get a pointer to bitmap by using bm_lock()
2025  WeaponSelectMaskPtr = bm_lock(WeaponSelectMaskBitmap, 8, BMP_AABITMAP);
2026  WeaponSelectMaskData = (ubyte*)WeaponSelectMaskPtr->data;
2027  Assert(WeaponSelectMaskData != NULL);
2028  bm_get_info(WeaponSelectMaskBitmap, &Weaponselect_mask_w, &Weaponselect_mask_h);
2029 
2030 
2031  // Set up the mask regions
2032  // initialize the different regions of the menu that will react when the mouse moves over it
2033  Num_weapon_select_regions = 0;
2034 
2035  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", COMMON_BRIEFING_REGION, 0);
2036  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", COMMON_SS_REGION, 0);
2037  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", COMMON_WEAPON_REGION, 0);
2038  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", COMMON_COMMIT_REGION, 0);
2039  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", COMMON_HELP_REGION, 0);
2040  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", COMMON_OPTIONS_REGION, 0);
2041 
2042  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", WING_0_SHIP_0, 0);
2043  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", WING_0_SHIP_1, 0);
2044  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", WING_0_SHIP_2, 0);
2045  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", WING_0_SHIP_3, 0);
2046  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", WING_1_SHIP_0, 0);
2047  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", WING_1_SHIP_1, 0);
2048  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", WING_1_SHIP_2, 0);
2049  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", WING_1_SHIP_3, 0);
2050  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", WING_2_SHIP_0, 0);
2051  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", WING_2_SHIP_1, 0);
2052  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", WING_2_SHIP_2, 0);
2053  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", WING_2_SHIP_3, 0);
2054 
2055  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", ICON_PRIMARY_0, 0);
2056  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", ICON_PRIMARY_1, 0);
2057  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", ICON_PRIMARY_2, 0);
2058  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", ICON_PRIMARY_3, 0);
2059  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", ICON_SECONDARY_0, 0);
2060  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", ICON_SECONDARY_1, 0);
2061  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", ICON_SECONDARY_2, 0);
2062  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", ICON_SECONDARY_3, 0);
2063 
2064  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", ICON_SHIP_PRIMARY_0, 0);
2065  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", ICON_SHIP_PRIMARY_1, 0);
2066  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", ICON_SHIP_PRIMARY_2, 0);
2067  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", ICON_SHIP_SECONDARY_0, 0);
2068  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", ICON_SHIP_SECONDARY_1, 0);
2069  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", ICON_SHIP_SECONDARY_2, 0);
2070  snazzy_menu_add_region(&Weapon_select_region[Num_weapon_select_regions++], "", ICON_SHIP_SECONDARY_3, 0);
2071 
2072  // init common UI
2073  Weapon_ui_window.create( 0, 0, gr_screen.max_w_unscaled, gr_screen.max_h_unscaled, 0 );
2074 
2075  if(Game_mode & GM_MULTIPLAYER){
2076  Weapon_ui_window.set_mask_bmap(Wl_mask_multi[Uses_apply_all_button][gr_screen.res]);
2077  } else {
2078  Weapon_ui_window.set_mask_bmap(Wl_mask_single[Uses_apply_all_button][gr_screen.res]);
2079  }
2080 
2081  Weapon_ui_window.tooltip_handler = wl_tooltip_handler;
2082  common_buttons_init(&Weapon_ui_window);
2084  Weapon_select_open = 1;
2085 
2086  // if we're in multiplayer always select the player's ship
2088 
2089  //Load the slot bitmap
2090  Weapon_slot_bitmap = bm_load("weapon_slot");
2091 }
2092 
2093 // ----------------------------------------------------------------
2094 // wl_dump_carried_icon()
2096 {
2097  if ( wl_icon_being_carried() ) {
2098  // Add back into the weapon pool
2099  if ( Carried_wl_icon.from_bank >= 0 ) {
2100  // return to list
2101  wl_drop(Carried_wl_icon.from_bank, -1, -1, Carried_wl_icon.weapon_class, Carried_wl_icon.from_slot);
2102  } else {
2103  if ( wl_carried_icon_moved() ) {
2105  }
2106  }
2107 
2109  }
2110 }
2111 
2121 int drop_icon_on_slot(int bank_num)
2122 {
2123  if ( Selected_wl_slot == -1 ) {
2124  return 0;
2125  }
2126 
2127  if(Game_mode & GM_MULTIPLAYER){
2128  if(multi_ts_disabled_slot(Selected_wl_slot)){
2129  return 0;
2130  }
2131  } else {
2132  if ( ss_disabled_slot( Selected_wl_slot, false ) ){
2133  return 0;
2134  }
2135  }
2136 
2137  Assert( Wss_slots != NULL );
2138 
2139  // check if slot exists
2140  if ( Wss_slots[Selected_wl_slot].wep_count[bank_num] < 0 ) {
2141  return 0;
2142  }
2143 
2144  if ( !wl_carried_icon_moved() ) {
2146  return 0;
2147  }
2148 
2149  wl_drop(Carried_wl_icon.from_bank, Carried_wl_icon.weapon_class, bank_num, -1, Selected_wl_slot);
2150  return 1;
2151 }
2152 
2153 // ----------------------------------------------------------------
2154 // maybe_drop_icon_on_slot()
2155 //
2156 void maybe_drop_icon_on_slot(int bank_num)
2157 {
2158  int dropped=0;
2159  if ( !mouse_down(MOUSE_LEFT_BUTTON) ) {
2160  if ( wl_icon_being_carried() )
2161  dropped = drop_icon_on_slot(bank_num);
2162 
2163  if ( dropped ) {
2165  }
2166  }
2167 }
2168 
2169 // ---------------------------------------------------------------------------------
2170 // do_mouse_over_list_weapon()
2171 //
2173 {
2174  Hot_weapon_icon = index;
2175 
2176  int region_index = ICON_PRIMARY_0+index;
2177  if ( index > 3 ) {
2178  region_index = ICON_SECONDARY_0 + (index - 4);
2179  }
2180 
2181  if ( Wl_mouse_down_on_region != region_index ){
2182  return;
2183  }
2184 
2186  wl_pick_icon_from_list(index);
2187 }
2188 
2197 {
2198  int dropped_on_slot, is_moved, mx, my;
2199 
2200  dropped_on_slot = 0;
2201  Assert(Selected_wl_slot >= 0);
2202  Assert(Wss_slots != NULL);
2203 
2204  if ( ss_disabled_slot( Selected_wl_slot , false) )
2205  return 0;
2206 
2207  Hot_weapon_bank_icon = index; // bank icon will be drawn highlighted
2208 
2209  if ( mouse_down(MOUSE_LEFT_BUTTON) ) {
2210  if ( Wl_mouse_down_on_region == (ICON_SHIP_PRIMARY_0+index) ){
2211  pick_from_ship_slot(index);
2212  }
2213  } else {
2214  int was_carried = wl_icon_being_carried();
2215  maybe_drop_icon_on_slot(index);
2216  if ( was_carried && !wl_icon_being_carried() ) {
2217  mouse_get_pos_unscaled( &mx, &my );
2218  if ( Carried_wl_icon.from_x != mx || Carried_wl_icon.from_y != my) {
2219  dropped_on_slot = 1;
2220  }
2221  }
2222  }
2223 
2224  // set Hot_weapon_bank if a droppable icon is being held over a slot that
2225  // can accept that icon
2226  is_moved = 0;
2227  mouse_get_pos_unscaled( &mx, &my );
2228  if ( Carried_wl_icon.from_x != mx || Carried_wl_icon.from_y != my) {
2229  is_moved = 1;
2230  }
2231 
2232  if ( wl_icon_being_carried() && is_moved ) {
2233  if ( Weapon_info[Carried_wl_icon.weapon_class].subtype != WP_MISSILE ) {
2234  if ( (index < 3) && (Wss_slots[Selected_wl_slot].wep_count[index] >= 0) )
2235  Hot_weapon_bank = index;
2236  } else {
2237  if ( index >= 3 && ( Wss_slots[Selected_wl_slot].wep_count[index] >= 0) )
2238  Hot_weapon_bank = index;
2239  }
2240  }
2241 
2242  return dropped_on_slot;
2243 }
2244 
2245 
2250 {
2251  if ( common_flash_bright() ) {
2252  // commit button
2255  } else {
2257  }
2258  }
2259 }
2260 
2261 
2262 void weapon_select_render(float frametime)
2263 {
2264  if ( !Background_playing ) {
2267  gr_bitmap(0, 0, GR_RESIZE_MENU);
2268  }
2269 }
2270 
2275 void wl_render_weapon_desc(float frametime)
2276 {
2277  int *weapon_desc_coords;
2278  int *weapon_title_coords;
2279 
2280  int line_height = gr_get_font_height() + 1;
2281 
2282  // retrieve the correct set of text coordinates
2283  if (Game_mode & GM_MULTIPLAYER) {
2284  weapon_desc_coords = Wl_new_weapon_desc_coords_multi[gr_screen.res];
2285  weapon_title_coords = Wl_new_weapon_title_coords_multi[gr_screen.res];
2286  } else {
2287  weapon_desc_coords = Wl_new_weapon_desc_coords[gr_screen.res];
2288  weapon_title_coords = Wl_new_weapon_title_coords[gr_screen.res];
2289  }
2290 
2291  // render the normal version of the weapom desc
2292  char bright_char[WEAPON_DESC_MAX_LINES]; // one bright char per line
2293  if (!Weapon_desc_wipe_done) {
2294  // draw mid-wipe version
2295  // decide which char is last (and bright)
2296  int bright_char_index = (int)(Weapon_desc_wipe_time_elapsed * WEAPON_DESC_MAX_LENGTH / WEAPON_DESC_WIPE_TIME);
2297  int i, w, h, curr_len;
2298 
2299  // draw weapon title (above weapon anim)
2300  for (i=0; i<2; i++) {
2301  curr_len = strlen(Weapon_desc_lines[i]);
2302 
2303  if (bright_char_index < curr_len) {
2304  // save bright char and plunk in some nulls to shorten string
2305  bright_char[i] = Weapon_desc_lines[i][bright_char_index];
2306  Weapon_desc_lines[i][bright_char_index] = '\0';
2307 
2308  // draw the strings
2310  gr_string(weapon_title_coords[0], weapon_title_coords[1]+(line_height*i), Weapon_desc_lines[i], GR_RESIZE_MENU);
2311 
2312  // draw the bright letters
2314  gr_get_string_size(&w, &h, Weapon_desc_lines[i], curr_len);
2315  gr_printf_menu(weapon_title_coords[0]+w, weapon_title_coords[1]+(line_height*i), "%c", bright_char[i]);
2316 
2317  // restore the bright char to the string
2318  Weapon_desc_lines[i][bright_char_index] = bright_char[i];
2319 
2320  } else {
2321  // draw the string
2323  gr_string(weapon_title_coords[0], weapon_title_coords[1]+(line_height*i), Weapon_desc_lines[i], GR_RESIZE_MENU);
2324  }
2325  }
2326 
2327  // draw weapon desc (below weapon anim)
2328  for (i=2; i<WEAPON_DESC_MAX_LINES; i++) {
2329  curr_len = strlen(Weapon_desc_lines[i]);
2330 
2331  if (bright_char_index < curr_len) {
2332  // save bright char and plunk in some nulls to shorten string
2333  bright_char[i] = Weapon_desc_lines[i][bright_char_index];
2334  Weapon_desc_lines[i][bright_char_index] = '\0';
2335 
2336  // draw the string
2338  gr_string(weapon_desc_coords[0], weapon_desc_coords[1]+(line_height*(i-2)), Weapon_desc_lines[i], GR_RESIZE_MENU);
2339 
2340  // draw the bright letters
2342  gr_get_string_size(&w, &h, Weapon_desc_lines[i], curr_len);
2343  gr_printf_menu(weapon_desc_coords[0]+w, weapon_desc_coords[1]+(line_height*(i-2)), "%c", bright_char[i]);
2344 
2345  // restore the bright char to the string
2346  Weapon_desc_lines[i][bright_char_index] = bright_char[i];
2347 
2348  } else {
2349  // draw the string
2351  gr_string(weapon_desc_coords[0], weapon_desc_coords[1]+(line_height*(i-2)), Weapon_desc_lines[i], GR_RESIZE_MENU);
2352  }
2353  }
2354 
2355  // update time
2356  Weapon_desc_wipe_time_elapsed += frametime;
2357  if (Weapon_desc_wipe_time_elapsed >= WEAPON_DESC_WIPE_TIME) {
2358  // wipe is done,set flag and stop sound
2359  Weapon_desc_wipe_done = 1;
2360  }
2361 
2362  } else {
2363 
2364  // draw full version
2365  // FIXME - change to use a for loop
2367  gr_string(weapon_title_coords[0], weapon_title_coords[1], Weapon_desc_lines[0], GR_RESIZE_MENU);
2368  gr_string(weapon_title_coords[0], weapon_title_coords[1] + line_height, Weapon_desc_lines[1], GR_RESIZE_MENU);
2369  gr_string(weapon_desc_coords[0], weapon_desc_coords[1], Weapon_desc_lines[2], GR_RESIZE_MENU);
2370  gr_string(weapon_desc_coords[0], weapon_desc_coords[1] + line_height, Weapon_desc_lines[3], GR_RESIZE_MENU);
2371  gr_string(weapon_desc_coords[0], weapon_desc_coords[1] + line_height * 2, Weapon_desc_lines[4], GR_RESIZE_MENU);
2372  gr_string(weapon_desc_coords[0], weapon_desc_coords[1] + line_height * 3, Weapon_desc_lines[5], GR_RESIZE_MENU);
2373  }
2374 }
2375 
2376 
2377 
2382 {
2383  int currchar_src = 0, currline_dest = 2, currchar_dest = 0, i;
2384  int w, h;
2385  int title_len = strlen(Weapon_info[Selected_wl_class].title);
2386 
2387  // init wipe vars
2388  Weapon_desc_wipe_time_elapsed = 0.0f;
2389  Weapon_desc_wipe_done = 0;
2390 
2391  // break title into two lines if too long
2392  strcpy_s(Weapon_desc_lines[0], Weapon_info[Selected_wl_class].title);
2393  gr_get_string_size(&w, &h, Weapon_info[Selected_wl_class].title, title_len);
2395  // split
2396  currchar_src = (int)(((float)title_len / (float)w) * Weapon_title_max_width[gr_screen.res]); // char to start space search at
2397  while (Weapon_desc_lines[0][currchar_src] != ' ') {
2398  currchar_src--;
2399  if (currchar_src <= 0) {
2400  currchar_src = title_len;
2401  break;
2402  }
2403  }
2404 
2405  Weapon_desc_lines[0][currchar_src] = '\0'; // shorten line 0
2406  strcpy_s(Weapon_desc_lines[1], &(Weapon_desc_lines[0][currchar_src+1])); // copy remainder into line 1
2407  } else {
2408  // entire title in line 0, thus line 1 is empty
2409  Weapon_desc_lines[1][0] = '\0';
2410  }
2411 
2412  // break current description into lines (break at the /n's)
2413  currchar_src = 0;
2414  if (Weapon_info[Selected_wl_class].desc != NULL) {
2415  while (Weapon_info[Selected_wl_class].desc[currchar_src] != '\0') {
2416  if (Weapon_info[Selected_wl_class].desc[currchar_src] == '\n') {
2417  // break here
2418  if (currchar_src != 0) { // protect against leading /n's
2419  Weapon_desc_lines[currline_dest][currchar_dest] = '\0';
2420  currline_dest++;
2421  currchar_dest = 0;
2422  }
2423  } else {
2424  // straight copy
2425  Weapon_desc_lines[currline_dest][currchar_dest] = Weapon_info[Selected_wl_class].desc[currchar_src];
2426  currchar_dest++;
2427  }
2428 
2429  currchar_src++;
2430 
2431  Assert(currline_dest < WEAPON_DESC_MAX_LINES);
2432  Assert(currchar_dest < WEAPON_DESC_MAX_LENGTH);
2433  }
2434  }
2435 
2436  // wrap up the line processing
2437  Weapon_desc_lines[currline_dest][currchar_dest] = '\0';
2438  for (i=currline_dest+1; i<WEAPON_DESC_MAX_LINES; i++) {
2439  Weapon_desc_lines[i][0] = '\0';
2440  }
2441 }
2442 
2443 
2444 
2449 void weapon_select_do(float frametime)
2450 {
2451  int k, wl_choice, snazzy_action;
2452 
2453  if ( !Weapon_select_open )
2455 
2456  wl_choice = snazzy_menu_do(WeaponSelectMaskData, Weaponselect_mask_w, Weaponselect_mask_h, Num_weapon_select_regions, Weapon_select_region, &snazzy_action, 0);
2457 
2458  if ( wl_choice >= 0 ) {
2459  if ( snazzy_action == SNAZZY_CLICKED ) {
2460  nprintf(("Alan","got one\n"));
2461  }
2462  }
2463 
2464  Hot_wl_slot = -1;
2465  Hot_weapon_icon = -1;
2466  Hot_weapon_bank = -1;
2467  Hot_weapon_bank_icon = -1;
2468 
2469  k = common_select_do(frametime);
2470 
2471  // Check common keypresses
2472  common_check_keys(k);
2473 
2474  if ( Mouse_down_last_frame ) {
2475  Wl_mouse_down_on_region = wl_choice;
2476  }
2477 
2478  if ( wl_choice > -1 ) {
2479  switch(wl_choice) {
2480  case ICON_PRIMARY_0:
2482  break;
2483  case ICON_PRIMARY_1:
2485  break;
2486  case ICON_PRIMARY_2:
2488  break;
2489  case ICON_PRIMARY_3:
2491  break;
2492  case ICON_SECONDARY_0:
2494  break;
2495  case ICON_SECONDARY_1:
2497  break;
2498  case ICON_SECONDARY_2:
2500  break;
2501  case ICON_SECONDARY_3:
2503  break;
2504  case ICON_SHIP_PRIMARY_0:
2505  if ( do_mouse_over_ship_weapon(0) )
2506  wl_choice = -1;
2507  break;
2508  case ICON_SHIP_PRIMARY_1:
2509  if ( do_mouse_over_ship_weapon(1) )
2510  wl_choice = -1;
2511  break;
2512  case ICON_SHIP_PRIMARY_2:
2513  if ( do_mouse_over_ship_weapon(2) )
2514  wl_choice = -1;
2515  break;
2516  case ICON_SHIP_SECONDARY_0:
2517  if ( do_mouse_over_ship_weapon(3) )
2518  wl_choice = -1;
2519  break;
2520  case ICON_SHIP_SECONDARY_1:
2521  if ( do_mouse_over_ship_weapon(4) )
2522  wl_choice = -1;
2523  break;
2524  case ICON_SHIP_SECONDARY_2:
2525  if ( do_mouse_over_ship_weapon(5) )
2526  wl_choice = -1;
2527  break;
2528  case ICON_SHIP_SECONDARY_3:
2529  if ( do_mouse_over_ship_weapon(6) )
2530  wl_choice = -1;
2531  break;
2532  case WING_0_SHIP_0:
2533  Hot_wl_slot = 0;
2534  break;
2535  case WING_0_SHIP_1:
2536  Hot_wl_slot = 1;
2537  break;
2538  case WING_0_SHIP_2:
2539  Hot_wl_slot = 2;
2540  break;
2541  case WING_0_SHIP_3:
2542  Hot_wl_slot = 3;
2543  break;
2544  case WING_1_SHIP_0:
2545  Hot_wl_slot = 4;
2546  break;
2547  case WING_1_SHIP_1:
2548  Hot_wl_slot = 5;
2549  break;
2550  case WING_1_SHIP_2:
2551  Hot_wl_slot = 6;
2552  break;
2553  case WING_1_SHIP_3:
2554  Hot_wl_slot = 7;
2555  break;
2556  case WING_2_SHIP_0:
2557  Hot_wl_slot = 8;
2558  break;
2559  case WING_2_SHIP_1:
2560  Hot_wl_slot = 9;
2561  break;
2562  case WING_2_SHIP_2:
2563  Hot_wl_slot = 10;
2564  break;
2565  case WING_2_SHIP_3:
2566  Hot_wl_slot = 11;
2567  break;
2568 
2569  default:
2570  break;
2571  } // end switch
2572  }
2573 
2574  if ( !mouse_down(MOUSE_LEFT_BUTTON) ) {
2576  }
2577 
2578  // Check for a mouse click on buttons
2581 
2582  // Check for the mouse clicks over a region
2583  if ( wl_choice > -1 && snazzy_action == SNAZZY_CLICKED ) {
2584  switch (wl_choice) {
2585  case ICON_PRIMARY_0:
2587  break;
2588  case ICON_PRIMARY_1:
2590  break;
2591  case ICON_PRIMARY_2:
2593  break;
2594  case ICON_PRIMARY_3:
2596  break;
2597  case ICON_SECONDARY_0:
2599  break;
2600  case ICON_SECONDARY_1:
2602  break;
2603  case ICON_SECONDARY_2:
2605  break;
2606  case ICON_SECONDARY_3:
2608  break;
2609  case ICON_SHIP_PRIMARY_0:
2611  break;
2612  case ICON_SHIP_PRIMARY_1:
2614  break;
2615  case ICON_SHIP_PRIMARY_2:
2617  break;
2618  case ICON_SHIP_SECONDARY_0:
2620  break;
2621  case ICON_SHIP_SECONDARY_1:
2623  break;
2624  case ICON_SHIP_SECONDARY_2:
2626  break;
2627  case ICON_SHIP_SECONDARY_3:
2629  break;
2630  case WING_0_SHIP_0:
2631  maybe_select_wl_slot(0,0);
2632  break;
2633  case WING_0_SHIP_1:
2634  maybe_select_wl_slot(0,1);
2635  break;
2636  case WING_0_SHIP_2:
2637  maybe_select_wl_slot(0,2);
2638  break;
2639  case WING_0_SHIP_3:
2640  maybe_select_wl_slot(0,3);
2641  break;
2642  case WING_1_SHIP_0:
2643  maybe_select_wl_slot(1,0);
2644  break;
2645  case WING_1_SHIP_1:
2646  maybe_select_wl_slot(1,1);
2647  break;
2648  case WING_1_SHIP_2:
2649  maybe_select_wl_slot(1,2);
2650  break;
2651  case WING_1_SHIP_3:
2652  maybe_select_wl_slot(1,3);
2653  break;
2654  case WING_2_SHIP_0:
2655  maybe_select_wl_slot(2,0);
2656  break;
2657  case WING_2_SHIP_1:
2658  maybe_select_wl_slot(2,1);
2659  break;
2660  case WING_2_SHIP_2:
2661  maybe_select_wl_slot(2,2);
2662  break;
2663  case WING_2_SHIP_3:
2664  maybe_select_wl_slot(2,3);
2665  break;
2666 
2667  default:
2668  break;
2669 
2670  } // end switch
2671  }
2672 
2673  gr_reset_clip();
2674 
2675  weapon_select_render(frametime);
2676  int *weapon_ani_coords;
2677  if (Game_mode & GM_MULTIPLAYER) {
2678  weapon_ani_coords = Wl_weapon_ani_coords_multi[gr_screen.res];
2679  } else {
2680  weapon_ani_coords = Wl_weapon_ani_coords[gr_screen.res];
2681  }
2682 
2683  if(Selected_wl_class != -1 && Wl_icons[Selected_wl_class].model_index != -1) {
2684  static float WeapSelectScreenWeapRot = 0.0f;
2685  wl_icon_info *sel_icon = &Wl_icons[Selected_wl_class];
2686  weapon_info *wip = &Weapon_info[Selected_wl_class];
2687  model_render_params render_info;
2688  draw_model_rotating(&render_info,
2689  sel_icon->model_index,
2690  weapon_ani_coords[0],
2691  weapon_ani_coords[1],
2692  gr_screen.res == 0 ? 202 : 332,
2693  gr_screen.res == 0 ? 185 : 260,
2694  &WeapSelectScreenWeapRot,
2695  &wip->closeup_pos,
2696  wip->closeup_zoom * 0.65f,
2700  wip->selection_effect);
2701  } else if ( Weapon_anim_class != -1 && ( Selected_wl_class == Weapon_anim_class )) {
2702  Assert(Selected_wl_class >= 0 && Selected_wl_class < MAX_WEAPON_TYPES );
2703  if ( Weapon_anim_class != Selected_wl_class )
2704  start_weapon_animation(Selected_wl_class);
2705 
2706  generic_anim_render(&Cur_Anim, (help_overlay_active(Weapon_select_overlay_id)) ? 0 : frametime, weapon_ani_coords[0], weapon_ani_coords[1], true);
2707  }
2708 
2709  if ( !Background_playing ) {
2710  Weapon_ui_window.draw();
2712  draw_wl_icons();
2713  wl_render_overhead_view(frametime);
2714  wl_draw_ship_weapons(Selected_wl_slot);
2715  for ( int i = 0; i < MAX_WING_BLOCKS; i++ ) {
2716  draw_wing_block(i, Hot_wl_slot, Selected_wl_slot, -1, false);
2717  }
2719  }
2720 
2721  // maybe blit the multiplayer "locked" button
2722  if((Game_mode & GM_MULTIPLAYER) && multi_ts_is_locked()){
2724  }
2725 
2726  if ( wl_icon_being_carried() ) {
2727  int mx, my, sx, sy;
2728  Assert(Carried_wl_icon.weapon_class < MAX_WEAPON_TYPES);
2729  Assert( (Wss_slots != NULL) && (Wl_icons != NULL) );
2730  mouse_get_pos_unscaled( &mx, &my );
2731  sx = mx + Wl_delta_x;
2732  sy = my + Wl_delta_y;
2733 
2734  if ( Wl_icons[Carried_wl_icon.weapon_class].can_use > 0)
2735  {
2736  wl_icon_info *icon = &Wl_icons[Carried_wl_icon.weapon_class];
2737  weapon_info *wip = &Weapon_info[Carried_wl_icon.weapon_class];
2738  if(icon->icon_bmaps[WEAPON_ICON_FRAME_SELECTED] != -1)
2739  {
2742  gr_bitmap(sx, sy, GR_RESIZE_MENU);
2743  } else {
2745  int w = 56;
2746  int h = 24;
2747  draw_brackets_square(sx, sy, sx+w, sy+h, GR_RESIZE_MENU);
2748  if(icon->model_index != -1)
2749  {
2750  //Draw the model
2751  draw_model_icon(icon->model_index, MR_NO_FOGGING | MR_NO_LIGHTING, wip->closeup_zoom / 2.5f, sx, sy, w, h, NULL, GR_RESIZE_MENU, &wip->closeup_pos);
2752  }
2753  else if(icon->laser_bmap != -1)
2754  {
2755  //Draw laser bitmap
2756  gr_set_clip(sx, sy, 56, 24, GR_RESIZE_MENU);
2757  gr_set_bitmap(icon->laser_bmap);
2758  gr_bitmap(0, 0, GR_RESIZE_MENU);
2759  gr_reset_clip();
2760  } else {
2761  //Draw the weapon name, crappy last-ditch effort to not crash.
2762  int half_x, half_y;
2763  char *print_name = (Weapon_info[Carried_wl_icon.weapon_class].alt_name[0]) ? Weapon_info[Carried_wl_icon.weapon_class].alt_name : Weapon_info[Carried_wl_icon.weapon_class].name;
2764 
2765  // Truncate the # and everything to the right. Zacam
2766  end_string_at_first_hash_symbol(print_name);
2767 
2768  // Center-align and fit the text for display
2769  gr_get_string_size(&half_x, &half_y, print_name);
2770  half_x = sx +((56 - half_x) / 2);
2771  half_y = sy +((28 - half_y) / 2); // Was ((24 - half_y) / 2) Zacam
2772  gr_string(half_x, half_y, print_name, GR_RESIZE_MENU);
2773  }
2774  }
2775  }
2776 
2777  // draw number to prevent it from disappearing on clicks
2778  if ( Carried_wl_icon.from_bank >= MAX_SHIP_PRIMARY_BANKS ) {
2779  if ( mx == Carried_wl_icon.from_x && my == Carried_wl_icon.from_y ) {
2780  int num_missiles = Wss_slots[Carried_wl_icon.from_slot].wep_count[Carried_wl_icon.from_bank];
2781 
2782  wl_render_icon_count(num_missiles, Wl_bank_coords[gr_screen.res][Carried_wl_icon.from_bank][0], Wl_bank_coords[gr_screen.res][Carried_wl_icon.from_bank][1]);
2783  }
2784  }
2785 
2786  // check so see if this is really a legal weapon to carry away
2787  if ( !Wl_icons[Carried_wl_icon.weapon_class].can_use )
2788  {
2789  int diffx, diffy;
2790  diffx = abs(Carried_wl_icon.from_x-mx);
2791  diffy = abs(Carried_wl_icon.from_y-my);
2792  if ( (diffx > 2) || (diffy > 2) ) {
2793  int ship_class = Wss_slots[Selected_wl_slot].ship_class;
2794 
2795  // might have to get weapon name translation
2796  if (Lcl_gr)
2797  {
2798  char display_name[NAME_LENGTH];
2799  strcpy_s(display_name, (Weapon_info[Carried_wl_icon.weapon_class].alt_name[0] != '\0' ) ? Weapon_info[Carried_wl_icon.weapon_class].alt_name : Weapon_info[Carried_wl_icon.weapon_class].name);
2800  lcl_translate_wep_name_gr(display_name);
2801  popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("A %s is unable to carry %s weaponry", 633), (Ship_info[ship_class].alt_name[0] != '\0') ? Ship_info[ship_class].alt_name : Ship_info[ship_class].name, display_name);
2802  }
2803  else
2804  {
2805  popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("A %s is unable to carry %s weaponry", 633), (Ship_info[ship_class].alt_name[0] != '\0') ? Ship_info[ship_class].alt_name : Ship_info[ship_class].name, Weapon_info[Carried_wl_icon.weapon_class].name);
2806  }
2807 
2809  }
2810  }
2811  }
2812 
2813  if ( Weapon_anim_class != Selected_wl_class) {
2814  start_weapon_animation(Selected_wl_class);
2815  }
2816 
2817  // render weapon description text
2818  wl_render_weapon_desc(frametime);
2819 
2821 
2822  // should render the chatbox as close to the end as possible so it overlaps all controls
2823  if(!Background_playing){
2824  // render some extra stuff in multiplayer
2825  if(Game_mode & GM_MULTIPLAYER){
2826  // render the chatbox
2827  chatbox_render();
2828 
2829  // draw tooltips
2830  Weapon_ui_window.draw_tooltip();
2831 
2832  // render the status indicator for the voice system
2834  }
2835  }
2836 
2837  // blit help overlay if active
2839  gr_flip();
2840 
2841  // If the commit button was pressed, do the commit button actions. Done at the end of the
2842  // loop so there isn't a skip in the animation (since ship_create() can take a long time if
2843  // the ship model is not in memory
2844  if ( Commit_pressed ) {
2845  if(Game_mode & GM_MULTIPLAYER){
2847  } else {
2848  commit_pressed();
2849  }
2850  Commit_pressed = 0;
2851  }
2852 }
2853 
2861 {
2862  if ( !Weapon_select_open ) {
2863  nprintf(("Alan","weapon_select_close() returning without doing anything\n"));
2864  return;
2865  }
2866 
2867  nprintf(("Alan", "Entering weapon_select_close()\n"));
2868 
2869  // done with the bitmaps, so unlock it
2870  bm_unlock(WeaponSelectMaskBitmap);
2871 
2872  Weapon_ui_window.destroy();
2873 
2874  // unload bitmaps
2875  bm_release(WeaponSelectMaskBitmap);
2876 
2877  wl_unload_icons();
2879  // ...must be last...
2881 
2882  Selected_wl_class = -1;
2883  Weapon_select_open = 0;
2884 
2885  if(Weapon_slot_bitmap != -1)
2886  {
2887  bm_release(Weapon_slot_bitmap);
2888  }
2889 }
2890 
2891 
2899 void wl_render_icon_count(int num, int x, int y)
2900 {
2901  char buf[32];
2902  int num_w, num_h;
2903  int number_to_draw = (num >= 10000) ? 9999 : num; // cap count @ 9999 - Goober5000 bumped from 999
2904  Assert(number_to_draw >= 0);
2905 
2906  sprintf(buf, "%d", number_to_draw);
2907  gr_get_string_size(&num_w, &num_h, buf, strlen(buf));
2908 
2909  // render
2911  gr_string(x-num_w-4, y+8, buf, GR_RESIZE_MENU);
2912 }
2913 
2914 
2927 void wl_render_icon(int index, int x, int y, int num, int draw_num_flag, int hot_mask, int hot_bank_mask, int select_mask)
2928 {
2929  int bitmap_id = -1;
2930  color *color_to_draw = NULL;
2931  wl_icon_info *icon;
2932 
2933  if ( Selected_wl_slot == -1 )
2934  return;
2935 
2936  icon = &Wl_icons[index];
2937 
2938  if ( icon->icon_bmaps[0] == -1 && icon->model_index == -1 && icon->laser_bmap == -1) {
2939  wl_load_icons(index);
2940  }
2941 
2942  // assume default bitmap is to be used
2943  if(icon->icon_bmaps[0] != -1)
2944  bitmap_id = icon->icon_bmaps[WEAPON_ICON_FRAME_NORMAL]; // normal frame
2945  else
2946  color_to_draw = &Icon_colors[ICON_FRAME_NORMAL];
2947 
2948  // next check if ship has mouse over it
2949  if ( !wl_icon_being_carried() ) {
2950  if ( (Hot_weapon_icon > -1 && Hot_weapon_icon == hot_mask)
2951  || (Hot_weapon_bank_icon > -1 && Hot_weapon_bank_icon == hot_bank_mask))
2952  {
2953  if(icon->icon_bmaps[0] != -1)
2954  bitmap_id = icon->icon_bmaps[WEAPON_ICON_FRAME_HOT]; // normal frame
2955  else
2956  color_to_draw = &Icon_colors[ICON_FRAME_HOT];
2957  }
2958  }
2959 
2960  // if icon is selected
2961  if ( Selected_wl_class > -1 ) {
2962  if ( Selected_wl_class == select_mask) {
2963  if(icon->icon_bmaps[0] != -1)
2964  bitmap_id = icon->icon_bmaps[WEAPON_ICON_FRAME_SELECTED]; // selected icon
2965  else
2966  color_to_draw = &Icon_colors[ICON_FRAME_SELECTED];
2967  }
2968  }
2969 
2970  // if icon is disabled
2971  if ( !icon->can_use ) {
2972  if(icon->icon_bmaps[0] != -1)
2973  bitmap_id = icon->icon_bmaps[WEAPON_ICON_FRAME_DISABLED]; // disabled icon
2974  else
2975  color_to_draw = &Icon_colors[ICON_FRAME_DISABLED];
2976  }
2977 
2978  if(bitmap_id != -1)
2979  {
2981  gr_set_bitmap(bitmap_id);
2982  gr_bitmap(x, y, GR_RESIZE_MENU);
2983  }
2984  else
2985  {
2986  gr_set_color_fast(color_to_draw);
2987  draw_brackets_square(x, y, x + 56, y + 24, GR_RESIZE_MENU);
2988 
2989  if(icon->model_index != -1)
2990  {
2991  //Draw the model
2992  draw_model_icon(icon->model_index, MR_NO_FOGGING | MR_NO_LIGHTING, Weapon_info[index].closeup_zoom * 0.4f, x, y, 56, 24, NULL, GR_RESIZE_MENU);
2993  }
2994  else if(icon->laser_bmap != -1)
2995  {
2996  gr_set_clip(x, y, 56, 24, GR_RESIZE_MENU);
2997  gr_set_bitmap(icon->laser_bmap);
2998  gr_bitmap(0, 0, GR_RESIZE_MENU);
2999  gr_reset_clip();
3000  }
3001  else
3002  {
3003  //Draw the weapon name, crappy last-ditch effort to not crash.
3004  int half_x, half_y;
3005  char *print_name = (Weapon_info[index].alt_name[0]) ? Weapon_info[index].alt_name : Weapon_info[index].name;
3006 
3007  // Truncate the # and everything to the right. Zacam
3008  end_string_at_first_hash_symbol(print_name);
3009 
3010  // Center-align and fit the text for display
3011  gr_get_string_size(&half_x, &half_y, print_name);
3012  half_x = x +((56 - half_x) / 2);
3013  half_y = y +((28 - half_y) / 2); // Was ((24 - half_y) / 2) Zacam
3014  gr_string(half_x, half_y, print_name, GR_RESIZE_MENU);
3015  }
3016  }
3017 
3018  // draw the number of the item
3019  // now, right justified
3020  if ( draw_num_flag != 0 ) {
3021  wl_render_icon_count(num, x, y);
3022  }
3023 }
3024 
3031 {
3032  int i;
3033  int *wep, *wep_count;
3034 
3035  if ( index == -1 )
3036  return;
3037 
3038  Assert(index >= 0 && index < MAX_WSS_SLOTS);
3039  Assert(Wss_slots != NULL);
3040  wep = Wss_slots[index].wep;
3041  wep_count = Wss_slots[index].wep_count;
3042 
3043  for ( i = 0; i < MAX_SHIP_WEAPONS; i++ )
3044  {
3045  if(i < Ship_info[Wss_slots[index].ship_class].num_primary_banks || (i >= MAX_SHIP_PRIMARY_BANKS && ((i - MAX_SHIP_PRIMARY_BANKS) < Ship_info[Wss_slots[index].ship_class].num_secondary_banks)))
3046  {
3047  if(Weapon_slot_bitmap != -1)
3048  {
3049  gr_set_bitmap(Weapon_slot_bitmap);
3050  gr_bitmap( Wl_bank_coords[gr_screen.res][i][0] - 2, Wl_bank_coords[gr_screen.res][i][1] - 2, GR_RESIZE_MENU);
3051  }
3052  else
3053  {
3055  draw_brackets_square( Wl_bank_coords[gr_screen.res][i][0], Wl_bank_coords[gr_screen.res][i][1], Wl_bank_coords[gr_screen.res][i][0] + 56, Wl_bank_coords[gr_screen.res][i][1] + 24, GR_RESIZE_MENU);
3056  }
3057  }
3058 
3059  if ( Carried_wl_icon.from_bank == i && Carried_wl_icon.from_slot == index ) {
3060  continue;
3061  }
3062 
3063  if ( (wep[i] != -1) && (wep_count[i] > 0) )
3064  {
3065  wl_render_icon( wep[i], Wl_bank_coords[gr_screen.res][i][0], Wl_bank_coords[gr_screen.res][i][1], wep_count[i], Wl_bank_count_draw_flags[i], -1, i, wep[i]);
3066  }
3067  }
3068 }
3069 
3076 void draw_wl_icon_with_number(int list_count, int weapon_class)
3077 {
3078  Assert( list_count >= 0 && list_count < 8 );
3079  Assert( (Wl_icons != NULL) && (Wl_pool != NULL) );
3080 
3081 
3082  if(Wl_icons[weapon_class].can_use)
3083  {
3085  }
3086  else
3087  {
3089  }
3090 
3091  wl_render_icon(weapon_class, Wl_weapon_icon_coords[gr_screen.res][list_count][0], Wl_weapon_icon_coords[gr_screen.res][list_count][1],
3092  Wl_pool[weapon_class], 1, list_count, -1, weapon_class);
3093 }
3094 
3099 {
3100  int i, count;
3101 
3102  count=0;
3103  for ( i = Plist_start; i < Plist_size; i++ ) {
3104  draw_wl_icon_with_number(count, Plist[i]);
3105  if ( ++count > 3 )
3106  break;
3107  }
3108 
3109  count=0;
3110  for ( i = Slist_start; i < Slist_size; i++ ) {
3111  draw_wl_icon_with_number(count+4, Slist[i]);
3112  if ( ++count > 3 )
3113  break;
3114  }
3115 }
3116 
3127 {
3128  int weapon_class, mx, my;
3129 
3130  // if this is a multiplayer game and the player is an observer, he can never pick any weapons up
3132  return;
3133  }
3134 
3135  // if a weapon is being carried, do nothing
3136  if ( wl_icon_being_carried() ) {
3137  return;
3138  }
3139 
3140  if ( index < 4 ) {
3141  weapon_class = Plist[Plist_start+index];
3142  } else {
3143  weapon_class = Slist[Slist_start+index-4];
3144  }
3145 
3146  // there isn't a weapon there at all!
3147  if ( weapon_class < 0 )
3148  return;
3149 
3150  Assert( Wl_pool != NULL );
3151 
3152  // no weapons left of that class
3153  if ( Wl_pool[weapon_class] <= 0 ) {
3154  return;
3155  }
3156 
3157  wl_set_carried_icon(-1, -1, weapon_class);
3159 
3160  mouse_get_pos_unscaled( &mx, &my );
3161  Wl_delta_x = Wl_weapon_icon_coords[gr_screen.res][index][0] - mx;
3162  Wl_delta_y = Wl_weapon_icon_coords[gr_screen.res][index][1] - my;
3163 }
3164 
3171 {
3172  int mx, my, *wep, *wep_count;
3173 
3174  Assert(num < 7);
3175 
3176  if ( Selected_wl_slot == -1 )
3177  return;
3178 
3179  if ( wl_icon_being_carried() )
3180  return;
3181 
3182  if ( ss_disabled_slot( Selected_wl_slot, false ) )
3183  return;
3184 
3185  Assert( (Wss_slots != NULL) && (Wl_icons != NULL) );
3186 
3187  wep = Wss_slots[Selected_wl_slot].wep;
3188  wep_count = Wss_slots[Selected_wl_slot].wep_count;
3189 
3190  // check if a weapon even exists in that slot
3191  if ( (wep[num] < 0) || (wep_count[num] <= 0) ) {
3192  return;
3193  }
3194 
3195  Assert(Wl_icons[wep[num]].can_use);
3196 
3197  wl_set_carried_icon(num, Selected_wl_slot, wep[num]);
3199 
3200  mouse_get_pos_unscaled( &mx, &my );
3201 
3202  Wl_delta_x = Wl_bank_coords[gr_screen.res][num][0] - mx;
3203  Wl_delta_y = Wl_bank_coords[gr_screen.res][num][1] - my;
3204 
3205  Carried_wl_icon.from_x = mx;
3206  Carried_wl_icon.from_y = my;
3207 }
3208 
3213 {
3214  int i;
3215 
3216  for ( i = 0; i < MAX_SHIP_WEAPONS; i++ ) {
3217  if ( (slot->wep_count[i] > 0) && (slot->wep[i] >= 0) )
3218  return 0;
3219  }
3220 
3221  return 1;
3222 }
3223 
3231 int wl_update_ship_weapons(int objnum, wss_unit *slot )
3232 {
3234  if(sip->num_secondary_banks <= 0 && sip->num_primary_banks <= 0)
3235  {
3236  return 0;
3237  }
3238  // AL 11-15-97: Ensure that the player ship hasn't removed all
3239  // weapons from their ship. This will cause a warning to appear.
3240  if ( objnum == OBJ_INDEX(Player_obj) && Weapon_select_open ) {
3241  if ( wl_slots_all_empty(slot) && (sip->num_primary_banks > 0 || sip->num_secondary_banks > 0)) {
3242  return -1;
3243  }
3244  }
3245 
3246  wl_bash_ship_weapons(&Ships[Objects[objnum].instance].weapons, slot);
3247  return 0;
3248 }
3249 
3250 
3259 {
3260  int i, j, sidx, pilot_index, max_count;
3261  subsys_status *ss;
3262 
3263  Assert(slot->ship_class >= 0);
3264 
3265  pilot_index = wl_get_pilot_subsys_index(pobjp);
3266 
3267  if ( pilot_index == -1 )
3268  return;
3269 
3270  ss = &Subsys_status[pilot_index];
3271 
3272  for ( i = 0; i < MAX_SHIP_PRIMARY_BANKS; i++ ) {
3273  ss->primary_banks[i] = -1;
3274  }
3275 
3276  for ( i = 0; i < MAX_SHIP_SECONDARY_BANKS; i++ ) {
3277  ss->secondary_banks[i] = -1;
3278  }
3279 
3280  j = 0;
3281  for ( i = 0; i < MAX_SHIP_PRIMARY_BANKS; i++ )
3282  {
3283  if ( (slot->wep_count[i] > 0) && (slot->wep[i] >= 0) )
3284  {
3285  ss->primary_banks[j] = slot->wep[i];
3286 
3287  // ballistic primaries - Goober5000
3288  if (Weapon_info[slot->wep[i]].wi_flags2 & WIF2_BALLISTIC)
3289  {
3290  // Important: the primary_ammo[] value is a percentage of max capacity!
3291  // which means that it's always 100%, since ballistic primaries are completely
3292  // full upon launch - Goober5000
3293  ss->primary_ammo[j] = 100;
3294  }
3295  else
3296  {
3297  ss->primary_ammo[j] = 0;
3298  }
3299 
3300  j++;
3301  }
3302  }
3303 
3304  j = 0;
3305  for ( i = 0; i < MAX_SHIP_SECONDARY_BANKS; i++ )
3306  {
3307  sidx = i+MAX_SHIP_PRIMARY_BANKS;
3308  if ( (slot->wep_count[sidx] > 0) && (slot->wep[sidx] >= 0) )
3309  {
3310  ss->secondary_banks[j] = slot->wep[sidx];
3311 
3312  // Important: the secondary_ammo[] value is a percentage of max capacity!
3313  max_count = wl_calc_missile_fit(slot->wep[sidx], Ship_info[slot->ship_class].secondary_bank_ammo_capacity[j]);
3314  ss->secondary_ammo[j] = fl2i( i2fl(slot->wep_count[sidx]) / max_count * 100.0f + 0.5f);
3315 
3316  j++;
3317  }
3318  }
3319 }
3320 
3324 void start_weapon_animation(int weapon_class)
3325 {
3326  char *p;
3327  char animation_filename[CF_MAX_FILENAME_LENGTH+4];
3328 
3330 
3331  if ( weapon_class < 0 )
3332  return;
3333 
3334  if ( weapon_class == Weapon_anim_class )
3335  return;
3336 
3338 
3339  //load a new animation if it's different to what's already playing
3340  if(strcmp(Cur_Anim.filename, Weapon_info[weapon_class].anim_filename) != 0) {
3341  //unload the previous anim
3342  generic_anim_unload(&Cur_Anim);
3343  //load animation here, we now only have one loaded
3344  p = strchr( Weapon_info[weapon_class].anim_filename, '.' );
3345  if(p)
3346  *p = '\0';
3347  if (gr_screen.res == GR_1024) {
3348  strcpy_s(animation_filename, "2_");
3349  strcat_s(animation_filename, Weapon_info[weapon_class].anim_filename);
3350  }
3351  else {
3352  strcpy_s(animation_filename, Weapon_info[weapon_class].anim_filename);
3353  }
3354 
3355  generic_anim_init(&Cur_Anim, animation_filename);
3356  Cur_Anim.ani.bg_type = bm_get_type(Weapon_select_background_bitmap);
3357  if(generic_anim_stream(&Cur_Anim) == -1) {
3358  //we've failed to load an animation, load an image and treat it like a 1 frame animation
3359  Cur_Anim.first_frame = bm_load(Weapon_info[weapon_class].anim_filename); //if we fail here, the value is still -1
3360  if(Cur_Anim.first_frame != -1) {
3361  Cur_Anim.num_frames = 1;
3362  }
3363  }
3364  }
3365 
3366  // start the text wipe
3368 
3369  Weapon_anim_class = weapon_class;
3370 
3371  if ( Wl_icons[weapon_class].model_index >= 0 )
3372  return;
3373 }
3374 
3379 {
3380  // don't reset of weapons pool in multiplayer
3381  if(Game_mode & GM_MULTIPLAYER){
3382  return;
3383  }
3384 
3387  wl_fill_slots();
3391 }
3392 
3398 {
3399  int i, j, sidx;
3400 
3401  j = 0;
3402  for (i = 0; i < MAX_SHIP_PRIMARY_BANKS; i++) {
3403  // set to default value first thing
3404  swp->primary_bank_weapons[i] = -1;
3405 
3406  // now set to true value
3407  if ( (slot->wep_count[i] > 0) && (slot->wep[i] >= 0) ) {
3408  swp->primary_bank_weapons[j] = slot->wep[i];
3409 
3410  // ballistic primaries - Goober5000
3412  // this is a bit tricky: we must recalculate ammo for full capacity
3413  // since wep_count for primaries does not store the ammo; ballistic
3414  // primaries always come with a full magazine
3415  swp->primary_bank_ammo[j] = wl_calc_ballistic_fit(swp->primary_bank_weapons[j], Ship_info[slot->ship_class].primary_bank_ammo_capacity[i]);
3416  } else {
3417  swp->primary_bank_ammo[j] = 0;
3418  }
3419 
3420  j++;
3421  }
3422  }
3423 
3424  // update our # of primary banks
3425  swp->num_primary_banks = j;
3426 
3427  j = 0;
3428  for (i = 0; i < MAX_SHIP_SECONDARY_BANKS; i++) {
3429  // set to default value first thing
3430  swp->secondary_bank_weapons[i] = -1;
3431 
3432  // now set the true value
3433  sidx = i+MAX_SHIP_PRIMARY_BANKS;
3434  if ( (slot->wep_count[sidx] > 0) && (slot->wep[sidx] >= 0) ) {
3435  swp->secondary_bank_weapons[j] = slot->wep[sidx];
3436  swp->secondary_bank_ammo[j] = slot->wep_count[sidx];
3437  j++;
3438  }
3439  }
3440 
3441  // update our # of secondary banks
3442  swp->num_secondary_banks = j;
3443 }
3444 
3448 void wl_swap_weapons(int ship_slot, int from_bank, int to_bank)
3449 {
3450  wss_unit *slot;
3451  int tmp;
3452 
3453  Assert( Wss_slots != NULL );
3454 
3455  slot = &Wss_slots[ship_slot];
3456 
3457  if ( from_bank == to_bank || (from_bank >= MAX_SHIP_WEAPONS || from_bank < 0 ) || (to_bank >= MAX_SHIP_WEAPONS || to_bank < 0 ) ) {
3458  return;
3459  }
3460 
3461  // swap weapon type
3462  tmp = slot->wep[from_bank];
3463  slot->wep[from_bank] = slot->wep[to_bank];
3464  slot->wep[to_bank] = tmp;
3465 
3466  // swap weapon count
3467  tmp = slot->wep_count[from_bank];
3468  slot->wep_count[from_bank] = slot->wep_count[to_bank];
3469  slot->wep_count[to_bank] = tmp;
3470 }
3471 
3475 void wl_saturate_bank(int ship_slot, int bank)
3476 {
3477  wss_unit *slot;
3478  int max_count, overflow;
3479 
3480  Assert( Wss_slots != NULL );
3481 
3482  slot = &Wss_slots[ship_slot];
3483 
3484  if ( (slot->wep[bank] < 0) || (slot->wep_count[bank] <= 0) ) {
3485  return;
3486  }
3487 
3488  max_count = wl_calc_missile_fit(slot->wep[bank], Ship_info[slot->ship_class].secondary_bank_ammo_capacity[bank-3]);
3489  overflow = slot->wep_count[bank] - max_count;
3490  if ( overflow > 0 ) {
3491  Assert( Wl_pool != NULL );
3492 
3493  slot->wep_count[bank] -= overflow;
3494  // add overflow back to pool
3495  Wl_pool[slot->wep[bank]] += overflow;
3496  }
3497 }
3498 
3499 // exit: 0 -> no data changed
3500 // 1 -> data changed
3501 // sound => gets filled with sound id to play
3502 // updated for specific bank by Goober5000
3503 int wl_swap_slot_slot(int from_bank, int to_bank, int ship_slot, int *sound, net_player *pl)
3504 {
3505  wss_unit *slot;
3506  int class_mismatch_flag, forced_update;
3507 
3508  Assert( Wss_slots != NULL );
3509 
3510  slot = &Wss_slots[ship_slot];
3511 
3512  // usually zero, unless we have a strange update thingy
3513  forced_update = 0;
3514 
3515  if ( slot->ship_class == -1 ) {
3516  Int3(); // should not be possible
3517  return forced_update;
3518  }
3519 
3520  // do nothing if swapping with self
3521  if ( from_bank == to_bank ) {
3522  *sound=SND_ICON_DROP_ON_WING;
3523  return forced_update; // no update
3524  }
3525 
3526  // ensure that source bank exists and has something to pick from
3527  if ( slot->wep[from_bank] == -1 || slot->wep_count[from_bank] <= 0 ) {
3528  return forced_update;
3529  }
3530 
3531  // ensure that the dest bank exists
3532  if ( slot->wep_count[to_bank] < 0 ) {
3533  return forced_update;
3534  }
3535 
3536  Assert( Wl_pool != NULL );
3537 
3538  // ensure banks are compatible as far as primary and secondary
3539  class_mismatch_flag = (IS_BANK_PRIMARY(from_bank) && IS_BANK_SECONDARY(to_bank)) || (IS_BANK_SECONDARY(from_bank) && IS_BANK_PRIMARY(to_bank));
3540 
3541  // further ensure that restrictions aren't breached
3542  if (!class_mismatch_flag) {
3543  ship_info *sip = &Ship_info[slot->ship_class];
3544 
3545  // check the to-bank first
3547  if (!eval_weapon_flag_for_game_type(sip->allowed_bank_restricted_weapons[to_bank][slot->wep[from_bank]])) {
3548  char display_name[NAME_LENGTH];
3549  char txt[39 + NAME_LENGTH];
3550 
3551  strcpy_s(display_name, (Weapon_info[slot->wep[from_bank]].alt_name[0]) ? Weapon_info[slot->wep[from_bank]].alt_name : Weapon_info[slot->wep[from_bank]].name);
3552 
3553  // might have to get weapon name translation
3554  if (Lcl_gr) {
3555  lcl_translate_wep_name_gr(display_name);
3556  }
3557 
3558  sprintf(txt, XSTR("This bank is unable to carry %s weaponry", 1628), display_name);
3559 
3560  if ( !(Game_mode & GM_MULTIPLAYER) || (Netgame.host == pl) ) {
3562  } else if (pl != NULL) {
3563  send_game_chat_packet(Netgame.host, txt, MULTI_MSG_TARGET, pl, NULL, 1);
3564  }
3565 
3566  return forced_update;
3567  }
3568  }
3569 
3570  // check the from-bank
3572  if (!eval_weapon_flag_for_game_type(sip->allowed_bank_restricted_weapons[from_bank][slot->wep[to_bank]])) {
3573  // going from "from" to "to" is valid (from previous if), but going the other way isn't...
3574  // so return the "to" to the list and just move the "from"
3575 
3576  // put to_bank back into list
3577  Wl_pool[slot->wep[to_bank]] += slot->wep_count[to_bank]; // return to list
3578  slot->wep[to_bank] = -1; // remove from slot
3579  slot->wep_count[to_bank] = 0;
3580  *sound=SND_ICON_DROP; // unless it changes later
3581  forced_update = 1; // because we can't return right away
3582  }
3583  }
3584  }
3585 
3586  if ( class_mismatch_flag ) {
3587  // put from_bank back into list
3588  Wl_pool[slot->wep[from_bank]] += slot->wep_count[from_bank]; // return to list
3589  slot->wep[from_bank] = -1; // remove from slot
3590  slot->wep_count[from_bank] = 0;
3591  *sound=SND_ICON_DROP;
3592  return 1;
3593  }
3594 
3595  // case 1: primaries (easy, even with ballistics, because ammo is always maximized)
3596  if ( IS_BANK_PRIMARY(from_bank) && IS_BANK_PRIMARY(to_bank) ) {
3597  wl_swap_weapons(ship_slot, from_bank, to_bank);
3598  *sound=SND_ICON_DROP_ON_WING;
3599  return 1;
3600  }
3601 
3602  // case 2: secondaries (harder)
3603  if ( IS_BANK_SECONDARY(from_bank) && IS_BANK_SECONDARY(to_bank) ) {
3604  // case 2a: secondaries are the same type
3605  if ( slot->wep[from_bank] == slot->wep[to_bank] ) {
3606  int dest_max, dest_can_fit, source_can_give;
3607  dest_max = wl_calc_missile_fit(slot->wep[to_bank], Ship_info[slot->ship_class].secondary_bank_ammo_capacity[to_bank-3]);
3608 
3609  dest_can_fit = dest_max - slot->wep_count[to_bank];
3610 
3611  if ( dest_can_fit <= 0 ) {
3612  // dest bank is already full.. nothing to do here
3613  return forced_update;
3614  }
3615 
3616  // see how much source can give
3617  source_can_give = MIN(dest_can_fit, slot->wep_count[from_bank]);
3618 
3619  if ( source_can_give > 0 ) {
3620  slot->wep_count[to_bank] += source_can_give; // add to dest
3621  slot->wep_count[from_bank] -= source_can_give; // take from source
3622  *sound=SND_ICON_DROP_ON_WING;
3623  return 1;
3624  } else {
3625  return forced_update;
3626  }
3627  }
3628 
3629  // case 2b: secondaries are different types
3630  if ( slot->wep[from_bank] != slot->wep[to_bank] ) {
3631  // swap 'em
3632  wl_swap_weapons(ship_slot, from_bank, to_bank);
3633 
3634  // put back some on list if required
3635  wl_saturate_bank(ship_slot, from_bank);
3636  wl_saturate_bank(ship_slot, to_bank);
3637  *sound=SND_ICON_DROP_ON_WING;
3638  return 1;
3639  }
3640  }
3641 
3642  Int3(); // should never get here
3643  return forced_update;
3644 }
3645 
3646 // exit: 0 -> no data changed
3647 // 1 -> data changed
3648 // sound => gets filled with sound id to play
3649 int wl_dump_to_list(int from_bank, int to_list, int ship_slot, int *sound)
3650 {
3651  wss_unit *slot;
3652 
3653  Assert( (Wss_slots != NULL) && (Wl_pool != NULL) );
3654 
3655  slot = &Wss_slots[ship_slot];
3656 
3657  // ensure that source bank exists and has something to pick from
3658  if ( slot->wep[from_bank] == -1 || slot->wep_count[from_bank] <= 0 ) {
3659  return 0;
3660  }
3661 
3662  // put weapon bank to the list
3663  Wl_pool[to_list] += slot->wep_count[from_bank]; // return to list
3664  slot->wep[from_bank] = -1; // remove from slot
3665  slot->wep_count[from_bank] = 0;
3666  *sound=SND_ICON_DROP;
3667 
3668  return 1;
3669 }
3670 
3671 // exit: 0 -> no data changed
3672 // 1 -> data changed
3673 // sound => gets filled with sound id to play
3674 int wl_grab_from_list(int from_list, int to_bank, int ship_slot, int *sound, net_player *pl)
3675 {
3676  int update=0;
3677  wss_unit *slot;
3678 
3679  Assert( (Wss_slots != NULL) && (Wl_pool != NULL) );
3680 
3681  slot = &Wss_slots[ship_slot];
3682  int max_fit;
3683 
3684  // ensure that the banks are both of the same class
3685  if ( (IS_LIST_PRIMARY(from_list) && IS_BANK_SECONDARY(to_bank)) || (IS_LIST_SECONDARY(from_list) && IS_BANK_PRIMARY(to_bank)) )
3686  {
3687  // do nothing
3688  *sound=SND_ICON_DROP;
3689  return 0;
3690  }
3691 
3692  // ensure that dest bank exists
3693  if ( slot->wep_count[to_bank] < 0 ) {
3694  *sound=SND_ICON_DROP;
3695  return 0;
3696  }
3697 
3698  // bank should be empty:
3699  Assert(slot->wep_count[to_bank] == 0);
3700  Assert(slot->wep[to_bank] < 0);
3701 
3702  // ensure that pool has weapon
3703  if ( Wl_pool[from_list] <= 0 ) {
3704  return 0;
3705  }
3706 
3707  ship_info *sip = &Ship_info[slot->ship_class];
3708 
3709  // ensure that this bank will accept the weapon...
3711  if (!eval_weapon_flag_for_game_type(sip->allowed_bank_restricted_weapons[to_bank][from_list])) {
3712  char display_name[NAME_LENGTH];
3713  char txt[39 + NAME_LENGTH];
3714 
3715  strcpy_s(display_name, Weapon_info[from_list].name);
3716 
3717  // might have to get weapon name translation
3718  if (Lcl_gr) {
3719  lcl_translate_wep_name_gr(display_name);
3720  }
3721 
3722  sprintf(txt, XSTR("This bank is unable to carry %s weaponry", 1628), display_name);
3723 
3724  if ( !(Game_mode & GM_MULTIPLAYER) || (Netgame.host == pl) ) {
3726  } else if (pl != NULL) {
3727  send_game_chat_packet(Netgame.host, txt, MULTI_MSG_TARGET, pl, NULL, 1);
3728  }
3729 
3730  return 0;
3731  }
3732  }
3733 
3734  // we will have some sort of success from this point
3735  update = 1;
3736 
3737  // find how much dest bank can fit
3738  if ( to_bank < MAX_SHIP_PRIMARY_BANKS ) {
3739  max_fit = 1;
3740  } else {
3741  max_fit = wl_calc_missile_fit(from_list, Ship_info[slot->ship_class].secondary_bank_ammo_capacity[to_bank-MAX_SHIP_PRIMARY_BANKS]);
3742  }
3743 
3744  // take weapon from list
3745  if ( Wl_pool[from_list] < max_fit ) {
3746  max_fit = Wl_pool[from_list];
3747  update=2;
3748  }
3749  Wl_pool[from_list] -= max_fit;
3750 
3751  // put on the slot
3752  slot->wep[to_bank] = from_list;
3753  slot->wep_count[to_bank] = max_fit;
3754 
3755  *sound=SND_ICON_DROP_ON_WING;
3756 
3757  return update;
3758 }
3759 
3760 // exit: 0 -> no data changed
3761 // 1 -> data changed
3762 // sound => gets filled with sound id to play
3763 int wl_swap_list_slot(int from_list, int to_bank, int ship_slot, int *sound, net_player *pl)
3764 {
3765  wss_unit *slot;
3766 
3767  Assert( (Wss_slots != NULL) && (Wl_pool != NULL) );
3768 
3769  slot = &Wss_slots[ship_slot];
3770  int max_fit;
3771 
3772  // ensure that the banks are both of the same class
3773  if ( (IS_LIST_PRIMARY(from_list) && IS_BANK_SECONDARY(to_bank)) || (IS_LIST_SECONDARY(from_list) && IS_BANK_PRIMARY(to_bank)) ) {
3774  // do nothing
3775  *sound=SND_ICON_DROP;
3776  return 0;
3777  }
3778 
3779  // ensure that dest bank exists
3780  if ( slot->wep_count[to_bank] < 0 ) {
3781  return 0;
3782  }
3783 
3784  // bank should have something in it
3785  Assert(slot->wep_count[to_bank] > 0);
3786  Assert(slot->wep[to_bank] >= 0);
3787 
3788  // ensure that pool has weapon
3789  if ( Wl_pool[from_list] <= 0 ) {
3790  return 0;
3791  }
3792 
3793  ship_info *sip = &Ship_info[slot->ship_class];
3794 
3795  // ensure that this bank will accept the weapon
3797  if (!eval_weapon_flag_for_game_type(sip->allowed_bank_restricted_weapons[to_bank][from_list])) {
3798  char display_name[NAME_LENGTH];
3799  char txt[39 + NAME_LENGTH];
3800 
3801  strcpy_s(display_name, (Weapon_info[from_list].alt_name[0]) ? Weapon_info[from_list].alt_name : Weapon_info[from_list].name);
3802 
3803  // might have to get weapon name translation
3804  if (Lcl_gr) {
3805  lcl_translate_wep_name_gr(display_name);
3806  }
3807 
3808  sprintf(txt, XSTR("This bank is unable to carry %s weaponry", 1628), display_name);
3809 
3810  if ( !(Game_mode & GM_MULTIPLAYER) || (Netgame.host == pl) ) {
3812  } else if (pl != NULL) {
3813  send_game_chat_packet(Netgame.host, txt, MULTI_MSG_TARGET, pl, NULL, 1);
3814  }
3815 
3816  return 0;
3817  }
3818  }
3819 
3820  // dump slot weapon back into list
3821  Wl_pool[slot->wep[to_bank]] += slot->wep_count[to_bank];
3822  slot->wep_count[to_bank] = 0;
3823  slot->wep[to_bank] = -1;
3824 
3825  // put weapon on ship from list
3826 
3827  // find how much dest bank can fit
3828  if ( to_bank < MAX_SHIP_PRIMARY_BANKS ) {
3829  max_fit = 1;
3830  } else {
3831  max_fit = wl_calc_missile_fit(from_list, Ship_info[slot->ship_class].secondary_bank_ammo_capacity[to_bank-MAX_SHIP_PRIMARY_BANKS]);
3832  }
3833 
3834  // take weapon from list
3835  if ( Wl_pool[from_list] < max_fit ) {
3836  max_fit = Wl_pool[from_list];
3837  }
3838  Wl_pool[from_list] -= max_fit;
3839 
3840  // put on the slot
3841  slot->wep[to_bank] = from_list;
3842  slot->wep_count[to_bank] = max_fit;
3843 
3844  *sound=SND_ICON_DROP_ON_WING;
3845  return 1;
3846 }
3847 
3853 {
3854 }
3855 
3856 int wl_apply(int mode,int from_bank,int from_list,int to_bank,int to_list,int ship_slot,int player_index, bool dont_play_sound)
3857 {
3858  int update=0;
3859  int sound=-1;
3860  net_player *pl;
3861 
3862  // get the appropriate net player
3863  if(Game_mode & GM_MULTIPLAYER){
3864  if(player_index == -1){
3865  pl = Net_player;
3866  } else {
3867  pl = &Net_players[player_index];
3868  }
3869  } else {
3870  pl = NULL;
3871  }
3872 
3873  switch(mode){
3874  case WSS_SWAP_SLOT_SLOT:
3875  update = wl_swap_slot_slot(from_bank, to_bank, ship_slot, &sound, pl);
3876  break;
3877  case WSS_DUMP_TO_LIST:
3878  update = wl_dump_to_list(from_bank, to_list, ship_slot, &sound);
3879  break;
3880  case WSS_GRAB_FROM_LIST:
3881  update = wl_grab_from_list(from_list, to_bank, ship_slot, &sound, pl);
3882  break;
3883  case WSS_SWAP_LIST_SLOT:
3884  update = wl_swap_list_slot(from_list, to_bank, ship_slot, &sound, pl);
3885  break;
3886  }
3887 
3888  // only play this sound if the move was done locally (by the host in other words)
3889  if ( (sound >= 0) && (player_index == -1) && !dont_play_sound) {
3890  gamesnd_play_iface(sound);
3891  }
3892 
3893  if ( update ) {
3894  if ( MULTIPLAYER_HOST ) {
3895  int size;
3896  ubyte wss_data[MAX_PACKET_SIZE-20];
3897 
3898  size = store_wss_data(wss_data, MAX_PACKET_SIZE-20,sound,player_index);
3899  Assert(pl != NULL);
3900  send_wss_update_packet(pl->p_info.team,wss_data, size);
3901  }
3902 
3903  if(Game_mode & GM_MULTIPLAYER){
3904  Assert(pl != NULL);
3905 
3906  // if the pool we're using has changed, synch stuff up
3907  if(pl->p_info.team == Net_player->p_info.team){
3908  wl_synch_interface();
3909  }
3910  } else {
3912  }
3913  }
3914 
3915  return update;
3916 }
3917 
3918 int wl_drop(int from_bank,int from_list,int to_bank,int to_list, int ship_slot, int player_index, bool dont_play_sound)
3919 {
3920  int mode;
3921  int update=0;
3922  net_player *pl;
3923 
3924  // get the appropriate net player
3925  if(Game_mode & GM_MULTIPLAYER){
3926  if(player_index == -1){
3927  pl = Net_player;
3928  } else {
3929  pl = &Net_players[player_index];
3930  }
3931  } else {
3932  pl = NULL;
3933  }
3934 
3936  if ( !(Game_mode & GM_MULTIPLAYER) || MULTIPLAYER_HOST ) {
3937  if(MULTI_TEAM){
3938  Assert(pl != NULL);
3939  // set the global pointers to the right pools
3941  }
3942 
3943  mode = wss_get_mode(from_bank, from_list, to_bank, to_list, ship_slot);
3944  if ( mode >= 0 ) {
3945  update = wl_apply(mode, from_bank, from_list, to_bank, to_list, ship_slot, player_index, dont_play_sound);
3946  }
3947 
3948  if(MULTI_TEAM){
3949  // set the global pointers to the right pools
3951  }
3952  } else {
3953  send_wss_request_packet(Net_player->player_id, from_bank, from_list, to_bank, to_list, ship_slot, -1, WSS_WEAPON_SELECT);
3954  }
3955 
3956  return update;
3957 }
3958 
3959 // Goober5000
3961 {
3962  int source_wss_slot, cur_wss_slot;
3963  int cur_wing_block, cur_wing_slot, cur_bank;
3964  int weapon_type_to_add, result;
3965  size_t i;
3966 
3967  ship_info *sip, *source_sip;
3968  weapon_info *wip;
3969 
3970  char ship_name[NAME_LENGTH];
3971  char *wep_display_name;
3972  char buf[NAME_LENGTH];
3973 
3974  // error stuff
3975  bool error_flag = false;
3976  SCP_vector<SCP_string> error_messages;
3977 
3978  // make sure we're not holding anything
3980 
3981  // find the currently selected ship (or the squadron leader if none)
3982  source_wss_slot = Selected_wl_slot;
3983  if (source_wss_slot == -1)
3984  source_wss_slot = 0;
3985 
3986  // get its class
3987  source_sip = &Ship_info[Wss_slots[source_wss_slot].ship_class];
3988 
3989  // find which wing this ship is part of
3990  cur_wing_block = source_wss_slot / MAX_WING_SLOTS;
3991 
3992  // for all ships in the wing
3993  for (cur_wing_slot = 0; cur_wing_slot < MAX_WING_SLOTS; cur_wing_slot++)
3994  {
3995  Assert( Wss_slots != NULL );
3996 
3997  // get the slot for this ship
3998  cur_wss_slot = cur_wing_block * MAX_WING_SLOTS + cur_wing_slot;
3999 
4000  // get the ship's name and class
4001  sip = &Ship_info[Wss_slots[cur_wss_slot].ship_class];
4002  ss_return_name(cur_wing_block, cur_wing_slot, ship_name);
4003 
4004  // don't process the selected ship
4005  if (cur_wss_slot == source_wss_slot)
4006  continue;
4007 
4008  // must be valid for us to change
4009  if (!ss_valid_slot(cur_wss_slot))
4010  continue;
4011 
4012  // copy weapons from source slot to this slot
4013  for (cur_bank = 0; cur_bank < MAX_SHIP_WEAPONS; cur_bank++)
4014  {
4015  // this bank must exist on both the source ship and the destination ship
4016  if (cur_bank < MAX_SHIP_PRIMARY_BANKS)
4017  {
4018  if (cur_bank >= source_sip->num_primary_banks || cur_bank >= sip->num_primary_banks)
4019  continue;
4020  }
4021  else
4022  {
4023  if (cur_bank-MAX_SHIP_PRIMARY_BANKS >= source_sip->num_secondary_banks || cur_bank-MAX_SHIP_PRIMARY_BANKS >= sip->num_secondary_banks)
4024  continue;
4025  }
4026 
4027  // dump the destination ship's weapons
4028  wl_drop(cur_bank, -1, -1, Wss_slots[cur_wss_slot].wep[cur_bank], cur_wss_slot, -1, true);
4029 
4030  // weapons must be present on the source ship
4031  if (Wss_slots[source_wss_slot].wep[cur_bank] < 0)
4032  continue;
4033 
4034  // determine the weapon we need
4035  weapon_type_to_add = Wss_slots[source_wss_slot].wep[cur_bank];
4036  wip = &Weapon_info[weapon_type_to_add];
4037 
4038  // maybe localize
4039  if (Lcl_gr)
4040  {
4041  strcpy_s(buf, (Weapon_info[weapon_type_to_add].alt_name[0]) ? Weapon_info[weapon_type_to_add].alt_name : Weapon_info[weapon_type_to_add].name);
4043  wep_display_name = buf;
4044  }
4045  else
4046  {
4047  wep_display_name = (Weapon_info[weapon_type_to_add].alt_name[0]) ? Weapon_info[weapon_type_to_add].alt_name : Weapon_info[weapon_type_to_add].name;
4048  }
4049 
4050  // make sure this ship can accept this weapon
4051  if (!eval_weapon_flag_for_game_type(sip->allowed_weapons[weapon_type_to_add])
4052  || ((wip->wi_flags2 & WIF2_BALLISTIC) && !(sip->flags & SIF_BALLISTIC_PRIMARIES)))
4053  {
4054  SCP_string temp;
4055  sprintf(temp, XSTR("%s is unable to carry %s weaponry", 1629), ship_name, wep_display_name);
4056  error_messages.push_back(temp);
4057 
4058  error_flag = true;
4059  continue;
4060  }
4061 
4062  // make sure this bank can accept this weapon
4064  {
4065  if (!eval_weapon_flag_for_game_type(sip->allowed_bank_restricted_weapons[cur_bank][weapon_type_to_add]))
4066  {
4067  SCP_string temp;
4068  if (cur_bank < MAX_SHIP_PRIMARY_BANKS)
4069  sprintf(temp, XSTR("%s is unable to carry %s weaponry in primary bank %d", 1630), ship_name, wep_display_name, cur_bank+1);
4070  else
4071  sprintf(temp, XSTR("%s is unable to carry %s weaponry in secondary bank %d", 1631), ship_name, wep_display_name, cur_bank+1-MAX_SHIP_PRIMARY_BANKS);
4072  error_messages.push_back(temp);
4073 
4074  error_flag = true;
4075  continue;
4076  }
4077  }
4078 
4079  // add from the weapon pool
4080  result = wl_drop(-1, weapon_type_to_add, cur_bank, -1, cur_wss_slot, -1, true);
4081 
4082  // bank left unfilled or partially filled
4083  if ((result == 0) || (result == 2))
4084  {
4085  SCP_string temp;
4086  sprintf(temp, XSTR("Insufficient %s available to arm %s", 1632), (Weapon_info[weapon_type_to_add].alt_name[0]) ? Weapon_info[weapon_type_to_add].alt_name : Weapon_info[weapon_type_to_add].name, ship_name);
4087  error_messages.push_back(temp);
4088 
4089  error_flag = true;
4090  continue;
4091  }
4092  }
4093  }
4094 
4095  // play sound
4097 
4098  // display error messages
4099  if (error_flag)
4100  {
4101  SCP_string full_error_message = "The following errors were encountered:\n";
4102 
4103  size_t j;
4104  bool is_duplicate;
4105 
4106  // copy all messages
4107  for (i = 0; i < error_messages.size(); i++)
4108  {
4109  // check for duplicate messages
4110  is_duplicate = false;
4111  for (j = 0; j < i; j++)
4112  {
4113  if (error_messages[i] == error_messages[j])
4114  {
4115  is_duplicate = true;
4116  break;
4117  }
4118  }
4119  if (is_duplicate)
4120  continue;
4121 
4122  // copy message
4123  full_error_message += "\n";
4124  full_error_message += error_messages[i];
4125  }
4126 
4127  // display popup
4128  popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, full_error_message.c_str());
4129  }
4130 }
void light_add_directional(const vec3d *dir, float intensity, float r, float g, float b, float spec_r, float spec_g, float spec_b, bool specular)
Definition: lighting.cpp:209
void gr_rect(int x, int y, int w, int h, int resize_mode)
Definition: 2d.cpp:2068
Definition: sound.cpp:39
#define WL_BUTTON_RESET
GLuint64EXT * result
Definition: Glext.h:10775
int wl_dump_to_list(int from_bank, int to_list, int ship_slot, int *sound)
int ss_return_saindex(int slot_num)
void bm_unlock(int handle)
Unlocks a bitmap.
Definition: bmpman.cpp:3005
int Plist[MAX_WEAPON_TYPES]
void set_highlight_action(void(*_user_function)(void))
Definition: button.cpp:375
void multi_ts_lock_pressed()
#define WING_0_SHIP_2
void wl_render_icon_count(int num, int x, int y)
#define WING_0_SHIP_3
UI_XSTR Weapon_select_text[GR_NUM_RESOLUTIONS][WEAPON_SELECT_NUM_TEXT]
struct screen3d::@234::@236 xyw
int secondary_ammo[MAX_SHIP_SECONDARY_BANKS]
Definition: missionparse.h:318
#define IS_BANK_SECONDARY(x)
#define MY_NET_PLAYER_NUM
Definition: multi.h:127
char tech_model[MAX_FILENAME_LEN]
Definition: weapon.h:338
int i
Definition: multi_pxo.cpp:466
#define WL_BUTTON_APPLY_ALL
void wl_reset_team_pointers()
float p
Definition: pstypes.h:111
void add_XSTR(char *string, int _xstr_id, int _x, int _y, UI_GADGET *_assoc, int _color_type, int _font_id=-1)
Definition: window.cpp:476
int button_hilighted()
Definition: button.cpp:387
int primary_bank_weapons[MAX_SHIP_PRIMARY_BANKS]
Definition: ship.h:103
void wl_unload_all_anims()
#define MIN(a, b)
Definition: pstypes.h:296
#define GR_RESIZE_MENU_NO_OFFSET
Definition: 2d.h:686
float Proj_fov
Definition: 3dsetup.cpp:31
#define MAX_SHIP_PRIMARY_BANKS
Definition: globals.h:62
char weapon_select_background[GR_NUM_RESOLUTIONS][MAX_FILENAME_LEN]
#define WEAPON_ICON_FRAME_NORMAL
#define ICON_SHIP_SECONDARY_3
void wl_apply_current_loadout_to_all_ships_in_current_wing()
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:1299
#define SUBSYS_STATUS_NO_CHANGE
Definition: missionparse.h:310
void weapon_select_init_team(int team_num)
char name[NAME_LENGTH]
Definition: weapon.h:322
int num_primary_banks
Definition: ship.h:99
int Game_mode
Definition: systemvars.cpp:24
GLfloat GLfloat GLfloat GLfloat h
Definition: Glext.h:7280
wl_icon_info Wl_icons_teams[MAX_TVT_TEAMS][MAX_WEAPON_TYPES]
void wl_redraw_pressed_buttons()
void gr_flip()
Definition: 2d.cpp:2113
brief_common_buttons Common_buttons[3][GR_NUM_RESOLUTIONS][NUM_COMMON_BUTTONS]
int n_missiles
Definition: model.h:769
polymodel * model_get(int model_num)
Definition: modelread.cpp:3134
weapon_info Weapon_info[MAX_WEAPON_TYPES]
Definition: weapons.cpp:79
void do_mouse_over_list_weapon(int index)
wl_icon_info * Wl_icons
ship_weapon weapons
Definition: ship.h:658
void wl_weapon_desc_start_wipe()
net_player * Net_player
Definition: multi.cpp:94
#define GR_RESIZE_MENU
Definition: 2d.h:684
#define MOUSE_LEFT_BUTTON
Definition: mouse.h:43
const char * wl_tooltip_handler(const char *str)
int wl_carried_icon_moved()
#define gr_end_view_matrix
Definition: 2d.h:896
void draw_model_icon(int model_id, int flags, float closeup_zoom, int x, int y, int w, int h, const ship_info *sip, int resize_mode, const vec3d *closeup_pos)
vec3d closeup_pos
Definition: weapon.h:340
GLuint index
Definition: Glext.h:5608
void multi_send_anti_timeout_ping()
Definition: multiutil.cpp:4171
int ss_return_original_ship_class(int slot_num)
matrix * vm_angles_2_matrix(matrix *m, const angles *a)
Definition: vecmat.cpp:752
SCP_vector< p_object > Parse_objects
void vm_rotate_matrix_by_angles(matrix *orient, const angles *tangles)
Definition: vecmat.cpp:1338
__inline void gr_circle(int xc, int yc, int d, int resize_mode=GR_RESIZE_FULL)
Definition: 2d.h:774
drop a ship icon on a wing slot
Definition: gamesnd.h:289
#define NUM_WEAPON_SETTINGS
int snazzy_menu_do(ubyte *data, int mask_w, int mask_h, int num_regions, MENU_REGION *regions, int *action, int poll_key, int *key)
Definition: snazzyui.cpp:59
int Cmdline_weapon_choice_3d
Definition: cmdline.cpp:379
int allowed_bank_restricted_weapons[MAX_SHIP_WEAPONS][MAX_WEAPON_TYPES]
Definition: ship.h:1335
#define ICON_PRIMARY_2
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
#define WING_0_SHIP_0
Assert(pm!=NULL)
struct wl_ship_class_info wl_ship_class_info
Definition: pstypes.h:88
#define GR_NUM_RESOLUTIONS
Definition: 2d.h:651
#define mprintf(args)
Definition: pstypes.h:238
#define WL_BUTTON_SCROLL_SECONDARY_UP
int Player_weapon_precedence[MAX_WEAPON_TYPES]
Definition: weapons.cpp:125
#define NETINFO_FLAG_OBSERVER
Definition: multi.h:605
w_bank * gun_banks
Definition: model.h:772
__inline void gr_string(int x, int y, const char *string, int resize_mode=GR_RESIZE_FULL)
Definition: 2d.h:769
#define WING_2_SHIP_0
#define WEAPON_DESC_MAX_LENGTH
int secondary_banks[MAX_SHIP_SECONDARY_BANKS]
Definition: missionparse.h:317
int subsystem_stricmp(const char *str1, const char *str2)
Definition: parselo.cpp:3648
general failure sound for any event
Definition: gamesnd.h:297
void wl_free_ship_class_data()
Definition: 2d.h:95
int ss_disabled_slot(int slot_num, bool ship_selection)
char anim_filename[MAX_FILENAME_LEN]
Definition: weapon.h:423
matrix Eye_matrix
Definition: 3dsetup.cpp:26
#define ICON_SHIP_PRIMARY_1
int res
Definition: 2d.h:370
int max_h_unscaled
Definition: 2d.h:361
int bm_get_info(int handle, int *w, int *h, ubyte *flags, int *nframes, int *fps)
Gets info on the bitmap indexed by handle.
Definition: bmpman.cpp:769
void set_flags(uint flags)
#define MR_NO_LIGHTING
Definition: model.h:867
struct vec3d::@225::@227 xyz
CButton * team
void wl_bash_ship_weapons(ship_weapon *swp, wss_unit *slot)
void model_render_immediate(model_render_params *render_info, int model_num, matrix *orient, vec3d *pos, int render, bool sort)
struct carried_icon carried_icon
#define WEAPON_ICON_FRAME_HOT
GLclampf f
Definition: Glext.h:7097
#define IS_BANK_PRIMARY(x)
void common_check_buttons()
#define WL_BUTTON_MULTI_LOCK
void weapon_select_do(float frametime)
int primary_ammo[MAX_SHIP_PRIMARY_BANKS]
Definition: missionparse.h:316
#define GR_MAYBE_CLEAR_RES(bmap)
Definition: 2d.h:639
model_subsystem * subsystems
Definition: ship.h:1271
#define MAX_WSS_SLOTS
void set_detail_level_lock(int detail_level_lock)
void wl_reset_selected_slot()
int common_scroll_up_pressed(int *start, int size, int max_show)
GLenum mode
Definition: Glext.h:5794
int Background_playing
void wl_set_team_pointers(int team)
void commit_pressed()
void help_overlay_set_state(int overlay_id, int resolution_index, int state)
virtual void hide(int n)
Definition: gadget.cpp:207
void gr_set_color_fast(color *dst)
Definition: 2d.cpp:1197
int restricted_loadout_flag[MAX_SHIP_WEAPONS]
Definition: ship.h:1334
void weapon_select_close_team()
int primary_bank_weapons[MAX_SHIP_PRIMARY_BANKS]
Definition: ship.h:1294
void common_buttons_maybe_reload(UI_WINDOW *ui_window)
#define WEAPON_ICON_FRAME_DISABLED
Definition: ui.h:195
std::basic_string< char, std::char_traits< char >, std::allocator< char > > SCP_string
Definition: vmallocator.h:21
int flags
Definition: multi.h:463
#define WING_1_SHIP_3
void set_active_ui(UI_WINDOW *ui_window)
void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
Definition: 2d.cpp:2105
GLsizeiptr size
Definition: Glext.h:5496
int max_w_unscaled
Definition: 2d.h:361
int subtype
Definition: weapon.h:326
#define Int3()
Definition: pstypes.h:292
#define WSS_GRAB_FROM_LIST
#define ICON_SHIP_SECONDARY_2
#define COMMON_WEAPON_REGION
int Mouse_down_last_frame
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: Glext.h:7308
void wl_set_disabled_weapons(int ship_class)
#define ICON_PRIMARY_3
const char *(* tooltip_handler)(const char *text)
Definition: ui.h:649
int bm_release(int handle, int clear_render_targets)
Frees both a bitmap's data and it's associated slot.
Definition: bmpman.cpp:2603
void wl_render_overhead_view(float frametime)
int render_type
Definition: weapon.h:327
void ss_return_name(int wing_block, int wing_slot, char *name)
void snazzy_menu_add_region(MENU_REGION *region, const char *text, int mask, int key, int click_sound)
Definition: snazzyui.cpp:163
#define gr_end_proj_matrix
Definition: 2d.h:894
vec3d pnt[MAX_SLOTS]
Definition: model.h:434
int ss_valid_slot(int slot_num)
int multi_ts_is_locked()
#define BMP_AABITMAP
antialiased bitmap
Definition: bmpman.h:52
void weapon_select_init()
void generic_anim_unload(generic_anim *ga)
Definition: generic.cpp:291
void maybe_select_new_ship_weapon(int index)
#define WL_BUTTON_SCROLL_PRIMARY_UP
color Color_blue
Definition: alphacolors.cpp:31
int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *keyframe, int can_drop_frames, int dir_type)
Loads a bitmap sequance so we can draw with it.
Definition: bmpman.cpp:1420
void wl_update_parse_object_weapons(p_object *pobjp, wss_unit *slot)
int mouse_get_pos_unscaled(int *xpos, int *ypos)
Definition: mouse.cpp:580
void shadows_end_render()
Definition: shadows.cpp:386
int wep_count[MAX_SHIP_WEAPONS]
#define MAX_WING_SLOTS
#define IS_LIST_PRIMARY(x)
void common_reset_buttons()
void common_set_interface_palette(char *filename)
void common_flash_button_init()
__inline void gr_set_clip(int x, int y, int w, int h, int resize_mode=GR_RESIZE_FULL)
Definition: 2d.h:741
void draw_forced(int frame_num)
Definition: button.cpp:104
generic_anim animation
void wl_reset_to_defaults()
int mouse_down(int btn)
Definition: mouse.cpp:315
int * Wl_pool
#define gr_set_view_matrix
Definition: 2d.h:895
void destroy()
Definition: window.cpp:189
void wl_init_pool(team_data *td)
int Plist_start
#define MAX_PACKET_SIZE
Definition: psnet2.h:34
int num_frames
Definition: generic.h:20
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
#define ICON_SECONDARY_0
#define MAX_SHIP_SECONDARY_BANKS
Definition: globals.h:63
int wl_calc_missile_fit(int wi_index, int capacity)
int icon_bmaps[NUM_ICON_FRAMES]
#define gr_reset_clip
Definition: 2d.h:745
int instance
Definition: object.h:150
void set_mask_bmap(char *fname)
Definition: window.cpp:75
matrix shadows_start_render(matrix *eye_orient, vec3d *eye_pos, float fov, float aspect, float veryneardist, float neardist, float middist, float fardist)
Definition: shadows.cpp:349
int set_bmaps(char *ani_filename, int nframes=3, int start_frame=1)
Definition: gadget.cpp:71
void wl_render_icon(int index, int x, int y, int num, int draw_num_flag, int hot_mask, int hot_bank_mask, int select_mask)
void batch_render_all(int stream_buffer)
Definition: grbatch.cpp:1124
int Cmdline_nohtl
Definition: cmdline.cpp:438
int wl_slots_all_empty(wss_unit *slot)
const float PI2
Definition: pstypes.h:305
void chatbox_render()
Definition: chatbox.cpp:683
char pof_file[MAX_FILENAME_LEN]
Definition: ship.h:1183
net_player_info p_info
Definition: multi.h:473
#define gr_set_proj_matrix
Definition: 2d.h:893
char * desc
Definition: weapon.h:325
int type_flags
Definition: multi.h:493
weapon animation starts
Definition: gamesnd.h:309
#define NUM_ICON_FRAMES
#define SIF_BIG_SHIP
Definition: ship.h:944
void common_redraw_pressed_buttons()
int wl_calc_ballistic_fit(int wi_index, int capacity)
int Slist[MAX_WEAPON_TYPES]
int common_select_do(float frametime)
#define MAX_SHIP_WEAPONS
Definition: globals.h:64
int do_mouse_over_ship_weapon(int index)
int ss_wing_slot_is_console_player(int index)
void wl_render_weapon_desc()
#define DOGFIGHT_WEAPON
Definition: ship.h:959
screen3d screen
Definition: pstypes.h:173
int subtype
Definition: lua.cpp:9763
void wl_maybe_flash_button()
#define WING_1_SHIP_1
#define ICON_PRIMARY_0
int state
Definition: multi.h:464
#define nprintf(args)
Definition: pstypes.h:239
#define GM_MULTIPLAYER
Definition: systemvars.h:18
int first_frame
Definition: generic.h:19
int primary_bank_ammo[MAX_SHIP_PRIMARY_BANKS]
Definition: ship.h:121
void send_game_chat_packet(net_player *from, const char *msg, int msg_mode, net_player *to, const char *expr, int server_msg)
Definition: multimsgs.cpp:615
float clip_aspect
Definition: 2d.h:372
#define MR_NO_TEXTURING
Definition: model.h:868
#define MAX_SHIP_CLASSES
Definition: globals.h:48
int multi_ts_disabled_slot(int slot_num, int player_index)
int flags
Definition: ship.h:1227
void g3_set_view_matrix(const vec3d *view_pos, const matrix *view_matrix, float zoom)
Definition: 3dsetup.cpp:152
int Weapon_title_max_width[GR_NUM_RESOLUTIONS]
#define WSS_WEAPON_SELECT
Definition: multi.h:321
void model_clear_instance(int model_num)
Definition: modelread.cpp:4624
char * filename
netgame_info Netgame
Definition: multi.cpp:97
int Cmdline_ship_choice_3d
Definition: cmdline.cpp:378
void weapon_select_common_init()
int num_secondary_banks
Definition: ship.h:100
int pressed()
Definition: button.cpp:325
#define WEAPON_ICON_FRAME_SELECTED
#define MULTIPLAYER_HOST
Definition: multi.h:131
int Commit_pressed
#define WP_LASER
Definition: weapon.h:27
#define MAX_WEAPON_TYPES
Definition: globals.h:73
#define COMMON_SS_REGION
int num_weapon_choices
Definition: missionparse.h:539
#define WEAPON_SELECT_NUM_TEXT
void multi_ts_commit_pressed()
void draw_wing_block(int wb_num, int hot_slot, int selected_slot, int class_select, bool ship_selection)
float Max_draw_distance
Definition: 2d.cpp:85
#define WRT_LASER
Definition: weapon.h:34
void generic_anim_render(generic_anim *ga, float frametime, int x, int y, bool menu)
Definition: generic.cpp:437
#define w(p)
Definition: modelsinc.h:68
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
#define NG_TYPE_TEAM
Definition: multi.h:650
net_player * host
Definition: multi.h:504
int wl_update_ship_weapons(int objnum, wss_unit *slot)
int weaponry_pool[MAX_WEAPON_TYPES]
Definition: missionparse.h:540
void wl_maybe_reset_selected_slot()
void weapon_select_close()
int n_subsystems
Definition: ship.h:1270
void weapon_select_render(float frametime)
#define ICON_SHIP_PRIMARY_0
#define GR_640
Definition: 2d.h:652
int primary_banks[MAX_SHIP_PRIMARY_BANKS]
Definition: missionparse.h:315
int subsys_index
Definition: missionparse.h:363
ubyte g3_rotate_vertex(vertex *dest, const vec3d *src)
Definition: 3dmath.cpp:97
Definition: bmpman.h:101
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:104
void draw_wl_icons()
#define NUM_COMMON_REGIONS
#define gr_curve
Definition: 2d.h:789
#define NETINFO_FLAG_TEAM_CAPTAIN
Definition: multi.h:612
#define ICON_SECONDARY_1
void common_select_init()
bitmap * bm_lock(int handle, ubyte bpp, ubyte flags, bool nodebug)
Locks down the bitmap indexed by bitmapnum.
Definition: bmpman.cpp:1754
short player_id
Definition: multi.h:460
void send_wss_update_packet(int team_num, ubyte *wss_data, int size)
Definition: multimsgs.cpp:5437
void wl_get_ship_weapons(int ship_index, int *wep, int *wep_count)
#define MULTI_DOGFIGHT
Definition: multi.h:656
void common_set_team_pointers(int team)
#define NETINFO_FLAG_GAME_HOST
Definition: multi.h:603
vec3d closeup_pos
Definition: ship.h:1327
#define WING_2_SHIP_1
#define ICON_FRAME_DISABLED
int secondary_bank_ammo_capacity[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:1300
int wss_get_mode(int from_slot, int from_list, int to_slot, int to_list, int wl_ship_slot)
void maybe_select_wl_slot(int block, int slot)
#define SIF_BALLISTIC_PRIMARIES
Definition: ship.h:880
int model_load(char *filename, int n_subsystems, model_subsystem *subsystems, int ferror=1, int duplicate=0)
Definition: modelread.cpp:2573
void wl_draw_ship_weapons(int index)
struct wl_bitmap_group wl_bitmap_group
int num_slots
Definition: model.h:433
#define MAX_WING_BLOCKS
#define CF_TYPE_INTERFACE
Definition: cfile.h:63
void model_page_in_textures(int modelnum, int ship_info_index=-1)
int idx
Definition: multiui.cpp:761
int g3_project_vertex(vertex *point)
Definition: 3dmath.cpp:202
void wl_init_ship_class_data()
int secondary_bank_ammo[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:134
void common_check_keys(int k)
void common_render_selected_screen_button()
vec3d * vm_vec_unrotate(vec3d *dest, const vec3d *src, const matrix *m)
Definition: vecmat.cpp:959
#define WL_BUTTON_DUMMY
int eval_weapon_flag_for_game_type(int weapon_flags)
char name[NAME_LENGTH]
Definition: ship.h:1163
int Cmdline_shadow_quality
Definition: cmdline.cpp:344
object Objects[MAX_OBJECTS]
Definition: object.cpp:62
GLint GLint GLint GLint GLint x
Definition: Glext.h:5182
void draw_wl_icon_with_number(int list_count, int weapon_class)
bool Glowpoint_use_depth_buffer
Definition: systemvars.cpp:76
unsigned char ubyte
Definition: pstypes.h:62
#define WEAPON_DESC_MAX_LINES
const char * XSTR(const char *str, int index)
Definition: localize.cpp:851
int Plist_size
#define OBJ_INDEX(objp)
Definition: object.h:235
#define MULTI_TEAM
Definition: multi.h:655
int wi_flags2
Definition: weapon.h:385
#define NOX(s)
Definition: pstypes.h:473
struct wl_icon_info wl_icon_info
bool end_string_at_first_hash_symbol(char *src)
Definition: parselo.cpp:3833
int Weapon_select_background_bitmap
void maybe_select_new_weapon(int index)
void _cdecl void void _cdecl Error(const char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
void wl_unload_icons()
#define MAX_WEAPON_ICONS_ON_SCREEN
#define WL_OVERLAY
Definition: contexthelp.h:22
#define SIF_HUGE_SHIP
Definition: ship.h:945
int Common_team
void capture_mouse()
Definition: gadget.cpp:225
int num_secondary_banks
Definition: ship.h:1298
GLuint const GLchar * name
Definition: Glext.h:5608
#define MULTI_TS_MAX_TVT_TEAMS
__inline void gr_line(int x1, int y1, int x2, int y2, int resize_mode=GR_RESIZE_FULL)
Definition: 2d.h:791
int weaponry_count[MAX_WEAPON_TYPES]
Definition: missionparse.h:541
wss_unit * Wss_slots
#define IDENTITY_MATRIX
Definition: vecmat.h:64
color Color_black
Definition: alphacolors.cpp:32
#define REVOLUTION_RATE
Definition: techmenu.cpp:37
void common_buttons_init(UI_WINDOW *ui_window)
#define COMMON_HELP_REGION
#define ICON_FRAME_SELECTED
vec3d Eye_position
Definition: 3dsetup.cpp:27
int bm_load(const char *real_filename)
Loads a bitmap so we can draw with it later.
Definition: bmpman.cpp:1119
#define WING_1_SHIP_2
GLboolean GLboolean GLboolean b
Definition: Glext.h:5781
ship Ships[MAX_SHIPS]
Definition: ship.cpp:122
void wl_init_icon_lists()
struct generic_anim::@239::@241 ani
#define NUM_WEAPON_BUTTONS
#define MULTI_PERM_OBSERVER(np)
Definition: multi.h:142
void wl_add_index_to_list(int wi_index)
briefing * Briefing
int selection_effect
Definition: weapon.h:424
int wl_icon_being_carried()
int wl_swap_slot_slot(int from_bank, int to_bank, int ship_slot, int *sound, net_player *pl)
GLuint GLuint num
Definition: Glext.h:9089
color Color_bright_white
Definition: alphacolors.cpp:32
void wl_get_ship_class_weapons(int ship_class, int *wep, int *wep_count)
int Wss_num_wings
int common_scroll_down_pressed(int *start, int size, int max_show)
scroll pressed (and scroll)
Definition: gamesnd.h:296
color Color_white
Definition: alphacolors.cpp:32
#define CALLSIGN_LEN
Definition: globals.h:31
color Icon_colors[NUM_ICON_FRAMES]
void link_hotspot(int num)
Definition: gadget.cpp:50
#define strcat_s(...)
Definition: safe_strings.h:68
int wl_drop(int from_bank, int from_list, int to_bank, int to_list, int ship_slot, int player_index, bool dont_play_sound)
void create(UI_WINDOW *wnd, char *_text, int _x, int _y, int _w, int _h, int do_repeat=0, int ignore_focus=0)
Definition: button.cpp:26
#define NAME_LENGTH
Definition: globals.h:15
#define COMMON_COMMIT_REGION
int wep[MAX_SHIP_WEAPONS]
GLubyte GLubyte GLubyte GLubyte w
Definition: Glext.h:5679
int Weapon_select_overlay_id
void draw_model_rotating(model_render_params *render_info, int model_id, int x1, int y1, int x2, int y2, float *rotation_buffer, vec3d *closeup_pos, float closeup_zoom, float rev_rate, int flags, int resize_mode, int effect)
#define ON_WEAPON_SELECT
Definition: missionbrief.h:20
#define WP_MISSILE
Definition: weapon.h:28
float rad
Definition: model.h:757
int button_down()
Definition: button.cpp:363
int Slist_start
#define fl2i(fl)
Definition: floating.h:33
void create(int _x, int _y, int _w, int _h, int _flags, int _f_id=-1)
Definition: window.cpp:140
#define ICON_FRAME_HOT
#define g3_end_frame()
Definition: 3d.h:49
void wl_reset_carried_icon()
Definition: ui.h:584
screen gr_screen
Definition: 2d.cpp:46
float Min_draw_distance
Definition: 2d.cpp:84
void gr_get_string_size(int *w, int *h, const char *text, int len=9999)
Definition: font.cpp:196
wl_buttons(char *name, int x1, int y1, int xt1, int yt1, int h)
void generic_anim_init(generic_anim *ga)
Definition: generic.cpp:80
void wl_swap_weapons(int ship_slot, int from_bank, int to_bank)
void wl_get_default_weapons(int ship_class, int slot_num, int *wep, int *wep_count)
Definition: ui.h:162
void weapon_button_do(int i)
#define ICON_SECONDARY_3
int drop_icon_on_slot(int bank_num)
int gr_get_font_height()
Definition: font.cpp:187
int store_wss_data(ubyte *block, int max_size, int sound, int player_index)
int ship_info_index
Definition: ship.h:539
void light_reset()
Definition: lighting.cpp:150
GLfloat GLfloat p
Definition: Glext.h:8373
int wl_get_ship_class(int wl_slot)
#define MR_IS_MISSILE
Definition: model.h:872
#define COMMON_OPTIONS_REGION
#define WSS_SWAP_SLOT_SLOT
#define IS_LIST_SECONDARY(x)
SCP_vector< ship_info > Ship_info
Definition: ship.cpp:164
#define LOCATION
Definition: pstypes.h:245
void common_play_highlight_sound()
Definition: gamesnd.cpp:1151
void stop_weapon_animation()
#define SNAZZY_CLICKED
Definition: snazzyui.h:29
void weapon_buttons_init()
void multi_common_voice_display_status()
Definition: multiui.cpp:369
ptr_u data
Pointer to data, or maybe offset into VRAM.
Definition: bmpman.h:109
void draw_tooltip()
Definition: window.cpp:304
BM_TYPE bm_get_type(int handle)
Returns the image type of the given bitmap handle.
Definition: bmpman.cpp:894
#define CF_MAX_FILENAME_LENGTH
Definition: cfile.h:39
#define WSS_SWAP_LIST_SLOT
#define MULTI_MSG_TARGET
Definition: multi_pmsg.h:30
wl_ship_class_info Wl_ships[MAX_SHIP_CLASSES]
void wl_remove_weps_from_pool(int *wep, int *wep_count, int ship_class)
color Color_normal
Definition: alphacolors.cpp:28
void wl_get_parseobj_weapons(int sa_index, int ship_class, int *wep, int *wep_count)
#define MAX_TVT_TEAMS
Definition: globals.h:57
int n_guns
Definition: model.h:768
void wl_load_icons(int weapon_class)
void wl_load_all_icons()
#define i2fl(i)
Definition: floating.h:32
void weapon_check_buttons()
void wl_dump_carried_icon()
#define ICON_SHIP_SECONDARY_1
GLint GLsizei count
Definition: Gl.h:1491
int Weapon_select_open
void gr_bitmap(int _x, int _y, int resize_mode)
Definition: 2d.cpp:1303
const float PI_2
Definition: pstypes.h:307
#define UI_XSTR_COLOR_GREEN
Definition: ui.h:160
team_data Team_data[MAX_TVT_TEAMS]
#define ICON_SECONDARY_2
#define WEAPON_DESC_WIPE_TIME
char pofbitmap_name[MAX_FILENAME_LEN]
Definition: weapon.h:328
object * Player_obj
Definition: object.cpp:56
#define NETPLAYER_STATE_WEAPON_SELECT
Definition: multi.h:682
int ship_index
Definition: multi.h:450
void pick_from_ship_slot(int num)
int temp
Definition: lua.cpp:4996
int mission_ui_background_load(const char *custom_background, const char *single_background, const char *multi_background)
#define WIF2_BALLISTIC
Definition: weapon.h:84
polymodel * pm
Definition: lua.cpp:1598
w_bank * missile_banks
Definition: model.h:773
bool gr_unsize_screen_posf(float *x, float *y, float *w, float *h, int resize_mode)
Definition: 2d.cpp:538
float closeup_zoom
Definition: ship.h:1328
int Multi_ping_timestamp
Definition: fredstubs.cpp:30
#define ICON_SHIP_PRIMARY_2
int bm_unload(int handle, int clear_render_targets, bool nodebug)
Unloads a bitmap's data, but not the bitmap info.
Definition: bmpman.cpp:2890
char filename[MAX_FILENAME_LEN]
Definition: generic.h:18
#define WING_2_SHIP_2
subsys_status * Subsys_status
#define MAX_WEAPON_BUTTONS
void wl_saturate_bank(int ship_slot, int bank)
GLboolean reset
Definition: Glext.h:5243
#define WL_BUTTON_SCROLL_SECONDARY_DOWN
void wl_synch_interface()
#define REGULAR_WEAPON
Definition: ship.h:958
#define WING_1_SHIP_0
char alt_name[NAME_LENGTH]
Definition: weapon.h:323
void gamesnd_play_iface(int n)
Definition: gamesnd.cpp:260
int anim_timer_start
void disable()
Definition: gadget.cpp:432
void draw()
Definition: window.cpp:220
float closeup_zoom
Definition: weapon.h:341
#define COMMON_BRIEFING_REGION
float h
Definition: pstypes.h:111
#define WING_2_SHIP_3
#define ICON_SHIP_SECONDARY_0
void send_wss_request_packet(short player_id, int from_slot, int from_index, int to_slot, int to_index, int wl_ship_slot, int ship_class, int mode, net_player *p)
Definition: multimsgs.cpp:5360
int wl_apply(int mode, int from_bank, int from_list, int to_bank, int to_list, int ship_slot, int player_index, bool dont_play_sound)
int Current_screen
vec3d vmd_zero_vector
Definition: vecmat.cpp:24
int subsys_count
Definition: missionparse.h:364
char overhead_filename[MAX_FILENAME_LEN]
Definition: ship.h:1341
int common_flash_bright()
int wl_swap_list_slot(int from_list, int to_bank, int ship_slot, int *sound, net_player *pl)
int help_overlay_get_index(const char *overlay_name)
int generic_anim_stream(generic_anim *ga)
Definition: generic.cpp:159
int wl_get_pilot_subsys_index(p_object *pobjp)
void draw_brackets_square(int x1, int y1, int x2, int y2, int resize_mode)
Definition: hudbrackets.cpp:49
net_player Net_players[MAX_PLAYERS]
Definition: multi.cpp:93
void maybe_drop_icon_on_slot(int bank_num)
void lcl_translate_wep_name_gr(char *name)
Definition: localize.cpp:1134
int timer_get_milliseconds()
Definition: timer.cpp:150
void _cdecl gr_printf_menu(int x, int y, const char *format,...)
Definition: font.cpp:314
#define WING_0_SHIP_1
#define MR_NO_FOGGING
Definition: model.h:884
#define stricmp(s1, s2)
Definition: config.h:271
drop a ship icon back to the list
Definition: gamesnd.h:290
void wl_set_selected_slot(int slot_num)
int wl_grab_from_list(int from_list, int to_bank, int ship_slot, int *sound, net_player *pl)
void wl_set_carried_icon(int from_bank, int from_slot, int weapon_class)
void help_overlay_maybe_blit(int overlay_id, int resolution_index)
#define ICON_PRIMARY_1
int help_overlay_active(int overlay_id)
#define GR_1024
Definition: 2d.h:653
int allowed_weapons[MAX_WEAPON_TYPES]
Definition: ship.h:1330
void start_weapon_animation(int weapon_class)
void light_rotate_all()
Definition: lighting.cpp:585
int Num_player_weapon_precedence
Definition: weapons.cpp:124
int Lcl_gr
Definition: localize.cpp:48
#define ICON_FRAME_NORMAL
void wl_cull_illegal_weapons(int ship_class, int *wep, int *wep_count)
#define WSS_DUMP_TO_LIST
float b
Definition: pstypes.h:111
void model_unload(int modelnum, int force=0)
Definition: modelread.cpp:162
GLint y
Definition: Gl.h:1505
UI_WINDOW Weapon_ui_window
int num_primary_banks
Definition: ship.h:1293
#define WL_BUTTON_SCROLL_PRIMARY_DOWN
#define g3_start_frame(zbuffer_flag)
Definition: 3d.h:39
int Slist_size
void wl_maybe_reset_selected_weapon_class()
void wl_fill_slots()
#define strcpy_s(...)
Definition: safe_strings.h:67
int ss_return_ship(int wing_block, int wing_slot, int *ship_index, p_object **ppobjp)
void wl_pick_icon_from_list(int index)
#define MR_AUTOCENTER
Definition: model.h:875