Add generate_ship_usage_list_team alongside the weaponry twin that already existed in missioneditor/common, so both loadout editors can drop their TVT/non-TVT branches and simply iterate Num_teams.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
FRED2, qtFRED, and the shared mission save code each carried their own copy of the loadout usage builders. The weaponry pair already had shared versions in missioneditor/common; this converts those to the SCP_map<int,int> signature the editors now use, adds the missing ship builder alongside them, and deletes both editors' private copies.
FRED2's playerstarteditor/freddoc and qtFRED's Editor/ErrorChecker all call the shared functions now, following the update_custom_wing_indexes consolidation precedent. missionsave's used_pool becomes a map as well, which removes its MAX_WEAPON_TYPES stack array.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
team_data was the last persistence-adjacent structure sized by MAX_SHIP_CLASSES: four parallel ship arrays plus four parallel weapon arrays (one slot per mission-file loadout line, holding a class or a sexp variable name, and a count or a sexp variable name) with manual num_*_choices counters, plus a dense per-class weapon_required flag array. Convert all of it to the sparse-container family:
ship_list / ship_list_variables / ship_count / ship_count_variables
-> SCP_vector<loadout_entry> ship_choices
weaponry_pool / weaponry_count / weaponry_pool_variable /
weaponry_amount_variable
-> SCP_vector<loadout_entry> weapon_choices
bool weapon_required[MAX_WEAPON_TYPES]
-> SCP_set<int> required_weapons
where loadout_entry is {class_index, count, class_variable, count_variable}, with empty variable strings meaning the value was given literally. num_ship_choices / num_weapon_choices become .size().
Intentional behavior fixes, all previously latent memory errors or
data bugs:
* is_ship_assignable stored an alt ship CLASS in a variable used as a
loadout list INDEX when default_to_this_class was false, then
swapped to ship_list[class] - garbage for any mission where the two
domains diverge. It now swaps to the alt class itself, per the
evident intent.
* The default-ship fallback read ship_list[0] even when a team had
zero ship choices; it now leaves default_ship at -1, and
ss_fixup_team_data guards its append of the default ship accordingly.
* FRED2's dumpstats indexed Ships[] with a ship class when printing
loadout entries; it now prints the entry's class or variable name
directly.
* Team parse now clears the previous mission's entries explicitly
rather than relying on overwrite-in-place.
This clears the largest remaining cluster of MAX_SHIP_CLASSES references on the way to lifting the ship class limit.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
FRED has an autosave feature but it wasn't invoked in too many places. This adds autosaving whenever a major dialog is closed, unless it was closed by hitting Cancel. NB: Autosave is not yet implemented in qtFRED.
Also, `addvariabledlg` incorrectly referred to `OnOk` instead of `OnOK` and `CMessageEditorDlg` incorrectly referred to `OnOK` instead of `OnOk`, so this fixes those and distinguishes `OnOk` by renaming it `OnButtonOk` to be consistent with the event editor and other dialogs.
We need to call `UpdateData()` in the `OnOK()` function and in several other places so that the member variables are populated with the most recent input from the UI. This prevents certain input (such as Player Entry Delay changes) from being lost by being overwritten with stale stored values.
This fixes a bug reported by Kitsune where the Player Entry Delay box did not work properly. It also fixes the random checkbox issue from #5494.
This introduces a new mechanism for handling bit flags. Instead of using an int (or two, or three) to write bits into, this uses the std::bitset in a wrapper class that accepts an enum class as input. This means that certain classes of errors we've had a few of in the engine, where a coder used the wrong set of flags or checked them against the wrong variable (SF_STEALTH vs SIF_STEALTH, for example) can now be detected at a compiler level rather than not at all.