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.

167 lines
5.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 Gamecraft.Wires;
  22. using GamecraftModdingAPI.Utility;
  23. using GamecraftModdingAPI.Engines;
  24. namespace GamecraftModdingAPI.Blocks
  25. {
  26. /// <summary>
  27. /// Engine which executes signal actions
  28. /// </summary>
  29. public class SignalEngine : IApiEngine
  30. {
  31. public string Name { get; } = "GamecraftModdingAPISignalGameEngine";
  32. public EntitiesDB entitiesDB { set; private get; }
  33. public bool isRemovable => false;
  34. public bool IsInGame = 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(EGID blockID, float signal, out uint signalID, bool input = true)
  45. {
  46. signalID = GetSignalIDs(blockID, input)[0];
  47. return SetSignal(signalID, signal);
  48. }
  49. public bool SetSignal(uint signalID, float signal, bool input = true)
  50. {
  51. var array = GetSignalStruct(signalID, out uint index, input);
  52. if (array != null) array[index].valueAsFloat = signal;
  53. return false;
  54. }
  55. public float AddSignal(EGID blockID, float signal, out uint signalID, bool clamp = true, bool input = true)
  56. {
  57. signalID = GetSignalIDs(blockID, input)[0];
  58. return AddSignal(signalID, signal, clamp, input);
  59. }
  60. public float AddSignal(uint signalID, float signal, bool clamp = true, bool input = true)
  61. {
  62. var array = GetSignalStruct(signalID, out uint index, input);
  63. if (array != null)
  64. {
  65. ref var channelData = ref array[index];
  66. channelData.valueAsFloat += signal;
  67. if (clamp)
  68. {
  69. if (channelData.valueAsFloat > Signals.POSITIVE_HIGH)
  70. {
  71. channelData.valueAsFloat = Signals.POSITIVE_HIGH;
  72. }
  73. else if (channelData.valueAsFloat < Signals.NEGATIVE_HIGH)
  74. {
  75. channelData.valueAsFloat = Signals.NEGATIVE_HIGH;
  76. }
  77. return channelData.valueAsFloat;
  78. }
  79. }
  80. return signal;
  81. }
  82. public float GetSignal(EGID blockID, out uint signalID, bool input = true)
  83. {
  84. signalID = GetSignalIDs(blockID, input)[0];
  85. return GetSignal(signalID, input);
  86. }
  87. public float GetSignal(uint signalID, bool input = true)
  88. {
  89. var array = GetSignalStruct(signalID, out uint index, input);
  90. return array?[index].valueAsFloat ?? 0f;
  91. }
  92. public uint[] GetSignalIDs(EGID blockID, bool input = true)
  93. {
  94. ref BlockPortsStruct bps = ref entitiesDB.QueryEntity<BlockPortsStruct>(blockID);
  95. uint[] signals;
  96. if (input) {
  97. signals = new uint[bps.inputCount];
  98. for (uint i = 0u; i < bps.inputCount; i++)
  99. {
  100. signals[i] = bps.firstInputID + i;
  101. }
  102. } else {
  103. signals = new uint[bps.outputCount];
  104. for (uint i = 0u; i < bps.outputCount; i++)
  105. {
  106. signals[i] = bps.firstOutputID + i;
  107. }
  108. }
  109. return signals;
  110. }
  111. public EGID[] GetElectricBlocks()
  112. {
  113. uint count = entitiesDB.Count<BlockPortsStruct>(BlockIdentifiers.OWNED_BLOCKS) + entitiesDB.Count<BlockPortsStruct>(BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS);
  114. uint i = 0;
  115. EGID[] res = new EGID[count];
  116. foreach (ref BlockPortsStruct s in entitiesDB.QueryEntities<BlockPortsStruct>(BlockIdentifiers.OWNED_BLOCKS))
  117. {
  118. res[i] = s.ID;
  119. i++;
  120. }
  121. foreach (ref BlockPortsStruct s in entitiesDB.QueryEntities<BlockPortsStruct>(BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS))
  122. {
  123. res[i] = s.ID;
  124. i++;
  125. }
  126. return res;
  127. }
  128. private ChannelDataStruct[] GetSignalStruct(uint signalID, out uint index, bool input = true)
  129. {
  130. ExclusiveGroup group = input
  131. ? NamedExclusiveGroup<InputPortsGroup>.Group
  132. : NamedExclusiveGroup<OutputPortsGroup>.Group;
  133. if (entitiesDB.Exists<PortEntityStruct>(signalID, group))
  134. {
  135. index = entitiesDB.QueryEntity<PortEntityStruct>(signalID, group).anyChannelIndex;
  136. ChannelDataStruct[] channelData = entitiesDB
  137. .QueryEntities<ChannelDataStruct>(NamedExclusiveGroup<ChannelDataGroup>.Group)
  138. .ToFastAccess(out uint _);
  139. return channelData;
  140. }
  141. index = 0;
  142. return null;
  143. }
  144. }
  145. }