// read in a new mission file from disk int CFREDDoc::load_mission(char *pathname) { char name[512], *old_name; int i, j, k, ob; int used_pool[MAX_WEAPON_TYPES]; waypoint_list *wptr; object *objp; Parse_viewer_pos = view_pos; Parse_viewer_orient = view_orient; // activate the localizer hash table fhash_flush(); clear_mission(); Fred_found_unknown_ship_during_parsing = 0; if (parse_main(pathname)) { sprintf(name, "Unable to load the file \"%s\"", pathname); Fred_view_wnd->MessageBox(name); create_new_mission(); return -1; } if(Fred_found_unknown_ship_during_parsing){ 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"); } Fred_found_unknown_ship_during_parsing = 0; for (i=0; i<Num_waypoint_lists; i++) { wptr = &Waypoint_lists[i]; for (j=0; j<wptr->count; j++){ ob = obj_create(OBJ_WAYPOINT, -1, i * 65536 + j, NULL, &wptr->waypoints[j], 0.0f, OF_RENDERS); } } obj_merge_created_list(); objp = GET_FIRST(&obj_used_list); while (objp != END_OF_LIST(&obj_used_list)) { if (objp->flags & OF_PLAYER_SHIP) { Assert(objp->type == OBJ_SHIP); objp->type = OBJ_START; // Player_starts++; } objp = GET_NEXT(objp); } for (i=0; i<num_wings; i++) { for (j=0; j<Wings[i].wave_count; j++) { ob = Ships[Wings[i].ship_index[j]].objnum; wing_objects[i][j] = ob; Ships[Wings[i].ship_index[j]].wingnum = i; Ships[Wings[i].ship_index[j]].arrival_cue = Locked_sexp_false; } // fix old ship names for ships in wings if needed while (j--) { if ( (Objects[wing_objects[i][j]].type == OBJ_SHIP) || (Objects[wing_objects[i][j]].type == OBJ_START) ) { // don't change player ship names sprintf(name, "%s %d", Wings[i].name, j + 1); old_name = Ships[Wings[i].ship_index[j]].ship_name; if (stricmp(name, old_name)) { // need to fix name update_sexp_references(old_name, name); ai_update_goal_references(REF_TYPE_SHIP, old_name, name); for (k=0; k<Num_reinforcements; k++) if (!stricmp(old_name, Reinforcements[k].name)) { Assert(strlen(name) < NAME_LENGTH); strcpy(Reinforcements[k].name, name); } strcpy(Ships[Wings[i].ship_index[j]].ship_name, name); } } } } generate_weaponry_usage_list(used_pool); for ( j = 0; j < Num_teams; j++ ) { for (i=0; i<Num_weapon_types; i++) { Team_data[j].weaponry_pool[i] -= used_pool[i]; // convert weaponry_pool to be extras available beyond the current ships weapons if (Team_data[j].weaponry_pool[i] < 0) Team_data[j].weaponry_pool[i] = 0; } } Assert(Mission_palette >= 0); Assert(Mission_palette <= 98); if (The_mission.flags & MISSION_FLAG_SUBSPACE) { strcpy(name, NOX("gamepalette-subspace")); } else { strcpy(name, "gamepalette1-01"); // sprintf(name, NOX("gamepalette1-%02d"), Mission_palette + 1); } palette_load_table(name); // go through all ships and translate their alternate name indices objp = GET_FIRST(&obj_used_list); while (objp != END_OF_LIST(&obj_used_list)) { // if this is a ship, check it, and mark its possible alternate name down in the auxiliary array if(((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->instance >= 0) && (Ships[objp->instance].alt_type_index >= 0)){ mission_parse_lookup_alt_index(Ships[objp->instance].alt_type_index, Fred_alt_names[objp->instance]); // also zero it Ships[objp->instance].alt_type_index = -1; } objp = GET_NEXT(objp); } view_pos = Parse_viewer_pos; view_orient = Parse_viewer_orient; set_modified(0); return 0; }
void CFREDDoc::OnFileImportFSM() { char fs1_mission_path[MAX_PATH_LEN]; char fs2_mission_path[MAX_PATH_LEN]; char dest_directory[MAX_PATH + 1]; // path stuff { char *ch; // get base paths strcpy_s(fs1_mission_path, Fred_exe_dir); ch = strrchr(fs1_mission_path, DIR_SEPARATOR_CHAR); if (ch != NULL) *ch = '\0'; strcpy_s(fs2_mission_path, Fred_exe_dir); ch = strrchr(fs2_mission_path, DIR_SEPARATOR_CHAR); if (ch != NULL) *ch = '\0'; // estimate the mission path for FS1 if ((ch = stristr(fs1_mission_path, "FreeSpace2")) != NULL) { strcpy(ch, "FreeSpace\\Data\\Missions"); } // estimate the mission path for FS2 strcat_s(fs2_mission_path, "\\Data\\Missions"); } // if mission has been modified, offer to save before continuing. if (!SaveModified()) return; // get location to import from CFileDialog dlgFile(TRUE, "fsm", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | OFN_ALLOWMULTISELECT, "FreeSpace Missions (*.fsm)|*.fsm|All files (*.*)|*.*||"); dlgFile.m_ofn.lpstrTitle = "Select one or more missions to import"; dlgFile.m_ofn.lpstrInitialDir = fs1_mission_path; // get FSM files if (dlgFile.DoModal() != IDOK) return; memset(dest_directory, 0, sizeof(dest_directory)); // get location to save to #if ( _MFC_VER >= 0x0700 ) //ITEMIDLIST fs2_mission_pidl = {0}; //SHParseDisplayName(A2CW(fs2_mission_path), NULL, fs2_mission_pidl, 0, 0); BROWSEINFO bi; bi.hwndOwner = theApp.GetMainWnd()->GetSafeHwnd(); //bi.pidlRoot = &fs2_mission_pidl; bi.pidlRoot = NULL; bi.pszDisplayName = dest_directory; bi.lpszTitle = "Select a location to save in"; bi.ulFlags = 0; bi.lpfn = NULL; bi.lParam = NULL; bi.iImage = NULL; LPCITEMIDLIST ret_val = SHBrowseForFolder(&bi); if (ret_val == NULL) return; SHGetPathFromIDList(ret_val, dest_directory); #else CFolderDialog dlgFolder(_T("Select a location to save in"), fs2_mission_path, NULL); if (dlgFolder.DoModal() != IDOK) return; strcpy_s(dest_directory, dlgFolder.GetFolderPath()); #endif // clean things up first if (Briefing_dialog) Briefing_dialog->icon_select(-1); clear_mission(); // process all missions POSITION pos(dlgFile.GetStartPosition()); while (pos) { char *ch; char filename[1024]; char fs1_path[MAX_PATH_LEN]; char dest_path[MAX_PATH_LEN]; CString fs1_path_mfc(dlgFile.GetNextPathName(pos)); CFred_mission_save save; DWORD attrib; FILE *fp; // path name too long? if (strlen(fs1_path_mfc) > MAX_PATH_LEN - 1) continue; // nothing here? if (!strlen(fs1_path_mfc)) continue; // get our mission strcpy_s(fs1_path, fs1_path_mfc); // load mission into memory if (load_mission(fs1_path, MPF_IMPORT_FSM)) continue; // get filename ch = strrchr(fs1_path, DIR_SEPARATOR_CHAR) + 1; if (ch != NULL) strcpy_s(filename, ch); else strcpy_s(filename, fs1_path); // truncate extension ch = strrchr(filename, '.'); if (ch != NULL) *ch = '\0'; // add new extension strcat_s(filename, ".fs2"); strcpy_s(Mission_filename, filename); // get new path strcpy_s(dest_path, dest_directory); strcat_s(dest_path, "\\"); strcat_s(dest_path, filename); // check attributes fp = fopen(dest_path, "r"); if (fp) { fclose(fp); attrib = GetFileAttributes(dest_path); if (attrib & FILE_ATTRIBUTE_READONLY) continue; } // try to save it if (save.save_mission_file(dest_path)) continue; // success } create_new_mission(); MessageBox(NULL, "Import complete. Please check the destination folder to verify all missions were imported successfully.", "Status", MB_OK); recreate_dialogs(); }
// -------------------------------------------------------------------------------------- // Create a new mine, set global variables. int create_new_mine(void) { int s; vms_vector sizevec; vms_matrix m1 = IDENTITY_MATRIX; // initialize_mine_arrays(); // gamestate_not_restored = 1; // Clear refueling center code fuelcen_reset(); hostage_init_all(); init_all_vertices(); Current_level_num = 0; //0 means not a real level Current_level_name[0] = 0; Gamesave_current_version = LEVEL_FILE_VERSION; Cur_object_index = -1; reset_objects(1); //just one object, the player num_groups = 0; current_group = -1; Num_vertices = 0; // Number of vertices in global array. Highest_vertex_index = 0; Num_segments = 0; // Number of segments in global array, will get increased in med_create_segment Highest_segment_index = 0; Cursegp = Segments; // Say current segment is the only segment. Curside = WBACK; // The active side is the back side Markedsegp = 0; // Say there is no marked segment. Markedside = WBACK; // Shouldn't matter since Markedsegp == 0, but just in case... for (s=0;s<MAX_GROUPS+1;s++) { GroupList[s].num_segments = 0; GroupList[s].num_vertices = 0; Groupsegp[s] = NULL; Groupside[s] = 0; } Num_robot_centers = 0; Num_open_doors = 0; wall_init(); trigger_init(); // Create New_segment, which is the segment we will be adding at each instance. med_create_new_segment(vm_vec_make(&sizevec,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE)); // New_segment = Segments[0]; // med_create_segment(Segments,0,0,0,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE,vm_mat_make(&m1,F1_0,0,0,0,F1_0,0,0,0,F1_0)); med_create_segment(Segments,0,0,0,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE,&m1); N_found_segs = 0; N_selected_segs = 0; N_warning_segs = 0; //--repair-- create_local_segment_data(); ControlCenterTriggers.num_links = 0; create_new_mission(); //editor_status("New mine created."); return 0; // say no error }
int CFREDDoc::load_mission(char *pathname, int flags) { // make sure we're in the correct working directory!!!!!! chdir(Fred_base_dir); char name[512], *old_name; int i, j, k, ob; int used_pool[MAX_WEAPON_TYPES]; object *objp; Parse_viewer_pos = view_pos; Parse_viewer_orient = view_orient; // activate the localizer hash table fhash_flush(); clear_mission(); if (parse_main(pathname, flags)) { if (flags & MPF_IMPORT_FSM) { sprintf(name, "Unable to import the file \"%s\".", pathname); Fred_view_wnd->MessageBox(name); } else { sprintf(name, "Unable to load the file \"%s\".", pathname); Fred_view_wnd->MessageBox(name); } create_new_mission(); return -1; } if ((Num_unknown_ship_classes > 0) || (Num_unknown_weapon_classes > 0) || (Num_unknown_loadout_classes > 0)) { if (flags & MPF_IMPORT_FSM) { char msg[256]; 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); Fred_view_wnd->MessageBox(msg); } else { 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."); } } obj_merge_created_list(); objp = GET_FIRST(&obj_used_list); while (objp != END_OF_LIST(&obj_used_list)) { if (objp->flags[Object::Object_Flags::Player_ship]) { Assert(objp->type == OBJ_SHIP); objp->type = OBJ_START; // Player_starts++; } objp = GET_NEXT(objp); } for (i = 0; i < Num_wings; i++) { for (j = 0; j < Wings[i].wave_count; j++) { ob = Ships[Wings[i].ship_index[j]].objnum; wing_objects[i][j] = ob; Ships[Wings[i].ship_index[j]].wingnum = i; Ships[Wings[i].ship_index[j]].arrival_cue = Locked_sexp_false; } // fix old ship names for ships in wings if needed while (j--) { if ((Objects[wing_objects[i][j]].type == OBJ_SHIP) || (Objects[wing_objects[i][j]].type == OBJ_START)) { // don't change player ship names wing_bash_ship_name(name, Wings[i].name, j + 1); old_name = Ships[Wings[i].ship_index[j]].ship_name; if (stricmp(name, old_name)) { // need to fix name update_sexp_references(old_name, name); ai_update_goal_references(REF_TYPE_SHIP, old_name, name); update_texture_replacements(old_name, name); for (k = 0; k < Num_reinforcements; k++) if (!strcmp(old_name, Reinforcements[k].name)) { Assert(strlen(name) < NAME_LENGTH); strcpy_s(Reinforcements[k].name, name); } strcpy_s(Ships[Wings[i].ship_index[j]].ship_name, name); } } } } for (i = 0; i < Num_teams; i++) { generate_weaponry_usage_list(i, used_pool); for (j = 0; j < Team_data[i].num_weapon_choices; j++) { // The amount used in wings is always set by a static loadout entry so skip any that were set by Sexp variables if ((!strlen(Team_data[i].weaponry_pool_variable[j])) && (!strlen(Team_data[i].weaponry_amount_variable[j]))) { // convert weaponry_pool to be extras available beyond the current ships weapons Team_data[i].weaponry_count[j] -= used_pool[Team_data[i].weaponry_pool[j]]; if (Team_data[i].weaponry_count[j] < 0) { Team_data[i].weaponry_count[j] = 0; } // zero the used pool entry used_pool[Team_data[i].weaponry_pool[j]] = 0; } } // double check the used pool is empty for (j = 0; j < MAX_WEAPON_TYPES; j++) { if (used_pool[j] != 0) { Warning(LOCATION, "%s is used in wings of team %d but was not in the loadout. Fixing now", Weapon_info[j].name, i + 1); // add the weapon as a new entry Team_data[i].weaponry_pool[Team_data[i].num_weapon_choices] = j; Team_data[i].weaponry_count[Team_data[i].num_weapon_choices] = used_pool[j]; strcpy_s(Team_data[i].weaponry_amount_variable[Team_data[i].num_weapon_choices], ""); strcpy_s(Team_data[i].weaponry_pool_variable[Team_data[i].num_weapon_choices++], ""); } } } Assert(Mission_palette >= 0); Assert(Mission_palette <= 98); // RT, don't need this anymore #if 0 if (The_mission.flags[Mission::Mission_Flags::Subspace]) { strcpy_s(name, NOX("gamepalette-subspace")); } else { strcpy_s(name, "gamepalette1-01"); // sprintf(name, NOX("gamepalette1-%02d"), Mission_palette + 1); } palette_load_table(name); #endif // go through all ships and translate their callsign and alternate name indices objp = GET_FIRST(&obj_used_list); while (objp != END_OF_LIST(&obj_used_list)) { // if this is a ship, check it, and mark its possible alternate name down in the auxiliary array if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->instance >= 0)) { if (Ships[objp->instance].alt_type_index >= 0) { mission_parse_lookup_alt_index(Ships[objp->instance].alt_type_index, Fred_alt_names[objp->instance]); // also zero it Ships[objp->instance].alt_type_index = -1; } if (Ships[objp->instance].callsign_index >= 0) { mission_parse_lookup_callsign_index(Ships[objp->instance].callsign_index, Fred_callsigns[objp->instance]); // also zero it Ships[objp->instance].callsign_index = -1; } } objp = GET_NEXT(objp); } view_pos = Parse_viewer_pos; view_orient = Parse_viewer_orient; set_modified(0); stars_post_level_init(); recreate_dialogs(); return 0; }