A stable modding interface between Techblox and mods https://mod.exmods.org/
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

131 líneas
5.4KB

  1. using System.Reflection;
  2. using DataLoader;
  3. using Gamecraft.Blocks.BlockGroups;
  4. using Gamecraft.Wires;
  5. using HarmonyLib;
  6. using RobocraftX.Blocks;
  7. using RobocraftX.Character;
  8. using RobocraftX.Common;
  9. using RobocraftX.Rendering;
  10. using RobocraftX.Rendering.GPUI;
  11. using Svelto.ECS;
  12. using Svelto.ECS.EntityStructs;
  13. using Unity.Mathematics;
  14. using TechbloxModdingAPI.Engines;
  15. using TechbloxModdingAPI.Utility;
  16. namespace TechbloxModdingAPI.Blocks.Engines
  17. {
  18. /// <summary>
  19. /// Engine which executes block placement actions
  20. /// </summary>
  21. public class PlacementEngine : IApiEngine
  22. {
  23. public bool IsInGame;
  24. public void Dispose()
  25. {
  26. IsInGame = false;
  27. }
  28. public void Ready()
  29. {
  30. IsInGame = true;
  31. }
  32. public EntitiesDB entitiesDB { get; set; }
  33. private static BlockEntityFactory _blockEntityFactory; //Injected from PlaceSingleBlockEngine
  34. private static IEntityFactory _entityFactory;
  35. public EntityInitializer PlaceBlock(BlockIDs block, float3 position, Player player, bool autoWire)
  36. { //It appears that only the non-uniform scale has any visible effect, but if that's not given here it will be set to the uniform one
  37. return BuildBlock((ushort) block, position, autoWire, (player ?? Player.LocalPlayer).Id);
  38. }
  39. private EntityInitializer BuildBlock(ushort block, float3 position, bool autoWire, uint playerId)
  40. {
  41. if (_blockEntityFactory == null)
  42. throw new BlockException("The factory is null.");
  43. if(!FullGameFields._dataDb.ContainsKey<CubeListData>(block))
  44. throw new BlockException("Block with ID " + block + " not found!");
  45. //RobocraftX.CR.MachineEditing.PlaceSingleBlockEngine
  46. DBEntityStruct dbEntity = new DBEntityStruct {DBID = block};
  47. EntityInitializer structInitializer = _blockEntityFactory.Build(CommonExclusiveGroups.nextBlockEntityID, block); //The ghost block index is only used for triggers
  48. uint prefabAssetID = structInitializer.Has<PrefabAssetIDComponent>()
  49. ? structInitializer.Get<PrefabAssetIDComponent>().prefabAssetID
  50. : throw new BlockException("Prefab asset ID not found!"); //Set by the game
  51. uint prefabId = PrefabsID.GetOrCreatePrefabID((ushort) prefabAssetID, (byte) BlockMaterial.SteelBodywork, 1, false);
  52. structInitializer.Init(new GFXPrefabEntityStructGPUI(prefabId));
  53. structInitializer.Init(dbEntity);
  54. structInitializer.Init(new PositionEntityStruct {position = position});
  55. structInitializer.Init(new RotationEntityStruct {rotation = quaternion.identity});
  56. structInitializer.Init(new ScalingEntityStruct {scale = new float3(1, 1, 1)});
  57. structInitializer.Init(new GridRotationStruct
  58. {
  59. position = position,
  60. rotation = quaternion.identity
  61. });
  62. structInitializer.Init(new UniformBlockScaleEntityStruct {scaleFactor = 1});
  63. structInitializer.Get<CubeMaterialStruct>().materialId = (byte) BlockMaterial.SteelBodywork;
  64. structInitializer.Init(new BlockPlacementInfoStruct
  65. {
  66. loadedFromDisk = false,
  67. placedBy = playerId,
  68. triggerAutoWiring = autoWire && structInitializer.Has<BlockPortsStruct>()
  69. });
  70. /*structInitializer.Init(new OverrideStaticComponent()
  71. { //TODO
  72. staticIfUnconnected = true
  73. });*/
  74. int nextFilterId = BlockGroupUtility.NextFilterId;
  75. structInitializer.Init(new BlockGroupEntityComponent
  76. {
  77. currentBlockGroup = nextFilterId
  78. });
  79. _entityFactory.BuildEntity<BlockGroupEntityDescriptor>((uint) nextFilterId,
  80. BlockGroupExclusiveGroups.BlockGroupEntityGroup)
  81. .Init(new BlockGroupTransformEntityComponent
  82. {
  83. blockGroupGridRotation = quaternion.identity,
  84. blockGroupGridPosition = position
  85. });
  86. foreach (var group in CharacterExclusiveGroups.AllCharacters)
  87. {
  88. EGID playerEGID = new EGID(playerId, group);
  89. if (!entitiesDB.TryQueryEntitiesAndIndex<PickedBlockExtraDataStruct>(playerEGID, out uint index,
  90. out var array)) continue;
  91. ref PickedBlockExtraDataStruct pickedBlock = ref array[index];
  92. pickedBlock.placedBlockEntityID = structInitializer.EGID;
  93. pickedBlock.placedBlockWasAPickedBlock = false;
  94. }
  95. return structInitializer;
  96. }
  97. public string Name => "TechbloxModdingAPIPlacementGameEngine";
  98. public bool isRemovable => false;
  99. [HarmonyPatch]
  100. public class FactoryObtainerPatch
  101. {
  102. static void Postfix(BlockEntityFactory blockEntityFactory, IEntityFactory entityFactory)
  103. {
  104. _blockEntityFactory = blockEntityFactory;
  105. _entityFactory = entityFactory;
  106. Logging.MetaDebugLog("Block entity factory injected.");
  107. }
  108. static MethodBase TargetMethod(Harmony instance)
  109. {
  110. return AccessTools.TypeByName("RobocraftX.CR.MachineEditing.PlaceSingleBlockEngine").GetConstructors()[0];
  111. }
  112. }
  113. }
  114. }