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.

150 lines
6.2KB

  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 IEntitiesDB entitiesDB { get; set; }
  39. internal static BlockEntityFactory _blockEntityFactory; //Injected from PlaceBlockEngine
  40. /// <summary>
  41. /// Places a block at the given position
  42. /// </summary>
  43. /// <param name="block">The block's type</param>
  44. /// <param name="color">The block's color</param>
  45. /// <param name="darkness">The block color's darkness - 0 is default color</param>
  46. /// <param name="position">The block's position - default block size is 0.2</param>
  47. /// <param name="uscale">The block's uniform scale - default scale is 1 (with 0.2 width)</param>
  48. /// <param name="scale">The block's non-uniform scale - less than 1 means <paramref name="uscale"/> is used</param>
  49. /// <param name="playerId">The player who placed the block</param>
  50. /// <exception cref="Exception"></exception>
  51. public void PlaceBlock(BlockIDs block, BlockColors color, byte darkness, float3 position, int uscale,
  52. float3 scale, uint playerId, quaternion rotation)
  53. { //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
  54. if (darkness > 9)
  55. throw new Exception("That is too dark. Make sure to use 0-9 as darkness. (0 is default.)");
  56. BuildBlock((ushort) block, (byte) (color + darkness * 10), position, uscale, scale, rotation).Init(
  57. new BlockPlacementInfoStruct()
  58. {
  59. loadedFromDisk = false,
  60. placedBy = playerId
  61. });
  62. }
  63. private EntityStructInitializer BuildBlock(ushort block, byte color, float3 position, int uscale, float3 scale, quaternion rot)
  64. {
  65. if (_blockEntityFactory == null)
  66. throw new Exception("The factory is null.");
  67. if (uscale < 1)
  68. throw new Exception("Scale needs to be at least 1");
  69. if (scale.x < 4e-5) scale.x = uscale;
  70. if (scale.y < 4e-5) scale.y = uscale;
  71. if (scale.z < 4e-5) scale.z = uscale;
  72. //RobocraftX.CR.MachineEditing.PlaceBlockEngine
  73. ScalingEntityStruct scaling = new ScalingEntityStruct {scale = scale};
  74. RotationEntityStruct rotation = new RotationEntityStruct {rotation = quaternion.identity};
  75. GridRotationStruct gridRotation = new GridRotationStruct
  76. {position = float3.zero, rotation = quaternion.identity};
  77. CubeCategoryStruct category = new CubeCategoryStruct
  78. {category = CubeCategory.General, type = CubeType.Block};
  79. uint dbid = block;
  80. DBEntityStruct dbEntity = new DBEntityStruct {DBID = dbid};
  81. uint num = PrefabsID.DBIDMAP[dbid];
  82. GFXPrefabEntityStructGO gfx = new GFXPrefabEntityStructGO {prefabID = num};
  83. BlockPlacementScaleEntityStruct placementScale = new BlockPlacementScaleEntityStruct
  84. {
  85. blockPlacementHeight = uscale, blockPlacementWidth = uscale, desiredScaleFactor = uscale,
  86. snapGridScale = uscale,
  87. unitSnapOffset = 0, isUsingUnitSize = true
  88. };
  89. EquippedColourStruct colour = new EquippedColourStruct {indexInPalette = color};
  90. EGID egid2;
  91. switch (category.category)
  92. {
  93. case CubeCategory.SpawnPoint:
  94. case CubeCategory.BuildingSpawnPoint:
  95. egid2 = MachineEditingGroups.NewSpawnPointBlockID;
  96. break;
  97. default:
  98. egid2 = MachineEditingGroups.NewBlockID;
  99. break;
  100. }
  101. int cubeId = PrefabsID.GenerateDBID((ushort) category.category, block);
  102. EntityStructInitializer
  103. structInitializer =
  104. _blockEntityFactory.Build(egid2, (uint) cubeId); //The ghost block index is only used for triggers
  105. if (colour.indexInPalette != byte.MaxValue)
  106. structInitializer.Init(new ColourParameterEntityStruct
  107. {
  108. indexInPalette = colour.indexInPalette
  109. });
  110. structInitializer.Init(new GFXPrefabEntityStructGPUI(gfx.prefabID));
  111. structInitializer.Init(new PhysicsPrefabEntityStruct(gfx.prefabID));
  112. structInitializer.Init(dbEntity);
  113. structInitializer.Init(new PositionEntityStruct {position = position});
  114. structInitializer.Init(rotation);
  115. structInitializer.Init(scaling);
  116. structInitializer.Init(gridRotation);
  117. structInitializer.Init(new UniformBlockScaleEntityStruct
  118. {
  119. scaleFactor = placementScale.desiredScaleFactor
  120. });
  121. return structInitializer;
  122. }
  123. public string Name { get; } = "GamecraftModdingAPIPlacementGameEngine";
  124. [HarmonyPatch]
  125. public class FactoryObtainerPatch
  126. {
  127. static void Postfix(BlockEntityFactory blockEntityFactory)
  128. {
  129. _blockEntityFactory = blockEntityFactory;
  130. Logging.MetaDebugLog("Block entity factory injected.");
  131. }
  132. static MethodBase TargetMethod(HarmonyInstance instance)
  133. {
  134. return typeof(PlaceBlockEngine).GetConstructors()[0];
  135. }
  136. }
  137. }
  138. }