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.

142 lines
5.6KB

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