using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using HarmonyLib;
using Gamecraft.ColourPalette;
using Gamecraft.TimeRunning;
using Gamecraft.Wires;
using RobocraftX.Blocks;
using RobocraftX.Common;
using RobocraftX.Physics;
using RobocraftX.Rendering;
using RobocraftX.Rendering.GPUI;
using Svelto.DataStructures;
using Svelto.ECS;
using Svelto.ECS.EntityStructs;
using Svelto.ECS.Hybrid;
using Techblox.BuildingDrone;
using Unity.Mathematics;
using TechbloxModdingAPI.Engines;
using TechbloxModdingAPI.Utility;
namespace TechbloxModdingAPI.Blocks.Engines
{
///
/// Engine for executing general block actions
///
public partial class BlockEngine : IApiEngine
{
public string Name { get; } = "TechbloxModdingAPIBlockGameEngine";
public EntitiesDB entitiesDB { set; private get; }
public bool isRemovable => false;
public void Dispose()
{
}
public void Ready()
{
}
public Block[] GetConnectedBlocks(EGID blockID)
{
if (!BlockExists(blockID)) return new Block[0];
Stack cubeStack = new Stack();
FasterList cubes = new FasterList(10);
var coll = entitiesDB.QueryEntities();
foreach (var (ecoll, _) in coll)
{
var ecollB = ecoll.ToBuffer();
for(int i = 0; i < ecoll.count; i++)
{
ref var conn = ref ecollB.buffer[i];
conn.isProcessed = false;
}
}
ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID, cubeStack, cubes,
(in GridConnectionsEntityStruct g) => { return false; });
var ret = new Block[cubes.count];
for (int i = 0; i < cubes.count; i++)
ret[i] = Block.New(cubes[i]);
return ret;
}
public float4 ConvertBlockColor(byte index) => index == byte.MaxValue
? new float4(-1f, -1f, -1f, -1f)
: entitiesDB.QueryEntity(index,
CommonExclusiveGroups.COLOUR_PALETTE_GROUP).Colour;
public OptionalRef GetBlockInfoOptional(Block block) where T : unmanaged, IEntityComponent
{
return entitiesDB.QueryEntityOptional(block);
}
public ref T GetBlockInfo(Block block) where T : unmanaged, IEntityComponent
{
#if DEBUG
if (!typeof(BlockTagEntityStruct).IsAssignableFrom(typeof(T)) && block.Exists && block.InitData.Valid)
throw new ArgumentException("The block exists but the init data has not been removed!");
#endif
return ref entitiesDB.QueryEntityOrDefault(block);
}
internal ref T GetBlockInfo(EcsObjectBase obj) where T : unmanaged, IEntityComponent
{
return ref entitiesDB.QueryEntityOrDefault(obj);
}
public ref T GetBlockInfoViewComponent(Block block) where T : struct, IEntityViewComponent
{
return ref entitiesDB.QueryEntityOrDefault(block);
}
internal object GetBlockInfo(Block block, Type type, string name)
{
/*var opt = AccessTools.Method(typeof(BlockEngine), "GetBlockInfoOptional", generics: new[] { type })
.Invoke(this, new object[] { block }); - TODO: Cannot call method with by-ref return value
var str = AccessTools.Method(opt.GetType(), "Get").Invoke(opt, Array.Empty