mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 08:15:59 -10:00
Store the support rearm pool sparsely (#7758)
`support_ship_info::rearm_weapon_pool` was a dense per-weapon-class array where -1 = unlimited (the default), 0 = not rearmable, and >0 = remaining stockpile. Convert it to a sparse per-team map: `std::array<SCP_map<int, int>, MAX_TVT_TEAMS> rearm_weapon_pool;` `int rearm_pool_default() const; // -1, or 0 under rearm_pool_from_loadout` Mission-file format and save output are unchanged. Also tightens the two weapon-class bounds checks in ship.cpp. This removes another `MAX_WEAPON_TYPES` sized structure on the way to lifting the weapon class limit. Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
1 parent
8e60b69922
commit
a168f5a9c0
12 files changed
+161
-91
No files matched your search
@@ -1305,13 +1305,8 @@ void parse_player_info2(mission *pm)
|
||||
required_string("+Weaponry Pool:");
|
||||
stuff_loadout_list(list2, ParseLookupType::MISSION_LOADOUT_WEAPON_LIST);
|
||||
|
||||
// When seeding the rearm pool from the loadout, reset this team's row to 0 so the per-weapon
|
||||
// loadout counts below accumulate from a clean baseline (rather than the -1 "unlimited" default).
|
||||
if (pm->support_ships.rearm_pool_from_loadout) {
|
||||
for (int wep = 0; wep < MAX_WEAPON_TYPES; ++wep) {
|
||||
pm->support_ships.rearm_weapon_pool[nt][wep] = 0;
|
||||
}
|
||||
}
|
||||
// When seeding the rearm pool from the loadout, the per-weapon loadout counts below accumulate
|
||||
// from a clean baseline: rearm_pool_default() is 0 in this mode, so no reset is needed here.
|
||||
|
||||
// check weapon class loadout entries
|
||||
for (auto &wc : list2) {
|
||||
@@ -1338,10 +1333,12 @@ void parse_player_info2(mission *pm)
|
||||
entry.count = wc.count;
|
||||
|
||||
if (pm->support_ships.rearm_pool_from_loadout) {
|
||||
if (Weapon_info[wc.index].disallow_rearm) {
|
||||
pm->support_ships.rearm_weapon_pool[nt][wc.index] = 0;
|
||||
} else if (wc.count > 0 && pm->support_ships.rearm_weapon_pool[nt][wc.index] >= 0) {
|
||||
pm->support_ships.rearm_weapon_pool[nt][wc.index] += wc.count;
|
||||
// disallow_rearm weapons stay at the from_loadout default of 0, i.e. absent
|
||||
if (!Weapon_info[wc.index].disallow_rearm && wc.count > 0) {
|
||||
int cur = pm->support_ships.rearm_weapon_pool[nt].value_or(wc.index, 0);
|
||||
if (cur >= 0) {
|
||||
pm->support_ships.rearm_weapon_pool[nt][wc.index] = cur + wc.count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1371,16 +1368,17 @@ void parse_player_info2(mission *pm)
|
||||
continue;
|
||||
}
|
||||
|
||||
auto& slot = pm->support_ships.rearm_weapon_pool[nt][wc.index];
|
||||
auto& team_pool = pm->support_ships.rearm_weapon_pool[nt];
|
||||
if (Weapon_info[wc.index].disallow_rearm) {
|
||||
slot = 0;
|
||||
team_pool[wc.index] = 0;
|
||||
} else if (wc.count < 0) {
|
||||
slot = -1;
|
||||
team_pool.erase(wc.index); // explicit unlimited == the -1 default, i.e. absent
|
||||
} else if (wc.count == 0) {
|
||||
slot = 0;
|
||||
team_pool[wc.index] = 0;
|
||||
} else if (wc.count > 0) {
|
||||
// First explicit entry replaces the -1 (unlimited) default; later duplicate entries accumulate.
|
||||
slot = (slot < 0) ? wc.count : slot + wc.count;
|
||||
int cur = team_pool.value_or(wc.index, -1);
|
||||
team_pool[wc.index] = (cur < 0) ? wc.count : cur + wc.count;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7387,7 +7385,7 @@ void support_ship_info::reset()
|
||||
tally = 0;
|
||||
support_available_for_species = 0; // will be filled in by the next loop
|
||||
for (auto& team_pool : rearm_weapon_pool) {
|
||||
std::fill(std::begin(team_pool), std::end(team_pool), -1); // -1 == unlimited per-weapon
|
||||
team_pool.clear(); // absent == rearm_pool_default()
|
||||
}
|
||||
disallow_rearm = false;
|
||||
allow_rearm_weapon_precedence = false;
|
||||
@@ -9750,10 +9748,8 @@ bool check_for_25_1_data()
|
||||
}
|
||||
|
||||
for (int team = 0; team < Num_teams; ++team) {
|
||||
for (int pool_wep = 0; pool_wep < MAX_WEAPON_TYPES; ++pool_wep) {
|
||||
if (The_mission.support_ships.rearm_weapon_pool[team][pool_wep] != -1) {
|
||||
return true;
|
||||
}
|
||||
if (!The_mission.support_ships.rearm_weapon_pool[team].empty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#ifndef _PARSE_H
|
||||
#define _PARSE_H
|
||||
|
||||
#include <array>
|
||||
#include <csetjmp>
|
||||
#include <set>
|
||||
|
||||
@@ -116,7 +117,14 @@ struct support_ship_info
|
||||
bool disallow_rearm; // if true, support ships can only repair and will not rearm weapons
|
||||
bool allow_rearm_weapon_precedence; // if true, support ships may swap to precedence weapons when rearm pool is empty
|
||||
bool rearm_pool_from_loadout; // initialize rearm pool from mission loadout after filling starting loadout ships
|
||||
int rearm_weapon_pool[MAX_TVT_TEAMS][MAX_WEAPON_TYPES]; // mission stockpile used to limit support ship rearming
|
||||
|
||||
// mission stockpile used to limit support ship rearming: weapon class -> amount remaining
|
||||
// (-1 = unlimited, 0 = not rearmable, >0 = limited); an absent entry means rearm_pool_default()
|
||||
std::array<SCP_map<int, int>, MAX_TVT_TEAMS> rearm_weapon_pool;
|
||||
|
||||
// the default for weapon classes without a pool entry: normally unlimited, but when the pool
|
||||
// is seeded from the mission loadout, any weapon not in the loadout cannot be rearmed
|
||||
int rearm_pool_default() const { return rearm_pool_from_loadout ? 0 : -1; }
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
@@ -4326,7 +4326,7 @@ int Fred_mission_save::save_objects()
|
||||
int Fred_mission_save::save_players()
|
||||
{
|
||||
bool wrote_fso_data = false;
|
||||
int i, j;
|
||||
int i;
|
||||
int var_idx;
|
||||
SCP_map<int, int> used_pool;
|
||||
|
||||
@@ -4525,18 +4525,17 @@ int Fred_mission_save::save_players()
|
||||
// version-gated support options; see also check_for_25_1_data()
|
||||
auto more_support_options_version = gameversion::version(25, 1);
|
||||
|
||||
// a savable pool entry is one on a rearmable player-allowed weapon with a non-default (!= -1) amount
|
||||
auto is_savable_rearm_pool_entry = [](const std::pair<const int, int> &entry) {
|
||||
return Weapon_info[entry.first].wi_flags[Weapon::Info_Flags::Player_allowed] &&
|
||||
!Weapon_info[entry.first].disallow_rearm && entry.second != -1;
|
||||
};
|
||||
|
||||
const auto &team_rearm_pool = The_mission.support_ships.rearm_weapon_pool[i];
|
||||
|
||||
bool has_rearm_pool_entries = false;
|
||||
if (save_config.save_format != MissionFormat::RETAIL && The_mission.required_fso_version >= more_support_options_version && !The_mission.support_ships.rearm_pool_from_loadout) {
|
||||
for (j = 0; j < weapon_info_size(); j++) {
|
||||
// mirror the skip conditions used when writing the pool below
|
||||
if (!Weapon_info[j].wi_flags[Weapon::Info_Flags::Player_allowed] || Weapon_info[j].disallow_rearm) {
|
||||
continue;
|
||||
}
|
||||
if (The_mission.support_ships.rearm_weapon_pool[i][j] != -1) {
|
||||
has_rearm_pool_entries = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
has_rearm_pool_entries = std::any_of(team_rearm_pool.begin(), team_rearm_pool.end(), is_savable_rearm_pool_entry);
|
||||
}
|
||||
if (has_rearm_pool_entries) {
|
||||
if (optional_string_fred("+Support Rearm Pool:", "$Starting Shipname:")) {
|
||||
@@ -4545,17 +4544,11 @@ int Fred_mission_save::save_players()
|
||||
fout("\n\n+Support Rearm Pool:");
|
||||
}
|
||||
|
||||
// the map iterates in ascending weapon class order, matching the old full scan
|
||||
fout(" (\n");
|
||||
for (j = 0; j < weapon_info_size(); j++) {
|
||||
if (!Weapon_info[j].wi_flags[Weapon::Info_Flags::Player_allowed]) {
|
||||
continue;
|
||||
}
|
||||
// Default is -1 (unlimited). Skip disallow_rearm weapons too, parse normalizes them to 0 anyway.
|
||||
if (Weapon_info[j].disallow_rearm) {
|
||||
continue;
|
||||
}
|
||||
if (The_mission.support_ships.rearm_weapon_pool[i][j] != -1) {
|
||||
fout("\t\"%s\"\t%d\n", Weapon_info[j].name, The_mission.support_ships.rearm_weapon_pool[i][j]);
|
||||
for (const auto &entry : team_rearm_pool) {
|
||||
if (is_savable_rearm_pool_entry(entry)) {
|
||||
fout("\t\"%s\"\t%d\n", Weapon_info[entry.first].name, entry.second);
|
||||
}
|
||||
}
|
||||
fout(")");
|
||||
|
||||
@@ -47,15 +47,20 @@ ADE_INDEXER(l_SupportRearmPoolTeam,
|
||||
return ADE_RETURN_NIL;
|
||||
}
|
||||
|
||||
auto &team_pool = The_mission.support_ships.rearm_weapon_pool[team_idx];
|
||||
int pool_default = The_mission.support_ships.rearm_pool_default();
|
||||
|
||||
if (ADE_SETTING_VAR) {
|
||||
// disallow_rearm weapons always read as 0, so there is nothing to store for them
|
||||
if (!Weapon_info[idx].disallow_rearm) {
|
||||
if (amount < 0) {
|
||||
The_mission.support_ships.rearm_weapon_pool[team_idx][idx] = -1;
|
||||
int new_value = (amount < 0) ? -1 : amount;
|
||||
|
||||
// don't store the default value; absence means the default
|
||||
if (new_value == pool_default) {
|
||||
team_pool.erase(idx);
|
||||
} else {
|
||||
The_mission.support_ships.rearm_weapon_pool[team_idx][idx] = amount;
|
||||
team_pool[idx] = new_value;
|
||||
}
|
||||
} else {
|
||||
The_mission.support_ships.rearm_weapon_pool[team_idx][idx] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +68,7 @@ ADE_INDEXER(l_SupportRearmPoolTeam,
|
||||
return ade_set_args(L, "i", 0);
|
||||
}
|
||||
|
||||
return ade_set_args(L, "i", The_mission.support_ships.rearm_weapon_pool[team_idx][idx]);
|
||||
return ade_set_args(L, "i", team_pool.value_or(idx, pool_default));
|
||||
}
|
||||
|
||||
ADE_FUNC(__len,
|
||||
|
||||
+26
-15
@@ -10831,12 +10831,15 @@ void ship_process_post(object * obj, float frametime)
|
||||
shipp->weapons.secondary_bank_start_ammo[i] = shipp->weapons.secondary_bank_ammo[i];
|
||||
}
|
||||
|
||||
if (The_mission.support_ships.rearm_pool_from_loadout && shipp->flags[Ship_Flags::From_player_wing]) {
|
||||
// the pool only exists for player loadout teams
|
||||
if (The_mission.support_ships.rearm_pool_from_loadout && shipp->flags[Ship_Flags::From_player_wing] && shipp->team >= 0 && shipp->team < Num_teams) {
|
||||
const int weapon_class = shipp->weapons.secondary_bank_weapons[i];
|
||||
if (SCP_vector_inbounds(Weapon_info, weapon_class)) {
|
||||
auto& slot = The_mission.support_ships.rearm_weapon_pool[shipp->team][weapon_class];
|
||||
if (slot >= 0) {
|
||||
slot = MAX(0, slot - shipp->weapons.secondary_bank_ammo[i]);
|
||||
// an absent entry is either unlimited or already 0, so subtracting from it is a no-op either way
|
||||
auto& team_pool = The_mission.support_ships.rearm_weapon_pool[shipp->team];
|
||||
auto it = team_pool.find(weapon_class);
|
||||
if (it != team_pool.end() && it->second >= 0) {
|
||||
it->second = MAX(0, it->second - shipp->weapons.secondary_bank_ammo[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10855,11 +10858,13 @@ void ship_process_post(object * obj, float frametime)
|
||||
}
|
||||
|
||||
const int weapon_class = shipp->weapons.primary_bank_weapons[i];
|
||||
if (The_mission.support_ships.rearm_pool_from_loadout && shipp->flags[Ship_Flags::From_player_wing] &&
|
||||
SCP_vector_inbounds(Weapon_info, weapon_class) && Weapon_info[weapon_class].wi_flags[Weapon::Info_Flags::Ballistic]) {
|
||||
auto& slot = The_mission.support_ships.rearm_weapon_pool[shipp->team][weapon_class];
|
||||
if (slot >= 0) {
|
||||
slot = MAX(0, slot - shipp->weapons.primary_bank_ammo[i]);
|
||||
// the pool only exists for player loadout teams
|
||||
if (The_mission.support_ships.rearm_pool_from_loadout && shipp->flags[Ship_Flags::From_player_wing] && shipp->team >= 0 && shipp->team < Num_teams
|
||||
&& SCP_vector_inbounds(Weapon_info, weapon_class) && Weapon_info[weapon_class].wi_flags[Weapon::Info_Flags::Ballistic]) {
|
||||
auto& team_pool = The_mission.support_ships.rearm_weapon_pool[shipp->team];
|
||||
auto it = team_pool.find(weapon_class);
|
||||
if (it != team_pool.end() && it->second >= 0) {
|
||||
it->second = MAX(0, it->second - shipp->weapons.primary_bank_ammo[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16101,7 +16106,7 @@ float ship_calculate_rearm_duration( object *objp )
|
||||
|
||||
static int get_mission_rearm_pool_for_weapon(int weapon_class, int team)
|
||||
{
|
||||
if ((weapon_class < 0) || (weapon_class >= MAX_WEAPON_TYPES)) {
|
||||
if (!Weapon_info.in_bounds(weapon_class)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -16118,7 +16123,7 @@ static int get_mission_rearm_pool_for_weapon(int weapon_class, int team)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return The_mission.support_ships.rearm_weapon_pool[team][weapon_class];
|
||||
return The_mission.support_ships.rearm_weapon_pool[team].value_or(weapon_class, The_mission.support_ships.rearm_pool_default());
|
||||
}
|
||||
|
||||
static bool weapon_allowed_for_current_game_type(int weapon_flags)
|
||||
@@ -16213,7 +16218,7 @@ static void use_mission_rearm_pool_for_weapon(int weapon_class, int amount, int
|
||||
return;
|
||||
}
|
||||
|
||||
if ((weapon_class < 0) || (weapon_class >= MAX_WEAPON_TYPES)) {
|
||||
if (!Weapon_info.in_bounds(weapon_class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -16222,12 +16227,18 @@ static void use_mission_rearm_pool_for_weapon(int weapon_class, int amount, int
|
||||
return;
|
||||
}
|
||||
|
||||
if (The_mission.support_ships.rearm_weapon_pool[team][weapon_class] < 0) {
|
||||
auto &team_pool = The_mission.support_ships.rearm_weapon_pool[team];
|
||||
|
||||
int cur = team_pool.value_or(weapon_class, The_mission.support_ships.rearm_pool_default());
|
||||
if (cur < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
The_mission.support_ships.rearm_weapon_pool[team][weapon_class] =
|
||||
MAX(0, The_mission.support_ships.rearm_weapon_pool[team][weapon_class] - amount);
|
||||
// don't insert an entry when nothing changes
|
||||
int next = MAX(0, cur - amount);
|
||||
if (next != cur) {
|
||||
team_pool[weapon_class] = next;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================================================================================
|
||||
|
||||
@@ -22,7 +22,6 @@ CSupportRearmDlg::CSupportRearmDlg(CWnd* pParent) : CDialog(CSupportRearmDlg::ID
|
||||
m_max_subsys_repair_val = 100.0f;
|
||||
m_weapon_pool_amount = 0;
|
||||
m_rearm_pool_team = 0;
|
||||
memset(m_rearm_weapon_pool, 0, sizeof(m_rearm_weapon_pool));
|
||||
}
|
||||
|
||||
void CSupportRearmDlg::DoDataExchange(CDataExchange* pDX)
|
||||
@@ -55,7 +54,7 @@ ON_BN_CLICKED(IDC_DISALLOW_SUPPORT_SHIPS, OnOptionChanged)
|
||||
ON_BN_CLICKED(IDC_SUPPORT_REPAIRS_HULL, OnOptionChanged)
|
||||
ON_BN_CLICKED(IDC_DISALLOW_SUPPORT_REARM, OnOptionChanged)
|
||||
ON_BN_CLICKED(IDC_LIMIT_SUPPORT_REARM_TO_POOL, OnOptionChanged)
|
||||
ON_BN_CLICKED(IDC_SUPPORT_REARM_POOL_FROM_LOADOUT, OnOptionChanged)
|
||||
ON_BN_CLICKED(IDC_SUPPORT_REARM_POOL_FROM_LOADOUT, OnRearmPoolFromLoadoutChanged)
|
||||
ON_BN_CLICKED(IDC_ALLOW_SUPPORT_REARM_PRECEDENCE, OnOptionChanged)
|
||||
ON_WM_DRAWITEM()
|
||||
END_MESSAGE_MAP()
|
||||
@@ -70,7 +69,7 @@ BOOL CSupportRearmDlg::OnInitDialog()
|
||||
m_rearm_pool_from_loadout = The_mission.support_ships.rearm_pool_from_loadout ? TRUE : FALSE;
|
||||
m_max_hull_repair_val = The_mission.support_ships.max_hull_repair_val;
|
||||
m_max_subsys_repair_val = The_mission.support_ships.max_subsys_repair_val;
|
||||
memcpy(m_rearm_weapon_pool, The_mission.support_ships.rearm_weapon_pool, sizeof(m_rearm_weapon_pool));
|
||||
m_rearm_weapon_pool = The_mission.support_ships.rearm_weapon_pool;
|
||||
m_rearm_pool_team = 0;
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
@@ -111,7 +110,7 @@ CString CSupportRearmDlg::format_weapon_pool_entry(int weapon_class) const
|
||||
{
|
||||
CString text;
|
||||
const auto& wi = Weapon_info[weapon_class];
|
||||
int amount = m_rearm_weapon_pool[m_rearm_pool_team][weapon_class];
|
||||
int amount = m_rearm_weapon_pool[m_rearm_pool_team].value_or(weapon_class, rearm_pool_default());
|
||||
if (wi.disallow_rearm) {
|
||||
text.Format("%s - 0 (disabled by weapon settings)", wi.name);
|
||||
return text;
|
||||
@@ -163,7 +162,7 @@ void CSupportRearmDlg::update_weapon_amount_display()
|
||||
if (weapon_class < 0 || weapon_class >= weapon_info_size()) {
|
||||
m_weapon_pool_amount = 0;
|
||||
} else {
|
||||
m_weapon_pool_amount = m_rearm_weapon_pool[m_rearm_pool_team][weapon_class];
|
||||
m_weapon_pool_amount = m_rearm_weapon_pool[m_rearm_pool_team].value_or(weapon_class, rearm_pool_default());
|
||||
}
|
||||
|
||||
UpdateData(FALSE);
|
||||
@@ -188,7 +187,7 @@ void CSupportRearmDlg::set_selected_weapon_amount(int amount)
|
||||
amount = -1;
|
||||
}
|
||||
|
||||
m_rearm_weapon_pool[m_rearm_pool_team][weapon_class] = amount;
|
||||
set_weapon_pool_entry(weapon_class, amount);
|
||||
weapon_list->DeleteString(sel);
|
||||
weapon_list->InsertString(sel, format_weapon_pool_entry(weapon_class));
|
||||
weapon_list->SetItemData(sel, weapon_class);
|
||||
@@ -196,6 +195,17 @@ void CSupportRearmDlg::set_selected_weapon_amount(int amount)
|
||||
update_weapon_amount_display();
|
||||
}
|
||||
|
||||
void CSupportRearmDlg::set_weapon_pool_entry(int weapon_class, int amount)
|
||||
{
|
||||
// don't store the default value; absence means the default
|
||||
auto &team_pool = m_rearm_weapon_pool[m_rearm_pool_team];
|
||||
if (amount == rearm_pool_default()) {
|
||||
team_pool.erase(weapon_class);
|
||||
} else {
|
||||
team_pool[weapon_class] = amount;
|
||||
}
|
||||
}
|
||||
|
||||
void CSupportRearmDlg::set_all_weapon_amount(int amount)
|
||||
{
|
||||
const int normalized_amount = (amount < 0) ? -1 : amount;
|
||||
@@ -208,9 +218,9 @@ void CSupportRearmDlg::set_all_weapon_amount(int amount)
|
||||
}
|
||||
|
||||
if (Weapon_info[weapon_class].disallow_rearm) {
|
||||
m_rearm_weapon_pool[m_rearm_pool_team][weapon_class] = 0;
|
||||
set_weapon_pool_entry(weapon_class, 0);
|
||||
} else {
|
||||
m_rearm_weapon_pool[m_rearm_pool_team][weapon_class] = normalized_amount;
|
||||
set_weapon_pool_entry(weapon_class, normalized_amount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,6 +331,28 @@ void CSupportRearmDlg::OnOptionChanged()
|
||||
update_control_states();
|
||||
}
|
||||
|
||||
void CSupportRearmDlg::OnRearmPoolFromLoadoutChanged()
|
||||
{
|
||||
if (!UpdateData(TRUE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// this flag changes the pool's default amount, so the displayed entries must be redrawn
|
||||
auto* weapon_list = (CListBox*)GetDlgItem(IDC_SUPPORT_REARM_WEAPON_LIST);
|
||||
if (weapon_list != nullptr) {
|
||||
const int previous_sel = weapon_list->GetCurSel();
|
||||
populate_weapon_list();
|
||||
if (previous_sel != LB_ERR && previous_sel < weapon_list->GetCount()) {
|
||||
weapon_list->SetCurSel(previous_sel);
|
||||
} else if (weapon_list->GetCount() > 0) {
|
||||
weapon_list->SetCurSel(0);
|
||||
}
|
||||
update_weapon_amount_display();
|
||||
}
|
||||
|
||||
update_control_states();
|
||||
}
|
||||
|
||||
void CSupportRearmDlg::OnSelchangeWeaponList()
|
||||
{
|
||||
update_weapon_amount_display();
|
||||
@@ -394,7 +426,7 @@ void CSupportRearmDlg::OnOK()
|
||||
The_mission.support_ships.rearm_pool_from_loadout = (m_rearm_pool_from_loadout != FALSE);
|
||||
The_mission.support_ships.max_hull_repair_val = m_max_hull_repair_val;
|
||||
The_mission.support_ships.max_subsys_repair_val = m_max_subsys_repair_val;
|
||||
memcpy(The_mission.support_ships.rearm_weapon_pool, m_rearm_weapon_pool, sizeof(m_rearm_weapon_pool));
|
||||
The_mission.support_ships.rearm_weapon_pool = m_rearm_weapon_pool;
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
@@ -21,6 +21,7 @@ class CSupportRearmDlg : public CDialog {
|
||||
afx_msg void OnSetAllPoolZero();
|
||||
afx_msg void OnSelchangePoolTeam();
|
||||
afx_msg void OnOptionChanged();
|
||||
afx_msg void OnRearmPoolFromLoadoutChanged();
|
||||
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
@@ -32,7 +33,9 @@ class CSupportRearmDlg : public CDialog {
|
||||
int get_selected_weapon_class() const;
|
||||
void set_selected_weapon_amount(int amount);
|
||||
void set_all_weapon_amount(int amount);
|
||||
void set_weapon_pool_entry(int weapon_class, int amount);
|
||||
CString format_weapon_pool_entry(int weapon_class) const;
|
||||
int rearm_pool_default() const { return m_rearm_pool_from_loadout ? 0 : -1; }
|
||||
|
||||
BOOL m_disallow_support_ships;
|
||||
BOOL m_limit_rearm_to_pool;
|
||||
@@ -44,5 +47,7 @@ class CSupportRearmDlg : public CDialog {
|
||||
float m_max_subsys_repair_val;
|
||||
int m_weapon_pool_amount;
|
||||
int m_rearm_pool_team;
|
||||
int m_rearm_weapon_pool[MAX_TVT_TEAMS][MAX_WEAPON_TYPES];
|
||||
|
||||
// weapon class -> amount; absent = rearm_pool_default(), mirroring the mission struct
|
||||
std::array<SCP_map<int, int>, MAX_TVT_TEAMS> m_rearm_weapon_pool;
|
||||
};
|
||||
@@ -77,11 +77,7 @@ void MissionSpecDialogModel::initializeData() {
|
||||
_m_support_rearm_settings.limitRearmToPool = The_mission.flags[Mission::Mission_Flags::Limited_support_rearm_pool];
|
||||
_m_support_rearm_settings.rearmPoolFromLoadout = The_mission.support_ships.rearm_pool_from_loadout;
|
||||
_m_support_rearm_settings.allowWeaponPrecedence = The_mission.support_ships.allow_rearm_weapon_precedence;
|
||||
for (int team = 0; team < MAX_TVT_TEAMS; ++team) {
|
||||
for (int i = 0; i < MAX_WEAPON_TYPES; ++i) {
|
||||
_m_support_rearm_settings.rearmWeaponPool[team][i] = The_mission.support_ships.rearm_weapon_pool[team][i];
|
||||
}
|
||||
}
|
||||
_m_support_rearm_settings.rearmWeaponPool = The_mission.support_ships.rearm_weapon_pool;
|
||||
|
||||
_m_contrail_threshold = The_mission.contrail_threshold;
|
||||
_m_contrail_threshold_flag = (_m_contrail_threshold != CONTRAIL_THRESHOLD_DEFAULT);
|
||||
@@ -146,11 +142,7 @@ bool MissionSpecDialogModel::apply() {
|
||||
The_mission.support_ships.disallow_rearm = _m_support_rearm_settings.disallowSupportRearm;
|
||||
The_mission.support_ships.allow_rearm_weapon_precedence = _m_support_rearm_settings.allowWeaponPrecedence;
|
||||
The_mission.support_ships.rearm_pool_from_loadout = _m_support_rearm_settings.rearmPoolFromLoadout;
|
||||
for (int team = 0; team < MAX_TVT_TEAMS; ++team) {
|
||||
for (int i = 0; i < weapon_info_size(); ++i) {
|
||||
The_mission.support_ships.rearm_weapon_pool[team][i] = _m_support_rearm_settings.rearmWeaponPool[team][i];
|
||||
}
|
||||
}
|
||||
The_mission.support_ships.rearm_weapon_pool = _m_support_rearm_settings.rearmWeaponPool;
|
||||
|
||||
// Copy mission flags
|
||||
The_mission.flags = _m_flags;
|
||||
|
||||
@@ -20,7 +20,12 @@ struct SupportRearmSettings {
|
||||
bool limitRearmToPool = false;
|
||||
bool rearmPoolFromLoadout = false;
|
||||
bool allowWeaponPrecedence = false;
|
||||
std::array<std::array<int, MAX_WEAPON_TYPES>, MAX_TVT_TEAMS> rearmWeaponPool{};
|
||||
|
||||
// weapon class -> amount; absent = rearmPoolDefault(), mirroring the mission struct
|
||||
std::array<SCP_map<int, int>, MAX_TVT_TEAMS> rearmWeaponPool;
|
||||
|
||||
// the default for weapon classes without a pool entry (see support_ship_info::rearm_pool_default)
|
||||
int rearmPoolDefault() const { return rearmPoolFromLoadout ? 0 : -1; }
|
||||
|
||||
bool operator==(const SupportRearmSettings& rhs) const
|
||||
{
|
||||
|
||||
@@ -80,6 +80,24 @@ void SupportRearmDialogModel::setAllowWeaponPrecedence(bool value)
|
||||
modify(_working.allowWeaponPrecedence, value);
|
||||
}
|
||||
|
||||
void SupportRearmDialogModel::storeWeaponPoolEntry(int team, int weaponClass, int amount)
|
||||
{
|
||||
auto &teamPool = _working.rearmWeaponPool[team];
|
||||
const int normalized = Weapon_info[weaponClass].disallow_rearm ? 0 : ((amount < 0) ? -1 : amount);
|
||||
|
||||
if (normalized == teamPool.value_or(weaponClass, _working.rearmPoolDefault())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// don't store the default value; absence means the default
|
||||
if (normalized == _working.rearmPoolDefault()) {
|
||||
teamPool.erase(weaponClass);
|
||||
} else {
|
||||
teamPool[weaponClass] = normalized;
|
||||
}
|
||||
set_modified();
|
||||
}
|
||||
|
||||
void SupportRearmDialogModel::setWeaponPoolEntry(int team, int weaponClass, int amount)
|
||||
{
|
||||
if (team < 0 || team >= MAX_TVT_TEAMS) {
|
||||
@@ -89,8 +107,7 @@ void SupportRearmDialogModel::setWeaponPoolEntry(int team, int weaponClass, int
|
||||
return;
|
||||
}
|
||||
|
||||
const int normalized = Weapon_info[weaponClass].disallow_rearm ? 0 : ((amount < 0) ? -1 : amount);
|
||||
modify(_working.rearmWeaponPool[team][weaponClass], normalized);
|
||||
storeWeaponPoolEntry(team, weaponClass, amount);
|
||||
}
|
||||
|
||||
void SupportRearmDialogModel::setAllVisibleWeaponPoolEntries(int team, int amount)
|
||||
@@ -100,8 +117,7 @@ void SupportRearmDialogModel::setAllVisibleWeaponPoolEntries(int team, int amoun
|
||||
}
|
||||
|
||||
for (auto cls : _visibleWeaponClasses) {
|
||||
const int normalized = Weapon_info[cls].disallow_rearm ? 0 : ((amount < 0) ? -1 : amount);
|
||||
modify(_working.rearmWeaponPool[team][cls], normalized);
|
||||
storeWeaponPoolEntry(team, cls, amount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ class SupportRearmDialogModel final : public AbstractDialogModel {
|
||||
const SCP_vector<int>& visibleWeaponClasses() const;
|
||||
|
||||
private:
|
||||
void storeWeaponPoolEntry(int team, int weaponClass, int amount);
|
||||
|
||||
SupportRearmSettings _working;
|
||||
SCP_vector<int> _visibleWeaponClasses;
|
||||
};
|
||||
|
||||
@@ -50,7 +50,8 @@ QString SupportRearmDialog::weaponEntryText(int weaponClass) const
|
||||
if (wi.disallow_rearm) {
|
||||
return QString::fromStdString(SCP_string(wi.name) + " - 0 (disabled by weapon settings)");
|
||||
}
|
||||
const int amount = _model->settings().rearmWeaponPool[_activePoolTeam][weaponClass];
|
||||
const auto& settings = _model->settings();
|
||||
const int amount = settings.rearmWeaponPool[_activePoolTeam].value_or(weaponClass, settings.rearmPoolDefault());
|
||||
if (amount < 0) {
|
||||
return QString::fromStdString(SCP_string(wi.name) + " - Unlimited");
|
||||
}
|
||||
@@ -130,7 +131,8 @@ void SupportRearmDialog::updateFromSelection()
|
||||
} else if (Weapon_info[cls].disallow_rearm) {
|
||||
ui->poolAmountSpin->setValue(0);
|
||||
} else {
|
||||
ui->poolAmountSpin->setValue(_model->settings().rearmWeaponPool[_activePoolTeam][cls]);
|
||||
const auto& settings = _model->settings();
|
||||
ui->poolAmountSpin->setValue(settings.rearmWeaponPool[_activePoolTeam].value_or(cls, settings.rearmPoolDefault()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,6 +245,9 @@ void SupportRearmDialog::on_limitPoolCheck_toggled(bool checked)
|
||||
void SupportRearmDialog::on_fromLoadoutCheck_toggled(bool checked)
|
||||
{
|
||||
_model->setRearmPoolFromLoadout(checked);
|
||||
// this flag changes the pool's default amount, so the displayed entries must be redrawn
|
||||
populateWeaponList();
|
||||
updateFromSelection();
|
||||
updateControlStates();
|
||||
}
|
||||
void SupportRearmDialog::on_precedenceCheck_toggled(bool checked)
|
||||
|
||||
Reference in new issue
Block a user