-
Notifications
You must be signed in to change notification settings - Fork 25
Node Types
There are 3 kinds of nodes: EntryNode
, ProcessNode
and ValueNode
.
Ability starts from an entry node, and move through each FlowNode
.
EntryNode
and ProcessNode
are FlowNode
.
EntryNode
is the first node for every running abilities. It receives a custom payload object, which should implement IEventContext
, and check if the ability can run.
For example, when you play a card, you might need to check whether you have enough mana, and maybe need to match additional conditions. In this case, we can create a PlayCardNode
to check if we can pay the resources.
For another example, when the turn end, you want to check and trigger every related abilities. Note that "on turn end" is a game event, so we can create a OnTurnEndNode
, and send a payload telling who's turn is end.
Example
[NodeCategory("Card Game Sample")]
public class OnDamagedEventNode : EntryNode
{
public Outport<Unit> attackerPort;
public override bool CanExecute(IEventContext payload)
{
if (payload is DamageEvent damageEvent)
{
// Check if the owner is one of the targets
for (var i = 0; i < damageEvent.targets.Count; i++)
{
if (damageEvent.targets[i] == Actor)
{
return true;
}
}
}
return false;
}
protected override AbilityState DoLogic()
{
// Set the outports
var payload = GetPayload<DamageEvent>();
attackerPort.SetValue(payload.attacker);
return AbilityState.RUNNING;
}
}
ProcessNode
is like an action. The best practice is to make each action small enough.
Example
[NodeCategory("Card Game Sample")]
public class ModifyManaNode : ProcessNode
{
public Inport<Player> playerPort;
public Inport<int> amountPort;
protected override AbilityState DoLogic()
{
// Modify the mana from the target
Player player = playerPort.GetValue();
int amount = amountPort.GetValue();
player.ModifyStat(StatId.MANA, amount);
// Event
EnqueueEvent(new ManaChangeEvent
{
modifyValue = amount,
newAmount = player.GetStat(StatId.MANA).CurrentValue,
});
return AbilityState.RUNNING;
}
}
ValueNode
is not FlowNode
. It gives values to other nodes.
To give the values, you need to set the values by overriding EvaluateSelf()
method.
Example
[NodeCategory("Card Game Sample")]
public class RandomPickNode : ValueNode
{
public Inport<IReadOnlyList<Unit>> sourcePort;
public Outport<Unit> resultPort;
protected override void EvaluateSelf()
{
IReadOnlyList<Unit> source = sourcePort.GetValue();
var payload = GetPayload<PlayCardNode.Payload>();
Unit unit = source.RandomPickOne(payload.random);
resultPort.SetValue(unit);
}
}