243 lines
No EOL
7.8 KiB
C#
243 lines
No EOL
7.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Gamecraft.ColourPalette;
|
|
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.Experimental;
|
|
using Techblox.ObjectIDBlockServer;
|
|
using TechbloxModdingAPI.Common.Engines;
|
|
using Unity.Mathematics;
|
|
using TechbloxModdingAPI.Utility.ECS;
|
|
using PrefabsID = RobocraftX.Common.PrefabsID;
|
|
|
|
namespace TechbloxModdingAPI.Blocks.Engines
|
|
{
|
|
/// <summary>
|
|
/// Engine for executing general block actions
|
|
/// </summary>
|
|
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 Array.Empty<Block>();
|
|
Stack<EGID> cubeStack = new Stack<EGID>();
|
|
FasterList<EGID> cubes = new FasterList<EGID>(10);
|
|
var coll = entitiesDB.QueryEntities<GridConnectionsEntityStruct>();
|
|
foreach (var ((ecoll, count), _) in coll)
|
|
{
|
|
for(int i = 0; i < count; i++)
|
|
{
|
|
ecoll[i].areConnectionsAssigned = false;
|
|
}
|
|
}
|
|
|
|
//TODO: GetConnectedCubesUtility
|
|
/*ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID, cubeStack, cubes,
|
|
(in GridConnectionsEntityStruct _) => 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<PaletteEntryEntityStruct>(index,
|
|
ColourPaletteExclusiveGroups.COLOUR_PALETTE_GROUP).Colour;
|
|
|
|
public void UpdateDisplayData(EGID id)
|
|
{
|
|
if (!BlockExists(id)) return;
|
|
var pos = entitiesDB.QueryEntity<PositionEntityStruct>(id);
|
|
var rot = entitiesDB.QueryEntity<RotationEntityStruct>(id);
|
|
var scale = entitiesDB.QueryEntity<ScalingEntityStruct>(id);
|
|
var skew = entitiesDB.QueryEntity<SkewComponent>(id);
|
|
entitiesDB.QueryEntity<RenderingDataStruct>(id).matrix =
|
|
math.mul(float4x4.TRS(pos.position, rot.rotation, scale.scale), skew.skewMatrix);
|
|
entitiesDB.PublishEntityChangeDelayed<GFXPrefabEntityStructGPUI>(id); // Signal a prefab change so it updates the render buffers
|
|
}
|
|
|
|
internal void UpdateDisplayedPrefab(Block block, byte material, bool flipped)
|
|
{
|
|
var prefabAssetIDOpt = entitiesDB.QueryEntityOptional<PrefabAssetIDComponent>(block);
|
|
uint prefabAssetID = prefabAssetIDOpt
|
|
? prefabAssetIDOpt.Get().prefabAssetID
|
|
: uint.MaxValue;
|
|
if (prefabAssetID == uint.MaxValue)
|
|
{
|
|
if (entitiesDB.QueryEntityOptional<BlockTagEntityStruct>(block)) //The block exists
|
|
throw new BlockException("Prefab asset ID not found for block " + block); //Set by the game
|
|
return;
|
|
}
|
|
|
|
uint prefabId =
|
|
PrefabsID.GetOrAddPrefabID((ushort) prefabAssetID, material, 1, flipped);
|
|
entitiesDB.QueryEntityOrDefault<GFXPrefabEntityStructGPUI>(block).prefabID = prefabId;
|
|
if (block.Exists)
|
|
{
|
|
entitiesDB.PublishEntityChangeDelayed<CubeMaterialStruct>(block.Id);
|
|
entitiesDB.PublishEntityChangeDelayed<GFXPrefabEntityStructGPUI>(block.Id);
|
|
|
|
/*ref BuildingActionComponent local =
|
|
ref entitiesDB.QueryEntity<BuildingActionComponent>(BuildingDroneUtility
|
|
.GetLocalBuildingDrone(entitiesDB).ToEGID(entitiesDB));
|
|
local.buildAction = BuildAction.ChangeMaterial;
|
|
local.targetPosition = block.Position; - TODO: This probably only plays the audio
|
|
this.entitiesDB.PublishEntityChangeDelayed<BuildingActionComponent>(local.ID);*/
|
|
}
|
|
//Phyiscs prefab: prefabAssetID, set on block creation from the CubeListData
|
|
}
|
|
|
|
public void UpdateBlockColor(EGID id)
|
|
{
|
|
entitiesDB.PublishEntityChangeDelayed<ColourParameterEntityStruct>(id);
|
|
}
|
|
|
|
public bool BlockExists(EGID blockID)
|
|
{
|
|
return entitiesDB.Exists<BlockTagEntityStruct>(blockID);
|
|
}
|
|
|
|
public SimBody[] GetSimBodiesFromID(byte id)
|
|
{
|
|
var ret = new FasterList<SimBody>(4);
|
|
var oids = entitiesDB.QueryEntitiesOptional<ObjectIdEntityStruct>(ObjectIDBlockExclusiveGroups.OBJECT_ID_BLOCK_GROUP);
|
|
EGIDMapper<GridConnectionsEntityStruct>? connections = null;
|
|
foreach (var oid in oids)
|
|
{
|
|
if (oid.Get().objectId != id) continue;
|
|
if (!connections.HasValue) //Would need reflection to get the group from the build group otherwise
|
|
connections = entitiesDB.QueryMappedEntities<GridConnectionsEntityStruct>(oid.EGID.groupID);
|
|
//var rid = connections.Value.Entity(tag.ID.entityID).machineRigidBodyId;
|
|
/*foreach (var rb in ret) - TODO
|
|
{
|
|
if (rb.Id.entityID == rid)
|
|
goto DUPLICATE; //Multiple Object Identifiers on one rigid body
|
|
}
|
|
|
|
ret.Add(new SimBody(rid));
|
|
DUPLICATE: ;*/
|
|
}
|
|
|
|
return ret.ToArray();
|
|
}
|
|
|
|
public SimBody[] GetConnectedSimBodies(uint id)
|
|
{
|
|
var (joints, count) = entitiesDB.QueryEntities<JointEntityStruct>(MachineSimulationGroups.JOINTS_GROUP);
|
|
var list = new FasterList<SimBody>(4);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
ref var joint = ref joints[i];
|
|
if (joint.isBroken) continue;
|
|
/*if (joint.connectedEntityA == id) list.Add(new SimBody(joint.connectedEntityB)); - TODO:
|
|
else if (joint.connectedEntityB == id) list.Add(new SimBody(joint.connectedEntityA));*/
|
|
}
|
|
|
|
return list.ToArray();
|
|
}
|
|
|
|
public SimBody[] GetClusterBodies(uint cid)
|
|
{
|
|
var groups = entitiesDB.QueryEntities<GridConnectionsEntityStruct>();
|
|
var bodies = new HashSet<uint>();
|
|
foreach (var ((coll, count), _) in groups)
|
|
{
|
|
for (var index = 0; index < count; index++)
|
|
{
|
|
var conn = coll[index];
|
|
/*if (conn.clusterId == cid) - TODO
|
|
bodies.Add(conn.machineRigidBodyId);*/
|
|
}
|
|
}
|
|
|
|
return bodies.Select(id => new SimBody(id, cid)).ToArray();
|
|
}
|
|
|
|
public EGID? FindBlockEGID(uint id)
|
|
{
|
|
var groups = entitiesDB.FindGroups<BlockTagEntityStruct>();
|
|
foreach (ExclusiveGroupStruct group in groups)
|
|
{
|
|
if (entitiesDB.Exists<BlockTagEntityStruct>(id, group))
|
|
return new EGID(id, group);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public Cluster GetCluster(uint sbid)
|
|
{
|
|
var groups = entitiesDB.QueryEntities<GridConnectionsEntityStruct>();
|
|
foreach (var ((coll, count), _) in groups)
|
|
{
|
|
for (var index = 0; index < count; index++)
|
|
{
|
|
var conn = coll[index];
|
|
//Static blocks don't have a cluster ID but the cluster destruction manager should have one
|
|
/*if (conn.machineRigidBodyId == sbid && conn.clusterId != uint.MaxValue) - TODO:
|
|
return new Cluster(conn.clusterId);*/
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public Block[] GetBodyBlocks(uint sbid)
|
|
{
|
|
var groups = entitiesDB.FindGroups<GridConnectionsEntityStruct>();
|
|
groups = new QueryGroups(groups).Except(CommonExclusiveGroups.DISABLED_JOINTS_IN_SIM_GROUP).Evaluate().result;
|
|
var set = new HashSet<Block>();
|
|
foreach (var ((coll, tags, count), _) in entitiesDB.QueryEntities<GridConnectionsEntityStruct, BlockTagEntityStruct>(groups))
|
|
{
|
|
for (var index = 0; index < count; index++)
|
|
{
|
|
var conn = coll[index];
|
|
/*if (conn.machineRigidBodyId == sbid) - TODO
|
|
set.Add(Block.New(tags[index].ID));*/
|
|
}
|
|
}
|
|
|
|
return set.ToArray();
|
|
}
|
|
|
|
public ObjectID[] GetObjectIDsFromID(byte id)
|
|
{
|
|
if (!entitiesDB.HasAny<ObjectIDTweakableComponent>(ObjectIDBlockExclusiveGroups.OBJECT_ID_BLOCK_GROUP))
|
|
return Array.Empty<ObjectID>();
|
|
|
|
var ret = new FasterList<ObjectID>(4);
|
|
var oids = entitiesDB.QueryEntitiesOptional<ObjectIDTweakableComponent>(ObjectIDBlockExclusiveGroups.OBJECT_ID_BLOCK_GROUP);
|
|
foreach (var oid in oids)
|
|
{
|
|
if (oid.Get().objectIDToTrigger == id)
|
|
ret.Add(new ObjectID(oid.EGID));
|
|
}
|
|
|
|
return ret.ToArray();
|
|
}
|
|
}
|
|
} |