Improve skipmemymissionyo in several ways, based on RedMageJoe's recent experience:
1. Allow spaces to be accepted in the mission prompt
2. If the requested mission can't be found, just abort rather than restarting the entire campaign
3. Clarify that the prompt needs a filename and add a message if the mission can't be found
4. Improve handling of the .fs2 extension
5. Fix a bounds check in `popup_input`
Use `std::unique_ptr` rather than `vm_malloc` and `vm_free` to handle optional strings in ship classes. This makes the code more robust and increases memory safety. This also allows several string variables to be consolidated in the ship class and weapon class script APIs.
Also add new `stuff_string()` overloads and a new `F_TRIMMED` string parsing type to handle the new fields and the string trimming done inside `stuff_malloc_string()`.
* Create scripting hook: 'On Options Menu Closed'
Complements #6591. This PR creates a hook, 'On Options Menu Closed' that provides a hook variable of `hv.OptionsAccepted` which is true if the options are accepted/saved, false if the options are discarded and not accepted/saved.
* Option to unify setting options with easy flag
Most modern UIs, including KNet 1.3, have options that are always set and do not require the user to click save, or on the few cases where options will not be saved automatically, the program shows a popup telling the user the changes are not saved. In addition, the user experience of setting many options then forgetting to press save is far more common and annoying then the opposite. As a last example, even the F3 in-game options menu presents Escape as the leave and save button, not the leave and discard button.
Currently, there are two screens where FSO allows users to press escape after setting options and leave without warning. The main options screen and the HUD screen. As it turns out, half of the options in the main options screen get saved even if the player presses escape (all the detail slider options along with the joystick and mouse sensitivity and dead zone settings), so current behavior is inconsistent to users.
This PR, aimed to be strategic and efficient, creates a game settings table option that allows mods to set so that the escape key for the HUD and Options screen does the same thing as pressing Ctrl-Enter/Accept. This optional setting unifies behavior, so that setting an option sets it whenever the user leaves that screen (whether it is pressing Escape, Ctrl-Enter, or the Accept button). The other screen that involves options and an escape is the control config menu, but that already methods in place to deal with escape in a consistent way.
Tested and everything works as expected.
* fix oversight of saving when going to F3 menu
* update to enum for future additions
* cleanup with better naming
* update warning message
* one more warning cleanup
* Create scripting hook: 'On Options Menu Tab Changed'
It would be very useful to know which options tab is active (IE Options, Multi, Detail) but it's all under one single Game State `GS_STATE_OPTIONS_MENU`.
This PR creates a hook, 'On Options Menu Tab Changed' that returns the value of the newly switched to options tab. Lafiel and I both discussed making this an ENUM, but the ENUM list is already quite bloated and this integer value seems like the cleanest solution.
Tested and works as expected.
* fix description typo
* Allow modders to always show first game tip at start
This PR adds a simple boolean that allows mods the ability to always show the game tips in the same order, starting with the first entry. This is particularly useful if the mod is introducing something to new players.
The current behavior is to pick a random starting location, so this PR just always starts at tip index 0.
Tested and works as expected.
* add comment clarification
* make into integer instead of bool
* better tips index setting method
* spelling and static cast
* one more static cast
* make actual warning
* clang and consistent order
Several changes related to the volumetrics model fix:
1. Update the `model_load()` prototype with better parameter names, including a new `ErrorType` enum defined in pstypes.h
2. Update the `MIN`, `MAX`, and `CLAMP` macros, all of which were susceptible to performance issues because they duplicated their tokens. This could cause functions or calculations to be re-run unnecessarily. Since the codebase is now on C++17, `std::clamp()` can be used.
3. Update the rest of the codebase to fix any associated issues.
`On Dialog Start` (used in SCPUI and within `popup_init`) reads popup options by affirmative or negative flags, and the popup for exiting the Mainhall did not set these flags. Notably, most popups that use `POPUP_NO` or `POPUP_YES` already, so this PR sets those flags for this popup. Now `On Dialog Start` within `popup_init` has access to the correct flags.
PR tested and works as expected, both in retail UI and SCPUI
* 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
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.
There were several bugs and design issues in the Vasudan headz cheat, probably due to being coded in a hurry right before release:
1. Although the cheat activated on the main hall, it was not immediately apparent, requiring the player to switch screens and come back
2. The detection of whether the main hall is Vasudan did not work after the cheat was activated, due to the background filename changing (this one is actually not Volition's fault)
3. The implementation of the cheat was actually in the wrong section of code, resulting in some confusion
These are now fixed. The cheat can be enabled or disabled from one function, the graphics are reloaded properly, and the main hall detection includes the cheat-active version of the main hall. Also, the door sounds have been slightly refactored to use a `std::pair` rather than a vector, since there are exactly two sounds, an open and a close.
Adds a new `+Ambient Sound:` field to mainhall.tbl, allowing any interface sound (or even no interface sound) to be used for the main hall ambient sound. The default ambient sound, as well as the sound played on the pilot select screen, is interface sound 12.
Implements #6421.
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.
```
code/menuui/barracks.cpp:188:8: error: type ‘struct barracks_buttons’ violates the C++ One Definition Rule [-Werror=odr]
188 | struct barracks_buttons {
| ^
code/menuui/playermenu.cpp:82:8: note: a different type is defined in another translation unit
82 | struct barracks_buttons {
| ^
code/osapi/osregistry.cpp:478: error: type ‘struct Section’ violates the C++ One Definition Rule [-Werror=odr]
478 | typedef struct Section
code/pilotfile/FileHandler.h:18: note: a different type is defined in another translation unit
18 | enum class Section {
```
The BWO fix in PR #6317 was not quite the correct fix. The `sim_room_lines` array contains the maximum number of scrollable lines, not the maximum number of lines on the screen at one time. This partially reverts commit 20338ff28b and implements a new fix that allows the full `MAX_LINES` but also properly checks the list button limit. Additionally, this adds the list button limit check to other vulnerable code sections.
Fixes the tech room being limited to a single page of missions after #6317. Testing confirms that the BWO crash is still fixed with this update.
This is an error that existed all the way back in retail. Each line in the simulator room (i.e. each mission name in the list) is also a "button" in the sense that clicking on it will highlight the line and set some values. The maximum number of buttons is `LIST_BUTTONS_MAX`, but the maximum number of `sim_room_lines` was a different #define, `MAX_LINES`. This was set to 200, a far higher value than the `LIST_BUTTONS_MAX` value of 42. The code responsibly checked the limit, but the limit was incorrect.
(This had not been seen in previous mods because the number of lines was never high enough to reach 42. BWO happened to use a font that was small enough to fit that many lines in the mission simulator screen. This explains why removing fonts.tbl prevented the bug from occurring.)
Thus when the number of lines reached 42, the sim room started writing to out-of-bounds memory. This didn't cause a crash immediately, but did corrupt the `Static_lights` vector, which in turn caused a crash as soon as a model was lit in-mission or in the ship loadout screen. It's rather strange that this crash only occurred in optimized SSE2 builds though.
The fix is simply to use `LIST_BUTTONS_MAX` as the limit, rather than `MAX_LINES`. This also removes the unused `MAX_DESC_LINES` and `Num_desc_lines` at the same time.
Fixes#6313.