Files
2026-05-21 16:04:49 +02:00

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);
}
}
}