|
- using System;
- 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;
- using Svelto.Context;
- using Svelto.Tasks;
- using RobocraftX;
- 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 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)
- {
- }
-
- 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 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)
- 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(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)
- {
- 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)
- {
- uREPL.Log.Output($"Last block id {CommonExclusiveGroups.CurrentBlockEntityID}, chosen {blockID}");
- //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;
-
- Gamecraft.DataStructures.FasterList<uint> cubesToMove = new Gamecraft.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);
- //uREPL.Log.Output($"Catching {connectedBlockID} with scale {scale.scale}");
- 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[(int)index].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 {cubesToMove.Count} connected blocks");
- return this.entitiesDB.QueryEntity<PositionEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).position;
- }
-
- public override void Dispose()
- {
- CustomCommandUtility.Unregister("MoveBlocks");
- CustomCommandUtility.Unregister("MoveLastBlock");
- //CustomCommandUtility.Unregister("MoveNearBlock");
- //CustomCommandUtility.Unregister("SetNearThreshold");
- }
- }
- }
|