Agent, Flight, Combat, MoveTo and Follow write only Ship.Command. Entities with no agent apply first, then each agent applies right after it decides. A pilot reads its own pending designation and aim item back from its command; FireControl gains Refuses/AgentFires/HitProbability overloads that take them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
26 lines
1,020 B
C#
26 lines
1,020 B
C#
using CultMath;
|
|
using static CultMath.math;
|
|
using float2 = CultMath.float2;
|
|
|
|
// Hold a standoff from the anchor: match its velocity, and close or open the gap in proportion to the error.
|
|
public class FollowState : BaseState
|
|
{
|
|
public FollowState(Agent agent) : base(agent) { }
|
|
|
|
public override void Update(float delta)
|
|
{
|
|
var task = _agent.Task as FollowTask;
|
|
if (task?.Anchor == null) return;
|
|
|
|
var toAnchor = task.Anchor.Position.xz - _agent.Ship.Position.xz;
|
|
var distance = length(toAnchor);
|
|
var direction = distance > 0 ? toAnchor / distance : _agent.Ship.Direction;
|
|
// Positive error: too far, close. Negative: too near, open.
|
|
var error = distance - task.Standoff;
|
|
var pull = direction * (float) sign(error) * saturate(abs(error) / max(task.Standoff, 1f));
|
|
var desired = task.Anchor.Velocity + pull * _agent.TopSpeed;
|
|
|
|
_agent.Ship.Command.Aim = float3(direction.x, 0, direction.y);
|
|
_agent.Accelerate(desired);
|
|
}
|
|
}
|