NorbiPeti
f403feb298
Removed BlockIdentifiers.OWNED_BLOCKS as the original got replaced with an array Added the correct group for each supported functional block Removed EntityFactory property from IEntitySerializer as it is provided on deserialization
192 lines
No EOL
5.7 KiB
C#
192 lines
No EOL
5.7 KiB
C#
using System.Collections.Generic;
|
|
|
|
using Gamecraft.Wires;
|
|
using RobocraftX.Blocks;
|
|
using RobocraftX.Common;
|
|
using RobocraftX.GUI.Hotbar.Colours;
|
|
using RobocraftX.Physics;
|
|
using RobocraftX.Scene.Simulation;
|
|
using Svelto.DataStructures;
|
|
using Svelto.ECS;
|
|
|
|
using GamecraftModdingAPI.Engines;
|
|
using GamecraftModdingAPI.Utility;
|
|
|
|
namespace GamecraftModdingAPI.Blocks
|
|
{
|
|
/// <summary>
|
|
/// Engine for executing general block actions
|
|
/// </summary>
|
|
public class BlockEngine : IApiEngine
|
|
{
|
|
public string Name { get; } = "GamecraftModdingAPIBlockGameEngine";
|
|
|
|
public EntitiesDB entitiesDB { set; private get; }
|
|
|
|
public bool isRemovable => false;
|
|
|
|
internal bool Synced = true;
|
|
|
|
public void Dispose()
|
|
{
|
|
}
|
|
|
|
public void Ready()
|
|
{
|
|
}
|
|
|
|
public Block[] GetConnectedBlocks(EGID blockID)
|
|
{
|
|
if (!BlockExists(blockID)) return new Block[0];
|
|
Stack<EGID> cubeStack = new Stack<EGID>();
|
|
FasterList<EGID> cubes = new FasterList<EGID>(10);
|
|
var coll = entitiesDB.QueryEntities<GridConnectionsEntityStruct>();
|
|
foreach (var (ecoll, _) in coll)
|
|
foreach (ref var conn in ecoll)
|
|
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] = new Block(cubes[i]);
|
|
return ret;
|
|
}
|
|
|
|
public void SetBlockColorFromPalette(ref ColourParameterEntityStruct color)
|
|
{
|
|
ref var paletteEntry = ref entitiesDB.QueryEntity<PaletteEntryEntityStruct>(color.indexInPalette,
|
|
CommonExclusiveGroups.COLOUR_PALETTE_GROUP);
|
|
color.paletteColour = paletteEntry.Colour;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a struct of a block. Can be used to set properties.
|
|
/// Returns a default value if not found.
|
|
/// </summary>
|
|
/// <param name="blockID">The block's ID</param>
|
|
/// <typeparam name="T">The struct to query</typeparam>
|
|
/// <returns>An editable reference to the struct</returns>
|
|
public ref T GetBlockInfo<T>(EGID blockID) where T : struct, IEntityComponent
|
|
{
|
|
if (!Synced)
|
|
{
|
|
Sync();
|
|
Synced = true;
|
|
}
|
|
if (entitiesDB.Exists<T>(blockID))
|
|
return ref entitiesDB.QueryEntity<T>(blockID);
|
|
T[] structHolder = new T[1]; //Create something that can be referenced
|
|
return ref structHolder[0]; //Gets a default value automatically
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a struct of a block. Can be used to set properties.
|
|
/// Returns a default value if not found.
|
|
/// </summary>
|
|
/// <param name="blockID">The block's ID</param>
|
|
/// <param name="exists">Whether the specified struct exists for the block</param>
|
|
/// <typeparam name="T">The struct to query</typeparam>
|
|
/// <returns>An editable reference to the struct</returns>
|
|
public ref T GetBlockInfo<T>(EGID blockID, out bool exists) where T : struct, IEntityComponent
|
|
{
|
|
if (!Synced)
|
|
{
|
|
Sync();
|
|
Synced = true;
|
|
}
|
|
exists = entitiesDB.Exists<T>(blockID);
|
|
if (exists)
|
|
return ref entitiesDB.QueryEntity<T>(blockID);
|
|
T[] structHolder = new T[1];
|
|
return ref structHolder[0];
|
|
}
|
|
|
|
public bool BlockExists(EGID id)
|
|
{
|
|
if (!Synced)
|
|
{
|
|
Sync();
|
|
Synced = true;
|
|
}
|
|
return entitiesDB.Exists<DBEntityStruct>(id);
|
|
}
|
|
|
|
public bool GetBlockInfoExists<T>(EGID blockID) where T : struct, IEntityComponent
|
|
{
|
|
if (!Synced)
|
|
{
|
|
Sync();
|
|
Synced = true;
|
|
}
|
|
return entitiesDB.Exists<T>(blockID);
|
|
}
|
|
|
|
public SimBody[] GetSimBodiesFromID(byte id)
|
|
{
|
|
var ret = new FasterList<SimBody>(4);
|
|
if (!entitiesDB.HasAny<ObjectIdEntityStruct>(CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP))
|
|
return new SimBody[0];
|
|
var oids = entitiesDB.QueryEntities<ObjectIdEntityStruct>(CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP);
|
|
var connections = entitiesDB.QueryMappedEntities<GridConnectionsEntityStruct>(CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP);
|
|
foreach (ref ObjectIdEntityStruct oid in oids)
|
|
{
|
|
if (oid.objectId != id) continue;
|
|
var rid = connections.Entity(oid.ID.entityID).machineRigidBodyId;
|
|
foreach (var rb in ret)
|
|
{
|
|
if (rb.Id.entityID == rid)
|
|
goto DUPLICATE; //Multiple Object Identifiers on one rigid body
|
|
}
|
|
ret.Add(new SimBody(rid));
|
|
DUPLICATE: ;
|
|
}
|
|
return ret.ToArray();
|
|
}
|
|
|
|
public ObjectIdentifier[] GetObjectIDsFromID(byte id, bool sim)
|
|
{
|
|
var ret = new FasterList<ObjectIdentifier>(4);
|
|
if (!entitiesDB.HasAny<ObjectIdEntityStruct>(CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP))
|
|
return new ObjectIdentifier[0];
|
|
var oids = entitiesDB.QueryEntities<ObjectIdEntityStruct>(CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP);
|
|
foreach (ref ObjectIdEntityStruct oid in oids)
|
|
if (sim ? oid.simObjectId == id : oid.objectId == id)
|
|
ret.Add(new ObjectIdentifier(oid.ID));
|
|
return ret.ToArray();
|
|
}
|
|
|
|
public SimBody[] GetConnectedSimBodies(uint id)
|
|
{
|
|
var joints = entitiesDB.QueryEntities<JointEntityStruct>(MachineSimulationGroups.JOINTS_GROUP);
|
|
var list = new FasterList<SimBody>(4);
|
|
foreach (var joint in joints)
|
|
{
|
|
if (joint.jointState == JointState.Broken) continue;
|
|
if (joint.connectedEntityA == id) list.Add(new SimBody(joint.connectedEntityB));
|
|
else if (joint.connectedEntityB == id) list.Add(new SimBody(joint.connectedEntityA));
|
|
}
|
|
|
|
return list.ToArray();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Synchronize newly created entity components with entities DB.
|
|
/// This forces a partial game tick, so it may be slow.
|
|
/// This also has the potential to make Gamecraft unstable.
|
|
/// Use this sparingly.
|
|
/// </summary>
|
|
private static void Sync()
|
|
{
|
|
DeterministicStepCompositionRootPatch.SubmitEntitiesNow();
|
|
}
|
|
|
|
#if DEBUG
|
|
public EntitiesDB GetEntitiesDB()
|
|
{
|
|
return entitiesDB;
|
|
}
|
|
#endif
|
|
}
|
|
} |