This is the second part in a series where I discuss the technical implementation of Starcom's mission system. You can read the first part here.
Last week I explained how the mission system works overall. As a quick recap, several times a second the MissionManager iterates over all active missions. Each mission has one or more "lanes" that define a sequence of nodes, where each node is a set of conditions to wait for, then a set of actions to execute when all conditions are satisfied. Once a node is executed, the lane advances to the next node.
So what is actually inside these "MissionCondition" and "MissionAction" objects?
Conditions inherit from the abstract "MissionCondition" class, shown here with some static utility methods removed for clarity. It is quite simple:
public abstract class MissionCondition
{
public virtual string Description
{
get
{
return "No description for " + this;
}
} public abstract bool IsSatisfied(MissionUpdate update); }
You may have wondered in the earlier screenshots from the tool how the nodes had plain English descriptions of what they did. Each subclass is responsible for providing a human-readable description of their behavior. So the tool can just call "condition.Description" when drawing the little node boxes and doesn't need to know what kind of condition it is.
Apart from that, the class defines an abstract method IsSatisfied, which all concrete implementations will need to define.
Let's look at an example:

The Cargo Spill mission waits for the player to be within 250 units of a particular ship.
This is handled by a PlayerProximityCondition:
/// <summary>
/// Detect when the player is within a certain range of a persistent object
/// </summary>