109 lines
4.9 KiB
C#
109 lines
4.9 KiB
C#
using Cysharp.Threading.Tasks;
|
|
using UnityEngine;
|
|
|
|
namespace DanieleMarotta.RiversongCodeShowcase
|
|
{
|
|
[Service(typeof(IIntentLogicExecutor))]
|
|
[GameSystemGroup(typeof(DefaultAgentsSystemGroup))]
|
|
[UpdateAfter(typeof(AgentManagerSystem))]
|
|
public class IntentExecutionSystem : GameSystem, IInitializable, IUpdatable, IIntentLogicExecutor
|
|
{
|
|
[InjectService]
|
|
private IEntityCollection _entityCollection;
|
|
|
|
private readonly IntentExecutionLogic[] _executionLogic = new IntentExecutionLogic[(int)AgentIntentType.Count];
|
|
|
|
public IntentExecutionSystem(IServiceLocator serviceLocator) : base(serviceLocator)
|
|
{
|
|
}
|
|
|
|
public async UniTask InitializeAsync()
|
|
{
|
|
var pathfindingLogic = new PathfindingIntentExecutionLogic();
|
|
var wanderingLogic = new WanderingExecutionLogic();
|
|
|
|
_executionLogic[(int)AgentIntentType.MakeLive] = new MakeLiveIntentExecutionLogic();
|
|
_executionLogic[(int)AgentIntentType.WaitSeconds] = new WaitSecondsIntentExecutionLogic();
|
|
_executionLogic[(int)AgentIntentType.WaitForever] = new WaitForeverIntentExecutionLogic();
|
|
_executionLogic[(int)AgentIntentType.FindPath] = pathfindingLogic;
|
|
_executionLogic[(int)AgentIntentType.SearchResourceNode] = pathfindingLogic;
|
|
_executionLogic[(int)AgentIntentType.SearchFertileTile] = pathfindingLogic;
|
|
_executionLogic[(int)AgentIntentType.SearchCritter] = pathfindingLogic;
|
|
_executionLogic[(int)AgentIntentType.FollowPath] = new FollowPathIntentExecutionLogic();
|
|
_executionLogic[(int)AgentIntentType.MoveToHarvestPosition] = new MoveToHarvestPositionIntentExecutionLogic();
|
|
_executionLogic[(int)AgentIntentType.HarvestResource] = new HarvestResourceIntentExecutionLogic();
|
|
_executionLogic[(int)AgentIntentType.HarvestFertileTile] = new HarvestFertileTileIntentExecutionLogic();
|
|
_executionLogic[(int)AgentIntentType.SetFertileTileLockState] = new SetFertileTileLockStateIntentExecutionLogic();
|
|
_executionLogic[(int)AgentIntentType.FireProjectile] = new FireProjectileExecutionLogic();
|
|
_executionLogic[(int)AgentIntentType.TakeProduct] = new TakeProductIntentExecutionLogic();
|
|
_executionLogic[(int)AgentIntentType.PutProduct] = new PutProductIntentExecutionLogic();
|
|
_executionLogic[(int)AgentIntentType.Wander] = wanderingLogic;
|
|
_executionLogic[(int)AgentIntentType.LoopWandering] = wanderingLogic;
|
|
_executionLogic[(int)AgentIntentType.LookAt] = new LookAtIntentExecutionLogic();
|
|
_executionLogic[(int)AgentIntentType.PlayAnimation] = new PlayAnimationIntentExecutionLogic();
|
|
|
|
foreach (var executionLogic in _executionLogic) await executionLogic.InitializeAsync(ServiceLocator);
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
foreach (Agent agent in _entityCollection.GetInternalEntityList(typeof(Agent))) UpdateAgent(agent);
|
|
}
|
|
|
|
private void UpdateAgent(Agent agent)
|
|
{
|
|
if (agent.LifecycleState == AgentLifecycleState.DeSpawning)
|
|
{
|
|
CancelRemainingIntents(agent);
|
|
return;
|
|
}
|
|
|
|
ref var intentQueue = ref agent.GetIntentQueueRW();
|
|
|
|
if (!intentQueue.TryPeekIntent(out var intent))
|
|
{
|
|
agent.IntentExecutionState = IntentExecutionState.EmptyQueue;
|
|
return;
|
|
}
|
|
|
|
var executionLogic = _executionLogic[(int)intent.Type];
|
|
|
|
if (agent.IntentExecutionState == IntentExecutionState.WaitingIntent)
|
|
{
|
|
if (executionLogic.OnStartingIntent(agent, intent) == IntentExecutionResult.Failure)
|
|
{
|
|
intentQueue.TryDequeueIntent(out _);
|
|
CancelRemainingIntents(agent);
|
|
return;
|
|
}
|
|
|
|
agent.IntentExecutionState = IntentExecutionState.ExecutingIntent;
|
|
agent.IntentExecutionTime = 0;
|
|
}
|
|
|
|
var result = executionLogic.Execute(agent, intent);
|
|
if (result == IntentExecutionResult.InProgress)
|
|
{
|
|
agent.IntentExecutionTime += Time.deltaTime;
|
|
return;
|
|
}
|
|
|
|
intentQueue.TryDequeueIntent(out _);
|
|
|
|
if (result == IntentExecutionResult.Failure) CancelRemainingIntents(agent);
|
|
|
|
agent.IntentExecutionState = IntentExecutionState.WaitingIntent;
|
|
}
|
|
|
|
public ref IntentQueue CancelRemainingIntents(Agent agent)
|
|
{
|
|
ref var intentQueue = ref agent.GetIntentQueueRW();
|
|
while (intentQueue.TryDequeueIntent(out var intent)) _executionLogic[(int)intent.Type].OnCanceled(agent, intent);
|
|
|
|
agent.IntentExecutionState = IntentExecutionState.WaitingIntent;
|
|
|
|
return ref intentQueue;
|
|
}
|
|
}
|
|
}
|