|
|
@@ -3,6 +3,7 @@ using System.Collections.Generic; |
|
|
|
using RobocraftX.Multiplayer; |
|
|
|
using RobocraftX.Common; |
|
|
|
using RobocraftX.Blocks; |
|
|
|
using RobocraftX.Blocks.Ghost; |
|
|
|
using Svelto.ECS; |
|
|
|
using Svelto.ECS.EntityStructs; |
|
|
|
using Unity.Entities; |
|
|
@@ -13,13 +14,17 @@ using RobocraftX.SimulationModeState; |
|
|
|
using RobocraftX.UECS; |
|
|
|
using Unity.Transforms; |
|
|
|
using Unity.Mathematics; |
|
|
|
using UnityEngine; |
|
|
|
|
|
|
|
namespace ExtraCommands.Building |
|
|
|
{ |
|
|
|
[CustomCommand("MoveBlocks", "Move all blocks (including ground) from their original position")] |
|
|
|
[CustomCommand("MoveLastBlock", "Move last block from original position")] |
|
|
|
[CustomCommand("MoveLastBlock", "Move last block from their original position")] |
|
|
|
[CustomCommand("MoveNearBlock", "Move blocks attached to your ghost block from their original position")] |
|
|
|
[CustomCommand("SetNearThreshold", "Set the threshold for a block to be considered 'near' to the ghost block")] |
|
|
|
class MoveBlocksCommandEngine : CustomCommandEngine |
|
|
|
{ |
|
|
|
private float nearbyThreshold = 0.2f; |
|
|
|
public MoveBlocksCommandEngine(UnityContext<FullGameCompositionRoot> ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams) |
|
|
|
{ |
|
|
|
} |
|
|
@@ -27,7 +32,9 @@ namespace ExtraCommands.Building |
|
|
|
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"); |
|
|
|
CustomCommandUtility.Register<float, float, float>("MoveLastBlock", MoveLastBlockCommand, "Move last block from their original position"); |
|
|
|
//CustomCommandUtility.Register<float, float, float>("MoveNearBlock", MoveNearbyBlockCommand, "Move blocks near your ghost block from their original position"); |
|
|
|
//CustomCommandUtility.Register<float>("SetNearThreshold", (float t)=> { this.nearbyThreshold = t; }, "Set the threshold for a block to be considered 'near' to the ghost block"); |
|
|
|
} |
|
|
|
|
|
|
|
// Move every block by vector (x,y,z) |
|
|
@@ -51,17 +58,61 @@ namespace ExtraCommands.Building |
|
|
|
// 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); |
|
|
|
//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)); |
|
|
|
float3 newPos = TranslateConnectedBlocks(CommonExclusiveGroups.CurrentBlockEntityID-1, new float3(x,y,z)); |
|
|
|
uREPL.Log.Output($"Moved block to ({newPos.x},{newPos.y},{newPos.z})"); |
|
|
|
} |
|
|
|
|
|
|
|
private void MoveNearbyBlockCommand(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; |
|
|
|
} |
|
|
|
// get ghost block data |
|
|
|
uint ghostCount; |
|
|
|
uint ghostBlockIndex = 0; |
|
|
|
Vector3 ghostLocation = Vector3.zero; |
|
|
|
PositionEntityStruct[] ghostBlockPositions = entitiesDB.QueryEntities<PositionEntityStruct>(GHOST_BLOCKS.GHOST_GROUPS_INCLUDING_INVISIBLE[0], out ghostCount); |
|
|
|
for (uint i = 0; i < ghostCount; i++) |
|
|
|
{ |
|
|
|
ref PositionEntityStruct pacman = ref ghostBlockPositions[i]; |
|
|
|
if ((Vector3)pacman.position != Vector3.zero) |
|
|
|
{ |
|
|
|
ghostLocation = pacman.position; |
|
|
|
ghostBlockIndex = i; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if (ghostLocation == Vector3.zero) |
|
|
|
{ |
|
|
|
uREPL.Log.Output("Ghost block not found; nothing moved"); |
|
|
|
return; |
|
|
|
} |
|
|
|
uint count; |
|
|
|
PositionEntityStruct[] positions = entitiesDB.QueryEntities<PositionEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out count); |
|
|
|
for (uint i = 0; i < count; i++) |
|
|
|
{ |
|
|
|
if (Math.Abs(positions[i].position.x - ghostLocation.x) < nearbyThreshold |
|
|
|
&& Math.Abs(positions[i].position.y - ghostLocation.y) < nearbyThreshold |
|
|
|
&& Math.Abs(positions[i].position.z - ghostLocation.z) < nearbyThreshold) |
|
|
|
{ |
|
|
|
float3 newPos = TranslateConnectedBlocks(i, new float3(x, y, z)); |
|
|
|
uREPL.Log.Output($"Moved block to ({newPos.x},{newPos.y},{newPos.z})"); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
uREPL.Log.Output("No block found near ghost block"); |
|
|
|
} |
|
|
|
|
|
|
|
// Move the block denoted by blockID by translationVector (old_position += translationVector) |
|
|
|
private float3 TranslateSingleBlock(uint blockID, float3 translationVector) |
|
|
|
{ |
|
|
@@ -91,27 +142,36 @@ namespace ExtraCommands.Building |
|
|
|
|
|
|
|
private float3 TranslateConnectedBlocks(uint blockID, float3 translationVector) |
|
|
|
{ |
|
|
|
uREPL.Log.Output($"Last block id {CommonExclusiveGroups.CurrentBlockEntityID}, chosen {blockID}"); |
|
|
|
//float3 newPosition = TranslateSingleBlock(blockID, translationVector); |
|
|
|
HashSet<uint> processedCubes = new HashSet<uint>(); |
|
|
|
//HashSet<uint> processedCubes = new HashSet<uint>(); |
|
|
|
Stack<uint> cubeStack = new Stack<uint>(); |
|
|
|
cubeStack.Push(blockID); |
|
|
|
uint count; |
|
|
|
GridConnectionsEntityStruct blockConnections; |
|
|
|
MachineGraphConnectionEntityStruct[] connections; |
|
|
|
//cubeStack.Push(blockID); |
|
|
|
//uint count; |
|
|
|
//GridConnectionsEntityStruct[] blockConnections; |
|
|
|
//MachineGraphConnectionEntityStruct[] connections; |
|
|
|
|
|
|
|
Svelto.DataStructures.FasterList<uint> cubesToMove = new Svelto.DataStructures.FasterList<uint>(); |
|
|
|
ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID, cubeStack, cubesToMove, (in GridConnectionsEntityStruct g) => { return false; }); |
|
|
|
for(int i = 0; i < cubesToMove.Count; i++) { |
|
|
|
TranslateSingleBlock(cubesToMove[i], translationVector); |
|
|
|
entitiesDB.QueryEntity<GridConnectionsEntityStruct>(cubesToMove[i], CommonExclusiveGroups.OWNED_BLOCKS_GROUP).isProcessed = false; |
|
|
|
} |
|
|
|
/* |
|
|
|
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); |
|
|
|
//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); |
|
|
|
uint index; |
|
|
|
blockConnections = entitiesDB.QueryEntitiesAndIndex<GridConnectionsEntityStruct>(connectedBlockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out index); |
|
|
|
connections = entitiesDB.QueryEntities<MachineGraphConnectionEntityStruct>(blockConnections[(int)index].connectionGroup, out count); |
|
|
|
|
|
|
|
foreach (MachineGraphConnectionEntityStruct conn in connections) |
|
|
|
{ |
|
|
|
if (!processedCubes.Contains(conn.connectedBlock.entityID) |
|
|
|
&& blockConnections.isConnectionGroupAssigned |
|
|
|
&& blockConnections[(int)index].isConnectionGroupAssigned |
|
|
|
&& (conn.oppositeConnectionEgid.entityID != 0u |
|
|
|
|| conn.oppositeConnectionEgid.entityID != conn.connectedBlock.entityID)) |
|
|
|
{ |
|
|
@@ -123,8 +183,8 @@ namespace ExtraCommands.Building |
|
|
|
foreach (uint id in processedCubes) |
|
|
|
{ |
|
|
|
TranslateSingleBlock(id, translationVector); |
|
|
|
} |
|
|
|
//uREPL.Log.Output($"Found {processedCubes.Count} connected blocks"); |
|
|
|
}*/ |
|
|
|
uREPL.Log.Output($"Found {cubesToMove.Count} connected blocks"); |
|
|
|
return this.entitiesDB.QueryEntity<PositionEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).position; |
|
|
|
} |
|
|
|
|
|
|
@@ -132,6 +192,8 @@ namespace ExtraCommands.Building |
|
|
|
{ |
|
|
|
CustomCommandUtility.Unregister("MoveBlocks"); |
|
|
|
CustomCommandUtility.Unregister("MoveLastBlock"); |
|
|
|
//CustomCommandUtility.Unregister("MoveNearBlock"); |
|
|
|
//CustomCommandUtility.Unregister("SetNearThreshold"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |