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.

103 lines
4.0KB

  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 Svelto.ECS;
  12. using Svelto.ECS.EntityStructs;
  13. using Unity.Mathematics;
  14. using UnityEngine;
  15. using GamecraftModdingAPI.Utility;
  16. using GamecraftModdingAPI.Engines;
  17. using GamecraftModdingAPI.Players;
  18. using RobocraftX.Rendering.GPUI;
  19. namespace GamecraftModdingAPI.Blocks
  20. {
  21. /// <summary>
  22. /// Engine which executes block placement actions
  23. /// </summary>
  24. public class PlacementEngine : IApiEngine
  25. {
  26. public bool IsInGame;
  27. public void Dispose()
  28. {
  29. IsInGame = false;
  30. }
  31. public void Ready()
  32. {
  33. IsInGame = true;
  34. }
  35. public EntitiesDB entitiesDB { get; set; }
  36. private static BlockEntityFactory _blockEntityFactory; //Injected from PlaceSingleBlockEngine
  37. public EntityInitializer PlaceBlock(BlockIDs block, float3 position, Player player, bool autoWire)
  38. { //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
  39. return BuildBlock((ushort) block, position, autoWire, (player ?? Player.LocalPlayer).Id);
  40. }
  41. private EntityInitializer BuildBlock(ushort block, float3 position, bool autoWire, uint playerId)
  42. {
  43. if (_blockEntityFactory == null)
  44. throw new BlockException("The factory is null.");
  45. uint resourceId = (uint) PrefabsID.GenerateResourceID(0, block);
  46. if (!PrefabsID.PrefabIDByResourceIDMap.ContainsKey(resourceId))
  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 prefabId = PrefabsID.GetOrCreatePrefabID(block, (byte) BlockMaterial.SteelBodywork, 0, false);
  52. structInitializer.Init(new GFXPrefabEntityStructGPUI(prefabId));
  53. structInitializer.Init(new PhysicsPrefabEntityStruct(prefabId));
  54. structInitializer.Init(dbEntity);
  55. structInitializer.Init(new PositionEntityStruct {position = position});
  56. structInitializer.Init(new BlockPlacementInfoStruct()
  57. {
  58. loadedFromDisk = false,
  59. placedBy = playerId,
  60. triggerAutoWiring = autoWire && structInitializer.Has<BlockPortsStruct>()
  61. });
  62. foreach (var group in CharacterExclusiveGroups.AllCharacters)
  63. {
  64. EGID playerEGID = new EGID(playerId, group);
  65. if (!entitiesDB.TryQueryEntitiesAndIndex<PickedBlockExtraDataStruct>(playerEGID, out uint index,
  66. out var array)) continue;
  67. ref PickedBlockExtraDataStruct pickedBlock = ref array[index];
  68. pickedBlock.placedBlockEntityID = structInitializer.EGID;
  69. pickedBlock.placedBlockWasAPickedBlock = false;
  70. }
  71. return structInitializer;
  72. }
  73. public string Name => "GamecraftModdingAPIPlacementGameEngine";
  74. public bool isRemovable => false;
  75. [HarmonyPatch]
  76. public class FactoryObtainerPatch
  77. {
  78. static void Postfix(BlockEntityFactory blockEntityFactory)
  79. {
  80. _blockEntityFactory = blockEntityFactory;
  81. Logging.MetaDebugLog("Block entity factory injected.");
  82. }
  83. static MethodBase TargetMethod(Harmony instance)
  84. {
  85. return AccessTools.TypeByName("RobocraftX.CR.MachineEditing.PlaceSingleBlockEngine").GetConstructors()[0];
  86. }
  87. }
  88. }
  89. }