137 lines
7 KiB
C#
137 lines
7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using RobocraftX.Multiplayer;
|
|
using RobocraftX.Common;
|
|
using RobocraftX.Blocks;
|
|
using Svelto.ECS;
|
|
using Svelto.ECS.EntityStructs;
|
|
using Unity.Entities;
|
|
using Svelto.Context;
|
|
using Svelto.Tasks;
|
|
using RobocraftX;
|
|
using RobocraftX.SimulationModeState;
|
|
using RobocraftX.UECS;
|
|
using Unity.Transforms;
|
|
using Unity.Mathematics;
|
|
|
|
namespace ExtraCommands.Building
|
|
{
|
|
[CustomCommand("MoveBlocks", "Move all blocks (including ground) from their original position")]
|
|
[CustomCommand("MoveLastBlock", "Move last block from original position")]
|
|
class MoveBlocksCommandEngine : CustomCommandEngine
|
|
{
|
|
public MoveBlocksCommandEngine(UnityContext<FullGameCompositionRoot> ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams)
|
|
{
|
|
}
|
|
|
|
public override void Ready()
|
|
{
|
|
CustomCommandUtility.Register<float, float, float>("MoveBlocks", MoveBlocksCommand, "Move all blocks (including ground) from their original position");
|
|
CustomCommandUtility.Register<float, float, float>("MoveLastBlock", MoveLastBlockCommand, "Move last block from original position");
|
|
}
|
|
|
|
// Move every block by vector (x,y,z)
|
|
private void MoveBlocksCommand(float x, float y, float z)
|
|
{
|
|
ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
|
|
if (simMode.simulationMode != SimulationMode.Build)
|
|
{
|
|
uREPL.Log.Error("Blocks can only be moved in Build Mode");
|
|
return;
|
|
}
|
|
uint count = this.entitiesDB.Count<PositionEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
|
float3 translationVector = new float3(x,y,z);
|
|
for (uint i = 0; i < count; i++)
|
|
{
|
|
TranslateSingleBlock(i, translationVector);
|
|
}
|
|
uREPL.Log.Output($"Moved {count} blocks");
|
|
}
|
|
|
|
// Move block with highest index by vector (x,y,z)
|
|
private void MoveLastBlockCommand(float x, float y, float z)
|
|
{
|
|
uint count = entitiesDB.Count<PositionEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
|
ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
|
|
if (simMode.simulationMode != SimulationMode.Build)
|
|
{
|
|
uREPL.Log.Error("Blocks can only be moved in Build Mode");
|
|
return;
|
|
}
|
|
float3 newPos = TranslateConnectedBlocks(count-1, new float3(x,y,z));
|
|
uREPL.Log.Output($"Moved block to ({newPos.x},{newPos.y},{newPos.z})");
|
|
}
|
|
|
|
// Move the block denoted by blockID by translationVector (old_position += translationVector)
|
|
private float3 TranslateSingleBlock(uint blockID, float3 translationVector)
|
|
{
|
|
ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntity<PositionEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
|
ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntity<GridRotationStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
|
ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntity<LocalTransformEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
|
ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntity<UECSPhysicsEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
|
// main (persistent) position
|
|
posStruct.position.x += translationVector.x;
|
|
posStruct.position.y += translationVector.y;
|
|
posStruct.position.z += translationVector.z;
|
|
// placement grid position
|
|
gridStruct.position.x += translationVector.x;
|
|
gridStruct.position.y += translationVector.y;
|
|
gridStruct.position.z += translationVector.z;
|
|
// rendered position
|
|
transStruct.position.x += translationVector.x;
|
|
transStruct.position.y += translationVector.y;
|
|
transStruct.position.z += translationVector.z;
|
|
// collision position
|
|
this.physWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Translation
|
|
{
|
|
Value = posStruct.position
|
|
});
|
|
return posStruct.position;
|
|
}
|
|
|
|
private float3 TranslateConnectedBlocks(uint blockID, float3 translationVector)
|
|
{
|
|
//float3 newPosition = TranslateSingleBlock(blockID, translationVector);
|
|
HashSet<uint> processedCubes = new HashSet<uint>();
|
|
Stack<uint> cubeStack = new Stack<uint>();
|
|
cubeStack.Push(blockID);
|
|
uint count;
|
|
GridConnectionsEntityStruct blockConnections;
|
|
MachineGraphConnectionEntityStruct[] connections;
|
|
|
|
while (cubeStack.Count > 0) // find all inter-connected blocks
|
|
{
|
|
uint connectedBlockID = cubeStack.Pop();
|
|
processedCubes.Add(connectedBlockID);
|
|
ScalingEntityStruct scale = entitiesDB.QueryEntity<ScalingEntityStruct>(connectedBlockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
|
//uREPL.Log.Output($"Catching {connectedBlockID} with scale {scale.scale}");
|
|
blockConnections = entitiesDB.QueryEntity<GridConnectionsEntityStruct>(connectedBlockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
|
connections = entitiesDB.QueryEntities<MachineGraphConnectionEntityStruct>(blockConnections.connectionGroup, out count);
|
|
|
|
foreach (MachineGraphConnectionEntityStruct conn in connections)
|
|
{
|
|
if (!processedCubes.Contains(conn.connectedBlock.entityID)
|
|
&& blockConnections.isConnectionGroupAssigned
|
|
&& (conn.oppositeConnectionEgid.entityID != 0u
|
|
|| conn.oppositeConnectionEgid.entityID != conn.connectedBlock.entityID))
|
|
{
|
|
//uREPL.Log.Output($"Block {connectedBlockID} connects to {conn.connectedBlock.entityID} (opposite {conn.oppositeConnectionEgid.entityID})");
|
|
cubeStack.Push(conn.connectedBlock.entityID);
|
|
}
|
|
}
|
|
}
|
|
foreach (uint id in processedCubes)
|
|
{
|
|
TranslateSingleBlock(id, translationVector);
|
|
}
|
|
//uREPL.Log.Output($"Found {processedCubes.Count} connected blocks");
|
|
return this.entitiesDB.QueryEntity<PositionEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).position;
|
|
}
|
|
|
|
public override void Dispose()
|
|
{
|
|
CustomCommandUtility.Unregister("MoveBlocks");
|
|
CustomCommandUtility.Unregister("MoveLastBlock");
|
|
}
|
|
}
|
|
}
|