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.

175 lines
5.3KB

  1. using System.Collections.Generic;
  2. using Gamecraft.Wires;
  3. using RobocraftX.Blocks;
  4. using RobocraftX.Common;
  5. using RobocraftX.GUI.Hotbar.Colours;
  6. using RobocraftX.Physics;
  7. using RobocraftX.Scene.Simulation;
  8. using Svelto.DataStructures;
  9. using Svelto.ECS;
  10. using GamecraftModdingAPI.Engines;
  11. using GamecraftModdingAPI.Utility;
  12. namespace GamecraftModdingAPI.Blocks
  13. {
  14. /// <summary>
  15. /// Engine for executing general block actions
  16. /// </summary>
  17. public class BlockEngine : IApiEngine
  18. {
  19. public string Name { get; } = "GamecraftModdingAPIBlockGameEngine";
  20. public EntitiesDB entitiesDB { set; private get; }
  21. public bool isRemovable => false;
  22. internal bool Synced = true;
  23. public void Dispose()
  24. {
  25. }
  26. public void Ready()
  27. {
  28. }
  29. public Block[] GetConnectedBlocks(EGID blockID)
  30. {
  31. if (!BlockExists(blockID)) return new Block[0];
  32. Stack<uint> cubeStack = new Stack<uint>();
  33. FasterList<uint> cubesToProcess = new FasterList<uint>();
  34. ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID.entityID, cubeStack, cubesToProcess, (in GridConnectionsEntityStruct g) => { return false; });
  35. var ret = new Block[cubesToProcess.count];
  36. for (int i = 0; i < cubesToProcess.count; i++)
  37. ret[i] = new Block(cubesToProcess[i]);
  38. return ret;
  39. }
  40. public void SetBlockColorFromPalette(ref ColourParameterEntityStruct color)
  41. {
  42. ref var paletteEntry = ref entitiesDB.QueryEntity<PaletteEntryEntityStruct>(color.indexInPalette,
  43. CommonExclusiveGroups.COLOUR_PALETTE_GROUP);
  44. color.paletteColour = paletteEntry.Colour;
  45. }
  46. /// <summary>
  47. /// Get a struct of a block. Can be used to set properties.
  48. /// Returns a default value if not found.
  49. /// </summary>
  50. /// <param name="blockID">The block's ID</param>
  51. /// <typeparam name="T">The struct to query</typeparam>
  52. /// <returns>An editable reference to the struct</returns>
  53. public ref T GetBlockInfo<T>(EGID blockID) where T : struct, IEntityComponent
  54. {
  55. if (!Synced)
  56. {
  57. Sync();
  58. Synced = true;
  59. }
  60. if (entitiesDB.Exists<T>(blockID))
  61. return ref entitiesDB.QueryEntity<T>(blockID);
  62. T[] structHolder = new T[1]; //Create something that can be referenced
  63. return ref structHolder[0]; //Gets a default value automatically
  64. }
  65. /// <summary>
  66. /// Get a struct of a block. Can be used to set properties.
  67. /// Returns a default value if not found.
  68. /// </summary>
  69. /// <param name="blockID">The block's ID</param>
  70. /// <param name="exists">Whether the specified struct exists for the block</param>
  71. /// <typeparam name="T">The struct to query</typeparam>
  72. /// <returns>An editable reference to the struct</returns>
  73. public ref T GetBlockInfo<T>(EGID blockID, out bool exists) where T : struct, IEntityComponent
  74. {
  75. if (!Synced)
  76. {
  77. Sync();
  78. Synced = true;
  79. }
  80. exists = entitiesDB.Exists<T>(blockID);
  81. if (exists)
  82. return ref entitiesDB.QueryEntity<T>(blockID);
  83. T[] structHolder = new T[1];
  84. return ref structHolder[0];
  85. }
  86. public bool BlockExists(EGID id)
  87. {
  88. return entitiesDB.Exists<DBEntityStruct>(id);
  89. }
  90. public bool GetBlockInfoExists<T>(EGID blockID) where T : struct, IEntityComponent
  91. {
  92. return entitiesDB.Exists<T>(blockID);
  93. }
  94. public SimBody[] GetSimBodiesFromID(byte id)
  95. {
  96. var ret = new FasterList<SimBody>(4);
  97. if (!entitiesDB.HasAny<ObjectIdEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP))
  98. return new SimBody[0];
  99. var oids = entitiesDB.QueryEntities<ObjectIdEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
  100. var connections = entitiesDB.QueryMappedEntities<GridConnectionsEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
  101. foreach (ref ObjectIdEntityStruct oid in oids)
  102. {
  103. if (oid.objectId != id) continue;
  104. var rid = connections.Entity(oid.ID.entityID).machineRigidBodyId;
  105. foreach (var rb in ret)
  106. {
  107. if (rb.Id.entityID == rid)
  108. goto DUPLICATE; //Multiple Object Identifiers on one rigid body
  109. }
  110. ret.Add(new SimBody(rid));
  111. DUPLICATE: ;
  112. }
  113. return ret.ToArray();
  114. }
  115. public ObjectIdentifier[] GetObjectIDsFromID(byte id)
  116. {
  117. var ret = new FasterList<ObjectIdentifier>(4);
  118. if (!entitiesDB.HasAny<ObjectIdEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP))
  119. return new ObjectIdentifier[0];
  120. var oids = entitiesDB.QueryEntities<ObjectIdEntityStruct>(CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
  121. foreach (ref ObjectIdEntityStruct oid in oids)
  122. if (oid.objectId == id)
  123. ret.Add(new ObjectIdentifier(oid.ID));
  124. return ret.ToArray();
  125. }
  126. public SimBody[] GetConnectedSimBodies(uint id)
  127. {
  128. var joints = entitiesDB.QueryEntities<JointEntityStruct>(MachineSimulationGroups.JOINTS_GROUP);
  129. var list = new FasterList<SimBody>(4);
  130. foreach (var joint in joints)
  131. {
  132. if (joint.jointState == JointState.Broken) continue;
  133. if (joint.connectedEntityA == id) list.Add(new SimBody(joint.connectedEntityB));
  134. else if (joint.connectedEntityB == id) list.Add(new SimBody(joint.connectedEntityA));
  135. }
  136. return list.ToArray();
  137. }
  138. /// <summary>
  139. /// Synchronize newly created entity components with entities DB.
  140. /// This forces a partial game tick, so it may be slow.
  141. /// This also has the potential to make Gamecraft unstable.
  142. /// Use this sparingly.
  143. /// </summary>
  144. private static void Sync()
  145. {
  146. DeterministicStepCompositionRootPatch.SubmitEntitiesNow();
  147. }
  148. #if DEBUG
  149. public EntitiesDB GetEntitiesDB()
  150. {
  151. return entitiesDB;
  152. }
  153. #endif
  154. }
  155. }