Files
FoodFactory/src/VoxelGrid/SlicerTest.cs

107 lines
3.7 KiB
C#

namespace ChickenGameTest;
using System;
using System.Collections.Generic;
using System.Linq;
using Arch.Core;
using Arch.Core.Extensions;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using FoodFactory;
using FoodFactory.Items;
using FoodFactory.Recipes;
using Godot;
using SJK.Functional;
[Meta(typeof(IAutoNode))]
public partial class SlicerTest : Node3D, IProvide<IBeltPortHost>, IProvide<IVoxelGridRegistry>
{
public override void _Notification(int what) => this.Notify(what);
private BeltPortHost _insertLogic = default!;
public IBeltPortHost Value() => _insertLogic;
[Dependency] public IVoxelGridRegistry GridRegistry => this.DependOn<IVoxelGridRegistry>();
[Dependency] public IRecipes Recipes => this.DependOn<IRecipes>();
IVoxelGridRegistry IProvide<IVoxelGridRegistry>.Value() => GridRegistry;
public GridTransform3D VoxelTransform
{
get => GridTransform3D.FromGodot(GlobalTransform);
set => GlobalTransform = value.ToGodot();
}
private Entity _itemBeingHeld = Entity.Null;
private List<Entity> sliced = [];
private VoxelGuid _guid;
public void OnResolved()
{
_insertLogic = new BeltPortHost();
_insertLogic.Bind(port => port is BeltPort beltPort && beltPort.PortName == "Input", () => new DelegateInsertBeltItemLogic(canAccept, canInsert));
_insertLogic.Bind(port => port is BeltPort beltPort && beltPort.PortName == "OutPut", () => new DelegateInsertBeltItemLogic((_, _) => false, (_, _) => false));
bool canAccept(IBeltPort port, IBeltItem item) => _itemBeingHeld.Id == -1 && !_itemBeingHeld.IsAlive() && item is IBeltItemData<Entity> beltItemData && beltItemData.GetItem().TryGet<Tags>(out var tags) && tags.Contains(TagRegistry.GetTag("sliceable"));
bool canInsert(IBeltPort beltPort, IBeltItem item)
{
if (item is IBeltItemData<Entity> itemData)
{
_itemBeingHeld = itemData.GetItem();
item.Dispose();
GD.Print("Added Item to slicer");
return true;
}
throw new NotImplementedException();
}
_guid = GridRegistry.Register(this, VoxelTransform.Origin);
this.Provide();
var time = new Timer() { Autostart = true, OneShot = false, WaitTime = .1 };
AddChild(time);
time.Timeout += () =>
{
if (sliced.Any())
{
var port = _insertLogic.GetPorts().FirstOrNone(port => port is BeltPort beltPort && beltPort.PortName == "OutPut").Bind(f => f.GetPortFacing(GridRegistry));
if (port.HasValue(out var v) && v.TryInsert(new TestItem() { Item = sliced[0] }, LaneSpan.One, 0))
{
GD.Print(sliced[0].Get<Carbohydrates>());
sliced.RemoveAt(0);
}
}
if (_itemBeingHeld.Id == -1)//TODO have a better way of dertming if item is valid, possibly nullable
{
return;
}
Span<Entity> items = [_itemBeingHeld];
var context = new RecipeContext(World.Worlds[0], items);
var builder = new RecipeResultBuilder(stackalloc bool[10], new ItemBuilder[10]);
Span<int> mapping = stackalloc int[1];
// var recipe = new PotatoCookRecipe();
var recipes = Recipes.GetRecipes("slice", 1, [_itemBeingHeld.Get<Tags>()], [], new RecipeOutput(2), mapping);
unsafe
{
while (RecipeProcessor.TryProcess(
ref recipes,
ref context,
ref builder,
&DestroyEntity,
out var created
))
{
_itemBeingHeld = Entity.Null;
sliced.AddRange(created);
break;
}
}
};
}
private static void DestroyEntity(Entity entity) => World.Worlds[entity.WorldId].Destroy(entity);
public override void _ExitTree()
{
GridRegistry.UnRegister(_guid);
base._ExitTree();
}
}