// 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 event_editor::OnOk() { char buf[256], names[2][MAX_MISSION_EVENTS][NAME_LENGTH]; int i, count; audiostream_close_file(m_wave_id, 0); m_wave_id = -1; save(); if (query_modified()) set_modified(); for (i=0; i<Num_mission_events; i++) { free_sexp2(Mission_events[i].formula); if (Mission_events[i].objective_text) free(Mission_events[i].objective_text); if (Mission_events[i].objective_key_text) free(Mission_events[i].objective_key_text); } count = 0; for (i=0; i<Num_mission_events; i++) Mission_events[i].result = 0; // use this as a processed flag // rename all sexp references to old events for (i=0; i<m_num_events; i++) if (m_sig[i] >= 0) { strcpy_s(names[0][count], Mission_events[m_sig[i]].name); strcpy_s(names[1][count], m_events[i].name); count++; Mission_events[m_sig[i]].result = 1; } // invalidate all sexp references to deleted events. for (i=0; i<Num_mission_events; i++) if (!Mission_events[i].result) { sprintf(buf, "<%s>", Mission_events[i].name); strcpy(buf + NAME_LENGTH - 2, ">"); // force it to be not too long strcpy_s(names[0][count], Mission_events[i].name); strcpy_s(names[1][count], buf); count++; } Num_mission_events = m_num_events; for (i=0; i<m_num_events; i++) { Mission_events[i] = m_events[i]; Mission_events[i].formula = m_event_tree.save_tree(m_events[i].formula); Mission_events[i].objective_text = m_events[i].objective_text; Mission_events[i].objective_key_text = m_events[i].objective_key_text; Mission_events[i].mission_log_flags = m_events[i].mission_log_flags; } // now update all sexp references while (count--) update_sexp_references(names[0][count], names[1][count], OPF_EVENT_NAME); for (i=Num_builtin_messages; i<Num_messages; i++) { if (Messages[i].avi_info.name) free(Messages[i].avi_info.name); if (Messages[i].wave_info.name) free(Messages[i].wave_info.name); } Num_messages = m_num_messages + Num_builtin_messages; Messages.resize(Num_messages); for (i=0; i<m_num_messages; i++) Messages[i + Num_builtin_messages] = m_messages[i]; theApp.record_window_data(&Events_wnd_data, this); delete Event_editor_dlg; Event_editor_dlg = NULL; }
int CMessageEditorDlg::update(int num) { char *ptr, buf[4096]; int i, node, fnode; CListBox *list; UpdateData(TRUE); if (num >= 0) { ptr = (char *) (LPCTSTR) m_message_name; for (i=0; i<Num_messages; i++) if ((i != num) && (!stricmp(m_message_name, Messages[i].name))) break; if (i == Num_messages) { // update name if no conflicts, otherwise keep old name update_sexp_references(Messages[num].name, ptr, OPF_MESSAGE); string_copy(Messages[num].name, m_message_name, NAME_LENGTH - 1); list = (CListBox *) GetDlgItem(IDC_MESSAGE_LIST); list->DeleteString(num); list->InsertString(num, m_message_name); } string_copy(Messages[num].message, m_message_text, MESSAGE_LENGTH - 1); if (Messages[num].avi_info.name) free(Messages[num].avi_info.name); ptr = (char *) (LPCTSTR) m_avi_filename; if (!ptr || !strlen(ptr)) Messages[num].avi_info.name = NULL; else Messages[num].avi_info.name = strdup(ptr); if (Messages[num].wave_info.name) free(Messages[num].wave_info.name); ptr = (char *) (LPCTSTR) m_wave_filename; if (!ptr || !strlen(ptr)) Messages[num].wave_info.name = NULL; else Messages[num].wave_info.name = strdup(ptr); // update the persona to the message. We subtract 1 for the "None" at the beginning of the combo // box list. Messages[num].persona_index = m_persona - 1; if (m_tree.query_false()) { if (m_event_num >= 0) { // need to delete event i = m_event_num; free_sexp2(Mission_events[i].formula); Assert(i < Num_mission_events); while (i < Num_mission_events - 1) { Mission_events[i] = Mission_events[i + 1]; i++; } Num_mission_events--; m_event_num = -1; } } else { if (m_event_num >= 0) free_sexp2(Mission_events[m_event_num].formula); else { if (Num_mission_events == MAX_MISSION_EVENTS) { MessageBox("You have reached the limit on mission events.\n" "Can't add an event to send this message."); goto exit; } Assert(Num_mission_events < MAX_MISSION_EVENTS); m_event_num = Num_mission_events++; string_copy(Mission_events[m_event_num].name, m_message_name, NAME_LENGTH - 1); Mission_events[m_event_num].repeat_count = 1; Mission_events[m_event_num].interval = 1; Mission_events[m_event_num].score = 0; Mission_events[m_event_num].chain_delay = -1; Mission_events[m_event_num].objective_text = NULL; Mission_events[m_event_num].objective_key_text = NULL; } fnode = m_tree.save_tree(); ptr = (char *) (LPCTSTR) m_message_name; node = alloc_sexp(ptr, SEXP_ATOM, SEXP_ATOM_STRING, -1, -1); ((CComboBox *) GetDlgItem(IDC_PRIORITY))->GetLBText(m_priority, buf); node = alloc_sexp(buf, SEXP_ATOM, SEXP_ATOM_STRING, -1, node); ((CComboBox *) GetDlgItem(IDC_SENDER))->GetLBText(m_sender, buf); node = alloc_sexp(buf, SEXP_ATOM, SEXP_ATOM_STRING, -1, node); node = alloc_sexp("send-message", SEXP_ATOM, SEXP_ATOM_OPERATOR, -1, node); node = alloc_sexp("", SEXP_LIST, SEXP_ATOM_LIST, node, -1); node = alloc_sexp("", SEXP_LIST, SEXP_ATOM_LIST, fnode, node); node = alloc_sexp("when", SEXP_ATOM, SEXP_ATOM_OPERATOR, -1, node); Mission_events[m_event_num].formula = node; } } exit: if (query_modified()) set_modified(); modified = 0; return 0; }
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; }
// update wing structure(s) with dialog data. The data is first checked for errors. If // no errors occur, returns 0. If an error occurs, returns -1. If the update is bypassed, // returns 1. Bypass is necessary to avoid an infinite loop, and it doesn't actually // update the data. Bypass only occurs if bypass mode is active and we still get an error. // Once the error no longer occurs, bypass mode is cleared and data is updated. int wing_editor::update_data(int redraw) { char *str, old_name[255], buf[512]; int i, z; object *ptr; nprintf(("Fred routing", "Wing dialog save\n")); if (!GetSafeHwnd()) return 0; UpdateData(TRUE); UpdateData(TRUE); if (cur_wing >= 0) { for (i=0; i<MAX_WINGS; i++) if (Wings[i].wave_count && !stricmp(Wings[i].name, m_wing_name) && (i != cur_wing)) { if (bypass_errors) return 1; bypass_errors = 1; z = MessageBox("This wing name is already being used by another wing\n" "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL); if (z == IDCANCEL) return -1; m_wing_name = _T(Wings[cur_wing].name); UpdateData(FALSE); } ptr = GET_FIRST(&obj_used_list); while (ptr != END_OF_LIST(&obj_used_list)) { if (ptr->type == OBJ_SHIP) { if (!stricmp(m_wing_name, Ships[ptr->instance].ship_name)) { if (bypass_errors) return 1; bypass_errors = 1; z = MessageBox("This wing name is already being used by a ship\n" "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL); if (z == IDCANCEL) return -1; m_wing_name = _T(Wings[cur_wing].name); UpdateData(FALSE); } } ptr = GET_NEXT(ptr); } for (i=0; i<MAX_WAYPOINT_LISTS; i++) if (Waypoint_lists[i].count && !stricmp(Waypoint_lists[i].name, m_wing_name)) { if (bypass_errors) return 1; bypass_errors = 1; z = MessageBox("This wing name is already being used by a waypoint path\n" "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL); if (z == IDCANCEL) return -1; m_wing_name = _T(Wings[cur_wing].name); UpdateData(FALSE); } if(jumpnode_get_by_name(m_wing_name) != NULL) { if (bypass_errors) return 1; bypass_errors = 1; z = MessageBox("This wing name is already being used by a jump node\n" "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL); if (z == IDCANCEL) return -1; m_wing_name = _T(Wings[cur_wing].name); UpdateData(FALSE); } strcpy(old_name, Wings[cur_wing].name); string_copy(Wings[cur_wing].name, m_wing_name, NAME_LENGTH, 1); update_data_safe(); update_custom_wing_indexes(); bypass_errors = 0; modified = 0; str = Wings[cur_wing].name; if (stricmp(old_name, str)) { update_sexp_references(old_name, str); ai_update_goal_references(REF_TYPE_WING, old_name, str); for (i=0; i<Num_reinforcements; i++) if (!stricmp(old_name, Reinforcements[i].name)) { Assert(strlen(str) < NAME_LENGTH); strcpy(Reinforcements[i].name, str); } for (i=0; i<Wings[cur_wing].wave_count; i++) { if ((Objects[wing_objects[cur_wing][i]].type == OBJ_SHIP) || (Objects[wing_objects[cur_wing][i]].type == OBJ_START)) { sprintf(buf, "%s %d", str, i + 1); rename_ship(Wings[cur_wing].ship_index[i], buf); } } Update_window = 1; } if (set_reinforcement(str, m_reinforcement) == 1) { free_sexp2(Wings[cur_wing].arrival_cue); Wings[cur_wing].arrival_cue = Locked_sexp_false; } } if (redraw) update_map_window(); return 0; }