namespace FoodFactory.Equipment; 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.Conveyors; using FoodFactory.Items; using FoodFactory.Math; using FoodFactory.Recipes; using FoodFactory.Voxel; using Godot; using SJK.Functional; [Meta(typeof(IAutoNode))] public partial class SlicerTest : Node3D, IProvide, IProvide { public override void _Notification(int what) => this.Notify(what); private BeltPortHost _insertLogic = default!; public IBeltPortHost Value() => _insertLogic; [Dependency] public IVoxelGridRegistry GridRegistry => this.DependOn(); [Dependency] public IFoodFactoryApi FoodFactory => this.DependOn(); [Dependency] public IRecipes Recipes => this.DependOn(); IVoxelGridRegistry IProvide.Value() => GridRegistry; public GridTransform3D VoxelTransform { get => GridTransform3D.FromGodot(GlobalTransform); set => GlobalTransform = value.ToGodot(); } private Entity _itemBeingHeld = Entity.Null; private List 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 beltItemData && beltItemData.GetItem().TryGet(out var tags) && tags.Contains(TagRegistry.GetTag("sliceable")); bool canInsert(IBeltPort beltPort, IBeltItem item) { if (item is IBeltItemData 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); FoodFactory.TickManger.GameTick += _ => { 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()); sliced.RemoveAt(0); } } if (_itemBeingHeld.Id == -1)//TODO have a better way of dertming if item is valid, possibly nullable { return; } Span items = [_itemBeingHeld]; var context = new RecipeContext(World.Worlds[0], items); var builder = new RecipeResultBuilder(stackalloc bool[10], new ItemBuilder[10]); Span mapping = stackalloc int[1]; // var recipe = new PotatoCookRecipe(); var recipes = Recipes.GetRecipes("slice", 1, [_itemBeingHeld.Get()], [], new RecipeOutput(2), mapping); unsafe { while (RecipeProcessor.TryProcess( recipes: ref recipes, context: ref context, builder: ref builder, destroyEntity: &DestroyEntity, filter: &RecipeProcessor.FilterByPass, resultEntity: 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(); } }