FS2_Open
Open source remastering of the Freespace 2 engine
management.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 "stdafx.h"
13 #include "FRED.h"
14 #include "MainFrm.h"
15 #include "FREDDoc.h"
16 #include "FREDView.h"
17 #include "FredRender.h"
18 #include "ai/aigoals.h"
19 #include "ship/ship.h"
20 #include "globalincs/linklist.h"
21 #include "globalincs/version.h"
22 #include "globalincs/alphacolors.h"
23 #include "mission/missionparse.h"
24 #include "mission/missionmessage.h"
25 #include "mission/missiongoals.h"
27 #include "Management.h"
28 #include "cfile/cfile.h"
29 #include "palman/palman.h"
30 #include "graphics/2d.h"
31 #include "render/3d.h"
32 #include "weapon/weapon.h"
33 #include "io/key.h"
34 #include "parse/parselo.h"
35 #include "math/fvi.h"
36 #include "starfield/starfield.h"
37 #include "parse/sexp.h"
38 #include "io/mouse.h"
40 #include "wing.h"
41 #include "MessageEditorDlg.h"
42 #include "EventEditor.h"
43 #include "MissionGoalsDlg.h"
44 #include "ShieldSysDlg.h"
45 #include "gamesnd/eventmusic.h"
46 #include "DebriefingEditorDlg.h"
47 #include "starfield/nebula.h"
48 #include "asteroid/asteroid.h"
49 #include "hud/hudsquadmsg.h"
50 #include "jumpnode/jumpnode.h"
51 #include "stats/medals.h"
52 #include "localization/localize.h"
53 #include "osapi/osregistry.h"
54 #include "localization/fhash.h"
55 #include "io/timer.h"
56 #include "nebula/neb.h"
57 #include "nebula/neblightning.h"
59 #include "osapi/osapi.h"
60 #include "graphics/font.h"
61 #include "object/objectdock.h"
62 #include "gamesnd/gamesnd.h"
63 #include "iff_defs/iff_defs.h"
64 #include "menuui/techmenu.h"
66 #include "mod_table/mod_table.h"
67 
68 #include <direct.h>
69 #include "cmdline/cmdline.h"
70 
71 #define MAX_DOCKS 1000
72 
73 #define UNKNOWN_USER "Unknown"
74 
75 extern void ssm_init(); // Need this to populate Ssm_info so OPF_SSM_CLASS does something. -MageKing17
76 
77 int cur_wing = -1;
80 int cur_ship = -1;
85 int bypass_update = 0;
87 int Update_ship = 0;
88 int Update_wing = 0;
89 
90 char Fred_exe_dir[512] = "";
91 char Fred_base_dir[512] = "";
92 
95 
96 // object numbers for ships in a wing.
98 
100 
101 // Goober5000
103 
104 CCriticalSection CS_cur_object_index;
105 
107  { "Waypoints", AI_GOAL_WAYPOINTS, 0 },
108  { "Waypoints once", AI_GOAL_WAYPOINTS_ONCE, 0 },
109  { "Warp", AI_GOAL_WARP, 0 },
110  { "Destroy subsystem", AI_GOAL_DESTROY_SUBSYSTEM, 0 },
111  { "Attack", AI_GOAL_CHASE | AI_GOAL_CHASE_WING, 0 },
112  { "Dock", AI_GOAL_DOCK, 0 },
113  { "Undock", AI_GOAL_UNDOCK, 0 },
114  { "Guard", AI_GOAL_GUARD | AI_GOAL_GUARD_WING, 0 },
115  { "Attack any ship", AI_GOAL_CHASE_ANY, 0 },
116  { "Disable ship", AI_GOAL_DISABLE_SHIP, 0 },
117  { "Disarm ship", AI_GOAL_DISARM_SHIP, 0 },
118  { "Evade ship", AI_GOAL_EVADE_SHIP, 0 },
119  { "Ignore ship", AI_GOAL_IGNORE, 0 },
120  { "Ignore ship (new)", AI_GOAL_IGNORE_NEW, 0 },
121  { "Stay near ship", AI_GOAL_STAY_NEAR_SHIP, 0 },
122  { "Keep safe distance", AI_GOAL_KEEP_SAFE_DISTANCE, 0 },
123  { "Stay still", AI_GOAL_STAY_STILL, 0 },
124  { "Play dead", AI_GOAL_PLAY_DEAD, 0 }
125 };
126 
128 
129 // internal function prototypes
130 void set_cur_indices(int obj);
131 int common_object_delete(int obj);
132 int create_waypoint(vec3d *pos, int waypoint_instance);
133 int create_ship(matrix *orient, vec3d *pos, int ship_type);
135 char *reg_read_string( char *section, char *name, char *default_value );
136 
137 extern int Nmodel_num;
138 extern int Nmodel_instance_num;
139 extern matrix Nmodel_orient;
140 extern int Nmodel_bitmap;
141 
142 void string_copy(char *dest, const CString &src, int max_len, int modify)
143 {
144  int len;
145 
146  if (modify)
147  if (strcmp(src, dest))
148  set_modified();
149 
150  len = strlen(src);
151  if (len >= max_len)
152  len = max_len - 1;
153 
154  strncpy(dest, src, len);
155  dest[len] = 0;
156 }
157 
158 void string_copy(SCP_string &dest, const CString &src, int modify)
159 {
160  if (modify)
161  if (strcmp(src, dest.c_str()))
162  set_modified();
163 
164  dest = src;
165 }
166 
167 // converts a multiline string (one with newlines in it) into a windows format multiline
168 // string (newlines changed to '\r\n').
169 void convert_multiline_string(CString &dest, const SCP_string &src)
170 {
171  dest = src.c_str();
172  dest.Replace("\n", "\r\n");
173 }
174 
175 // converts a multiline string (one with newlines in it) into a windows format multiline
176 // string (newlines changed to '\r\n').
177 void convert_multiline_string(CString &dest, const char *src)
178 {
179  dest = src;
180  dest.Replace("\n", "\r\n");
181 }
182 
183 // Converts a windows format multiline CString back into a normal multiline string.
184 void deconvert_multiline_string(char *dest, const CString &str, int max_len)
185 {
186  // leave room for the null terminator
187  memset(dest, 0, max_len);
188  strncpy(dest, (LPCTSTR) str, max_len - 1);
189 
190  replace_all(dest, "\r\n", "\n", max_len);
191 }
192 
193 // ditto for SCP_string
194 void deconvert_multiline_string(SCP_string &dest, const CString &str)
195 {
196  dest = str;
197  replace_all(dest, "\r\n", "\n");
198 }
199 
200 // medal_stuff Medals[NUM_MEDALS];
201 /*
202 void parse_medal_tbl()
203 {
204  int rval, num_medals;
205 
206  // open localization
207  lcl_ext_open();
208 
209  if ((rval = setjmp(parse_abort)) != 0) {
210  mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "medals.tbl", rval));
211  lcl_ext_close();
212  return;
213  }
214 
215  read_file_text("medals.tbl");
216  reset_parse();
217 
218  // parse in all the rank names
219  num_medals = 0;
220  required_string("#Medals");
221  while ( required_string_either("#End", "$Name:") ) {
222  Assert ( num_medals < NUM_MEDALS);
223  required_string("$Name:");
224  stuff_string( Medals[num_medals].name, F_NAME, NULL );
225  required_string("$Bitmap:");
226  stuff_string( Medals[num_medals].bitmap, F_NAME, NULL );
227  required_string("$Num mods:");
228  stuff_int( &Medals[num_medals].num_versions);
229 
230  // some medals are based on kill counts. When string +Num Kills: is present, we know that
231  // this medal is a badge and should be treated specially
232  Medals[num_medals].kills_needed = 0;
233 
234  if ( optional_string("+Num Kills:") ) {
235  char buf[MULTITEXT_LENGTH + 1];
236 
237  stuff_int( &Medals[num_medals].kills_needed );
238 
239  required_string("$Wavefile 1:");
240  stuff_string(buf, F_NAME, NULL, MAX_FILENAME_LEN);
241 
242  required_string("$Wavefile 2:");
243  stuff_string(buf, F_NAME, NULL, MAX_FILENAME_LEN);
244 
245  required_string("$Promotion Text:");
246  stuff_string(buf, F_MULTITEXT, NULL);
247  }
248 
249  num_medals++;
250  }
251 
252  required_string("#End");
253 
254  // close localization
255  lcl_ext_close();
256 }
257 */
258 
259 void parse_init(bool basic = false);
260 void brief_init_colors();
261 
263 {
265  {
266  generic_anim_load(&ii->regular);
267  hud_anim_load(&ii->fade);
268  hud_anim_load(&ii->highlight);
269  }
270 }
271 
272 bool fred_init()
273 {
274  int i;
275  char palette_filename[1024];
276 
277  if (!vm_init(24*1024*1024)) {
278  MessageBox( NULL, "Not enough memory to run Fred.\r\nTry closing down some other applications.\r\n", "Not Enough Memory", MB_OK );
279  return false;
280  }
281 
282  srand( (unsigned) time(NULL) );
284 
285  // initialize registry stuff
287 
288  timer_init();
289 
290  Assert(strlen(Fred_base_dir) > 0); //-V805
291 
292  // sigh... this should enable proper reading of cmdline_fso.cfg - Goober5000
294 
295  // this should enable mods - Kazan
296  fred2_parse_cmdline(__argc, __argv);
297 
298 #ifndef NDEBUG
299  #if FS_VERSION_REVIS == 0
300  mprintf(("Fred2 Open version: %i.%i.%i\n", FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD));
301  #else
302  mprintf(("Fred2 Open version: %i.%i.%i.%i\n", FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD, FS_VERSION_REVIS));
303  #endif
304 
305  extern void cmdline_debug_print_cmdline();
307 #endif
308 
309  // d'oh
311  exit(1);
312  }
313 
314  // Load game_settings.tbl
315  mod_table_init();
316 
317  // initialize localization module. Make sure this is done AFTER initialzing OS.
318  // NOTE : Fred should ALWAYS run in English. Otherwise it might swap in another language
319  // when saving - which would cause inconsistencies when externalizing to tstrings.tbl via Exstr
320  // trust me on this :)
322 
323  // Goober5000 - force init XSTRs (so they work, but only work in English, based on above comment)
324  extern int Xstr_inited;
325  Xstr_inited = 1;
326 
327 #ifndef NDEBUG
329 #endif
330 
331  //CFREDView *window = CFREDView::GetView();
332  //HWND hwndApp = window->GetSafeHwnd();
333  //os_set_window((uint) hwndApp);
334 
335  /*
336  int result = MessageBox(NULL,
337  "Welcome to OGL Fred2_open. Do you want to run in htl? "
338  "Its faster on any system and runs in full detail but is still buggy.",
339  "Question", MB_ICONQUESTION | MB_YESNOCANCEL);
340 
341  if(result == IDCANCEL) return false;
342 
343  Cmdline_nohtl = result != IDYES;
344  */
345 
346  /* - HTL is now on by default so the warning is redundant - Karajorma
347  if (Cmdline_nohtl)
348  {
349  MessageBox(NULL, "You are not running in HTL mode for FRED. Although HTL mode isn't required, there may be some crashes"
350  " when trying to render the new high polygon models. To enable HTL mode, create a shortcut to FRED, right-click into properties"
351  " and add \"-fredhtl\" to the end of the string in the \"target\" box.", "FRED2", MB_ICONWARNING | MB_OK);
352  }
353  */
354 
355  snd_init();
356 
357  // Not ready for this yet
358  // Cmdline_nospec = 1;
359  // Cmdline_noglow = 1;
360  Cmdline_window = 1;
361 
362  gr_init(GR_OPENGL, 640, 480, 32);
363 
364  Mouse_hidden = 1;
365 
366  gr_font_init(); // loads up all fonts
367 
368  gr_set_gamma(3.0f);
369 
370  sprintf(palette_filename, "gamepalette%d-%02d", 1, 1);
371  mprintf(("Loading palette %s\n", palette_filename));
372  palette_load_table(palette_filename);
373 
374  key_init();
375  mouse_init();
376 
377  iff_init(); // Goober5000
378  species_init(); // Kazan
379 
381 
382  // for fred specific replacement texture stuff
384 
385  // Goober5000
386  for (i = 0; i < MAX_IFFS; i++)
387  Show_iff[i] = true;
388 
389  // Goober5000
397  strcpy_s(Voice_script_entry_format, "Sender: $sender\r\nPersona: $persona\r\nFile: $filename\r\nMessage: $message");
399 
400  hud_init_comm_orders(); // Goober5000
401 
403 
404  gamesnd_parse_soundstbl(); // needs to be loaded after species stuff but before interface/weapon/ship stuff - taylor
406  obj_init();
407  model_free_all(); // Free all existing models
408  ai_init();
410  armor_init();
411  weapon_init();
412  parse_medal_tbl(); // get medal names for sexpression usage
413  glowpoint_init();
414  ship_init();
415  parse_init();
417 
418  // initialize and activate external string hash table
419  // make sure to do here so that we don't parse the table files into the hash table - waste of space
420  fhash_init();
421  fhash_activate();
422 
424  neb2_init(); // fullneb stuff
425  stars_init();
426  ssm_init(); // The game calls this after stars_init(), and we need Ssm_info initialized for OPF_SSM_CLASS. -MageKing17
428  fred_preload_all_briefing_icons(); //phreak. This needs to be done or else the briefing icons won't show up
431  cmd_brief_reset();
434 
436 
437  // neb lightning
438  nebl_init();
439 
440  gr_reset_clip();
441  g3_start_frame(0);
443 
444  // Get the default player ship
446 
447  Id_select_type_start = Ship_info.size() + 2;
448  Id_select_type_jump_node = Ship_info.size() + 1;
450  Fred_main_wnd -> init_tools();
451  return true;
452 }
453 
455 {
461 
462  view_physics.max_rotvel.xyz.x *= physics_rot / 30.0f;
463  view_physics.max_rotvel.xyz.y *= physics_rot / 30.0f;
464  view_physics.max_rotvel.xyz.z *= physics_rot / 30.0f;
467 }
468 
469 int create_object_on_grid(int waypoint_instance)
470 {
471  int obj = -1;
472  float rval;
473  vec3d dir,pos;
474 
476 
477  rval = fvi_ray_plane(&pos, &The_grid->center, &The_grid->gmatrix.vec.uvec, &view_pos, &dir, 0.0f);
478 
479  if (rval>=0.0f) {
480  unmark_all();
481  obj = create_object(&pos, waypoint_instance);
482  if (obj >= 0) {
483  mark_object(obj);
484  FREDDoc_ptr->autosave("object create");
485 
486  } else if (obj == -1)
487  Fred_main_wnd->MessageBox("Maximum ship limit reached. Can't add any more ships.");
488  }
489 
490  return obj;
491 }
492 
494 {
495  int i = 1;
496 
497  do {
498  sprintf(Ships[ship].ship_name, "U.R.A. Moron %d", i++);
499  } while (query_ship_name_duplicate(ship));
500 }
501 
502 int create_ship(matrix *orient, vec3d *pos, int ship_type)
503 {
504  // Save the Current Working dir to restore in a minute - fred is being stupid
505  char pwd[MAX_PATH_LEN];
506  getcwd(pwd, MAX_PATH_LEN); // get the present working dir - probably <fs2path>[/modpapth]/data/missions/
507 
508 
509  int obj, z1, z2;
510  float temp_max_hull_strength;
511  ship_info *sip;
512 
513  // "pop" and cfile_chdirs off the sta
514  chdir(Fred_base_dir);
515 
516 
517  obj = ship_create(orient, pos, ship_type);
518  if (obj == -1)
519  return -1;
520 
521  // ok, done with file io, restore the pwd
522  chdir(pwd);
523 
524  Objects[obj].phys_info.speed = 33.0f;
525 
527  sip = &Ship_info[shipp->ship_info_index];
528 
529  if (query_ship_name_duplicate(Objects[obj].instance))
530  fix_ship_name(Objects[obj].instance);
531 
532  // default stuff according to species and IFF
533  shipp->team = Species_info[Ship_info[shipp->ship_info_index].species].default_iff;
535 
536  // default shield setting
537  shipp->special_shield = -1;
538  z1 = Shield_sys_teams[shipp->team];
539  z2 = Shield_sys_types[ship_type];
540  if (((z1 == 1) && z2) || (z2 == 1))
541  Objects[obj].flags |= OF_NO_SHIELDS;
542 
543  // set orders according to whether the ship is on the player ship's team
544  {
545  object *temp_objp;
546  ship *temp_shipp = NULL;
547 
548  // find the first player ship
549  for (temp_objp = GET_FIRST(&obj_used_list); temp_objp != END_OF_LIST(&obj_used_list); temp_objp = GET_NEXT(temp_objp))
550  {
551  if (temp_objp->type == OBJ_START)
552  {
553  temp_shipp = &Ships[temp_objp->instance];
554  break;
555  }
556  }
557 
558  // set orders if teams match, or if player couldn't be found
559  if (temp_shipp == NULL || shipp->team == temp_shipp->team)
560  {
561  // if this ship is not a small ship, then make the orders be the default orders without
562  // the depart item
563  if (!(sip->flags & SIF_SMALL_SHIP))
564  {
566  shipp->orders_accepted &= ~DEPART_ITEM;
567  }
568  }
569  else
570  {
571  shipp->orders_accepted = 0;
572  }
573  }
574 
575  // calc kamikaze stuff
576  if (shipp->use_special_explosion)
577  {
578  temp_max_hull_strength = (float)shipp->special_exp_blast;
579  }
580  else
581  {
582  temp_max_hull_strength = sip->max_hull_strength;
583  }
584 
585  Ai_info[shipp->ai_index].kamikaze_damage = (int) min(1000.0f, 200.0f + (temp_max_hull_strength / 4.0f));
586 
587  return obj;
588 }
589 
591 {
592  int i;
593 
594  for (i=0; i<MAX_SHIPS; i++)
595  if ((i != ship) && (Ships[i].objnum != -1))
596  if (!stricmp(Ships[i].ship_name, Ships[ship].ship_name))
597  return 1;
598 
599  return 0;
600 }
601 
602 void copy_bits(int *dest, int src, int mask)
603 {
604  *dest &= ~mask;
605  *dest |= src & mask;
606 }
607 
608 int dup_object(object *objp)
609 {
610  int i, j, n, inst, obj = -1;
611  ai_info *aip1, *aip2;
612  object *objp1, *objp2;
613  ship_subsys *subp1, *subp2;
614  static int waypoint_instance(-1);
615 
616  if (!objp) {
617  waypoint_instance = -1;
618  return 0;
619  }
620 
621  inst = objp->instance;
622  if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) {
623  obj = create_ship(&objp->orient, &objp->pos, Ships[inst].ship_info_index);
624  if (obj == -1)
625  return -1;
626 
627  n = Objects[obj].instance;
628  Ships[n].team = Ships[inst].team;
629  Ships[n].arrival_cue = dup_sexp_chain(Ships[inst].arrival_cue);
630  Ships[n].departure_cue = dup_sexp_chain(Ships[inst].departure_cue);
631  Ships[n].cargo1 = Ships[inst].cargo1;
636  Ships[n].weapons = Ships[inst].weapons;
637  Ships[n].hotkey = Ships[inst].hotkey;
638 
639  aip1 = &Ai_info[Ships[n].ai_index];
640  aip2 = &Ai_info[Ships[inst].ai_index];
641  aip1->behavior = aip2->behavior;
642  aip1->ai_class = aip2->ai_class;
643  for (i=0; i<MAX_AI_GOALS; i++)
644  aip1->goals[i] = aip2->goals[i];
645 
646  if ( aip2->ai_flags & AIF_KAMIKAZE )
647  aip1->ai_flags |= AIF_KAMIKAZE;
648  if ( aip2->ai_flags & AIF_NO_DYNAMIC )
649  aip2->ai_flags |= AIF_NO_DYNAMIC;
650 
651  aip1->kamikaze_damage = aip2->kamikaze_damage;
652 
653  objp1 = &Objects[obj];
654  objp2 = &Objects[Ships[inst].objnum];
655  objp1->phys_info.speed = objp2->phys_info.speed;
656  objp1->phys_info.fspeed = objp2->phys_info.fspeed;
657  objp1->hull_strength = objp2->hull_strength;
658  objp1->shield_quadrant[0] = objp2->shield_quadrant[0];
659 
660  subp1 = GET_FIRST(&Ships[n].subsys_list);
661  subp2 = GET_FIRST(&Ships[inst].subsys_list);
662  while (subp1 != END_OF_LIST(&Ships[n].subsys_list)) {
663  Assert(subp2 != END_OF_LIST(&Ships[inst].subsys_list));
664  subp1 -> current_hits = subp2 -> current_hits;
665  subp1 = GET_NEXT(subp1);
666  subp2 = GET_NEXT(subp2);
667  }
668 
669  for (i=0; i<Num_reinforcements; i++)
670  if (!stricmp(Reinforcements[i].name, Ships[inst].ship_name)) {
671  if (Num_reinforcements < MAX_REINFORCEMENTS) {
672  j = Num_reinforcements++;
673  strcpy_s(Reinforcements[j].name, Ships[n].ship_name);
676  }
677 
678  break;
679  }
680 
681  } else if (objp->type == OBJ_WAYPOINT) {
682  obj = create_waypoint(&objp->pos, waypoint_instance);
683  waypoint_instance = Objects[obj].instance;
684  }
685 
686  if (obj == -1)
687  return -1;
688 
689  Objects[obj].pos = objp->pos;
690  Objects[obj].orient = objp->orient;
692  return obj;
693 }
694 
695 int create_object(vec3d *pos, int waypoint_instance)
696 {
697  int obj, n;
698 
700  obj = create_waypoint(pos, waypoint_instance);
701 
703  if (Player_starts >= MAX_PLAYERS) {
704  Fred_main_wnd->MessageBox("Unable to create new player start point.\n"
705  "You have reached the maximum limit.", NULL, MB_OK | MB_ICONEXCLAMATION);
706  obj = -2;
707 
709  Fred_main_wnd->MessageBox("You can't have more than one player start in\n"
710  "single player missions.\n", NULL, MB_OK | MB_ICONEXCLAMATION);
711  obj = -2;
712 
714  Fred_main_wnd->MessageBox("You can't have more than one player start in\n"
715  "a training missions.\n", NULL, MB_OK | MB_ICONEXCLAMATION);
716  obj = -2;
717 
718  } else
720 
722  CJumpNode jnp(pos);
723  obj = jnp.GetSCPObjectNumber();
724  Jump_nodes.push_back(std::move(jnp));
726  obj = -1;
727  } else { // creating a ship
728  obj = create_ship(NULL, pos, cur_model_index);
729  if (obj == -1)
730  return -1;
731 
732  n = Objects[obj].instance;
735  Ships[n].cargo1 = 0;
736  }
737 
738  if (obj < 0)
739  return obj;
740 
742  set_modified();
743  Update_window = 1;
744  return obj;
745 }
746 
747 int create_player(int num, vec3d *pos, matrix *orient, int type, int init)
748 {
749  int obj;
750 
751  if (type == -1){
752  type = Default_player_model;
753  }
754 
755  Assert(type >= 0);
757  Player_starts++;
758  obj = create_ship(orient, pos, type);
760 
761  // be sure arrival/departure cues are set
765  set_modified();
766  return obj;
767 }
768 
769 int create_waypoint(vec3d *pos, int waypoint_instance)
770 {
771  int obj = waypoint_add(pos, waypoint_instance);
772  set_modified();
773  return obj;
774 }
775 
777 {
778  reset_mission();
779  *Mission_filename = 0;
780  FREDDoc_ptr->autosave("nothing");
781  Undo_count = 0;
782 }
783 
785 {
786  clear_mission();
788 }
789 
791 {
792  char *str;
793  int i, j, count;
794  CTime t;
795 
796  // clean up everything we need to before we reset back to defaults.
797  if (Briefing_dialog){
799  }
800 
801  extern void allocate_mission_text(int size);
803 
804  The_mission.cutscenes.clear();
806  cmd_brief_reset();
808 
809  Asteroid_field.num_initial_asteroids = 0; // disable asteroid field by default.
810  Asteroid_field.speed = 0.0f;
811  vm_vec_make(&Asteroid_field.min_bound, -1000.0f, -1000.0f, -1000.0f);
812  vm_vec_make(&Asteroid_field.max_bound, 1000.0f, 1000.0f, 1000.0f);
813  vm_vec_make(&Asteroid_field.inner_min_bound, -500.0f, -500.0f, -500.0f);
814  vm_vec_make(&Asteroid_field.inner_max_bound, 500.0f, 500.0f, 500.0f);
821 
823 
824  obj_init();
825  model_free_all(); // Free all existing models
826  ai_init();
828  ship_init();
831 
832  Num_wings = 0;
833  for (i=0; i<MAX_WINGS; i++){
834  Wings[i].wave_count = 0;
835  Wings[i].wing_squad_filename[0] = '\0';
837  }
838 
839  for (i=0; i<MAX_IFFS; i++){
840  Shield_sys_teams[i] = 0;
841  }
842 
843  for (i=0; i<MAX_SHIP_CLASSES; i++){
844  Shield_sys_types[i] = 0;
845  }
846 
847  Num_ai_dock_names = 0;
848  Num_reinforcements = 0;
849  set_cur_indices(-1);
850 
851  str = reg_read_string("SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "RegisteredOwner", NULL);
852  if (!str) {
853  str = reg_read_string("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "RegisteredOwner", NULL);
854  if (!str) {
855  str = getenv("USERNAME");
856  if (!str){
857  str = UNKNOWN_USER;
858  }
859  }
860  }
861 
862  t = CTime::GetCurrentTime();
863  strcpy_s(The_mission.name, "Untitled");
864  strncpy(The_mission.author, str, NAME_LENGTH - 1);
865  The_mission.author[NAME_LENGTH - 1] = 0;
866  strcpy_s(The_mission.created, t.Format("%x at %X"));
868  strcpy_s(The_mission.notes, "This is a FRED2_OPEN created mission.\n");
869  strcpy_s(The_mission.mission_desc, "Put mission description here\n");
875 
876  Player_starts = 0;
877  Num_teams = 1;
878 
879  // reset alternate name & callsign stuff
880  for(i=0; i<MAX_SHIPS; i++){
881  strcpy_s(Fred_alt_names[i], "");
882  strcpy_s(Fred_callsigns[i], "");
883  }
884 
885  // set up the default ship types for all teams. For now, this is the same class
886  // of ships for all teams
887  for (i=0; i<MAX_TVT_TEAMS; i++) {
888  count = 0;
889  for ( j = 0; j < static_cast<int>(Ship_info.size()); j++ ) {
891  Team_data[i].ship_list[count] = j;
892  strcpy_s(Team_data[i].ship_list_variables[count], "");
893  Team_data[i].ship_count[count] = 5;
894  strcpy_s(Team_data[i].ship_count_variables[count], "");
895  count++;
896  }
897  }
899 
900  count = 0;
901  for (j=0; j<MAX_WEAPON_TYPES; j++){
902  if (Weapon_info[j].wi_flags & WIF_PLAYER_ALLOWED){
903  if(Weapon_info[j].subtype == WP_LASER){
905  } else {
907  }
909  strcpy_s(Team_data[i].weaponry_pool_variable[count], "");
910  strcpy_s(Team_data[i].weaponry_amount_variable[count], "");
911  count++;
912  }
913  Team_data[i].weapon_required[j] = false;
914  }
916  }
917 
919  Mission_text[1] = Mission_text_raw[1] = 0;
920 
922  Num_mission_events = 0;
923  Num_goals = 0;
924  unmark_all();
925  obj_init();
926  model_free_all(); // Free all existing models
928  init_sexp();
929  messages_init();
930  brief_reset();
931  debrief_reset();
932  ship_init();
935 
936  mission_parse_reset_alt(); // alternate ship type names
938 
939  strcpy(Cargo_names[0], "Nothing");
940  Num_cargo = 1;
942 
943  // reset background bitmaps and suns
945  Nebula_index = 0;
946  Mission_palette = 1;
947  Nebula_pitch = (int) ((float) (rand() & 0x0fff) * 360.0f / 4096.0f);
948  Nebula_bank = (int) ((float) (rand() & 0x0fff) * 360.0f / 4096.0f);
949  Nebula_heading = (int) ((float) (rand() & 0x0fff) * 360.0f / 4096.0f);
950  Neb2_awacs = -1.0f;
951  Neb2_poof_flags = 0;
953  for(i=0; i<MAX_NEB2_POOFS; i++){
954  Neb2_poof_flags |= (1<<i);
955  }
956 
958  Nmodel_num = -1;
959  Nmodel_instance_num = -1;
960  vm_set_identity(&Nmodel_orient);
961  Nmodel_bitmap = -1;
962 
964 
965  // Goober5000
968 
969  // Goober5000: reset ALL mission flags, not just nebula!
970  The_mission.flags = 0;
971  The_mission.support_ships.max_support_ships = -1; // negative means infinite
975 
977 
978  char palette_filename[1024];
979  strcpy_s(palette_filename, "gamepalette1-01");
980 // sprintf( palette_filename, "gamepalette%d-%02d", 1, Mission_palette+1 );
981  mprintf(( "Loading palette %s\n", palette_filename ));
982  palette_load_table(palette_filename);
983 
990 
991  // no sound environment
993 
994  ENVMAP = -1;
995 
997  Update_window = 1;
998 }
999 
1001 {
1002  int obj_found = FALSE;
1003  object *ptr;
1004 
1006  return FALSE;
1007 
1008  ptr = GET_FIRST(&obj_used_list);
1009  while (ptr != END_OF_LIST(&obj_used_list)) {
1010  Assert(ptr->type != OBJ_NONE);
1011  if (OBJ_INDEX(ptr) == index)
1012  obj_found = TRUE;
1013 
1014  ptr = GET_NEXT(ptr);
1015  }
1016 
1017  Assert(obj_found); // just to make sure it's in the list like it should be.
1018  return TRUE;
1019 }
1020 
1022 {
1023  int obj_found = FALSE;
1024  object *ptr;
1025 
1027  return FALSE;
1028 
1029  ptr = GET_FIRST(&obj_used_list);
1030  while (ptr != END_OF_LIST(&obj_used_list)) {
1031  Assert(ptr->type != OBJ_NONE);
1032  if (OBJ_INDEX(ptr) == index)
1033  obj_found = TRUE;
1034 
1035  ptr = GET_NEXT(ptr);
1036  }
1037 
1038  Assert(obj_found); // just to make sure it's in the list like it should be.
1039  return TRUE;
1040 }
1041 
1043 {
1044  int obj_found = FALSE;
1045  object *ptr;
1046 
1048  return FALSE;
1049 
1050  ptr = GET_FIRST(&obj_used_list);
1051  while (ptr != END_OF_LIST(&obj_used_list)) {
1052  Assert(ptr->type != OBJ_NONE);
1053  if (OBJ_INDEX(ptr) == index)
1054  obj_found = TRUE;
1055 
1056  ptr = GET_NEXT(ptr);
1057  }
1058 
1059  Assert(obj_found); // just to make sure it's in the list like it should be.
1060  return TRUE;
1061 }
1062 
1063 // Sets the current object to whatever is specified or advances to the next object
1064 // in the list if nothing is passed.
1066 {
1067  if (obj < 0)
1068  unmark_all();
1069  else
1070  mark_object(obj);
1071 
1072  set_cur_indices(obj); // select the new object
1073  Update_ship = Update_wing = 1;
1075  Update_window = 1;
1076 }
1077 
1078 // changes the currently selected wing. It is assumed that cur_wing == cur_ship's wing
1079 // number. Don't call this if this won't be true, or else you'll screw things up.
1081 {
1082  cur_wing = wing;
1083 /* if (cur_ship != -1)
1084  Assert(cur_wing == Ships[cur_ship].wingnum);
1085  if ((cur_object_index != -1) && (Objects[cur_object_index].type == OBJ_SHIP))
1086  Assert(cur_wing == Ships[Objects[cur_object_index].instance].wingnum);*/
1087  Update_wing = 1;
1088  Update_window = 1;
1089 }
1090 
1091 // sets up the various cur_* global variables related to the selecting of an object. This
1092 // is an internal function that shouldn't typically get called directly. Use set_cur_object_index() instead.
1094 {
1095  int i;
1096  object *ptr;
1097  CSingleLock sync(&CS_cur_object_index);
1098 
1099  sync.Lock(); // Don't modify until it's unlocked (if it's locked elsewhere).
1100  if (query_valid_object(obj)) {
1102  cur_ship = cur_wing = -1;
1103  cur_waypoint_list = NULL;
1104  cur_waypoint = NULL;
1105 
1106  if ((Objects[obj].type == OBJ_SHIP) || (Objects[obj].type == OBJ_START)) {
1109  if (cur_wing >= 0)
1110  for (i=0; i<Wings[cur_wing].wave_count; i++)
1111  if (wing_objects[cur_wing][i] == cur_object_index) {
1112  cur_wing_index = i;
1113  break;
1114  }
1115 
1116  } else if (Objects[obj].type == OBJ_WAYPOINT) {
1117  cur_waypoint = find_waypoint_with_instance(Objects[obj].instance);
1118  Assert(cur_waypoint != NULL);
1119  cur_waypoint_list = cur_waypoint->get_parent_list();
1120  }
1121 
1122  return;
1123  }
1124 
1125  if (obj == -1 || !Num_objects) {
1127  cur_waypoint_list = NULL;
1128  cur_waypoint = NULL;
1129  return;
1130  }
1131 
1133  ptr = Objects[cur_object_index].next;
1134  else
1135  ptr = GET_FIRST(&obj_used_list);
1136 
1137  if (ptr == END_OF_LIST(&obj_used_list))
1138  ptr = ptr->next;
1139 
1140  Assert(ptr != END_OF_LIST(&obj_used_list));
1141  cur_object_index = OBJ_INDEX(ptr);
1142  Assert(ptr->type != OBJ_NONE);
1143  cur_ship = cur_wing = -1;
1144  cur_waypoint_list = NULL;
1145  cur_waypoint = NULL;
1146 
1147  if (ptr->type == OBJ_SHIP) {
1148  cur_ship = ptr->instance;
1150  for (i=0; i<Wings[cur_wing].wave_count; i++)
1151  if (wing_objects[cur_wing][i] == cur_object_index) {
1152  cur_wing_index = i;
1153  break;
1154  }
1155 
1156  } else if (ptr->type == OBJ_WAYPOINT) {
1157  cur_waypoint = find_waypoint_with_instance(ptr->instance);
1158  Assert(cur_waypoint != NULL);
1159  cur_waypoint_list = cur_waypoint->get_parent_list();
1160  }
1161 }
1162 
1164 {
1165  int z;
1166 
1167  nprintf(("Fred routing", "updating dialog boxes\n"));
1168 
1169  // check wing first, since ships are dependent on wings, but not the reverse
1171  if (z) {
1172  nprintf(("Fred routing", "wing dialog save failed\n"));
1173  Wing_editor_dialog.SetWindowPos(&Fred_main_wnd->wndTop, 0, 0, 0, 0,
1174  SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
1175 
1176  return z;
1177  }
1178 
1180  if (z) {
1181  nprintf(("Fred routing", "ship dialog save failed\n"));
1182  Ship_editor_dialog.SetWindowPos(&Fred_main_wnd->wndTop, 0, 0, 0, 0,
1183  SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
1184 
1185  return z;
1186  }
1187 
1189  if (z) {
1190  nprintf(("Fred routing", "waypoint dialog save failed\n"));
1191  Waypoint_editor_dialog.SetWindowPos(&Fred_main_wnd->wndTop, 0, 0, 0, 0,
1192  SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
1193 
1194  return z;
1195  }
1196 
1198  return 0;
1199 }
1200 
1202 {
1203  int r;
1204 
1206  r = common_object_delete(obj);
1208  return r;
1209 }
1210 
1211 int delete_object(object *ptr)
1212 {
1213  int r;
1214 
1216  r = common_object_delete(OBJ_INDEX(ptr));
1218  return r;
1219 }
1220 
1222 {
1223  int r;
1224 
1226  r = common_object_delete(Ships[ship].objnum);
1228  return r;
1229 }
1230 
1232 {
1233  char msg[255], *name;
1234  int i, z, r, type;
1235  object *objp;
1237 
1238  type = Objects[obj].type;
1239  if (type == OBJ_START) {
1240  i = Objects[obj].instance;
1241  if (Player_starts < 2) { // player 1 start
1242  Fred_main_wnd->MessageBox("Must have at least 1 player starting point!",
1243  NULL, MB_OK | MB_ICONEXCLAMATION);
1244 
1245  unmark_object(obj);
1246  return 1;
1247  }
1248 
1249  Assert((i >= 0) && (i < MAX_SHIPS));
1250  sprintf(msg, "Player %d", i + 1);
1251  name = msg;
1252  r = reference_handler(name, REF_TYPE_PLAYER, obj);
1253  if (r)
1254  return r;
1255 
1256  if (Ships[i].wingnum >= 0) {
1257  r = delete_ship_from_wing(i);
1258  if (r)
1259  return r;
1260  }
1261 
1262  Objects[obj].type = OBJ_SHIP; // was allocated as a ship originally, so remove as such.
1264 
1265  // check if any ship is docked with this ship and break dock if so
1266  while (object_is_docked(&Objects[obj]))
1267  {
1269  }
1270 
1271  if (Player_start_shipnum == i) { // need a new single player start.
1272  objp = GET_FIRST(&obj_used_list);
1273  while (objp != END_OF_LIST(&obj_used_list)) {
1274  if (objp->type == OBJ_START) {
1276  break;
1277  }
1278 
1279  objp = GET_NEXT(objp);
1280  }
1281  }
1282 
1283  Player_starts--;
1284 
1285  } else if (type == OBJ_WAYPOINT) {
1286  waypoint *wpt = find_waypoint_with_instance(Objects[obj].instance);
1287  Assert(wpt != NULL);
1288  waypoint_list *wp_list = wpt->get_parent_list();
1289  int index = calc_waypoint_list_index(Objects[obj].instance);
1290  int count = (int) wp_list->get_waypoints().size();
1291 
1292  // we'll end up deleting the path, so check for path references
1293  if (count == 1) {
1294  name = wp_list->get_name();
1295  r = reference_handler(name, REF_TYPE_PATH, obj);
1296  if (r)
1297  return r;
1298  }
1299 
1300  // check for waypoint references
1301  sprintf(msg, "%s:%d", wp_list->get_name(), index + 1);
1302  name = msg;
1303  r = reference_handler(name, REF_TYPE_WAYPOINT, obj);
1304  if (r)
1305  return r;
1306 
1307  // at this point we've confirmed we want to delete it
1308 
1310  if (count == 1) {
1312  }
1313 
1314  // the actual removal code has been moved to this function in waypoints.cpp
1315  waypoint_remove(wpt);
1316 
1317  } else if (type == OBJ_SHIP) {
1318  name = Ships[Objects[obj].instance].ship_name;
1319  r = reference_handler(name, REF_TYPE_SHIP, obj);
1320  if (r)
1321  return r;
1322 
1323  z = Objects[obj].instance;
1324  if (Ships[z].wingnum >= 1) {
1326  r = delete_ship_from_wing(z);
1327  if (r)
1328  return r;
1329 
1330  } else if (Ships[z].wingnum >= 0) {
1331  r = delete_ship_from_wing(z);
1332  if (r)
1333  return r;
1334 
1336  }
1337 
1338  for (i=0; i<Num_reinforcements; i++)
1339  if (!stricmp(name, Reinforcements[i].name)) {
1341  break;
1342  }
1343 
1344  // check if any ship is docked with this ship and break dock if so
1345  while (object_is_docked(&Objects[obj]))
1346  {
1348  }
1349 
1350  } else if (type == OBJ_POINT) {
1352  Briefing_dialog->delete_icon(Objects[obj].instance);
1353  Update_window = 1;
1354  return 0;
1355 
1356  } else if (type == OBJ_JUMP_NODE) {
1357  for (jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp) {
1358  if(jnp->GetSCPObject() == &Objects[obj])
1359  break;
1360  }
1361 
1362  // come on, WMC, we don't want to call obj_delete twice...
1363  // fool the destructor into not calling obj_delete yet
1364  Objects[obj].type = OBJ_NONE;
1365 
1366  // now call the destructor
1367  Jump_nodes.erase(jnp);
1368 
1369  // now restore the jump node type so that the below unmark and obj_delete will work
1371  }
1372 
1373  unmark_object(obj);
1374 
1375  //we need to call obj_delete() even if obj is a jump node
1376  //the statement "delete Objects[obj].jnp" deletes the jnp object
1377  //obj_delete() frees up the object slot where the node used to reside.
1378  //if we don't call this then the node will still show up in fred and you can try to delete it twice
1379  //this causes an ugly crash.
1380  obj_delete(obj);
1381  set_modified();
1382  Update_window = 1;
1383  return 0;
1384 }
1385 
1387 {
1388  object *ptr, *next;
1389 
1390  delete_flag = 0;
1391  ptr = GET_FIRST(&obj_used_list);
1392  while (ptr != END_OF_LIST(&obj_used_list)) {
1393  next = GET_NEXT(ptr);
1394  if (ptr->flags & OF_MARKED)
1395  if (delete_object(ptr) == 2) // user went to a reference, so don't get in the way.
1396  break;
1397 
1398  ptr = next;
1399  }
1400 
1401  if (!delete_flag)
1403 
1404  Update_window = 1;
1405 }
1406 
1408 {
1409  int i;
1410 
1411  for (i=num; i<Num_reinforcements-1; i++)
1412  Reinforcements[i] = Reinforcements[i + 1];
1413 
1414  Num_reinforcements--;
1415  set_modified();
1416 }
1417 
1418 // delete ship, removing it from its wing if necessary.
1420 {
1421  char name[NAME_LENGTH];
1422  int i, r, wing, end;
1423 
1424  wing = Ships[ship].wingnum;
1425  if (wing >= 0) {
1426  if (Wings[wing].wave_count == 1) {
1427  cur_wing = -1;
1428  Update_wing = 1;
1429  r = delete_wing(wing, 1);
1430  if (r) {
1431  if (r == 2){
1432  delete_flag = 1;
1433  }
1434 
1435  return r;
1436  }
1437 
1438  } else {
1439  i = Wings[wing].wave_count;
1440  end = i - 1;
1441  while (i--){
1442  if (wing_objects[wing][i] == Ships[ship].objnum){
1443  break;
1444  }
1445  }
1446 
1447  Assert(i != -1); // Error, object should be in wing.
1448  if (Wings[wing].special_ship == i){
1449  Wings[wing].special_ship = 0;
1450  } else if (Wings[wing].special_ship > i) {
1451  Wings[wing].special_ship--;
1452  }
1453 
1454  if (i != end) {
1457  if (Objects[wing_objects[wing][i]].type == OBJ_SHIP) {
1458  wing_bash_ship_name(name, Wings[wing].name, i + 1);
1459  rename_ship(Wings[wing].ship_index[i], name);
1460  }
1461  }
1462 
1463  if (Wings[wing].threshold >= Wings[wing].wave_count){
1465  }
1466 
1467  Wings[wing].wave_count--;
1468  if (Wings[wing].wave_count && (Wings[wing].threshold >= Wings[wing].wave_count)){
1470  }
1471  }
1472  }
1473 
1474  set_modified();
1475  return 0;
1476 }
1477 
1478 // Return true if current object is valid and is in a wing.
1479 // Else return false.
1481 {
1482  if (query_valid_object(obj)){
1483  if (Ships[Objects[obj].instance].wingnum != -1){
1484  return TRUE;
1485  }
1486  }
1487 
1488  return FALSE;
1489 }
1490 
1491 void mark_object(int obj)
1492 {
1493  Assert(query_valid_object(obj));
1494  if (!(Objects[obj].flags & OF_MARKED)) {
1495  Objects[obj].flags |= OF_MARKED; // set as marked
1496  Marked++;
1497  Update_window = 1;
1498  if (cur_object_index == -1){
1499  set_cur_object_index(obj);
1500  }
1501  Update_ship = Update_wing = 1;
1503  }
1504 }
1505 
1507 {
1508  Assert(query_valid_object(obj));
1509  if (Objects[obj].flags & OF_MARKED) {
1510  Objects[obj].flags &= ~OF_MARKED;
1511  Marked--;
1512  Update_window = 1;
1513  if (obj == cur_object_index) { // need to find a new index
1514  object *ptr;
1515 
1516  ptr = GET_FIRST(&obj_used_list);
1517  while (ptr != END_OF_LIST(&obj_used_list)) {
1518  if (ptr->flags & OF_MARKED) {
1519  set_cur_object_index(OBJ_INDEX(ptr)); // found one
1520  return;
1521  }
1522 
1523  ptr = GET_NEXT(ptr);
1524  }
1525 
1526  set_cur_object_index(-1); // can't find one; nothing is marked.
1527  }
1528  Update_ship = Update_wing = 1;
1530  }
1531 }
1532 
1533 // clears the marked flag of all objects (so nothing is marked)
1535 {
1536  int i;
1537 
1538  if (Marked) {
1539  for (i=0; i<MAX_OBJECTS; i++){
1540  Objects[i].flags &= ~OF_MARKED;
1541  }
1542 
1543  Marked = 0;
1544  Update_window = 1;
1546  }
1547 }
1548 
1549 void clear_menu(CMenu *ptr)
1550 {
1551  int count;
1552 
1553  count = ptr->GetMenuItemCount();
1554  while (count--){
1555  ptr->DeleteMenu(count, MF_BYPOSITION);
1556  }
1557 }
1558 
1559 void generate_wing_popup_menu(CMenu *mptr, int first_id, int state)
1560 {
1561  int i, z, columns, rows, count;
1562 
1563  columns = 1;
1564  rows = Num_wings;
1565  while (rows > 25) {
1566  columns++;
1567  rows = Num_wings / columns;
1568  }
1569 
1570  count = rows + 1;
1571  for (i=0; i<MAX_WINGS; i++){
1572  if (Wings[i].wave_count) {
1573  z = state | MF_STRING;
1574  if (!count--) {
1575  count = rows;
1576  z |= MF_MENUBARBREAK;
1577  }
1578 
1579  mptr->AppendMenu(z, first_id + i, Wings[i].name);
1580  }
1581  }
1582 
1583  mptr->DeleteMenu(ID_PLACEHOLDER, MF_BYCOMMAND);
1584 }
1585 
1586 void generate_ship_popup_menu(CMenu *mptr, int first_id, int state, int filter)
1587 {
1588  int z, ship, columns, rows, count, num_ships;
1589  object *ptr;
1590 
1591  columns = 1;
1592  num_ships = ship_get_num_ships();
1593  rows = num_ships;
1594  while (rows > 25) {
1595  columns++;
1596  rows = num_ships / columns;
1597  }
1598 
1599  count = rows + 1;
1600  ptr = GET_FIRST(&obj_used_list);
1601  while (ptr != END_OF_LIST(&obj_used_list)) {
1602  if ((ptr->type == OBJ_SHIP) || ((ptr->type == OBJ_START) && (filter & SHIP_FILTER_PLAYERS))) {
1603  z = 1;
1604  if (filter & SHIP_FILTER_FLYABLE) {
1605  if (Ship_info[Ships[get_ship_from_obj(ptr)].ship_info_index].flags & SIF_NOT_FLYABLE){
1606  z = 0;
1607  }
1608  }
1609 
1610  if (z) {
1611  z = state | MF_STRING;
1612  if (!count--) {
1613  count = rows;
1614  z |= MF_MENUBARBREAK;
1615  }
1616 
1617  ship = ptr->instance;
1618  mptr->AppendMenu(z, first_id + ship, Ships[ship].ship_name);
1619  }
1620  }
1621 
1622  ptr = GET_NEXT(ptr);
1623  }
1624 
1625  mptr->DeleteMenu(ID_PLACEHOLDER, MF_BYCOMMAND);
1626 }
1627 
1628 // Alternate string lookup function, taking a CString instead. The reason that it's here,
1629 // instead of parselo.cpp, is because the class CString require an include of windows.h,
1630 // which everyone wants to avoid including in any freespace header files. So..
1631 int string_lookup(const CString &str1, char *strlist[], int max)
1632 {
1633  int i;
1634 
1635  for (i=0; i<max; i++) {
1636  Assert(strlen(strlist[i]));
1637 
1638  if (!stricmp((LPCTSTR) str1, strlist[i])){
1639  return i;
1640  }
1641  }
1642 
1643  return -1;
1644 }
1645 
1646 int gray_menu_tree(CMenu *base)
1647 {
1648  int i, z, count = 0;
1649  CMenu *submenu;
1650 
1651  i = base->GetMenuItemCount();
1652  while (i--) {
1653  if ((submenu = base->GetSubMenu(i))>0) {
1654  if (gray_menu_tree(submenu)) {
1655  count++;
1656  } else {
1657  base->EnableMenuItem(i, MF_GRAYED | MF_BYPOSITION);
1658  }
1659 
1660  } else {
1661  z = base->GetMenuState(i, MF_BYPOSITION);
1662  if (z == MF_ENABLED){
1663  count++;
1664  }
1665  }
1666  }
1667 
1668  return count;
1669 }
1670 
1672 {
1673  int i, z;
1674 
1675  Assert(wing != -1);
1676  if (wing == -1){
1677  return 0;
1678  }
1679 
1680  if (query_initial_orders_empty(Wings[wing].ai_goals)){
1681  return 0;
1682  }
1683 
1684  i = Wings[wing].wave_count; // wing has orders, now check ships.
1685  while (i--) {
1687  if (!query_initial_orders_empty(Ai_info[z].goals)){ // ship also has orders
1688  return 1;
1689  }
1690  }
1691 
1692  return 0;
1693 }
1694 
1696 {
1697  int i;
1698 
1699  for (i=0; i<MAX_AI_GOALS; i++){
1700  if (ai_goals[i].ai_mode != AI_GOAL_NONE){
1701  return 0;
1702  }
1703  }
1704 
1705  return 1;
1706 }
1707 
1708 int set_reinforcement(char *name, int state)
1709 {
1710  int i, index, cur = -1;
1711 
1712  for (i=0; i<Num_reinforcements; i++){
1713  if (!stricmp(Reinforcements[i].name, name)){
1714  cur = i;
1715  }
1716  }
1717 
1718  if (!state && (cur != -1)) {
1719  Num_reinforcements--;
1721 
1722  // clear the ship/wing flag for this reinforcement
1723  index = ship_name_lookup(name);
1724  if ( index != -1 ){
1726  } else {
1727  index = wing_name_lookup(name);
1728  if ( index != -1 ){
1730  }
1731  }
1732  if (index == -1 ){
1733  Int3(); // get allender -- coudln't find ship/wing for clearing reinforcement flag
1734  }
1735 
1736  set_modified();
1737  return -1;
1738  }
1739 
1740  if (state && (cur == -1) && (Num_reinforcements < MAX_REINFORCEMENTS)) {
1741  Assert(strlen(name) < NAME_LENGTH);
1742  strcpy_s(Reinforcements[Num_reinforcements].name, name);
1745  memset( Reinforcements[Num_reinforcements].no_messages, 0, MAX_REINFORCEMENT_MESSAGES * NAME_LENGTH );
1746  memset( Reinforcements[Num_reinforcements].yes_messages, 0, MAX_REINFORCEMENT_MESSAGES * NAME_LENGTH );
1747  Num_reinforcements++;
1748 
1749  // set the reinforcement flag on the ship or wing
1750  index = ship_name_lookup(name);
1751  if ( index != -1 ){
1753  } else {
1754  index = wing_name_lookup(name);
1755  if ( index != -1 ){
1757  }
1758  }
1759  if ( index == -1 ){
1760  Int3(); // get allender -- coudln't find ship/wing for setting reinforcement flag
1761  }
1762 
1763  set_modified();
1764  return 1;
1765  }
1766 
1767  // this code will take care of setting the bits for the ship/wing flags
1768  if ( state && (cur != -1) ) {
1769  // set the reinforcement flag on the ship or wing
1770  index = ship_name_lookup(name);
1771  if ( index != -1 ){
1773  } else {
1774  index = wing_name_lookup(name);
1775  if ( index != -1 ){
1777  }
1778  }
1779  if ( index == -1 ){
1780  Int3(); // get allender -- coudln't find ship/wing for setting reinforcement flag
1781  }
1782  }
1783 
1784  return 0;
1785 }
1786 
1787 int get_docking_list(int model_index)
1788 {
1789  int i;
1790  polymodel *pm;
1791 
1792  pm = model_get(model_index);
1793  Assert(pm->n_docks <= MAX_DOCKS);
1794  for (i=0; i<pm->n_docks; i++)
1795  Docking_bay_list[i] = pm->docking_bays[i].name;
1796 
1797  return pm->n_docks;
1798 }
1799 
1800 // DA 1/7/99 These ship names are not variables
1801 int rename_ship(int ship, char *name)
1802 {
1803  int i;
1804 
1805  Assert(ship >= 0);
1806  Assert(strlen(name) < NAME_LENGTH);
1807 
1808  update_sexp_references(Ships[ship].ship_name, name);
1809  ai_update_goal_references(REF_TYPE_SHIP, Ships[ship].ship_name, name);
1810  update_texture_replacements(Ships[ship].ship_name, name);
1811  for (i=0; i<Num_reinforcements; i++)
1812  if (!stricmp(Ships[ship].ship_name, Reinforcements[i].name)) {
1813  strcpy_s(Reinforcements[i].name, name);
1814  }
1815 
1816  strcpy_s(Ships[ship].ship_name, name);
1817  if (ship == cur_ship)
1818  Ship_editor_dialog.m_ship_name = _T(name);
1819 
1820  return 0;
1821 }
1822 
1824 {
1825  char new_name[512];
1826  int i;
1827 
1828  sprintf(new_name, "<%s>", name);
1829  update_sexp_references(name, new_name);
1830  ai_update_goal_references(type, name, new_name);
1831  update_texture_replacements(name, new_name);
1832  for (i=0; i<Num_reinforcements; i++)
1833  if (!stricmp(name, Reinforcements[i].name)) {
1834  strcpy_s(Reinforcements[i].name, new_name);
1835  }
1836 
1837  return 0;
1838 }
1839 
1841 {
1842  int i;
1843 
1844  for (i=0; i<Num_mission_events; i++)
1845  verify_sexp_tree(Mission_events[i].formula);
1846 
1847  for (i=0; i<Num_goals; i++)
1848  verify_sexp_tree(Mission_goals[i].formula);
1849 
1850  for (i=0; i<MAX_WINGS; i++)
1851  if (Wings[i].wave_count) {
1852  verify_sexp_tree(Wings[i].arrival_cue);
1853  verify_sexp_tree(Wings[i].departure_cue);
1854  }
1855 
1856  for (i=0; i<MAX_SHIPS; i++)
1857  if (Ships[i].objnum >= 0) {
1858  verify_sexp_tree(Ships[i].arrival_cue);
1859  verify_sexp_tree(Ships[i].departure_cue);
1860  if (Ships[i].ai_index < 0)
1861  Assert(0);
1862  if (Ai_info[Ships[i].ai_index].shipnum != i)
1863  Int3();
1864  }
1865 
1866  return 0;
1867 }
1868 
1870 {
1871  object *ptr;
1872 
1873  ptr = GET_FIRST(&obj_used_list);
1874  while (ptr != END_OF_LIST(&obj_used_list)) {
1875  if (ptr->flags & OF_MARKED) {
1876  if (ptr->flags & OF_HIDDEN)
1877  unmark_object(OBJ_INDEX(ptr));
1878 
1879  else switch (ptr->type) {
1880  case OBJ_WAYPOINT:
1881  if (!Show_waypoints)
1882  unmark_object(OBJ_INDEX(ptr));
1883  break;
1884 
1885  case OBJ_START:
1886  if (!Show_starts || !Show_ships)
1887  unmark_object(OBJ_INDEX(ptr));
1888  break;
1889 
1890  case OBJ_SHIP:
1891  if (!Show_ships)
1892  unmark_object(OBJ_INDEX(ptr));
1893 
1894  if (!Show_iff[Ships[ptr->instance].team])
1895  unmark_object(OBJ_INDEX(ptr));
1896 
1897  break;
1898  }
1899  }
1900 
1901  ptr = GET_NEXT(ptr);
1902  }
1903 }
1904 
1905 // Fills a combo box with a list of all docking points of type 'type' on ship 'ship'.
1906 // Item data is the actual docking point index.
1907 void set_valid_dock_points(int ship, int type, CComboBox *box)
1908 {
1909  int i, z, num, model;
1910 
1911  model = Ship_info[Ships[ship].ship_info_index].model_num;
1912  num = model_get_num_dock_points(model);
1913  for (i=0; i<num; i++)
1914  if (model_get_dock_index_type(model, i) & type) {
1915  z = box->AddString(model_get_dock_name(model, i));
1916  box->SetItemData(z, i);
1917  }
1918 
1919  Assert(box->GetCount());
1920 }
1921 
1922 // Given an object index, find the ship index for that object.
1924 {
1925  if ((Objects[obj].type == OBJ_SHIP) || (Objects[obj].type == OBJ_START))
1926  return Objects[obj].instance;
1927 
1928  Int3();
1929  return 0;
1930 }
1931 
1933 {
1934  if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START))
1935  return objp->instance;
1936 
1937  Int3();
1938  return 0;
1939 }
1940 
1941 void ai_update_goal_references(int type, const char *old_name, const char *new_name)
1942 {
1943  int i;
1944 
1945  for (i=0; i<MAX_AI_INFO; i++) // loop through all Ai_info entries
1946  if (Ai_info[i].shipnum != -1) // skip if unused
1947  ai_update_goal_references(Ai_info[i].goals, type, old_name, new_name);
1948 
1949  for (i=0; i<MAX_WINGS; i++)
1950  if (Wings[i].wave_count)
1951  ai_update_goal_references(Wings[i].ai_goals, type, old_name, new_name);
1952 }
1953 
1955 {
1956  int i;
1957 
1958  for (i=0; i<MAX_AI_INFO; i++) // loop through all Ai_info entries
1959  if (Ai_info[i].shipnum >= 0) // skip if unused
1960  if (query_referenced_in_ai_goals(Ai_info[i].goals, type, name))
1961  return Ai_info[i].shipnum | SRC_SHIP_ORDER;
1962 
1963  for (i=0; i<MAX_WINGS; i++)
1964  if (Wings[i].wave_count)
1965  if (query_referenced_in_ai_goals(Wings[i].ai_goals, type, name))
1966  return i | SRC_WING_ORDER;
1967 
1968  return 0;
1969 }
1970 
1971 int advanced_stricmp(char *one, char *two)
1972 {
1973  if (!one && !two)
1974  return 0;
1975 
1976  if (!one)
1977  return -1;
1978 
1979  if (!two)
1980  return 1;
1981 
1982  return stricmp(one, two);
1983 }
1984 
1985 // returns 0: go ahead change object
1986 // 1: don't change it
1987 // 2: abort (they used cancel to go to reference)
1988 int reference_handler(char *name, int type, int obj)
1989 {
1990  char msg[2048], text[128], type_name[128];
1991  int r, n, node;
1992 
1993  switch (type) {
1994  case REF_TYPE_SHIP:
1995  sprintf(type_name, "Ship \"%s\"", name);
1996  break;
1997 
1998  case REF_TYPE_WING:
1999  sprintf(type_name, "Wing \"%s\"", name);
2000  break;
2001 
2002  case REF_TYPE_PLAYER:
2003  strcpy_s(type_name, name);
2004  break;
2005 
2006  case REF_TYPE_WAYPOINT:
2007  sprintf(type_name, "Waypoint \"%s\"", name);
2008  break;
2009 
2010  case REF_TYPE_PATH:
2011  sprintf(type_name, "Waypoint path \"%s\"", name);
2012  break;
2013 
2014  default:
2015  Error(LOCATION, "Type unknown for object \"%s\". Let Hoffos know now!", name);
2016  }
2017 
2018  r = query_referenced_in_sexp(type, name, &node);
2019  if (r) {
2020  n = r & SRC_DATA_MASK;
2021  switch (r & SRC_MASK) {
2022  case SRC_SHIP_ARRIVAL:
2023  sprintf(text, "the arrival cue of ship \"%s\"", Ships[n].ship_name);
2024  break;
2025 
2026  case SRC_SHIP_DEPARTURE:
2027  sprintf(text, "the departure cue of ship \"%s\"", Ships[n].ship_name);
2028  break;
2029 
2030  case SRC_WING_ARRIVAL:
2031  sprintf(text, "the arrival cue of wing \"%s\"", Wings[n].name);
2032  break;
2033 
2034  case SRC_WING_DEPARTURE:
2035  sprintf(text, "the departure cue of wing \"%s\"", Wings[n].name);
2036  break;
2037 
2038  case SRC_EVENT:
2039  if (*Mission_events[n].name)
2040  sprintf(text, "event \"%s\"", Mission_events[n].name);
2041  else
2042  sprintf(text, "event #%d", n);
2043 
2044  break;
2045 
2046  case SRC_MISSION_GOAL:
2047  if (*Mission_goals[n].name)
2048  sprintf(text, "mission goal \"%s\"", Mission_goals[n].name);
2049  else
2050  sprintf(text, "mission goal #%d", n);
2051 
2052  break;
2053 
2054  case SRC_DEBRIEFING:
2055  sprintf(text, "debriefing #%d", n);
2056  break;
2057 
2058  case SRC_BRIEFING:
2059  sprintf(text, "briefing #%d", n);
2060  break;
2061 
2062  default: // very bad. Someone added an sexp somewhere and didn't change this.
2063  Warning(LOCATION, "\"%s\" referenced by an unknown sexp source! "
2064  "Run for the hills and let Hoffoss know right now!", name);
2065 
2066  delete_flag = 1;
2067  return 2;
2068  }
2069 
2070  sprintf(msg, "%s is referenced by %s (possibly more sexps).\n"
2071  "Do you want to delete it anyway?\n\n"
2072  "(click Cancel to go to the reference)", type_name, text);
2073 
2074  r = sexp_reference_handler(node, r, msg);
2075  if (r == 1) {
2076  if (obj >= 0)
2077  unmark_object(obj);
2078 
2079  return 1;
2080  }
2081 
2082  if (r == 2) {
2083  delete_flag = 1;
2084  return 2;
2085  }
2086  }
2087 
2088  r = query_referenced_in_ai_goals(type, name);
2089  if (r) {
2090  n = r & SRC_DATA_MASK;
2091  switch (r & SRC_MASK) {
2092  case SRC_SHIP_ORDER:
2093  sprintf(text, "ship \"%s\"", Ships[n].ship_name);
2094  break;
2095 
2096  case SRC_WING_ORDER:
2097  sprintf(text, "wing \"%s\"", Wings[n].name);
2098  break;
2099 
2100  default: // very bad. Someone added an sexp somewhere and didn't change this.
2101  Error(LOCATION, "\"%s\" referenced by an unknown initial orders source! "
2102  "Run for the hills and let Hoffoss know right now!", name);
2103  }
2104 
2105  sprintf(msg, "%s is referenced by the initial orders of %s (possibly \n"
2106  "more initial orders). Do you want to delete it anyway?\n\n"
2107  "(click Cancel to go to the reference)", type_name, text);
2108 
2109  r = orders_reference_handler(r, msg);
2110  if (r == 1) {
2111  if (obj >= 0)
2112  unmark_object(obj);
2113 
2114  return 1;
2115  }
2116 
2117  if (r == 2) {
2118  delete_flag = 1;
2119  return 2;
2120  }
2121  }
2122 
2123  if ((type != REF_TYPE_SHIP) && (type != REF_TYPE_WING))
2124  return 0;
2125 
2126  for (n=0; n<Num_reinforcements; n++)
2127  if (!stricmp(name, Reinforcements[n].name))
2128  break;
2129 
2130  if (n < Num_reinforcements) {
2131  sprintf(msg, "Ship \"%s\" is a reinforcement unit.\n"
2132  "Do you want to delete it anyway?", name);
2133 
2134  r = Fred_main_wnd->MessageBox(msg, NULL, MB_YESNO | MB_ICONEXCLAMATION);
2135  if (r == IDNO) {
2136  if (obj >= 0)
2137  unmark_object(obj);
2138 
2139  return 1;
2140  }
2141  }
2142 
2143  return 0;
2144 }
2145 
2146 int orders_reference_handler(int code, char *msg)
2147 {
2148  int r, n;
2149 
2150  r = Fred_main_wnd->MessageBox(msg, "Warning", MB_YESNOCANCEL | MB_ICONEXCLAMATION);
2151  if (r == IDNO)
2152  return 1;
2153 
2154  if (r == IDYES)
2155  return 0;
2156 
2157  ShipGoalsDlg dlg_goals;
2158 
2159  n = code & SRC_DATA_MASK;
2160  switch (code & SRC_MASK) {
2161  case SRC_SHIP_ORDER:
2162  unmark_all();
2163  mark_object(Ships[n].objnum);
2164 
2165  dlg_goals.self_ship = n;
2166  dlg_goals.DoModal();
2167  if (!query_initial_orders_empty(Ai_info[Ships[n].ai_index].goals))
2168  if ((Ships[n].wingnum >= 0) && (query_initial_orders_conflict(Ships[n].wingnum)))
2169  Fred_main_wnd->MessageBox("This ship's wing also has initial orders", "Possible conflict");
2170 
2171  break;
2172 
2173  case SRC_WING_ORDER:
2174  unmark_all();
2175  mark_wing(n);
2176 
2177  dlg_goals.self_wing = n;
2178  dlg_goals.DoModal();
2180  Fred_main_wnd->MessageBox("One or more ships of this wing also has initial orders", "Possible conflict");
2181 
2182  break;
2183 
2184  default: // very bad. Someone added an sexp somewhere and didn't change this.
2185  Error(LOCATION, "Unknown initial order reference source");
2186  }
2187 
2188  delete_flag = 1;
2189  return 2;
2190 }
2191 
2192 int sexp_reference_handler(int node, int code, char *msg)
2193 {
2194  int r;
2195 
2196  r = Fred_main_wnd->MessageBox(msg, "Warning", MB_YESNOCANCEL | MB_ICONEXCLAMATION);
2197  if (r == IDNO)
2198  return 1;
2199 
2200  if (r == IDYES)
2201  return 0;
2202 
2203  switch (code & SRC_MASK) {
2204  case SRC_SHIP_ARRIVAL:
2205  case SRC_SHIP_DEPARTURE:
2206  if (!Ship_editor_dialog.GetSafeHwnd())
2208 
2209  Ship_editor_dialog.SetWindowPos(&Fred_main_wnd->wndTop, 0, 0, 0, 0,
2210  SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
2211  Ship_editor_dialog.ShowWindow(SW_RESTORE);
2212 
2214  unmark_all();
2215  mark_object(Ships[code & SRC_DATA_MASK].objnum);
2216  break;
2217 
2218  case SRC_WING_ARRIVAL:
2219  case SRC_WING_DEPARTURE:
2220  if (!Wing_editor_dialog.GetSafeHwnd())
2222 
2223  Wing_editor_dialog.SetWindowPos(&Fred_main_wnd->wndTop, 0, 0, 0, 0,
2224  SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
2225  Wing_editor_dialog.ShowWindow(SW_RESTORE);
2226 
2228  unmark_all();
2229  mark_wing(code & SRC_DATA_MASK);
2230  break;
2231 
2232  case SRC_EVENT:
2233  if (Message_editor_dlg) {
2234  Fred_main_wnd->MessageBox("You must close the message editor before the event editor can be opened");
2235  break;
2236  }
2237 
2238  if (!Event_editor_dlg) {
2242  }
2243 
2244  Event_editor_dlg->SetWindowPos(&CWnd::wndTop, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
2245  Event_editor_dlg->ShowWindow(SW_RESTORE);
2246  break;
2247 
2248  case SRC_MISSION_GOAL: {
2249  CMissionGoalsDlg dlg;
2250 
2251  dlg.select_sexp_node = node;
2252  dlg.DoModal();
2253  break;
2254  }
2255 
2256  case SRC_DEBRIEFING: {
2258 
2259  dlg.select_sexp_node = node;
2260  dlg.DoModal();
2261  break;
2262  }
2263 
2264  case SRC_BRIEFING: {
2265  if (!Briefing_dialog) {
2268  }
2269 
2270  Briefing_dialog->SetWindowPos(&Briefing_dialog->wndTop, 0, 0, 0, 0,
2271  SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
2272  Briefing_dialog->ShowWindow(SW_RESTORE);
2273  Briefing_dialog->focus_sexp(node);
2274  break;
2275  }
2276 
2277  default: // very bad. Someone added an sexp somewhere and didn't change this.
2278  Error(LOCATION, "Unknown sexp reference source");
2279  }
2280 
2281  delete_flag = 1;
2282  return 2;
2283 }
2284 
2285 char *object_name(int obj)
2286 {
2287  static char text[80];
2288  waypoint_list *wp_list;
2289  int waypoint_num;
2290 
2291  if (!query_valid_object(obj))
2292  return "*none*";
2293 
2294  switch (Objects[obj].type) {
2295  case OBJ_SHIP:
2296  case OBJ_START:
2297  return Ships[Objects[obj].instance].ship_name;
2298 
2299  case OBJ_WAYPOINT:
2300  wp_list = find_waypoint_list_with_instance(Objects[obj].instance, &waypoint_num);
2301  Assert(wp_list != NULL);
2302  sprintf(text, "%s:%d", wp_list->get_name(), waypoint_num + 1);
2303  return text;
2304 
2305  case OBJ_POINT:
2306  return "Briefing icon";
2307  }
2308 
2309  return "*unknown*";
2310 }
2311 
2313 {
2314  int i;
2315 
2316  if (order == AI_GOAL_NONE) // special case
2317  return "None";
2318 
2319  for (i=0; i<Ai_goal_list_size; i++)
2320  if (Ai_goal_list[i].def & order)
2321  return Ai_goal_list[i].name;
2322 
2323  return "???";
2324 }
2325 
2326 void object_moved(object *objp)
2327 {
2328  if (objp->type == OBJ_WAYPOINT)
2329  {
2331  Assert(wpt != NULL);
2332  wpt->set_pos(&objp->pos);
2333  }
2334 
2335  if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) // do we have a ship?
2336  {
2337  // reset the already-handled flag (inefficient, but it's FRED, so who cares)
2338  for (int i = 0; i < MAX_OBJECTS; i++)
2340 
2341  // move all docked objects docked to me
2343  }
2344 }
2345 
2346 // determine if all the ships in a given wing are all marked or not.
2348 {
2349  int count = 0;
2350  object *ptr;
2351 
2352  if (!Wings[wing].wave_count)
2353  return 0;
2354 
2355  ptr = GET_FIRST(&obj_used_list);
2356  while (ptr != END_OF_LIST(&obj_used_list)) {
2357  if (ptr->flags & OF_MARKED)
2358  if ((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START))
2359  if (Ships[get_ship_from_obj(ptr)].wingnum == wing)
2360  count++;
2361 
2362  ptr = GET_NEXT(ptr);
2363  }
2364 
2365  if (count == Wings[wing].wave_count)
2366  return 1;
2367 
2368  return 0;
2369 }
2370 
2371 void generate_ship_usage_list(int *arr, int wing)
2372 {
2373  int i;
2374 
2375  if (wing < 0) {
2376  return;
2377  }
2378 
2379  i = Wings[wing].wave_count;
2380  while (i--) {
2382  }
2383 }
2384 
2386 {
2387  int i, j;
2388  ship_weapon *swp;
2389 
2390  if (wing < 0)
2391  return;
2392 
2393  i = Wings[wing].wave_count;
2394  while (i--) {
2395  swp = &Ships[Wings[wing].ship_index[i]].weapons;
2396  j = swp->num_primary_banks;
2397  while (j--) {
2398  if (swp->primary_bank_weapons[j] >= 0 && swp->primary_bank_weapons[j] < MAX_WEAPON_TYPES) {
2399  arr[swp->primary_bank_weapons[j]]++;
2400  }
2401  }
2402 
2403  j = swp->num_secondary_banks;
2404  while (j--) {
2405  if (swp->secondary_bank_weapons[j] >=0 && swp->secondary_bank_weapons[j] < MAX_WEAPON_TYPES) {
2406  arr[swp->secondary_bank_weapons[j]] += (int) floor((swp->secondary_bank_ammo[j] * swp->secondary_bank_capacity[j] / 100.0f / Weapon_info[swp->secondary_bank_weapons[j]].cargo_size) + 0.5f);
2407  }
2408  }
2409  }
2410 }
2411 
2413 {
2414  int i;
2415 
2416  for (i=0; i<MAX_WEAPON_TYPES; i++)
2417  arr[i] = 0;
2418 
2420  Assert (team >= 0 && team < MAX_TVT_TEAMS);
2421 
2422  for (i=0; i<MAX_TVT_WINGS_PER_TEAM; i++) {
2423  generate_weaponry_usage_list(arr, TVT_wings[(team * MAX_TVT_WINGS_PER_TEAM) + i]);
2424  }
2425  }
2426  else {
2427  for (i=0; i<MAX_STARTING_WINGS; i++) {
2429  }
2430  }
2431 }
2432 
2434 {
2435  CJumpNode *jnp = jumpnode_get_by_name((LPCTSTR) name);
2436  return jnp;
2437 }
2438 
2439 // function which adds all current ships in the Fred mission to the passed in combo box. useful for
2440 // building up ship lists for arrival/departure targets
2441 void management_add_ships_to_combo( CComboBox *box, int flags )
2442 {
2443  int get_special_anchor(char *name);
2444  object *objp;
2445  int id, i, restrict_to_players;
2446 
2447  box->ResetContent();
2448 
2449  // add the "special" targets, i.e. any friendly, any hostile, etc.
2450  if (flags & SHIPS_2_COMBO_SPECIAL)
2451  {
2452  for (restrict_to_players = 0; restrict_to_players < 2; restrict_to_players++)
2453  {
2454  for (i = 0; i < Num_iffs; i++)
2455  {
2456  char tmp[NAME_LENGTH + 15];
2457  stuff_special_arrival_anchor_name(tmp, i, restrict_to_players, 0);
2458 
2459  id = box->AddString(tmp);
2460  box->SetItemData(id, get_special_anchor(tmp));
2461  }
2462  }
2463  }
2464 
2465  // either add all ships to the list, or only add ships with docking bays.
2466  if ( flags & SHIPS_2_COMBO_ALL_SHIPS ) {
2467  for ( objp = GET_FIRST(&obj_used_list); objp != END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
2468  if ( ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && !(objp->flags & OF_MARKED) ) {
2469  id = box->AddString(Ships[get_ship_from_obj(objp)].ship_name);
2470  box->SetItemData(id, get_ship_from_obj(objp));
2471  }
2472  }
2473  } else if ( flags & SHIPS_2_COMBO_DOCKING_BAY_ONLY ) {
2474  for ( objp = GET_FIRST(&obj_used_list); objp != END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
2475  if ( ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && !(objp->flags & OF_MARKED) ) {
2476  polymodel *pm;
2477 
2478  // determine if this ship has a docking bay
2479  pm = model_get( Ship_info[Ships[objp->instance].ship_info_index].model_num );
2480  Assert( pm );
2481  if ( pm->ship_bay && (pm->ship_bay->num_paths > 0) ) {
2482  id = box->AddString(Ships[get_ship_from_obj(objp)].ship_name);
2483  box->SetItemData(id, get_ship_from_obj(objp));
2484  }
2485  }
2486  }
2487  }
2488 }
2489 
2490 char *reg_read_string( char *section, char *name, char *default_value )
2491 {
2492  HKEY hKey = NULL;
2493  DWORD dwType, dwLen;
2494  char keyname[1024];
2495  static char tmp_string_data[1024];
2496  LONG lResult;
2497 
2498  strcpy_s( keyname, section );
2499 
2500  lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, // Where it is
2501  keyname, // name of key
2502  NULL, // DWORD reserved
2503  KEY_QUERY_VALUE, // Allows all changes
2504  &hKey ); // Location to store key
2505 
2506  if ( lResult != ERROR_SUCCESS ) {
2507  mprintf(( "Error opening registry key '%s'\n", keyname ));
2508  goto Cleanup;
2509  }
2510 
2511  if ( !name ) {
2512  mprintf(( "No variable name passed\n" ));
2513  goto Cleanup;
2514  }
2515 
2516  dwLen = 1024;
2517  lResult = RegQueryValueEx( hKey, // Handle to key
2518  name, // The values name
2519  NULL, // DWORD reserved
2520  &dwType, // What kind it is
2521  (ubyte *)&tmp_string_data, // value to set
2522  &dwLen ); // How many bytes to set
2523 
2524  if ( lResult != ERROR_SUCCESS ) {
2525  mprintf(( "Error reading registry key '%s'\n", name ));
2526  goto Cleanup;
2527  }
2528 
2529  default_value = tmp_string_data;
2530 
2531 Cleanup:
2532  if ( hKey )
2533  RegCloseKey(hKey);
2534 
2535  return default_value;
2536 }
2537 
2538 // Goober5000
2540 {
2541  int i;
2542 
2543  if (wing < 0)
2544  return 0;
2545 
2547  {
2548  for (i=0; i<MAX_TVT_WINGS; i++)
2549  {
2550  if (wing == TVT_wings[i])
2551  return 1;
2552  }
2553  }
2554  else
2555  {
2556  for (i=0; i<MAX_STARTING_WINGS; i++)
2557  {
2558  if (wing == Starting_wings[i])
2559  return 1;
2560  }
2561  }
2562 
2563  return 0;
2564 }
2565 
2566 // Goober5000
2567 // This must be done when either the wing name or the custom name is changed.
2568 // (It's also duplicated in FS2, in post_process_mission, for setting the indexes at mission load.)
2570 {
2571  int i;
2572 
2573  for (i = 0; i < MAX_STARTING_WINGS; i++)
2574  {
2576  }
2577 
2578  for (i = 0; i < MAX_SQUADRON_WINGS; i++)
2579  {
2581  }
2582 
2583  for (i = 0; i < MAX_TVT_WINGS; i++)
2584  {
2586  }
2587 }
2588 
2589 // Goober5000
2590 void stuff_special_arrival_anchor_name(char *buf, int iff_index, int restrict_to_players, int retail_format)
2591 {
2592  char *iff_name = Iff_info[iff_index].iff_name;
2593 
2594  // stupid retail hack
2595  if (retail_format && !stricmp(iff_name, "hostile") && !restrict_to_players)
2596  iff_name = "enemy";
2597 
2598  if (restrict_to_players)
2599  sprintf(buf, "<any %s player>", iff_name);
2600  else
2601  sprintf(buf, "<any %s>", iff_name);
2602 
2603  strlwr(buf);
2604 }
2605 
2606 // Goober5000
2607 void stuff_special_arrival_anchor_name(char *buf, int anchor_num, int retail_format)
2608 {
2609  // filter out iff
2610  int iff_index = anchor_num;
2611  iff_index &= ~SPECIAL_ARRIVAL_ANCHOR_FLAG;
2612  iff_index &= ~SPECIAL_ARRIVAL_ANCHOR_PLAYER_FLAG;
2613 
2614  // filter players
2615  int restrict_to_players = (anchor_num & SPECIAL_ARRIVAL_ANCHOR_PLAYER_FLAG);
2616 
2617  // get name
2618  stuff_special_arrival_anchor_name(buf, iff_index, restrict_to_players, retail_format);
2619 }
2620 
2621 // Goober5000
2622 void update_texture_replacements(const char *old_name, const char *new_name)
2623 {
2625  {
2626  if (!stricmp(ii->ship_name, old_name))
2627  strcpy_s(ii->ship_name, new_name);
2628  }
2629 }
field_type_t field_type
Definition: asteroid.h:136
void mod_table_init()
Definition: mod_table.cpp:345
int Neb2_poof_flags
Definition: neb.cpp:64
float max_rear_vel
Definition: physics.h:53
char * Mission_text
Definition: parselo.cpp:46
matrix skybox_orientation
Definition: missionparse.h:148
void clear_mission()
Definition: management.cpp:790
int dup_sexp_chain(int node)
Definition: sexp.cpp:1379
char Voice_abbrev_command_briefing[NAME_LENGTH]
char Starting_wing_names[MAX_STARTING_WINGS][NAME_LENGTH]
Definition: ship.cpp:139
char Neb2_texture_name[MAX_FILENAME_LEN]
Definition: neb.cpp:75
wing Wings[MAX_WINGS]
Definition: ship.cpp:128
void wing_bash_ship_name(char *ship_name, const char *wing_name, int index)
Definition: ship.cpp:12686
int i
Definition: multi_pxo.cpp:466
CFREDApp theApp
Definition: fred.cpp:115
void fred_render_init()
Definition: fredrender.cpp:155
int Nebula_heading
Definition: nebula.cpp:40
uint num_respawns
Definition: missionparse.h:141
#define AI_GOAL_UNDOCK
Definition: aigoals.h:36
void species_init()
int primary_bank_weapons[MAX_SHIP_PRIMARY_BANKS]
Definition: ship.h:103
int Id_select_type_waypoint
Definition: fredview.cpp:112
bool gr_init(int d_mode, int d_width, int d_height, int d_depth)
Definition: 2d.cpp:909
int Nmodel_flags
Definition: starfield.cpp:169
int create_waypoint(vec3d *pos, int waypoint_instance)
Definition: management.cpp:769
#define SRC_SHIP_ARRIVAL
Definition: sexp.h:842
int Locked_sexp_false
Definition: sexp.cpp:828
void correct_marking()
void fhash_init()
Definition: fhash.cpp:55
bool weapon_required[MAX_WEAPON_TYPES]
Definition: missionparse.h:544
void init_pending_messages(void)
Definition: fred.cpp:437
int Undo_count
Definition: freddoc.cpp:93
void generate_weaponry_usage_list(int *arr, int wing)
int team
Definition: ship.h:606
int player_start1
Definition: fredrender.cpp:77
#define SRC_DEBRIEFING
Definition: sexp.h:850
void ai_update_goal_references(int type, const char *old_name, const char *new_name)
CMessageEditorDlg * Message_editor_dlg
int Num_mission_events
#define MB_YESNO
Definition: config.h:182
#define SEXP_ATOM_OPERATOR
Definition: sexp.h:911
int create_object(vec3d *pos, int waypoint_instance)
Definition: management.cpp:695
char * get_name()
Definition: waypoint.cpp:84
int num_primary_banks
Definition: ship.h:99
CString m_ship_name
Definition: shipeditordlg.h:99
int game_type
Definition: missionparse.h:138
int Player_start_shipnum
Marking_box marking_box
Definition: fredview.cpp:116
int cur_wing_index
Definition: management.cpp:78
int update_dialog_boxes()
CShipEditorDlg Ship_editor_dialog
Definition: fred.cpp:55
void initialize_data(int full_update)
void gamesnd_parse_soundstbl()
Definition: gamesnd.cpp:1116
polymodel * model_get(int model_num)
Definition: modelread.cpp:3134
weapon_info Weapon_info[MAX_WEAPON_TYPES]
Definition: weapons.cpp:79
void nebula_init(const char *filename, int pitch, int bank, int heading)
Definition: nebula.cpp:133
ship_weapon weapons
Definition: ship.h:658
int Num_ai_dock_names
Definition: aigoals.cpp:59
void update_custom_wing_indexes()
#define OF_TEMP_MARKED
Definition: object.h:126
void brief_reset()
void mission_campaign_clear()
#define REF_TYPE_WING
Definition: sexp.h:837
char name[NAME_LENGTH]
Definition: missionparse.h:131
GLuint index
Definition: Glext.h:5608
#define AI_GOAL_CHASE_WING
Definition: aigoals.h:37
void unmark_all()
char * model_get_dock_name(int modelnum, int index)
Definition: modelread.cpp:5103
#define AI_GOAL_DOCK
Definition: aigoals.h:30
void waypoint_parse_init()
Definition: waypoint.cpp:101
physics_info phys_info
Definition: object.h:157
int Xstr_inited
Definition: localize.cpp:73
#define MAX_WINGS
Definition: globals.h:50
#define AI_GOAL_WAYPOINTS
Definition: aigoals.h:31
#define MAX_SHIPS
Definition: globals.h:37
char * object_name(int obj)
void object_moved(object *objp)
int model_get_dock_index_type(int modelnum, int index)
Definition: modelread.cpp:5120
#define SRC_DATA_MASK
Definition: sexp.h:854
void generate_ship_popup_menu(CMenu *mptr, int first_id, int state, int filter)
int replace_all(char *str, char *oldstr, char *newstr, uint max_len, int range)
Definition: parselo.cpp:3941
#define AI_GOAL_GUARD
Definition: aigoals.h:38
#define DEFAULT_NMODEL_FLAGS
Definition: starfield.h:20
int rename_ship(int ship, char *name)
int arrival_location
Definition: ship.h:610
#define SHIPS_2_COMBO_DOCKING_BAY_ONLY
Definition: management.h:135
#define MAX_DOCKS
Definition: management.cpp:71
waypoint_list * find_waypoint_list_with_instance(int waypoint_instance, int *waypoint_index)
Definition: waypoint.cpp:254
int delete_object(int obj)
void obj_init()
Definition: object.cpp:327
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
int generic_anim_load(generic_anim *ga)
Definition: generic.cpp:138
Assert(pm!=NULL)
#define FS2_OPEN_DEFAULT_LANGUAGE
Definition: localize.h:28
int special_exp_blast
Definition: ship.h:586
int Id_select_type_jump_node
Definition: fredview.cpp:110
void stuff_special_arrival_anchor_name(char *buf, int iff_index, int restrict_to_players, int retail_format)
int departure_location
Definition: ship.h:617
Definition: pstypes.h:88
char Fred_alt_names[MAX_SHIPS][NAME_LENGTH+1]
Definition: management.cpp:93
#define mprintf(args)
Definition: pstypes.h:238
int ai_index
Definition: ship.h:538
int bypass_update
Definition: management.cpp:85
int ai_class
Definition: ai.h:369
#define AI_GOAL_STAY_NEAR_SHIP
Definition: aigoals.h:47
char wing_squad_filename[MAX_FILENAME_LEN]
Definition: ship.h:1518
#define AI_GOAL_CHASE_ANY
Definition: aigoals.h:41
void stars_pre_level_init(bool clear_backgrounds)
Definition: starfield.cpp:714
void write_ini_file(int degree=0)
Definition: fred.cpp:552
void set_cur_wing(int wing)
struct vec3d::@225::@227 xyz
char * reg_read_string(char *section, char *name, char *default_value)
CButton * team
int skybox_flags
Definition: missionparse.h:150
int Nebula_index
int update_data(int redraw=1)
#define FS_VERSION_MAJOR
Definition: version.h:37
vec3d max_vel
Definition: physics.h:49
GLclampf f
Definition: Glext.h:7097
void set_cur_indices(int obj)
int snd_init()
Definition: sound.cpp:131
void update_sexp_references(const char *old_name, const char *new_name, int format, int node)
Definition: sexp.cpp:28332
#define MAX_OBJECTS
Definition: globals.h:83
void os_init_registry_stuff(const char *company, const char *app, const char *version)
Definition: osregistry.cpp:423
void fiction_viewer_reset()
#define AI_GOAL_WARP
Definition: aigoals.h:33
#define TRUE
Definition: pstypes.h:399
int Mouse_hidden
Definition: mouse.cpp:52
#define OF_NO_SHIELDS
Definition: object.h:110
int Num_cargo
#define AI_GOAL_IGNORE
Definition: aigoals.h:42
int max_respawn_delay
Definition: missionparse.h:142
ai_info Ai_info[MAX_AI_INFO]
Definition: ai.cpp:23
void lcl_init(int lang_init)
Definition: localize.cpp:107
int query_referenced_in_sexp(int mode, char *name, int *node)
Definition: sexp.cpp:28382
object obj_used_list
Definition: object.cpp:53
int cur_wing
Definition: management.cpp:77
#define AI_GOAL_DISARM_SHIP
Definition: aigoals.h:40
CMainFrame * Fred_main_wnd
Definition: mainfrm.cpp:89
Definition: ship.h:1516
int alloc_sexp(char *text, int type, int subtype, int first, int rest)
Definition: sexp.cpp:1123
void ship_init()
Definition: ship.cpp:5086
int wing_insignia_texture
Definition: ship.h:1566
#define MB_YESNOCANCEL
Definition: config.h:183
Definition: ai.h:329
int physics_speed
Definition: fredview.cpp:105
uint flags
Definition: ship.h:644
int Marked
Definition: fredview.cpp:101
waypoint_list * cur_waypoint_list
Definition: management.cpp:83
int model_get_num_dock_points(int modelnum)
Definition: modelread.cpp:5112
#define MAX_SHIPS_PER_WING
Definition: globals.h:52
hull_check orient
Definition: lua.cpp:5049
std::basic_string< char, std::char_traits< char >, std::allocator< char > > SCP_string
Definition: vmallocator.h:21
void obj_merge_created_list(void)
Definition: object.cpp:651
int delete_ship_from_wing(int ship)
void dock_move_docked_objects(object *objp)
Definition: objectdock.cpp:371
object * objp
Definition: lua.cpp:3105
int type
Definition: ship.h:84
int invalidate_references(char *name, int type)
vec3d inner_min_bound
Definition: asteroid.h:131
GLsizeiptr size
Definition: Glext.h:5496
void deconvert_multiline_string(char *dest, const CString &str, int max_len)
Definition: management.cpp:184
void alpha_colors_init()
#define Int3()
Definition: pstypes.h:292
void gr_font_init()
Definition: font.cpp:699
int orders_reference_handler(int code, char *msg)
vec3d max_rotvel
Definition: physics.h:52
vec3d min_bound
Definition: asteroid.h:127
#define AIF_KAMIKAZE
Definition: ai.h:55
ship_bay_t * ship_bay
Definition: model.h:776
#define MAX_SQUADRON_WINGS
Definition: globals.h:55
int GetSCPObjectNumber()
Definition: jumpnode.cpp:133
#define AI_GOAL_NONE
Definition: ai.h:194
int get_default_player_ship_index()
Returns the index of the default player ship.
Definition: ship.cpp:4862
void techroom_intel_init()
Definition: techmenu.cpp:1050
ship * shipp
Definition: lua.cpp:9162
void parse_init(bool basic=false)
vec3d pos
Definition: object.h:152
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: Glext.h:7308
#define MAX_REINFORCEMENT_MESSAGES
Definition: ship.h:78
#define MAX_TVT_WINGS
Definition: globals.h:59
vec3d max_bound
Definition: asteroid.h:128
int get_docking_list(int model_index)
vec3d view_pos
Definition: fredrender.cpp:103
mission_goal Mission_goals[MAX_GOALS]
void nebl_init()
#define GR_OPENGL
Definition: 2d.h:648
int ai_flags
Definition: ai.h:330
#define CONTRAIL_THRESHOLD_DEFAULT
Definition: missionparse.h:226
void parse_medal_tbl()
Definition: medals.cpp:246
int default_parse_flags2
Definition: iff_defs.h:47
void fix_ship_name(int ship)
Definition: management.cpp:493
#define SPECIAL_ARRIVAL_ANCHOR_FLAG
Definition: missionparse.h:37
void mission_event_shutdown()
SCP_list< CJumpNode > Jump_nodes
Definition: jumpnode.cpp:16
GLenum type
Definition: Gl.h:1492
dock_bay * docking_bays
Definition: model.h:774
const char * Osreg_app_name
Definition: osregistry.cpp:35
void create_new_mission()
Definition: management.cpp:776
void fred_preload_all_briefing_icons()
Definition: management.cpp:262
void ai_init(void)
Definition: aicode.cpp:828
int hotkey
Definition: ship.h:540
iff_info Iff_info[MAX_IFFS]
Definition: iff_defs.cpp:20
int ship_count[MAX_SHIP_CLASSES]
Definition: missionparse.h:535
HWND DWORD code
Definition: vddraw.h:425
reinforcements Reinforcements[MAX_REINFORCEMENTS]
Definition: ship.cpp:165
void reset_mission()
Definition: management.cpp:784
SCP_vector< waypoint > & get_waypoints()
Definition: waypoint.cpp:89
int num_initial_asteroids
Definition: asteroid.h:135
float Neb2_awacs
Definition: neb.cpp:156
int query_valid_object(int index)
int ship_get_num_ships()
Definition: ship.cpp:522
int Squadron_wings[MAX_SQUADRON_WINGS]
Definition: ship.cpp:135
sound_env sound_environment
Definition: missionparse.h:155
waypoint_list * get_parent_list()
Definition: waypoint.cpp:56
int object_is_docked(object *objp)
Definition: object.cpp:2019
int orders_accepted
Definition: ship.h:624
int Locked_sexp_true
Definition: sexp.cpp:828
void convert_multiline_string(CString &dest, const SCP_string &src)
Definition: management.cpp:169
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
bool use_special_explosion
Definition: ship.h:584
#define OBJ_WAYPOINT
Definition: object.h:36
#define gr_reset_clip
Definition: 2d.h:745
int instance
Definition: object.h:150
int physics_rot
Definition: fredview.cpp:106
#define MISSION_TYPE_SINGLE
Definition: missionparse.h:61
int create_object_on_grid(int waypoint_instance)
Definition: management.cpp:469
char squad_filename[MAX_FILENAME_LEN]
Definition: missionparse.h:144
#define OBJ_START
Definition: object.h:35
void mission_parse_reset_alt()
GLdouble GLdouble GLdouble r
Definition: Glext.h:5337
int update_data(int redraw=1)
#define SHIP_FILTER_FLYABLE
Definition: management.h:23
struct matrix::@228::@230 vec
char created[DATE_TIME_LENGTH]
Definition: missionparse.h:134
void resolve_parse_flags(object *objp, int parse_flags, int parse_flags2)
int subtype
Definition: lua.cpp:9763
int query_object_in_wing(int obj)
#define nprintf(args)
Definition: pstypes.h:239
char Voice_abbrev_briefing[NAME_LENGTH]
float cargo_size
Definition: weapon.h:388
matrix gmatrix
Definition: missiongrid.h:24
int create_player(int num, vec3d *pos, matrix *orient, int type, int init)
Definition: management.cpp:747
void messages_init()
void stars_post_level_init()
Definition: starfield.cpp:782
void set_cur_object_index(int obj)
matrix Nmodel_orient
Definition: starfield.cpp:168
SCP_vector< briefing_icon_info > Briefing_icon_info
#define MAX_SHIP_CLASSES
Definition: globals.h:48
int query_valid_ship(int index)
int secondary_bank_capacity[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:136
event_editor * Event_editor_dlg
Definition: eventeditor.cpp:30
int Update_wing
Definition: management.cpp:88
int vm_init(int min_heap_size)
Definition: windebug.cpp:1657
int autosave(char *desc)
Definition: freddoc.cpp:264
void ssm_init()
char * Nebula_filenames[NUM_NEBULAS]
int flags
Definition: ship.h:1227
int num_paths
Definition: model.h:540
void g3_set_view_matrix(const vec3d *view_pos, const matrix *view_matrix, float zoom)
Definition: 3dsetup.cpp:152
ai_profile_t * ai_profile
Definition: missionparse.h:168
#define SIF_SMALL_SHIP
Definition: ship.h:943
int delete_flag
Definition: management.cpp:84
int gray_menu_tree(CMenu *base)
int wingnum
Definition: ship.h:623
char Squadron_wing_names[MAX_SQUADRON_WINGS][NAME_LENGTH]
Definition: ship.cpp:140
float speed
Definition: physics.h:79
#define DEFAULT_COMMAND
#define MAX_STARTING_WINGS
Definition: globals.h:54
int num_secondary_banks
Definition: ship.h:100
ai_goal goals[MAX_AI_GOALS]
Definition: ai.h:412
mission_event Mission_events[MAX_MISSION_EVENTS]
int shipnum
Definition: ai.h:331
void cmdline_debug_print_cmdline()
Definition: cmdline.cpp:538
#define SRC_MISSION_GOAL
Definition: sexp.h:847
void brief_init_colors()
#define WP_LASER
Definition: weapon.h:27
#define MAX_WEAPON_TYPES
Definition: globals.h:73
int num_weapon_choices
Definition: missionparse.h:539
#define PF_ACCELERATES
Definition: physics.h:18
float hull_strength
Definition: object.h:160
vec3d center
Definition: missiongrid.h:23
ai_profile_t Ai_profiles[MAX_AI_PROFILES]
Definition: ai_profiles.cpp:22
int dup_object(object *objp)
Definition: management.cpp:608
#define SHIPS_2_COMBO_SPECIAL
Definition: management.h:133
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
void vm_set_identity(matrix *m)
Definition: vecmat.cpp:150
#define SHIP_FILTER_PLAYERS
Definition: management.h:22
int n_docks
Definition: model.h:770
void event_music_reset_choices()
#define UNKNOWN_USER
Definition: management.cpp:73
void set_physics_controls()
Definition: management.cpp:454
int weaponry_pool[MAX_WEAPON_TYPES]
Definition: missionparse.h:540
int update_data(int redraw=1)
#define MAX_AI_GOALS
Definition: ai.h:91
GLdouble GLdouble z
Definition: Glext.h:5451
char Voice_script_entry_format[NOTES_LENGTH]
void delete_reinforcement(int num)
void set_valid_dock_points(int ship, int type, CComboBox *box)
char squad_name[NAME_LENGTH]
Definition: missionparse.h:145
int Shield_sys_types[MAX_SHIP_CLASSES]
bool fred_init()
Definition: management.cpp:272
#define GR_640
Definition: 2d.h:652
int sexp_reference_handler(int node, int code, char *msg)
char Voice_abbrev_debriefing[NAME_LENGTH]
int Num_objects
Definition: object.cpp:68
void physics_init(physics_info *pi)
Definition: physics.cpp:49
int Nebula_bank
Definition: nebula.cpp:39
void armor_init()
Definition: ship.cpp:18394
char cargo1
Definition: ship.h:549
int uses
Definition: ship.h:85
char notes[NOTES_LENGTH]
Definition: missionparse.h:136
#define AI_GOAL_STAY_STILL
Definition: aigoals.h:52
int Num_wings
Definition: ship.cpp:120
#define MB_OK
Definition: config.h:179
#define FS_VERSION_MINOR
Definition: version.h:38
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:104
int query_whole_wing_marked(int wing)
int Num_teams
object * dock_get_first_docked_object(object *objp)
Definition: objectdock.cpp:47
int wing_objects[MAX_WINGS][MAX_SHIPS_PER_WING]
Definition: management.cpp:97
#define MAX_PLAYERS
Definition: pstypes.h:32
char skybox_model[MAX_FILENAME_LEN]
Definition: missionparse.h:147
int Voice_export_selection
matrix eye_orient
Definition: fredrender.cpp:112
CFREDDoc * FREDDoc_ptr
Definition: freddoc.cpp:90
int waypoint_add(vec3d *pos, int waypoint_instance)
Definition: waypoint.cpp:401
void event_music_init()
Definition: eventmusic.cpp:261
int wing_is_player_wing(int wing)
Definition: ship.h:534
#define SRC_WING_DEPARTURE
Definition: sexp.h:845
GLenum GLuint id
Definition: Glext.h:5156
vec3d eye_pos
Definition: fredrender.cpp:103
#define REF_TYPE_WAYPOINT
Definition: sexp.h:839
char Mission_filename[80]
char Voice_abbrev_message[NAME_LENGTH]
#define AI_GOAL_EVADE_SHIP
Definition: aigoals.h:44
unsigned long DWORD
Definition: config.h:90
int Default_player_model
Definition: management.cpp:86
int cur_model_index
Definition: management.cpp:81
#define SRC_EVENT
Definition: sexp.h:846
int cfile_chdir(const char *dir)
Change to the specified directory.
Definition: cfile.cpp:372
#define SIF_DEFAULT_PLAYER_SHIP
Definition: ship.h:876
char Fred_base_dir[512]
Definition: management.cpp:91
int secondary_bank_ammo[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:134
void allocate_mission_text(int size)
Definition: parselo.cpp:2088
int query_valid_waypoint(int index)
void neb2_init()
Definition: neb.cpp:250
GLdouble GLdouble t
Definition: Glext.h:5329
int Cmdline_window
Definition: cmdline.cpp:502
int delete_ship(int ship)
char loading_screen[GR_NUM_RESOLUTIONS][MAX_FILENAME_LEN]
Definition: missionparse.h:146
int wave_count
Definition: ship.h:1527
#define AI_GOAL_IGNORE_NEW
Definition: aigoals.h:57
#define REF_TYPE_PATH
Definition: sexp.h:840
class object * next
Definition: object.h:144
object Objects[MAX_OBJECTS]
Definition: object.cpp:62
ai_goal_list Ai_goal_list[]
Definition: management.cpp:106
GLclampd n
Definition: Glext.h:7286
unsigned char ubyte
Definition: pstypes.h:62
#define AI_GOAL_PLAY_DEAD
Definition: aigoals.h:53
#define SPECIAL_ARRIVAL_ANCHOR_PLAYER_FLAG
Definition: missionparse.h:38
uint flags
Definition: physics.h:37
bool Voice_no_replace_filenames
void string_copy(char *dest, const CString &src, int max_len, int modify)
Definition: management.cpp:142
int ship_create(matrix *orient, vec3d *pos, int ship_type, char *ship_name)
Definition: ship.cpp:9690
void debrief_reset()
SCP_vector< mission_cutscene > cutscenes
Definition: missionparse.h:170
#define SRC_SHIP_ORDER
Definition: sexp.h:848
#define AI_GOAL_WAYPOINTS_ONCE
Definition: aigoals.h:32
#define OBJ_INDEX(objp)
Definition: object.h:235
#define OF_MARKED
Definition: object.h:125
void weapon_init()
Definition: weapons.cpp:3516
#define vm_vec_make(v, _x, _y, _z)
Definition: vecmat.h:48
char modified[DATE_TIME_LENGTH]
Definition: missionparse.h:135
matrix orient
Definition: object.h:153
void mission_brief_common_init()
void hud_init_comm_orders()
long LONG
Definition: config.h:95
bool Show_iff[MAX_IFFS]
Definition: management.cpp:102
int TVT_wings[MAX_TVT_WINGS]
Definition: ship.cpp:136
#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
waypoint * find_waypoint_with_instance(int waypoint_instance)
Definition: waypoint.cpp:279
wing_editor Wing_editor_dialog
Definition: fred.cpp:56
#define AI_GOAL_GUARD_WING
Definition: aigoals.h:43
physics_info view_physics
Definition: fredrender.cpp:114
GLbitfield flags
Definition: Glext.h:6722
void jumpnode_level_close()
Definition: jumpnode.cpp:485
int wing_name_lookup(const char *name, int ignore_count)
Definition: ship.cpp:12706
#define REF_TYPE_PLAYER
Definition: sexp.h:838
int Starting_wings[MAX_STARTING_WINGS]
Definition: ship.cpp:132
void set_modified(BOOL arg)
Definition: freddoc.cpp:676
GLuint const GLchar * name
Definition: Glext.h:5608
int weaponry_count[MAX_WEAPON_TYPES]
Definition: missionparse.h:541
int get_special_anchor(char *name)
#define SRC_BRIEFING
Definition: sexp.h:851
#define MAX_PATH_LEN
Definition: pstypes.h:325
float fspeed
Definition: physics.h:80
char command_sender[NAME_LENGTH]
Definition: missionparse.h:159
char * name
Definition: pstypes.h:206
#define MISSION_TYPE_TRAINING
Definition: missionparse.h:63
int create_ship(matrix *orient, vec3d *pos, int ship_type)
Definition: management.cpp:502
char * get_order_name(int order)
const char * Osreg_company_name
Definition: osregistry.cpp:28
ship Ships[MAX_SHIPS]
Definition: ship.cpp:122
int query_referenced_in_ai_goals(int type, const char *name)
int string_lookup(const CString &str1, char *strlist[], int max)
#define REF_TYPE_SHIP
Definition: sexp.h:836
CJumpNode * jumpnode_get_by_name(const CString &name)
if(aifft_max_checks<=0)
Definition: aiturret.cpp:1581
int special_shield
Definition: ship.h:594
int Shield_sys_teams[MAX_IFFS]
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
int arrival_delay
Definition: ship.h:87
GLuint GLuint num
Definition: Glext.h:9089
#define WIF_PLAYER_ALLOWED
Definition: weapon.h:68
#define SF_REINFORCEMENT
Definition: ship.h:437
void mouse_init()
Definition: mouse.cpp:103
void obj_delete(int objnum)
Definition: object.cpp:522
void model_free_all()
Definition: modelread.cpp:337
#define MB_ICONEXCLAMATION
Definition: config.h:184
#define MAX_AI_INFO
Definition: ai.h:564
#define FS_VERSION_REVIS
Definition: version.h:40
#define EOF_CHAR
Definition: parselo.h:31
#define AI_GOAL_KEEP_SAFE_DISTANCE
Definition: aigoals.h:48
int field_debris_type[MAX_ACTIVE_DEBRIS_TYPES]
Definition: asteroid.h:138
#define NAME_LENGTH
Definition: globals.h:15
int delete_wing(int wing_num, int bypass)
Definition: wing.cpp:72
#define AI_GOAL_DISABLE_SHIP
Definition: aigoals.h:39
char Mission_parse_storm_name[NAME_LENGTH]
int Id_select_type_start
Definition: fredview.cpp:111
void waypoint_level_close()
Definition: waypoint.cpp:106
int Default_ai_profile
Definition: ai_profiles.cpp:21
int common_object_delete(int obj)
int select_sexp_node
Definition: wing_editor.h:24
int behavior
Definition: ai.h:335
#define SEXP_ATOM
Definition: sexp.h:864
int fred2_parse_cmdline(int argc, char *argv[])
Definition: cmdline.cpp:1813
int special_ship
Definition: ship.h:1537
void mark_object(int obj)
void ai_profiles_init()
int Show_starts
Definition: fredview.cpp:89
int set_reinforcement(char *name, int state)
#define DEPART_ITEM
Definition: hudsquadmsg.h:56
int query_initial_orders_empty(ai_goal *ai_goals)
void generate_wing_popup_menu(CMenu *mptr, int first_id, int state)
#define SHIPS_2_COMBO_ALL_SHIPS
Definition: management.h:134
int Ai_goal_list_size
Definition: management.cpp:127
int cur_ship
Definition: management.cpp:80
void copy_bits(int *dest, int src, int mask)
Definition: management.cpp:602
char * Docking_bay_list[MAX_DOCKS]
Definition: management.cpp:99
void fhash_activate()
Definition: fhash.cpp:61
int ship_info_index
Definition: ship.h:539
char * Mission_text_raw
Definition: parselo.cpp:47
#define MAX_NEB2_POOFS
Definition: neb.h:45
#define MAX_REINFORCEMENTS
Definition: ship.h:58
int verify_sexp_tree(int node)
Definition: sexp.cpp:1353
waypoint_path_dlg Waypoint_editor_dialog
Definition: fred.cpp:57
GLenum src
Definition: Glext.h:5917
SCP_vector< ship_info > Ship_info
Definition: ship.cpp:164
#define LOCATION
Definition: pstypes.h:245
void ai_do_objects_undocked_stuff(object *docker, object *dockee)
Definition: aicode.cpp:3054
#define WF_REINFORCEMENT
Definition: ship.h:1504
#define AIF_NO_DYNAMIC
Definition: ai.h:56
int MessageBox(HWND h, const char *s1, const char *s2, int i)
int departure_delay
Definition: ship.h:621
char name[MAX_NAME_LEN]
Definition: model.h:529
char TVT_wing_names[MAX_TVT_WINGS][NAME_LENGTH]
Definition: ship.cpp:141
void cmd_brief_reset()
int hud_anim_load(hud_anim *ha)
Load a hud_anim.
Definition: hud.cpp:2193
int Update_ship
Definition: management.cpp:87
int has_inner_bound
Definition: asteroid.h:130
SCP_vector< float > shield_quadrant
Definition: object.h:159
SCP_vector< species_info > Species_info
#define PF_SLIDE_ENABLED
Definition: physics.h:21
char mission_desc[MISSION_DESC_LENGTH]
Definition: missionparse.h:137
void delete_marked()
int ship_get_default_orders_accepted(ship_info *sip)
Definition: ship.cpp:5480
hull_check pos
Definition: lua.cpp:5050
int Show_ships
Definition: fredview.cpp:88
#define MAX_TVT_WINGS_PER_TEAM
Definition: globals.h:58
GLsizei GLsizei GLuint * obj
Definition: Glext.h:5619
int ENVMAP
References a map that is for environment mapping -Bobboau.
Definition: bmpman.cpp:59
#define MAX_TVT_TEAMS
Definition: globals.h:57
#define AI_GOAL_CHASE
Definition: aigoals.h:29
CCriticalSection CS_cur_object_index
Definition: management.cpp:104
void set_pos(vec3d *pos)
Definition: waypoint.cpp:61
#define SIF_NOT_FLYABLE
Definition: ship.h:946
int threshold
Definition: ship.h:1523
void unmark_object(int obj)
vec3d inner_max_bound
Definition: asteroid.h:132
#define SRC_MASK
Definition: sexp.h:853
debris_genre_t debris_genre
Definition: asteroid.h:137
GLint GLsizei count
Definition: Gl.h:1491
int internal_integrity_check()
int query_initial_orders_conflict(int wing)
#define ID_PLACEHOLDER
Definition: resource.h:1288
team_data Team_data[MAX_TVT_TEAMS]
GLenum GLsizei len
Definition: Glext.h:6283
void timer_init()
Definition: timer.cpp:55
int Default_command_persona
#define FS_VERSION_BUILD
Definition: version.h:39
void mark_wing(int wing)
Definition: wing.cpp:60
GLuint GLdouble GLdouble GLint GLint order
Definition: Glext.h:10665
int Num_reinforcements
Definition: ship.cpp:121
Definition: ai.h:134
void iff_init()
Definition: iff_defs.cpp:117
#define MAX_IFFS
Definition: globals.h:34
#define OF_HIDDEN
Definition: object.h:127
int Nmodel_bitmap
Definition: starfield.cpp:170
int cur_object_index
Definition: management.cpp:79
int kamikaze_damage
Definition: ai.h:523
int ship_index[MAX_SHIPS_PER_WING]
Definition: ship.h:1531
polymodel * pm
Definition: lua.cpp:1598
int command_persona
Definition: missionparse.h:158
grid * The_grid
Definition: missiongrid.cpp:20
void mission_parse_reset_callsign()
int departure_cue
Definition: ship.h:620
int select_sexp_node
Definition: eventeditor.h:50
int Num_iffs
Definition: iff_defs.cpp:19
float fvi_ray_plane(vec3d *new_pnt, const vec3d *plane_pnt, const vec3d *plane_norm, const vec3d *ray_origin, const vec3d *ray_direction, float rad)
Definition: fvi.cpp:118
int reference_handler(char *name, int type, int obj)
asteroid_field Asteroid_field
Definition: asteroid.cpp:64
char Voice_abbrev_mission[NAME_LENGTH]
int contrail_threshold
Definition: missionparse.h:151
SCP_vector< texture_replace > Fred_texture_replacements
#define OBJ_NONE
Definition: object.h:31
briefing_editor_dlg * Briefing_dialog
Definition: fred.cpp:59
int ship_name_lookup(const char *name, int inc_players)
Definition: ship.cpp:12900
int arrival_cue
Definition: ship.h:614
float max_hull_strength
Definition: ship.h:1309
char envmap_name[MAX_FILENAME_LEN]
Definition: missionparse.h:149
void clear_menu(CMenu *ptr)
void generate_ship_usage_list(int *arr, int wing)
int get_ship_from_obj(int obj)
uint flags
Definition: object.h:151
void brief_parse_icon_tbl()
mission The_mission
char Fred_callsigns[MAX_SHIPS][NAME_LENGTH+1]
Definition: management.cpp:94
#define AI_GOAL_DESTROY_SUBSYSTEM
Definition: aigoals.h:34
int Num_goals
void stars_init()
Definition: starfield.cpp:693
int Show_waypoints
Definition: object.cpp:73
char type
Definition: object.h:146
#define SRC_WING_ORDER
Definition: sexp.h:849
vec3d vmd_zero_vector
Definition: vecmat.cpp:24
support_ship_info support_ships
Definition: missionparse.h:143
#define SRC_SHIP_DEPARTURE
Definition: sexp.h:843
char Voice_abbrev_campaign[NAME_LENGTH]
void strlwr(char *s)
waypoint * cur_waypoint
Definition: management.cpp:82
void waypoint_remove(waypoint *wpt)
Definition: waypoint.cpp:466
#define FALSE
Definition: pstypes.h:400
void init_sexp()
Definition: sexp.cpp:1090
#define gr_set_gamma
Definition: 2d.h:829
int Nmodel_instance_num
Definition: starfield.cpp:167
char Fred_exe_dir[512]
Definition: management.cpp:90
#define OBJ_POINT
Definition: object.h:40
int query_ship_name_duplicate(int ship)
Definition: management.cpp:590
char * Cargo_names[]
char iff_name[NAME_LENGTH]
Definition: iff_defs.h:36
GLenum GLint GLuint mask
Definition: Glext.h:5605
int default_parse_flags
Definition: iff_defs.h:46
int Mission_palette
int Nmodel_num
Definition: starfield.cpp:166
char author[NAME_LENGTH]
Definition: missionparse.h:132
int num_ship_choices
Definition: missionparse.h:531
#define stricmp(s1, s2)
Definition: config.h:271
#define OBJ_JUMP_NODE
Definition: object.h:45
void management_add_ships_to_combo(CComboBox *box, int flags)
matrix vmd_identity_matrix
Definition: vecmat.cpp:28
void g3_point_to_vec_delayed(vec3d *v, int sx, int sy)
Definition: 3dmath.cpp:254
float max_subsys_repair_val
Definition: missionparse.h:107
void update_texture_replacements(const char *old_name, const char *new_name)
#define SIF_NO_FRED
Definition: ship.h:914
#define GR_1024
Definition: 2d.h:653
char ship_name[NAME_LENGTH]
Definition: ship.h:604
int id
Definition: sound.h:92
void key_init()
Definition: key.cpp:864
void focus_sexp(int select_sexp_node)
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: Glext.h:6566
#define OF_DOCKED_ALREADY_HANDLED
Definition: object.h:117
void clear_texture_replacements()
GLuint GLuint end
Definition: Gl.h:1502
void load_filter_info(void)
Definition: outwnd.cpp:167
int advanced_stricmp(char *one, char *two)
#define MISSION_TEXT_SIZE
Definition: parselo.h:20
int calc_waypoint_list_index(int waypoint_instance)
Definition: waypoint.cpp:125
struct wing wing
void glowpoint_init()
Definition: modelread.cpp:5779
int Update_window
Definition: fred.cpp:48
int cfile_init(const char *exe_dir, const char *cdrom_dir)
Initialize the cfile system. Called once at application start.
Definition: cfile.cpp:183
int arrival_delay
Definition: ship.h:615
int flags
Definition: ship.h:1556
#define g3_start_frame(zbuffer_flag)
Definition: 3d.h:39
int ship_list[MAX_SHIP_CLASSES]
Definition: missionparse.h:533
#define strcpy_s(...)
Definition: safe_strings.h:67
void update_map_window()
Definition: fred.cpp:532
int Nebula_pitch
Definition: nebula.cpp:38
#define SRC_WING_ARRIVAL
Definition: sexp.h:844
int Player_starts
#define MISSION_TYPE_MULTI_TEAMS
Definition: missionparse.h:65
void palette_load_table(const char *filename)
Definition: palman.cpp:132