75 lines
2.4 KiB
C#
75 lines
2.4 KiB
C#
using System;
|
|
using Cysharp.Threading.Tasks;
|
|
using Unity.Mathematics;
|
|
using UnityEngine.Pool;
|
|
using Random = UnityEngine.Random;
|
|
|
|
namespace DanieleMarotta.RiversongCodeShowcase
|
|
{
|
|
public class WanderingExecutionLogic : IntentExecutionLogic
|
|
{
|
|
private ITileSpace _tileSpace;
|
|
|
|
private World _world;
|
|
|
|
public override UniTask InitializeAsync(IServiceLocator serviceLocator)
|
|
{
|
|
_tileSpace = serviceLocator.GetService<ITileSpace>();
|
|
_world = serviceLocator.GetService<World>();
|
|
|
|
return UniTask.CompletedTask;
|
|
}
|
|
|
|
public override IntentExecutionResult Execute(Agent agent, in AgentIntent intent)
|
|
{
|
|
switch (intent.Type)
|
|
{
|
|
case AgentIntentType.Wander:
|
|
return Wander(agent);
|
|
|
|
case AgentIntentType.LoopWandering:
|
|
LoopWandering(agent);
|
|
return IntentExecutionResult.Success;
|
|
}
|
|
|
|
throw new InvalidOperationException();
|
|
}
|
|
|
|
private IntentExecutionResult Wander(Agent agent)
|
|
{
|
|
using var candidatesScope = ListPool<int2>.Get(out var candidates);
|
|
|
|
var tile = _tileSpace.WorldToTile(agent.Position);
|
|
for (var i = 0; i < 8; i++)
|
|
{
|
|
var candidate = ((Directions)i).ToVector();
|
|
if (!_world.BlockMap.IsBlocked(tile + candidate, BlockReason.BlocksAgents)) candidates.Add(candidate);
|
|
}
|
|
if (candidates.Count <= 0) return IntentExecutionResult.Failure;
|
|
|
|
var direction = candidates[Random.Range(0, candidates.Count)];
|
|
|
|
if (agent.Definition.WanderingRadius > 0)
|
|
{
|
|
var distance = TileMath.StepCount(agent.WanderingCenter, tile + direction);
|
|
if (distance > agent.Definition.WanderingRadius) direction = math.sign(agent.WanderingCenter - tile);
|
|
}
|
|
|
|
ref var path = ref agent.GetPathRW();
|
|
path.Steps.Clear();
|
|
path.Steps.Add(tile);
|
|
path.Steps.Add(tile + direction);
|
|
|
|
return IntentExecutionResult.Success;
|
|
}
|
|
|
|
private void LoopWandering(Agent agent)
|
|
{
|
|
var idleTimeRange = agent.Definition.WanderingIdleTime;
|
|
var idleTime = Random.Range(idleTimeRange.x, idleTimeRange.y);
|
|
|
|
IntentQueue.LoopWandering(ref agent.GetIntentQueueRW(), idleTime);
|
|
}
|
|
}
|
|
}
|