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.

180 lines
5.6KB

  1. using System;
  2. using System.Collections.Generic;
  3. using Gamecraft.Wires;
  4. using RobocraftX.Blocks;
  5. using RobocraftX.Common;
  6. using RobocraftX.GUI.Hotbar.Colours;
  7. using RobocraftX.Physics;
  8. using RobocraftX.Scene.Simulation;
  9. using Svelto.DataStructures;
  10. using Svelto.ECS;
  11. using GamecraftModdingAPI.Engines;
  12. namespace GamecraftModdingAPI.Blocks
  13. {
  14. /// <summary>
  15. /// Engine for executing general block actions
  16. /// </summary>
  17. public partial class BlockEngine : IApiEngine
  18. {
  19. public string Name { get; } = "GamecraftModdingAPIBlockGameEngine";
  20. public EntitiesDB entitiesDB { set; private get; }
  21. public bool isRemovable => false;
  22. public void Dispose()
  23. {
  24. }
  25. public void Ready()
  26. {
  27. }
  28. public Block[] GetConnectedBlocks(EGID blockID)
  29. {
  30. if (!BlockExists(blockID)) return new Block[0];
  31. Stack<EGID> cubeStack = new Stack<EGID>();
  32. FasterList<EGID> cubes = new FasterList<EGID>(10);
  33. var coll = entitiesDB.QueryEntities<GridConnectionsEntityStruct>();
  34. foreach (var (ecoll, _) in coll)
  35. foreach (ref var conn in ecoll)
  36. conn.isProcessed = false;
  37. ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID, cubeStack, cubes,
  38. (in GridConnectionsEntityStruct g) => { return false; });
  39. var ret = new Block[cubes.count];
  40. for (int i = 0; i < cubes.count; i++)
  41. ret[i] = new Block(cubes[i]);
  42. return ret;
  43. }
  44. public void SetBlockColorFromPalette(ref ColourParameterEntityStruct color)
  45. {
  46. ref var paletteEntry = ref entitiesDB.QueryEntity<PaletteEntryEntityStruct>(color.indexInPalette,
  47. CommonExclusiveGroups.COLOUR_PALETTE_GROUP);
  48. color.paletteColour = paletteEntry.Colour;
  49. }
  50. public ref T GetBlockInfo<T>(EGID blockID) where T : struct, IEntityComponent
  51. {
  52. if (entitiesDB.Exists<T>(blockID))
  53. return ref entitiesDB.QueryEntity<T>(blockID);
  54. T[] structHolder = new T[1]; //Create something that can be referenced
  55. return ref structHolder[0]; //Gets a default value automatically
  56. }
  57. public U GetBlockInfo<T, U>(Block block, Func<T, U> getter,
  58. U def = default) where T : struct, IEntityComponent
  59. {
  60. if (entitiesDB.Exists<T>(block.Id))
  61. return getter(entitiesDB.QueryEntity<T>(block.Id));
  62. if (block.InitData.Group == null) return def;
  63. var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group);
  64. if (initializer.Has<T>())
  65. return getter(initializer.Get<T>());
  66. return def;
  67. }
  68. public delegate void Setter<T, U>(ref T component, U value) where T : struct, IEntityComponent;
  69. public void SetBlockInfo<T, U>(Block block, Setter<T, U> setter, U value) where T : struct, IEntityComponent
  70. {
  71. if (entitiesDB.Exists<T>(block.Id))
  72. setter(ref entitiesDB.QueryEntity<T>(block.Id), value);
  73. else if (block.InitData.Group != null)
  74. {
  75. var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group);
  76. T component = initializer.Has<T>() ? initializer.Get<T>() : default;
  77. ref T structRef = ref component;
  78. setter(ref structRef, value);
  79. initializer.Init(structRef);
  80. }
  81. }
  82. public bool BlockExists(EGID blockID)
  83. {
  84. return entitiesDB.Exists<DBEntityStruct>(blockID);
  85. }
  86. public bool GetBlockInfoExists<T>(Block block) where T : struct, IEntityComponent
  87. {
  88. if (entitiesDB.Exists<T>(block.Id))
  89. return true;
  90. if (block.InitData.Group == null)
  91. return false;
  92. var init = new EntityComponentInitializer(block.Id, block.InitData.Group);
  93. return init.Has<T>();
  94. }
  95. public SimBody[] GetSimBodiesFromID(byte id)
  96. {
  97. var ret = new FasterList<SimBody>(4);
  98. if (!entitiesDB.HasAny<ObjectIdEntityStruct>(CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP))
  99. return new SimBody[0];
  100. var oids = entitiesDB.QueryEntities<ObjectIdEntityStruct>(CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP);
  101. var connections = entitiesDB.QueryMappedEntities<GridConnectionsEntityStruct>(CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP);
  102. foreach (ref ObjectIdEntityStruct oid in oids)
  103. {
  104. if (oid.objectId != id) continue;
  105. var rid = connections.Entity(oid.ID.entityID).machineRigidBodyId;
  106. foreach (var rb in ret)
  107. {
  108. if (rb.Id.entityID == rid)
  109. goto DUPLICATE; //Multiple Object Identifiers on one rigid body
  110. }
  111. ret.Add(new SimBody(rid));
  112. DUPLICATE: ;
  113. }
  114. return ret.ToArray();
  115. }
  116. public ObjectIdentifier[] GetObjectIDsFromID(byte id, bool sim)
  117. {
  118. var ret = new FasterList<ObjectIdentifier>(4);
  119. if (!entitiesDB.HasAny<ObjectIdEntityStruct>(CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP))
  120. return new ObjectIdentifier[0];
  121. var oids = entitiesDB.QueryEntities<ObjectIdEntityStruct>(CommonExclusiveGroups.BUILD_OBJID_BLOCK_GROUP);
  122. foreach (ref ObjectIdEntityStruct oid in oids)
  123. if (sim ? oid.simObjectId == id : oid.objectId == id)
  124. ret.Add(new ObjectIdentifier(oid.ID));
  125. return ret.ToArray();
  126. }
  127. public SimBody[] GetConnectedSimBodies(uint id)
  128. {
  129. var joints = entitiesDB.QueryEntities<JointEntityStruct>(MachineSimulationGroups.JOINTS_GROUP);
  130. var list = new FasterList<SimBody>(4);
  131. foreach (var joint in joints)
  132. {
  133. if (joint.jointState == JointState.Broken) continue;
  134. if (joint.connectedEntityA == id) list.Add(new SimBody(joint.connectedEntityB));
  135. else if (joint.connectedEntityB == id) list.Add(new SimBody(joint.connectedEntityA));
  136. }
  137. return list.ToArray();
  138. }
  139. public EGID? FindBlockEGID(uint id)
  140. {
  141. var groups = entitiesDB.FindGroups<DBEntityStruct>();
  142. foreach (ExclusiveGroupStruct group in groups)
  143. {
  144. if (entitiesDB.Exists<DBEntityStruct>(id, group))
  145. return new EGID(id, group);
  146. }
  147. return null;
  148. }
  149. #if DEBUG
  150. public EntitiesDB GetEntitiesDB()
  151. {
  152. return entitiesDB;
  153. }
  154. #endif
  155. }
  156. }