184 Commits
Author SHA1 Message Date
LuytenKy bb69b1b9db Refactor: CC_preset (#7809)
* CC_preset: Prevent post-construction type modification and handle pst duplication

* remove redundant function

* CC_preset: remove default constructor, require explicit type

* remove duplicate
2026-11-02 22:40:54 -05:00
Goober5000andClaude Opus 4.7 190472f77e Remove the weapon class limit
With every fixed-size weapon-class-indexed structure now converted to dynamic containers, we can finally remove the `MAX_WEAPON_TYPES` limit!

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-09-08 13:20:36 -04:00
Goober5000andClaude Opus 4.7 f353ca7d18 Remove the ship class limit
With every fixed-size ship-class-indexed structure now converted to dynamic containers, we can finally remove the `MAX_SHIP_CLASSES` limit!

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-08-30 23:00:29 -04:00
Goober5000 745398e6b9 Merge pull request #7679 from Goober5000/refactor/loadout_pools
refactor loadout pools for vectorized ship and weapon classes
2026-08-07 22:09:26 -04:00
Goober5000andClaude Opus 4.7 30d81a83fb store campaign allowed-class lists in sets
Convert the allowed-ships and allowed-weapons lists to sets, rather than naive vectors that stored a true/false for every class.  Since these are ordered sets, iteration occurs in the same sequence as iteration of `Ship_info` or `Weapon_info`.  Associated data structures such as `Granted_ships` and `Granted_weapons` are converted as well.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-08-04 22:14:58 -04:00
Goober5000andClaude Opus 4.7 77186c72fc refactor loadout pools for vectorized ship and weapon classes
Convert ship/weapon loadout pools from naive per-class arrays to ordered maps that list loadout entries.  Each entry represents a ship/weapon class and its count.  An absent entry means the class is not in this mission's loadout.  Since these are ordered maps, iteration of the map keys occurs in the same sequence as iteration of `Ship_info` or `Weapon_info`.

Includes several bugfixes:
- `csg_read_loadout` now clears both pools before reading.  Previously the pools were only zeroed in `mission_campaign_init`
- `restore_wss_data`: non-transmitted classes are now absent rather than memset to 0
- a copy-paste bug where the weapon pool entries were bounds-checked against MAX_SHIP_CLASSES
- `wss_maybe_restore_loadout`: the pool write-back now preserves loadout membership instead of writing a count for every class
- `ss_dump_to_list`/`ss_swap_list_slot`: returning a slot ship whose class is not in the pool now makes it available instead of silently losing it.  Unreachable in retail but reachable via script
- off-by-one errors in the Lua `Ship_Pool`/`Weapon_Pool` indexers

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-08-03 01:28:28 -04:00
Goober5000 6180173fe8 Merge pull request #7487 from Goober5000/feature/format_classes
Convert CSG/PLR fixed ship/weapon arrays to SCP_vector
2026-07-30 03:23:56 -04:00
Goober5000andClaude Opus 4.8 bed228d264 avoid undefined behavior from UNREACHABLE on reachable code paths (#7555)
* avoid undefined behavior from UNREACHABLE on reachable code paths

UNREACHABLE expands to __assume(false) / __builtin_unreachable() in
release builds, which is undefined behavior if the code is ever actually
reached. Many UNREACHABLE sites only guard against unexpected-but-
possible runtime states (values from tables, mission/save files, network
packets, scripting, or user input), so reaching them should degrade
gracefully rather than invoke UB.

Replace UNREACHABLE with Assertion(false, ...) at all such sites. It
still pops an error in debug builds, but in release it is a harmless
no-op that simply falls through to the following code. Sites that are
genuinely unreachable by local invariants (e.g. a switch over a bounded
random number) are left as UNREACHABLE.

A few converted sites had no safe fall-through -- an uninitialized read,
null dereference, or null call would have followed -- so they also get a
minimal recovery: initialize the value, guard the dereference, return
early, or skip the offending item.

Where the converted site was a simple guard of the form
    if (x) { Assertion(false, ...); return; }
hoist the check onto the invariant instead:
    Assertion(!x, ...);
    if (x) { return; }
This states the expectation directly and shows the offending value in
the debug popup, while keeping the same graceful runtime degradation.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

* addendum

After consultation with Lafiel, use UNREACHABLE in situations that are effectively impossible even if not provably impossible.  UNREACHABLE = "this shouldn't ever happen"; Assertion = "if this ever happens, it's a coding error".  Also fix a few other sites and change a couple to Warnings.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-09 11:20:25 +09:00
Goober5000andClaude Opus 4.7 237516c08c Convert CSG/PLR fixed ship/weapon arrays to SCP_vector
Ship_info is already an SCP_vector but MAX_SHIP_CLASSES (500) is held in
place by fixed-size structures throughout the engine and editors. This
converts the seven file-format-adjacent arrays whose persistence touches
the .csg campaign save and .plr pilot file formats:

  campaign::ships_allowed         [MAX_SHIP_CLASSES] -> SCP_vector<ubyte>
  campaign::weapons_allowed       [MAX_WEAPON_TYPES] -> SCP_vector<ubyte>
  loadout_data::ship_pool         [MAX_SHIP_CLASSES] -> SCP_vector<int>
  loadout_data::weapon_pool       [MAX_WEAPON_TYPES] -> SCP_vector<int>
  scoring_struct::kills           [MAX_SHIP_CLASSES] -> SCP_vector<int>
  scoring_struct::m_kills         [MAX_SHIP_CLASSES] -> SCP_vector<int>
  scoring_struct::m_okKills       [MAX_SHIP_CLASSES] -> SCP_vector<int>

The CSG and PLR file formats already store explicit counts and key by
ship/weapon names, so no on-disk format change is needed. Existing
read/write loops already iterated by ship_info_size() / weapon_info_size()
and just compile through against the new vector types.

Vectors are sized to ship_info_size() / weapon_info_size() in
scoring_struct::init(), mission_campaign_clear(), player_loadout_init(),
and the campaign-pool reset paths in csg.cpp and multi_campaign.cpp.
All of these run after weapon_init() / ship_init(), so the sizing
invariant holds. scoring_struct globals constructed at static-init time
start with empty vectors; first index access is always post-table-parse.

Multiplayer stats sync (multimsgs.cpp) now derives offsets and counts
from the vector size; added USHRT_MAX assertions on the sender side
since the wire protocol packs offset/count as USHORT. The FSTracker
sync (multi_fstracker.cpp) clamps vmt->num_ships down to the local
mod's kills.size() before transmission and guards the receive-side
write so a tracker payload with more ship slots than this mod has won't
overrun the vector.

The MAX_SHIP_CLASSES cap itself stays in place at ship.cpp:2327; this
is one prerequisite toward lifting it. The other ~25 fixed-size
ship-class-indexed structures (team_data, Ss_pool_teams, Wl_ships,
FRED2 editor arrays, qtFRED Editor::_ship_usage, etc.) remain to be
addressed in follow-up PRs.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-30 02:21:22 -04:00
Goober5000andClaude Opus 4.6 3f85d6172a use std::move() for local variables that are copied but not reused (#7308)
* use std::move() for local variables that are copied but not reused

Addresses ~140 Coverity "Variable copied when it could be moved"
defects across 74 files.  Every std::move() targets a local variable
whose value is consumed by push_back, emplace, assignment, lambda
capture, or a function call and is never read again afterward.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* clang: use std::make_shared

* clang: use std::make_unique

* address feedback

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-05-07 14:40:38 +09:00
Goober5000 ce31a33029 fix persistent variables and containers (#7192) 2026-03-13 08:16:28 -04:00
Mike Nelson 021eb8e49a Fix two HUD Config preset issues (#6830)
* always use exact match

* custom gauges should use the type for colors with old preset files
2025-07-24 16:51:45 -04:00
wookieejedi dbe0af1a24 Allow Custom Gauges to fully use parent type colors (#6799)
* Allow Custom Gauges to fully use parent type colors

#6670 allowed for custom coloring of HUD gauges, so this PR follows that up with fixing a few edge cases where mods with custom gauges that are linked to parent gauge types accurately reflect the color of their parent gauge type in both the new saved HUD file and the in-mission HUD.

This ability to link color to parent gauges for custom gauges the player cannot edit is what the behavior has always been, so this PR does not change any expected behavior it simply ensures that the new HUD updates and various combinations of table entries for `Config` are all robustly accounted for. For example, in FotG we have multiple non-configurable custom gauges all tied to the center reticle, so if the player changes the color of the center reticle all the custom gauges set to that type also automatically change color.

Tested and works as expected.

* appease clang

* one more clang

* clang needs to calm down

* instruct clang to be calm

* fix comment typo
2025-06-30 12:53:13 -04:00
Taylor Richards 552f9990d9 remove support for memory mapped files (#6748)
FSO doesn't appear to use this any longer. And even when it was enabled the
requirements made it largely useless anyway. Removing to clean up cfile a
bit and so we don't have to keep maintaining it.
2025-06-05 17:53:13 -04:00
wookieejedi 66a85113a7 Very small debug log cleanup (#6747) 2025-06-03 21:07:05 -04:00
Goober5000 298869e517 properly convert main hall 2025-05-17 00:27:00 -04:00
Mike Nelson f1f95717d1 Support Custom Gauges in HUD Config UI (#6670)
* Support coloring custom gauges

* remove NULL
2025-05-14 13:18:03 -04:00
Goober5000 ceee045b35 coverity: move instead of copy 2025-05-10 01:15:46 -04:00
Goober5000 d7796b3767 coverity: use references to avoid unnecessary copies 2025-05-10 01:15:46 -04:00
Mike Nelson 1a503faa6b Better color preset handling (#6655) 2025-04-06 11:09:43 -04:00
Mike Nelson 60777154be Hud config upgrades (#6581)
* base working version

* localization and minor tweaks

* add retail UI controls

* Add way to hide gauges from Config view

* convert hud config from index matching to id matching

* clang
2025-03-22 22:47:38 -04:00
wookieejedi 0cb01f50ca Fix changes to Options not properly discarding when escape key pressed (#6597) 2025-02-22 20:55:01 -05:00
Mike Nelson 922ff160e2 Check for invalid player progress (#6554)
* check for invalid player progress

* clarity

* requested change
2025-01-29 13:37:01 -05:00
Mike Nelson 4dfaa85b6f Default settings tbl (#6491)
* initial version of default_settings.tbl

* Add a way to change player detail level defaults and implement a couple more options to detail_settings.tbl

* support the rest of 2d.cpp options

* Allow enforcing options to a specific value

* modernize detail defaults, levels, and values

* Fix parsing issue and remove lambda capture by reference

* fix print

* clang

* More efficient +Enforce parsing

* cleanup

* typo

* don't negate this

* error_display

* clarify language between presets, levels, and values

* add default case

* small fix

* use a map to minimize string lookups
2025-01-12 11:29:11 -05:00
Goober5000 5c737a5bf9 improve campaign file extension handling (#6443)
As discovered by WouterSmits, campaigns with periods in their filenames caused issues with FSO's campaign handling.  Specifically, in The Babylon Project, the EA-Minbari war v1.0.fc2 campaign would not save progress because FSO expected EA-Minbari war v1.fc2 in certain places.  This is because the `_splitpath()` function attempted to remove an extension from a filename that already had it removed.  For most campaigns this did not matter, but WouterSmits found a campaign where it did.

To solve this, there is now a new `util::get_file_part()` function to remove the path without removing the extension.  This replaces `_splitpath()` for campaign files, as well as the similar `clean_filename()` and `GetFilePart()` functions in other places.  All code paths were inspected for any chance of inadvertent extension adding, and Assertions were added to verify future code.  The only potential problem area was `player:loadCampaignSavefile()` which now pre-removes the campaign extension if needed.
2024-12-22 22:31:58 +01:00
Goober5000 86afcb3405 use proper stats in barracks (take two)
The barracks should use the actual all-time/multi stats from the pilot file instead of the active campaign stats.  Export the all-time stats from the pilot file in order to populate the barracks.

Follow-up to #6238.
2024-11-11 19:17:04 -05:00
Goober5000 3d556af391 Merge pull request #1451 from Goober5000/pilot_stats_fixes
better stats handling when switching or resetting campaigns
2024-07-14 20:06:51 -04:00
Goober5000 7557c54aa9 restore clearing of stats based on comments from #6238 2024-07-11 21:53:16 -04:00
wookieejedi f20c1bddfd Fix short read error with red alert csg file reading (#6229)
In current master, the debug log commonly shows `CSG => Warning: (0x0011) Short read, information may have been lost!`.

Thanks to Taylor for pointing the following issue out:
The function `pilotfile::csg_read_redalert()` returns if `ship_list_size` is zero, but it still needs to check the `wing_list_size` a bit below that. This has likely not caused data loss issues ATM, because it's reasonable to assume that if `ship_list_size` is zero then so is `wing_list_size`. But it's still a bug and should be fixed before it does cause some real data loss.

This PR moves the relevant read sections to within each respective if-block. That way the function is capable of checking both `ship_list_size` and `wing_list_size` on every load (even if `ship_list_size` is zero).
2024-07-05 12:50:56 -04:00
Goober5000 691fe96151 Merge branch 'master' into pilot_stats_fixes 2024-07-03 20:56:56 -04:00
Mike Nelson aee0123587 Allow player-specific options even when using In-Game Options (#6045)
* Move these functions into OptionsManager for more global use

* Make sure player options are preferred even when using OptionsManager

* persist the newly loaded options to disk

* Actually let's persist these only if the load is successful and also handle the multi option

* Comment this out for now I guess
2024-06-09 12:29:15 +02:00
Goober5000 ec241fcab3 standardize on isValid() and make validity member functions const 2024-02-26 15:56:41 -05:00
mjn-mixael dcce4a6538 Set the globals at player select rather than player load 2023-12-06 15:08:23 -06:00
mjn-mixael 33a1b1f8ca clean up and fix 2023-12-06 09:59:36 -06:00
Goober5000 b5fdf52e8c Merge pull request #5428 from Goober5000/remove_key_save
remove hud_squadmsg_save_keys()
2023-10-18 03:25:09 -04:00
Goober5000 c2d0eafc36 add wing status to red-alert system
If consecutive red-alert missions have different numbers of ships in a wing, then calculating the number of waves will not be correct.  This necessitates the addition of wing status to the stored data for red-alert sequences.

Not only must wing data be stored in `Red_alert_wing_status`, but also in the CSG file.  This necessitates a version bump.  Fortunately, the current design of CSG files allows extra data to be added to a section without breaking old builds, since the CSG loader will just skip over the unrecognized data.

This also renames `red_alert_wingman_status` to `red_alert_ship_status` since it's not limited to wingmen, as well as fixing the omission of exited ships if they are in the player's wing but don't have the red-alert-carry flag.

Fixes #5637.  Follow-up to #4457 and #5609.
2023-09-28 21:14:11 -04:00
Joshua Glatt 4fa5c0d3e7 Fix save on mission close' container (#5463) 2023-06-20 21:12:37 -07:00
Goober5000 99450fa643 remove hud_squadmsg_save_keys()
Remove this function and associated items, since they are commented out and unused.
2023-05-27 13:39:47 -04:00
MjnMixael fbb209ef6b Modular rank table (#4854)
* vectorize ranks

* Add modular table parsing

* int

* comments

* prevent field overwriting if tbm is used

* address feedback

* off by one
2023-02-14 17:25:52 +09:00
BMagnu af1f0eaeca Rework Script Conditions (#4960)
* add skeleton for hook condition API

* Begin Scripting Hook refactor

* Program Hook Conditions for current new-style hooks

* Replace more hooks

* Fully transition global hooks

* Convert legacy hooks pt. 1

* Convert legacy hooks pt. 2

* Convert legacy hooks pt. 3

* Post-conversion cleanup

* restore parsing

* Add Documentation and fix parsing

* Fixup engine ingame hook adding

* Fixup engine ingame hook adding again

* Fix warnings

* Fix GCC unqualified template base lookup

* unqualified lookup v2

* Virtual Destrcutors

* Fix Clang

* Fix ship objp hook condition shadow

* Remove global hook include in ship.h

* Incorporate Feedback

* Incorporate Feedback 2

* Add revision to inline version specififer
2022-12-14 03:51:27 +09:00
Goober5000 226e956fcc dynamic events and goals
Make events and goals dynamic in missions and campaigns.  When parsing, initialize all fields to their defaults.
2022-12-09 13:10:39 -05:00
Goober5000 98a3c64cc8 fix campaign loading in FRED
Load campaigns using the full path provided by the user, not just from the configured mod paths.

Also tweaks initialization based on the campaign having already been cleared in `mission_campaign_clear()`.
2022-11-15 20:40:33 -05:00
Taylor Richards 3e57da1681 add support for subfolders to cfile (#4771)
* add subfolder support to cfile

* sort files in VP archives before indexing them

* fix indexing of sub-subfolders

* remove unused 8B22K & 16B11K sound path types

* add more items to skip subfolder scanning

* fix windows build issues

* fix unit tests by allowing 0-byte files to be indexed

* fix file indexing on windows

* add test for cfile subfolders

* remove specific 'markup' and 'css' interface subfolders

They aren't directly referenced anywhere by pathtype and the new
subfolder code will continue to index and load files from them

* add player binds to list of always-root locations

* remove file-based localization support

An alternative is left in place for old fonts, as that was the only place
it appeared to be used.

This method of file localization conflicts with subfolder support however
so if it's needed in the future then changes to the subfolder code will
be necessary.

* add subfolder support to cf_find_file_location_ext()

* add subfolder tests for cf_find_file_location*()

* add shlwapi to needed win32 libs

* small bit of cleanup

* add subfolder support to cf_get_file_list()

* add tests for cfile subfolder lists

* report files that might be shadowed

* fix issue with lists when a filter is used

Also fixes discrepancy in older cf_get_file_list() when a sub path
is specified (should be used in all cases, not just glob).

* address review suggestions
2022-11-15 08:00:13 -05:00
MjnMixael 1ba0b8dcbe Modular medals (#4851)
* Modular medals table

* Remove Num_medals completely

* Handle badges out of order and allow setting of masks to handle mask indecies out of order

* const const const

* qtFRED

* address feedback
2022-11-07 22:53:28 +09:00
Fabian Woltermann e21dfcb457 when resetting stats before replaying a mission, check the rank table to see which rank the player should be 2022-09-08 19:17:47 +02:00
kiloku 516548d6be No clamping bools 2022-07-03 07:49:35 -03:00
kiloku d1800d8622 Use the labels displayed in the menus 2022-07-03 07:48:03 -03:00
kiloku 319c8cc2a1 Clamp values before saving 2022-07-02 09:47:46 -03:00
kiloku 07b8e8d6cb Clamp settings values when loading 2022-07-01 22:56:19 -03:00
Goober5000 7013981de5 add isActive checks for new-style script hooks
What it says on the tin.  Follow-up to #3538.  Fixes #4398.
2022-06-13 02:13:14 -04:00