Added DataBased Compiled/Provider system
This commit is contained in:
@@ -43,6 +43,7 @@
|
|||||||
<PackageReference Include="MessagePack" Version="3.1.4" />
|
<PackageReference Include="MessagePack" Version="3.1.4" />
|
||||||
<PackageReference Include="NCalc.LambdaCompilation" Version="5.12.0" />
|
<PackageReference Include="NCalc.LambdaCompilation" Version="5.12.0" />
|
||||||
<PackageReference Include="NCalcSync" Version="5.12.0" />
|
<PackageReference Include="NCalcSync" Version="5.12.0" />
|
||||||
|
<PackageReference Include="SharpYaml" Version="3.7.1" />
|
||||||
<PackageReference Include="SjkScripts" Version="1.0.17" />
|
<PackageReference Include="SjkScripts" Version="1.0.17" />
|
||||||
<PackageReference Include="System.IO.Abstractions" Version="22.1.0" />
|
<PackageReference Include="System.IO.Abstractions" Version="22.1.0" />
|
||||||
<PackageReference Include="EnvironmentAbstractions" Version="5.0.0" />
|
<PackageReference Include="EnvironmentAbstractions" Version="5.0.0" />
|
||||||
|
|||||||
13
mods/raw_onion.yaml
Normal file
13
mods/raw_onion.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
Id: raw_onion
|
||||||
|
|
||||||
|
# TypeMapping:
|
||||||
|
# Tags: FoodFactory.Items.Tags
|
||||||
|
Components:
|
||||||
|
Name: Raw Onion
|
||||||
|
Tags: ["onion", "raw", "vegetable", "burnable", "sliceable"]
|
||||||
|
Temperature:
|
||||||
|
Fahrenheit: 71.
|
||||||
|
# Bacteria:
|
||||||
|
# - salmonella: 400.
|
||||||
|
BurnableTemp:
|
||||||
|
Temperature: 477.594
|
||||||
13
mods/raw_potato.yaml
Normal file
13
mods/raw_potato.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
Id: raw_potato
|
||||||
|
|
||||||
|
# TypeMapping:
|
||||||
|
# Tags: FoodFactory.Items.Tags
|
||||||
|
Components:
|
||||||
|
Name: Raw Potato
|
||||||
|
Tags: ["potato", "raw", "vegetable", "burnable"]
|
||||||
|
Temperature:
|
||||||
|
Fahrenheit: 71.
|
||||||
|
# Bacteria:
|
||||||
|
# - salmonella: 400.
|
||||||
|
BurnableTemp:
|
||||||
|
Temperature: 100.
|
||||||
15
mods/raw_red_onion.yaml
Normal file
15
mods/raw_red_onion.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
Id: raw_red_onion
|
||||||
|
|
||||||
|
Extend:
|
||||||
|
- raw_onion
|
||||||
|
# TypeMapping:
|
||||||
|
# Tags: FoodFactory.Items.Tags
|
||||||
|
Components:
|
||||||
|
Name: Raw Red Onion
|
||||||
|
Color:
|
||||||
|
R: 1
|
||||||
|
G: 0
|
||||||
|
B: 0
|
||||||
|
Tags:
|
||||||
|
With: ["red"]
|
||||||
|
Except: ["sliceable"]
|
||||||
@@ -9,6 +9,8 @@ using FoodFactory.Voxel;
|
|||||||
using FoodFactory.Math;
|
using FoodFactory.Math;
|
||||||
using FoodFactory.Items;
|
using FoodFactory.Items;
|
||||||
using FoodFactory.Conveyors;
|
using FoodFactory.Conveyors;
|
||||||
|
using System.Linq;
|
||||||
|
using Arch.Core.Extensions;
|
||||||
|
|
||||||
[Meta(typeof(IAutoNode))]
|
[Meta(typeof(IAutoNode))]
|
||||||
public partial class ItemSpawner : Node3D, IProvide<IBeltPortHost>
|
public partial class ItemSpawner : Node3D, IProvide<IBeltPortHost>
|
||||||
@@ -52,12 +54,25 @@ public partial class ItemSpawner : Node3D, IProvide<IBeltPortHost>
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var itemBlueprint = ItemFactory.GetBlueprint(ItemName);
|
var itemBlueprint = ItemFactory.GetCompiledBlueprint(ItemName);
|
||||||
var dummyItem = new TestItem();
|
var dummyItem = new TestItem();
|
||||||
if (beltPort.CanAccept(dummyItem, 0))
|
if (beltPort.CanAccept(dummyItem, 0))
|
||||||
{
|
{
|
||||||
var ctx = new BlueprintContext() { BluePrintId = new BlueprintId(itemBlueprint), World = World };
|
var ctx = new BlueprintContext() { /*BluePrintId = new BlueprintId(itemBlueprint),*/ World = World };
|
||||||
dummyItem.Item = itemBlueprint.Factory(ctx);
|
|
||||||
|
var newItem = itemBlueprint.CreateEmptyItem(ctx);
|
||||||
|
// ItemFactory.BinderRegistry.Apply(newItem, ctx.World, itemBlueprint);
|
||||||
|
foreach (var providers in itemBlueprint.Providers)
|
||||||
|
{
|
||||||
|
var type = providers[0].GetProviderType();
|
||||||
|
for (int i = 0; i < providers.Length; i++)
|
||||||
|
{
|
||||||
|
ComponentBinder.Apply(type, newItem, providers[i], ctx);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GD.Print(newItem.Get<Tags>());
|
||||||
|
dummyItem.Item = newItem;
|
||||||
if (!beltPort.TryInsert(dummyItem, 0))
|
if (!beltPort.TryInsert(dummyItem, 0))
|
||||||
{
|
{
|
||||||
World.Destroy(dummyItem.Item);//TODO this should not call, but not sure
|
World.Destroy(dummyItem.Item);//TODO this should not call, but not sure
|
||||||
|
|||||||
@@ -86,6 +86,10 @@ public partial class OvenTest : Node3D, IProvide<IBeltPortHost>, IProvide<IVoxel
|
|||||||
resultEntity: out var created
|
resultEntity: out var created
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
|
if (created.Length == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Debug.Assert(created.Length <= 1);
|
Debug.Assert(created.Length <= 1);
|
||||||
|
|
||||||
_itemBeingHeld = created[0];
|
_itemBeingHeld = created[0];
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ public partial class SlicerTest : Node3D, IProvide<IBeltPortHost>, IProvide<IVox
|
|||||||
var port = _insertLogic.GetPorts().FirstOrNone(port => port is BeltPort beltPort && beltPort.PortName == "OutPut").Bind(f => f.GetPortFacing(GridRegistry));
|
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] }, 0))
|
if (port.HasValue(out var v) && v.TryInsert(new TestItem() { Item = sliced[0] }, 0))
|
||||||
{
|
{
|
||||||
GD.Print(sliced[0].Get<Carbohydrates>());
|
|
||||||
sliced.RemoveAt(0);
|
sliced.RemoveAt(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ public readonly struct Tags : IEquatable<Tags>, IReadOnlyCollection<Tag>
|
|||||||
var key = new TagArrayKey(tags);
|
var key = new TagArrayKey(tags);
|
||||||
if (!_internedTags.TryGetValue(key, out var interned))
|
if (!_internedTags.TryGetValue(key, out var interned))
|
||||||
{
|
{
|
||||||
|
interned = _internedTags.Count;
|
||||||
_tags.Add(tags);
|
_tags.Add(tags);
|
||||||
_internedTags[key] = _tags.Count - 1;
|
_internedTags[key] = _tags.Count - 1;
|
||||||
}
|
}
|
||||||
|
|||||||
108
src/Items/IDataCompiler.cs
Normal file
108
src/Items/IDataCompiler.cs
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
namespace FoodFactory.Items;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using Arch.Core;
|
||||||
|
using Arch.Core.Extensions;
|
||||||
|
using FoodFactory.Recipes;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
public interface IDataCompiler
|
||||||
|
{
|
||||||
|
IValueProvider CompileUnTyped(object data);//Use Dicnary and have preset values
|
||||||
|
Type GetCompilerType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IDataCompiler<T> : IDataCompiler
|
||||||
|
{
|
||||||
|
IValueProvider<T> Compile(object data);
|
||||||
|
Type IDataCompiler.GetCompilerType() => typeof(T);
|
||||||
|
IValueProvider IDataCompiler.CompileUnTyped(object data) => Compile(data);
|
||||||
|
}
|
||||||
|
public interface IValueProvider
|
||||||
|
{
|
||||||
|
Type GetProviderType();
|
||||||
|
void Resolve(BlueprintContext context, Entity entity);
|
||||||
|
ProviderMode Mode { get; }
|
||||||
|
}
|
||||||
|
public enum ProviderMode
|
||||||
|
{
|
||||||
|
Static,
|
||||||
|
Modify
|
||||||
|
}
|
||||||
|
public interface IValueProvider<T> : IValueProvider
|
||||||
|
{
|
||||||
|
Type IValueProvider.GetProviderType() => typeof(T);
|
||||||
|
void Resolve(BlueprintContext context, ref T value);
|
||||||
|
void IValueProvider.Resolve(BlueprintContext context, Entity entity) => Resolve(context, ref entity.Get<T>());
|
||||||
|
}
|
||||||
|
public sealed class FactoryCompiledNode<T> : IValueProvider<T>
|
||||||
|
{
|
||||||
|
public delegate void ResolveFunc(in BlueprintContext context, ref T value);
|
||||||
|
private readonly ResolveFunc _factory;
|
||||||
|
|
||||||
|
public ProviderMode Mode => ProviderMode.Modify;
|
||||||
|
|
||||||
|
public FactoryCompiledNode(ResolveFunc factory)
|
||||||
|
{
|
||||||
|
_factory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Resolve(BlueprintContext context, ref T value) => _factory(context, ref value);
|
||||||
|
}
|
||||||
|
public sealed class StaticCompiledNode<T> : IValueProvider<T>
|
||||||
|
{
|
||||||
|
public StaticCompiledNode(T value)
|
||||||
|
{
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Value { get; }
|
||||||
|
|
||||||
|
public void Resolve(BlueprintContext context, ref T value) => value = Value;
|
||||||
|
public ProviderMode Mode => ProviderMode.Static;
|
||||||
|
}
|
||||||
|
public sealed class StaticReflectionCompiledNode<T> : IValueProvider<T> where T : struct
|
||||||
|
{
|
||||||
|
//TODO Make more performance by only having properties of each method, and share use a list using tuples instead.
|
||||||
|
// private readonly Dictionary<string, object> _data;
|
||||||
|
private readonly T _template;
|
||||||
|
|
||||||
|
public StaticReflectionCompiledNode(Dictionary<string, object> itemData)
|
||||||
|
{
|
||||||
|
StructReflection.ApplyValues(ref _template, itemData);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Resolve(BlueprintContext context, ref T value) => value = _template;
|
||||||
|
public ProviderMode Mode => ProviderMode.Static;
|
||||||
|
|
||||||
|
}
|
||||||
|
public sealed class RuntimeReflectionCompiledNode<T> : IValueProvider<T> where T : struct
|
||||||
|
{
|
||||||
|
//TODO Make more performance by only having properties of each method, and share use a list using tuples instead.
|
||||||
|
private readonly Dictionary<string, object> _data;
|
||||||
|
// private readonly T _template;
|
||||||
|
|
||||||
|
public RuntimeReflectionCompiledNode(Dictionary<string, object> itemData)
|
||||||
|
{
|
||||||
|
_data = itemData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Resolve(BlueprintContext context, ref T value) => StructReflection.ApplyValues(ref value, _data);
|
||||||
|
public ProviderMode Mode => ProviderMode.Modify;
|
||||||
|
|
||||||
|
}
|
||||||
|
public class CompiledBlueprint
|
||||||
|
{
|
||||||
|
public string Id { get; init; }
|
||||||
|
public Tags Traits { get; set; }
|
||||||
|
public IValueProvider[][] Providers = [];
|
||||||
|
public Signature Signature;
|
||||||
|
public Entity CreateEmptyItem(BlueprintContext blueprintContext) => blueprintContext.World.Create(Signature);
|
||||||
|
|
||||||
|
}
|
||||||
1
src/Items/IDataCompiler.cs.uid
Normal file
1
src/Items/IDataCompiler.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://caur7nt65ia2o
|
||||||
@@ -36,6 +36,7 @@ public class TestItem() : IBeltItem, IBeltItemData<Entity>
|
|||||||
public Node3D CreateItemVisual()
|
public Node3D CreateItemVisual()
|
||||||
{
|
{
|
||||||
Node3D node;
|
Node3D node;
|
||||||
|
var tags = Item.Get<Tags>().ToArray();
|
||||||
if (Item.Get<Tags>().Contains(TagRegistry.GetTag("potato")))
|
if (Item.Get<Tags>().Contains(TagRegistry.GetTag("potato")))
|
||||||
{
|
{
|
||||||
node = PotatoScene.Instantiate<Node3D>();
|
node = PotatoScene.Instantiate<Node3D>();
|
||||||
@@ -55,7 +56,7 @@ public class TestItem() : IBeltItem, IBeltItemData<Entity>
|
|||||||
node.GetChildren().OfType<Node3D>().ToList().ForEach(i => i.Scale *= new Vector3(.2f, .2f, .2f));
|
node.GetChildren().OfType<Node3D>().ToList().ForEach(i => i.Scale *= new Vector3(.2f, .2f, .2f));
|
||||||
if (Item.TryGet<Color>(out var color))
|
if (Item.TryGet<Color>(out var color))
|
||||||
{
|
{
|
||||||
node.GetChildren().OfType<MeshInstance3D>().FirstOrNone().IfSome(some => some.SetSurfaceOverrideMaterial(0, new StandardMaterial3D() { AlbedoColor = Item.TryGet<Color>(out var color) ? color : Colors.White }));
|
node.GetChildren().OfType<MeshInstance3D>().FirstOrNone().IfSome(some => some.SetSurfaceOverrideMaterial(0, new StandardMaterial3D() { AlbedoColor = color }));
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
// return new MeshInstance3D() { Mesh = new BoxMesh() { Size = new(.1f, .1f, .1f) }, MaterialOverride = new StandardMaterial3D() { AlbedoColor = Item.TryGet<Color>(out var color) ? color : Colors.White } };
|
// return new MeshInstance3D() { Mesh = new BoxMesh() { Size = new(.1f, .1f, .1f) }, MaterialOverride = new StandardMaterial3D() { AlbedoColor = Item.TryGet<Color>(out var color) ? color : Colors.White } };
|
||||||
|
|||||||
79
src/Items/ItemData.cs
Normal file
79
src/Items/ItemData.cs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
namespace FoodFactory.Items;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using FoodFactory.Math;
|
||||||
|
using FoodFactory.Recipes;
|
||||||
|
using SharpYaml;
|
||||||
|
using SharpYaml.Serialization;
|
||||||
|
|
||||||
|
public class ItemData
|
||||||
|
{
|
||||||
|
public string Id { get; set; } = "";
|
||||||
|
public string[] Extend { get; set; } = [];
|
||||||
|
[YamlConverter(typeof(ComponentsPatcherConverter))]
|
||||||
|
public Dictionary<string, object> Components { get; set; } = [];
|
||||||
|
public HashSet<string> Remove { get; set; } = [];
|
||||||
|
// public DataNode GetComponent(Type type)
|
||||||
|
// {
|
||||||
|
// if (!Components.TryGetValue(type.Name, out var value))
|
||||||
|
// {
|
||||||
|
// throw new System.Exception();
|
||||||
|
// }
|
||||||
|
// if (value is Dictionary<string, object> thing)
|
||||||
|
// {
|
||||||
|
// return new DataNode(thing);
|
||||||
|
// }
|
||||||
|
// return new DataNode(new() { ["Value"] = value });
|
||||||
|
// }
|
||||||
|
// public DataNode GetComponent<T>() where T : struct => GetComponent(typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ComponentsPatcherConverter : YamlConverter<Dictionary<string, object>>
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, Type> _componentsTypes = new(){
|
||||||
|
[nameof(Temperature)] = typeof(IValueProvider<Temperature>),
|
||||||
|
// [nameof(Tags)] = typeof(IValueProvider<Tags>),
|
||||||
|
// [nameof(Name)] = typeof(IValueProvider<Name>),
|
||||||
|
// [nameof(Mass)] = typeof(IValueProvider<Mass>),
|
||||||
|
// [nameof(Godot.Color)] = typeof(IValueProvider<Godot.Color>),
|
||||||
|
// [nameof(BurnableTemp)] = typeof(IValueProvider<BurnableTemp>),
|
||||||
|
};
|
||||||
|
|
||||||
|
// public ComponentsPatcherConverter(Dictionary<string, Type> componentsTypes)
|
||||||
|
// {
|
||||||
|
// _componentsTypes = componentsTypes;
|
||||||
|
// }
|
||||||
|
|
||||||
|
public override Dictionary<string, object>? Read(YamlReader reader)
|
||||||
|
{
|
||||||
|
var dict = new Dictionary<string,object>();
|
||||||
|
if (reader.TokenType == YamlTokenType.StartMapping)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
}
|
||||||
|
while (reader.TokenType != YamlTokenType.EndMapping)
|
||||||
|
{
|
||||||
|
var key = reader.ScalarValue;
|
||||||
|
reader.Read();
|
||||||
|
var d = reader.ScalarValue;
|
||||||
|
|
||||||
|
if (!_componentsTypes.TryGetValue(key, out var type))
|
||||||
|
{
|
||||||
|
type = typeof(object);
|
||||||
|
}
|
||||||
|
if (!reader.TryGetCustomConverter(type, out var converter)){
|
||||||
|
converter = reader.GetConverter(type);
|
||||||
|
}
|
||||||
|
object data;
|
||||||
|
data = converter.Read(reader, type);
|
||||||
|
|
||||||
|
// reader.Read();
|
||||||
|
dict[key] = data;
|
||||||
|
|
||||||
|
}
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(YamlWriter writer, Dictionary<string, object> value) => throw new NotImplementedException();
|
||||||
|
}
|
||||||
1
src/Items/ItemData.cs.uid
Normal file
1
src/Items/ItemData.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://ymjkr070i83c
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
namespace FoodFactory;
|
namespace FoodFactory;
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using Arch.Core;
|
using Arch.Core;
|
||||||
using Arch.Core.Extensions;
|
using Arch.Core.Extensions;
|
||||||
using Arch.Core.Utils;
|
using Arch.Core.Utils;
|
||||||
@@ -11,7 +14,10 @@ using Chickensoft.Introspection;
|
|||||||
using Chickensoft.SaveFileBuilder;
|
using Chickensoft.SaveFileBuilder;
|
||||||
using FoodFactory.Items;
|
using FoodFactory.Items;
|
||||||
using FoodFactory.Math;
|
using FoodFactory.Math;
|
||||||
|
using FoodFactory.Recipes;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using SharpYaml;
|
||||||
|
using SharpYaml.Serialization;
|
||||||
using Utf8Json;
|
using Utf8Json;
|
||||||
|
|
||||||
public class Test
|
public class Test
|
||||||
@@ -63,7 +69,86 @@ public class Test
|
|||||||
var worldJson = serializer.ToJson(world);
|
var worldJson = serializer.ToJson(world);
|
||||||
// GD.Print(worldJson);
|
// GD.Print(worldJson);
|
||||||
var otherWorld = serializer.FromJson(worldJson);
|
var otherWorld = serializer.FromJson(worldJson);
|
||||||
|
foreach (var item in ComponentRegistry.TypeToComponentType.Keys)
|
||||||
|
{
|
||||||
|
if (item is null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
GD.Print(item.Name);
|
||||||
|
GD.Print(item.Namespace);
|
||||||
|
GD.Print(item.FullName);
|
||||||
|
}
|
||||||
|
string yaml = @"
|
||||||
|
Id: potato_raw
|
||||||
|
|
||||||
|
# TypeMapping:
|
||||||
|
# Tags: FoodFactory.Items.Tags
|
||||||
|
Components:
|
||||||
|
Name: Raw Potato
|
||||||
|
Tags:
|
||||||
|
- potato
|
||||||
|
- vegetable
|
||||||
|
- raw
|
||||||
|
- burnable
|
||||||
|
Temperature:
|
||||||
|
-
|
||||||
|
$type: temperature
|
||||||
|
Kelvin : 500.
|
||||||
|
|
||||||
|
Bacteria:
|
||||||
|
- salmonella: !!float 400.
|
||||||
|
BurnableTemp: !!float 400.
|
||||||
|
";
|
||||||
|
var options = new YamlSerializerOptions()
|
||||||
|
{
|
||||||
|
// Converters = [new Recipes.DataNodeSerlicer()]
|
||||||
|
// PolymorphismOptions = new YamlPolymorphismOptions
|
||||||
|
// {
|
||||||
|
// DerivedTypeMappings =
|
||||||
|
// {
|
||||||
|
// [typeof(DataNode)] =
|
||||||
|
// [
|
||||||
|
// new YamlDerivedType(typeof(SequenceNode), "sequence"){Tag = "!sequence"},
|
||||||
|
// new YamlDerivedType(typeof(MappingNode), "mapping"){Tag = "!mapping"},
|
||||||
|
// new YamlDerivedType(typeof(ValueNode), "value"){Tag = "!value"}
|
||||||
|
// ],
|
||||||
|
// [typeof(object)] =
|
||||||
|
// [
|
||||||
|
// new YamlDerivedType(typeof(Temperature), "temperature") { Tag = "!temperature"}
|
||||||
|
// ]
|
||||||
|
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
};
|
||||||
|
// var test = YamlSerializer.Serialize(new ItemData()
|
||||||
|
// {
|
||||||
|
// Id = "potato_raw",
|
||||||
|
// Components = { [nameof(Name)] = new ValueNode("Raw Potato") ,
|
||||||
|
// [nameof(Temperature)] = new ValueNode(100f),
|
||||||
|
// [nameof(Tags)] = new SequenceNode([new ValueNode("potato"), new ValueNode("vegetable"), new ValueNode("food"),new ValueNode("raw"),new ValueNode("burnable")])}
|
||||||
|
// }, options);
|
||||||
|
// GD.Print(test);
|
||||||
|
var result = YamlSerializer.Deserialize<ItemData>(yaml,options);
|
||||||
|
var names = result.Components.Keys.ToArray();
|
||||||
|
var list3 = new List<Type>();
|
||||||
|
foreach (var item in Assembly.GetAssembly(typeof(Name)).GetTypes())
|
||||||
|
{
|
||||||
|
if (!names.Contains(item.Name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
list3.Add(item);
|
||||||
|
}
|
||||||
|
// var types = names.Select(f => Type.GetType(f)).ToArray();
|
||||||
|
// var names2 = new Type[]{typeof(Name), typeof(Temperature), typeof(Tags)};
|
||||||
|
var componentTypes = list3.Select(Component.GetComponentType).ToArray();
|
||||||
|
|
||||||
|
Entity entite = world.Create(componentTypes);
|
||||||
|
// var reg = new ComponentBinderRegistry();
|
||||||
|
// reg.Add(new TemperatureBinder());
|
||||||
|
// reg.Apply(entite,world,result);
|
||||||
|
// GD.Print(string.Join(',',entite.GetAllComponents()));
|
||||||
// ISaveChunk<GameData> saveChunk =new SaveChunk<GameData>(
|
// ISaveChunk<GameData> saveChunk =new SaveChunk<GameData>(
|
||||||
// chunk =>
|
// chunk =>
|
||||||
// {
|
// {
|
||||||
|
|||||||
96
src/Items/StructReflection.cs
Normal file
96
src/Items/StructReflection.cs
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
namespace FoodFactory.Items;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
public static class StructReflection
|
||||||
|
{
|
||||||
|
public static void ApplyValues<T>(
|
||||||
|
ref T target,
|
||||||
|
Dictionary<string, object> values)
|
||||||
|
where T : struct
|
||||||
|
{
|
||||||
|
object boxed = target;
|
||||||
|
|
||||||
|
Type type = typeof(T);
|
||||||
|
|
||||||
|
foreach (var kvp in values)
|
||||||
|
{
|
||||||
|
string name = kvp.Key;
|
||||||
|
object value = kvp.Value;
|
||||||
|
|
||||||
|
// Try property first
|
||||||
|
var prop = type.GetProperty(
|
||||||
|
name,
|
||||||
|
BindingFlags.Public |
|
||||||
|
BindingFlags.Instance);
|
||||||
|
|
||||||
|
if (prop != null && prop.CanWrite)
|
||||||
|
{
|
||||||
|
object converted = ConvertValue(value, prop.PropertyType);
|
||||||
|
prop.SetValue(boxed, converted);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then field
|
||||||
|
var field = type.GetField(
|
||||||
|
name,
|
||||||
|
BindingFlags.Public |
|
||||||
|
BindingFlags.Instance);
|
||||||
|
|
||||||
|
if (field != null)
|
||||||
|
{
|
||||||
|
object converted = ConvertValue(value, field.FieldType);
|
||||||
|
field.SetValue(boxed, converted);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception(
|
||||||
|
$"Member '{name}' not found on {type.Name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
target = (T)boxed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object ConvertValue(object value, Type targetType)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
return null!;
|
||||||
|
|
||||||
|
Type valueType = value.GetType();
|
||||||
|
|
||||||
|
if (targetType.IsAssignableFrom(valueType))
|
||||||
|
return value;
|
||||||
|
|
||||||
|
return Convert.ChangeType(value, targetType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
static RefSetter<T, TValue> CreateFieldSetter<T, TValue>(FieldInfo field)
|
||||||
|
{
|
||||||
|
var target = Expression.Parameter(typeof(T).MakeByRefType(), "target");
|
||||||
|
var value = Expression.Parameter(typeof(TValue), "value");
|
||||||
|
|
||||||
|
var fieldExp = Expression.Field(target, field);
|
||||||
|
|
||||||
|
var assign = Expression.Assign(fieldExp, value);
|
||||||
|
|
||||||
|
return Expression.Lambda<RefSetter<T, TValue>>(
|
||||||
|
assign,
|
||||||
|
target,
|
||||||
|
value
|
||||||
|
).Compile();
|
||||||
|
}
|
||||||
|
static RefSetter<T, TValue> CreatePropertySetter<T, TValue>(PropertyInfo prop)
|
||||||
|
{
|
||||||
|
var target = Expression.Parameter(typeof(T).MakeByRefType(), "target");
|
||||||
|
var value = Expression.Parameter(typeof(TValue), "value");
|
||||||
|
|
||||||
|
var call = Expression.Call(target, prop.SetMethod!, value);
|
||||||
|
|
||||||
|
return Expression
|
||||||
|
.Lambda<RefSetter<T, TValue>>(call, target, value)
|
||||||
|
.Compile();
|
||||||
|
}
|
||||||
|
*/
|
||||||
1
src/Items/StructReflection.cs.uid
Normal file
1
src/Items/StructReflection.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://bpw4csgtk7qwf
|
||||||
@@ -32,7 +32,21 @@ public enum TemperatureUnit
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Fahrenheit
|
Fahrenheit
|
||||||
}
|
}
|
||||||
|
public record struct Fahrenheit(double Value)
|
||||||
|
{
|
||||||
|
public static implicit operator Fahrenheit(double value) => new(value);
|
||||||
|
public static implicit operator Temperature(Fahrenheit value) => new(value);
|
||||||
|
}
|
||||||
|
public record struct Celsius(double Value)
|
||||||
|
{
|
||||||
|
public static implicit operator Celsius(double value) => new(value);
|
||||||
|
public static implicit operator Temperature(Celsius value) => new(value);
|
||||||
|
}
|
||||||
|
public record struct Kelvin(double Value)
|
||||||
|
{
|
||||||
|
public static implicit operator Kelvin(double value) => new(value);
|
||||||
|
public static implicit operator Temperature(Kelvin value) => new(value);
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A temperature value.
|
/// A temperature value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -53,7 +67,18 @@ public struct Temperature : IFormattable, IComparable,
|
|||||||
/// <param name="kelvin">The value of the temperature.</param>
|
/// <param name="kelvin">The value of the temperature.</param>
|
||||||
public Temperature(double kelvin) : this() { _kelvin = kelvin; }
|
public Temperature(double kelvin) : this() { _kelvin = kelvin; }
|
||||||
|
|
||||||
|
public Temperature(Fahrenheit fahrenheit)
|
||||||
|
{
|
||||||
|
_kelvin = FahrenheitToKelvin(fahrenheit.Value);
|
||||||
|
}
|
||||||
|
public Temperature(Celsius celsius)
|
||||||
|
{
|
||||||
|
_kelvin = CelsiusToKelvin(celsius.Value);
|
||||||
|
}
|
||||||
|
public Temperature(Kelvin kelvin)
|
||||||
|
{
|
||||||
|
_kelvin = kelvin.Value;
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new temperature with the specified value in the
|
/// Creates a new temperature with the specified value in the
|
||||||
/// specified unit of measurement.
|
/// specified unit of measurement.
|
||||||
@@ -90,6 +115,11 @@ public struct Temperature : IFormattable, IComparable,
|
|||||||
|
|
||||||
set => _kelvin = value;
|
set => _kelvin = value;
|
||||||
}
|
}
|
||||||
|
public Kelvin KelvinMeasurement
|
||||||
|
{
|
||||||
|
readonly get => _kelvin;
|
||||||
|
set => _kelvin = value.Value;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the temperature value in Celsius.
|
/// Gets or sets the temperature value in Celsius.
|
||||||
@@ -98,6 +128,11 @@ public struct Temperature : IFormattable, IComparable,
|
|||||||
{
|
{
|
||||||
readonly get => KelvinToCelsius(_kelvin); set => _kelvin = CelsiusToKelvin(value);
|
readonly get => KelvinToCelsius(_kelvin); set => _kelvin = CelsiusToKelvin(value);
|
||||||
}
|
}
|
||||||
|
public Celsius CelsiusMeasurement
|
||||||
|
{
|
||||||
|
readonly get => KelvinToCelsius(_kelvin);
|
||||||
|
set => _kelvin = CelsiusToKelvin(value.Value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the temperature value in Fahrenheit.
|
/// Gets or sets the temperature value in Fahrenheit.
|
||||||
@@ -106,6 +141,11 @@ public struct Temperature : IFormattable, IComparable,
|
|||||||
{
|
{
|
||||||
readonly get => KelvinToFahrenheit(_kelvin); set => _kelvin = FahrenheitToKelvin(value);
|
readonly get => KelvinToFahrenheit(_kelvin); set => _kelvin = FahrenheitToKelvin(value);
|
||||||
}
|
}
|
||||||
|
public Fahrenheit FahrenheitMeasurement
|
||||||
|
{
|
||||||
|
readonly get => KelvinToFahrenheit(_kelvin);
|
||||||
|
set => _kelvin = FahrenheitToKelvin(value.Value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the temperature value in the specified unit of measurement.
|
/// Gets the temperature value in the specified unit of measurement.
|
||||||
|
|||||||
@@ -2,21 +2,201 @@ namespace FoodFactory.Recipes;
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using Arch.Core;
|
using Arch.Core;
|
||||||
|
using Arch.Core.Extensions;
|
||||||
using FoodFactory.Items;
|
using FoodFactory.Items;
|
||||||
using FoodFactory.Math;
|
using FoodFactory.Math;
|
||||||
using FoodFactory.Voxel;
|
using FoodFactory.Voxel;
|
||||||
|
using Godot;
|
||||||
|
using SharpYaml;
|
||||||
|
using SharpYaml.Model;
|
||||||
|
using SharpYaml.Serialization;
|
||||||
|
using SJK.Functional;
|
||||||
|
using Utf8Json;
|
||||||
|
|
||||||
public interface IBlueprintManger
|
public interface IBlueprintManger
|
||||||
{
|
{
|
||||||
Blueprint GetBlueprint(string name);
|
Blueprint GetBlueprint(string name);
|
||||||
|
CompiledBlueprint GetCompiledBlueprint(string name);
|
||||||
|
// ComponentBinderRegistry BinderRegistry { get; }
|
||||||
}
|
}
|
||||||
public class BlueprintManger : IBlueprintManger
|
public class BlueprintManger : IBlueprintManger
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, Blueprint> _bluePrints = [];
|
// private readonly Dictionary<string, Blueprint> _bluePrints = [];
|
||||||
|
// public readonly ComponentBinderRegistry ComponentBinder = new();
|
||||||
|
public readonly Dictionary<string, Blueprint> Blueprints = [];
|
||||||
|
public readonly Dictionary<string, CompiledBlueprint> CompiledBlueprints = [];
|
||||||
|
public readonly Dictionary<string, IDataCompiler> Providers = [];
|
||||||
|
|
||||||
|
// public ComponentBinderRegistry BinderRegistry { get; }
|
||||||
|
|
||||||
|
public BlueprintManger()
|
||||||
|
{
|
||||||
|
// BinderRegistry = new ComponentBinderRegistry();
|
||||||
|
|
||||||
|
// BinderRegistry.Add(new ComponentBinder<Temperature>());
|
||||||
|
// BinderRegistry.Add(new ComponentBinder<Tags>());
|
||||||
|
// BinderRegistry.Add(new ComponentBinder<BurnableTemp>());
|
||||||
|
// BinderRegistry.Add(new ComponentBinder<Bacteria>());
|
||||||
|
// BinderRegistry.Add(new ComponentBinder<Mass>());
|
||||||
|
// BinderRegistry.Add(new ComponentBinder<Carbohydrates>());
|
||||||
|
// BinderRegistry.Add(new ComponentBinder<Name>());
|
||||||
|
|
||||||
|
// Providers.Add(nameof(Temperature), new TemperatureCompiler());
|
||||||
|
Providers.Add(nameof(Tags), new TagsCompiler());
|
||||||
|
Providers.Add(nameof(Name), new NameCompiler());
|
||||||
|
Providers.Add(nameof(Mass), new DefaultCompiler<Mass>());
|
||||||
|
Providers.Add(nameof(Color), new DefaultCompiler<Color>());
|
||||||
|
Providers.Add(nameof(BurnableTemp), new DefaultConverterCompiler<BurnableTemp>(){Converter = data =>
|
||||||
|
{
|
||||||
|
if (data is Dictionary<string,object> dict){
|
||||||
|
if (dict.TryGetValue(nameof(BurnableTemp.Temperature), out var value))
|
||||||
|
{
|
||||||
|
dict[nameof(BurnableTemp.Temperature)] = new Temperature((double)value);
|
||||||
|
}
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var root = "/home/ronnie/Documents/Godot/Projects/ChickenGameTest/mods";
|
||||||
|
var dir = DirAccess.Open(root);
|
||||||
|
var cache = new Dictionary<string, CompiledBlueprint>();
|
||||||
|
var types = Assembly.GetAssembly(typeof(Name)).GetTypes();//Temperary mesure
|
||||||
|
var itemDatas = new List<ItemData>();
|
||||||
|
|
||||||
|
var options = new YamlSerializerOptions()
|
||||||
|
{
|
||||||
|
Converters = [
|
||||||
|
// new ComponentsPatcherConverter(
|
||||||
|
// new(){
|
||||||
|
// [nameof(Temperature)] = typeof(IValueProvider<Temperature>),
|
||||||
|
// [nameof(Tags)] = typeof(IValueProvider<Tags>),
|
||||||
|
// [nameof(Name)] = typeof(IValueProvider<Name>),
|
||||||
|
// [nameof(Mass)] = typeof(IValueProvider<Mass>),
|
||||||
|
// [nameof(Color)] = typeof(IValueProvider<Color>),
|
||||||
|
// [nameof(BurnableTemp)] = typeof(IValueProvider<BurnableTemp>),
|
||||||
|
// }
|
||||||
|
// ),
|
||||||
|
new TemperatureCompiler(),
|
||||||
|
|
||||||
|
]
|
||||||
|
};
|
||||||
|
foreach (var item in dir.GetFiles())
|
||||||
|
{
|
||||||
|
if (item.EndsWith(".yaml"))
|
||||||
|
{
|
||||||
|
var file = FileAccess.Open(dir.GetCurrentDir() + "/" + item, FileAccess.ModeFlags.Read);
|
||||||
|
var data = YamlSerializer.Deserialize<ItemData>(file.GetAsText(),options);
|
||||||
|
itemDatas.Add(data);
|
||||||
|
// var compiledBlueprint = new CompiledBlueprint
|
||||||
|
// {
|
||||||
|
// // Id = data.Id,
|
||||||
|
// // Signature = new Signature([typeof(BlueprintId), .. types.Where(f => data.Components.ContainsKey(f.Name)).Select(Component.GetComponentType)]),
|
||||||
|
// // Providers = new IValueProvider[data.Components.Count]
|
||||||
|
// // };
|
||||||
|
// // var i = 0;
|
||||||
|
// // foreach (var item2 in data.Components)
|
||||||
|
// // {
|
||||||
|
// // var compiler = Providers[item2.Key];
|
||||||
|
// // var compiled = compiler.CompileUnTyped(item2.Value);
|
||||||
|
// // compiledBlueprint.Providers[i] = compiled;
|
||||||
|
// // i++;
|
||||||
|
// // }
|
||||||
|
// CompiledBlueprints.Add(compiledBlueprint.Id, compiledBlueprint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CompiledBlueprints = LoadBluprints([.. itemDatas]);
|
||||||
|
}
|
||||||
|
private Dictionary<string, CompiledBlueprint> LoadBluprints(ItemData[] all, Dictionary<string, CompiledBlueprint>? existing = null)
|
||||||
|
{
|
||||||
|
var completed = existing is not null ? new(existing) : new Dictionary<string,CompiledBlueprint>();
|
||||||
|
var queue = new Queue<ItemData>(all);
|
||||||
|
while (queue.Any())
|
||||||
|
{
|
||||||
|
reset:
|
||||||
|
var item = queue.Dequeue();
|
||||||
|
var sources = new List<CompiledBlueprint>();
|
||||||
|
foreach (var c in item.Extend)
|
||||||
|
{
|
||||||
|
if (!completed.ContainsKey(c))
|
||||||
|
{
|
||||||
|
queue.Enqueue(item);
|
||||||
|
goto reset;
|
||||||
|
}
|
||||||
|
sources.Add(completed[c]);
|
||||||
|
}
|
||||||
|
var providers = new Dictionary<Type, List<IValueProvider>>();//TODO Make Blupritns able to hold muiple providers in a array for cases taht build off previouse providers
|
||||||
|
foreach (var blueprint in sources)
|
||||||
|
{
|
||||||
|
foreach (var provider in blueprint.Providers)
|
||||||
|
{
|
||||||
|
if (item.Remove.Contains(provider[0].GetProviderType().Name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!providers.TryGetValue(provider[0].GetProviderType(), out var providersList))
|
||||||
|
{
|
||||||
|
providers[provider[0].GetProviderType()] = providersList = new();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < provider.Length; i++)
|
||||||
|
{
|
||||||
|
if (provider[i].Mode == ProviderMode.Static)
|
||||||
|
{
|
||||||
|
providersList.Clear();
|
||||||
|
providersList.Add(provider[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var component in item.Components)
|
||||||
|
{
|
||||||
|
var compiler = Providers[component.Key];
|
||||||
|
var compiledProvider = compiler.CompileUnTyped(component.Value);
|
||||||
|
if (!providers.TryGetValue(compiledProvider.GetProviderType(), out var providersList))
|
||||||
|
{
|
||||||
|
providers[compiledProvider.GetProviderType()] = providersList = new();
|
||||||
|
}
|
||||||
|
providersList.Add(compiledProvider);
|
||||||
|
}
|
||||||
|
var compiled = new CompiledBlueprint()
|
||||||
|
{
|
||||||
|
Id = item.Id,
|
||||||
|
// Traits = new Tags([.. item.Components.Keys]),//TODO need a way for recipies to look in each 'parent/extend' for getting recipes, either iterating each parent pool(recipe behing only in max shared, or each buckert container a copy for each parent)
|
||||||
|
Signature = [.. providers.Keys],
|
||||||
|
Providers = [.. providers.Values.Select(list => list.ToArray())],
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
ex Food-> onion -> red onion
|
||||||
|
if onion id, then onion and red onion bucket have a recipe
|
||||||
|
of for each trait, iterate each bucket, starting from spefic, to top.
|
||||||
|
*/
|
||||||
|
completed.Add(item.Id, compiled);
|
||||||
|
}
|
||||||
|
return completed;
|
||||||
|
}
|
||||||
|
public CompiledBlueprint? GetCompiledBlueprint(string id)
|
||||||
|
|
||||||
|
{
|
||||||
|
if (CompiledBlueprints.TryGetValue(id, out var compiledBlueprint))
|
||||||
|
{
|
||||||
|
return compiledBlueprint;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
public Blueprint GetBlueprint(string name)
|
public Blueprint GetBlueprint(string name)
|
||||||
{
|
{
|
||||||
if (!_bluePrints.TryGetValue(name, out var blueprint))
|
|
||||||
|
// throw new NotImplementedException();
|
||||||
|
if (!Blueprints.TryGetValue(name, out var blueprint))
|
||||||
{
|
{
|
||||||
//TODO this is where this should look through mods/base game
|
//TODO this is where this should look through mods/base game
|
||||||
if (name == "Potato")
|
if (name == "Potato")
|
||||||
@@ -47,6 +227,10 @@ public class BlueprintManger : IBlueprintManger
|
|||||||
return blueprint;
|
return blueprint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// public record Blueprint(string Name, Func<BlueprintContext, Entity> Factory)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// }
|
||||||
public record Blueprint(string Name, Func<BlueprintContext, Entity> Factory)
|
public record Blueprint(string Name, Func<BlueprintContext, Entity> Factory)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -56,4 +240,306 @@ public struct BlueprintContext
|
|||||||
{
|
{
|
||||||
public World World;
|
public World World;
|
||||||
public BlueprintId BluePrintId;
|
public BlueprintId BluePrintId;
|
||||||
|
public object PlaceHolderApi;
|
||||||
}
|
}
|
||||||
|
// public interface IComponentBinder
|
||||||
|
// {
|
||||||
|
// ComponentType ComponentType { get; }
|
||||||
|
// void ApplyUntyped(
|
||||||
|
// Entity existing,
|
||||||
|
// IValueProvider data,
|
||||||
|
// BlueprintContext context);
|
||||||
|
// void ApplyUntyped(
|
||||||
|
// Span<Entity> existing,
|
||||||
|
// IValueProvider data,
|
||||||
|
// BlueprintContext context);
|
||||||
|
// }
|
||||||
|
// public class ComponentBinder<T> : IComponentBinder where T : struct
|
||||||
|
// {
|
||||||
|
// public ComponentType ComponentType => Component<T>.ComponentType;
|
||||||
|
|
||||||
|
// public void ApplyUntyped(
|
||||||
|
// Entity existing,
|
||||||
|
// IValueProvider data,
|
||||||
|
// BlueprintContext context)
|
||||||
|
// {
|
||||||
|
// if (data is IValueProvider<T> dataT)
|
||||||
|
// {
|
||||||
|
// ref var component = ref context.World.Get<T>(existing);
|
||||||
|
// Apply(ref component, dataT, context);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// throw new System.Exception();
|
||||||
|
// }
|
||||||
|
// public void ApplyUntyped(Span<Entity> existing, IValueProvider data, BlueprintContext context)
|
||||||
|
// {
|
||||||
|
// if (data is not IValueProvider<T> dataT)
|
||||||
|
// {
|
||||||
|
// throw new System.Exception();
|
||||||
|
// }
|
||||||
|
// for (int i = 0; i < existing.Length; i++)
|
||||||
|
// {
|
||||||
|
// Apply(ref existing[i].Get<T>(), dataT, context);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void Apply(
|
||||||
|
// ref T existing,
|
||||||
|
// IValueProvider<T> data,
|
||||||
|
// BlueprintContext context) => data.Resolve(context, ref existing);
|
||||||
|
// }
|
||||||
|
// public class DefaultBinder<T> : ComponentBinder<T> where T : struct
|
||||||
|
// {
|
||||||
|
// public override void Apply(ref T existing, IValueProvider<T> data, BlueprintContext context);
|
||||||
|
|
||||||
|
// }
|
||||||
|
// public class TemperatureBinder : ComponentBinder<Temperature>
|
||||||
|
// {
|
||||||
|
// public override void Apply(ref Temperature existing, IValueProvider<Temperature> data, BlueprintContext context) => data.Resolve(context, ref existing);
|
||||||
|
|
||||||
|
// }
|
||||||
|
public sealed class TemperatureCompiler : YamlConverter<IValueProvider<Temperature>>//, IDataCompiler<Temperature>
|
||||||
|
{
|
||||||
|
// public IValueProvider<Temperature> Compile(object data)
|
||||||
|
// {
|
||||||
|
// if (data is IValueProvider<Temperature> t)
|
||||||
|
// {
|
||||||
|
// return t;
|
||||||
|
// }
|
||||||
|
// if (data is string says)
|
||||||
|
// {
|
||||||
|
// if (says == "ambient")
|
||||||
|
// {
|
||||||
|
// return new AmbientTemperatureProvider();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (data is float f)
|
||||||
|
// {
|
||||||
|
// return new StaticCompiledNode<Temperature>(new Temperature(f));
|
||||||
|
// }
|
||||||
|
// if (data is double d)
|
||||||
|
// {
|
||||||
|
// return new StaticCompiledNode<Temperature>(new Temperature(d));
|
||||||
|
// }
|
||||||
|
// if (data is Dictionary<string, object> dict)
|
||||||
|
// {
|
||||||
|
// return new StaticReflectionCompiledNode<Temperature>(dict);
|
||||||
|
|
||||||
|
// }
|
||||||
|
// throw new NotSupportedException();
|
||||||
|
// }
|
||||||
|
|
||||||
|
public override IValueProvider<Temperature>? Read(YamlReader reader)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == YamlTokenType.Scalar)
|
||||||
|
{
|
||||||
|
var value = reader.ScalarValue;
|
||||||
|
reader.Read();
|
||||||
|
if (value == "ambient")
|
||||||
|
{
|
||||||
|
return new AmbientTemperatureProvider();
|
||||||
|
}
|
||||||
|
if (float.TryParse(value, out var f))
|
||||||
|
{
|
||||||
|
return new StaticCompiledNode<Temperature>(new Temperature(f));
|
||||||
|
}
|
||||||
|
if (double.TryParse(value, out var d))
|
||||||
|
{
|
||||||
|
return new StaticCompiledNode<Temperature>(new Temperature(f));
|
||||||
|
}
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
if (reader.TokenType == YamlTokenType.StartMapping)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
IValueProvider<Temperature>? provider = null;
|
||||||
|
while (reader.TokenType != YamlTokenType.EndMapping)
|
||||||
|
{
|
||||||
|
var key = reader.ScalarValue;
|
||||||
|
reader.Read();
|
||||||
|
if (key == nameof(Fahrenheit))
|
||||||
|
{
|
||||||
|
provider = new StaticCompiledNode<Temperature>(new Fahrenheit(float.Parse(reader.ScalarValue)));
|
||||||
|
}
|
||||||
|
reader.Read();
|
||||||
|
}
|
||||||
|
return provider??throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(YamlWriter writer, IValueProvider<Temperature> value) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public sealed class AmbientTemperatureProvider : IValueProvider<Temperature>
|
||||||
|
{
|
||||||
|
public ProviderMode Mode => ProviderMode.Static;
|
||||||
|
|
||||||
|
public void Resolve(BlueprintContext context, ref Temperature value)
|
||||||
|
{
|
||||||
|
value.Kelvin = (float)context.PlaceHolderApi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public sealed class DefaultCompiler<T> : IDataCompiler<T> where T : struct
|
||||||
|
{
|
||||||
|
|
||||||
|
public IValueProvider<T> Compile(object data) => new StaticReflectionCompiledNode<T>(data as Dictionary<string, object>);
|
||||||
|
}
|
||||||
|
public sealed class DefaultConverterCompiler<T> : IDataCompiler<T> where T : struct
|
||||||
|
{
|
||||||
|
public required Func<object, Dictionary<string, object>> Converter { get; set; }
|
||||||
|
public IValueProvider<T> Compile(object data) => new StaticReflectionCompiledNode<T>(Converter(data));
|
||||||
|
}
|
||||||
|
public sealed class NameCompiler : IDataCompiler<Name>
|
||||||
|
{
|
||||||
|
public IValueProvider<Name> Compile(object data)
|
||||||
|
{
|
||||||
|
if (data is string s)
|
||||||
|
{
|
||||||
|
return new StaticCompiledNode<Name>(new(s));
|
||||||
|
}
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public sealed class TagsCompiler : IDataCompiler<Tags>
|
||||||
|
{
|
||||||
|
public IValueProvider<Tags> Compile(object data)
|
||||||
|
{
|
||||||
|
if (data is List<object> list)
|
||||||
|
{
|
||||||
|
var cast = list.Cast<string>().ToArray();
|
||||||
|
Tags tag = new(cast);
|
||||||
|
return new StaticCompiledNode<Tags>(tag);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (data is Dictionary<string,object> dict)
|
||||||
|
{
|
||||||
|
var tagsWith = new string[0];
|
||||||
|
if (dict.TryGetValue("With", out var with))
|
||||||
|
{
|
||||||
|
tagsWith = ((List<object>)with).Cast<string>().ToArray();
|
||||||
|
}
|
||||||
|
var tagsWiothout = new string[0];
|
||||||
|
if (dict.TryGetValue("Except", out var except))
|
||||||
|
{
|
||||||
|
tagsWiothout = ((List<object>)except).Cast<string>().ToArray();
|
||||||
|
}
|
||||||
|
return new FactoryCompiledNode<Tags>((in context, ref tags) =>
|
||||||
|
{
|
||||||
|
tags = tags.With(tagsWith).WithOut(tagsWiothout);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// public class ComponentBinderRegistry
|
||||||
|
// {
|
||||||
|
// private readonly Dictionary<ComponentType, IComponentBinder> _binder = [];
|
||||||
|
// public void Add<T>(ComponentBinder<T> componentBinder) where T : struct
|
||||||
|
// {
|
||||||
|
|
||||||
|
// _binder.Add(typeof(T), componentBinder);
|
||||||
|
// }
|
||||||
|
// public void Apply(Entity entity, World world, CompiledBlueprint itemData)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// var s = world.GetSignature(entity);
|
||||||
|
// for (int i = 0; i < s.Count; i++)
|
||||||
|
// {
|
||||||
|
// if (!_binder.ContainsKey(s.Components[i]))
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// var binder = _binder[s.Components[i]];
|
||||||
|
// var type = s.Components[i].Type;
|
||||||
|
// var context = new BlueprintContext(){World = world};
|
||||||
|
// binder.ApplyUntyped(entity, itemData.Providers[type], context);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// public void Apply(Span<Entity> entities, World world, CompiledBlueprint itemData)
|
||||||
|
// {
|
||||||
|
// var signature = world.GetSignature(entities[0]);
|
||||||
|
// for (int i = 1; i < entities.Length; i++)
|
||||||
|
// {
|
||||||
|
// Debug.Assert(world.GetSignature(entities[i]) == signature);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for (int i = 0; i < signature.Count; i++)
|
||||||
|
// {
|
||||||
|
// var binder = _binder[signature.Components[i]];
|
||||||
|
// var type = signature.Components[i].Type;
|
||||||
|
// var context = new BlueprintContext(){World = world};
|
||||||
|
// binder.ApplyUntyped(entities, itemData.Providers[type], context);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
// public abstract class DataNode//(Dictionary<string, object> Data)
|
||||||
|
// {
|
||||||
|
// public abstract DataNodeType NodeType { get; }
|
||||||
|
// // public T Get<T>(string name) => (T)Data[name];
|
||||||
|
// }
|
||||||
|
// public enum DataNodeType
|
||||||
|
// {hthous stomatitis, pharyngitis, adenitis) is a
|
||||||
|
// Value,
|
||||||
|
// Sequence,
|
||||||
|
// Mapping,
|
||||||
|
// Component
|
||||||
|
// }
|
||||||
|
// public sealed class ValueNode(object value) : DataNode
|
||||||
|
// {
|
||||||
|
// public override DataNodeType NodeType => DataNodeType.Value;
|
||||||
|
|
||||||
|
// public object Value { get; set; } = value;
|
||||||
|
|
||||||
|
// public Option<T> As<T>() => Value is T o?Option<T>.Some(o):Option<T>.None;
|
||||||
|
// }
|
||||||
|
// public sealed class SequenceNode(IReadOnlyList<DataNode> values) : DataNode
|
||||||
|
// {
|
||||||
|
// public override DataNodeType NodeType => DataNodeType.Sequence;
|
||||||
|
|
||||||
|
// public IReadOnlyList<DataNode> Values { get; set; } = values;
|
||||||
|
// }
|
||||||
|
// public sealed class MappingNode(IReadOnlyDictionary<string, DataNode> values) : DataNode
|
||||||
|
// {
|
||||||
|
// public override DataNodeType NodeType => DataNodeType.Mapping;
|
||||||
|
|
||||||
|
// public IReadOnlyDictionary<string, DataNode> Values { get; set; } = values;
|
||||||
|
|
||||||
|
// public bool TryGet<T>(string key, [NotNullWhen(true)] out T value) where T : DataNode
|
||||||
|
// {
|
||||||
|
// var result = Values.TryGetValue(key, out var node);
|
||||||
|
// value = (T)node!;
|
||||||
|
// return result;
|
||||||
|
|
||||||
|
// }
|
||||||
|
// public bool TryGet(string key, [NotNullWhen(true)] out DataNode node) => Values.TryGetValue(key, out node!);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public class DataNodeSerlicer : YamlConverter<DataNode>, IJsonFormatter<DataNode>
|
||||||
|
// {
|
||||||
|
// private Dictionary<string,string> _data = new();
|
||||||
|
// public DataNode Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver)
|
||||||
|
// {
|
||||||
|
// var i = 0;
|
||||||
|
// while (reader.ReadIsInObject(ref i))
|
||||||
|
// {
|
||||||
|
// var name = reader.ReadPropertyName();
|
||||||
|
// var value = reader.ReadString();
|
||||||
|
// _data.Add(name, value);
|
||||||
|
// }
|
||||||
|
// throw new NotImplementedException();
|
||||||
|
// }
|
||||||
|
// public void Serialize(ref JsonWriter writer, DataNode value, IJsonFormatterResolver formatterResolver) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
// public override DataNode? Read(YamlReader reader)
|
||||||
|
// {
|
||||||
|
// // reader.pa
|
||||||
|
// throw new NotImplementedException();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public override void Write(YamlWriter writer, DataNode value)
|
||||||
|
// {
|
||||||
|
// throw new NotImplementedException();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|||||||
81
src/Recipes/ComponetBinder.cs
Normal file
81
src/Recipes/ComponetBinder.cs
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using Arch.Core;
|
||||||
|
using FoodFactory.Items;
|
||||||
|
using FoodFactory.Recipes;
|
||||||
|
|
||||||
|
public static class ComponentBinder
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<Type, ApplyDelegate> _cache = new();
|
||||||
|
|
||||||
|
private delegate void ApplyDelegate(
|
||||||
|
Entity entity,
|
||||||
|
IValueProvider provider,
|
||||||
|
BlueprintContext context);
|
||||||
|
|
||||||
|
public static void Apply(Type componentType, Span<Entity> existing, IValueProvider data, BlueprintContext context)
|
||||||
|
{
|
||||||
|
if (!_cache.TryGetValue(componentType, out var del))
|
||||||
|
{
|
||||||
|
del = CreateDelegate(componentType);
|
||||||
|
_cache[componentType] = del;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < existing.Length; i++)
|
||||||
|
{
|
||||||
|
Apply(componentType, existing[i], data, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void Apply(
|
||||||
|
ReadOnlySpan<Type> componentType,
|
||||||
|
Entity entity,
|
||||||
|
ReadOnlySpan<IValueProvider> provider,
|
||||||
|
BlueprintContext context)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < componentType.Length; i++)
|
||||||
|
{
|
||||||
|
Apply(componentType[i], entity, provider[i], context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void Apply(
|
||||||
|
Type componentType,
|
||||||
|
Entity entity,
|
||||||
|
IValueProvider provider,
|
||||||
|
BlueprintContext context)
|
||||||
|
{
|
||||||
|
if (!_cache.TryGetValue(componentType, out var del))
|
||||||
|
{
|
||||||
|
del = CreateDelegate(componentType);
|
||||||
|
_cache[componentType] = del;
|
||||||
|
}
|
||||||
|
|
||||||
|
del(entity, provider, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ApplyDelegate CreateDelegate(Type t)
|
||||||
|
{
|
||||||
|
var method = typeof(ComponentBinder)
|
||||||
|
.GetMethod(nameof(ApplyGeneric),
|
||||||
|
BindingFlags.Static | BindingFlags.NonPublic)!
|
||||||
|
.MakeGenericMethod(t);
|
||||||
|
|
||||||
|
return (ApplyDelegate)Delegate.CreateDelegate(
|
||||||
|
typeof(ApplyDelegate),
|
||||||
|
method);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ApplyGeneric<T>(
|
||||||
|
Entity entity,
|
||||||
|
IValueProvider provider,
|
||||||
|
BlueprintContext context)
|
||||||
|
{
|
||||||
|
if (provider is not IValueProvider<T> typedProvider)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
ref var component = ref context.World.Get<T>(entity);
|
||||||
|
|
||||||
|
typedProvider.Resolve(context, ref component);
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/Recipes/ComponetBinder.cs.uid
Normal file
1
src/Recipes/ComponetBinder.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://cmes4oeo8jjov
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
[ext_resource type="Script" uid="uid://dcrb286hmpli" path="res://src/VoxelGrid/VoxelGridNode.cs" id="1_tsdpe"]
|
[ext_resource type="Script" uid="uid://dcrb286hmpli" path="res://src/VoxelGrid/VoxelGridNode.cs" id="1_tsdpe"]
|
||||||
[ext_resource type="Script" uid="uid://cnkblltup5guy" path="res://src/Equipment/OvenTest.cs" id="3_r7dgx"]
|
[ext_resource type="Script" uid="uid://cnkblltup5guy" path="res://src/Equipment/OvenTest.cs" id="3_r7dgx"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bktqs1lw6go4" path="res://src/VoxelGrid/ItemSpawner.tscn" id="5_mxaon"]
|
[ext_resource type="PackedScene" uid="uid://bktqs1lw6go4" path="res://src/VoxelGrid/ItemSpawner.tscn" id="5_mxaon"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://bkg733oidira6" path="res://assets/KayKit_Restaurant_Bits_1.0_FREE/Assets/gltf/oven.gltf" id="5_ujjjs"]
|
||||||
[ext_resource type="PackedScene" uid="uid://h00mq2srsbfa" path="res://assets/kenney_conveyor-kit/Models/GLB format/door.glb" id="5_wk2t5"]
|
[ext_resource type="PackedScene" uid="uid://h00mq2srsbfa" path="res://assets/kenney_conveyor-kit/Models/GLB format/door.glb" id="5_wk2t5"]
|
||||||
[ext_resource type="Script" uid="uid://ee5aoxi8mjnw" path="res://src/Equipment/BeltPort.cs" id="6_2wkfx"]
|
[ext_resource type="Script" uid="uid://ee5aoxi8mjnw" path="res://src/Equipment/BeltPort.cs" id="6_2wkfx"]
|
||||||
[ext_resource type="PackedScene" uid="uid://c4h7mwnfrdesg" path="res://src/Conveyors/ConveyorBeltStraight/ConveyorBeltStraight.tscn" id="6_mxaon"]
|
[ext_resource type="PackedScene" uid="uid://c4h7mwnfrdesg" path="res://src/Conveyors/ConveyorBeltStraight/ConveyorBeltStraight.tscn" id="6_mxaon"]
|
||||||
@@ -10,6 +11,9 @@
|
|||||||
[ext_resource type="Script" uid="uid://yec84plemjv1" path="res://src/Equipment/SlicerTest.cs" id="8_2lg7i"]
|
[ext_resource type="Script" uid="uid://yec84plemjv1" path="res://src/Equipment/SlicerTest.cs" id="8_2lg7i"]
|
||||||
[ext_resource type="Script" uid="uid://culjdbwllmsyk" path="res://src/Equipment/StackerTest.cs" id="8_e2skk"]
|
[ext_resource type="Script" uid="uid://culjdbwllmsyk" path="res://src/Equipment/StackerTest.cs" id="8_e2skk"]
|
||||||
|
|
||||||
|
[sub_resource type="BoxMesh" id="BoxMesh_2wkfx"]
|
||||||
|
size = Vector3(1, 1, 2)
|
||||||
|
|
||||||
[sub_resource type="Curve3D" id="Curve3D_mxaon"]
|
[sub_resource type="Curve3D" id="Curve3D_mxaon"]
|
||||||
_data = {
|
_data = {
|
||||||
"points": PackedVector3Array(0, 0, 0, 0, 0, 0, 0, 0.5, -0.5, 0, 0, 0, 0, 0, 0, 0, 0.5, 0),
|
"points": PackedVector3Array(0, 0, 0, 0, 0, 0, 0, 0.5, -0.5, 0, 0, 0, 0, 0, 0, 0, 0.5, 0),
|
||||||
@@ -17,9 +21,6 @@ _data = {
|
|||||||
}
|
}
|
||||||
point_count = 2
|
point_count = 2
|
||||||
|
|
||||||
[sub_resource type="BoxMesh" id="BoxMesh_2wkfx"]
|
|
||||||
size = Vector3(1, 1, 2)
|
|
||||||
|
|
||||||
[node name="VoxelGridNode" type="Node3D" unique_id=825696340]
|
[node name="VoxelGridNode" type="Node3D" unique_id=825696340]
|
||||||
script = ExtResource("1_tsdpe")
|
script = ExtResource("1_tsdpe")
|
||||||
|
|
||||||
@@ -59,6 +60,9 @@ transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, 4, 0
|
|||||||
[node name="ConveyorBeltStraight9" parent="." unique_id=1449572266 instance=ExtResource("6_mxaon")]
|
[node name="ConveyorBeltStraight9" parent="." unique_id=1449572266 instance=ExtResource("6_mxaon")]
|
||||||
transform = Transform3D(1.3113416e-07, 0, -1, 0, 1, 0, 1, 0, 1.3113416e-07, 3, 0, 1)
|
transform = Transform3D(1.3113416e-07, 0, -1, 0, 1, 0, 1, 0, 1.3113416e-07, 3, 0, 1)
|
||||||
|
|
||||||
|
[node name="ConveyorBeltStraight44" parent="." unique_id=27021356 instance=ExtResource("6_mxaon")]
|
||||||
|
transform = Transform3D(-1, 0, -8.742277e-08, 0, 1, 0, 8.742277e-08, 0, -1, 3, 0, 0)
|
||||||
|
|
||||||
[node name="ConveyorBeltStraight26" parent="." unique_id=181268712 instance=ExtResource("6_mxaon")]
|
[node name="ConveyorBeltStraight26" parent="." unique_id=181268712 instance=ExtResource("6_mxaon")]
|
||||||
transform = Transform3D(1.3113416e-07, 0, -1, 0, 1, 0, 1, 0, 1.3113416e-07, 5, 0, 5)
|
transform = Transform3D(1.3113416e-07, 0, -1, 0, 1, 0, 1, 0, 1.3113416e-07, 5, 0, 5)
|
||||||
|
|
||||||
@@ -152,40 +156,28 @@ Width = 1
|
|||||||
Access = 1
|
Access = 1
|
||||||
PortName = "Input"
|
PortName = "Input"
|
||||||
|
|
||||||
[node name="Path3D" type="Path3D" parent="OvenTest/Node3D2" unique_id=1525648764]
|
|
||||||
curve = SubResource("Curve3D_mxaon")
|
|
||||||
|
|
||||||
[node name="door3" parent="OvenTest/Node3D2" unique_id=351624885 instance=ExtResource("5_wk2t5")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.870017e-08, 0, -0.6001501)
|
|
||||||
|
|
||||||
[node name="Node3D3" type="Node3D" parent="OvenTest" unique_id=1033202746]
|
[node name="Node3D3" type="Node3D" parent="OvenTest" unique_id=1033202746]
|
||||||
transform = Transform3D(-2.1855693e-07, 0, -1, 0, 1, 0, 1, 0, -2.1855693e-07, 0, 0, 1)
|
transform = Transform3D(-2.1855693e-07, 0, -1, 0, 1, 0, 1, 0, -2.1855693e-07, 0, 0, 0)
|
||||||
script = ExtResource("6_2wkfx")
|
script = ExtResource("6_2wkfx")
|
||||||
Face = 4
|
Face = 4
|
||||||
Width = 1
|
Width = 1
|
||||||
Access = 2
|
Access = 2
|
||||||
PortName = "OutPut"
|
PortName = "OutPut"
|
||||||
|
|
||||||
[node name="Path3D2" type="Path3D" parent="OvenTest/Node3D3" unique_id=739562310]
|
[node name="oven" parent="OvenTest" unique_id=169939827 instance=ExtResource("5_ujjjs")]
|
||||||
curve = SubResource("Curve3D_mxaon")
|
transform = Transform3D(-2.1855694e-08, 0, -0.5, 0, 0.5, 0, 0.5, 0, -2.1855694e-08, 0, 0, 0)
|
||||||
|
|
||||||
[node name="door4" parent="OvenTest/Node3D3" unique_id=1602265662 instance=ExtResource("5_wk2t5")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.9604645e-08, 0, -0.3998499)
|
|
||||||
|
|
||||||
[node name="door5" parent="OvenTest/Node3D3" unique_id=102838222 instance=ExtResource("5_wk2t5")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.9604645e-08, 0, -0.3998499)
|
|
||||||
|
|
||||||
[node name="ItemSpawner" parent="." unique_id=966349707 instance=ExtResource("5_mxaon")]
|
[node name="ItemSpawner" parent="." unique_id=966349707 instance=ExtResource("5_mxaon")]
|
||||||
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, -1.0023941, 0, 0.0019463301)
|
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, -1.0023941, 0, 0.0019463301)
|
||||||
ItemName = "Potato"
|
ItemName = "raw_potato"
|
||||||
|
|
||||||
[node name="ItemSpawner2" parent="." unique_id=405829395 instance=ExtResource("5_mxaon")]
|
[node name="ItemSpawner2" parent="." unique_id=405829395 instance=ExtResource("5_mxaon")]
|
||||||
transform = Transform3D(3.059797e-07, 0, -1, 0, 1, 0, 1, 0, 3.059797e-07, -1, 0, 1)
|
transform = Transform3D(3.059797e-07, 0, -1, 0, 1, 0, 1, 0, 3.059797e-07, -1, 0, 1)
|
||||||
ItemName = "Onion"
|
ItemName = "raw_onion"
|
||||||
|
|
||||||
[node name="ItemSpawner3" parent="." unique_id=422927887 instance=ExtResource("5_mxaon")]
|
[node name="ItemSpawner3" parent="." unique_id=422927887 instance=ExtResource("5_mxaon")]
|
||||||
transform = Transform3D(3.059797e-07, 0, -1, 0, 1, 0, 1, 0, 3.059797e-07, -1, 0, 6)
|
transform = Transform3D(3.059797e-07, 0, -1, 0, 1, 0, 1, 0, 3.059797e-07, -1, 0, 6)
|
||||||
ItemName = "Potato"
|
ItemName = "raw_red_onion"
|
||||||
|
|
||||||
[node name="Balancer" type="Node3D" parent="." unique_id=619243985]
|
[node name="Balancer" type="Node3D" parent="." unique_id=619243985]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, 2)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, 2)
|
||||||
|
|||||||
Reference in New Issue
Block a user