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.

181 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. 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<EGID> cubeStack = new Stack<EGID>();
  33. FasterList<EGID> cubes = new FasterList<EGID>(10);
  34. var coll = entitiesDB.QueryEntities<GridConnectionsEntityStruct>();
  35. foreach (var (ecoll, _) in coll)
  36. foreach (ref var conn in ecoll)
  37. conn.isProcessed = false;
  38. ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID, cubeStack, cubes,
  39. (in GridConnectionsEntityStruct g) => { return false; });
  40. var ret = new Block[cubes.count];
  41. for (int i = 0; i < cubes.count; i++)
  42. ret[i] = new Block(cubes[i]);
  43. return ret;
  44. }
  45. public void SetBlockColorFromPalette(ref ColourParameterEntityStruct color)
  46. {
  47. ref var paletteEntry = ref entitiesDB.QueryEntity<PaletteEntryEntityStruct>(color.indexInPalette,
  48. CommonExclusiveGroups.COLOUR_PALETTE_GROUP);
  49. color.paletteColour = paletteEntry.Colour;
  50. }
  51. public ref T GetBlockInfo<T>(EGID blockID) where T : struct, IEntityComponent
  52. {
  53. if (entitiesDB.Exists<T>(blockID))
  54. return ref entitiesDB.QueryEntity<T>(blockID);
  55. T[] structHolder = new T[1]; //Create something that can be referenced
  56. return ref structHolder[0]; //Gets a default value automatically
  57. }
  58. public U GetBlockInfo<T, U>(Block block, Func<T, U> getter,
  59. U def = default) where T : struct, IEntityComponent
  60. {
  61. if (entitiesDB.Exists<T>(block.Id))
  62. return getter(entitiesDB.QueryEntity<T>(block.Id));
  63. if (block.InitData.Group == null) return def;
  64. var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group);
  65. if (initializer.Has<T>())
  66. return getter(initializer.Get<T>());
  67. return def;
  68. }
  69. public delegate void Setter<T, U>(ref T component, U value) where T : struct, IEntityComponent;
  70. public void SetBlockInfo<T, U>(Block block, Setter<T, U> setter, U value) where T : struct, IEntityComponent
  71. {
  72. if (entitiesDB.Exists<T>(block.Id))
  73. setter(ref entitiesDB.QueryEntity<T>(block.Id), value);
  74. if (block.InitData.Group != null)
  75. {
  76. var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group);
  77. ref T structRef = ref (new T[1])[0]; //A reference for a default value for struct
  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. }