Chase view deltas are not reset on mission init, so ensure they are reset to prevent the viewing jumps that can be seen at the start of mission in chase view. Also ensure perspective and slew lock are properly resotred.
* Fix estimate_ship_speed_upper_limit to handle non-ship objects gracefully
* Add collision handling for OBJ_PROP objects
Implement OBJ_PROP-specific collision messaging and logic: update player death messages, fix incorrect argument usage in collision checks, and set killer attributes for PROP collisions.
Root cause
Commit 87ea04fa5 "change atan2_safe to atan2" (July 2024) replaced FSO's custom atan2_safe with the standard atan2. The old function returned a different range:
range returned
old atan2_safe (-PI/2, 3PI/2)
standard atan2 (-PI, PI]
do_view_track_target() in playercontrol.cpp:417 computes the padlock heading as a raw subtraction of two extracted headings:
chase_slew_angles.h = forward_angles.h - view_angles.h;
The forward vector rotated into the player's own frame is always (0,0,1), so forward_angles.h is always PI/2. With the old range that subtraction landed in (-PI, PI) — symmetric, and the ±120° neck clamp below applied evenly. With standard atan2 it lands in [-PI/2, 3PI/2) instead: -90° to the left, but +270° to the right.
Leftward travel dead-ends at 90° (straight abeam) instead of 120°, and the moment a target crosses just past the player's left shoulder the value wraps to a large positive number and gets clamped to +120° — the camera snaps hard right.
The fix
Rather than reverting atan2_safe (standard atan2 is correct, and other callers depend on the new range), this PR wraps the heading difference back into (-PI, PI] before the neck clamp, using the same "over-the-top correction" idiom already used by do_view_external() a few hundred lines down:
// Do over-the-top correction.
// Headings are extracted with atan2, so each one lies in (-PI, PI] and their difference can be
// nearly a full circle in either direction. Without wrapping it back into (-PI, PI], a target just
// past the left shoulder reads as being almost all the way around to the right instead.
if (chase_slew_angles.h > PI)
chase_slew_angles.h -= PI2;
else if (chase_slew_angles.h < -PI)
chase_slew_angles.h += PI2;
The Secondary_dual_fire flag is per-ship, but not every secondary bank
can dual fire. Previously the HUD drew the dual fire link icon even
when the armed bank had only one firepoint, and firing such a bank
cleared the flag entirely, silently discarding the player's dual fire
preference for the other banks.
Extend the ignored-rather-than-cleared approach already established
for no-doublefire weapons to the single-firepoint case:
- add ship_secondary_bank_can_dual_fire() as the single source of truth
for bank validity, No_doublefire, ai_profiles restrictions, and
firepoint count
- ship_fire_secondary() now fires single and leaves the flag alone when
the bank cannot dual fire, instead of removing the flag
- the weapons gauges and the hardpoints gauge consult the helper, so the
link icon and second-firepoint highlight are no longer drawn for
incapable banks
- the dual fire toggle on a single-firepoint bank now explains why it
cannot dual fire and leaves the preference untouched
- restoring the saved dual fire preference no longer depends on bank 0's
firepoint count, since incapable banks now simply ignore the flag
- key control and force feedback also consult the helper
Co-Authored-By: Claude Fable 5 <[email protected]>
Some code refactoring to allow mission titles to be strings of any length. Titles that are too long to actually display (based on string width) will be visibly truncated using `font::force_fit_string`, but the underlying title will not be affected. Multiplayer is still subject to the 31-character length limit, so titles sent over the network will still have characters truncated.
Also removes some redundant calls to `gr_get_string_size`, since `font::force_fit_string` returns the fitted string width.
* Implement Photo Mode
* fix gr string errors
* return raw char array
* control conflict groups and better photo param defines
* better param identification in real time
* make photo mode hude dynamically sized
* fix xstrs after all changes
* missed a few
* use modern loop
Add coverity[GLOBAL_INIT_ORDER] annotations to ~50 global variables
across 27 files. These were all analyzed and confirmed safe:
- ~48 OptionBuilder::finish() globals use a Meyers singleton
(OptionsManager::instance()), which guarantees safe init order.
Destruction is also safe due to shared_ptr ref-counting.
- 6 default-constructed container globals (vectors, maps) have no
cross-TU dependencies at construction or destruction time.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
The existing `cannot-perform-scan` flag prevents the cargo from being shown on the HUD, but some modders would like to see the cargo while still preventing a ship from being able to perform a scan. So, this renames the existing flag to `cannot-perform-scan-hide-cargo` and adds a new `cannot-perform-scan-show-cargo` flag. Compatibility code in both mission parsing and flag evaluation ensures that missions using the old flag will still work.
Note that if both `cannot-perform-scan-hide-cargo` and `cannot-perform-scan-show-cargo` are set, the former will take precedence.
The `$Scannable` field in objecttypes.tbl controls whether a ship can be targeted by the "target unscanned ship" key. This is independent of which ship types can actually be *scanned*, which is not connected to any field in objecttypes.tbl.
So, this PR renames the `$Scannable` field to `$Targetable as unscanned:` to be clearer about what it actually does, and it adds the missing counterpart `$Scannable by default:` flag to specify which ship types can actually be scanned.
Note that this is only relevant for legacy scanning behavior. Mods which use `$Unify scanning behavior:` do not need either of the ship type flags.
A minor bug in #6077 resulted in a crash loading campaigns on the multi ui.
The bug itself was not fatal, however it triggered a cascade of poor error
handling which led to a crash. A lot of these issues date back to retail.
This fixes the minor bug, and hopefully adds enough error handling to
preemptively squash a repeat of the crash problem.
Although normalized vectors in FSO are supposed to stay normalized, occasionally small floating point errors can pop up. In most cases these do not cause a problem, but in certain cases these errors can rapidly accumulate and corrupt an otherwise well-behaved matrix. This can most easily be seen with daisy-chained dock sequences or docked ships with angled dockpoints.
This PR audits the usage of `vm_vector_2_matrix_norm` to re-normalize vectors in cases where floating point errors could accumulate. There are also a few new Assertions for extra vigilance.
Follow-up to #6596. Fixes#6634.
1. Use `const char *flag_desc` because constructing a SCP_string for each flag description is not needed
2. Make `VALID_FNAME` check for nullptr
3. Modify the signature of `coalesce()` to allow capturing of mixed `const` and non-`const` arguments
4. Use `std::for_each` (via `SCP_tolower`) rather than `std::transform` to fix compilation warnings
Most places in the code that use `vm_vector_2_matrix` do so on already-normalized vectors. Changing these to `vm_vector_2_matrix_norm` avoids redundant normalization.
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.
* 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
Adds an optional argument to the `lock-perspective` sexp to allow locking of the 'free look' or 'padlock' view. This prevents the player from looking around which might not be desired in certain forced perspective situations.
Fixes a bug with new unified scanning PR (#6000) and adds a bit of cleanup, including consistent brackets, whitespace cleanup, and removing vestigial function from the original PR.
Tested and works as expected.
* Exposes the New Flight Cursor Mode to Scripting
Thanks to #6136, FSO supports switching between two methods of flying. This PR exposes those settings and values to scripters. Tested and works as expected.
* fix aiming setting
* add reset position function
* cleanup setting pitch and heading
* one more cleanup
* update to enum support
* remove older version
* one more fix for setting flight mode
* Clean unneeded properties
* properly queue-ify keys
* Refactor key checking to use functions instead of globals
* Update hooks and cache checked-against key
* Documentation and Naming
* match tilde
* only remove control not debug
This refactors the ship registry and the OSWPT struct to store data as indexes rather than pointers. This is a prerequisite for making these collections dynamic in the future. See also #5800.
Adds a `DEATH_ROLL` status to specifically cover the state after ships have been destroyed but before they exit. I've also audited all code that interacts with the ship registry to use the correct state with this new state taken into consideration.
This fixes access to exploding ships that was broken when the ship registry framework was introduced. In particular, the `when destroyed X beam-lock-all X` QoL feature now works again.
Several related fixes:
1. Copy the actual ship name, not the display name, to `killer_parent_name` for two reasons:
1a. Since `killer_parent_name` is used to look up the ship, it must be the actual ship name, not the display name.
1b. Copying the display name can cause a buffer overflow because display names can be longer than 31 characters.
2. The display name functionality is moved to the more appropriate location in `player_generate_death_message()`.
3. Remove `player_get_killer_weapon_name()` which only served as a proxy check for whether the weapon index was used or not.
4. Use `ship_registry_get()` rather than `ship_name_lookup()`.
5. Add comments to clarify the use of `killer_parent_name`.
The logic used to select builtin messages was complex and hard to follow. This commit replaces it with logic that, while not identical, is both similar and more flexible. Additionally, the old logic had a major limitation when it came to downgrading messages: If a message type was defined for *any* persona, then it couldn't be downgraded for *any* persona. The new logic removes this limitation, and makes downgrade paths easier to define as well.
Some message types had hard-coded occurrence chances. These have been removed, and the default occurrence chance for the corresponding type modified to compensate.
Add XSTR entries for "or", "None", and "Nothing".
Note that there is already an XSTR entry for "none", but it does not have the right capitalization.
Note that "None" is localized in `textify_scancode` but not `textify_scancode_universal`.
This makes "Nothing" cargo use appropriate localization.
Fixes#5227.