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.

113 lines
4.6KB

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