The FreeSpace AI includes behavior to run away from shockwaves to try to avoid explosion damage. This is implemented for both ships and missiles, although the missile implementation has been buggy ever since retail. There are several issues:
1. The AI attempts to evade a weapon immediately upon launch. Many missiles have a period of free flight before they start homing on their target. During the free flight period, the homing position is not set. Consequently, the AI will not know the position to avoid and will make assumptions.
2. The AI assumes the shockwave-producing weapon will detonate at the center of the ship it is targeting, although missiles detonate on the surface. A capital ship is likely to be significantly larger than the weapon's blast radius, leading the AI to believe the detonation will be much farther away than it actually is.
3. When avoiding ship shockwaves, the `shockwave_object` field is not cleared when avoiding is complete. This can result in stale references (though not crashes, due to object type checks), causing AI to not avoid future explosions in certain cases.
4. When avoiding ship shockwaves, the code does not check the correct ship for the amount of damage caused by the shockwave.
All of these issues are now fixed. Since this is a change in AI behavior, these fixes are tied to a new AI profiles flag.
Several locations in the code (notably `ai_info` and `waypoint_h`) previously stored pointers for waypoints and waypoint lists that need to be valid for more than one frame. Since both waypoint lists and waypoint paths may change size, resulting in vector reallocation, the information should be stored as indexes instead.
Fixes#6353.
Per #4294, this adds two new flag that, together, are equivalent to the legacy "immobile" flag but individually provide more fine-grained control. Since the physics for position and orientation have a bit of overlap, the new flag functionality simply reverts whatever position or orientation changes were done by the physics sim.
In the FRED and qtFRED ship flags dialogs, the "immobile" flag (aka "Does Not Move") is replaced by the two new flags, but in FSO the situation is more complicated. The old and new flags coexist and have overlapping functionality, so the mission designer must be careful to set and unset the appropriate flag (that is, it is possible for both "immobile" and "don't-change-position" to be set at the same time, in which case the ship cannot change position without both flags being unset). The `set-immobile` and `set-mobile` legacy SEXPs ensure that the new flags are removed so as not to conflict with the legacy flag, but the `alter-ship-flag` and `are-ship-flags-set` SEXPs and the `getFlag` and `setFlag` script functions use exactly what the FREDder/scripter specifies and nothing else.
(I attempted to completely replace "immobile" with the two newer flags, but it proved intractable to do this while maintaining reverse compatibility: retrofitting single-flag functions to apply dual flags for one particular situation made the functions harder to understand as well as introducing many edge cases and opportunities for bugs or "gotchas".)
Implements #4294.
The somewhat modern AI flag for `Require_exact_los` is extremely useful in multiple different situations, for example making large capital ship weapons not fire into friendly surrounding ships on accident. When the feature was added, the `check_los` function was provided with a default value of `10.0` meters for minimum radius detection. This PR exposes that value to modders so they can set it to a reasonable value depending on the ship sizes of their specific needs. And as a note, the los value just uses a simple numerical comparison check, so the los detection could be set to a negative value with no consequence (hence why error messages were not added, though if folks would like I can certainly add them).
* base working version of unlimited debris types
* Proper FRED support
* make qtFRED handle asteroids properly
* fix qtFRED assertion
* further clean out MAX_RETAIL_DEBRIS_TYPES
* These should be sizes not POFs
* Move this to it's own method
* convert asteroid subtypes to a vector
* unlimit asteroid subtypes
* fix some global shadowing
* signed/unsigned mismatch
* Address feedback
This refactors the object_h struct to store objects as indexes rather than pointers. This is a prerequisite for making the collection of objects dynamic in the future. See also #6100.
Follow-up to #5800 and #5829.
Follow-up to #6047. This method better accounts for matching the guardee ship orientation when using the new AI flag.
Tested and works as expected. Thanks @BMagnu!
When waypoint start index and direction were added in #5698 / 42fc989 et seq., the `Fix_ai_path_order_bug` flag needed to be updated to account for those new options. This fixes that.
Fixes#6052.
* Add AI Flag to `align to target when guarding stationary ship`
When a ship is ordered to guard another ship that is stationary and not incredibly large, the AI will fly to a position then turn and face away from the targeted ship. This behavior is not ideal in various scenarios, including both blockade style formations and overall visuals.
The PR adds a flag that tells the AI to align to the target ship it is guarding once the AI has reached it's guarding position in this situation, which allows all the guarding ships to have the same orientation and look much better and work better for directional defenses.
Tested and works as expected. Also changed some `NULL` to `nullptr` in this function for cleanup.
* remove duplicate brackets
Turn `Parse_names` into a vector and add SCP_string overloads of ship registry functions. Refactor calling code to use registry as appropriate. Remove an unused overload of `mission_parse_get_parse_object`.
1. make `check_ok_to_fire` return a boolean (like `check_los`)
2. make `check_ok_to_fire` and `check_los` both use a position argument since we don't need the whole turret
3. remove the redundant position prediction code from `ship_get_global_turret_gun_info` (since that needs to be a "pure" function) while making sure "share fire direction" still works
4. skip calculation of the vector in `ship_get_global_turret_gun_info` if we don't need it
5. move the position prediction code out of `aifft_rotate_turret` and into its own function
6. prune some gun position calculation calls since in most cases one will suffice
7. fix position "jitter" with weapon subsystem damage in missions that use gravity
8. `model_rotate_gun` now uses a nullptr position for a reset instead of an extra boolean argument
9. use a more efficient method to calculate gun barrel length
10. a couple variable name changes for clarity
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.
In many calls to `ship_get_subsystem_strength`, the caller doesn't care about the actual number, just whether the subsystem type is destroyed. So this adds an optimization to check specifically for that. In the case of `SUBSYSTEM_ENGINE`, this avoids an iteration over every subsystem on the ship which, for a ship with many turrets, can be significant.
Add "tactical" versions of disable and disarm goals which only perform the specific task without implying anything else. The target ship is not protected and attack goals are not cleared from other ships.
There is also a new AI profiles flag to make this the default hud squad message command instead of the classic disable/disarm.