A stable modding interface between Techblox and mods https://mod.exmods.org/
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.

193 lines
7.0KB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using RobocraftX;
  7. using RobocraftX.Blocks;
  8. using RobocraftX.Blocks.Ghost;
  9. using RobocraftX.Common;
  10. using RobocraftX.Multiplayer;
  11. using RobocraftX.SimulationModeState;
  12. using RobocraftX.UECS;
  13. using Unity.Entities;
  14. using Svelto.Context;
  15. using Svelto.DataStructures;
  16. using Svelto.ECS;
  17. using Svelto.ECS.EntityStructs;
  18. using Unity.Transforms;
  19. using Unity.Mathematics;
  20. using UnityEngine;
  21. using GamecraftModdingAPI.Utility;
  22. namespace GamecraftModdingAPI.Blocks
  23. {
  24. /// <summary>
  25. /// Engine which executes signal actions
  26. /// </summary>
  27. public class SignalEngine : IApiEngine
  28. {
  29. public string Name { get; } = "GamecraftModdingAPISignalGameEngine";
  30. public IEntitiesDB entitiesDB { set; private get; }
  31. public bool IsInGame = false;
  32. private Stack<uint> cubesStack = new Stack<uint>();
  33. private bool stackInUse = false;
  34. private FasterList<uint> cubesList = new FasterList<uint>();
  35. private bool listInUse = false;
  36. public void Dispose()
  37. {
  38. IsInGame = false;
  39. }
  40. public void Ready()
  41. {
  42. IsInGame = true;
  43. }
  44. // implementations for Signal static class
  45. public bool SetSignal(uint blockID, uint channel, float signal, out EGID clusterID)
  46. {
  47. clusterID = GetClusterEGID(blockID, channel);
  48. return SetSignal(clusterID, signal);
  49. }
  50. public bool SetSignal(EGID clusterID, float signal)
  51. {
  52. if (entitiesDB.Exists<ChannelOutputSignalDataStruct>(clusterID))
  53. {
  54. entitiesDB.QueryEntity<ChannelOutputSignalDataStruct>(clusterID).outputSignal = signal;
  55. return true;
  56. }
  57. return false;
  58. }
  59. public float AddSignal(uint blockID, uint channel, float signal, out EGID clusterID, bool clamp = true)
  60. {
  61. clusterID = GetClusterEGID(blockID, channel);
  62. return AddSignal(clusterID, signal, clamp);
  63. }
  64. public float AddSignal(EGID clusterID, float signal, bool clamp=true)
  65. {
  66. if (entitiesDB.Exists<ChannelOutputSignalDataStruct>(clusterID))
  67. {
  68. ref ChannelOutputSignalDataStruct chanOutSig = ref entitiesDB.QueryEntity<ChannelOutputSignalDataStruct>(clusterID);
  69. chanOutSig.outputSignal += signal;
  70. if (clamp)
  71. {
  72. if (chanOutSig.outputSignal > Signals.POSITIVE_HIGH)
  73. {
  74. chanOutSig.outputSignal = Signals.POSITIVE_HIGH;
  75. }
  76. else if (chanOutSig.outputSignal < Signals.NEGATIVE_HIGH)
  77. {
  78. chanOutSig.outputSignal = Signals.NEGATIVE_HIGH;
  79. }
  80. return chanOutSig.outputSignal;
  81. }
  82. }
  83. return signal;
  84. }
  85. public float GetSignal(uint blockID, uint channel, out EGID clusterID)
  86. {
  87. clusterID = GetClusterEGID(blockID, channel);
  88. return GetSignal(clusterID);
  89. }
  90. public float GetSignal(EGID clusterID)
  91. {
  92. if (entitiesDB.Exists<ChannelOutputSignalDataStruct>(clusterID))
  93. {
  94. return entitiesDB.QueryEntity<ChannelOutputSignalDataStruct>(clusterID).outputSignal;
  95. }
  96. return 0f;
  97. }
  98. public EGID GetClusterEGID(uint blockID, uint channel)
  99. {
  100. //uint[] connectedCubeIDs = GetConductivelyConnectedBlocks(blockID);
  101. //uint index;
  102. //ElectricityEntityStruct[] structs;
  103. EGID elecEGID = new EGID(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
  104. if (!entitiesDB.Exists<ElectricityEntityStruct>(elecEGID))
  105. {
  106. elecEGID = new EGID(blockID, CommonExclusiveGroups.FUNCTIONAL_BLOCK_PART_GROUP);
  107. }
  108. if (!entitiesDB.Exists<ElectricityEntityStruct>(elecEGID))
  109. {
  110. return default;
  111. }
  112. ref ElectricityEntityStruct eStruct = ref entitiesDB.QueryEntity<ElectricityEntityStruct>(elecEGID);
  113. ref ConductiveClusterID clusterId = ref entitiesDB.QueryEntity<ConductiveClusterIdStruct>(eStruct.ID).clusterId;
  114. uint operatingChannel = entitiesDB.QueryEntity<SignalOperatingChannelStruct>(eStruct.ID).operatingChannel;
  115. EGID eGID = new EGID(channel, BlockIdentifiers.OUTPUT_SIGNAL_CHANNELS + clusterId.ID);
  116. if (clusterId.initialized && clusterId.isConductive && entitiesDB.Exists<ChannelOutputSignalDataStruct>(eGID))
  117. {
  118. return eGID;
  119. }
  120. return default;
  121. }
  122. public uint[] GetElectricBlocks()
  123. {
  124. uint count = entitiesDB.Count<ElectricityEntityStruct>(CommonExclusiveGroups.FUNCTIONAL_CUBES_IN_BOTH_SIM_AND_BUILD[0])
  125. + entitiesDB.Count<ElectricityEntityStruct>(CommonExclusiveGroups.FUNCTIONAL_CUBES_IN_BOTH_SIM_AND_BUILD[1]);
  126. uint i = 0;
  127. uint[] res = new uint[count];
  128. foreach (ref var ees in entitiesDB.QueryEntities<ElectricityEntityStruct>(CommonExclusiveGroups.FUNCTIONAL_CUBES_IN_BOTH_SIM_AND_BUILD))
  129. {
  130. res[i] = ees.ID.entityID;
  131. i++;
  132. }
  133. return res;
  134. }
  135. private uint[] GetConductivelyConnectedBlocks(uint blockID)
  136. {
  137. if (!(stackInUse || listInUse))
  138. {
  139. stackInUse = true;
  140. listInUse = true;
  141. cubesStack.Clear();
  142. cubesList.FastClear();
  143. ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID, cubesStack, cubesList, (in GridConnectionsEntityStruct g) => { return g.isIsolator; });
  144. uint[] res = cubesList.ToArray();
  145. stackInUse = false;
  146. listInUse = false;
  147. foreach (var id in res)
  148. {
  149. entitiesDB.QueryEntity<GridConnectionsEntityStruct>(id, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).isProcessed = false;
  150. }
  151. return res;
  152. }
  153. else
  154. {
  155. Stack<uint> cubeStack = new Stack<uint>();
  156. FasterList<uint> cubeList = new FasterList<uint>();
  157. ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID, cubesStack, cubesList, (in GridConnectionsEntityStruct g) => { return g.isIsolator; });
  158. uint[] res = cubesList.ToArray();
  159. foreach (var id in res)
  160. {
  161. entitiesDB.QueryEntity<GridConnectionsEntityStruct>(id, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).isProcessed = false;
  162. }
  163. return res;
  164. }
  165. }
  166. public bool IsSimulationMode()
  167. {
  168. return GamecraftModdingAPI.Utility.GameState.IsSimulationMode();
  169. }
  170. }
  171. }