With the advent of the SCP and the advanced SEXPs added by it, it is now possible to set up zones in a mission which will apply various hazards and other effects to those who enter them. Essentially a kind of terrain in space. This article will go over the the different types of effects as well as the types of zones one can set up, and finally show a few complete examples of how to implement them in FRED.
Among those effects that can be simulated, there are two pimary types: Toggled effects and Repeating effects.
A toggled effect is one that is turned on by one event when an object enters the zone, and turned off by another when it leaves. There is no need to constantly reapply the effect while the object is in the zone. Below is a list of some of the effects that fall into this category and the SEXPs used to simulate them:
- Inability to jump (using never-warp and allow-warp)
- Reduced sensor range (using radar-set-max-range)
- Inability to fire primary weapons (using lock-primary-weapon and unlock-primary-weapon)
- Inability to fire secondary weapons (using lock-secondary-weapon and unlock-secondary-weapon)
- Cover from sensors (using ship-stealthy and ship-unstealthy)
- No HUD (using hud-disable)
- No shields (using shields-off and shields-on)
A repeating effect is one that needs to be reapplied at set intervals for the duration an object remains in the zone. Unlike toggled effects, these can be done with a single event as it doesn't matter in which direction an object crosses the boundary to the zone, only whether it is in it. Again, below is a list of some of the effects that fall into this category and the SEXPs used to simulate them:
- Damage (using sabotage-subsystem)
- Repair (using repair-subsystem)
- EMP (using explosion-effect)
- Frontal shield damage (player ship only, using special-check)
There are three basic ways to define a zone, which can mixed and matched to create more complex shapes: A border, a sphere, and a box.
BordersA border zone is defined by selecting a value either the X, Y or Z plane, beyond which an object is considered to be inside the zone. The check to determine whether an object is in this zone is as simple as using get-object-x/y/z to check whether the object's current position on the selected plane is beyond that of the border, as shown here:
SpheresSpherical zones are defined by a point at their center marked by a waypoint, and a radius around it. Any object that moves inside the radius is considered to be inside the zone. To determine whether an object is inside the radius, use the distance SEXP to check how close the object is to the waypoint at the center of the circle, as shown below:
BoxesBox-shaped zones are defined by a point in their center and the dimensions of the box along the X, Y and Z axes respectively. Any object that is inside the boundaries on all 3 axes at once is considered to be inside the zone. Fortunately, the num-within-box SEXP will return the number of objects from a list that are inside a specified box area, eliminating the need to check for each axis individually with get-object-x/y/z. It is used as follows when determining whether an object is inside our box zone, with the first three numbers being the coordinates for the center, and the next three being the dimensions along the 3 axes:
To check for an object leaving the zone as needed for toggled effects, change the number 1 in the equals (=) check to a 0, as that will reverse the statement.
Except from the conditional, the structure of the events used for Toggle and Repeating effects differ considerably, so they will be handled seperately.
Common to all events simulating effect zones, regardless of which of the types mentioned above are used, are the every-time or every-time-argument conditionals. These are used in place of the original when as it must be possible to enter and exit zones repeatedly. When only one object is to be affected by a zone, every-time is the conditional of choice, and is substituted with every-time-argument when multiple objects can be affected.
A note on using every-time and every-time-argument is needed at this point: When using these conditionals, as is necessary for the events described here, it is vitally important that the conditions for them to trigger are set up properly. Specifically to this case, they must be prevented from repeatedly firing to apply an effect that has already been applied, as this can significantly degrade performance on slower computers. See the warnings in their respective articles for more details. How to deal with this is already covered in the following sections, but it is important enough to warrant a warning here explaining why it is absolutely necessary to not skip that part of the event.
As mentioned earlier, when simulating a toggled effect, two events are needed. One that checks for entry into the zone and engages the desired effect, and another that checks for exit from the area and disengages the effect.
In addition to cheking for entry and exit, though, the events must also (using and) check whether they even need to activate - If the effect is already engaged, there is no point in engaging it again regardless of whether an object is inside the zone or not. Likewise, when it is outside, there is no point in continually disengaging the effect if this has already been done once. There are two ways of doing this: The easy way, which is for effects that can be checked using a status SEXP (such as ship-stealthy, which can be checked with is-ship-stealthy), and the hard way, in which it is necessary to use a variable to track the status of the effect.For the latter, when an effect can't be checked for using a status SEXP, instead set up a numeric variable and set this to 1 whenever the effect is engaged, and to 0 whenever the effect is disengaged. Then include a check against the variable being the required value in the trigger for both the entry and the exit events, and this will keep the events from triggering except when they are really needed. The setup when using variables will look something like the image below:
At first glance, using a variable like this may appear as if it would cause trouble when it is used with a set of objects instead of just one. However, while this does result in the events going off somewhat more often than they absolutely need to, this method will nonetheless succeed in keeping the event triggering under control, as the extra triggerings will only happen at the point where one of the tracked objects passes into or out of the zone.
When simulating a repeating effect, it is as mentioned only necessary to check for an object's presence inside the zone.That still leaves the matter of a repeat delay, though, and the only way to keep track of a delay in this type of event is by using a variable. This is done by using the variable to store the current mission-time every time the event is triggered, and then including in the triggering conditions a check against mission-time being greater than the variable by an amount equal to the desired delay. In practise, such a setup will look something like the image below:
As with the variables for Toggle events, this is safe for use with multiple objects in an every-time-argument based event, though at first glance it may appear not to be.
Informing the Player
In an action packed environment, the player may not be keeping enough track of his/her position to be aware that they are entering an effect zone. As such it would be prudent to inform them of that fact. There are two ways of doing this: Either have a wingman or Command send a normal comm message warning about the zone, or use the training-msg SEXP to fake system messages informing the player of what is going on.
Of those two, the training message has the advantage of not being dependant on any wingmen being around, not requiring voice acting in case that is being considered for the mission, and, perhaps most importantly, it has the advantage of being displayed in the center of the HUD, clearly setting it apart from other messages and drawing attention to the fact that the player may be in danger simply by virtue of location.
Below are a two complete examples of zone events, one toggle event and one repeating event, and using every-time and every-time-argument respectively. Taken directly from FRED.