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.

146 lines
4.5KB

  1. using Svelto.ECS;
  2. using Gamecraft.Wires;
  3. using GamecraftModdingAPI.Engines;
  4. namespace GamecraftModdingAPI.Blocks
  5. {
  6. /// <summary>
  7. /// Engine which executes signal actions
  8. /// </summary>
  9. public class SignalEngine : IApiEngine
  10. {
  11. public string Name { get; } = "GamecraftModdingAPISignalGameEngine";
  12. public EntitiesDB entitiesDB { set; private get; }
  13. public bool isRemovable => false;
  14. public bool IsInGame = false;
  15. public void Dispose()
  16. {
  17. IsInGame = false;
  18. }
  19. public void Ready()
  20. {
  21. IsInGame = true;
  22. }
  23. // implementations for Signal static class
  24. public bool SetSignal(EGID blockID, float signal, out uint signalID, bool input = true)
  25. {
  26. signalID = GetSignalIDs(blockID, input)[0];
  27. return SetSignal(signalID, signal);
  28. }
  29. public bool SetSignal(uint signalID, float signal, bool input = true)
  30. {
  31. var array = GetSignalStruct(signalID, out uint index, input);
  32. if (array != null) array[index].valueAsFloat = signal;
  33. return false;
  34. }
  35. public float AddSignal(EGID blockID, float signal, out uint signalID, bool clamp = true, bool input = true)
  36. {
  37. signalID = GetSignalIDs(blockID, input)[0];
  38. return AddSignal(signalID, signal, clamp, input);
  39. }
  40. public float AddSignal(uint signalID, float signal, bool clamp = true, bool input = true)
  41. {
  42. var array = GetSignalStruct(signalID, out uint index, input);
  43. if (array != null)
  44. {
  45. ref var channelData = ref array[index];
  46. channelData.valueAsFloat += signal;
  47. if (clamp)
  48. {
  49. if (channelData.valueAsFloat > Signals.POSITIVE_HIGH)
  50. {
  51. channelData.valueAsFloat = Signals.POSITIVE_HIGH;
  52. }
  53. else if (channelData.valueAsFloat < Signals.NEGATIVE_HIGH)
  54. {
  55. channelData.valueAsFloat = Signals.NEGATIVE_HIGH;
  56. }
  57. return channelData.valueAsFloat;
  58. }
  59. }
  60. return signal;
  61. }
  62. public float GetSignal(EGID blockID, out uint signalID, bool input = true)
  63. {
  64. signalID = GetSignalIDs(blockID, input)[0];
  65. return GetSignal(signalID, input);
  66. }
  67. public float GetSignal(uint signalID, bool input = true)
  68. {
  69. var array = GetSignalStruct(signalID, out uint index, input);
  70. return array?[index].valueAsFloat ?? 0f;
  71. }
  72. public uint[] GetSignalIDs(EGID blockID, bool input = true)
  73. {
  74. ref BlockPortsStruct bps = ref entitiesDB.QueryEntity<BlockPortsStruct>(blockID);
  75. uint[] signals;
  76. if (input) {
  77. signals = new uint[bps.inputCount];
  78. for (uint i = 0u; i < bps.inputCount; i++)
  79. {
  80. signals[i] = bps.firstInputID + i;
  81. }
  82. } else {
  83. signals = new uint[bps.outputCount];
  84. for (uint i = 0u; i < bps.outputCount; i++)
  85. {
  86. signals[i] = bps.firstOutputID + i;
  87. }
  88. }
  89. return signals;
  90. }
  91. public EGID[] GetElectricBlocks()
  92. {
  93. uint count = entitiesDB.Count<BlockPortsStruct>(BlockIdentifiers.OWNED_BLOCKS) + entitiesDB.Count<BlockPortsStruct>(BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS);
  94. uint i = 0;
  95. EGID[] res = new EGID[count];
  96. foreach (ref BlockPortsStruct s in entitiesDB.QueryEntities<BlockPortsStruct>(BlockIdentifiers.OWNED_BLOCKS))
  97. {
  98. res[i] = s.ID;
  99. i++;
  100. }
  101. foreach (ref BlockPortsStruct s in entitiesDB.QueryEntities<BlockPortsStruct>(BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS))
  102. {
  103. res[i] = s.ID;
  104. i++;
  105. }
  106. return res;
  107. }
  108. private ChannelDataStruct[] GetSignalStruct(uint signalID, out uint index, bool input = true)
  109. {
  110. ExclusiveGroup group = input
  111. ? NamedExclusiveGroup<InputPortsGroup>.Group
  112. : NamedExclusiveGroup<OutputPortsGroup>.Group;
  113. if (entitiesDB.Exists<PortEntityStruct>(signalID, group))
  114. {
  115. index = entitiesDB.QueryEntity<PortEntityStruct>(signalID, group).anyChannelIndex;
  116. ChannelDataStruct[] channelData = entitiesDB
  117. .QueryEntities<ChannelDataStruct>(NamedExclusiveGroup<ChannelDataGroup>.Group)
  118. .ToFastAccess(out uint _);
  119. return channelData;
  120. }
  121. index = 0;
  122. return null;
  123. }
  124. }
  125. }