Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 22 additions & 29 deletions code/mission/missioncampaign.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,35 +392,33 @@ void mission_campaign_build_list(bool desc, bool sort, bool multiplayer)
*/
void mission_campaign_get_sw_info()
{
int i, count, ship_list[MAX_SHIP_CLASSES], weapon_list[MAX_WEAPON_TYPES];

if (optional_string("+Starting Ships:")) {
count = sz2i(stuff_int_list(ship_list, MAX_SHIP_CLASSES, ParseLookupType::SHIP_INFO_TYPE));

// now set the array elements stating which ships we are allowed
for (i = 0; i < count; i++) {
if (Ship_info[ship_list[i]].flags[Ship::Info_Flags::Player_ship])
Campaign.ships_allowed[ship_list[i]] = 1;
}
}
else {
if (optional_string("+Starting Ships:")) {
SCP_vector<int> ship_list;
stuff_int_list(ship_list, ParseLookupType::SHIP_INFO_TYPE);

// now set the array elements stating which ships we are allowed
for (int idx : ship_list) {
if (Ship_info[idx].flags[Ship::Info_Flags::Player_ship])
Campaign.ships_allowed[idx] = 1;
}
} else {
// set allowable ships to the SIF_PLAYER_SHIPs
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it) {
if (it->flags[Ship::Info_Flags::Player_ship])
Campaign.ships_allowed[std::distance(Ship_info.cbegin(), it)] = 1;
}
}

if (optional_string("+Starting Weapons:")) {
count = sz2i(stuff_int_list(weapon_list, MAX_WEAPON_TYPES, ParseLookupType::WEAPON_POOL_TYPE));
if (optional_string("+Starting Weapons:")) {
SCP_vector<int> weapon_list;
stuff_int_list(weapon_list, ParseLookupType::WEAPON_POOL_TYPE);

// now set the array elements stating which ships we are allowed
for (i = 0; i < count; i++) {
if (Weapon_info[weapon_list[i]].wi_flags[Weapon::Info_Flags::Player_allowed])
Campaign.weapons_allowed[weapon_list[i]] = 1;
// now set the array elements stating which weapons we are allowed
for (int idx : weapon_list) {
if (Weapon_info[idx].wi_flags[Weapon::Info_Flags::Player_allowed])
Campaign.weapons_allowed[idx] = 1;
}
}
else {
} else {
// set allowable weapons to the player-allowed ones
for (auto it = Weapon_info.cbegin(); it != Weapon_info.cend(); ++it) {
if (it->wi_flags[Weapon::Info_Flags::Player_allowed])
Expand Down Expand Up @@ -732,13 +730,8 @@ void player_loadout_init()
memset(Player_loadout.filename, 0, sizeof(Player_loadout.filename));
memset(Player_loadout.last_modified, 0, sizeof(Player_loadout.last_modified));

for ( i = 0; i < MAX_SHIP_CLASSES; i++ ) {
Player_loadout.ship_pool[i] = 0;
}

for ( i = 0; i < MAX_WEAPON_TYPES; i++ ) {
Player_loadout.weapon_pool[i] = 0;
}
Player_loadout.ship_pool.assign(ship_info_size(), 0);
Player_loadout.weapon_pool.assign(weapon_info_size(), 0);

for ( i = 0; i < MAX_WSS_SLOTS; i++ ) {
Player_loadout.unit_data[i].ship_class = -1;
Expand Down Expand Up @@ -1270,8 +1263,8 @@ void mission_campaign_clear()
Campaign.loop_reentry = 0;
Campaign.realign_required = 0;
Campaign.num_players = 0;
memset( Campaign.ships_allowed, 0, sizeof(Campaign.ships_allowed) );
memset( Campaign.weapons_allowed, 0, sizeof(Campaign.weapons_allowed) );
Campaign.ships_allowed.assign(ship_info_size(), 0);
Campaign.weapons_allowed.assign(weapon_info_size(), 0);
Campaign.persistent_variables.clear();
Campaign.red_alert_variables.clear();
Campaign.persistent_containers.clear();
Expand Down
4 changes: 2 additions & 2 deletions code/mission/missioncampaign.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ class campaign
int loop_reentry; // mission number to return to after loop is finished
int realign_required; // are any missions missing alignment info? (Fred)
int num_players; // valid in multiplayer campaigns -- number of players campaign supports.
ubyte ships_allowed[MAX_SHIP_CLASSES]; // which ships the player can use
ubyte weapons_allowed[MAX_WEAPON_TYPES]; // which weapons the player can use
SCP_vector<ubyte> ships_allowed; // which ships the player can use
SCP_vector<ubyte> weapons_allowed; // which weapons the player can use
cmission missions[MAX_CAMPAIGN_MISSIONS]; // decription of the missions
SCP_vector<sexp_variable> persistent_variables; // These variables will be saved at the end of a mission
SCP_vector<sexp_variable> red_alert_variables; // state of the variables in the previous mission of a Red Alert scenario.
Expand Down
28 changes: 9 additions & 19 deletions code/missionui/missionscreencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1095,13 +1095,13 @@ void wss_save_loadout()
Assert( (Ss_pool != NULL) && (Wl_pool != NULL) && (Wss_slots != NULL) );

// save the ship pool
for ( i = 0; i < MAX_SHIP_CLASSES; i++ ) {
Player_loadout.ship_pool[i] = Ss_pool[i];
for ( i = 0; i < ship_info_size(); i++ ) {
Player_loadout.ship_pool[i] = Ss_pool[i];
}

// save the weapons pool
for ( i = 0; i < MAX_WEAPON_TYPES; i++ ) {
Player_loadout.weapon_pool[i] = Wl_pool[i];
for ( i = 0; i < weapon_info_size(); i++ ) {
Player_loadout.weapon_pool[i] = Wl_pool[i];
}

// save the ship class / weapons for each slot
Expand Down Expand Up @@ -1132,23 +1132,13 @@ void wss_maybe_restore_loadout()
return;
}

// first we generate a pool of ships and weapons used the last time this mission was played. We also generate a pool of what is
// first we generate a pool of ships and weapons used the last time this mission was played. We also generate a pool of what is
// available in this mission.
int last_loadout_ships[MAX_SHIP_CLASSES];
int this_loadout_ships[MAX_SHIP_CLASSES];

int last_loadout_weapons[MAX_WEAPON_TYPES];
int this_loadout_weapons[MAX_WEAPON_TYPES];
SCP_vector<int> last_loadout_ships(ship_info_size(), 0);
SCP_vector<int> this_loadout_ships(ship_info_size(), 0);

// zero all pools
for (i = 0; i < MAX_SHIP_CLASSES; i++) {
last_loadout_ships[i] = 0;
this_loadout_ships[i] = 0;
}
for (i = 0; i < MAX_WEAPON_TYPES; i++) {
last_loadout_weapons[i] = 0;
this_loadout_weapons[i] = 0;
}
SCP_vector<int> last_loadout_weapons(weapon_info_size(), 0);
SCP_vector<int> this_loadout_weapons(weapon_info_size(), 0);

// record the ship classes / weapons used last time
for ( i = 0; i < MAX_WSS_SLOTS; i++ ) {
Expand Down
4 changes: 2 additions & 2 deletions code/missionui/missionscreencommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,8 @@ typedef struct loadout_data
char filename[MAX_FILENAME_LEN]; // mission filename
char last_modified[DATE_TIME_LENGTH]; // when mission was last modified
wss_unit unit_data[MAX_WSS_SLOTS]; // ship and weapon data
int weapon_pool[MAX_WEAPON_TYPES]; // available weapons
int ship_pool[MAX_SHIP_CLASSES]; // available ships
SCP_vector<int> weapon_pool; // available weapons
SCP_vector<int> ship_pool; // available ships
} loadout_data;

extern loadout_data Player_loadout;
Expand Down
14 changes: 7 additions & 7 deletions code/network/multi_campaign.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,29 +279,29 @@ void multi_campaign_process_update(ubyte *data, header *hinfo)
}
} else {
// clear the ships and weapons allowed arrays
memset(Campaign.ships_allowed,0,MAX_SHIP_CLASSES);
memset(Campaign.weapons_allowed,0,MAX_WEAPON_TYPES);
Campaign.ships_allowed.assign(ship_info_size(), 0);
Campaign.weapons_allowed.assign(weapon_info_size(), 0);

// get all ship classes
GET_USHORT(spool_size);
for(idx=0;idx<spool_size;idx++){
GET_USHORT(s_val);

if (s_val < MAX_SHIP_CLASSES) {
if (Campaign.ships_allowed.in_bounds(s_val)) {
Campaign.ships_allowed[s_val] = 1;
}
}
}

// get all weapon classes
GET_USHORT(wpool_size);
for(idx=0;idx<wpool_size;idx++){
GET_USHORT(s_val);

if (s_val < MAX_WEAPON_TYPES) {
if (Campaign.weapons_allowed.in_bounds(s_val)) {
Campaign.weapons_allowed[s_val] = 1;
}
}
}
}

// ack the server
Net_player->state = NETPLAYER_STATE_CPOOL_ACK;
Expand Down
11 changes: 10 additions & 1 deletion code/network/multi_fstracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,11 @@ void multi_stats_fs_to_tracker(scoring_struct *fs, vmt_stats_struct *vmt, player
// find only up to last in array with at least 1 kill
vmt->num_ships = MAX_FS2OPEN_COUNTS - vmt->num_medals;

// can't transmit more ship classes than this mod actually has
if (static_cast<size_t>(vmt->num_ships) > fs->kills.size()) {
vmt->num_ships = static_cast<unsigned char>(fs->kills.size());
}

for (int idx = vmt->num_ships-1; idx >= 0; --idx) {
if (fs->kills[idx] > 0) {
break;
Expand Down Expand Up @@ -958,7 +963,11 @@ void multi_stats_tracker_to_fs(vmt_stats_struct *vmt,scoring_struct *fs)
fs->medal_counts[idx] = static_cast<int>(vmt->counts[idx]);
}
} else {
fs->kills[idx2++] = static_cast<int>(vmt->counts[idx]);
// tracker may have more ship slots than this mod's ship_info; drop excess
if (fs->kills.in_bounds(idx2)) {
fs->kills[idx2] = static_cast<int>(vmt->counts[idx]);
}
++idx2;
}
}
}
Expand Down
21 changes: 12 additions & 9 deletions code/network/multimsgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6564,11 +6564,13 @@ void send_player_stats_block_packet(net_player *pl, int stats_code, net_player *

// kill information - alltime
switch(stats_code){
case STATS_ALLTIME:
case STATS_ALLTIME:
// alltime kills
// Wire protocol packs offset/count as USHORT; bump to wider field if ship_info_size() ever exceeds USHRT_MAX.
Assertion(sc->kills.size() <= USHRT_MAX, "ship_info_size() exceeds STATS_ALLTIME_KILLS packet's USHORT field width");
idx = 0;
while (idx < MAX_SHIP_CLASSES) {
send_player_stats_block_packet(pl, STATS_ALLTIME_KILLS, target, idx, MAX_SHIP_CLASSES-idx);
while (idx < sz2i(sc->kills.size())) {
send_player_stats_block_packet(pl, STATS_ALLTIME_KILLS, target, idx, sz2i(sc->kills.size())-idx);
idx += MAX_SHIPS_PER_PACKET;
}

Expand Down Expand Up @@ -6600,11 +6602,12 @@ void send_player_stats_block_packet(net_player *pl, int stats_code, net_player *
ADD_INT(sc->last_backup); // should be 32-bit value - taylor
break;

case STATS_MISSION:
// mission OKkills
case STATS_MISSION:
// mission OKkills
Assertion(sc->m_okKills.size() <= USHRT_MAX, "ship_info_size() exceeds STATS_MISSION_CLASS_KILLS packet's USHORT field width");
idx = 0;
while (idx < MAX_SHIP_CLASSES) {
send_player_stats_block_packet(pl, STATS_MISSION_CLASS_KILLS, target, idx, MAX_SHIP_CLASSES-idx);
while (idx < sz2i(sc->m_okKills.size())) {
send_player_stats_block_packet(pl, STATS_MISSION_CLASS_KILLS, target, idx, sz2i(sc->m_okKills.size())-idx);
idx += MAX_SHIPS_PER_PACKET;
}

Expand Down Expand Up @@ -6720,7 +6723,7 @@ void process_player_stats_block_packet(ubyte *data, header *hinfo)
for (idx = si_offset; idx < si_offset+si_count; idx++) {
GET_INT(i_tmp);

if (idx < MAX_SHIP_CLASSES) {
if (sc->kills.in_bounds(idx)) {
sc->kills[idx] = i_tmp;
}
}
Expand All @@ -6733,7 +6736,7 @@ void process_player_stats_block_packet(ubyte *data, header *hinfo)
for (idx = si_offset; idx < si_offset+si_count; idx++) {
GET_INT(i_tmp);

if (idx < MAX_SHIP_CLASSES) {
if (sc->m_okKills.in_bounds(idx)) {
sc->m_okKills[idx] = i_tmp;
}
}
Expand Down
4 changes: 2 additions & 2 deletions code/pilotfile/csg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1610,8 +1610,8 @@ void pilotfile::csg_reset_data(bool reset_ships_and_weapons)

// zero out allowed ships/weapons
if (reset_ships_and_weapons) {
memset(Campaign.ships_allowed, 0, sizeof(Campaign.ships_allowed));
memset(Campaign.weapons_allowed, 0, sizeof(Campaign.weapons_allowed));
Campaign.ships_allowed.assign(ship_info_size(), 0);
Campaign.weapons_allowed.assign(weapon_info_size(), 0);
}

// reset campaign status
Expand Down
4 changes: 2 additions & 2 deletions code/pilotfile/pilotfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ void pilotfile::set_multi_stats(const scoring_struct *stats)
multi_stats.ship_kills.clear();
multi_stats.ship_kills.shrink_to_fit();

auto kills_size = std::min(SDL_arraysize(stats->kills), Ship_info.size());
auto kills_size = stats->kills.size();

for (idx = 0; idx < kills_size; ++idx) {
if (stats->kills[idx] <= 0) {
Expand Down Expand Up @@ -446,7 +446,7 @@ bool pilotfile::export_stats(scoring_struct *stats)

// only export ships that this mod knows about (should already be index)
for (auto &item : p_stats->ship_kills) {
if ( (item.index >= 0) && (item.index < MAX_SHIP_CLASSES) ) {
if ( stats->kills.in_bounds(item.index) ) {
stats->kills[item.index] = item.val;
}
}
Expand Down
4 changes: 2 additions & 2 deletions code/pilotfile/plr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ void pilotfile::plr_read_stats()
for (size_t idx = 0; idx < list_size; idx++) {
auto j = all_time_stats.ship_kills[idx].index;

if (j >= 0) {
if (p->stats.kills.in_bounds(j)) {
p->stats.kills[j] = all_time_stats.ship_kills[idx].val;
}
}
Expand Down Expand Up @@ -665,7 +665,7 @@ void pilotfile::plr_read_stats_multi()
for (size_t idx = 0; idx < list_size; idx++) {
auto j = multi_stats.ship_kills[idx].index;

if (j >= 0) {
if (p->stats.kills.in_bounds(j)) {
p->stats.kills[j] = multi_stats.ship_kills[idx].val;
}
}
Expand Down
Loading
Loading