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.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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. 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).Init(
  46. new BlockPlacementInfoStruct()
  47. {
  48. loadedFromDisk = false,
  49. placedBy = playerId
  50. });
  51. }
  52. private EntityStructInitializer BuildBlock(ushort block, byte color, float3 position, int uscale, float3 scale, float3 rot)
  53. {
  54. if (_blockEntityFactory == null)
  55. throw new Exception("The factory is null.");
  56. if (uscale < 1)
  57. throw new Exception("Scale needs to be at least 1");
  58. if (scale.x < 4e-5) scale.x = uscale;
  59. if (scale.y < 4e-5) scale.y = uscale;
  60. if (scale.z < 4e-5) scale.z = uscale;
  61. //RobocraftX.CR.MachineEditing.PlaceBlockEngine
  62. ScalingEntityStruct scaling = new ScalingEntityStruct {scale = scale};
  63. Quaternion rotQ = Quaternion.Euler(rot);
  64. RotationEntityStruct rotation = new RotationEntityStruct {rotation = rotQ};
  65. GridRotationStruct gridRotation = new GridRotationStruct
  66. {position = position, rotation = rotQ};
  67. CubeCategoryStruct category = new CubeCategoryStruct
  68. {category = CubeCategory.General, type = CubeType.Block};
  69. uint dbid = block;
  70. DBEntityStruct dbEntity = new DBEntityStruct {DBID = dbid};
  71. uint num = PrefabsID.DBIDMAP[dbid];
  72. GFXPrefabEntityStructGO gfx = new GFXPrefabEntityStructGO {prefabID = num};
  73. BlockPlacementScaleEntityStruct placementScale = new BlockPlacementScaleEntityStruct
  74. {
  75. blockPlacementHeight = uscale, blockPlacementWidth = uscale, desiredScaleFactor = uscale,
  76. snapGridScale = uscale,
  77. unitSnapOffset = 0, isUsingUnitSize = true
  78. };
  79. EquippedColourStruct colour = new EquippedColourStruct {indexInPalette = color};
  80. EGID egid2;
  81. switch (category.category)
  82. {
  83. case CubeCategory.SpawnPoint:
  84. case CubeCategory.BuildingSpawnPoint:
  85. egid2 = MachineEditingGroups.NewSpawnPointBlockID;
  86. break;
  87. default:
  88. egid2 = MachineEditingGroups.NewBlockID;
  89. break;
  90. }
  91. int cubeId = PrefabsID.GenerateDBID((ushort) category.category, block);
  92. EntityStructInitializer
  93. structInitializer =
  94. _blockEntityFactory.Build(egid2, (uint) cubeId); //The ghost block index is only used for triggers
  95. if (colour.indexInPalette != byte.MaxValue)
  96. structInitializer.Init(new ColourParameterEntityStruct
  97. {
  98. indexInPalette = colour.indexInPalette
  99. });
  100. structInitializer.Init(new GFXPrefabEntityStructGPUI(gfx.prefabID));
  101. structInitializer.Init(new PhysicsPrefabEntityStruct(gfx.prefabID));
  102. structInitializer.Init(dbEntity);
  103. structInitializer.Init(new PositionEntityStruct {position = position});
  104. structInitializer.Init(rotation);
  105. structInitializer.Init(scaling);
  106. structInitializer.Init(gridRotation);
  107. structInitializer.Init(new UniformBlockScaleEntityStruct
  108. {
  109. scaleFactor = placementScale.desiredScaleFactor
  110. });
  111. return structInitializer;
  112. }
  113. public string Name { get; } = "GamecraftModdingAPIPlacementGameEngine";
  114. [HarmonyPatch]
  115. public class FactoryObtainerPatch
  116. {
  117. static void Postfix(BlockEntityFactory blockEntityFactory)
  118. {
  119. _blockEntityFactory = blockEntityFactory;
  120. Logging.MetaDebugLog("Block entity factory injected.");
  121. }
  122. static MethodBase TargetMethod(HarmonyInstance instance)
  123. {
  124. return typeof(PlaceBlockEngine).GetConstructors()[0];
  125. }
  126. }
  127. }
  128. }