* take a model reference when a ship changes class
ship_model_change() only loaded the model when the class had none, so a ship
switched to a class whose model had been loaded only by a select-screen
preview adopted that preview's single reference. Closing the screen then
freed the model from under the ship, and the first simulation frame asserted
in model_get(). This is what happened on a replayed mission with a restored
loadout: ship select was skipped, the weapon-select overhead loaded the new
class once, the commit switched the player to it, and the screen close
released it.
Load unconditionally, as ship_create() already does, so the ship holds its own
reference.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
* reject stale model ids in model_unload and release select-screen handles at level close
model_unload only used the slot part of the id it was given, so a handle kept
across missions would free whatever model had since been loaded into that slot.
Validate the id against the slot's occupant and warn instead.
Two holders could present such handles: the weapon-select icon models under a
scripted UI that overrides the state hooks (the native close never runs), and
the ship-select 3D model global, which was never reset between missions.
Release the select-screen handles from game_level_close, and unload the
ship-select model on screen close and on every selection change.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
* consolidate the select-screen resource release
The weapon side released its icons, anims, and ship class data from two
functions keyed on whether the screen was open, and the level-close path added
a third copy. Give the weapon side the same shape as the ship side: one
unconditional weapon_select_common_close(), with weapon_select_close() left as
pure UI teardown. common_select_level_close() now just calls the two common
closes, and common_select_close() calls it in turn. The ship-select 3D model
is released from ship_select_common_close() so both paths cover it.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
---------
Co-authored-by: Claude Fable 5.1 <[email protected]>
When a destroyed subsystem was repaired, its submodels were only restored if the repair was done through a SEXP. A subsystem repaired by a support ship, by automatic repair, by a script, or through the debug console regained its hitpoints but not its submodels, so a ship could have a working turret with no model. Any -destroyed form also remained visible.
All of these now call restore_subsystem_submodels, which brings back the subsystem's submodels and hides the -destroyed submodel linked to a special-point subsystem. The -destroyed form of an ordinary submodel is hidden when the submodels are next replicated. The SEXP code uses the same function, with no change in its behavior.
Destruction outside do_subobj_destroyed_stuff now goes through a new blow_off_subsystem_submodels function, which do_subobj_destroyed_stuff also uses. It blows off both of the subsystem's submodels and shows any linked -destroyed submodel, unless the subsystem has "no disappear". This handles the cases where a subsystem appears destroyed without going through do_subobj_destroyed_stuff:
- the subsystem is destroyed at the start of the mission
- the subsystem was destroyed in the previous mission of a red-alert sequence
- the ship changes class while the subsystem's submodels are blown off
Previously the first two blew off only the first submodel, ignored "no disappear" for it, and never showed a linked -destroyed submodel; the third did nothing. For red alert, subsystems with no hitpoints at all are not treated as destroyed. For a class change, the visible state is carried over rather than inferred from hitpoints, so a subsystem set to zero without being blown up, or repaired without its submodels, keeps its appearance.
Red alert also restores the submodels of a subsystem that the mission file starts destroyed if the previous mission's data gives it hitpoints. Ship-copy-damage now shows or hides the -destroyed submodel linked to a special-point subsystem to match the copied state.
As before, the link between special-point subsystems and -destroyed submodels requires "$Link special-point subsystems to -destroyed submodels:" in game_settings.tbl.
The multiplayer hitpoint-update path is not changed. A client receives subsystem hitpoints separately from the notification that a subsystem was destroyed, so a hitpoint update sent just before the destruction could arrive after it and wrongly restore the submodels.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
- A parse flag to indicate when the mission is being parsed, and a new `ship_class_index()` accessor in the ship registry, both currently unused
- Make the ship registry more robust, especially in FRED: properly update it when ships are renamed or deleted
* 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]>
Ships that red-alerted, but that departed before red-alert was triggered, would have 0 weapons on the subsequent mission. Since exited ships do not store weapon information, that information was never saved in the red-alert status, and so `num_primary_banks` and `num_secondary_banks` would inadvertently be set to 0. This bug has been around since the pilotfile upgrade in 2013, and apparently was common knowledge among several players, but was never reported. :-/ The fix is easy enough: skip setting weapon information if that information is not saved in red-alert status. (We should also skip setting subsystem information in the same circumstances, although that did not cause any subsystem misbehavior.)
* keep from crashing
* Also, bash the number of waves if necessary
* Add Debug warning to modders
* address feedback
* formatting
---------
Co-authored-by: Goober5000 <[email protected]>
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.
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.
Two fixes for red alert missions:
1. Since any ship in the wing can be stored, not just the wing leader, the "prospective name" check should check for all possible names in each wave
2. If a wing wasn't actually stored, the red alert code should not reset the wing's wave number to 0
Follow-up to #4457.
When iterating through `Ship_obj_list`, check the `Should_be_dead` flag before using the object. This fixes#4990 and adds defense-in-depth checks to guard against similar errors elsewhere.
I considered moving the `Ship_obj_list` removal from `obj_delete` to `ship_cleanup`, but decided it would be prudent to avoid fundamental changes to lifecycle management.
This range check is to ensure that the ship's hull is in a valid range, so it should therefore check that the hull is less than the max strength, not less than the current strength. This was inadvertently changed in 593be42e66 and a04e83ab01, but retail behavior is to set the exact hull from the previous mission.
Tested for both regular ships and delayed-arrival ships. Fixes#4472.
- support sync state before entering mission
- return to briefing for sync and stats saving
- handle campaign progression properly
- initialize net_player state properly (fixes#2560)
This can be used for mark parts of the code which should be unreachable
in normal execution. In debug mode, if such a statement is reached an
Error dialog is shown which aborts the execution. In release mode the
macro is replaced with a compiler specific expression that lets the
compiler know that this part is unreachable which allows it to optimize
the code better.
This adds a new class which allows to create type safe resource handle
types. At the moment, the engine uses ints pretty much everywhere for
providing handles to resources created by the specific subsystems. Since
all ints are the same to the C/C++ typesystem it is perfectly legal to
pass a sound handle to the graphics API as a buffer handle which will
obviously cause issues.
This adds a new type called "ID" which is a wrapper class for a generic
handle but with added type safety. An instance of this class cannot be
passed to a function expecting another type of handle which provided
compile-time type safety for these APIs.
As an initial test I converted the game sound handles to this new type.
I already found a bug in the mainhall system thanks to this new type.
The mainhall used the game sound handles as sound instance handles which
probably meant that that specific code never really worked right. I
removed the code since there was no better alternative for fixing it.
This happened in BtA where a script changed the font after rendering its
UI. Since the briefing code didn't account for that, the word wrapping
code used the wrong font for calculating how long a line would be which
made the display look wrong.
It was previously thought that dock_undock_all() was supposed to be within ship_cleanup() and was safe to do so. Nope.
dock_evaluate_all_docked_objects makes the assumption that the dock_list is still valid, so if the function called by it happens to nuke the dock_list (like with ship_cleanup) then it'll work with invalid pointer values.
* Adds a warning for debug users when an unknown ship_state is passed to red_alert_delete.
* Removes commented-out code
* Doxy's ship_cleanup()
*Conform to each file's style.
*Extend ship_cleanup to better handle red-alert deletion.
*Also treat cleanup_mode as a flagset, instead of an enum as it was previously.
*Use existing methods to determine dock status and find the head of the dock list.
*Fixes a derp with dock_dead_undock_all()
*Doccument some docking methods in object.h
*Address requested changes.