In #5649 / b6c0e8b, the ship registry was updated to take ship death rolls into account. There was one small wrinkle that it did not account for, however: SEXP operators that return numeric values had previously (i.e. before the introduction of the ship registry) checked the mission log for ship destruction, but after #5649 the EXITED status was not set until after the ship had completely exploded, resulting in certain SEXPs having their conditions slightly modified. The equivalent of checking the mission log for ship destruction is now checking the ship status for DEATH_ROLL, so it is necessary to make that change for the numeric SEXPs to behave as they did before.
The motivating result for all this is to fix SEXPs like `hits-left` firing after a ship has been destroyed but before it has finished exploding. This can be seen by loading the first non-training mission of FSPort and comparing the messages that are sent if you use cheats to kill Alpha 2.
SEXP helps should let the FREDder know whether a given ship argument
needs to be already in-mission for the SEXPression to operate. Update
the helps to include (ship needs to be in-mission) or (ship does not
need to be in-mission) or other relevant helpful information.
Since its creation, the `is-in-mission` sexp operator has only checked for ships. But mission designers might assume this also works for wings, leading to a situation where the sexp always returns false because no ship can have the same name as a wing. Fortunately wing functionality can be added to this sexp without affecting ship functionality.
This fixes a few items that were revealed in the course of Dark Visor's SEXP documentation PR. The EXITED status should return NAN_FOREVER, not just NAN. The CANT_EVAL value is never returned from the sexp on account of ship status, due to the preceding check, and is not an appropriate return value anyway; so that is removed. Finally, for a ship that can't move, the NAN return value is better than CANT_EVAL, since it represents the numeric situation more accurately and can also be checked by `is-nan`.
This is a new method of ensuring that OPF_POSITIVE numbers are positive. It works for all numeric arguments, including variables and literals, and caches the status of the node to avoid lookups for every negative number on every frame. Tested on both operator and non-operator cases.
Follow-up to #5915.
Operators that specify OPF_POSITIVE should be guaranteed to get positive numbers. This code was previously disabled for performance reasons, but following the contract of the SEXP system is more important. A future PR will improve the performance of the functions used here.
Also, the `num-players` operator takes no arguments, so fix that.
1. Allow a `+` to appear in front of numbers, just as with `-`
2. Check for `.` and `,` within numbers to give a less misleading error message than "not a number"
3. The old number hack inadvertently skipped numeric literals, so specifically check for those
There are several SEXP argument types that themselves encompass multiple argument types: for example, ships and wings. This could be misleading when there is an error message displayed. So, this updates the error codes to explicitly cover all of the possibilities.
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.
Adds a SEXP that specifically checks for whether a player has skipped a mission. This can be used to set tech room entries, allowed ships/weapons, and other campaign data that would otherwise break if a player skipped a mission.
This only applies to the the failed-five-times popup. For this to work with the `skipmemymissionyo` cheat, it would be necessary to load every intervening mission and check the events. That being said, `skipmemymissionyo` already automatically allows all ships and weapons, so there is much less, if any, need for this SEXP in that case.
These new SEXP operators clear all status information from an event or goal, making it as if the event or goal had never been evaluated.
Implements feature discussed in #4184.
The requirement for delayed event status checks to be strictly greater than the event fired timestamp (see commit eed50619ca / PR #5267) means that `is-event-true-delay 0` will not work in debriefings if the event becomes true and the debriefing SEXPs are evaluated on the exact same timestamp. Normally this is not a problem, but one important exception is the `end-mission` operator which instantly sends the player to debriefing.
This timestamp behavior is working as designed and should be consistent as long as the `end-mission` operator has been around (I've verified it as far back as 3.7.4). But it does lead to inconvenient situations where the event that called `end-mission` cannot be evaluated by the debriefing. This makes it slightly more complicated to plan debriefing stages based on these events.
Therefore, it makes sense to add an exception to the event status function to ignore the delay if the evaluation is not in-mission. This is consistent with evaluating events that *never* fired and also satisfies the principle of least astonishment for mission designers.
This also adds relevant documentation to the event and goal status operators.
Convert additional timestamps to use the new timestamp system. This covers all timestamps referred to in freespace.cpp. For purposes of organization, the fade-in/fade-out timestamps have been moved to light.h|cpp and the training timestamps have been moved to missiontraining.h|cpp.
There are also several related code enhancements:
1. `FadeType` has been converted from `enum` to `enum class`
2. Initialization of the various training variables has been added to `training_mission_init` (previously they had never been reset between missions)
3. Validity checks have been added to the relevant locations for these timestamps