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]>
Neither editor had a teardown to match FSO's game_shutdown(), so the engine
data they set up was never freed. Add editor_free_engine_data() to free it,
and call it from a new fred_shutdown() in FRED and from qtFRED's shutdown(),
before the graphics system closes.
Also:
- Delete FRED's modeless editors if they are still open at exit.
- Make FRED's dialog tooltips and sexp tree image lists members, since
they were leaked or depended on OnDestroy() being called.
- Parent qtFRED's item models so they are deleted with their widgets.
- Enable the CRT leak report in qtFRED, which previously had none.
- In qtFRED, call shutdown() last in closeEvent(), since it destroys the
window.
- Make the preferences path and user SID strings function-level statics,
so MFC's leak dump no longer reports them as leaks.
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]>
The sexp tree refactor (#7301) moved the OPF listing logic into a shared
model that asks the editor for campaign-aware lists via virtual methods
on SexpTreeEditorInterface. QtFRED's campaign editor got the necessary
overrides, but FRED2's never did, so its OPF_MISSION_NAME /
OPF_GOAL_NAME / OPF_EVENT_NAME dropdowns fell back to the currently
loaded mission's data instead of the campaign's.
Backport the overrides to FRED2, restoring its pre-refactor behavior
(including listing only missions at earlier campaign levels), and hoist
QtFRED's loadAndFindCampaignMission helper into missioneditor/common so
both editors share one copy.
Co-Authored-By: Claude Fable 5 <[email protected]>
The ship editor, wing editor, waypoint path dialog, and jump node
dialog all had near-identical code to check whether a new name
conflicts with an existing ship, wing, waypoint path, jump node, or
target priority group (or is empty, or begins with '<'). Both FRED2
and qtFRED carried their own copies of this logic.
Extract it into a single check_name_conflict() function in
code/missioneditor/common.cpp, shared by both editors, and replace the
duplicated validation at each call site with a one-line call:
- FRED2: shipeditordlg, wing_editor, waypointpathdlg, jumpnodedlg
- qtFRED: ShipEditorDialogModel, WaypointEditorDialogModel,
JumpNodeEditorDialogModel, and Editor::validate_wing_name
This also aligns a few small behavioral differences that had crept in
between the two editors: the waypoint and jump node dialogs now skip
empty wing slots (wave_count == 0) when checking for wing-name
collisions, and the qtFRED wing editor now rejects names beginning
with '<'.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
reassign_wing_slot moves a wing between Wings[] slots, fixing up every
back-reference: Ships[i].wingnum, the Starting/Squadron/TVT_wings caches
(via update_custom_wing_indexes), the FRED-side parallel array
wing_objects, and cur_wing (passed via FredWingSlotConfig so non-FRED
callers can opt out). swap_wing_slots wraps it as a three-leg swap
through a temporary empty slot.
Also consolidates update_custom_wing_indexes (previously duplicated
verbatim in fred2/management.cpp and qtfred Editor) into common.cpp so
the new utility — and any future caller — has one shared implementation.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
reassign_ship_slot moves a ship between Ships[] slots, fixing up every
back-reference: Objects[].instance, Ai_info[].shipnum, Wings[].ship_index[],
Player_start_shipnum, Ship_registry's cached shipnum, and the FRED-side
parallel arrays Fred_alt_names/Fred_callsigns plus cur_ship (passed via
FredShipSlotConfig so non-FRED callers can opt out). swap_ship_slots
wraps it as a three-leg swap through a temporary empty slot.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
In single-player missions, the "Set as Player Ship" button is supposed to make
the selected ship the one and only player start. FRED did this correctly, but
qtFRED routed the button through the same setPlayer() toggle used by the
multiplayer "Player Ship" checkbox, which only promoted the selected ship and
never demoted the previous player start. Since the checkbox is disabled in
single player, there was no way to demote the old start, so single-player
missions could accumulate multiple player starts.
Consolidate the exclusive logic into a shared helper,
set_single_player_start() in missioneditor/common.cpp, and call it from both
FRED's OnSetAsPlayerShip() and a new qtFRED model method,
makeSolePlayerStart(), which the button now uses. This also avoids
setPlayer()'s early return on stale dialog state, which could cause the button
to silently do nothing.
Follow-up to #7600.
Co-authored-by: Claude Fable 5 <[email protected]>
If a player ship is changed to a regular ship, be sure that
Player_start_shipnum does not still point to the old ship.
Consolidate the several near-duplicate copies of the "repoint
Player_start_shipnum to a valid player start" logic, in both FRED and
qtFRED, into a single shared helper, ensure_valid_player_start_shipnum()
in missioneditor/common.cpp.
Also add some guards in situations where Player_start_shipnum might
be -1.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
* set line edit fields to max length in code
* fix some dialog window titles
* remove unused context help button on Windows
* address some easy todo items
* static access
Testing in FotG exposed a bug that dates back to retail. During mission parsing, arrival and departure anchors were represented by indexes into `Parse_names`. After parsing, they were converted to ship indexes -- but only in FRED. Since some functions are shared between FRED and FS2, this can produce inconsistent results, which can be hard to detect since parse indexes and ship indexes are usually the same.
This refactors arrival and departure anchors to be represented by ship registry indexes in all cases. It also adds conversion functions for the benefit of FRED and QtFRED since those dialogs were designed with ship indexes in mind.
* Generalize mission save from original FRED
* make qtfred use the new generalized missionsave
* split campaign save into a sister class
* allow unlimited campaign description length to be saved
* have the campaign editor pass the links to save properly
* cleanup
* future todo
* fixes
* more fixes
* cleanup vars
* clang
* add missing guardian threshold and fix var name
* more clang
* conflict resolution error
* update qtfred to use the new campaign save