FS2_Open
Open source remastering of the Freespace 2 engine
freddoc.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 <direct.h>
13 
14 #include "stdafx.h"
15 #include "FRED.h"
16 #include <stdlib.h>
17 //#include <atlbase.h>
18 //#include <atlconv.h>
19 
20 #include "FREDDoc.h"
21 #include "FREDView.h"
22 #include "PrefsDlg.h"
23 
24 #include "render/3d.h"
25 #include "object/object.h"
26 #include "editor.h"
27 #include "ai/ai.h"
28 #include "cfile/cfile.h"
29 
30 #include "cfile/cfilesystem.h"
31 #include "ship/ship.h"
32 #include "mission/missionparse.h"
33 #include "mission/missiongoals.h"
34 #include "MissionSave.h"
35 #include "weapon/weapon.h"
36 #include "Management.h"
37 #include "globalincs/linklist.h"
38 #include "FredRender.h"
39 #include "MainFrm.h"
40 #include "EventEditor.h"
41 #include "ai/aigoals.h"
42 #include "MessageEditorDlg.h"
43 #include "palman/palman.h"
44 #include "localization/fhash.h"
45 #include "cmdline/cmdline.h"
46 #include "starfield/starfield.h"
47 #include "localization/localize.h"
48 
49 extern int Num_objects;
50 
51 #ifdef _DEBUG
52 #undef THIS_FILE
53 static char THIS_FILE[] = __FILE__;
54 #endif
55 
56 // In editor mode, use class CFile, in game, use CFILE (our file)
57 #define XFILE CFile
58 
59 // stupid
60 #ifndef __FOLDERDLG_H__
61  #include "FolderDlg.h"
62 #endif
63 
65 // CFREDDoc
66 
67 IMPLEMENT_DYNCREATE(CFREDDoc, CDocument)
68 
69 BEGIN_MESSAGE_MAP(CFREDDoc, CDocument)
70  //{{AFX_MSG_MAP(CFREDDoc)
71  ON_COMMAND(ID_EDIT_DELETE, OnEditDelete)
72  ON_COMMAND(ID_DUPLICATE, OnDuplicate)
73  ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
74  ON_COMMAND(ID_EDIT_CUT, OnEditCut)
75  ON_COMMAND(ID_EDIT_HOLD, OnEditHold)
76  ON_COMMAND(ID_EDIT_FETCH, OnEditFetch)
77  ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
78  ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
79  ON_COMMAND(ID_FILE_PREFERENCES, OnFilePreferences)
80  ON_COMMAND(ID_FILE_IMPORT_FSM, OnFileImportFSM)
81  //}}AFX_MSG_MAP
82 END_MESSAGE_MAP()
83 
85 // CFREDDoc construction/destruction
86 
87 // Global pointer to the FREDDoc class.
88 // Used by MK to, among other things, I hope, update the modified flag from
89 // outside the FREDDoc class.
90 CFREDDoc *FREDDoc_ptr = NULL;
93 int Undo_count = 0;
94 
95 extern int Num_unknown_ship_classes;
98 
99 CFREDDoc::CFREDDoc()
100 {
101  int i;
102 
103  FREDDoc_ptr = this;
104  confirm_deleting = TRUE;
105  show_capital_ships = TRUE;
106  show_elevations = TRUE;
107  show_fighters = TRUE;
108  show_grid = TRUE;
109  show_misc_objects = TRUE;
110  show_planets = TRUE;
111  show_waypoints = TRUE;
112  show_starfield = TRUE;
113 
114  for (i=0; i<BACKUP_DEPTH; i++)
115  undo_desc[i].Empty();
116 }
117 
119 {
120 }
121 
123 {
124  if (!CDocument::OnNewDocument())
125  return FALSE;
126 
127  // TODO: add reinitialization code here
132  show_grid = FALSE;
137  // (SDI documents will reuse this document)
138 
139  return TRUE;
140 }
141 
142 // read in a new mission file from disk
144 {
145  char name[1024];
146  int i, len;
147 
148  if (pathname)
149  strcpy_s(mission_pathname, pathname);
150 
151  if (Briefing_dialog)
152  Briefing_dialog->icon_select(-1); // clean things up first
153 
154  len = strlen(mission_pathname);
155  strcpy_s(name, mission_pathname);
156  if (name[len - 4] == '.')
157  len -= 4;
158 
159  name[len] = 0; // drop extension
160  i = len;
161  while (i--)
162  if ((name[i] == '\\') || (name[i] == ':'))
163  break;
164 
165  strcpy_s(Mission_filename, name + i + 1);
166 // for (i=1; i<=BACKUP_DEPTH; i++) {
167 // sprintf(name + len, ".%.3d", i);
168 // unlink(name);
169 // }
170 
172  *Mission_filename = 0;
173  return FALSE;
174  }
175 
177  autosave("nothing");
178  Undo_count = 0;
179  return TRUE;
180 }
181 
182 // save mission to a file
184 {
185  CFred_mission_save save;
186  char name[1024];
187  int len;
188  DWORD attrib;
189  FILE *fp;
190 
191  len = strlen(pathname);
192  strcpy_s(name, pathname);
193  if (name[len - 4] == '.')
194  len -= 4;
195 
196  name[len] = 0; // drop extension
197  while (len--)
198  if ((name[len] == '\\') || (name[len] == ':'))
199  break;
200 
201  strcpy_s(Mission_filename, name + len + 1);
203  if (Briefing_dialog) {
206  }
207 
208  if (Event_editor_dlg)
209  Fred_main_wnd->MessageBox("Event editor dialog is still open, so changes there won't be saved");
210 
211  if (Message_editor_dlg)
212  Fred_main_wnd->MessageBox("Message editor dialog is still open, so changes there won't be saved");
213 
214  fp = fopen(pathname, "r");
215  if (fp) {
216  fclose(fp);
217  attrib = GetFileAttributes(pathname);
218  if (attrib & FILE_ATTRIBUTE_READONLY) {
219  Fred_main_wnd->MessageBox("File is read-only. You need to check it out before saving to it");
220  return FALSE;
221  }
222  }
223 
224  if (save.save_mission_file((char *) pathname)) {
225  Fred_main_wnd->MessageBox("An error occured while saving!", NULL, MB_OK | MB_ICONEXCLAMATION);
226  return FALSE;
227  }
228 
229  SetModifiedFlag(FALSE);
230  if (load_mission((char *) pathname))
231  Error(LOCATION, "Failed attempting to reload mission after saving. Report this bug now!");
232 
233  if (Briefing_dialog) {
236  }
237 
238  return TRUE;
239 // return CDocument::OnSaveDocument(pathname);
240 }
241 
243 {
244  char name[256];
245  FILE *fp;
246 
247  Undo_available = 0;
248  if (!Undo_count)
249  return 0;
250 
251 
252  cf_create_default_path_string(name, sizeof(name) - 1, CF_TYPE_MISSIONS);
254  strcat_s(name, ".002");
255  fp = fopen(name, "r");
256  if (!fp)
257  return 0;
258 
259  fclose(fp);
260  Undo_available = 1;
261  return 1;
262 }
263 
264 int CFREDDoc::autosave(char *desc)
265 {
266  int i;
267  CFred_mission_save save;
268  CWaitCursor wait;
269 
270  if (Autosave_disabled)
271  return 0;
272 
273  if (Briefing_dialog)
275 
278  return -1;
279  }
280 
281  for (i=BACKUP_DEPTH; i>1; i--)
282  undo_desc[i] = undo_desc[i - 1];
283 
284  if (desc)
285  undo_desc[1] = desc;
286  else
287  undo_desc[1].Empty();
288 
289  Undo_count++;
290  check_undo();
291  return 0;
292 }
293 
295 {
296  char name[256], backup_name[256];
297  int i, r, len;
298  FILE *fp;
299 
300 
301  cf_create_default_path_string(name, sizeof(name) - 1, CF_TYPE_MISSIONS);
303  strcpy_s(backup_name, name);
304  strcat_s(name, ".002");
305  fp = fopen(name, "r");
306  if (!fp)
307  return 0;
308 
309  fclose(fp);
310  if (Briefing_dialog)
311  Briefing_dialog->icon_select(-1); // clean things up first
312 
313 // editor_init_mission();
314  r = load_mission(name);
315  Update_window = 1;
316 
317  len = strlen(backup_name);
318  strcat_s(backup_name, ".001");
319  cf_delete(backup_name, CF_TYPE_MISSIONS);
320 
321  for (i=1; i<BACKUP_DEPTH; i++) {
322  sprintf(backup_name + len, ".%.3d", i + 1);
323  sprintf(name + len, ".%.3d", i);
324  cf_rename(backup_name, name, CF_TYPE_MISSIONS);
325  undo_desc[i] = undo_desc[i + 1];
326  }
327 
328  Undo_count--;
329  check_undo();
330  return r;
331 }
332 
333 // read in a new mission file from disk
334 int CFREDDoc::load_mission(char *pathname, int flags)
335 {
336  // make sure we're in the correct working directory!!!!!!
337  chdir(Fred_base_dir);
338 
339  char name[512], *old_name;
340  int i, j, k, ob;
341  int used_pool[MAX_WEAPON_TYPES];
342  object *objp;
343 
346 
347  // activate the localizer hash table
348  fhash_flush();
349 
350  clear_mission();
351 
352  if (parse_main(pathname, flags))
353  {
354  if (flags & MPF_IMPORT_FSM)
355  {
356  sprintf(name, "Unable to import the file \"%s\".", pathname);
357  Fred_view_wnd->MessageBox(name);
358  }
359  else
360  {
361  sprintf(name, "Unable to load the file \"%s\".", pathname);
362  Fred_view_wnd->MessageBox(name);
363  }
365  return -1;
366  }
367 
369  {
370  if (flags & MPF_IMPORT_FSM)
371  {
372  char msg[256];
373  sprintf(msg, "Fred encountered unknown ship/weapon classes when importing \"%s\" (path \"%s\"). You will have to manually edit the converted mission to correct this.", The_mission.name, pathname);
374  Fred_view_wnd->MessageBox(msg);
375  }
376  else
377  {
378  Fred_view_wnd->MessageBox("Fred encountered unknown ship/weapon classes when parsing the mission file. This may be due to mission disk data you do not have.");
379  }
380  }
381 
383  objp = GET_FIRST(&obj_used_list);
384  while (objp != END_OF_LIST(&obj_used_list)) {
385  if (objp->flags & OF_PLAYER_SHIP) {
386  Assert(objp->type == OBJ_SHIP);
387  objp->type = OBJ_START;
388 // Player_starts++;
389  }
390 
391  objp = GET_NEXT(objp);
392  }
393 
394  for (i=0; i<Num_wings; i++) {
395  for (j=0; j<Wings[i].wave_count; j++) {
396  ob = Ships[Wings[i].ship_index[j]].objnum;
397  wing_objects[i][j] = ob;
398  Ships[Wings[i].ship_index[j]].wingnum = i;
400  }
401 
402  // fix old ship names for ships in wings if needed
403  while (j--) {
404  if ( (Objects[wing_objects[i][j]].type == OBJ_SHIP) || (Objects[wing_objects[i][j]].type == OBJ_START) ) { // don't change player ship names
405  wing_bash_ship_name(name, Wings[i].name, j + 1);
406  old_name = Ships[Wings[i].ship_index[j]].ship_name;
407  if (stricmp(name, old_name)) { // need to fix name
408  update_sexp_references(old_name, name);
409  ai_update_goal_references(REF_TYPE_SHIP, old_name, name);
410  update_texture_replacements(old_name, name);
411  for (k=0; k<Num_reinforcements; k++)
412  if (!strcmp(old_name, Reinforcements[k].name)) {
413  Assert(strlen(name) < NAME_LENGTH);
414  strcpy_s(Reinforcements[k].name, name);
415  }
416 
417  strcpy_s(Ships[Wings[i].ship_index[j]].ship_name, name);
418  }
419  }
420  }
421  }
422 
423  for ( i = 0; i < Num_teams; i++ ) {
424  generate_weaponry_usage_list(i, used_pool);
425  for (j=0; j<Team_data[i].num_weapon_choices; j++) {
426  // The amount used in wings is always set by a static loadout entry so skip any that were set by Sexp variables
427  if ( (!strlen(Team_data[i].weaponry_pool_variable[j])) && (!strlen(Team_data[i].weaponry_amount_variable[j])) ) {
428  // convert weaponry_pool to be extras available beyond the current ships weapons
429  Team_data[i].weaponry_count[j] -= used_pool[Team_data[i].weaponry_pool[j]];
430  if (Team_data[i].weaponry_count[j] < 0) {
431  Team_data[i].weaponry_count[j] = 0;
432  }
433 
434  // zero the used pool entry
435  used_pool[Team_data[i].weaponry_pool[j]] = 0;
436  }
437  }
438  // double check the used pool is empty
439  for (j=0; j<MAX_WEAPON_TYPES; j++) {
440  if (used_pool[j] != 0) {
441  Warning(LOCATION, "%s is used in wings of team %d but was not in the loadout. Fixing now", Weapon_info[j].name , i+1);
442 
443  // add the weapon as a new entry
446  strcpy_s(Team_data[i].weaponry_amount_variable[Team_data[i].num_weapon_choices], "");
447  strcpy_s(Team_data[i].weaponry_pool_variable[Team_data[i].num_weapon_choices++], "");
448  }
449  }
450  }
451 
452  Assert(Mission_palette >= 0);
453  Assert(Mission_palette <= 98);
454 
455  // RT, don't need this anymore
456 #if 0
457 
459  strcpy_s(name, NOX("gamepalette-subspace"));
460  } else {
461  strcpy_s(name, "gamepalette1-01");
462  // sprintf(name, NOX("gamepalette1-%02d"), Mission_palette + 1);
463  }
464 
465  palette_load_table(name);
466 #endif
467 
468  // go through all ships and translate their callsign and alternate name indices
469  objp = GET_FIRST(&obj_used_list);
470  while (objp != END_OF_LIST(&obj_used_list)) {
471  // if this is a ship, check it, and mark its possible alternate name down in the auxiliary array
472  if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->instance >= 0)) {
473  if (Ships[objp->instance].alt_type_index >= 0) {
475 
476  // also zero it
477  Ships[objp->instance].alt_type_index = -1;
478  }
479 
480  if (Ships[objp->instance].callsign_index >= 0) {
482 
483  // also zero it
484  Ships[objp->instance].callsign_index = -1;
485  }
486  }
487 
488  objp = GET_NEXT(objp);
489  }
490 
491 
494  set_modified(0);
496 
497  recreate_dialogs();
498 
499  return 0;
500 }
501 
502 // Editor-level interface to mission load/save.
503 
504 // Does nothing now.. Handled by OnOpenDocument and OnSaveDocument. This is because we
505 // want to avoid using the CArchive for file I/O -JH
506 void CFREDDoc::Serialize(CArchive& ar)
507 {
508  return;
509 /* The original Serialize code
510  int rw_flag;
511  XFILE *fp;
512 // CString CSfilename;
513 // char filename[128], *tfilename;
514 
515  fp = ar.GetFile();
516  rw_flag = ar.IsStoring();
517 
518 // CSfilename = fp->GetFileName();
519 // tfilename = CSfilename.GetBuffer(16);
520 // strcpy_s(filename, tfilename);
521 // CSfilename.ReleaseBuffer();
522 // -- Don't close this, it gets closed by MFC -- ar.Close();
523 
524  cfile_serialize(fp, rw_flag);
525  cfile_serialize_editor(fp, rw_flag);
526 */
527 }
528 
530 // CFREDDoc diagnostics
531 
532 #ifdef _DEBUG
533 void CFREDDoc::AssertValid() const
534 {
535  CDocument::AssertValid();
536 }
537 
538 void CFREDDoc::Dump(CDumpContext& dc) const
539 {
540  CDocument::Dump(dc);
541 }
542 #endif //_DEBUG
543 
544 
546 // CFREDDoc commands
547 
549 {
550  // TODO: Add your command handler code here
551 
552 }
553 
555 {
556  // TODO: Add your command handler code here
557 
558 }
559 
561 {
562  // TODO: Add your command handler code here
563 
564 }
565 
567 {
568  // TODO: Add your command handler code here
569 
570 }
571 
573 {
574  // TODO: Add your command handler code here
575 
576 }
577 
579 {
580  // TODO: Add your command handler code here
581 
582 }
583 
585 {
586  // TODO: Add your command handler code here
587 
588 }
589 
591 {
592  // TODO: Add your command handler code here
593 
594 }
595 
597 {
598  CPrefsDlg dlg;
599  // Initialize dialog data
604  dlg.m_ShowGrid = show_grid;
609 
610  // Invoke the dialog box
611  if (dlg.DoModal() == IDOK)
612  {
613  // retrieve the dialog data
618  show_grid = dlg.m_ShowGrid;
623  }
624 
625 }
626 
627 // initialize (clear out) the mission, so it's empty and ready to use.
629 {
630  reset_mission();
631  SetModifiedFlag(FALSE);
632  recreate_dialogs();
633 }
634 /*
635 void CFREDDoc::OnFileNew()
636 {
637  // If mission has been modified, offer to save before continuing.
638  while (IsModified()) {
639  int rval;
640 
641  rval = MessageBox(NULL,
642  "You have not saved your work.\n(Which isn't surprising...)\nSave it now?",
643  "Creating New Mission",
644  MB_YESNOCANCEL + MB_ICONEXCLAMATION);
645 
646  if (rval == IDYES) {
647  OnFileSave();
648  } else if (rval == IDCANCEL)
649  return;
650  else if (rval == IDNO)
651  break;
652  }
653 
654  editor_init_mission();
655 
656 }
657 */
659 {
660  if (FREDDoc_ptr)
661  if (flags & US_WORLD_CHANGED)
662  FREDDoc_ptr->SetModifiedFlag();
663 }
664 
666 {
667  DeleteContents();
668 }
669 
670 
672 {
674 }
675 
677 {
678  Local_modified = arg;
679  FREDDoc_ptr->SetModifiedFlag(arg);
680 }
681 
683 //
684 // Below is old, obsolete code, kept around just in case it might be found
685 // useful some time in the future for something.
686 //
688 
689 /*
690 #define SerializeFloat(fp, mode, f) if (mode == 1) fp->Write(&f, sizeof(float)); else fp->Read(&f, sizeof(float))
691 #define SerializeInt(fp, mode, f) if (mode == 1) fp->Write(&f, sizeof(int)); else fp->Read(&f, sizeof(int))
692 
693 void SerializeVector(XFILE *fp, int mode, vector *v)
694 {
695  SerializeFloat(fp, mode, v->x);
696  SerializeFloat(fp, mode, v->y);
697  SerializeFloat(fp, mode, v->z);
698 }
699 
700 void SerializeMatrix(XFILE *fp, int mode, matrix *m)
701 {
702  SerializeVector(fp, mode, &m->rvec);
703  SerializeVector(fp, mode, &m->uvec);
704  SerializeVector(fp, mode, &m->fvec);
705 }
706 
707 void SerializePhysicsInfo(XFILE *fp, int mode, physics_info *pi)
708 {
709  SerializeFloat(fp, mode, pi->mass);
710  SerializeFloat(fp, mode, pi->drag);
711  SerializeVector(fp, mode, &pi->max_thrust);
712  SerializeVector(fp, mode, &pi->max_rotthrust);
713  SerializeFloat(fp, mode, pi->turnroll);
714  SerializeInt(fp, mode, pi->flags);
715  SerializeVector(fp, mode, &pi->velocity);
716  SerializeVector(fp, mode, &pi->rotvel);
717  SerializeVector(fp, mode, &pi->thrust);
718  SerializeVector(fp, mode, &pi->rotthrust);
719 }
720 
722 // CFREDDoc serialization
723 void SerializeObject(XFILE *fp, int mode, object *objp)
724 {
725  SerializeInt(fp, mode, objp->signature);
726  SerializeInt(fp, mode, objp->type);
727  SerializeInt(fp, mode, objp->parent);
728  SerializeInt(fp, mode, objp->parent_sig);
729  SerializeInt(fp, mode, objp->parent_type);
730  SerializeInt(fp, mode, objp->instance);
731  SerializeInt(fp, mode, objp->flags);
732  SerializeInt(fp, mode, objp->flags2); // Goober5000 - code is obsolete, but I added this just in case
733  SerializeFloat(fp, mode, objp->radius);
734 // SerializeInt(fp, mode, objp->wing);
735  SerializePhysicsInfo(fp, mode, &objp->phys_info);
736  SerializeVector(fp, mode, &objp->pos);
737  SerializeMatrix(fp, mode, &objp->orient);
738 }
739 
740 void SerializeAI(XFILE *fp, int mode, ai_info *aip)
741 {
742  SerializeInt(fp, mode, aip->shipnum);
743  SerializeInt(fp, mode, aip->type);
744  SerializeInt(fp, mode, aip->wing);
745 //MWA -- SerializeInt(fp, mode, aip->current_waypoint);
746 }
747 
748 void SerializeShip(XFILE *fp, int mode, ship *shipp)
749 {
750  SerializeInt(fp, mode, shipp->objnum);
751  SerializeInt(fp, mode, shipp->ai_index);
752  SerializeInt(fp, mode, shipp->subtype);
753  SerializeInt(fp, mode, shipp->modelnum);
754  SerializeInt(fp, mode, shipp->hits);
755  SerializeInt(fp, mode, shipp->dying);
756 }
757 
758 void SerializeGrid(XFILE *fp, int mode, grid *gridp)
759 {
760  int i;
761 
762  SerializeInt(fp, mode, gridp->nrows);
763  SerializeInt(fp, mode, gridp->ncols);
764  SerializeMatrix(fp, mode, &gridp->gmatrix);
765  SerializePhysicsInfo(fp, mode, &gridp->physics);
766  SerializeFloat(fp, mode, gridp->square_size);
767  SerializeFloat(fp, mode, gridp->planeD);
768 
769  for (i=0; i<MAX_GRID_POINTS; i++)
770  SerializeVector(fp, mode, &gridp->gpoints[i]);
771 
772 }
773 
774 void cfile_serialize(XFILE *fp, int flag)
775 {
776  int i;
777  int highest_object_index = 0, highest_ship_index = 0, highest_ai_index = 0;
778 
779  Assert((flag == 0) || (flag == 1));
780 
781 // fp = cfopen(filename, flag ? "wb" : "rb");
782 // if (!fp)
783 // MessageBox(NULL, strerror(errno), "File Open Error!", MB_ICONSTOP);
784 
785  // Find highest used object if writing.
786  if (flag == 1) {
787  for (i=MAX_OBJECTS-1; i>0; i--)
788  if (Objects[i].type != OBJ_NONE) {
789  highest_object_index = i;
790  break;
791  }
792  }
793 
794  if (flag == 0) {
795  num_ships = 0;
796  Num_objects = 0;
797  }
798 
799  SerializeInt(fp, flag, highest_object_index);
800 
801  for (i=1; i<=highest_object_index; i++) {
802  SerializeObject(fp, flag, &Objects[i]);
803  if (flag == 0)
804  if (Objects[i].type != OBJ_NONE)
805  Num_objects++;
806  }
807 
808  // Read/write ships
809  if (flag == 1) {
810  for (i=MAX_SHIPS-1; i>0; i--)
811  if (Ships[i].objnum) {
812  highest_ship_index = i;
813  break;
814  }
815  }
816 
817  SerializeInt(fp, flag, highest_ship_index);
818 
819  for (i=1; i<=highest_ship_index; i++) {
820  SerializeShip(fp, flag, &Ships[i]);
821  if (flag == 0)
822  if (Ships[i].objnum)
823  num_ships++;
824  }
825 
826  // Read/write AI info
827  if (flag == 1) {
828  for (i=MAX_AI_INFO-1; i>0; i--)
829  if (Ai_info[i].shipnum) {
830  highest_ai_index = i;
831  break;
832  }
833  }
834 
835  SerializeInt(fp, flag, highest_ai_index);
836 
837  for (i=1; i<=highest_ai_index; i++)
838  SerializeAI(fp, flag, &Ai_info[i]);
839 }
840 
841 void cfile_serialize_editor(XFILE *fp, int flag)
842 {
843  // Editor only stuff
844  SerializeMatrix(fp, flag, &view_orient);
845  SerializeVector(fp, flag, &view_pos);
846 
847  SerializeInt(fp, flag, Control_mode);
848  SerializeInt(fp, flag, cur_object_index);
849  SerializeInt(fp, flag, cur_wing);
850 
851  SerializeGrid(fp, flag, The_grid);
852 
853 }
854 */
855 
856 // Goober5000
858 {
859  char fs1_mission_path[MAX_PATH_LEN];
860  char fs2_mission_path[MAX_PATH_LEN];
861  char dest_directory[MAX_PATH+1];
862 
863  // path stuff
864  {
865  char *ch;
866 
867  // get base paths
868  strcpy_s(fs1_mission_path, Fred_exe_dir);
869  ch = strrchr(fs1_mission_path, DIR_SEPARATOR_CHAR);
870  if (ch != NULL)
871  *ch = '\0';
872  strcpy_s(fs2_mission_path, Fred_exe_dir);
873  ch = strrchr(fs2_mission_path, DIR_SEPARATOR_CHAR);
874  if (ch != NULL)
875  *ch = '\0';
876 
877  // estimate the mission path for FS1
878  if ((ch = stristr(fs1_mission_path, "FreeSpace2")) != NULL)
879  {
880  strcpy(ch, "FreeSpace\\Data\\Missions");
881  }
882 
883  // estimate the mission path for FS2
884  strcat_s(fs2_mission_path, "\\Data\\Missions");
885  }
886 
887  // if mission has been modified, offer to save before continuing.
888  if (!SaveModified())
889  return;
890 
891 
892  // get location to import from
893  CFileDialog dlgFile(TRUE, "fsm", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | OFN_ALLOWMULTISELECT, "FreeSpace Missions (*.fsm)|*.fsm|All files (*.*)|*.*||");
894  dlgFile.m_ofn.lpstrTitle = "Select one or more missions to import";
895  dlgFile.m_ofn.lpstrInitialDir = fs1_mission_path;
896 
897  // get FSM files
898  if (dlgFile.DoModal() != IDOK)
899  return;
900 
901  memset( dest_directory, 0, sizeof(dest_directory) );
902 
903  // get location to save to
904 #if ( _MFC_VER >= 0x0700 )
905  //ITEMIDLIST fs2_mission_pidl = {0};
906 
907  //SHParseDisplayName(A2CW(fs2_mission_path), NULL, fs2_mission_pidl, 0, 0);
908 
909  BROWSEINFO bi;
910  bi.hwndOwner = theApp.GetMainWnd()->GetSafeHwnd();
911  //bi.pidlRoot = &fs2_mission_pidl;
912  bi.pidlRoot = NULL;
913  bi.pszDisplayName = dest_directory;
914  bi.lpszTitle = "Select a location to save in";
915  bi.ulFlags = 0;
916  bi.lpfn = NULL;
917  bi.lParam = NULL;
918  bi.iImage = NULL;
919 
920  LPCITEMIDLIST ret_val = SHBrowseForFolder(&bi);
921 
922  if(ret_val == NULL)
923  return;
924 
925  SHGetPathFromIDList(ret_val, dest_directory);
926 #else
927  CFolderDialog dlgFolder(_T("Select a location to save in"), fs2_mission_path, NULL);
928  if(dlgFolder.DoModal() != IDOK)
929  return;
930 
931  strcpy_s( dest_directory, dlgFolder.GetFolderPath() );
932 #endif
933 
934  // clean things up first
935  if (Briefing_dialog)
937 
938  clear_mission();
939 
940  // process all missions
941  POSITION pos(dlgFile.GetStartPosition());
942  while(pos)
943  {
944  char *ch;
945  char filename[1024];
946  char fs1_path[MAX_PATH_LEN];
947  char dest_path[MAX_PATH_LEN];
948 
949  CString fs1_path_mfc(dlgFile.GetNextPathName(pos));
950  CFred_mission_save save;
951 
952  DWORD attrib;
953  FILE *fp;
954 
955 
956  // path name too long?
957  if (strlen(fs1_path_mfc) > MAX_PATH_LEN - 1)
958  continue;
959 
960  // nothing here?
961  if (!strlen(fs1_path_mfc))
962  continue;
963 
964  // get our mission
965  strcpy_s(fs1_path, fs1_path_mfc);
966 
967  // load mission into memory
968  if (load_mission(fs1_path, MPF_IMPORT_FSM))
969  continue;
970 
971  // get filename
972  ch = strrchr(fs1_path, DIR_SEPARATOR_CHAR) + 1;
973  if (ch != NULL)
974  strcpy_s(filename, ch);
975  else
976  strcpy_s(filename, fs1_path);
977 
978  // truncate extension
979  ch = strrchr(filename, '.');
980  if (ch != NULL)
981  *ch = '\0';
982 
983  // add new extension
984  strcat_s(filename, ".fs2");
985 
986  strcpy_s(Mission_filename, filename);
987 
988  // get new path
989  strcpy_s(dest_path, dest_directory);
990  strcat_s(dest_path, "\\");
991  strcat_s(dest_path, filename);
992 
993  // check attributes
994  fp = fopen(dest_path, "r");
995  if (fp)
996  {
997  fclose(fp);
998  attrib = GetFileAttributes(dest_path);
999  if (attrib & FILE_ATTRIBUTE_READONLY)
1000  continue;
1001  }
1002 
1003  // try to save it
1004  if (save.save_mission_file(dest_path))
1005  continue;
1006 
1007  // success
1008  }
1009 
1011 
1012  MessageBox(NULL, "Import complete. Please check the destination folder to verify all missions were imported successfully.", "Status", MB_OK);
1013  recreate_dialogs();
1014 }
1015 
1016 void CFREDDoc::recreate_dialogs()
1017 {
1018  if(Briefing_dialog)
1019  {
1023  Briefing_dialog->SetWindowPos(&CWnd::wndTop, 0, 0, 0, 0,
1024  SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
1025  Briefing_dialog->ShowWindow(SW_RESTORE);
1026  }
1027 
1028  if(Bg_bitmap_dialog)
1029  {
1033  Bg_bitmap_dialog->SetWindowPos(&CWnd::wndTop, 0, 0, 0, 0,
1034  SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
1035  Bg_bitmap_dialog->ShowWindow(SW_RESTORE);
1036  }
1037 }
void clear_mission()
Definition: management.cpp:790
wing Wings[MAX_WINGS]
Definition: ship.cpp:128
BOOL show_planets
Definition: freddoc.h:42
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
afx_msg void OnClose()
vec3d Parse_viewer_pos
int Num_unknown_ship_classes
int Locked_sexp_false
Definition: sexp.cpp:828
int Undo_count
Definition: freddoc.cpp:93
#define ID_EDIT_DELETE
Definition: resource.h:1198
int cf_delete(const char *filename, int path_type)
Delete the specified file.
Definition: cfile.cpp:483
void generate_weaponry_usage_list(int *arr, int wing)
CMessageEditorDlg * Message_editor_dlg
int objnum
Definition: ship.h:537
void fhash_flush()
Definition: fhash.cpp:79
int alt_type_index
Definition: ship.h:556
weapon_info Weapon_info[MAX_WEAPON_TYPES]
Definition: weapons.cpp:79
BOOL show_elevations
Definition: freddoc.h:38
afx_msg void OnEditCopy()
Definition: freddoc.cpp:560
afx_msg void OnEditHold()
Definition: freddoc.cpp:578
char name[NAME_LENGTH]
Definition: missionparse.h:131
virtual BOOL OnOpenDocument(LPCTSTR lpszPathName)
Definition: freddoc.cpp:143
void mission_parse_lookup_callsign_index(int index, char *out)
#define MAX_PATH
void mission_parse_lookup_alt_index(int index, char *out)
afx_msg void OnEditDelete()
Definition: freddoc.cpp:548
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
Assert(pm!=NULL)
CString undo_desc[BACKUP_DEPTH+1]
Definition: freddoc.h:49
char Fred_alt_names[MAX_SHIPS][NAME_LENGTH+1]
Definition: management.cpp:93
#define DIR_SEPARATOR_CHAR
Definition: pstypes.h:43
virtual void OnEditClearAll()
Definition: freddoc.cpp:665
void update_sexp_references(const char *old_name, const char *new_name, int format, int node)
Definition: sexp.cpp:28332
#define TRUE
Definition: pstypes.h:399
object obj_used_list
Definition: object.cpp:53
int check_undo()
Definition: freddoc.cpp:242
CMainFrame * Fred_main_wnd
Definition: mainfrm.cpp:89
#define OF_PLAYER_SHIP
Definition: object.h:109
void obj_merge_created_list(void)
Definition: object.cpp:651
int cf_create_default_path_string(char *path, uint path_max, int pathtype, const char *filename, bool localize)
object * objp
Definition: lua.cpp:3105
AFX_INLINE LPCTSTR GetFolderPath(VOID) const
Definition: folderdlg.h:186
BOOL show_capital_ships
Definition: freddoc.h:37
vec3d view_pos
Definition: fredrender.cpp:103
bg_bitmap_dlg * Bg_bitmap_dialog
Definition: fred.cpp:58
int Num_unknown_loadout_classes
BOOL m_ShowPlanets
Definition: prefsdlg.h:30
GLenum type
Definition: Gl.h:1492
afx_msg void OnEditFetch()
Definition: freddoc.cpp:584
void create_new_mission()
Definition: management.cpp:776
reinforcements Reinforcements[MAX_REINFORCEMENTS]
Definition: ship.cpp:165
void reset_mission()
Definition: management.cpp:784
virtual void Serialize(CArchive &ar)
Definition: freddoc.cpp:506
int instance
Definition: object.h:150
int Undo_available
Definition: freddoc.cpp:92
#define OBJ_START
Definition: object.h:35
GLdouble GLdouble GLdouble r
Definition: Glext.h:5337
afx_msg void OnEditUndo()
Definition: freddoc.cpp:590
BOOL m_ShowElevations
Definition: prefsdlg.h:26
matrix view_orient
Definition: fredrender.cpp:112
int autoload()
Definition: freddoc.cpp:294
void stars_post_level_init()
Definition: starfield.cpp:782
event_editor * Event_editor_dlg
Definition: eventeditor.cpp:30
int autosave(char *desc)
Definition: freddoc.cpp:264
#define US_WORLD_CHANGED
Definition: freddoc.h:19
char * filename
afx_msg void OnFilePreferences()
Definition: freddoc.cpp:596
int wingnum
Definition: ship.h:623
#define ID_EDIT_HOLD
Definition: resource.h:1199
char * stristr(char *str, const char *substr)
Definition: parselo.cpp:3729
#define MAX_WEAPON_TYPES
Definition: globals.h:73
int num_weapon_choices
Definition: missionparse.h:539
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
int Num_unknown_weapon_classes
int weaponry_pool[MAX_WEAPON_TYPES]
Definition: missionparse.h:540
BOOL m_ShowCapitalShips
Definition: prefsdlg.h:25
int Num_objects
Definition: object.cpp:68
BOOL show_fighters
Definition: freddoc.h:39
int global_error_check()
Definition: fredview.cpp:2427
int autosave_mission_file(char *pathname)
afx_msg void OnDuplicate()
Definition: freddoc.cpp:554
int Num_wings
Definition: ship.cpp:120
#define MB_OK
Definition: config.h:179
int Num_teams
int cf_rename(const char *old_name, const char *name, int dir_type)
Definition: cfile.cpp:567
virtual INT DoModal(VOID)
Definition: folderdlg.cpp:158
int wing_objects[MAX_WINGS][MAX_SHIPS_PER_WING]
Definition: management.cpp:97
static void UpdateStatus(int flags=US_WORLD_CHANGED)
Definition: freddoc.cpp:658
BOOL m_ShowGrid
Definition: prefsdlg.h:28
CFREDDoc * FREDDoc_ptr
Definition: freddoc.cpp:90
int callsign_index
Definition: ship.h:557
virtual void DeleteContents()
Definition: freddoc.cpp:671
char Mission_filename[80]
unsigned long DWORD
Definition: config.h:90
char Fred_base_dir[512]
Definition: management.cpp:91
cfbp fp
Definition: cfile.cpp:1065
void ai_update_goal_references(ai_goal *goals, int type, const char *old_name, const char *new_name)
Definition: aigoals.cpp:2295
int wave_count
Definition: ship.h:1527
CFREDView * Fred_view_wnd
Definition: fredview.cpp:138
BOOL show_waypoints
Definition: freddoc.h:43
#define ID_FILE_PREFERENCES
Definition: resource.h:1197
afx_msg void OnFileImportFSM()
Definition: freddoc.cpp:857
object Objects[MAX_OBJECTS]
Definition: object.cpp:62
afx_msg void OnEditCut()
Definition: freddoc.cpp:566
#define ID_EDIT_FETCH
Definition: resource.h:1200
#define NOX(s)
Definition: pstypes.h:473
int Autosave_disabled
Definition: fredview.cpp:86
#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
#define ID_FILE_IMPORT_FSM
Definition: resource.h:1447
int load_mission(char *pathname, int flags=0)
Definition: freddoc.cpp:334
GLbitfield flags
Definition: Glext.h:6722
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
#define ID_DUPLICATE
Definition: resource.h:1185
#define MAX_PATH_LEN
Definition: pstypes.h:325
BOOL show_grid
Definition: freddoc.h:40
int BOOL
Definition: config.h:80
BOOL m_ShowMiscObjects
Definition: prefsdlg.h:29
ship Ships[MAX_SHIPS]
Definition: ship.cpp:122
#define REF_TYPE_SHIP
Definition: sexp.h:836
#define MB_ICONEXCLAMATION
Definition: config.h:184
#define BACKUP_DEPTH
Definition: missionsave.h:25
#define strcat_s(...)
Definition: safe_strings.h:68
virtual BOOL OnSaveDocument(LPCTSTR lpszPathName)
Definition: freddoc.cpp:183
#define NAME_LENGTH
Definition: globals.h:15
int Local_modified
Definition: freddoc.cpp:91
char mission_pathname[256]
Definition: freddoc.h:45
int save_mission_file(char *pathname)
#define MISSION_BACKUP_NAME
Definition: freddoc.h:17
BOOL m_ShowStarfield
Definition: prefsdlg.h:32
afx_msg void OnEditPaste()
Definition: freddoc.cpp:572
int parse_main(const char *mission_name, int flags)
#define CF_TYPE_MISSIONS
Definition: cfile.h:74
#define LOCATION
Definition: pstypes.h:245
BOOL confirm_deleting
Definition: freddoc.h:36
void update_data(int update=1)
int MessageBox(HWND h, const char *s1, const char *s2, int i)
afx_msg void editor_init_mission()
Definition: freddoc.cpp:628
hull_check pos
Definition: lua.cpp:5050
BOOL m_ShowWaypoints
Definition: prefsdlg.h:31
virtual BOOL OnNewDocument()
Definition: freddoc.cpp:122
matrix Parse_viewer_orient
team_data Team_data[MAX_TVT_TEAMS]
BOOL m_ShowFighters
Definition: prefsdlg.h:27
GLenum GLsizei len
Definition: Glext.h:6283
#define MPF_IMPORT_FSM
Definition: missionparse.h:51
int Num_reinforcements
Definition: ship.cpp:121
int ship_index[MAX_SHIPS_PER_WING]
Definition: ship.h:1531
briefing_editor_dlg * Briefing_dialog
Definition: fred.cpp:59
int arrival_cue
Definition: ship.h:614
BOOL show_starfield
Definition: freddoc.h:44
uint flags
Definition: object.h:151
mission The_mission
char Fred_callsigns[MAX_SHIPS][NAME_LENGTH+1]
Definition: management.cpp:94
BOOL m_ConfirmDeleting
Definition: prefsdlg.h:24
char type
Definition: object.h:146
#define FALSE
Definition: pstypes.h:400
char Fred_exe_dir[512]
Definition: management.cpp:90
virtual ~CFREDDoc()
Definition: freddoc.cpp:118
int Mission_palette
#define stricmp(s1, s2)
Definition: config.h:271
void update_texture_replacements(const char *old_name, const char *new_name)
char ship_name[NAME_LENGTH]
Definition: ship.h:604
BOOL show_misc_objects
Definition: freddoc.h:41
#define MISSION_FLAG_SUBSPACE
Definition: missionparse.h:68
int Update_window
Definition: fred.cpp:48
#define strcpy_s(...)
Definition: safe_strings.h:67
void palette_load_table(const char *filename)
Definition: palman.cpp:132