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.

164 lines
4.9KB

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