83 lines
3.1 KiB
C#
83 lines
3.1 KiB
C#
using System;
|
|
using Cysharp.Threading.Tasks;
|
|
using Unity.Mathematics;
|
|
|
|
namespace DanieleMarotta.RiversongCodeShowcase
|
|
{
|
|
public class PathfindingIntentExecutionLogic : IntentExecutionLogic
|
|
{
|
|
private IPathfinder _pathfinder;
|
|
|
|
private ITileSpace _tileSpace;
|
|
|
|
private IFailedPathCache _failedPathCache;
|
|
|
|
private ISignalBus _signalBus;
|
|
|
|
public override UniTask InitializeAsync(IServiceLocator serviceLocator)
|
|
{
|
|
_pathfinder = serviceLocator.GetService<IPathfinder>();
|
|
_tileSpace = serviceLocator.GetService<ITileSpace>();
|
|
_failedPathCache = serviceLocator.GetService<IFailedPathCache>();
|
|
_signalBus = serviceLocator.GetService<ISignalBus>();
|
|
|
|
return UniTask.CompletedTask;
|
|
}
|
|
|
|
public override IntentExecutionResult OnStartingIntent(Agent agent, in AgentIntent intent)
|
|
{
|
|
ref var path = ref agent.GetPathRW();
|
|
path.Steps.Clear();
|
|
|
|
var searchType = intent.Type switch
|
|
{
|
|
AgentIntentType.FindPath => PathSearchType.FindPath,
|
|
AgentIntentType.SearchResourceNode => PathSearchType.SearchResourceNode,
|
|
AgentIntentType.SearchFertileTile => PathSearchType.SearchFertileTile,
|
|
AgentIntentType.SearchCritter => PathSearchType.SearchCritterHerd,
|
|
_ => throw new ArgumentOutOfRangeException()
|
|
};
|
|
var query = new PathQuery
|
|
{
|
|
SearchType = searchType,
|
|
SourceTile = _tileSpace.WorldToTile(agent.Position),
|
|
DestinationRect = intent.Rect,
|
|
TargetId = intent.TargetId,
|
|
TraversalRules = intent.PathTraversalRules,
|
|
MaxDistance = intent.PathMaxDistance
|
|
};
|
|
|
|
agent.PathQueryHandle = _pathfinder.FindPath(path, ref query);
|
|
|
|
return IntentExecutionResult.Success;
|
|
}
|
|
|
|
public override IntentExecutionResult Execute(Agent agent, in AgentIntent intent)
|
|
{
|
|
switch (_pathfinder.CompletePath(agent.PathQueryHandle))
|
|
{
|
|
case PathQueryResult.InProgress:
|
|
return IntentExecutionResult.InProgress;
|
|
|
|
case PathQueryResult.InvalidQuery:
|
|
return IntentExecutionResult.Failure;
|
|
|
|
case PathQueryResult.Failure:
|
|
if ((intent.PathTraversalRules & PathTraversalRules.UpdateFailedPathCache) != 0) _failedPathCache.FailPath(agent.HomeId, intent.TargetId);
|
|
_signalBus.Raise(new PathQueryFailedSignal(intent.PathTraversalRules));
|
|
return IntentExecutionResult.Failure;
|
|
}
|
|
|
|
ref var path = ref agent.GetPathRW();
|
|
var agentTile = _tileSpace.WorldToTile(agent.Position);
|
|
if (path.Steps.Length > 0 && math.any(agentTile != path.Steps[0]))
|
|
{
|
|
agent.Position = _tileSpace.TileToWorld(path.Steps[0]);
|
|
agent.Velocity = float3.zero;
|
|
}
|
|
|
|
return IntentExecutionResult.Success;
|
|
}
|
|
}
|
|
}
|