Some of the `frand_range` calls were used for integer calculations, so we can use `Random::next` now.
This also reduces the number of C-style casts in the codebase.
Add `const` to the `eval_enemy_obj_struct` struct so its values aren't inadvertently overwritten. Handle a bit of const-correctness propagation. Also add default member initialization to the struct.
Add `const` to the `mc_info` struct so its values aren't inadvertently overwritten. Tweak some of the collision code to prevent overwrites.
Also remove the `flak_muzzle_flash` declaration since that function no longer exists.
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.)
The code has always checked a per-weapon-class value called `lock_fov` when comparing the dot product of a ship to its target to see if it can lock on to it, however the weapon table hasn't ever included a way to set this value; it's always the default value of 0.85. This just adds "+Lock FOV:" entries to aspect/javelin homing missile parsing after "+Seeker Strength:", which will set `lock_fov` as long as the supplied input is between 0 and 360 degrees.
Add some extra logic implied by the `Begun_detonation` flag. Missiles that are homing can have their targets, headings, speeds, and lifetimes changed for various reasons. If a missile has begun detonation, particularly if it is in "detonation limbo" because it is flying across a bowl-shaped turret, we don't want to change any of that. The "detonation limbo" weapon lifetime is only accurate if all of those values remain constant.
Follow up to #4006.
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.
1. Add a `vanish()` function for beam objects, to be consistent with other object types
2. Add a `BeamFree` virtvar, analogous to `TurretLocked`
3. Add timestamp variants of TurretLocked and BeamFree to be consistent with sexps
4. Add `BeamLife`, `BeamWarmup`, and `BeamWarmdown` virtvars so scripts can access table properties
5. Add "On Beam Death", "On Beam Warmup", and "On Beam Warmdown" hooks
6. Clarify some existing documentation and patch a couple things
When weapon flags are parsed in a modular table and override the previous set of flags, certain flags must be kept to preserve the behavior of the weapon. The previous `preset_wi_flags` technique only worked if all such flags (homing, has-display-name, even whether the weapon turns) were set in the same modular table. If a modular table overrode the flags but didn't specify those lines over again, mysterious and subtle bugs would occur.
This modifies the flag parsing to explicitly preserve all appropriate flags from the existing weapon entry, which fixes the bug. It also allows all of the flags to be specified in one place, rather than scattering `preset_wi_flags` assignments throughout `parse_weapon`. And this also adds quite a few flags to the flag list that were not handled at all under the previous design.
Finally this fixes a few incorrect assignments of default values to fields that should only happen the first time a weapon entry is parsed.
For mods which want primary weapons to 'detonate', setting the detonation range is not reliable because, due to rounding imprecision, either the range (which detonates) or the lifetime (which does not) may happen first. So this adds a flag to always detonate a weapon when its lifetime expires. Secondary weapons have this flag by default, but primary weapons can add this flag in the $Flags list. Additionally, if the detonation range and the predicted range due to lifetime are equal, the flag is added automatically.
Resolves#5521.
It appears that `(turret->turret_enemy_objnum < 0)` is an expected and allowed condition, so just assert that the objnum does not exceed MAX_OBJECTS.
Fixes#5470.
#5328 added a very useful culling for particles created by specific particle effects (ie weapons, now beams), though in an effort to simplify the culling process, that PR removed the necessary culling of default smoke on ships. This PR restores the culling of default smoke while also keeping the new culling of particle specific effects. Tested and works as expected, including fixing the slowdowns caused by the aforementioned removal of smoke effect culls.