Skip to content

Commit

Permalink
remove the special_ship field
Browse files Browse the repository at this point in the history
This field existed in retail, but was not used for its intended purpose.  Subsequently, I modified the functionality so that it worked as advertised, but this has side-effects for retail missions which specify a special ship other than the wing leader.  I'm not sure to what extent this field actually enhances a mission, so I propose removing it.
  • Loading branch information
Goober5000 committed Nov 27, 2023
1 parent 369b90a commit 8b1e9a9
Show file tree
Hide file tree
Showing 19 changed files with 58 additions and 147 deletions.
6 changes: 3 additions & 3 deletions code/ai/aigoals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,10 @@ void ai_maybe_add_form_goal(wing* wingp)
if (Netgame.type_flags & NG_TYPE_TEAM) {
const ship_registry_entry* ship_regp = ship_registry_get(Ships[wingp->ship_index[j]].ship_name);
wingnum = TVT_wings[ship_regp->p_objp->team];
ai_add_ship_goal_player(AIG_TYPE_PLAYER_SHIP, AI_GOAL_FORM_ON_WING, -1, Ships[Wings[wingnum].ship_index[Wings[wingnum].special_ship]].ship_name, aip);
ai_add_ship_goal_player(AIG_TYPE_PLAYER_SHIP, AI_GOAL_FORM_ON_WING, -1, Ships[Wings[wingnum].ship_index[0]].ship_name, aip);
} else {
wingnum = Starting_wings[0];
ai_add_ship_goal_player(AIG_TYPE_PLAYER_SHIP, AI_GOAL_FORM_ON_WING, -1, Ships[Wings[wingnum].ship_index[Wings[wingnum].special_ship]].ship_name, aip);
ai_add_ship_goal_player(AIG_TYPE_PLAYER_SHIP, AI_GOAL_FORM_ON_WING, -1, Ships[Wings[wingnum].ship_index[0]].ship_name, aip);
}
} else if (!(Game_mode & GM_MULTIPLAYER)) {
ai_add_ship_goal_player(AIG_TYPE_PLAYER_SHIP, AI_GOAL_FORM_ON_WING, -1, Player_ship->ship_name, aip);
Expand Down Expand Up @@ -549,7 +549,7 @@ void ai_goal_purge_invalid_goals( ai_goal *aigp, ai_goal *goal_list, ai_info *ai

// for wings we grab the ship type of the wing leader
if (ai_wingnum >= 0) {
ai_ship_type = Ship_info[Wings[ai_wingnum].special_ship_ship_info_index].class_type;
ai_ship_type = Ship_info[Wings[ai_wingnum].wing_leader_ship_class].class_type;
}
// otherwise we simply grab it from the ship itself
else {
Expand Down
10 changes: 5 additions & 5 deletions code/hud/hudsquadmsg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -884,9 +884,9 @@ void hud_squadmsg_send_to_all_fighters( int command, int player_num )
continue;

// get the first ship on the wing list and look at its team and then its type
shipnum = Wings[i].ship_index[Wings[i].special_ship];
shipnum = Wings[i].ship_index[0];

// if special ship isn't valid then just move on
// if wing leader isn't valid then just move on
if (shipnum < 0)
continue;

Expand All @@ -897,7 +897,7 @@ void hud_squadmsg_send_to_all_fighters( int command, int player_num )
continue;

// can't message if ship not fighter/bomber if the command isn't to everyone.
if ( !(Ship_info[Wings[i].special_ship_ship_info_index].is_fighter_bomber()) )
if ( !(Ship_info[Wings[i].wing_leader_ship_class].is_fighter_bomber()) )
continue;

// don't send the command if the "wing" won't accept the command. We do this by looking at
Expand Down Expand Up @@ -2126,8 +2126,8 @@ void hud_squadmsg_wing_command()
default_orders.erase(CAPTURE_TARGET_ITEM); // we cannot capture any target with a wing.

Num_menu_items = 0;
shipnum = wingp->ship_index[wingp->special_ship];
Assertion(shipnum >= 0, "Special ship (%d) for wing '%s' has a negative ship_index (%d). This should not happen; get a coder!\n", wingp->special_ship, wingp->name, shipnum);
shipnum = wingp->ship_index[0];
Assertion(shipnum >= 0, "Wing leader for wing '%s' has a negative ship_index (%d). This should not happen; get a coder!\n", wingp->name, shipnum);
orders = Ships[shipnum].orders_accepted; // get the orders that the wing leader will accept

for ( size_t order_id : default_orders ) {
Expand Down
4 changes: 2 additions & 2 deletions code/mission/missionhotkey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -633,8 +633,8 @@ int hotkey_build_team_listing(int enemy_team_mask, int y, bool list_enemies)
char wing_name[NAME_LENGTH];

// the wing has to be valid
if (Wings[i].current_count && Wings[i].ship_index[Wings[i].special_ship] >= 0) {
ship *shipp = &Ships[Wings[i].ship_index[Wings[i].special_ship]];
if (Wings[i].current_count && Wings[i].ship_index[0] >= 0) {
ship *shipp = &Ships[Wings[i].ship_index[0]];

// check IFF override and team mask
if (Iff_info[shipp->team].hotkey_team == IFF_hotkey_team::Default) {
Expand Down
29 changes: 11 additions & 18 deletions code/mission/missionparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2222,8 +2222,8 @@ int parse_create_object_sub(p_object *p_objp, bool standalone_ship)
shipp->flags.set(Ship::Ship_Flags::Navpoint_carry);

// if it's wing leader, take the opportunity to set the wing leader's info index in the wing struct
if (!Fred_running && p_objp->pos_in_wing == 0 && wingp->special_ship_ship_info_index != -1) {
wingp->special_ship_ship_info_index = p_objp->ship_class;
if (!Fred_running && p_objp->pos_in_wing == 0) {
wingp->wing_leader_ship_class = p_objp->ship_class;
}
}

Expand Down Expand Up @@ -3968,8 +3968,8 @@ void swap_parse_object(p_object *p_obj, int new_ship_class)
// First things first. Change the class of the p_object
p_obj->ship_class = new_ship_class;

if (p_obj->wingnum > -1 && p_obj->pos_in_wing == 0) {
Wings[p_obj->wingnum].special_ship_ship_info_index = new_ship_class;
if (!Fred_running && p_obj->wingnum >= 0 && p_obj->pos_in_wing == 0) {
Wings[p_obj->wingnum].wing_leader_ship_class = new_ship_class;
}

// Hitpoints
Expand Down Expand Up @@ -4415,10 +4415,6 @@ int parse_wing_create_ships( wing *wingp, int num_to_create, bool force_create,
for (j = i; j < length - 1; j++)
{
wingp->ship_index[j] = wingp->ship_index[j+1];

// update "special" ship too
if (wingp->special_ship == j+1)
wingp->special_ship--;
}

// last value becomes -1
Expand Down Expand Up @@ -4469,12 +4465,9 @@ int parse_wing_create_ships( wing *wingp, int num_to_create, bool force_create,
// test code to check to be sure that all ships in the wing are ignoring the same types
// of orders from the leader
if ( Fred_running ) {
Assert( wingp->ship_index[wingp->special_ship] != -1 );
Assert( wingp->ship_index[0] != -1 );
const std::set<size_t>& orders = Ships[wingp->ship_index[0]].orders_accepted;
for (it = 0; it < wingp->current_count; it++ ) {
if (it == wingp->special_ship)
continue;

for (it = 1; it < wingp->current_count; it++ ) {
if ( orders != Ships[wingp->ship_index[it]].orders_accepted ) {
Warning(LOCATION, "ships in wing %s are ignoring different player orders. Please find Mark A\nto talk to him about this.", wingp->name );
break;
Expand Down Expand Up @@ -4551,8 +4544,8 @@ void parse_wing(mission *pm)
required_string("$Wave Threshold:");
stuff_int(&wingp->threshold);

required_string("$Special Ship:");
stuff_int(&wingp->special_ship);
if (optional_string("$Special Ship:"))
stuff_int(&i); // not used

// Use a custom formation if specified
if (optional_string("+Formation:")) {
Expand Down Expand Up @@ -4816,9 +4809,9 @@ void parse_wing(mission *pm)
p_objp->wingnum = wingnum;
p_objp->pos_in_wing = i;

// we have found our "special ship" (our wing leader)
// we have found our wing leader
if (!Fred_running && i == 0){
wingp->special_ship_ship_info_index = p_objp->ship_class;
wingp->wing_leader_ship_class = p_objp->ship_class;
}

// Goober5000 - if this is a player start object, there shouldn't be a wing arrival delay (Mantis #2678)
Expand Down Expand Up @@ -7825,7 +7818,7 @@ bool mission_maybe_make_wing_arrive(int wingnum, bool force_arrival)
if(MULTI_TEAM)
{
// send a hostile wing arrived message
rship = wingp->ship_index[wingp->special_ship];
rship = wingp->ship_index[0];

int multi_team_filter = Ships[rship].team;

Expand Down
26 changes: 4 additions & 22 deletions code/parse/sexp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6504,17 +6504,8 @@ object_ship_wing_point_team::object_ship_wing_point_team(wing* wp)
else
type = OSWPT_TYPE_WING_NOT_PRESENT;

// point to wing leader if he is valid
if ((wingp->special_ship >= 0) && (wingp->ship_index[wingp->special_ship] >= 0))
{
objp = &Objects[Ships[wingp->ship_index[wingp->special_ship]].objnum];
}
// boo... well, just point to ship at index 0
else
{
objp = &Objects[Ships[wingp->ship_index[0]].objnum];
Warning(LOCATION, "Substituting ship '%s' at index 0 for nonexistent wing leader at index %d!", Ships[objp->instance].ship_name, wingp->special_ship);
}
// point to wing leader
objp = &Objects[Ships[wingp->ship_index[0]].objnum];
}

void object_ship_wing_point_team::clear()
Expand Down Expand Up @@ -6632,17 +6623,8 @@ void eval_object_ship_wing_point_team(object_ship_wing_point_team *oswpt, int no
{
oswpt->type = OSWPT_TYPE_WING;

// point to wing leader if he is valid
if ((wingp->special_ship >= 0) && (wingp->ship_index[wingp->special_ship] >= 0))
{
oswpt->objp = &Objects[Ships[wingp->ship_index[wingp->special_ship]].objnum];
}
// boo... well, just point to ship at index 0
else
{
oswpt->objp = &Objects[Ships[wingp->ship_index[0]].objnum];
Warning(LOCATION, "Substituting ship '%s' at index 0 for nonexistent wing leader at index %d!", Ships[oswpt->objp->instance].ship_name, wingp->special_ship);
}
// point to wing leader
oswpt->objp = &Objects[Ships[wingp->ship_index[0]].objnum];
}
// it's still a valid wing even if nobody is here
else
Expand Down
22 changes: 3 additions & 19 deletions code/ship/ship.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6957,8 +6957,7 @@ void wing::clear()
total_departed = 0;
total_vanished = 0;

special_ship = 0;
special_ship_ship_info_index = -1;
wing_leader_ship_class = -1;

arrival_location = ARRIVE_AT_LOCATION;
arrival_distance = 0;
Expand Down Expand Up @@ -8294,21 +8293,6 @@ void ship_wing_cleanup( int shipnum, wing *wingp )
Assert ( wingp->current_count >= 0 );
wingp->ship_index[wingp->current_count] = -1;

// adjust the special ship if necessary
if (wingp->special_ship > 0 && wingp->special_ship >= index){
wingp->special_ship--;

// sorry to have make this a little convoluted, if I put this after this if statement, then I introduce edge case bugs.
// if there are ships in the wing, and the special ship changed, make sure the special_ship_ship_info_index is updated too
if (wingp->current_count > 0){
wingp->special_ship_ship_info_index = Ships[wingp->ship_index[wingp->special_ship]].ship_info_index;
}

// if the special ship *variable* didn't change, but the wing leader did because index was 0, adjust special_ship_ship_info_index
} else if (wingp->current_count > 0 && index == 0) {
wingp->special_ship_ship_info_index = Ships[wingp->ship_index[0]].ship_info_index;
}

// if the current count is 0, check to see if the wing departed or was destroyed.
if (wingp->current_count == 0)
{
Expand Down Expand Up @@ -11108,8 +11092,8 @@ void change_ship_type(int n, int ship_type, int by_sexp)
ph_inf = objp->phys_info;

// if this ship is the wing leader, update the ship info index that the wing keeps track of.
if (!Fred_running && p_objp != nullptr && p_objp->wingnum > -1 && p_objp->pos_in_wing == 0) {
Wings[p_objp->wingnum].special_ship_ship_info_index = ship_type;
if (!Fred_running && p_objp != nullptr && p_objp->wingnum >= 0 && p_objp->pos_in_wing == 0) {
Wings[p_objp->wingnum].wing_leader_ship_class = ship_type;
}

// MageKing17 - See if any AIs are doing anything with subsystems of this ship (targeting, goal to destroy)
Expand Down
3 changes: 1 addition & 2 deletions code/ship/ship.h
Original file line number Diff line number Diff line change
Expand Up @@ -1566,8 +1566,7 @@ typedef struct wing {
int total_departed; // total number of ships departed in this wing (including all waves)
int total_vanished; // total number of ships vanished in this wing (including all waves)

int special_ship; // the leader of the wing. An index into ship_index[].
int special_ship_ship_info_index; // the ship info index of the special ship
int wing_leader_ship_class; // the ship info index of the wing leader

int arrival_location; // arrival and departure information for wings -- similar to info for ships
int arrival_distance; // distance from some ship where this ship arrives
Expand Down
8 changes: 4 additions & 4 deletions fred2/dumpstats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ void DumpStats::get_species_ship_breakdown(CString &buffer)
buffer += "\tFighter wings:\r\n";
for (i=0; i<MAX_WINGS; i++) {
if (Wings[i].wave_count > 0) {
int wing_leader_shipnum = Wings[i].ship_index[Wings[i].special_ship];
int wing_leader_shipnum = Wings[i].ship_index[0];
if (Ship_info[Ships[wing_leader_shipnum].ship_info_index].species == species) {
if (Ship_info[Ships[wing_leader_shipnum].ship_info_index].flags[Ship::Info_Flags::Fighter]) {
temp.Format("\t\tWing: %s, count: %d, waves: %d, type: %s\r\n", Wings[i].name, Wings[i].wave_count, Wings[i].num_waves, Ship_info[Ships[wing_leader_shipnum].ship_info_index].name);
Expand All @@ -598,7 +598,7 @@ void DumpStats::get_species_ship_breakdown(CString &buffer)
buffer += "\tBomber wings:\r\n";
for (i=0; i<MAX_WINGS; i++) {
if (Wings[i].wave_count > 0) {
int wing_leader_shipnum = Wings[i].ship_index[Wings[i].special_ship];
int wing_leader_shipnum = Wings[i].ship_index[0];
if (Ship_info[Ships[wing_leader_shipnum].ship_info_index].species == species) {
if (Ship_info[Ships[wing_leader_shipnum].ship_info_index].flags[Ship::Info_Flags::Bomber]) {
temp.Format("\t\tWing: %s, count: %d, waves: %d, type: %s\r\n", Wings[i].name, Wings[i].wave_count, Wings[i].num_waves, Ship_info[Ships[wing_leader_shipnum].ship_info_index].name);
Expand Down Expand Up @@ -765,7 +765,7 @@ void DumpStats::get_default_ship_loadouts(CString &buffer)
buffer += "\tFighter wings:\r\n";
for (i=0; i<MAX_WINGS; i++) {
if (Wings[i].wave_count > 0) {
int wing_leader_shipnum = Wings[i].ship_index[Wings[i].special_ship];
int wing_leader_shipnum = Wings[i].ship_index[0];
if (Ship_info[Ships[wing_leader_shipnum].ship_info_index].species == species) {
if (Ship_info[Ships[wing_leader_shipnum].ship_info_index].flags[Ship::Info_Flags::Fighter]) {
temp.Format("\t\tWing: %s\r\n", Wings[i].name);
Expand All @@ -781,7 +781,7 @@ void DumpStats::get_default_ship_loadouts(CString &buffer)
buffer += "\tBomber wings:\r\n";
for (i=0; i<MAX_WINGS; i++) {
if (Wings[i].wave_count > 0) {
int wing_leader_shipnum = Wings[i].ship_index[Wings[i].special_ship];
int wing_leader_shipnum = Wings[i].ship_index[0];
if (Ship_info[Ships[wing_leader_shipnum].ship_info_index].species == species) {
if (Ship_info[Ships[wing_leader_shipnum].ship_info_index].flags[Ship::Info_Flags::Bomber]) {
temp.Format("\t\tWing: %s\r\n", Wings[i].name);
Expand Down
16 changes: 6 additions & 10 deletions fred2/fred.rc
Original file line number Diff line number Diff line change
Expand Up @@ -1193,12 +1193,11 @@ BEGIN
PUSHBUTTON "Prev",IDC_PREV,240,7,24,14,0,WS_EX_STATICEDGE
PUSHBUTTON "Next",IDC_NEXT,267,7,24,14,0,WS_EX_STATICEDGE
EDITTEXT IDC_WING_NAME,65,7,73,14,ES_AUTOHSCROLL
COMBOBOX IDC_WING_SPECIAL_SHIP,65,23,73,161,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_WING_WAVES,65,37,61,14,ES_AUTOHSCROLL | ES_NUMBER
EDITTEXT IDC_WING_WAVES,65,23,61,14,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "Spin2",IDC_SPIN_WAVES,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,127,37,11,15
EDITTEXT IDC_WING_WAVE_THRESHOLD,65,53,61,15,ES_AUTOHSCROLL | ES_NUMBER
EDITTEXT IDC_WING_WAVE_THRESHOLD,65,39,61,15,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "Spin2",IDC_SPIN_WAVE_THRESHOLD,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,127,53,11,15
COMBOBOX IDC_HOTKEY,65,70,73,115,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_HOTKEY,65,56,73,115,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Squad Logo",IDC_WING_SQUAD_LOGO_BUTTON,7,89,55,14
EDITTEXT IDC_WING_SQUAD_LOGO,65,90,80,14,ES_AUTOHSCROLL | ES_READONLY
CONTROL "Reinforcement Unit",IDC_REINFORCEMENT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,143,10,77,10
Expand Down Expand Up @@ -1234,9 +1233,8 @@ BEGIN
CONTROL "Hide Cues",IDC_HIDE_CUES,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE | WS_TABSTOP,241,71,49,12
GROUPBOX "Departure",IDC_STATIC,153,110,138,270
RTEXT "Wing Name",IDC_STATIC,19,10,42,8
RTEXT "Wave Threshold",IDC_STATIC,7,56,54,8
RTEXT "# of Waves",IDC_STATIC,16,40,45,8
RTEXT "Leader",IDC_STATIC,38,25,23,8,NOT WS_GROUP
RTEXT "Wave Threshold",IDC_STATIC,7,42,54,8
RTEXT "# of Waves",IDC_STATIC,16,26,45,8
LTEXT "Location",IDC_STATIC,15,124,28,8
LTEXT "Cue:",IDC_STATIC,15,259,16,8
GROUPBOX "Arrival",IDC_CUE_FRAME,7,110,138,270
Expand All @@ -1245,7 +1243,7 @@ BEGIN
LTEXT "Delay",IDC_STATIC,160,140,19,8
LTEXT "Delay",IDC_STATIC,15,140,19,8
LTEXT "Seconds",IDC_STATIC,102,141,45,8
RTEXT "Hotkey",IDC_STATIC,37,72,24,8
RTEXT "Hotkey",IDC_STATIC,37,58,24,8
GROUPBOX "Delay Between Waves",IDC_STATIC,15,154,119,30
LTEXT "Min",IDC_STATIC,21,167,12,8
LTEXT "Max",IDC_STATIC,80,167,14,8
Expand Down Expand Up @@ -3144,8 +3142,6 @@ END

IDD_WING_EDITOR DLGINIT
BEGIN
IDC_WING_SPECIAL_SHIP, 0x403, 6, 0
0x6977, 0x676e, 0x0031,
IDC_HOTKEY, 0x403, 5, 0
0x6f4e, 0x656e, "\000"
IDC_HOTKEY, 0x403, 11, 0
Expand Down
7 changes: 1 addition & 6 deletions fred2/fredview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2785,10 +2785,6 @@ int CFREDView::global_error_check()
}
}

if ((Wings[i].special_ship < 0) || (Wings[i].special_ship >= Wings[i].wave_count)){
return internal_error("Special ship out of range for \"%s\"", Wings[i].name);
}

if (Wings[i].num_waves < 0){
return internal_error("Number of waves for \"%s\" is negative", Wings[i].name);
}
Expand Down Expand Up @@ -4376,8 +4372,7 @@ void CFREDView::OnMarkWing()
for (i=0; i<Wings[wing].wave_count; i++)
mark_object(wing_objects[wing][i]);

Assert(Wings[wing].special_ship >= 0 && Wings[wing].special_ship < Wings[wing].wave_count);
set_cur_object_index(wing_objects[wing][Wings[wing].special_ship]);
set_cur_object_index(wing_objects[wing][0]);
}
}

Expand Down
5 changes: 0 additions & 5 deletions fred2/management.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1349,11 +1349,6 @@ int delete_ship_from_wing(int ship)
}

Assert(i != -1); // Error, object should be in wing.
if (Wings[wing].special_ship == i){
Wings[wing].special_ship = 0;
} else if (Wings[wing].special_ship > i) {
Wings[wing].special_ship--;
}

if (i != end) {
wing_objects[wing][i] = wing_objects[wing][end];
Expand Down
10 changes: 6 additions & 4 deletions fred2/missionsave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4912,10 +4912,12 @@ int CFred_mission_save::save_wings()
parse_comments();
fout(" %d", Wings[i].threshold);

required_string_fred("$Special Ship:");
parse_comments();
fout(" %d\t\t;! %s", Wings[i].special_ship,
Ships[Wings[i].ship_index[Wings[i].special_ship]].ship_name);
if (Mission_save_format == FSO_FORMAT_RETAIL) {
if (optional_string_fred("$Special Ship:")) {
parse_comments();
fout(" %d\t\t;! %s", 0, Ships[Wings[i].ship_index[0]].ship_name);
}
}

if (Mission_save_format != FSO_FORMAT_RETAIL) {
if (Wings[i].formation >= 0 && Wings[i].formation < (int)Wing_formations.size())
Expand Down
1 change: 0 additions & 1 deletion fred2/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@
#define IDC_SHIP_WEAPON1 1019
#define IDC_WEAPON_ENERGY_AMMO_USAGE 1019
#define IDC_SHIP_WEAPON2 1020
#define IDC_WING_SPECIAL_SHIP 1021
#define IDC_MODEL_NAME 1021
#define IDC_WEAPON_LIGHT_CAST 1021
#define IDC_AI_DETERMINATION 1022
Expand Down
Loading

0 comments on commit 8b1e9a9

Please sign in to comment.