Moar Gamecraft commands!
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
7.5KB

  1. using System;
  2. using System.Collections.Generic;
  3. using RobocraftX.Multiplayer;
  4. using RobocraftX.Common;
  5. using RobocraftX.Blocks;
  6. using Svelto.ECS;
  7. using Svelto.ECS.EntityStructs;
  8. using Unity.Entities;
  9. using Svelto.Context;
  10. using Svelto.DataStructures;
  11. using Svelto.Tasks;
  12. using RobocraftX;
  13. using RobocraftX.SimulationModeState;
  14. using RobocraftX.UECS;
  15. using Unity.Transforms;
  16. namespace ExtraCommands.Building
  17. {
  18. [CustomCommand("MoveBlocks", "Move all blocks (including ground) from their original position")]
  19. [CustomCommand("MoveLastBlock", "Move last block from original position")]
  20. class MoveBlocksCommandEngine : CustomCommandEngine
  21. {
  22. public MoveBlocksCommandEngine(UnityContext<FullGameCompositionRoot> ctxHolder, EnginesRoot enginesRoot, World physW, Action reloadGame, MultiplayerInitParameters mpParams) : base(ctxHolder, enginesRoot, physW, reloadGame, mpParams)
  23. {
  24. }
  25. public override void Ready()
  26. {
  27. CustomCommandUtility.Register<float, float, float>("MoveBlocks", MoveBlocksCommand, "Move all blocks (including ground) from their original position");
  28. CustomCommandUtility.Register<float, float, float>("MoveLastBlock", MoveLastBlockCommand, "Move last block from original position");
  29. }
  30. // Move every block by vector (x,y,z)
  31. private void MoveBlocksCommand(float x, float y, float z)
  32. {
  33. ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
  34. if (simMode.simulationMode != SimulationMode.Build)
  35. {
  36. uREPL.Log.Error("Blocks can only be moved in Build Mode");
  37. return;
  38. }
  39. uint count = this.entitiesDB.Count<PositionEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
  40. float3 translationVector = new float3(x,y,z);
  41. for (uint i = 0; i < count; i++)
  42. {
  43. TranslateSingleBlock(i, translationVector);
  44. }
  45. uREPL.Log.Output($"Moved {count} blocks");
  46. }
  47. // Move block with highest index by vector (x,y,z)
  48. private void MoveLastBlockCommand(float x, float y, float z)
  49. {
  50. ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
  51. if (simMode.simulationMode != SimulationMode.Build)
  52. {
  53. uREPL.Log.Error("Blocks can only be moved in Build Mode");
  54. return;
  55. }
  56. uint count = this.entitiesDB.Count<PositionEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
  57. float3 newPos = TranslateConnectedBlocks(count-1, new float3(x,y,z));
  58. uREPL.Log.Output($"Moved block to ({newPos.x},{newPos.y},{newPos.z})");
  59. }
  60. // Move the block denoted by blockID by translationVector (old_position += translationVector)
  61. private float3 TranslateSingleBlock(uint blockID, float3 translationVector)
  62. {
  63. ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntity<PositionEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
  64. ref GridRotationStruct gridStructs = this.entitiesDB.QueryEntity<GridRotationStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
  65. ref LocalTransformEntityStruct transStructs = this.entitiesDB.QueryEntity<LocalTransformEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
  66. ref UECSPhysicsEntityStruct phyStructs = this.entitiesDB.QueryEntity<UECSPhysicsEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
  67. // main (persistent) position
  68. posStruct.position.x += translationVector.x;
  69. posStruct.position.y += translationVector.y;
  70. posStruct.position.z += translationVector.z;
  71. // placement grid position
  72. gridStruct.position.x += translationVector.x;
  73. gridStruct.position.y += translationVector.y;
  74. gridStruct.position.z += translationVector.z;
  75. // rendered position
  76. transStruct.position.x += translationVector.x;
  77. transStruct.position.y += translationVector.y;
  78. transStruct.position.z += translationVector.z;
  79. // collision position
  80. this.physWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Translation
  81. {
  82. Value = posStruct.position
  83. });
  84. return posStruct.position;
  85. }
  86. private float3 TranslateConnectedBlocks(uint blockID, float3 translationVector)
  87. {
  88. newPosition = TranslateSingleBlock(blockID, translationVector);
  89. uint count = this.entitiesDB.Count<PositionEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
  90. Stack<uint> cubeStack = new Stack<uint>(count);
  91. FasterList<uint> cubeList = new FasterList<uint>(count);
  92. ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(this.entitiesDB, blockID, cubeStack, cubeList, false /*unused*/);
  93. foreach (uint id in FasterList.ToArrayFast(cubeList))
  94. {
  95. TranslateSingleBlock(id, translationVector);
  96. }
  97. return newPosition;
  98. }
  99. // unused; for future reference
  100. private void ToggleMode()
  101. {
  102. ref SimulationModeStateEntityStruct ptr = ref this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
  103. ref SimulationFrameEntityStruct ptr2 = ref this.entitiesDB.QueryUniqueEntity<SimulationFrameEntityStruct>(SimulationFrame.SimulationFrameGroup);
  104. switch (ptr.simulationMode)
  105. {
  106. case SimulationMode.Build:
  107. ptr.simulationMode = SimulationMode.SwitchToSim;
  108. ptr.simulationModeChangeFrame = ptr2.simFrame;
  109. return;
  110. case SimulationMode.SwitchToSim:
  111. case SimulationMode.SwitchToBuild:
  112. return;
  113. case SimulationMode.Simulation:
  114. ptr.simulationMode = SimulationMode.SwitchToBuild;
  115. ptr.simulationModeChangeFrame = ptr2.simFrame;
  116. ptr.rigidBodiesCreated = false;
  117. return;
  118. default:
  119. throw new ArgumentOutOfRangeException();
  120. }
  121. }
  122. // unused; for future reference
  123. private IEnumerator<TaskContract> TriggerSwitchToSimTask()
  124. {
  125. this.ToggleMode();
  126. yield break;
  127. }
  128. // unused; for future reference
  129. private IEnumerator<TaskContract> WaitThenTriggerSwitchToBuildTask()
  130. {
  131. while (true)
  132. {
  133. SimulationModeStateEntityStruct modeStruct = this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
  134. if (modeStruct.simulationMode == SimulationMode.Simulation)
  135. {
  136. this.ToggleMode();
  137. break;
  138. } else
  139. {
  140. yield return Yield.It;
  141. }
  142. }
  143. yield break;
  144. }
  145. public override void Dispose()
  146. {
  147. CustomCommandUtility.Unregister("MoveBlocks");
  148. CustomCommandUtility.Unregister("MoveLastBlock");
  149. }
  150. }
  151. }