void briefing_editor_dlg::OnMakeIcon() { char *name; int z, len, team, ship, waypoint, count = -1; int cargo = 0, cargo_count = 0, freighter_count = 0; object *ptr; vec3d min, max, pos; brief_icon *iconp; if (Briefing->stages[m_cur_stage].num_icons >= MAX_STAGE_ICONS) return; m_cur_icon = Briefing->stages[m_cur_stage].num_icons++; iconp = &Briefing->stages[m_cur_stage].icons[m_cur_icon]; ship = waypoint = -1; team = 0; jump_node *jnp = NULL; vm_vec_make(&min, 9e19f, 9e19f, 9e19f); vm_vec_make(&max, -9e19f, -9e19f, -9e19f); ptr = GET_FIRST(&obj_used_list); while (ptr != END_OF_LIST(&obj_used_list)) { if (ptr->flags & OF_MARKED) { if (ptr->pos.xyz.x < min.xyz.x) min.xyz.x = ptr->pos.xyz.x; if (ptr->pos.xyz.x > max.xyz.x) max.xyz.x = ptr->pos.xyz.x; if (ptr->pos.xyz.y < min.xyz.y) min.xyz.y = ptr->pos.xyz.y; if (ptr->pos.xyz.y > max.xyz.y) max.xyz.y = ptr->pos.xyz.y; if (ptr->pos.xyz.z < min.xyz.z) min.xyz.z = ptr->pos.xyz.z; if (ptr->pos.xyz.z > max.xyz.z) max.xyz.z = ptr->pos.xyz.z; switch (ptr->type) { case OBJ_SHIP: case OBJ_START: ship = ptr->instance; break; case OBJ_WAYPOINT: waypoint = ptr->instance; break; case OBJ_JUMP_NODE: jnp = ptr->jnp; break; default: Int3(); } if (ship >= 0) { team = Ships[ship].team; z = ship_query_general_type(ship); if (Ship_info[Ships[ship].ship_info_index].flags & SIF_CARGO) cargo_count++; if (Ship_info[Ships[ship].ship_info_index].flags & SIF_FREIGHTER) { // direct docked with any marked cargo? for (dock_instance *dock_ptr = ptr->dock_list; dock_ptr != NULL; dock_ptr = dock_ptr->next) { if (dock_ptr->docked_objp->flags & OF_MARKED) { if (Ship_info[Ships[dock_ptr->docked_objp->instance].ship_info_index].flags & SIF_CARGO) freighter_count++; } } } } count++; } ptr = GET_NEXT(ptr); } if (cargo_count && cargo_count == freighter_count) cargo = 1; vm_vec_avg(&pos, &min, &max); if (ship >= 0) name = Ships[ship].ship_name; else if (waypoint >= 0) name = Waypoint_lists[waypoint / 65536].name; else if (jnp != NULL) name = jnp->get_name_ptr(); else return; len = strlen(name); if (len >= MAX_LABEL_LEN - 1) len = MAX_LABEL_LEN - 1; strncpy(iconp->label, name, len); iconp->label[len] = 0; // iconp->text[0] = 0; iconp->type = 0; iconp->team = team; iconp->pos = pos; iconp->flags = 0; iconp->id = Cur_brief_id++; if (ship >= 0) { iconp->ship_class = Ships[ship].ship_info_index; switch (Ship_info[Ships[ship].ship_info_index].flags & SIF_ALL_SHIP_TYPES) { case SIF_KNOSSOS_DEVICE: iconp->type = ICON_KNOSSOS_DEVICE; break; case SIF_CORVETTE: iconp->type = ICON_CORVETTE; break; case SIF_GAS_MINER: iconp->type = ICON_GAS_MINER; break; case SIF_SUPERCAP: iconp->type = ICON_SUPERCAP; break; case SIF_SENTRYGUN: iconp->type = ICON_SENTRYGUN; break; case SIF_AWACS: iconp->type = ICON_AWACS; break; case SIF_CARGO: if (cargo) iconp->type = (count == 1) ? ICON_FREIGHTER_WITH_CARGO : ICON_FREIGHTER_WING_WITH_CARGO; else iconp->type = count ? ICON_CARGO_WING : ICON_CARGO; break; case SIF_SUPPORT: iconp->type = ICON_SUPPORT_SHIP; break; case SIF_FIGHTER: iconp->type = count ? ICON_FIGHTER_WING : ICON_FIGHTER; break; case SIF_BOMBER: iconp->type = count ? ICON_BOMBER_WING : ICON_BOMBER; break; case SIF_FREIGHTER: if (cargo) iconp->type = (count == 1) ? ICON_FREIGHTER_WITH_CARGO : ICON_FREIGHTER_WING_WITH_CARGO; else iconp->type = count ? ICON_FREIGHTER_WING_NO_CARGO : ICON_FREIGHTER_NO_CARGO; break; case SIF_CRUISER: iconp->type = count ? ICON_CRUISER_WING : ICON_CRUISER; break; case SIF_TRANSPORT: iconp->type = count ? ICON_TRANSPORT_WING : ICON_TRANSPORT; break; case SIF_CAPITAL: case SIF_DRYDOCK: iconp->type = ICON_CAPITAL; break; case SIF_NAVBUOY: iconp->type = ICON_WAYPOINT; break; default: iconp->type = ICON_ASTEROID_FIELD; break; } } // jumpnodes else if(jnp != NULL){ // find the first navbuoy iconp->ship_class = -1; for (int i = 0; i < Num_ship_classes; i++) { if (Ship_info[i].flags & SIF_NAVBUOY) { iconp->ship_class = i; break; } } iconp->type = ICON_JUMP_NODE; } // everything else else { // find the first navbuoy iconp->ship_class = -1; for (int i = 0; i < Num_ship_classes; i++) { if (Ship_info[i].flags & SIF_NAVBUOY) { iconp->ship_class = i; break; } } iconp->type = ICON_WAYPOINT; } if (!m_change_local){ propagate_icon(m_cur_icon); } icon_obj[m_cur_icon] = obj_create(OBJ_POINT, -1, m_cur_icon, NULL, &pos, 0.0f, OF_RENDERS); Assert(icon_obj[m_cur_icon] >= 0); obj_merge_created_list(); unmark_all(); set_cur_object_index(icon_obj[m_cur_icon]); GetDlgItem(IDC_MAKE_ICON) -> EnableWindow(FALSE); GetDlgItem(IDC_PROPAGATE_ICONS) -> EnableWindow(TRUE); update_data(1); }
// 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; }
// 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 friendly, hostile, leader; 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->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 flight group 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 flight group \"%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(); 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_cue = Locked_sexp_true; Wings[wing].departure_cue = Locked_sexp_false; Wings[wing].hotkey = -1; Wings[wing].flags = 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 (wing < 0) { Fred_main_wnd->MessageBox("Too many flight groups, can't create more!", "Error", MB_ICONEXCLAMATION); return -1; } if (dlg.DoModal() == IDCANCEL) return -1; 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) { switch (ship_query_general_type(ptr->instance)) { case SHIP_TYPE_CARGO: case SHIP_TYPE_FIGHTER_BOMBER: case SHIP_TYPE_CRUISER: case SHIP_TYPE_FREIGHTER: case SHIP_TYPE_CAPITAL: case SHIP_TYPE_TRANSPORT: case SHIP_TYPE_REPAIR_REARM: case SHIP_TYPE_NAVBUOY: case SHIP_TYPE_SENTRYGUN: case SHIP_TYPE_SPACE_OBJECT: case SHIP_TYPE_ESCAPEPOD: case SHIP_TYPE_SUPERCAP: case SHIP_TYPE_STEALTH: case SHIP_TYPE_DRYDOCK: //case SHIP_TYPE_AWACS: //case SHIP_TYPE_GAS_MINER: // all ships added so that any craft type can be formed into a flight group /*case SHIP_TYPE_FIGHTER_BOMBER: case SHIP_TYPE_CRUISER: case SHIP_TYPE_AWACS: case SHIP_TYPE_GAS_MINER: case SHIP_TYPE_CORVETTE: case SHIP_TYPE_FREIGHTER: case SHIP_TYPE_CAPITAL: case SHIP_TYPE_TRANSPORT: case SHIP_TYPE_SUPERCAP:*/ break; default: 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 = friendly = hostile = 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); } sprintf(msg, "%s %d", Wings[wing].name, i + 1); rename_ship(ship, msg); if (Ships[ship].team == TEAM_FRIENDLY) friendly = 1; else if ((Ships[ship].team == TEAM_HOSTILE) || (Ships[ship].team == TEAM_NEUTRAL)) hostile = 1; 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); if (friendly && hostile) Fred_main_wnd->MessageBox("Both hostile and friendly ships in same wing", "Warning"); mark_wing(wing); return 0; }