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.

PlacementEngine.cs 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. using System;
  2. using System.Reflection;
  3. using DataLoader;
  4. using Harmony;
  5. using RobocraftX.Blocks;
  6. using RobocraftX.Blocks.Ghost;
  7. using RobocraftX.Blocks.Scaling;
  8. using RobocraftX.Character;
  9. using RobocraftX.CommandLine.Custom;
  10. using RobocraftX.Common;
  11. using RobocraftX.Common.Input;
  12. using RobocraftX.Common.Utilities;
  13. using RobocraftX.CR.MachineEditing;
  14. using RobocraftX.StateSync;
  15. using Svelto.ECS;
  16. using Svelto.ECS.EntityStructs;
  17. using Unity.Jobs;
  18. using Unity.Mathematics;
  19. using UnityEngine;
  20. using uREPL;
  21. using GamecraftModdingAPI.Utility;
  22. namespace GamecraftModdingAPI.Blocks
  23. {
  24. /// <summary>
  25. /// Engine which executes block placement actions
  26. /// </summary>
  27. public class PlacementEngine : IApiEngine
  28. {
  29. public bool IsInGame = false;
  30. public void Dispose()
  31. {
  32. IsInGame = false;
  33. }
  34. public void Ready()
  35. {
  36. IsInGame = true;
  37. }
  38. public EntitiesDB entitiesDB { get; set; }
  39. internal static BlockEntityFactory _blockEntityFactory; //Injected from PlaceBlockEngine
  40. public void PlaceBlock(BlockIDs block, BlockColors color, byte darkness, float3 position, int uscale,
  41. float3 scale, uint playerId, float3 rotation)
  42. { //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
  43. if (darkness > 9)
  44. throw new Exception("That is too dark. Make sure to use 0-9 as darkness. (0 is default.)");
  45. BuildBlock((ushort) block, (byte) (color + darkness * 10), position, uscale, scale, rotation, playerId);
  46. }
  47. private void BuildBlock(ushort block, byte color, float3 position, int uscale, float3 scale, float3 rot, uint playerId)
  48. {
  49. if (_blockEntityFactory == null)
  50. throw new Exception("The factory is null.");
  51. if (uscale < 1)
  52. throw new Exception("Scale needs to be at least 1");
  53. if (scale.x < 4e-5) scale.x = uscale;
  54. if (scale.y < 4e-5) scale.y = uscale;
  55. if (scale.z < 4e-5) scale.z = uscale;
  56. uint dbid = block;
  57. if (!PrefabsID.DBIDMAP.ContainsKey(dbid))
  58. throw new Exception("Block with ID " + dbid + " not found!");
  59. //RobocraftX.CR.MachineEditing.PlaceBlockEngine
  60. ScalingEntityStruct scaling = new ScalingEntityStruct {scale = scale};
  61. Quaternion rotQ = Quaternion.Euler(rot);
  62. RotationEntityStruct rotation = new RotationEntityStruct {rotation = rotQ};
  63. GridRotationStruct gridRotation = new GridRotationStruct
  64. {position = position, rotation = rotQ};
  65. CubeCategoryStruct category = new CubeCategoryStruct
  66. {category = CubeCategory.General, type = CubeType.Block};
  67. DBEntityStruct dbEntity = new DBEntityStruct {DBID = dbid};
  68. BlockPlacementScaleEntityStruct placementScale = new BlockPlacementScaleEntityStruct
  69. {
  70. blockPlacementHeight = uscale, blockPlacementWidth = uscale, desiredScaleFactor = uscale,
  71. snapGridScale = uscale,
  72. unitSnapOffset = 0, isUsingUnitSize = true
  73. };
  74. EquippedColourStruct colour = new EquippedColourStruct {indexInPalette = color};
  75. EGID egid2;
  76. switch (category.category)
  77. {
  78. case CubeCategory.SpawnPoint:
  79. case CubeCategory.BuildingSpawnPoint:
  80. egid2 = MachineEditingGroups.NewSpawnPointBlockID;
  81. break;
  82. default:
  83. egid2 = MachineEditingGroups.NewBlockID;
  84. break;
  85. }
  86. EntityStructInitializer
  87. structInitializer =
  88. _blockEntityFactory.Build(egid2, dbid); //The ghost block index is only used for triggers
  89. if (colour.indexInPalette != byte.MaxValue)
  90. structInitializer.Init(new ColourParameterEntityStruct
  91. {
  92. indexInPalette = colour.indexInPalette,
  93. needsUpdate = true
  94. });
  95. uint prefabId = PrefabsID.GetPrefabId(dbid, 0);
  96. structInitializer.Init(new GFXPrefabEntityStructGPUI(prefabId));
  97. structInitializer.Init(new PhysicsPrefabEntityStruct(prefabId));
  98. structInitializer.Init(dbEntity);
  99. structInitializer.Init(new PositionEntityStruct {position = position});
  100. structInitializer.Init(rotation);
  101. structInitializer.Init(scaling);
  102. structInitializer.Init(gridRotation);
  103. structInitializer.Init(new UniformBlockScaleEntityStruct
  104. {
  105. scaleFactor = placementScale.desiredScaleFactor
  106. });
  107. structInitializer.Init(new BlockPlacementInfoStruct()
  108. {
  109. loadedFromDisk = false,
  110. placedBy = playerId
  111. });
  112. PrimaryRotationUtility.InitialisePrimaryDirection(rotation.rotation, ref structInitializer);
  113. EGID playerEGID = new EGID(playerId, CharacterExclusiveGroups.OnFootGroup);
  114. ref PickedBlockExtraDataStruct pickedBlock = ref entitiesDB.QueryEntity<PickedBlockExtraDataStruct>(playerEGID);
  115. pickedBlock.placedBlockEntityID = playerEGID;
  116. pickedBlock.placedBlockWasAPickedBlock = false;
  117. }
  118. public string Name { get; } = "GamecraftModdingAPIPlacementGameEngine";
  119. [HarmonyPatch]
  120. public class FactoryObtainerPatch
  121. {
  122. static void Postfix(BlockEntityFactory blockEntityFactory)
  123. {
  124. _blockEntityFactory = blockEntityFactory;
  125. Logging.MetaDebugLog("Block entity factory injected.");
  126. }
  127. static MethodBase TargetMethod(HarmonyInstance instance)
  128. {
  129. return AccessTools.TypeByName("RobocraftX.CR.MachineEditing.PlaceBlockEngine").GetConstructors()[0];
  130. }
  131. }
  132. }
  133. }