* 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.
Ship's implicit move operations compiled but were semantically broken in
two ways: moving copied the subsys_list sentinel's links verbatim,
leaving the bookend nodes of the intrusive subsystem list pointing at
the old sentinel address; and the raw owning warpin_effect /
warpout_effect pointers were copied without nulling the source, so a
vacated Ships[] slot aliased live WarpEffects that ship::clear() (on
slot reuse) or ship_close() (which walks every slot) would delete out
from under the destination ship.
Fix both at the member level so the compiler-generated moves are
correct by composition:
- Add ship_subsys_sentinel, derived from ship_subsys, whose move
operations re-link the bookend nodes (handling the null-linked,
self-referential-empty, and populated source states) and leave the
moved-from sentinel as an initialized empty list. Copying is
deleted. Public inheritance keeps &ship::subsys_list convertible to
ship_subsys*, so list_init, GET_FIRST, and every other call site is
unchanged.
- Convert warpin_effect and warpout_effect to std::unique_ptr. The
delete-and-null blocks in ship::clear(), ship_close(), and
ship_set_warp_effects() collapse into reset(); call sites that borrow
the pointer into a raw local now use get().
With the members handling themselves, declare ship's special member
functions: defaulted default constructor and moves, deleted copies
(previously implicit via the unique_ptr members, now stated intent).
The moves are deliberately not declared noexcept because members like
SCP_map and std::deque do not have standard-guaranteed nothrow moves;
the computed exception specification is used instead.
Co-Authored-By: Claude Fable 5 <[email protected]>
* 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]>
* rename misleading variable check_again to never_check_again
The first element of collision_result means "never check again" per the
typedef comment, but was destructured as check_again (opposite meaning).
Rename to never_check_again to match the actual semantics and prevent
future confusion.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix data races in ship-weapon collision threading
Two thread-safety bugs in ship_weapon_check_collision, which runs on
worker threads:
1. update_danger_weapon() wrote to Ai_info[] (danger_weapon_objnum,
danger_weapon_signature) without synchronization. Multiple weapons
targeting the same ship would race on the same Ai_info entry.
2. Homing missile detonation logic wrote wp->lifeleft and
wp->weapon_flags directly on the Weapons[] global array.
Fix: defer both writes to the main-thread post-processing phase via
new flags in ship_weapon_collision_data. Also convert the collision
data from a 6-element tuple to a named struct for readability.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix data race in ship-ship collision submodel checking
ship_ship_check_collision() toggled pmi->submodel[].collision_checked
flags on the heavy ship's polymodel_instance to selectively enable/
disable submodel collision checks. When two collision pairs shared the
same heavy ship, worker threads would race on the same pmi entries.
Fix: add a collision_checked_override pointer to mc_info that lets
callers provide a thread-local array of collision_checked values.
model_collide() uses the override when set, falling back to the
pmi->submodel[] field otherwise. ship_ship_check_collision() now
builds a local SCP_vector<char> and passes it via the override,
completely avoiding writes to shared polymodel_instance state.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Ensure threads have spun down before continuing non-threaded execution
* address review feedback for ship-weapon collision threading
- postproc flag now accumulates incrementally instead of being OR'd
at the final return, ensuring all return paths respect it
- early return for predictive collisions now preserves the
should_update_danger_weapon flag in the collision data
- moved nprintf detonation debug print to the main-thread process
pass for thread safety
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* move collision_checked from pmi into mc_info for thread safety
collision_checked flags were transient per-collision-pass state that
didn't belong in the shared polymodel_instance. Now mc_info owns an
SCP_vector<char> that model_collide auto-initializes from pmi when
empty. All collision callers (ship-ship, asteroid, debris, prop)
updated to manipulate mc.collision_checked instead of pmi->submodel[].
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Convert to CV and spinup counter
* Update comment
---------
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Co-authored-by: BMagnu <[email protected]>
* First draft of prop object type
* Add prop editor dialog in FRED
* prop sexps
* lua table prop support
* lab support
* lua mission access to props
* prop collision support
* use std::optional so the object->instance id is always valid
* allow props to block suns
* minor cleanup and remove arbitrary limit. Still limited to 500 objects.
* Sort props by category
* cleanup
* implement collision hooks
* parse prop flags and further ensure props are inited and closed correctly
* Add Cyborg's multi suggestions
* fix missing header
* add props to empty slots if available
* add multi signature
* fix rebase issues and match collisions to the new multithread style
* appease Clang the Conquerer
* save/parse mission prop classes by name
* Clean up comments and finish TODOs
* fix string errors
* clang wants this to be static now
* address feedback
* address feedback
* Use model num from prop info instead
* merge prop and ship collision group sexps together
* fix rebase bug
* address feedback
* fix name shadowing
* ship heavy submodel
* clang
---------
Co-authored-by: Asteroth <[email protected]>
* add new conditions
* don't worry about it
* implement new conditions
* bugfixing
* handle pokethrough differently
* clang for the clang god
* appeasement
* to the last i grapple with thee
* from hell's heart etc
* bugfixing
* support hits while dying
* fix shield math, cleanup
* fix memory error
* Make scripting use the full-blown particle system
* Add reverse option
* Add animation reversal as an option to modern particles
* Start implementation of beam particles
* Add multi-emission particle source API for legacy particles
* Attach beam muzzle particles to the correct host
* Reorder code in order to facilitate apparent visual size as modular curve input for particles
* fix lua api
* Typo
* Fix scripting and beam muzzle particles
* Remove muzzleflash code, prepare to replace with particles
* Begin mflash effect conversion
* Pass final parameters to mflashes and fix curve
* Remove deprecated particle function
* Add debris flame particles
* remove weapon_explosion table
* Convert shield explosion particles
* Fix modular curve full inputs and convert particle curve inputs accordingly
* Allow particle volume offset and rotation with curve-based rot around fvec
* Add Ring and Point Volumes
* Convert PSPEW to new system
* Make particle curve timing aware of interp
* Update todos
* get rid of performance waste
* Add last parameter for converted pspews
* Fix pspew bugs
* Fix direction for default pspew
* Fix order for voluem rotation
* particle vel interp
* particle vel interp 2
* Make beam muzzle stay parented to the firing ship, as it's likely the more commonly intended variamnt
* fix scripting particle lifetime
* Allow beam muzzle particle override
* Skip invalid pspews
* remove pspew dcf code
* Fix sparkler stretch
* Correct sparkler bia
* General sparkler weirdness
* Tune distribution of sparklers
* Convert Asteroid particles
* Fix conversion warning
* Fix conversion warning again
* Fix conversion warning again again
* Really clang?
* One fix and one enhancement to AI shield behavior
This PR adds one fix and one enhancement to AI shield behavior.
1) Fix: Testing, especially in FotG, revealed an edge-case bug with shield management where the AI will not direct shield energy to a quadrant if it was hit when that quadrant was down. In other words, if a shield quadrant is knocked down to 0 and continues to be shot the AI will not realize it needs to direct energy to that quadrant. This is because `quadrant` is set to -1 if a shield segment is down. This ensures that the resulting effects and damage calculations properly ignore that quadrant downstream, but it also results in `aip->last_hit_quadrant` being set to -1. This PR adds a fix to properly record which shield was actually hit, so that the AI knows to direct energy to that quadrant.
2) Enhancement: In combat situations with fire coming from many directions, it is good practice to keep shields equalized, so this PR adds a flag for the AI to always attempt to balance shields, even if it is being fired upon (instead of the current behavior to always direct energy to the hit shield quadrant).
Both flags are tested and work as expected.
* fix copy paste
* rename to avoid previous confusion
* also make as ai class flag
As discovered by PDFCommand and tracked down by Asteroth, there was another "missed target" check in `ship_weapon_check_collision()`, in addition to the more comprehensive check in `weapon_home()`. Since the check is redundant and there is an existing `$Fixed Missile Detonation:`, skip the check if the flag is active.
* Fix incorrect ship legacy particle curve assignment
* Setup trigger radius
* Properly attach particle sources to objects and subobjects
* Add trigger velocity for weapon impacts
* Onetime particle source timing fix
* Warnings
* Allow global_to_local to work with no submodel
* Allow global_to_local to work with no submodel, again
* Partially builds weapon curves.
* Further curve implementation
* Implementation of more output types.
* Cleanup
* Adjusts warning.
* Appeases clang.
* further appeasement
* Appeasement and time-traveling review changes
* change the enum branch too that'd be good
* More requested changes
* Basic abstraction for generic modular curves
* Make curve list by output statically sized
* Make instance-randomization consistent and mapless
* Add parsing
* Add derived modular curve sets
* Fix incorrect unpack
* Split modular curve set and definition, properly comment struct usage
* Split off specific type-traits into own file
* Fix modular curves for multi-derive case
* Implement some basic weapon curves, as well as the damage multiplier hit curve
* Merges in generified system built by Lafiel.
* Fills out beam curvesets.
* Renames curvesets.
* Removes launch curves for now.
* Testing, bugfixing.
* Various cleanup
* Returns extern do_subobj_hit_stuff
* Fixes compile errors
* Beam flag checking
* Rearranges beam flag checking.
---------
Co-authored-by: BMagnu <[email protected]>
This was motivated by the recent Coverity report. Coverity noticed that a few of the copy assignments could be replaced by move assignments, but on further investigation one copy each in `ship_weapon_check_collision()` and `beam_collide_ship()` can be entirely removed, another either/or copy in each can be replaced with an either/or pointer assignment, and a few copies can be done only when needed. Another vec3d copy (`hit_dir`) can be replaced with a vec3d pointer; it is no longer modified locally, so there is no longer a need to keep a local copy.
* Add the submodel that was hit to the On Ship Collision scripting hook. (This will only be non-nil if the ship was the "heavy object".)
* Add a `getModel()` function to the scripted submodel object.
* Fix some incorrect documentation in `OnShipCollision`.
This initializes `mc_info` to the correct values when it is constructed, removing the need for `mc_info_init`.
This PR also fixes a group of incorrectly inverted assignments in beam.cpp.
* Fixes CTD with decals on dying ships
If a ship was getting shot with weapons that used decals, the decal code would hit an assertation, because the invalid decals were not being all removed.
This PR updates the decal cleanup loop, to ensure that no decals are missed and all invalid ones are removed. Tests confirm this fixes the issue.
Also cleaned up some comments and moved another assertation before setting of variables.
* Exposes modder useful options to decals
Now that decals are very stable, this PR exposes two options that are very useful for using decals, a random range for the radius along with the option to have a random rotation when the decal is created.
Tested and everything works as expected.
* add script ability to toggle decals
* properly use set arg not func
* fix two minor things in decal shader
* one more cleanup line
* fixes
Adds gravity! Applies on a per-mission basis, and weapons, ships, debris, and asteroids now have a configurable "gravity const" which multiplies the effect of gravity on them, by default everything except debris is 0 (meaning no effect even when the mission has gravity). AI and the lead indicator will also lead for ballistic trajectories as well, given a gravity-affected weapon. No FRED support or gravity direction control yet, to come in later PRs.
This takes a few of the existing hooks and converts them to the new style of hook definition which can include more extensive documentation and enumeration of supported hook variables.
This is an updated version of #3151 to work with the latest codebase.
NOTE: Before this can be integrated into the codebase, it needs an implementation for `bool script_state::IsActiveAction(int hookId)` which apparently only has support for old-style script hooks.
For script hooks which use conditions, be more consistent about evaluating both objects involved, as well as evaluating the different types of objects.
Fixes#3874.
The orientation was broken since the engine rendered the decal box in
the direction of the hit normal which meant that the viewer was looking
at a flipped version of the decal texture.
This fixes that by flipping the direction of the decal before passing it
to the GPU.
This also fixes the orientation for weapon decals which previously did
not take the orientation of the weapon that just impacted into account.
There is a bit of code that detonates a missile if it misses impacting on a subsystem. On Nyctaeus's Arachnas model, missiles could reach the center point of the main beam turret submodel without actually hitting any part of the submodel. The fail-safe code would set the missile to detonate in that case, but on low-FPS systems the weapon would be able to actually hit the turret before it detonated. On high-FPS systems, there is a clean miss.
This reworks the code to delay the missile detonation until it reaches the other side of the submodel, so it has time to hit some other part of it. It also reduces the detonation time from 1/100 of a second (which is more than one frame on 120 FPS systems) to 1/1000 of a second (which is always less than one frame).
* Multiplayer Dumbfire Rollback
This creates a packet that sends the relative position and orientation info for a primary or dumbfire missle shot. The client creates this packet when firing those two types of weapons and sends it to the server. The server goes back to the frame that the client fired the weapon and quicky resimulates all the frames in-between.
This includes collision detection, restoring positions, orientations and veloicties, but not subsystem orientations.
* Address Feedback
* allow clients to send subsystem info
* Check for object number not weapon number
* Readability Adjustment
Also slightly optimizes some of the hooks because the adding/removing of hook variables should be guarded by the same if() block that controls execution.
The previous system was kind of hacky and made things a bit inflexible.
This improves that system quite a bit and also adds unit tests for the
hook variable functionality.
A bit of small cleanups in preparation of larger scale refactoring.
remove unused member heavy_collision_cm_pos of collision info struct,
which was set in several places but never used.
In this block of code, the conditions were checked with a set of four hook variables but then subsequently run with only two. This adds all four previously used variables. More importantly, it adds the hook variables with expected and user-friendly names, since 'self' and 'object' are not necessarily intuitive.