FS2_Open
Open source remastering of the Freespace 2 engine
redalert.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 #define REDALERT_INTERNAL
12 #include "ai/aigoals.h"
13 #include "cfile/cfile.h"
14 #include "freespace2/freespace.h"
16 #include "gamesnd/gamesnd.h"
17 #include "globalincs/alphacolors.h"
18 #include "globalincs/linklist.h"
19 #include "graphics/font.h"
20 #include "hud/hudwingmanstatus.h"
21 #include "io/key.h"
22 #include "io/mouse.h"
23 #include "io/timer.h"
26 #include "mission/missiongoals.h"
29 #include "missionui/redalert.h"
30 #include "mod_table/mod_table.h"
31 #include "model/model.h"
32 #include "ship/ship.h"
33 #include "sound/audiostr.h"
34 #include "sound/fsspeech.h"
35 #include "weapon/weapon.h"
36 
37 #include <stdexcept>
38 
39 
41 // Red Alert Mission-Level
43 
44 static int Red_alert_new_mission_timestamp; // timestamp used to give user a little warning for red alerts
45 //static int Red_alert_num_slots_used = 0;
46 static int Red_alert_voice_started;
47 
50 
52 // Red Alert Interface
54 
56  "RedAlert",
57  "2_RedAlert"
58 };
59 
61  "RedAlert-m",
62  "2_RedAlert-m"
63 };
64 
65 // font to use for "incoming transmission"
67  FONT2,
68  FONT2
69 };
70 
72  140,
73  200
74 };
75 
76 /*
77 static int Ra_flash_coords[GR_NUM_RESOLUTIONS][2] = {
78  {
79  61, 108 // GR_640
80  },
81  {
82  61, 108 // GR_1024
83  }
84 };
85 */
86 
87 #define NUM_BUTTONS 2
88 
89 #define RA_REPLAY_MISSION 0
90 #define RA_CONTINUE 1
91 
93  { // GR_640
94  ui_button_info("RAB_00", 2, 445, -1, -1, 0),
95  ui_button_info("RAB_01", 575, 432, -1, -1, 1),
96  },
97  { // GR_1024
98  ui_button_info("2_RAB_00", 4, 712, -1, -1, 0),
99  ui_button_info("2_RAB_01", 920, 691, -1, -1, 1),
100  }
101 };
102 
103 #define RED_ALERT_NUM_TEXT 3
105  { // GR_640
106  { "Replay", 1405, 46, 451, UI_XSTR_COLOR_PINK, -1, &Buttons[0][RA_REPLAY_MISSION].button },
107  { "Previous Mission", 1452, 46, 462, UI_XSTR_COLOR_PINK, -1, &Buttons[0][RA_REPLAY_MISSION].button },
108  { "Continue", 1069, 564, 413, UI_XSTR_COLOR_PINK, -1, &Buttons[0][RA_CONTINUE].button },
109  },
110  { // GR_1024
111  { "Replay", 1405, 75, 722, UI_XSTR_COLOR_PINK, -1, &Buttons[1][RA_REPLAY_MISSION].button },
112  { "Previous Mission", 1452, 75, 733, UI_XSTR_COLOR_PINK, -1, &Buttons[1][RA_REPLAY_MISSION].button },
113  { "Continue", 1069, 902, 661, UI_XSTR_COLOR_PINK, -1, &Buttons[1][RA_CONTINUE].button },
114  }
115 };
116 
117 // indicies for coordinates
118 #define RA_X_COORD 0
119 #define RA_Y_COORD 1
120 #define RA_W_COORD 2
121 #define RA_H_COORD 3
122 
123 
124 static int Text_delay;
125 
127  {
128  14, 151, 522, 289
129  },
130  {
131  52, 241, 785, 463
132  }
133 };
134 
135 static UI_WINDOW Ui_window;
136 // static hud_anim Flash_anim;
137 static int Background_bitmap;
138 static int Red_alert_inited = 0;
139 
140 static int Red_alert_voice;
141 
142 // open and pre-load the stream buffers for the different voice streams
144 {
145  Assert( Briefing != NULL );
146  if ( strnicmp(Briefing->stages[0].voice, NOX("none"), 4) && (Briefing->stages[0].voice[0] != '\0') ) {
147  Red_alert_voice = audiostream_open( Briefing->stages[0].voice, ASF_VOICE );
148  }
149 }
150 
151 // close all the briefing voice streams
153 {
154  if ( Red_alert_voice != -1 ) {
155  audiostream_close_file(Red_alert_voice, 0);
156  Red_alert_voice = -1;
157  }
158 }
159 
160 // start playback of the red alert voice
162 {
163  if ( !Briefing_voice_enabled ) {
164  return;
165  }
166 
167  if ( Red_alert_voice < 0 ) {
168  // play simulated speech?
170  if (fsspeech_playing()) {
171  return;
172  }
173 
175  Red_alert_voice_started = 1;
176  }
177  } else {
178  if (audiostream_is_playing(Red_alert_voice)) {
179  return;
180  }
181 
182  audiostream_play(Red_alert_voice, Master_voice_volume, 0);
183  Red_alert_voice_started = 1;
184  }
185 }
186 
187 // stop playback of the red alert voice
189 {
190  if ( !Red_alert_voice_started )
191  return;
192 
193  if (Red_alert_voice < 0) {
194  fsspeech_stop();
195  } else {
196  audiostream_stop(Red_alert_voice, 1, 0); // stream is automatically rewound
197  }
198 }
199 
200 // pausing and unpausing of red alert voice
202 {
203  if ( !Red_alert_voice_started )
204  return;
205 
206  if (Red_alert_voice < 0) {
207  fsspeech_pause(true);
208  } else {
209  audiostream_pause(Red_alert_voice);
210  }
211 }
212 
214 {
215  if ( !Red_alert_voice_started )
216  return;
217 
218  if (Red_alert_voice < 0) {
219  fsspeech_pause(false);
220  } else {
221  audiostream_unpause(Red_alert_voice);
222  }
223 }
224 
225 // a button was pressed, deal with it
227 {
228  switch (n) {
229  case RA_CONTINUE:
230  // warp the mouse cursor the the middle of the screen for those who control with a mouse
232 
233  if(Game_mode & GM_MULTIPLAYER){
234  // process the initial orders now (moved from post_process_mission()in missionparse)
237  }
238 
240  break;
241 
242  case RA_REPLAY_MISSION:
243  if ( Game_mode & GM_CAMPAIGN_MODE ) {
244  // TODO: make call to campaign code to set correct mission for loading
245  // mission_campaign_play_previous_mission(Red_alert_precursor_mission);
248  break;
249  }
250 
252  } else {
254  }
255  break;
256  }
257 }
258 
259 // blit "incoming transmission"
260 #define RA_FLASH_CYCLE 0.25f
261 float Ra_flash_time = 0.0f;
262 int Ra_flash_up = 0;
264 {
265  const char *str = XSTR("Incoming Transmission", 1406);
266  int w, h;
267 
268  // get the string size
270  gr_get_string_size(&w, &h, str);
271 
272  // set alpha color
273  color flash_color;
274  if(Ra_flash_up){
275  gr_init_alphacolor(&flash_color, (int)(255.0f * (Ra_flash_time / RA_FLASH_CYCLE)), 0, 0, 255);
276  } else {
277  gr_init_alphacolor(&flash_color, (int)(255.0f * (1.0f - (Ra_flash_time / RA_FLASH_CYCLE))), 0, 0, 255);
278  }
279 
280  // draw
281  gr_set_color_fast(&flash_color);
284 
285  // increment flash time
288  Ra_flash_time = 0.0f;
290  }
291 
292  // back to the original font
294 }
295 
296 // Called once when red alert interface is started
298 {
299  int i;
300  ui_button_info *b;
301 
302  if ( Red_alert_inited ) {
303  return;
304  }
305 
308 
309  for (i=0; i<NUM_BUTTONS; i++) {
310  b = &Buttons[gr_screen.res][i];
311 
312  b->button.create(&Ui_window, "", b->x, b->y, 60, 30, 0, 1);
313  // set up callback for when a mouse first goes over a button
315  b->button.set_bmaps(b->filename);
316  b->button.link_hotspot(b->hotspot);
317  }
318 
319  // all text
320  for(i=0; i<RED_ALERT_NUM_TEXT; i++){
321  Ui_window.add_XSTR(&Red_alert_text[gr_screen.res][i]);
322  }
323 
324  // set up red alert hotkeys
326 
327  // hud_anim_init(&Flash_anim, Ra_flash_coords[gr_screen.res][RA_X_COORD], Ra_flash_coords[gr_screen.res][RA_Y_COORD], NOX("AlertFlash"));
328  // hud_anim_load(&Flash_anim);
329 
330  Red_alert_voice = -1;
331 
332  if ( !Briefing ) {
333  Briefing = &Briefings[0];
334  }
335 
336  // load in background image and flashing red alert animation
338 
339  if ( Briefing->num_stages > 0 ) {
341  }
342 
344 
345  // we have to reset/setup the shipselect and weaponselect pointers before moving on
348 
349  Text_delay = timestamp(200);
350 
351  Red_alert_voice_started = 0;
352  Red_alert_inited = 1;
353 }
354 
355 // Called once when the red alert interface is exited
357 {
358  if (Red_alert_inited) {
359 
362 
364 
365  if (Background_bitmap >= 0) {
366  bm_release(Background_bitmap);
367  }
368 
369  Ui_window.destroy();
370  // bm_unload(&Flash_anim);
371  common_free_interface_palette(); // restore game palette
372  game_flush();
373  }
374 
375  Red_alert_inited = 0;
376 
377  fsspeech_stop();
378 }
379 
380 // called once per frame when game state is GS_STATE_RED_ALERT
381 void red_alert_do_frame(float frametime)
382 {
383  int i, k;
384 
385  // ensure that the red alert interface has been initialized
386  if (!Red_alert_inited) {
387  Int3();
388  return;
389  }
390 
391  // commit if skipping briefing, but not in multi - Goober5000
392  if (!(Game_mode & GM_MULTIPLAYER)) {
394  {
396  return;
397  }
398  }
399 
400  k = Ui_window.process() & ~KEY_DEBUGGED;
401  switch (k) {
402  case KEY_ESC:
403 // gameseq_post_event(GS_EVENT_ENTER_GAME);
405  break;
406  } // end switch
407 
408  for (i=0; i<NUM_BUTTONS; i++){
409  if (Buttons[gr_screen.res][i].button.pressed()){
411  }
412  }
413 
414  GR_MAYBE_CLEAR_RES(Background_bitmap);
415  if (Background_bitmap >= 0) {
416  gr_set_bitmap(Background_bitmap);
417  gr_bitmap(0, 0, GR_RESIZE_MENU);
418  }
419 
420  Ui_window.draw();
421  // hud_anim_render(&Flash_anim, frametime);
422 
424 
425  if ( timestamp_elapsed(Text_delay) ) {
426  int finished_wipe = 0;
427  if ( Briefing->num_stages > 0 ) {
429  }
430 
431  if (finished_wipe) {
433  }
434  }
435 
436  // blit incoming transmission
438 
439  gr_flip();
440 }
441 
442 // set the red alert status for the current mission
444 {
445  Red_alert_new_mission_timestamp = timestamp(-1); // make invalid
446 }
447 
448 // Store a ships weapons into a wingman status structure
449 void red_alert_store_weapons(red_alert_ship_status *ras, ship_weapon *swp)
450 {
451  int i;
452  weapon_info *wip;
453  wep_t weapons;
454 
455  // Make sure there isn't any data from the previous ship.
456  ras->primary_weapons.clear();
457  ras->secondary_weapons.clear();
458 
459  if (swp == NULL) {
460  return;
461  }
462 
463  // edited to accommodate ballistics - Goober5000
464  for (i = 0; i < swp->num_primary_banks; i++) {
465  weapons.index = swp->primary_bank_weapons[i];
466 
467  if (weapons.index < 0) {
468  continue;
469  }
470 
471  wip = &Weapon_info[weapons.index];
472 
473  if (wip->wi_flags2 & WIF2_BALLISTIC) {
474  // to avoid triggering the below condition: this way, minimum ammo will be 2...
475  // since the red-alert representation of a conventional primary is 0 -> not used,
476  // 1 -> used, I added the representation 2 and above -> ballistic primary
477  weapons.count = swp->primary_bank_ammo[i] + 2;
478  } else {
479  weapons.count = 1;
480  }
481 
482  ras->primary_weapons.push_back( weapons );
483  }
484 
485  for (i = 0; i < swp->num_secondary_banks; i++) {
486  weapons.index = swp->secondary_bank_weapons[i];
487 
488  if (weapons.index < 0) {
489  continue;
490  }
491 
492  weapons.count = swp->secondary_bank_ammo[i];
493 
494  ras->secondary_weapons.push_back( weapons );
495  }
496 }
497 
498 // Take the weapons stored in a wingman_status struct, and bash them into the ship weapons struct
499 void red_alert_bash_weapons(red_alert_ship_status *ras, ship_weapon *swp)
500 {
501  int i, list_size = 0;
502 
503  // restore from ship_exited
504  if ( (ras->ship_class == RED_ALERT_DESTROYED_SHIP_CLASS) || (ras->ship_class == RED_ALERT_PLAYER_DEL_SHIP_CLASS) ) {
505  return;
506  }
507 
508  // modified to accommodate ballistics - Goober5000
509  list_size = (int)ras->primary_weapons.size();
510  CLAMP(list_size, 0, MAX_SHIP_PRIMARY_BANKS);
511  for (i = 0; i < list_size; i++) {
512  Assert( ras->primary_weapons[i].index >= 0 );
513 
514  swp->primary_bank_weapons[i] = ras->primary_weapons[i].index;
515  swp->primary_bank_ammo[i] = ras->primary_weapons[i].count;
516 
518  // adjust to correct ammo count, per red_alert_store_weapons()
519  swp->primary_bank_ammo[i] -= 2;
520  }
521  }
522  swp->num_primary_banks = list_size;
523 
524  // bash secondary weapons
525  list_size = (int)ras->secondary_weapons.size();
526  CLAMP(list_size, 0, MAX_SHIP_SECONDARY_BANKS);
527  for (i = 0; i < list_size; i++) {
528  Assert( ras->secondary_weapons[i].index >= 0 );
529 
530  swp->secondary_bank_weapons[i] = ras->secondary_weapons[i].index;
531  swp->secondary_bank_ammo[i] = ras->secondary_weapons[i].count;
532  }
533  swp->num_secondary_banks = list_size;
534 }
535 
536 void red_alert_bash_weapons(red_alert_ship_status *ras, p_object *pobjp)
537 {
538  int i, list_size = 0;
539  ship_info *sip;
540  subsys_status *sssp = NULL;
541 
542  // restore from ship_exited
543  if ( (ras->ship_class == RED_ALERT_DESTROYED_SHIP_CLASS) || (ras->ship_class == RED_ALERT_PLAYER_DEL_SHIP_CLASS) )
544  return;
545  sip = &Ship_info[ras->ship_class];
546 
547  // parse objects use the "pilot" subsystem
548  for (i = 0; i < pobjp->subsys_count; i++)
549  {
550  if (!stricmp(Subsys_status[pobjp->subsys_index + i].name, "pilot"))
551  {
552  sssp = &Subsys_status[pobjp->subsys_index + i];
553  break;
554  }
555  }
556 
557  if (sssp == NULL)
558  {
559  Warning(LOCATION, "Parse object data for ship '%s' doesn't contain the 'Pilot' subsystem!", pobjp->name);
560  return;
561  }
562 
563  // bash primary weapons
564  list_size = (int)ras->primary_weapons.size();
565  CLAMP(list_size, 0, MAX_SHIP_PRIMARY_BANKS);
566  for (i = 0; i < list_size; i++)
567  {
568  Assert( ras->primary_weapons[i].index >= 0 );
569  sssp->primary_banks[i] = ras->primary_weapons[i].index;
570 
572  {
573  float max_count = sip->primary_bank_ammo_capacity[i] / Weapon_info[sssp->primary_banks[i]].cargo_size;
574  sssp->primary_ammo[i] = fl2i(100.0f * (ras->primary_weapons[i].count - 2) / max_count + 0.5f);
575  }
576  else
577  sssp->primary_ammo[i] = 100;
578  }
579 
580  // bash secondary weapons
581  list_size = (int)ras->secondary_weapons.size();
582  CLAMP(list_size, 0, MAX_SHIP_SECONDARY_BANKS);
583  for (i = 0; i < list_size; i++)
584  {
585  Assert( ras->secondary_weapons[i].index >= 0 );
586  sssp->secondary_banks[i] = ras->secondary_weapons[i].index;
587 
588  float max_count = sip->secondary_bank_ammo_capacity[i] / Weapon_info[sssp->secondary_banks[i]].cargo_size;
589  sssp->secondary_ammo[i] = fl2i(100.0f * ras->secondary_weapons[i].count / max_count + 0.5f);
590  }
591 }
592 
593 void red_alert_bash_subsys_status(red_alert_ship_status *ras, ship *shipp)
594 {
595  ship_subsys *ss;
596  int i, count = 0;
597  int list_size;
598 
599  // restore from ship_exited
600  if ( (ras->ship_class == RED_ALERT_DESTROYED_SHIP_CLASS) || (ras->ship_class == RED_ALERT_PLAYER_DEL_SHIP_CLASS) ) {
601  return;
602  }
603 
604  ss = GET_FIRST(&shipp->subsys_list);
605  while ( ss != END_OF_LIST( &shipp->subsys_list ) ) {
606  // using at() here for the bounds check, although out-of-bounds should
607  // probably never happen here
608  try {
609  ss->current_hits = ras->subsys_current_hits.at(count);
610  } catch (std::out_of_range range) {
611  break;
612  }
613 
614  if (ss->current_hits <= 0) {
615  ss->submodel_info_1.blown_off = 1;
616  }
617 
618  ss = GET_NEXT( ss );
619  count++;
620  }
621 
622  list_size = (int)ras->subsys_aggregate_current_hits.size();
623  CLAMP(list_size, 0, SUBSYSTEM_MAX);
624  for (i = 0; i < list_size; i++) {
625  shipp->subsys_info[i].aggregate_current_hits = ras->subsys_aggregate_current_hits[i];
626  }
627 }
628 
629 extern int insert_subsys_status(p_object *pobjp);
630 
631 void red_alert_bash_subsys_status(red_alert_ship_status *ras, p_object *pobjp)
632 {
633  int i, j;
634  ship_info *sip;
635  model_subsystem *psub = NULL;
636  subsys_status *sssp = NULL;
637 
638  // restore from ship_exited
639  if ( (ras->ship_class == RED_ALERT_DESTROYED_SHIP_CLASS) || (ras->ship_class == RED_ALERT_PLAYER_DEL_SHIP_CLASS) )
640  return;
641  sip = &Ship_info[ras->ship_class];
642 
643  // do this differently than the other bash_subsys_status... since the p_object may not contain
644  // all the subsystems, iterate on the red_alert_ship_status entries rather than the p_object's
645  // and create missing subsystems where necessary
646  for (i = 0; i < (int) ras->subsys_current_hits.size(); i++)
647  {
648  psub = &sip->subsystems[i];
649 
650  // in the p_object, subsystem 0 is the pilot, and afterwards the subsystems go in order
651  j = i + 1;
652 
653  // this subsystem is in the p_object
654  if (j < pobjp->subsys_count)
655  {
656  sssp = &Subsys_status[pobjp->subsys_index + j];
657  }
658  // must create subsystem (same technique as in parse_copy_damage)
659  else
660  {
661  // jam in the new subsystem at the end of the existing list for this parse object
662  int new_idx = insert_subsys_status(pobjp);
663  Assert(new_idx == pobjp->subsys_index + j);
664  sssp = &Subsys_status[new_idx];
665 
666  strcpy_s(sssp->name, psub->subobj_name);
667  }
668 
669  float max_hits = psub->max_subsys_strength * (pobjp->ship_max_hull_strength / sip->max_hull_strength);
670 
671  float current_hits = ras->subsys_current_hits[i];
672 
673  sssp->percent = 100.0f * (max_hits - current_hits) / max_hits;
674  }
675 }
676 
677 void red_alert_store_subsys_status(red_alert_ship_status *ras, ship *shipp)
678 {
679  ship_subsys *ss;
680  int i;
681 
682  // Make sure there isn't any data from the previous ship.
683  ras->subsys_current_hits.clear();
684  ras->subsys_aggregate_current_hits.clear();
685 
686  if (shipp == NULL) {
687  return;
688  }
689 
690  ss = GET_FIRST(&shipp->subsys_list);
691  while ( ss != END_OF_LIST( &shipp->subsys_list ) ) {
692  ras->subsys_current_hits.push_back( ss->current_hits );
693 
694  ss = GET_NEXT( ss );
695  }
696 
697  for (i = 0; i < SUBSYSTEM_MAX; i++)
698  // Pyro3d - Fixes AP8 Based RA crashes
699  ras->subsys_aggregate_current_hits.push_back(shipp->subsys_info[i].aggregate_current_hits);
700 }
701 
702 
703 /*
704  * Record the current state of the players wingman & ships with the "red-alert-carry" flag
705  * Wingmen without the red-alert-carry flag are only stored if they survive
706  * dead wingmen must still be handled in red_alert_bash_wingman_status
707  */
709 {
710  ship *shipp;
711  red_alert_ship_status ras;
712  ship_obj *so;
713  object *ship_objp;
714 
715  // store the mission filename for the red alert precursor mission
717 
718  // Pyro3d - Clear list of stored red alert ships
719  // Probably not the best solution, but it prevents an assertion in change_ship_type()
720  Red_alert_wingman_status.clear();
721 
722  // store status for all existing ships
723  for ( so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so) ) {
724  ship_objp = &Objects[so->objnum];
725  Assert(ship_objp->type == OBJ_SHIP);
726  shipp = &Ships[ship_objp->instance];
727 
728  if ( shipp->flags & SF_DYING ) {
729  continue;
730  }
731 
732  if ( !(shipp->flags & SF_FROM_PLAYER_WING) && !(shipp->flags & SF_RED_ALERT_STORE_STATUS) ) {
733  continue;
734  }
735 
736  ras.name = shipp->ship_name;
737  ras.hull = Objects[shipp->objnum].hull_strength;
738  ras.ship_class = shipp->ship_info_index;
739  red_alert_store_weapons(&ras, &shipp->weapons);
740  red_alert_store_subsys_status(&ras, shipp);
741 
742  Red_alert_wingman_status.push_back( ras );
743  // niffiwan: trying to track down red alert bug creating HUGE pilot files
744  Assert( (Red_alert_wingman_status.size() <= MAX_SHIPS) );
745  }
746 
747  // store exited ships that did not die
748  for (int idx=0; idx<(int)Ships_exited.size(); idx++) {
750  ras.name = Ships_exited[idx].ship_name;
751  ras.hull = float(Ships_exited[idx].hull_strength);
752 
753  // if a ship has been destroyed or removed manually by the player, then mark it as such ...
754  if ( Ships_exited[idx].flags & SEF_DESTROYED ) {
755  ras.ship_class = RED_ALERT_DESTROYED_SHIP_CLASS;
756  }
758  ras.ship_class = RED_ALERT_PLAYER_DEL_SHIP_CLASS;
759  }
760  // ... otherwise we want to make sure and carry over the ship class
761  else {
762  Assert( Ships_exited[idx].ship_class >= 0 );
763  ras.ship_class = Ships_exited[idx].ship_class;
764  }
765 
766  red_alert_store_weapons(&ras, NULL);
767  red_alert_store_subsys_status(&ras, NULL);
768 
769  Red_alert_wingman_status.push_back( ras );
770  // niffiwan: trying to track down red alert bug creating HUGE pilot files
771  Assert( (Red_alert_wingman_status.size() <= MAX_SHIPS) );
772  }
773  }
774 
775  Assert( !Red_alert_wingman_status.empty() );
776 }
777 
778 // Delete a ship in a red alert mission (since it must have died/departed in the previous mission)
779 void red_alert_delete_ship(ship *shipp, int ship_state)
780 {
781  if ( (shipp->wing_status_wing_index >= 0) && (shipp->wing_status_wing_pos >= 0) ) {
782  if (ship_state == RED_ALERT_DESTROYED_SHIP_CLASS) {
784  } else if (ship_state == RED_ALERT_PLAYER_DEL_SHIP_CLASS) {
786  } else {
787  Error(LOCATION, "Red Alert: asked to delete ship (%s) with invalid ship state (%d)", shipp->ship_name, ship_state);
788  }
789  }
790 
792  obj_delete(shipp->objnum);
793  if ( shipp->wingnum >= 0 ) {
794  ship_wing_cleanup( shipp-Ships, &Wings[shipp->wingnum] );
795  }
796 }
797 
798 // just mark the parse object as never going to arrive
799 void red_alert_delete_ship(p_object *pobjp, int ship_state)
800 {
801  if (ship_state == RED_ALERT_DESTROYED_SHIP_CLASS || ship_state == RED_ALERT_PLAYER_DEL_SHIP_CLASS)
802  {
803  pobjp->flags2 |= P2_RED_ALERT_DELETED;
804 
805  if (pobjp->wingnum < 0)
806  pobjp->flags |= P_SF_CANNOT_ARRIVE;
807  }
808  else
809  Error(LOCATION, "Red Alert: asked to delete ship (%s) with invalid ship state (%d)", pobjp->name, ship_state);
810 }
811 
812 /*
813  * Take the red alert status information, and adjust the red alert ships accordingly
814  * "red alert ships" are wingmen and any ship with the red-alert-carry flag
815  * Wingmen without red alert data still need to be handled / removed
816  */
818 {
819  int j;
820  ship_obj *so;
821 
824 
825  SCP_unordered_map<int, int> Wing_pobjects_deleted;
827 
828  if ( !(Game_mode & GM_CAMPAIGN_MODE) ) {
829  return;
830  }
831 
832  if ( Red_alert_wingman_status.empty() ) {
833  return;
834  }
835 
836  // go through all ships in the game, and see if there is red alert status data for any
837 
838  so = GET_FIRST(&Ship_obj_list);
839  for ( ; so != END_OF_LIST(&Ship_obj_list); )
840  {
841  object *ship_objp = &Objects[so->objnum];
842  Assert(ship_objp->type == OBJ_SHIP);
843  ship *shipp = &Ships[ship_objp->instance];
844 
845  if ( !(shipp->flags & SF_FROM_PLAYER_WING) && !(shipp->flags & SF_RED_ALERT_STORE_STATUS) ) {
846  so = GET_NEXT(so);
847  continue;
848  }
849 
850  bool ship_data_restored = false;
851  int ship_state = RED_ALERT_DESTROYED_SHIP_CLASS;
852 
853  for ( rasii = Red_alert_wingman_status.begin(); rasii != Red_alert_wingman_status.end(); ++rasii )
854  {
855  red_alert_ship_status *ras = &(*rasii);
856 
857  // red-alert data matches this ship!
858  if ( !stricmp(ras->name.c_str(), shipp->ship_name) )
859  {
860  // we only want to restore ships which haven't been destroyed, or were removed by the player
861  if ( (ras->ship_class != RED_ALERT_DESTROYED_SHIP_CLASS) && (ras->ship_class != RED_ALERT_PLAYER_DEL_SHIP_CLASS) )
862  {
863  // if necessary, restore correct ship class
864  if ( ras->ship_class != shipp->ship_info_index )
865  {
866  if (ras->ship_class >= 0 && ras->ship_class < static_cast<int>(Ship_info.size()))
867  change_ship_type(SHIP_INDEX(shipp), ras->ship_class);
868  else
869  mprintf(("Invalid ship class specified in red alert data for ship %s. Using mission defaults.\n", shipp->ship_name));
870  }
871 
872  // restore hull (but not shields)
873  if (ras->hull >= 0.0f && ras->hull <= ship_objp->hull_strength)
874  ship_objp->hull_strength = ras->hull;
875  else
876  mprintf(("Invalid health in red alert data for ship %s. Using mission defaults.\n", shipp->ship_name));
877 
878  // restore weapons and subsys
879  red_alert_bash_weapons(ras, &shipp->weapons);
880  red_alert_bash_subsys_status(ras, shipp);
881 
882  ship_data_restored = true;
883  }
884  // must be destroyed or deleted
885  else
886  {
887  ship_state = ras->ship_class;
888  }
889 
890  // we won't have two ships with the same name, so bail
891  break;
892  }
893  }
894 
895  // remove ship if it was destroyed, or if there's no red-alert data for it
896  if ( !ship_data_restored ) {
897  // we need to be a little tricky here because deletion invalidates the ship_obj
898  ship_obj *next_so = GET_NEXT(so);
899  red_alert_delete_ship(shipp, ship_state);
900  so = next_so;
901  } else {
902  so = GET_NEXT(so);
903  }
904  }
905 
906  // NOTE: in retail, red alert data was not loaded for ships that arrived later in the mission
908  return;
909 
910  // go through all ships yet to arrive, and see if there is red alert status data for any
911 
912  for ( poii = Parse_objects.begin(); poii != Parse_objects.end(); ++poii )
913  {
914  p_object *pobjp = &(*poii);
915 
916  // objects that have already arrived would have been handled in the above loop
917  if ( pobjp->created_object != NULL )
918  continue;
919 
920  // if we're in a wing, check whether we're in the player wing
921  bool from_player_wing = false;
922  if (pobjp->wingnum >= 0)
923  {
924  for (j = 0; j < MAX_STARTING_WINGS; j++)
925  {
926  if (!stricmp(Starting_wing_names[j], Wings[pobjp->wingnum].name))
927  {
928  from_player_wing = true;
929  break;
930  }
931  }
932  }
933 
934  // same condition as in ship_obj loop
935  if ( !from_player_wing && !(pobjp->flags & P_SF_RED_ALERT_STORE_STATUS) ) {
936  continue;
937  }
938 
939  bool ship_data_restored = false;
940  int ship_state = RED_ALERT_DESTROYED_SHIP_CLASS;
941 
942  for ( rasii = Red_alert_wingman_status.begin(); rasii != Red_alert_wingman_status.end(); ++rasii )
943  {
944  red_alert_ship_status *ras = &(*rasii);
945 
946  // red-alert data matches this ship!
947  if ( !stricmp(ras->name.c_str(), pobjp->name) )
948  {
949  // we only want to restore ships which haven't been destroyed, or were removed by the player
950  if ( (ras->ship_class != RED_ALERT_DESTROYED_SHIP_CLASS) && (ras->ship_class != RED_ALERT_PLAYER_DEL_SHIP_CLASS) )
951  {
952  // if necessary, restore correct ship class
953  if ( ras->ship_class != pobjp->ship_class )
954  {
955  if (ras->ship_class >= 0 && ras->ship_class < static_cast<int>(Ship_info.size()))
956  swap_parse_object(pobjp, ras->ship_class);
957  else
958  {
959  mprintf(("Invalid ship class specified in red alert data for ship %s. Using mission defaults.\n", pobjp->name));
960 
961  // We will break anyway to this should work
962  break;
963  }
964  }
965 
966  // restore hull (but not shields)
967  if (ras->hull >= 0.0f && ras->hull <= (pobjp->initial_hull * pobjp->ship_max_hull_strength / 100.0f))
968  pobjp->initial_hull = (int) (ras->hull * 100.0f / pobjp->ship_max_hull_strength);
969  else
970  mprintf(("Invalid health in red alert data for ship %s. Using mission defaults.\n", pobjp->name));
971 
972  // restore weapons and subsys
973  red_alert_bash_weapons(ras, pobjp);
974  red_alert_bash_subsys_status(ras, pobjp);
975 
976  ship_data_restored = true;
977  }
978  // must be destroyed or deleted
979  else
980  {
981  ship_state = ras->ship_class;
982  }
983 
984  // we won't have two ships with the same name, so bail
985  break;
986  }
987  }
988 
989  // remove ship if it was destroyed, or if there's no red-alert data for it
990  if ( !ship_data_restored )
991  {
992  red_alert_delete_ship(pobjp, ship_state);
993 
994  if (pobjp->wingnum >= 0)
995  Wing_pobjects_deleted[pobjp->wingnum]++;
996  }
997  }
998 
999  // if all parse objects in a wing have been removed, decrement the count for that wing
1000  for (ii = Wing_pobjects_deleted.begin(); ii != Wing_pobjects_deleted.end(); ++ii)
1001  {
1002  wing *wingp = &Wings[ii->first];
1003 
1004  if (wingp->num_waves > 0 && wingp->wave_count == ii->second)
1005  {
1006  wingp->current_wave++;
1007  wingp->red_alert_skipped_ships += wingp->wave_count;
1008 
1009  if (wingp->num_waves == 0)
1010  wingp->flags |= WF_WING_GONE;
1011 
1012  // look through all ships yet to arrive...
1013  for (p_object *pobjp = GET_FIRST(&Ship_arrival_list); pobjp != END_OF_LIST(&Ship_arrival_list); pobjp = GET_NEXT(pobjp))
1014  {
1015  // ...and mark the ones in this wing
1016  if (pobjp->wingnum == ii->first)
1017  {
1018  // no waves left to arrive, so mark ships accordingly
1019  if (wingp->num_waves == 0)
1020  pobjp->flags |= P_SF_CANNOT_ARRIVE;
1021  // we skipped one complete wave, so clear the flag so the next wave creates all ships
1022  else
1023  pobjp->flags2 &= ~P2_RED_ALERT_DELETED;
1024  }
1025  }
1026  }
1027  }
1028 }
1029 
1030 // return !0 if this is a red alert mission, otherwise return 0
1032 {
1034 }
1035 
1036 // called from sexpression code to start a red alert mission
1038 {
1039  // if we are not in campaign mode, go to debriefing
1040 // if ( !(Game_mode & GM_CAMPAIGN_MODE) ) {
1041 // gameseq_post_event( GS_EVENT_DEBRIEF ); // proceed to debriefing
1042 // return;
1043 // }
1044 
1045  // check player health here.
1046  // if we're dead (or about to die), don't start red alert mission.
1047  if (Player_obj->type == OBJ_SHIP) {
1048  if (Player_obj->hull_strength > 0) {
1049  // make sure we don't die
1051 
1052  // do normal red alert stuff
1053  Red_alert_new_mission_timestamp = timestamp(RED_ALERT_WARN_TIME);
1054 
1055  // throw down a sound here to make the warning seem ultra-important
1056  // gamesnd_play_iface(SND_USER_SELECT);
1058  }
1059  }
1060 }
1061 
1062 // called from HUD code to see if we're red-alerting
1064 {
1065  // it is specifically a question of whether the timestamp is running
1066  return timestamp_valid(Red_alert_new_mission_timestamp);
1067 }
1068 
1069 // called from the game loop to check if we should actually do the red-alert
1071 {
1072  // if the timestamp is invalid, do nothing.
1073  if ( !timestamp_valid(Red_alert_new_mission_timestamp) )
1074  return;
1075 
1076  // return if the timestamp hasn't elapsed yet
1077  if ( !timestamp_elapsed(Red_alert_new_mission_timestamp) )
1078  return;
1079 
1080  // basic premise here is to stop the current mission, and then set the next mission in the campaign
1081  // which better be a red alert mission
1082  if ( Game_mode & GM_CAMPAIGN_MODE ) {
1089 
1090  // CD CHECK
1092  } else {
1094  }
1095 }
1096 
1097 /*
1098  * red_alert_clear()
1099  *
1100  * clear all red alert "wingman" data
1101  * Allows data to be cleared from outside REDALERT_INTERNAL code
1102  */
1104 {
1105  Red_alert_wingman_status.clear();
1106 }
void game_flush()
Definition: fredstubs.cpp:83
void ship_wing_cleanup(int shipnum, wing *wingp)
Definition: ship.cpp:7640
void red_alert_voice_pause()
Definition: redalert.cpp:201
void set_highlight_action(void(*_user_function)(void))
Definition: button.cpp:375
void hud_set_wingman_status_none(int wing_index, int wing_pos)
char Starting_wing_names[MAX_STARTING_WINGS][NAME_LENGTH]
Definition: ship.cpp:139
void red_alert_do_frame(float frametime)
Definition: redalert.cpp:381
int Ra_flash_up
Definition: redalert.cpp:262
int timestamp(int delta_ms)
Definition: timer.cpp:226
wing Wings[MAX_WINGS]
Definition: ship.cpp:128
void fsspeech_pause(bool playing)
Definition: fsspeech.h:46
int secondary_ammo[MAX_SHIP_SECONDARY_BANKS]
Definition: missionparse.h:318
int i
Definition: multi_pxo.cpp:466
char wing_status_wing_pos
Definition: ship.h:553
int Briefing_voice_enabled
void mouse_set_pos(int xpos, int ypos)
Definition: mouse.cpp:604
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 primary_bank_weapons[MAX_SHIP_PRIMARY_BANKS]
Definition: ship.h:103
char name[NAME_LENGTH]
Definition: missionparse.h:346
#define MAX_SHIP_PRIMARY_BANKS
Definition: globals.h:62
void fsspeech_stop()
Definition: fsspeech.h:45
int num_primary_banks
Definition: ship.h:99
int objnum
Definition: ship.h:537
int Game_mode
Definition: systemvars.cpp:24
GLfloat GLfloat GLfloat GLfloat h
Definition: Glext.h:7280
void gr_flip()
Definition: 2d.cpp:2113
#define RA_REPLAY_MISSION
Definition: redalert.cpp:89
int x
Definition: ui.h:658
char Game_current_mission_filename[MAX_FILENAME_LEN]
Definition: fredstubs.cpp:26
weapon_info Weapon_info[MAX_WEAPON_TYPES]
Definition: weapons.cpp:79
ship_weapon weapons
Definition: ship.h:658
int insert_subsys_status(p_object *pobjp)
#define GR_RESIZE_MENU
Definition: 2d.h:684
SCP_vector< game_snd > Snds
Definition: gamesnd.cpp:19
submodel_instance_info submodel_info_1
Definition: ship.h:368
float flFrametime
Definition: fredstubs.cpp:22
void red_alert_voice_load()
Definition: redalert.cpp:143
int y
Definition: ui.h:658
char wing_status_wing_index
Definition: ship.h:552
#define ASF_VOICE
Definition: audiostr.h:21
void red_alert_button_pressed(int n)
Definition: redalert.cpp:226
int index
Definition: pstypes.h:213
SCP_vector< p_object > Parse_objects
#define MAX_SHIPS
Definition: globals.h:37
int brief_color_text_init(const char *src, int w, const char default_color, int instance, int max_lines, const bool append)
void swap_parse_object(p_object *p_obj, int new_ship_class)
#define WF_WING_GONE
Definition: ship.h:1501
brief_stage stages[MAX_BRIEF_STAGES]
void ship_add_exited_ship(ship *sp, int reason)
Definition: ship.cpp:5298
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
Assert(pm!=NULL)
void red_alert_store_subsys_status(red_alert_ship_status *ras, ship *shipp)
Definition: redalert.cpp:677
#define GR_NUM_RESOLUTIONS
Definition: 2d.h:651
#define mprintf(args)
Definition: pstypes.h:238
SCP_string Red_alert_precursor_mission
Definition: redalert.cpp:49
void gr_init_alphacolor(color *clr, int r, int g, int b, int alpha, int type)
Definition: 2d.cpp:1173
__inline void gr_string(int x, int y, const char *string, int resize_mode=GR_RESIZE_FULL)
Definition: 2d.h:769
int Ra_flash_font[GR_NUM_RESOLUTIONS]
Definition: redalert.cpp:66
#define RA_FLASH_CYCLE
Definition: redalert.cpp:260
int secondary_banks[MAX_SHIP_SECONDARY_BANKS]
Definition: missionparse.h:317
general failure sound for any event
Definition: gamesnd.h:297
Definition: 2d.h:95
int res
Definition: 2d.h:370
int max_h_unscaled
Definition: 2d.h:361
GLclampf f
Definition: Glext.h:7097
#define SHIP_INDEX(shipp)
Definition: ship.h:1602
int red_alert_in_progress()
Definition: redalert.cpp:1063
#define SEF_PLAYER_DELETED
Definition: ship.h:849
char background[GR_NUM_RESOLUTIONS][MAX_FILENAME_LEN]
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
int ship_class
Definition: missionparse.h:351
Definition: ship.h:1516
#define P2_RED_ALERT_DELETED
Definition: missionparse.h:517
SCP_vector< red_alert_ship_status > Red_alert_wingman_status
Definition: redalert.cpp:48
void red_alert_store_wingman_status()
Definition: redalert.cpp:708
void gr_set_color_fast(color *dst)
Definition: 2d.cpp:1197
uint flags
Definition: ship.h:644
void mission_campaign_mission_over(bool do_next_mission)
float Ra_flash_time
Definition: redalert.cpp:261
void weapon_select_close_team()
UI_XSTR Red_alert_text[GR_NUM_RESOLUTIONS][RED_ALERT_NUM_TEXT]
Definition: redalert.cpp:104
std::basic_string< char, std::char_traits< char >, std::allocator< char > > SCP_string
Definition: vmallocator.h:21
void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
Definition: 2d.cpp:2105
int max_w_unscaled
Definition: 2d.h:361
#define Int3()
Definition: pstypes.h:292
briefing Briefings[MAX_TVT_TEAMS]
ship * shipp
Definition: lua.cpp:9162
ship_subsys_info subsys_info[SUBSYSTEM_MAX]
Definition: ship.h:632
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 red_alert_voice_stop()
Definition: redalert.cpp:188
#define RA_X_COORD
Definition: redalert.cpp:118
#define SHIP_GUARDIAN_THRESHOLD_DEFAULT
Definition: ship.h:47
#define CLAMP(x, min, max)
Definition: pstypes.h:488
int audiostream_is_playing(int i)
Definition: audiostr.cpp:1827
void red_alert_delete_ship(ship *shipp, int ship_state)
Definition: redalert.cpp:779
int objnum
Definition: ship.h:1483
ship_subsys subsys_list
Definition: ship.h:630
char name[NAME_LENGTH]
Definition: missionparse.h:313
void destroy()
Definition: window.cpp:189
void red_alert_voice_unpause()
Definition: redalert.cpp:213
int mission_campaign_previous_mission()
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
#define MAX_SHIP_SECONDARY_BANKS
Definition: globals.h:63
int instance
Definition: object.h:150
void set_mask_bmap(char *fname)
Definition: window.cpp:75
#define MISSION_FLAG_NO_BRIEFING
Definition: missionparse.h:78
int set_bmaps(char *ani_filename, int nframes=3, int start_frame=1)
Definition: gadget.cpp:71
void red_alert_start_mission()
Definition: redalert.cpp:1037
GLenum GLint * range
Definition: Glext.h:7096
char voice[MAX_FILENAME_LEN]
void common_free_interface_palette()
void mission_parse_fixup_players()
#define SEF_DESTROYED
Definition: ship.h:846
#define P_SF_RED_ALERT_STORE_STATUS
Definition: missionparse.h:463
#define GM_MULTIPLAYER
Definition: systemvars.h:18
float cargo_size
Definition: weapon.h:388
void audiostream_stop(int i, int rewind, int paused)
Definition: audiostr.cpp:1840
void scoring_level_close(int accepted)
Definition: scoring.cpp:432
int primary_bank_ammo[MAX_SHIP_PRIMARY_BANKS]
Definition: ship.h:121
char name[NAME_LENGTH]
Definition: ship.h:1517
#define MISSION_FLAG_RED_ALERT
Definition: missionparse.h:84
int wingnum
Definition: ship.h:623
#define strnicmp(s1, s2, n)
Definition: config.h:272
void red_alert_store_weapons(red_alert_ship_status *ras, ship_weapon *swp)
Definition: redalert.cpp:449
int hotspot
Definition: ui.h:659
void weapon_select_common_init()
#define MAX_STARTING_WINGS
Definition: globals.h:54
int num_secondary_banks
Definition: ship.h:100
int pressed()
Definition: button.cpp:325
float hull_strength
Definition: object.h:160
#define w(p)
Definition: modelsinc.h:68
float ship_max_hull_strength
Definition: missionparse.h:425
#define KEY_ENTER
Definition: key.h:125
int primary_banks[MAX_SHIP_PRIMARY_BANKS]
Definition: missionparse.h:315
int subsys_index
Definition: missionparse.h:363
#define NUM_BUTTONS
Definition: redalert.cpp:87
#define SEF_RED_ALERT_CARRY
Definition: ship.h:851
int snd_play(game_snd *gs, float pan, float vol_scale, int priority, bool is_voice_msg)
Definition: sound.cpp:517
#define P_SF_CANNOT_ARRIVE
Definition: missionparse.h:478
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:104
#define RA_H_COORD
Definition: redalert.cpp:121
void ai_post_process_mission()
Definition: aigoals.cpp:159
char * Red_alert_mask[GR_NUM_RESOLUTIONS]
Definition: redalert.cpp:60
float aggregate_current_hits
Definition: ship.h:419
UI_BUTTON button
Definition: ui.h:660
float current_hits
Definition: ship.h:319
int secondary_bank_ammo_capacity[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:1300
void red_alert_init()
Definition: redalert.cpp:297
Definition: ship.h:534
float max_subsys_strength
Definition: model.h:180
void red_alert_maybe_move_to_next_mission()
Definition: redalert.cpp:1070
void fsspeech_play(int type, const char *text)
Definition: fsspeech.h:44
int idx
Definition: multiui.cpp:761
int secondary_bank_ammo[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:134
void audiostream_unpause(int i, bool via_sexp_or_script)
Definition: audiostr.cpp:1960
int primary_bank_ammo_capacity[MAX_SHIP_PRIMARY_BANKS]
Definition: ship.h:1296
void ship_select_common_init()
int wave_count
Definition: ship.h:1527
object Objects[MAX_OBJECTS]
Definition: object.cpp:62
GLclampd n
Definition: Glext.h:7286
void red_alert_voice_unload()
Definition: redalert.cpp:152
const char * XSTR(const char *str, int index)
Definition: localize.cpp:851
ship * Player_ship
Definition: ship.cpp:124
void red_alert_bash_weapons(red_alert_ship_status *ras, ship_weapon *swp)
Definition: redalert.cpp:499
int num_waves
Definition: ship.h:1522
int red_alert_skipped_ships
Definition: ship.h:1529
int ship_guardian_threshold
Definition: ship.h:601
int max_w
Definition: 2d.h:360
int wi_flags2
Definition: weapon.h:385
#define NOX(s)
Definition: pstypes.h:473
#define OBJ_SHIP
Definition: object.h:32
void _cdecl void void _cdecl Error(const char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
void red_alert_clear()
Definition: redalert.cpp:1103
GLbitfield flags
Definition: Glext.h:6722
#define RA_W_COORD
Definition: redalert.cpp:120
void set_hotkey(int keycode)
Definition: gadget.cpp:280
void red_alert_blit_title()
Definition: redalert.cpp:263
void mission_goal_fail_incomplete()
#define SF_RED_ALERT_STORE_STATUS
Definition: ship.h:469
object * created_object
Definition: missionparse.h:396
GLboolean GLboolean GLboolean b
Definition: Glext.h:5781
ship Ships[MAX_SHIPS]
Definition: ship.cpp:122
void audiostream_close_file(int i, int fade)
Definition: audiostr.cpp:1772
briefing * Briefing
bool fsspeech_play_from(int type)
Definition: fsspeech.h:52
int initial_hull
Definition: missionparse.h:366
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
void mission_campaign_eval_next_mission()
void obj_delete(int objnum)
Definition: object.cpp:522
#define FONT1
Definition: font.h:65
void mission_campaign_store_goals_and_events_and_variables()
void red_alert_bash_subsys_status(red_alert_ship_status *ras, ship *shipp)
Definition: redalert.cpp:593
void link_hotspot(int num)
Definition: gadget.cpp:50
#define RED_ALERT_NUM_TEXT
Definition: redalert.cpp:103
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 KEY_ESC
Definition: key.h:124
void red_alert_close()
Definition: redalert.cpp:356
#define UI_XSTR_COLOR_PINK
Definition: ui.h:161
#define FONT2
Definition: font.h:66
int red_alert_mission()
Definition: redalert.cpp:1031
#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
Definition: ui.h:584
screen gr_screen
Definition: 2d.cpp:46
void gr_get_string_size(int *w, int *h, const char *text, int len=9999)
Definition: font.cpp:196
directive complete
Definition: gamesnd.h:125
Definition: ui.h:162
void hud_set_wingman_status_dead(int wing_index, int wing_pos)
int current_wave
Definition: ship.h:1522
char subobj_name[MAX_NAME_LEN]
Definition: model.h:172
char default_redalert_briefing_color
Definition: alphacolors.cpp:43
void red_alert_voice_play()
Definition: redalert.cpp:161
ship_obj Ship_obj_list
Definition: ship.cpp:162
int ship_info_index
Definition: ship.h:539
#define KEY_DEBUGGED
Definition: key.h:65
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
int max_h
Definition: 2d.h:360
#define timestamp_elapsed(stamp)
Definition: timer.h:102
Definition: pstypes.h:212
int count
Definition: pstypes.h:214
char * Red_alert_fname[GR_NUM_RESOLUTIONS]
Definition: redalert.cpp:55
SCP_vector< exited_ship > Ships_exited
Definition: ship.cpp:152
void audiostream_play(int i, float volume, int looping)
Definition: audiostr.cpp:1803
#define KEY_CTRLED
Definition: key.h:64
color Color_normal
Definition: alphacolors.cpp:28
void change_ship_type(int n, int ship_type, int by_sexp)
Definition: ship.cpp:9983
void red_alert_invalidate_timestamp()
Definition: redalert.cpp:443
char * filename
Definition: ui.h:657
int brief_render_text(int line_offset, int x, int y, int h, float frametime, int instance, int line_spacing)
GLint GLsizei count
Definition: Gl.h:1491
void gr_bitmap(int _x, int _y, int resize_mode)
Definition: 2d.cpp:1303
p_object Ship_arrival_list
object * Player_obj
Definition: object.cpp:56
#define SF_DYING
Definition: ship.h:447
int mission_ui_background_load(const char *custom_background, const char *single_background, const char *multi_background)
int audiostream_open(const char *filename, int type)
Definition: audiostr.cpp:1713
#define WIF2_BALLISTIC
Definition: weapon.h:84
subsys_status * Subsys_status
float max_hull_strength
Definition: ship.h:1309
void audiostream_pause(int i, bool via_sexp_or_script)
Definition: audiostr.cpp:1943
#define RA_CONTINUE
Definition: redalert.cpp:90
#define SUBSYSTEM_MAX
Definition: model.h:64
void gamesnd_play_iface(int n)
Definition: gamesnd.cpp:260
bool fsspeech_playing()
Definition: fsspeech.h:53
mission The_mission
void draw()
Definition: window.cpp:220
struct ui_button_info ui_button_info
void gr_set_font(int fontnum)
Definition: font.cpp:566
bool Red_alert_applies_to_delayed_ships
Definition: mod_table.cpp:35
char type
Definition: object.h:146
int Ra_brief_text_wnd_coords[GR_NUM_RESOLUTIONS][4]
Definition: redalert.cpp:126
void red_alert_bash_wingman_status()
Definition: redalert.cpp:817
int subsys_count
Definition: missionparse.h:364
#define SF_FROM_PLAYER_WING
Definition: ship.h:457
int process(int key_in=-1, int process_mouse=1)
Definition: window.cpp:401
void gameseq_post_event(int event)
#define RA_Y_COORD
Definition: redalert.cpp:119
#define GM_CAMPAIGN_MODE
Definition: systemvars.h:29
#define stricmp(s1, s2)
Definition: config.h:271
#define timestamp_valid(stamp)
Definition: timer.h:104
char ship_name[NAME_LENGTH]
Definition: ship.h:604
float Master_voice_volume
Definition: sound.cpp:54
int Ra_flash_y[GR_NUM_RESOLUTIONS]
Definition: redalert.cpp:71
int flags
Definition: ship.h:1556
#define strcpy_s(...)
Definition: safe_strings.h:67