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 { private QueryDescription _desc = new QueryDescription().WithAll(); public static Resources> 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, IProvide, IProvide, IProvide, IProvide { public override void _Notification(int what) => this.Notify(what); private World _world = default!; World IProvide.Value() => _world; private IVoxelGridRegistry _voxelGridRegistry = default!; IVoxelGridRegistry IProvide.Value() => _voxelGridRegistry; private IBlueprintManger _blueprintManger = default!; IBlueprintManger IProvide.Value() => _blueprintManger; private Recipes _recipes = default!; IRecipes IProvide.Value() => _recipes; private IItemRenderer _itemRenderer = default!; IItemRenderer IProvide.Value() => _itemRenderer; Group _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("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); } }