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 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. using System;
  2. using System.Reflection;
  3. using DataLoader;
  4. using GamecraftModdingAPI.Blocks;
  5. using GamecraftModdingAPI.Utility;
  6. using Harmony;
  7. using JetBrains.Annotations;
  8. using RobocraftX.Blocks;
  9. using RobocraftX.Blocks.Ghost;
  10. using RobocraftX.Blocks.Scaling;
  11. using RobocraftX.Character;
  12. using RobocraftX.CommandLine.Custom;
  13. using RobocraftX.Common;
  14. using RobocraftX.Common.Input;
  15. using RobocraftX.Common.Utilities;
  16. using RobocraftX.CR.MachineEditing;
  17. using RobocraftX.StateSync;
  18. using Svelto.ECS;
  19. using Svelto.ECS.EntityStructs;
  20. using Unity.Jobs;
  21. using Unity.Mathematics;
  22. using UnityEngine;
  23. using uREPL;
  24. namespace GCMC
  25. {
  26. public class PlacementEngine : IApiEngine
  27. {
  28. public bool IsInGame = false;
  29. public void Dispose()
  30. {
  31. IsInGame = false;
  32. }
  33. public void Ready()
  34. {
  35. IsInGame = true;
  36. }
  37. public IEntitiesDB entitiesDB { get; set; }
  38. internal static BlockEntityFactory _blockEntityFactory; //Injected from PlaceBlockEngine
  39. /// <summary>
  40. /// Places a block at the given position
  41. /// </summary>
  42. /// <param name="block">The block's type</param>
  43. /// <param name="color">The block's color</param>
  44. /// <param name="darkness">The block color's darkness - 0 is default color</param>
  45. /// <param name="position">The block's position - default block size is 0.2</param>
  46. /// <param name="uscale">The block's uniform scale - default scale is 1 (with 0.2 width)</param>
  47. /// <param name="scale">The block's non-uniform scale - less than 1 means <paramref name="uscale"/> is used</param>
  48. /// <param name="playerId">The player who placed the block</param>
  49. /// <exception cref="Exception"></exception>
  50. public void PlaceBlock(BlockIDs block, BlockColors color, byte darkness, float3 position, int uscale,
  51. float3 scale, uint playerId, quaternion rotation)
  52. { //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
  53. try
  54. {
  55. if (darkness > 9)
  56. throw new Exception("That is too dark. Make sure to use 0-9 as darkness. (0 is default.)");
  57. BuildBlock((ushort) block, (byte) (color + darkness * 10), position, uscale, scale, rotation).Init(
  58. new BlockPlacementInfoStruct()
  59. {
  60. loadedFromDisk = false,
  61. placedBy = playerId
  62. });
  63. }
  64. catch (Exception e)
  65. {
  66. Console.WriteLine(e);
  67. Log.Error(e.Message);
  68. }
  69. }
  70. private EntityStructInitializer BuildBlock(ushort block, byte color, float3 position, int uscale, float3 scale, quaternion rot)
  71. {
  72. if (_blockEntityFactory == null)
  73. throw new Exception("The factory is null.");
  74. if (uscale < 1)
  75. throw new Exception("Scale needs to be at least 1");
  76. if (scale.x < 4e-5) scale.x = uscale;
  77. if (scale.y < 4e-5) scale.y = uscale;
  78. if (scale.z < 4e-5) scale.z = uscale;
  79. //RobocraftX.CR.MachineEditing.PlaceBlockEngine
  80. ScalingEntityStruct scaling = new ScalingEntityStruct {scale = scale};
  81. RotationEntityStruct rotation = new RotationEntityStruct {rotation = quaternion.identity};
  82. GridRotationStruct gridRotation = new GridRotationStruct
  83. {position = float3.zero, rotation = quaternion.identity};
  84. CubeCategoryStruct category = new CubeCategoryStruct
  85. {category = CubeCategory.General, type = CubeType.Block};
  86. uint dbid = block;
  87. DBEntityStruct dbEntity = new DBEntityStruct {DBID = dbid};
  88. uint num = PrefabsID.DBIDMAP[dbid];
  89. GFXPrefabEntityStructGO gfx = new GFXPrefabEntityStructGO {prefabID = num};
  90. BlockPlacementScaleEntityStruct placementScale = new BlockPlacementScaleEntityStruct
  91. {
  92. blockPlacementHeight = uscale, blockPlacementWidth = uscale, desiredScaleFactor = uscale,
  93. snapGridScale = uscale,
  94. unitSnapOffset = 0, isUsingUnitSize = true
  95. };
  96. EquippedColourStruct colour = new EquippedColourStruct {indexInPalette = color};
  97. EGID egid2;
  98. switch (category.category)
  99. {
  100. case CubeCategory.SpawnPoint:
  101. case CubeCategory.BuildingSpawnPoint:
  102. egid2 = MachineEditingGroups.NewSpawnPointBlockID;
  103. break;
  104. default:
  105. egid2 = MachineEditingGroups.NewBlockID;
  106. break;
  107. }
  108. int cubeId = PrefabsID.GenerateDBID((ushort) category.category, block);
  109. EntityStructInitializer
  110. structInitializer =
  111. _blockEntityFactory.Build(egid2, (uint) cubeId); //The ghost block index is only used for triggers
  112. if (colour.indexInPalette != byte.MaxValue)
  113. structInitializer.Init(new ColourParameterEntityStruct
  114. {
  115. indexInPalette = colour.indexInPalette
  116. });
  117. structInitializer.Init(new GFXPrefabEntityStructGPUI(gfx.prefabID));
  118. structInitializer.Init(new PhysicsPrefabEntityStruct(gfx.prefabID));
  119. structInitializer.Init(dbEntity);
  120. structInitializer.Init(new PositionEntityStruct {position = position});
  121. structInitializer.Init(rotation);
  122. structInitializer.Init(scaling);
  123. structInitializer.Init(gridRotation);
  124. structInitializer.Init(new UniformBlockScaleEntityStruct
  125. {
  126. scaleFactor = placementScale.desiredScaleFactor
  127. });
  128. return structInitializer;
  129. }
  130. public string Name { get; } = nameof(PlacementEngine);
  131. [HarmonyPatch]
  132. [UsedImplicitly]
  133. public class FactoryObtainerPatch
  134. {
  135. static void Postfix(BlockEntityFactory blockEntityFactory)
  136. {
  137. _blockEntityFactory = blockEntityFactory;
  138. Debug.Log("Block entity factory injected.");
  139. }
  140. static MethodBase TargetMethod(HarmonyInstance instance)
  141. {
  142. return typeof(PlaceBlockEngine).GetConstructors()[0];
  143. }
  144. }
  145. }
  146. }