// delete a whole wing, also deleting its ships if necessary. int delete_wing(int wing_num, int bypass) { int i, r, total; if (already_deleting_wing) return 0; r = check_wing_dependencies(wing_num); if (r) return r; already_deleting_wing = 1; for (i=0; i<Num_reinforcements; i++) if (!stricmp(Wings[wing_num].name, Reinforcements[i].name)) { delete_reinforcement(i); break; } invalidate_references(Wings[wing_num].name, REF_TYPE_WING); if (!bypass) { total = Wings[wing_num].wave_count; for (i=0; i<total; i++) delete_object(wing_objects[wing_num][i]); } Wings[wing_num].wave_count = 0; Wings[wing_num].wing_squad_filename[0] = '\0'; Wings[wing_num].wing_insignia_texture = -1; if (cur_wing == wing_num) set_cur_wing(cur_wing = -1); // yes, one '=' is correct. free_sexp2(Wings[wing_num].arrival_cue); free_sexp2(Wings[wing_num].departure_cue); Num_wings--; set_modified(); update_custom_wing_indexes(); already_deleting_wing = 0; return 0; }
// delete a whole wing, leaving ships intact but wingless. void remove_wing(int wing_num) { int i, total; object *ptr; if (check_wing_dependencies(wing_num)) return; Ship_editor_dialog.bypass_errors = Wing_editor_dialog.bypass_errors = 1; Ship_editor_dialog.update_data(0); total = Wings[wing_num].wave_count; for (i=0; i<total; i++) { ptr = &Objects[wing_objects[wing_num][i]]; if (ptr->type == OBJ_SHIP) remove_ship_from_wing(ptr->instance, 0); else if (ptr->type == OBJ_START) remove_player_from_wing(ptr->instance, 0); } Assert(!Wings[wing_num].wave_count); Wings[wing_num].wave_count = 0; Wings[wing_num].wing_squad_filename[0] = '\0'; Wings[wing_num].wing_insignia_texture = -1; Ship_editor_dialog.initialize_data(1); Ship_editor_dialog.bypass_errors = Wing_editor_dialog.bypass_errors = 0; if (cur_wing == wing_num) { set_cur_wing(cur_wing = -1); // yes, one '=' is correct. } free_sexp2(Wings[wing_num].arrival_cue); free_sexp2(Wings[wing_num].departure_cue); Num_wings--; update_custom_wing_indexes(); set_modified(); }
// Forms a wing from marked objects int create_wing() { char msg[1024]; int i, ship, wing = -1, waypoints = 0, count = 0, illegal_ships = 0; int leader, leader_team; object *ptr; create_wing_dlg dlg; if (!query_valid_object()) return -1; leader = cur_object_index; ptr = GET_FIRST(&obj_used_list); while (ptr != END_OF_LIST(&obj_used_list)) { if (( (ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START) ) && (ptr->flags & OF_MARKED)) { count++; i = -1; switch (ptr->type) { case OBJ_SHIP: case OBJ_START: i = Ships[ptr->instance].wingnum; break; } if (i >= 0) { if (wing < 0) wing = i; else if (wing != i) wing = MULTI_WING; } } ptr = GET_NEXT(ptr); } if (count > MAX_SHIPS_PER_WING) { sprintf(msg, "You have too many ships marked!\n" "A wing is limited to %d ships total", MAX_SHIPS_PER_WING); Fred_main_wnd->MessageBox(msg, "Error", MB_ICONEXCLAMATION); return -1; } if ((wing >= 0) && (wing != MULTI_WING)) { sprintf(msg, "Do you want to reform wing \"%s\"?", Wings[wing].name); i = Fred_main_wnd->MessageBox(msg, "Query", MB_YESNOCANCEL); if (i == IDCANCEL) return -1; else if (i == IDNO) wing = -1; else { // must be IDYES for (i=Wings[wing].wave_count-1; i>=0; i--) { ptr = &Objects[wing_objects[wing][i]]; switch (ptr->type) { case OBJ_SHIP: remove_ship_from_wing(ptr->instance, 0); break; case OBJ_START: remove_player_from_wing(ptr->instance, 0); break; default: Int3(); // shouldn't be in a wing! } } Assert(!Wings[wing].wave_count); Num_wings--; } } else wing = -1; if (wing < 0) { wing = find_free_wing(); if (wing < 0) { Fred_main_wnd->MessageBox("Too many wings, can't create more!", "Error", MB_ICONEXCLAMATION); return -1; } Wings[wing].num_waves = 1; Wings[wing].threshold = 0; Wings[wing].arrival_location = Wings[wing].departure_location = 0; Wings[wing].arrival_distance = 0; Wings[wing].arrival_anchor = -1; Wings[wing].arrival_delay = 0; Wings[wing].arrival_cue = Locked_sexp_true; Wings[wing].departure_delay = 0; Wings[wing].departure_cue = Locked_sexp_false; Wings[wing].hotkey = -1; Wings[wing].flags = 0; Wings[wing].wave_delay_min = 0; Wings[wing].wave_delay_max = 0; for (i=0; i<MAX_AI_GOALS; i++) { Wings[wing].ai_goals[i].ai_mode = AI_GOAL_NONE; Wings[wing].ai_goals[i].priority = -1; // this sets up the priority field to be like ships } if (dlg.DoModal() == IDCANCEL) return -1; dlg.m_name.TrimLeft(); dlg.m_name.TrimRight(); string_copy(Wings[wing].name, dlg.m_name, NAME_LENGTH - 1); } set_cur_indices(-1); ptr = GET_FIRST(&obj_used_list); while (ptr != END_OF_LIST(&obj_used_list)) { if (ptr->flags & OF_MARKED) { // if ((ptr->type == OBJ_START) && (ptr->instance)) { // starts++; // unmark_object(OBJ_INDEX(ptr)); // } else if (ptr->type == OBJ_WAYPOINT) { if (ptr->type == OBJ_WAYPOINT) { waypoints++; unmark_object(OBJ_INDEX(ptr)); } else if (ptr->type == OBJ_SHIP) { int ship_type = ship_query_general_type(ptr->instance); if(ship_type < 0 || !(Ship_types[ship_type].ai_bools & STI_AI_CAN_FORM_WING)) { illegal_ships++; unmark_object(OBJ_INDEX(ptr)); } } } ptr = GET_NEXT(ptr); } // if this wing is a player starting wing, automatically set the hotkey for this wing for (i = 0; i < MAX_STARTING_WINGS; i++ ) { if ( !stricmp(Wings[wing].name, Starting_wing_names[i]) ) { Wings[wing].hotkey = i; break; } } count = 0; if (Objects[Ships[Player_start_shipnum].objnum].flags & OF_MARKED) count = 1; ptr = GET_FIRST(&obj_used_list); while (ptr != END_OF_LIST(&obj_used_list)) { if (ptr->flags & OF_MARKED) { if ((ptr->type == OBJ_START) && (ptr->instance == Player_start_shipnum)) i = 0; // player 1 start always goes to front of the wing else i = count++; Assert((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)); ship = ptr->instance; if (Ships[ship].wingnum != -1) { if (ptr->type == OBJ_SHIP) remove_ship_from_wing(ship); else remove_player_from_wing(ptr->instance); } wing_bash_ship_name(msg, Wings[wing].name, i + 1); rename_ship(ship, msg); Wings[wing].ship_index[i] = ship; Ships[ship].wingnum = wing; if (Ships[ship].arrival_cue >= 0) free_sexp2(Ships[ship].arrival_cue); Ships[ship].arrival_cue = Locked_sexp_false; if (Ships[ship].departure_cue >= 0) free_sexp2(Ships[ship].departure_cue); Ships[ship].departure_cue = Locked_sexp_false; wing_objects[wing][i] = OBJ_INDEX(ptr); if (OBJ_INDEX(ptr) == leader) Wings[wing].special_ship = i; } ptr = GET_NEXT(ptr); } if (!count) // this should never happen, so if it does, needs to be fixed now. Error(LOCATION, "No valid ships were selected to form wing from"); Wings[wing].wave_count = count; Num_wings++; // if (starts) // Fred_main_wnd->MessageBox("Multi-player starting points can't be part of a wing!\n" // "All marked multi-player starting points were ignored", // "Error", MB_ICONEXCLAMATION); if (waypoints) Fred_main_wnd->MessageBox("Waypoints can't be part of a wing!\n" "All marked waypoints were ignored", "Error", MB_ICONEXCLAMATION); if (illegal_ships) Fred_main_wnd->MessageBox("Some ship types aren't allowed to be in a wing.\n" "All marked ships of these types were ignored", "Error", MB_ICONEXCLAMATION); leader_team = Ships[Wings[wing].ship_index[Wings[wing].special_ship]].team; for (i = 0; i < Wings[wing].wave_count; i++) { if (Ships[Wings[wing].ship_index[i]].team != leader_team) { Fred_main_wnd->MessageBox("Wing contains ships on different teams", "Warning"); break; } } mark_wing(wing); update_custom_wing_indexes(); return 0; }
void CustomWingNames::OnOK() { UpdateData(TRUE); strip_quotation_marks(m_starting_1); strip_quotation_marks(m_starting_2); strip_quotation_marks(m_starting_3); strip_quotation_marks(m_squadron_1); strip_quotation_marks(m_squadron_2); strip_quotation_marks(m_squadron_3); strip_quotation_marks(m_squadron_4); strip_quotation_marks(m_squadron_5); strip_quotation_marks(m_tvt_1); strip_quotation_marks(m_tvt_2); if (strcmp(m_starting_1, m_tvt_1)) { MessageBox("The first starting wing and the first team-versus-team wing must have the same wing name."); return; } if (!stricmp(m_starting_1, m_starting_2) || !stricmp(m_starting_1, m_starting_3) || !stricmp(m_starting_2, m_starting_3)) { MessageBox("Duplicate wing names in starting wing list."); return; } if (!stricmp(m_squadron_1, m_squadron_2) || !stricmp(m_squadron_1, m_squadron_3) || !stricmp(m_squadron_1, m_squadron_4) || !stricmp(m_squadron_1, m_squadron_5) || !stricmp(m_squadron_2, m_squadron_3) || !stricmp(m_squadron_2, m_squadron_4) || !stricmp(m_squadron_2, m_squadron_5) || !stricmp(m_squadron_3, m_squadron_4) || !stricmp(m_squadron_3, m_squadron_5) || !stricmp(m_squadron_4, m_squadron_5)) { MessageBox("Duplicate wing names in squadron wing list."); return; } if (!stricmp(m_tvt_1, m_tvt_2)) { MessageBox("Duplicate wing names in team-versus-team wing list."); return; } // copy starting wings strcpy_s(Starting_wing_names[0], m_starting_1); strcpy_s(Starting_wing_names[1], m_starting_2); strcpy_s(Starting_wing_names[2], m_starting_3); // copy squadron wings strcpy_s(Squadron_wing_names[0], m_squadron_1); strcpy_s(Squadron_wing_names[1], m_squadron_2); strcpy_s(Squadron_wing_names[2], m_squadron_3); strcpy_s(Squadron_wing_names[3], m_squadron_4); strcpy_s(Squadron_wing_names[4], m_squadron_5); // copy tvt wings strcpy_s(TVT_wing_names[0], m_tvt_1); strcpy_s(TVT_wing_names[1], m_tvt_2); update_custom_wing_indexes(); CDialog::OnOK(); }
// 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; }