using Cysharp.Threading.Tasks; namespace DanieleMarotta.RiversongCodeShowcase { public class SetFertileTileLockStateIntentExecutionLogic : IntentExecutionLogic { private World _world; private ITileSpace _tileSpace; public override UniTask InitializeAsync(IServiceLocator serviceLocator) { _world = serviceLocator.GetService(); _tileSpace = serviceLocator.GetService(); return UniTask.CompletedTask; } public override void OnCanceled(Agent agent, AgentIntent intent) { if (intent.TargetId != Entity.InvalidId) return; Unlock(agent); } public override IntentExecutionResult Execute(Agent agent, in AgentIntent intent) { return intent.TargetId == Entity.InvalidId ? Unlock(agent) : Lock(agent); } private IntentExecutionResult Lock(Agent agent) { ref var path = ref agent.GetPathRW(); var tile = path.StepCount > 0 ? path.Steps[^1] : _tileSpace.WorldToTile(agent.Position); ref var fertility = ref _world.Fertility.GetValueRW(tile); if (fertility.MaxFertility <= 0 || fertility.CurrentFertility < fertility.MaxFertility || fertility.LockId != Entity.InvalidId) return IntentExecutionResult.Failure; fertility.LockId = agent.Id; ref var farming = ref agent.GetJobStateRW().Farming; farming.LockedTile = tile; return IntentExecutionResult.Success; } private IntentExecutionResult Unlock(Agent agent) { ref var farming = ref agent.GetJobStateRW().Farming; if (farming.LockedTile == null) return IntentExecutionResult.Success; var tile = farming.LockedTile.Value; ref var fertility = ref _world.Fertility.GetValueRW(tile); if (fertility.LockId == agent.Id) fertility.LockId = Entity.InvalidId; farming.LockedTile = null; return IntentExecutionResult.Success; } } }