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.

192 lines
7.1KB

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