Set model instances to -1 when objects are deleted, and guard against null model instances in `modelinstance_replace_active_texture`. This may fix a crash in Event Horizon.
* framework for support ship rearm pool and flags
* scripting api
* FRED support
* QtFRED support
* do not save non-player-allowed weapons
* tvt and mission versioning
* fix variable name
* minor fixes and clarity
* oops
* add qtfred help docs
* fixes and cleanup
* clang and readability
* address feedback
* address feedback
* new mine weapon type
* some fixes and cleanup
* fix some parsing issues
* make sure mines get plotted
* make mine spawned objects can get a correct target
* some cleanup and additional features
* chasing mines
* some Lua tweaks
* generalize proximity detonations
* minor tweaks
* collapse namespace
* address feedback
* add wing display names
Adds display name capability for wings, matching the pattern and infrastructure of display names for ships. As in #7234, wing display names take precedence over ship display names, if both are provided; because if ship display names took precedence, a ship would have the same display name in every wave.
All the relevant display locations are handled, including the HUD, escort list, message box, and mission log. Lua API support is provided as well.
Adds full support for both FRED and QtFRED, including the always-save-display-names setting.
Addresses #7189 and the last request from #1730.
* add help text from #7234
* 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]>
Fixes the long-standing intermittent bug where the GTD Orion#Repulse in
Silent Threat: Reborn's "Forced Hand" mission spawns with all subsystems
unlinked, leaving the ship untargetable and undisableable. The same root
cause has been reported since at least 2015 (HLP topic 89403) and was
provisionally closed in #3147 as fixed by #3858, but #3858 was an unrelated
parse_ship_values memory leak fix and never actually addressed this
behavior. Recently the underlying check at ship.cpp ~8043 was promoted
from Warning to Error (#5591), which is why Release players are now
hitting a hard error dialog instead of just seeing missing subsystems.
Root cause
----------
model_unload() walks Ship_info and resets si.model_num = -1 on every
ship_info that referenced the model, but does not touch
si.subsystems[k].model_num. Subsystem entries are left pointing at the
freed model id. When a subsequent mission reloads the same pof under a
new id, ship variants that share the model rely on
ship_copy_subsystem_fixup() to re-link their subsystem arrays, but the
fixup matches by name via model_copy_subsystems() and any unmatched
destination subsystem stays at -1. The mismatch case in
model_copy_subsystems() was guarded only by Int3(), which is a no-op in
Release builds, so the failure was completely silent until subsys_set()
errored out much later with no useful context.
The bug is intermittent because it depends on three independent ordering
factors: which prior mission was last played, which Orion variant that
mission used, and the iteration order of Ship_info during the next
mission's ship_page_in().
Changes
-------
* model_unload(): when clearing si.model_num for an unloaded model, also
clear every si.subsystems[k].model_num that pointed at the same id.
This is the structural fix and eliminates the entire class of stale
subsystem pointers surviving across mission boundaries.
* model_copy_subsystems(): replace the silent Int3() in the name-mismatch
branch with Error(LOCATION, ...) naming the unmatched subsystem. This
surfaces a failure mode that has been invisible in Release builds for
over a decade and gives modders an actionable diagnostic when sibling
ship classes that share a model have inconsistent subsystem names.
* ship.cpp: introduce verify_ship_subsystems_linked() helper that checks
every model_subsystem on a ship_info is linked into the same model the
ship is using, and fails with Error(LOCATION, ...) naming both
polymodels if not. This is the canonical post-condition for both
ship_copy_subsystem_fixup() and model_load() (which is supposed to
link subsystems via do_new_subsystem()).
* ship_create(): call verify_ship_subsystems_linked() after
ship_copy_subsystem_fixup() so that any failure to link a subsystem
is surfaced with full context (ship name, subsystem name, both model
filenames) instead of propagating to a generic error in subsys_set()
much later. This closes a long-standing asymmetry where ship_page_in()
had a guard (added by zookeeper in 2015) but ship_create() did not.
* ship_page_in(): three post-fixup verifications were gated by
#ifndef NDEBUG with Warning() or Assertion() calls, both of which are
no-ops in Release builds. Replace each with a verify_ship_subsystems_linked()
call so they fire in Release as well.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Collection of fixes for multiple issues with the multi code found by Claude AI (by way of Goober5000), plus additional issues noted by myself while checking the code. These fixes are primarily focused on the interpolation code.
These changes should not be breaking and are largely exclusive to server-side handling, but still need to be tested thoroughly before being merged. Any tests must be done with at least the server (master) using the fixes.
* Tune ups for standalones
Fixes two warnings from building in standalone and also provide, also adds needed function to actually tell if game is in standalone mode.
* better fix for armor flags
1. Modify `ship_get_subsys_for_submodel` to use the subsystem indexer. This changes the operation from O(n) to O(1) and also allows the function to work with turret gun barrels.
2. Add an `isValid` check to `ParticleSource::finishCreation` to prevent unknown state from being accessed if the source is not valid.
3. Tweak `EffectHostTurret` and make sure it works for fighter beams.
4. Prevent `createOnTurret` from running on submodels that are not turrets.
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.
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.
Add a useful function for getting a ship_info pointer from a ship registry entry. Also rename `ship_has_dock_bay` to `ship_has_hangar_bay` for clarity, since docking bays and docking points are not the same thing. Finally, add a `model_has_hangar_bay` function.
All other display names are `SCP_string`, so make these `SCP_string` as well to be consistent and to allow arbitrary-length display names.
Also fix a few infelicities with German translation and the script API.
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.
The object and ship indexes held by the ship registry do not actually need to be cleared until `ship_cleanup` completes. This will allow the ship to be referenced in any functions (via script hooks or otherwise) that are called during cleanup.
Tweak related script documentation while we're at it.
Follow-up to #7120. Fixes#7122.
This dates back to commit `300d5fc2c1`. It probably did something at some point, but with various upgrades over the years, it no longer has any effect.
It looks like a lot of the model interp code (e.g. `model_interp_defpoints`, which isn't called anywhere) can be removed as well, but that's a bit more involved.
Addresses a behavior idiosyncrasy encountered by Solaris. If this flag is enabled, explosions with a visual radius of 0 do not have fireballs created, and do not have the fireball lifetime added to the explosion lifetime.
Infamously, in FSO, a wing whose mothership is destroyed will not, itself, be considered destroyed if it has more waves remaining, because wing cleanup and logging typically only happen when the last ship in the last wave exits the mission. Instead, with no mothership to arrive from, waves will simply no longer arrive. Events that check to see if the wing is destroyed or departed will never fire.
This PR fixes that behavior, ensuring that the wing is cleaned up and logged properly, by using the same logic as the enhanced `cancel-future-waves` SEXP operator. This is tied to a new `$cancel future waves of any wing launched from an exited ship:` AI profiles flag which is enabled by default on 25.0+.
If the `cancel-future-waves` sexp is called when a wave is not present, it would previously not handle wing cleanup, such as setting flags and updating the mission log.
* Allow 'No Impact Debris' to also apply to explosions
The ship/subsystem flag `no impact debris` prevents the default debris shards from spawning, which is very valuable especially now that impact effects can be completely customized via the -particles table. Now that particle effects are also an option for ship and subsystems explosions, it is also invaluable to have the ability to turn off the spawning of shards when either of those explosions happen.
This PR uses the same flag of `no impact debris` and simply does not spawn the default shards for ship explosions or subsystem explosions of that flag is enabled. I thought about adding two new flags, but that would add to the flag clutter, and most folks who use these flags to turn off impacts I would estimate also want them off for actual explosions. Also, a new flag called `no explosion debris` would likely be confusing, so if a new flag were to be added it should be called something like `no default explosion debris shards` or something. Overall I've opted with the simpler and cleaner solution to just have it all under the impact flags. If two new flags are desired though I can easily add them.
Tested and works as expected.
* throw clang a bone
* use two different flags
* update flag name
* typo and logic fix
* allow custom generic debris to always work
* update to better methods
* cleanup logic
* clang