Moar Gamecraft commands!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
8.9KB

  1. using System;
  2. using System.Collections.Generic;
  3. using RobocraftX.Multiplayer;
  4. using RobocraftX.Common;
  5. using Svelto.ECS;
  6. using Svelto.ECS.EntityStructs;
  7. using Unity.Entities;
  8. using Svelto.Context;
  9. using Svelto.Tasks;
  10. using RobocraftX;
  11. using RobocraftX.SimulationModeState;
  12. using RobocraftX.UECS;
  13. using Unity.Transforms;
  14. using Unity.Mathematics;
  15. using UnityEngine;
  16. namespace ExtraCommands.Building
  17. {
  18. [CustomCommand("RotateBlocks", "Rotate all blocks (including ground) from their original position")]
  19. [CustomCommand("RotateLastBlock", "Rotate last block from original position")]
  20. class RotateBlocksCommandEngine : CustomCommandEngine
  21. {
  22. public RotateBlocksCommandEngine(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>("RotateBlocks", RotateBlocksCommand, "Rotate all blocks (including ground) from their original position");
  28. CustomCommandUtility.Register<float, float, float>("RotateLastBlock", RotateLastBlockCommand, "Rotate last block from original position");
  29. }
  30. // Move every block by vector (x,y,z)
  31. private void RotateBlocksCommand(float x, float y, float z)
  32. {
  33. Vector3 eulerAngles = new Vector3(x, y, z);
  34. ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
  35. if (simMode.simulationMode != SimulationMode.Build)
  36. {
  37. uREPL.Log.Error("Blocks can only be moved in Build Mode");
  38. return;
  39. }
  40. uint rotCount, gridCount, transCount, phyCount;
  41. RotationEntityStruct[] rotStructs = this.entitiesDB.QueryEntities<RotationEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out rotCount);
  42. GridRotationStruct[] gridStructs = this.entitiesDB.QueryEntities<GridRotationStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out gridCount);
  43. LocalTransformEntityStruct[] transStructs = this.entitiesDB.QueryEntities<LocalTransformEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out transCount);
  44. UECSPhysicsEntityStruct[] phyStructs = this.entitiesDB.QueryEntities<UECSPhysicsEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out phyCount);
  45. if (rotCount != transCount || transCount != phyCount)
  46. {
  47. uREPL.Log.Error("Block lists returned are not the same length!"); // they're arrays, not lists
  48. return;
  49. }
  50. for (uint i = 0; i < rotCount; i++)
  51. {
  52. ref RotationEntityStruct rotStruct = ref rotStructs[i]; // main (persistent) rotation
  53. Quaternion newRotation = (Quaternion)rotStruct.rotation;
  54. newRotation.eulerAngles += eulerAngles;
  55. rotStruct.rotation = (quaternion)newRotation;
  56. ref GridRotationStruct gridStruct = ref gridStructs[i]; // placement grid rotation
  57. Quaternion newGridRotation = (Quaternion)gridStruct.rotation;
  58. newGridRotation.eulerAngles += eulerAngles;
  59. gridStruct.rotation = (quaternion)newGridRotation;
  60. ref LocalTransformEntityStruct transStruct = ref transStructs[i]; // rendered position
  61. Quaternion newTransRotation = (Quaternion)rotStruct.rotation;
  62. newTransRotation.eulerAngles += eulerAngles;
  63. transStruct.rotation = newTransRotation;
  64. ref UECSPhysicsEntityStruct phyStruct = ref phyStructs[i]; // collision position
  65. this.physWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Rotation
  66. {
  67. Value = rotStruct.rotation
  68. });
  69. }
  70. uREPL.Log.Output($"Moved {rotCount} blocks");
  71. }
  72. // Move block with highest index by vector (x,y,z)
  73. private void RotateLastBlockCommand(float x, float y, float z)
  74. {
  75. Vector3 eulerAngles = new Vector3(x, y, z);
  76. ref SimulationModeStateEntityStruct simMode = ref this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
  77. if (simMode.simulationMode != SimulationMode.Build)
  78. {
  79. uREPL.Log.Error("Blocks can only be moved in Build Mode");
  80. return;
  81. }
  82. uint rotCount, gridCount, transCount, phyCount;
  83. RotationEntityStruct[] rotStructs = this.entitiesDB.QueryEntities<RotationEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out rotCount);
  84. GridRotationStruct[] gridStructs = this.entitiesDB.QueryEntities<GridRotationStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out gridCount);
  85. LocalTransformEntityStruct[] transStructs = this.entitiesDB.QueryEntities<LocalTransformEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out transCount);
  86. UECSPhysicsEntityStruct[] phyStructs = this.entitiesDB.QueryEntities<UECSPhysicsEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP, out phyCount);
  87. if (rotCount == 0 || gridCount == 0 || transCount == 0 || phyCount == 0)
  88. {
  89. uREPL.Log.Error("No block found");
  90. return;
  91. }
  92. ref RotationEntityStruct rotStruct = ref rotStructs[rotCount-1]; // main (persistent) position
  93. Quaternion newRotation = (Quaternion)rotStruct.rotation;
  94. newRotation.eulerAngles += eulerAngles;
  95. rotStruct.rotation = (quaternion)newRotation;
  96. ref GridRotationStruct gridStruct = ref gridStructs[gridCount-1]; // placement grid rotation
  97. Quaternion newGridRotation = (Quaternion)gridStruct.rotation;
  98. newGridRotation.eulerAngles += eulerAngles;
  99. gridStruct.rotation = (quaternion)newGridRotation;
  100. ref LocalTransformEntityStruct transStruct = ref transStructs[transCount-1]; // rendered position
  101. Quaternion newTransRotation = (Quaternion)rotStruct.rotation;
  102. newTransRotation.eulerAngles += eulerAngles;
  103. transStruct.rotation = newTransRotation;
  104. ref UECSPhysicsEntityStruct phyStruct = ref phyStructs[phyCount-1]; // collision position
  105. this.physWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Rotation
  106. {
  107. Value = rotStruct.rotation
  108. });
  109. uREPL.Log.Output($"Rotated block to ({rotStruct.rotation.value.x},{rotStruct.rotation.value.y},{rotStruct.rotation.value.z})");
  110. }
  111. // unused; for future reference
  112. private void ToggleMode()
  113. {
  114. ref SimulationModeStateEntityStruct ptr = ref this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
  115. ref SimulationFrameEntityStruct ptr2 = ref this.entitiesDB.QueryUniqueEntity<SimulationFrameEntityStruct>(SimulationFrame.SimulationFrameGroup);
  116. switch (ptr.simulationMode)
  117. {
  118. case SimulationMode.Build:
  119. ptr.simulationMode = SimulationMode.SwitchToSim;
  120. ptr.simulationModeChangeFrame = ptr2.simFrame;
  121. return;
  122. case SimulationMode.SwitchToSim:
  123. case SimulationMode.SwitchToBuild:
  124. return;
  125. case SimulationMode.Simulation:
  126. ptr.simulationMode = SimulationMode.SwitchToBuild;
  127. ptr.simulationModeChangeFrame = ptr2.simFrame;
  128. ptr.rigidBodiesCreated = false;
  129. return;
  130. default:
  131. throw new ArgumentOutOfRangeException();
  132. }
  133. }
  134. // unused; for future reference
  135. private IEnumerator<TaskContract> TriggerSwitchToSimTask()
  136. {
  137. this.ToggleMode();
  138. yield break;
  139. }
  140. // unused; for future reference
  141. private IEnumerator<TaskContract> WaitThenTriggerSwitchToBuildTask()
  142. {
  143. while (true)
  144. {
  145. SimulationModeStateEntityStruct modeStruct = this.entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP);
  146. if (modeStruct.simulationMode == SimulationMode.Simulation)
  147. {
  148. this.ToggleMode();
  149. break;
  150. } else
  151. {
  152. yield return Yield.It;
  153. }
  154. }
  155. yield break;
  156. }
  157. public override void Dispose()
  158. {
  159. CustomCommandUtility.Unregister("MoveBlocks");
  160. CustomCommandUtility.Unregister("MoveLastBlock");
  161. }
  162. }
  163. }