323 Commits
Author SHA1 Message Date
Boutros Tawaifi 49464c56f6 Add an "On Ship Damage" script hook (#7894)
* Add an "On Ship Damage" script hook

Runs after resolved damage has been applied to a ship (lethal hits run before
the destruction callback). Hook variables: Target, Source, Attacker,
WeaponClass, WeaponSubtype, SourceKind (PROJECTILE, BEAM, SHOCKWAVE, COLLISION,
OTHER), DamageType, ShieldDamage, HullDamage, Quadrant, Ballistic, BeamWeapon
and LethalHit. Conditions can filter on the target ship. Nothing is computed
unless a script has registered the hook.

* Move the On Ship Damage hook call out of a lambda

ship_do_damage() now calls a file-level static function, ship_run_damage_hook(), that takes the values it needs as arguments instead of capturing the function state. Hook behaviour is unchanged.

* Report subsystem damage in the On Ship Damage hook

Adds SubsystemDamage, the total subsystem strength a damage application removed, so a hit absorbed by subsystems no longer looks like a small hull hit. The hook description now says it only runs where damage is applied, which excludes multiplayer clients.

* Address On Ship Damage review comments

- Remove WeaponClass, WeaponSubtype, Ballistic and BeamWeapon from the
  hook. Scripts read these from Source when it is a weapon.
- Add a "Weapon class" condition for the On Ship Damage hook. It matches
  only when the damage source is a weapon of that class; a weapon name
  that does not exist never matches.
- SubsystemDamage is now a table keyed by subsystem handle that lists only
  the subsystems that lost strength. The total is removed.
- Rename PROJECTILE to NON_BEAM_WEAPON.
- Classify SourceKind by damage source: COLLISION for ship, debris and
  asteroid collisions; EXPLOSION for ship-death and docked-ship blasts and
  asteroid blasts; WASH for engine wash; SELF for kills where the ship
  damages itself; OTHER for other ship-sourced damage.
- Reword the hook description.

* Key On Ship Damage SubsystemDamage by canonical name

Lua tables cannot use subsystem handles as keys in a usable way, so key
the SubsystemDamage table by each subsystem's CanonicalName instead.

* Tag ship-vs-prop damage as a collision and use in_bounds

The ship-vs-prop collision call didn't pass DamageSource::Collision, so
the On Ship Damage hook reported those hits as OTHER. Every other
collision path was already tagged.

Also use SCP_vector::in_bounds() for the Weapon_info and Damage_types
index checks in ship_run_damage_hook().
2026-11-06 18:41:29 -05:00
Goober5000andClaude Opus 5.5 f7eb2ca419 restore subsystem sounds when a subsystem is repaired
A subsystem's looping sounds are now switched by ship_update_subsys_sounds, split out of ship_recalc_subsys_strength, which the support-ship and automatic repair paths now also call when a subsystem comes back from zero.  Previously those paths left the subsystem playing its dead sound.

Both the recalc and do_subobj_destroyed_stuff also cleared the dead-sound flag immediately after assigning the dead sound, so a revived subsystem never stopped it and a destroyed one gained another copy on each recalc.  They now set the flag.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-29 02:58:50 -04:00
Goober5000andClaude Fable 5.1 112ca2fc4b handle submodel repair/destruction consistently
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]>
2026-09-29 02:58:02 -04:00
Fabian Woltermann 68e9a30463 Fix a couple of oversights in prop collisions (#7753)
* 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.
2026-08-29 11:17:07 +02:00
The Force da05081405 Fix C4709 Warnings In modern VS (#7576)
* Fix C4709 Warnings on latest VS

* more

* suppress false positive

* Switch to using any/none_of

* Address Feedback

* Fix Line endings?

* Fix commits and strip out flag_combinator

* more fixes

* nolint
2026-07-26 14:33:00 +01:00
Goober5000 c3b8922fe3 address feedback 2026-05-14 23:35:00 -04:00
Goober5000 8f916174be clang 2026-05-14 03:30:53 -04:00
Goober5000 bed223c5c7 second part of comm node fix
Fix #4089, part 2:
- properly link special-point subsystems with -destroyed submodels, if such a relationship exists and a game_settings.tbl flag is set
- add some helper functions for -destroyed variants of submodels (and now subsystems)
2026-05-14 00:04:31 -04:00
Goober5000andClaude Opus 4.6 3f85d6172a use std::move() for local variables that are copied but not reused (#7308)
* 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]>
2026-05-07 14:40:38 +09:00
Taylor Richards aef736643a fix ship whack sync issue in multi
Put ships getting whacked by weapons or other objects into simulation mode to avoid odd
position changes when client-side whacks get overridden by server interoplation updates.
2026-04-02 16:31:57 -04:00
Mike NelsonandAsteroth 070a8e18fa Adds Props as a new object type (#6836)
* 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]>
2026-02-16 14:41:34 +01:00
Goober5000 adfb8200a5 remove the splodeing code
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.
2025-11-12 03:47:28 -05:00
Goober5000 d77f413f39 vectorize subsystem damage/heal list
When checking for subsystems within range of a hit, more than one subsystem is unusual, and 32 (the original `MAX_SUBSYS_LIST` value) is so unlikely as to be impossible.  So bumping it to 200 was not needed here -- DTP might have confused it with one of the other subsystem limits.  But rather than reducing the limit again, we can simply make the array into a vector.
2025-10-11 19:13:18 -04:00
wookieejedi 7eff7900a6 Allow mods to tune generic debris generation (#7027)
* 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
2025-10-07 07:42:44 -04:00
Kestrellius 9e618f6632 Particle effect hooks for subsystem destruction (#6937)
* add particle hook

* partial bugfixing

* bugfixing

* appeasement

* syntax fix
2025-08-22 07:19:15 -04:00
Goober5000 dde16a54c6 restore inadvertently deleted code
This has an interesting history.  In the original Volition source release, global damage was set to originate from the shockwave position, which would have avoided the fireball issue fixed by #6882.  (Technically, though, this was only done for huge ships which would have still left the problem for smaller ships.)  In c2716d4ee8, this code was changed to run in non-HTL mode in an attempt to fix a bug.  Then in 70529dbd5a, as part of the removal of non-HTL mode, the code was entirely deleted.  So, this restores the code.

The #6882 fix is still valid, both because it works for non-huge ships, and because shockwaves may not necessarily originate from the subobject being destroyed.  The #6882 fix also subsumes the effect of the restored code, but it's still good to restore the code in case future development may depend on it.
2025-08-16 01:14:45 -04:00
Kestrellius 8f835fe34b check for global (#6882) 2025-07-30 07:52:46 -04:00
Kestrellius abc82bd323 Handle impacts for obscure code paths (#6848)
* handle healing weapons

* incorporate shield threshold features

* fix piercing sign error

* use function
2025-07-30 20:12:35 +09:00
wookieejedi 168b3310ab Cleanup of Shield Hitpoint Threshold (#6851)
* Cleanup of Shield Hitpoint Threshold

Overall cleanup that does a few things:

1) Changes `ship_is_shield_up` from integer to bool.

2) `ship_is_shield_up` was only ever called to look at one quadrant, never for all quadrants, so took the opportunity to update the 'all-quadrant' block to account for ships with a non-standard number of shield quadrants.

3) ` MAX(2.0f, Shield_percent_skips_damage * shield_get_max_quad(ship_objp)` was used many times throughout the code (and will be used at least 2 more times with #6848), so simply consolidated all of those uses into a new function called `ship_shield_hitpoint_threshold`. Happy to edit the name however.

4) Removed un-needed redundant comments from `ship_is_shield_up` definition in `ship.h` since those comments were already present in the actual function within `shield.cpp`, and all the other functions used comments in that file instead.

Again happy to tune or edit with any other choices.

* use proper default arg style

* actually commit the updated files

* appease modern clang

* clang round 2
2025-07-24 08:39:58 -04:00
Kestrellius 365d9c57e3 gate hull and subsys impacts (#6855) 2025-07-23 08:07:42 -04:00
Kestrellius 199c7b79ef Make sure global damage doesn't spawn impact effects (#6842)
* check whether damage is global

* use static

* remove extraneous arguments
2025-07-20 07:45:27 -04:00
wookieejedi 26e9ecab0e Allow mods to set threshold at which shield stops taking damage (#6847)
* Allow mods to set threshold at which shield stops taking damage

FSO logic dictates that shields collisions and any related sound or visuals related to shields are skipped if the shields are under 10%. This is rather unintuitive especially for mods, so this PR creates a game setting value that allows mods to set this value.

Also, this PR fixes a bug where the HUD shield gauge would try and incorporate this feature but did not do it correctly. Specifically, the gauge skips shield segment rendering if the raw shield strength was 0.1 not the percent. Incorrectly using the raw value results in HUD shields being rendered (albeit faintly) even if the damage was skipping the shield and directly damaging the hull. In other words, if the shield segment was 8%, the shield segment would show faintly even the shield is skipping damage.

Tested and works as expected. Also happy to discuss or answer any questions!

* update local variable name for clarity

* rename `ship_quadrant_shield_strength`

* cleanup with updated get percent function

* more cleanup

* wording and safety tuning

* use correct default number
2025-07-19 18:24:49 -04:00
Kestrellius 6921f550c1 Enhanced functionality for conditional impacts (#6785)
* 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
2025-07-12 11:40:53 +02:00
BMagnu 1180f8762a Fix them oopsies (#6768) 2025-06-11 00:23:33 +02:00
Goober5000 44cdb29135 some refinement of shield quadrants
Remove the `n_quadrants` field because it is entirely redundant to the size of `shield_quadrant`.  Also, be more rigorous about the difference between `shield_get_quad(i)` (which can fluctuate) and `shield_quadrant[i]` (which gives the exact quadrant strength).  Finally add some C++ casts and move some checks to better places.
2025-03-08 01:10:59 -05:00
Goober5000 d31f0a1b79 several fixes to ship sparks
1. Refactor `num_hits` to `num_sparks` and `MAX_SHIP_HITS` to `MAX_SHIP_SPARKS` to be consistent with their current (since FS1 pre-release) usage.
2. Remove the unused `HP_SCALE`.
3. Always initialize at least one spark pair.  If `choose_next_spark()` was entered when `num_sparks` was 1, `num_spark_pairs` would be 0 and none of the spark pairs would be initialized.  Consequently, accessing the pair at index 0 would return garbage data.
4. Iterate through `num_spark_pairs` when counting the indexes, rather than the hardcoded (and incorrect) magic number 6.

Fixes a crash discovered by Dawnesya that can only occur when a ship has both the "fighter" and "cruiser" flags.  Normally, fighters never enter the `choose_next_spark()` function and 'big' ships always have at least 3 sparks.
2025-02-22 01:59:07 -05:00
Goober5000 ca624f86e2 a few pstypes changes and refinements
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.
2025-01-30 21:35:03 -05:00
Goober5000 cecfd9f7ff fix calculation of percent_killed
This has been broken ever since commit 6c17ef09ab in 2005.  Since `get_hull_pct()` did not return negative values, `percent_killed` was always 0.  Allow negative values in this case.
2025-01-12 16:52:16 -05:00
KestrelliusandBMagnu 228fd17ff1 Modular curves for weapon attributes during lifetime (#6319)
* 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]>
2024-12-10 23:32:46 +01:00
Asteroth c28842739e Allow beams to do energy leeching (#6377)
* allow beams to do esuck

* dont forget to use mult

* consistent comments
2024-11-26 19:13:54 +01:00
Goober5000 524ecbe826 handle clang warnings 2024-11-07 23:33:13 -05:00
Goober5000 31a86e3f3d all the consts!
Some experimentation resulted in a lot of const-cascading.  This PR applies `const` to a large number of functions.
2024-11-07 23:33:13 -05:00
Goober5000 168d3c9ddf add "override submodel impact" subsystem flag
With the `$Damage Impacted Subsystem First:` game_settings flag, weapons will damage submodels over subsystems, even if the subsystem is closer.  Yet occasionally this is not the correct behavior (e.g. for the Rahu's engines).  The new subsystem flag allows this behavior to be selectively overridden.
2024-03-25 15:49:52 -04:00
JohnAFernandez 6f263365af Merge pull request #5761 from JohnAFernandez/Coverity-COPY_INSTEAD_OF_MOVE-ISSUES
These std moves were suggested by Coverity as optimizations
2023-11-19 23:11:26 -05:00
Goober5000 3af831e0b7 rename Vaporize Percent Chance
This option was misleadingly named when originally introduced, so give it a more sensible name.  The old name is still accepted for backwards compatibility.
2023-11-16 15:57:53 -05:00
John Fernandez 0a5cf6ad9d Try the std moves suggested by Coverity
For many coverity issues
2023-11-03 14:40:04 -04:00
John Fernandez 40c8cbbb25 Add check for negative index
For coverity 1523515
2023-10-30 10:56:45 -04:00
Goober5000 4fbe3b7131 make sure class_type exists when used
A mission in Mantle caused an invalid vector access when checking whether to vaporize a ship whose ship type was -1.  Turns out having "no type" is actually allowed, so I audited all `class_type` accesses throughout the code for potential -1 accesses.  Most were properly checked but a few were not.  A few others needed to be tweaked.

(I suspect this is something that would be on the Coverity list if it isn't already.)
2023-10-29 15:17:22 -04:00
Goober5000 4f6d9c36a8 don't kill/self-destruct ship if it's already dying
If a ship is in the process of dying, it shouldn't be killed or self-destructed again.  This fixes a bug noticed by RedMageJoe during the Derelict playthrough.

(This situation is distinct from a ship being hit while in the middle of its death roll.  That shortens the death roll but does not try to kill the ship again.)
2023-10-16 00:36:10 -04:00
Tyler Blount 10f484a504 Merge pull request #5649 from Goober5000/fix_ship_status
fix ShipStatus states to correctly account for exploding ships
2023-10-03 18:11:25 -07:00
Birk Magnussen c2e01864d5 Incorporate feedback 2023-10-02 17:48:03 +02:00
Goober5000 b6c0e8b562 fix ShipStatus states to correctly account for exploding ships
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.
2023-10-01 18:10:55 -04:00
Birk Magnussen 348fb5ffb4 Change to variables 2023-10-01 01:25:38 +02:00
Birk Magnussen 30da49be81 Fix null dereference when hit for damage by a null object 2023-09-30 09:55:47 +02:00
Goober5000 c84cb7ab64 supply parameter for is_beam in all armor checks
For certain calculations involving armor, the `GetDamage` function needs to know if the damage is being applied by a beam so it can apply the calculations with the proper frametime.  The parameter was not provided in all cases, so this fixes that.

Follow-up to #1609.
2023-09-06 18:17:37 -04:00
Goober5000 d3b1ad4328 remove vestigial debug variables 2023-08-07 16:59:02 -04:00
Goober5000 5f8234d1cd fix some bugs revealed by ships with long display names
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`.
2023-07-03 20:08:26 -04:00
Asteroth d4beb69328 Add player damage inflicted factor (#5406)
* add player damage inflicted factor

* update default file
2023-05-21 08:17:31 -04:00
wookieejedi f2987aa749 Fix max Z speed when using ETS and engine damage tracking (#5368)
* Fix max Z speed when using ETS and engine damage tracking

Follow up for #5137 and #5292. This engine strength check thus needs to be added to all instances where `max_vel.xyz.z` is updated, so a function was created and added in respective locations. Fixes #5367.

* cleanup and adding validity assertations

* cleanup outdated comments

* might as well make the cleanup look nice

* update to account for more edge cases

* cleanup
2023-04-23 22:01:05 -04:00
Goober5000 ede86efa99 move self-destruct mission logging to ship_hit_kill
This moves `LOG_SELF_DESTRUCTED` to the same place that `LOG_SHIP_DESTROYED` is recorded.  This allows self-destruction to be correctly recorded when a ship is self-destructed via script, as well as when it is auto-repaired with a negative hull multiplier, or when ships are killed off in in-game joining.
2023-03-09 23:47:19 -05:00