151 lines
4.0 KiB
C#
151 lines
4.0 KiB
C#
namespace ChickenGameTest;
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text.RegularExpressions;
|
|
using Arch.Core;
|
|
using Arch.Core.Extensions;
|
|
using Arch.LowLevel;
|
|
using Arch.System;
|
|
using Chickensoft.AutoInject;
|
|
using Chickensoft.Introspection;
|
|
using FoodFactory;
|
|
using FoodFactory.Recipes;
|
|
using Godot;
|
|
public class BacterialSystem : BaseSystem<World, float>
|
|
{
|
|
private QueryDescription _desc = new QueryDescription().WithAll<Bacteria, Temperature>();
|
|
public static Resources<List<BacteriaData>> Resources = new();
|
|
public BacterialSystem(World world) : base(world)
|
|
{
|
|
|
|
}
|
|
public override void Update(in float t)
|
|
{
|
|
var delta = t;
|
|
World.ParallelQuery(in _desc, (Entity entity, ref Bacteria bacteria, ref Temperature temperature) =>
|
|
{
|
|
var handle = bacteria.Data;
|
|
var data = Resources.Get(in handle);
|
|
for (int i = 0; i < data.Count; i++)
|
|
{
|
|
data[i] = data[i] with { Count = BacteriaModel.UpdatePopulation(data[i].Count, temperature.Celsius, delta) };
|
|
// GD.Print(data[i].Count);
|
|
if (data[i].Count <= 0.5)
|
|
{
|
|
data.RemoveAt(i);
|
|
i--;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
//Will Liklely be the game instead of a node like this
|
|
[Meta(typeof(IAutoNode))]// [Tool]
|
|
public partial class VoxelGridNode : Node3D, IProvide<IVoxelGridRegistry>, IProvide<IItemRenderer>, IProvide<IRecipes>, IProvide<IBlueprintManger>, IProvide<World>
|
|
{
|
|
public override void _Notification(int what) => this.Notify(what);
|
|
|
|
private World _world = default!;
|
|
World IProvide<World>.Value() => _world;
|
|
private IVoxelGridRegistry _voxelGridRegistry = default!;
|
|
IVoxelGridRegistry IProvide<IVoxelGridRegistry>.Value() => _voxelGridRegistry;
|
|
private IBlueprintManger _blueprintManger = default!;
|
|
IBlueprintManger IProvide<IBlueprintManger>.Value() => _blueprintManger;
|
|
private Recipes _recipes = default!;
|
|
IRecipes IProvide<IRecipes>.Value() => _recipes;
|
|
private IItemRenderer _itemRenderer = default!;
|
|
IItemRenderer IProvide<IItemRenderer>.Value() => _itemRenderer;
|
|
Group<float> _systems;
|
|
public override void _Ready()
|
|
{
|
|
// GD.Print();
|
|
base._Ready();
|
|
_voxelGridRegistry = new VoxelRegistry();
|
|
_itemRenderer = new ItemRenderSimple();
|
|
_blueprintManger = new BlueprintManger();
|
|
_recipes = new Recipes();
|
|
_world = World.Create();
|
|
_systems = new Group<float>("Items", new BacterialSystem(_world));
|
|
|
|
|
|
AddChild(_itemRenderer as Node);
|
|
Timer timer = new Timer() { WaitTime = .25f, Autostart = true };//TEST
|
|
AddChild(timer);//TEST
|
|
// timer.Timeout += _itemRenderer.Tick;//TEST
|
|
timer.Timeout += () =>
|
|
{
|
|
_systems.BeforeUpdate(.25f);
|
|
_systems.Update(.25f);
|
|
_systems.AfterUpdate(.25f);
|
|
};
|
|
_systems.Initialize();
|
|
this.Provide();
|
|
|
|
}
|
|
|
|
|
|
public override void _Input(InputEvent @event)
|
|
{
|
|
if (@event.IsActionPressed("ui_up"))
|
|
{
|
|
foreach (var item in GetChildren())
|
|
{
|
|
if (item is ConveyorBeltStraight conveyor)
|
|
{
|
|
var node = conveyor.GetNode("Node") as TestItemConveyor;
|
|
node.IsReversed = !node.IsReversed;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
public override void _ExitTree()
|
|
{
|
|
base._ExitTree();
|
|
_systems.Dispose();
|
|
_world.Dispose();
|
|
}
|
|
}
|
|
public static class BacteriaModel
|
|
{
|
|
// population = current bacteria count
|
|
// temperature = degrees Celsius
|
|
// deltaTime = elapsed time (hours)
|
|
public static double UpdatePopulation(
|
|
double population,
|
|
double temperature,
|
|
double deltaTime)
|
|
{
|
|
double rate;
|
|
|
|
// Very cold -> slight die-off
|
|
if (temperature <= 5)
|
|
{
|
|
rate = -0.1;
|
|
}
|
|
// Growth zone
|
|
else if (temperature < 35)
|
|
{
|
|
rate = 0.06 * (temperature - 5);
|
|
}
|
|
// Hot but still survivable
|
|
else if (temperature < 60)
|
|
{
|
|
rate = 1.8 - 0.08 * (temperature - 35);
|
|
}
|
|
// Dangerous heat -> bacteria die
|
|
else
|
|
{
|
|
rate = -0.8;
|
|
}
|
|
|
|
// Population update
|
|
double newPopulation =
|
|
population + (deltaTime * population * rate);
|
|
|
|
// Prevent negative bacteria counts
|
|
return Math.Max(0, newPopulation);
|
|
}
|
|
}
|