Spite up project, added BeltData, some asoited compoents, remvoed unused usings, and removed uneeded comment code.

This commit is contained in:
2026-05-10 12:33:20 -04:00
parent d620189e4e
commit 4db51be374
53 changed files with 1892 additions and 608 deletions

231
src/Recipes/Recipe.cs Normal file
View File

@@ -0,0 +1,231 @@
namespace FoodFactory.Recipes;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Arch.Core;
using Arch.Core.Extensions;
using Arch.Core.Extensions.Dangerous;
using FoodFactory.Items;
using Godot;
public abstract record Recipe(string Name, BlueprintId[]? BlueprintIds, bool[] RequireAll, Tags[] Inputs, Tags[] Exclude, RecipeOutput RecipeOutput, RecipeAction Action = default, bool InputsOrdered = true)
{
public abstract bool CanProcess(in RecipeContext context);
public abstract RecipeResult Process(in RecipeContext context, ref RecipeResultBuilder builder);
}
public readonly record struct RecipeOutput
{
public int? Min { get; }
public int? Max { get; }
[MemberNotNullWhen(true, nameof(Min), nameof(Max))]
public bool IsExact => Min.HasValue && Max.HasValue && Min == Max;
[MemberNotNullWhen(true, nameof(Min), nameof(Max))]
public bool IsRange => Min.HasValue && Max.HasValue && Min != Max;
public bool IsUnbounded => Min == null && Max == null;
public RecipeOutput(int exact)
{
Min = exact;
Max = exact;
}
public RecipeOutput(int min, int max)
{
Min = min;
Max = max;
}
private RecipeOutput(int? min, int? max)
{
Min = min;
Max = max;
}
public static RecipeOutput Any => new(null, null);
}
public struct CompiledRecipe
{
public Recipe RecipeRef;
// public BlueprintId[] InputBlueprints;
public ItemEntry[] ItemEntries;
public bool IsOrdered;
}
public struct ItemEntry
{
public bool RequireAll;
public Tags InputTags;
public Tags ExcludeTags;
public BlueprintId? Blueprint;
}
public static class RecipeCompiler
{
public static CompiledRecipe Compile(Recipe recipe) => new()
{
RecipeRef = recipe,
ItemEntries = BuildEntries(recipe),
// IsOrdered = recipe.InputsOrdered,
};
private static ItemEntry[] BuildEntries(Recipe recipe)
{
var entries = new ItemEntry[recipe.Inputs.Length];
for (var i = 0; i < entries.Length; i++)
{
entries[i] = new ItemEntry
{
RequireAll = recipe.RequireAll[i],
InputTags = recipe.Inputs[i],
ExcludeTags = recipe.Exclude[i],
// Blueprint = recipe.BlueprintIds?[i],
};
}
return entries;
}
}
public record BurnItemRecipe : Recipe
{
public BurnItemRecipe() : base("Burn_item",
BlueprintIds: null,
RequireAll: [false],
Inputs: [new Tags("burnable")],
Exclude: [new Tags("burned")],
RecipeOutput: RecipeOutput.Any,
Action: new RecipeAction("cook"),
InputsOrdered: true)
{
}
public override bool CanProcess(in RecipeContext context)
{
if (context.Items[0].TryGet<Temperature>(out var temp) && context.Items[0].TryGet<BurnableTemp>(out var burnableTemp) && temp > burnableTemp.Temperature)
{
return true;
}
return false;
}
public override RecipeResult Process(in RecipeContext context, ref RecipeResultBuilder builder) => new(BurnItem);
private void BurnItem(RecipeContext context)
{
// context.Entity[0].Remove<BurnableTemp>();
context.Items[0].Add(new BurnedItem(context.Items[0].Get<Temperature>(), "Was Burned as some time thing"));
context.Items[0].Set(context.Items[0].Get<Tags>().WithOut("burnable").With("burned"));
context.Items[0].Set($"Burned_{context.Items[0].Get<Name>().Value}");
if (context.Items[0].Has<Color>())
{
context.Items[0].Set(context.Items[0].Get<Color>() * Colors.Black);
}
else
{
context.Items[0].Add(Colors.Black);
}
}
}
public record OnionSliceRecipe() : Recipe(Name: "Onion_Slice",
BlueprintIds: null,
RequireAll: [false],
Inputs: [new Tags("onion", "sliceable")],
Exclude: [new Tags()],
Action: "slice",
RecipeOutput: new RecipeOutput(2)
)
{
public override bool CanProcess(in RecipeContext context) => true;
public override RecipeResult Process(in RecipeContext context, ref RecipeResultBuilder builder)
{
builder.AddRemove(true);
builder.AddCreate(Slice);
builder.AddCreate(Slice);
return builder.Build();
}
private Entity Slice(in RecipeContext context)
{
Span<Entity> span = stackalloc Entity[1];
var signature = context.World.GetSignature(context.Items[0]);
context.World.Create(span, signature, 1);
PotatoCookRecipe.CopyEntities(context.Items, span, context.World);
span[0].Set(new Name("Sliced " + context.Items[0].Get<Name>().Value));
span[0].Set(new Mass(context.Items[0].Get<Mass>().Value * .5));
span[0].Set(span[0].Get<Tags>().With("sliced"));
return span[0];
}
}
public record PotatoCookRecipe() : Recipe(Name: "Potato_Cook",
BlueprintIds: null,
RequireAll: [false],
Inputs: [new Tags("potato", "raw")],
Exclude: [new Tags()],
InputsOrdered: true,
Action: "cook",
RecipeOutput: new RecipeOutput(1))
{
public override bool CanProcess(in RecipeContext context)
{
if (!(context.Items[0].TryGet<Temperature>(out var temp) && temp.Fahrenheit > 350))
{
return false;
}
return true;
}
public override RecipeResult Process(in RecipeContext context, ref RecipeResultBuilder builder)
{
builder.AddRemove(true);
builder.AddCreate(NewPotato);
return builder.Build();
}
private Entity NewPotato(in RecipeContext context)
{
Span<Entity> span = stackalloc Entity[1];
var signature = context.World.GetSignature(context.Items[0]);
context.World.Create(span, signature, 1);
CopyEntity(context.Items[0], span[0], context.World);
span[0].Set(new Name("Cooked_Potato"));
span[0].Set(context.Items[0].Get<Tags>().With("cooked").WithOut("raw"));
// span[0].Set(context.Entity[0].Get<Temperature>());
if (context.Items[0].Has<Color>())
{
context.Items[0].Set(context.Items[0].Get<Color>() * Colors.Brown);
}
else
{
context.Items[0].Add(Colors.Brown);
}
return span[0];
}
public static void CopyEntities(Span<Entity> from, Span<Entity> to, World world)
{
Debug.Assert(from.Length == to.Length);
for (int i = 0; i < from.Length; i++)
{
CopyEntity(from[i], to[i], world);
}
}
public static void CopyEntity(Entity src, Entity dst, World world)
{
var srcData = world.GetEntityData(src);
var dstData = world.GetEntityData(dst);
var components = srcData.Archetype
.GetChunk(srcData.Slot.ChunkIndex)
.Components;
var componentsDst = dstData.Archetype
.GetChunk(dstData.Slot.ChunkIndex)
.Components;
int srcIndex = srcData.Slot.Index;
int dstIndex = dstData.Slot.Index;
for (int i = 0; i < components.Length; i++)
{
componentsDst[i].SetValue(components[i].GetValue(srcIndex), dstIndex);
}
}
}