Moar Gamecraft commands!
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.

158 lines
6.7KB

  1. using System;
  2. using System.Linq;
  3. using System.Reflection;
  4. using GamecraftModdingAPI.Commands;
  5. using Harmony;
  6. using RobocraftX.GUI.CommandLine;
  7. using RobocraftX.Multiplayer;
  8. using RobocraftX.StateSync;
  9. using RobocraftX.Character;
  10. using Svelto.ECS;
  11. using Unity.Entities;
  12. using UnityEngine;
  13. using uREPL;
  14. using Svelto.Context;
  15. using RobocraftX;
  16. using RobocraftX.Blocks.Ghost;
  17. using RobocraftX.Blocks.Scaling;
  18. using RobocraftX.Common;
  19. using RobocraftX.CR.MachineEditing;
  20. using Svelto.ECS.EntityStructs;
  21. using Unity.Mathematics;
  22. namespace ExtraCommands.Basics
  23. {
  24. [CustomCommand("SetScale")]
  25. class SetScaleCommandEngine : ICustomCommandEngine
  26. {
  27. public void Ready()
  28. {
  29. CommandRegistrationHelper.Register<float, float, float>("SetScale", SetScaleCommand, "Set the scale for the next block. Use 0 0 0 to reset. The displayed cube is uniformly scaled until placed.");
  30. }
  31. public IEntitiesDB entitiesDB { get; set; }
  32. private static float3 _scale;
  33. //private HarmonyInstance harmony;
  34. private void SetScaleCommand(float x, float y, float z)
  35. {
  36. /*if (harmony == null)
  37. {
  38. Console.WriteLine("Patching...");
  39. harmony = HarmonyInstance.Create("org.exmods.extracommands.setscale");
  40. var type = Type.GetType("RobocraftX.CR.MachineEditing.PlacementCursorEngine");
  41. var method = type.GetMethod("<UpdateCursor>g__UpdatePlacementCursorScales|10_0");
  42. harmony.Patch(method, new HarmonyMethod(((Func<bool>) PatchPrefix).Method));
  43. Console.WriteLine("Patched");
  44. }*/
  45. _scale = new float3(x, y, z);
  46. EntityCollection<GhostScalingEntityStruct> scalings =
  47. entitiesDB.QueryEntities<GhostScalingEntityStruct>(
  48. (ExclusiveGroupStruct) NamedExclusiveGroup<GHOST_BLOCKS>.Group);
  49. Console.WriteLine("Found " + scalings.length + " scalings.");
  50. var egid = new EGID(0, NamedExclusiveGroup<GHOST_BLOCKS>.Group);
  51. for (int index = 0; index < scalings.length; index++)
  52. {
  53. Console.WriteLine("G scaling " + index + ": " + scalings[index].ghostScale);
  54. ref var scaling = ref entitiesDB.QueryEntity<ScalingEntityStruct>(egid);
  55. Console.WriteLine("Scaling " + index + ": " + scaling);
  56. ref var scale = ref entitiesDB.QueryEntity<BlockPlacementScaleEntityStruct>(egid);
  57. Console.WriteLine("Scale " + index + ": " + scale.snapGridScale);
  58. UpdateScale(ref scale, ref scaling, ref scalings[index], egid);
  59. }
  60. }
  61. private void UpdateScale(ref BlockPlacementScaleEntityStruct scale, ref ScalingEntityStruct scaling,
  62. ref GhostScalingEntityStruct gscaling, EGID egid)
  63. {
  64. Console.WriteLine("Attempting to update scale...");
  65. if (_scale.x < 4e-5 || _scale.y < 4e-5 || _scale.z < 4e-5) return;
  66. Console.WriteLine("Scale is set, continuing.");
  67. scale.snapGridScale = Math.Max((int) _scale.x, 1);
  68. scale.blockPlacementHeight = Math.Max((int) _scale.y, 1);
  69. scale.desiredScaleFactor = Math.Max((int) _scale.x, 1);
  70. entitiesDB.PublishEntityChange<BlockPlacementScaleEntityStruct>(egid);
  71. Console.WriteLine("Scale published");
  72. scaling.scale = _scale;
  73. entitiesDB.PublishEntityChange<ScalingEntityStruct>(egid);
  74. Console.WriteLine("Scaling published");
  75. gscaling.ghostScale = _scale;
  76. gscaling.hasBlockBeenUnformedScaled = true; //Apply scale instead of overwriting it
  77. entitiesDB.PublishEntityChange<GhostScalingEntityStruct>(egid);
  78. Console.WriteLine("Scale updated (" + scaling.scale + ")");
  79. }
  80. public void Dispose()
  81. {
  82. CommandRegistrationHelper.Unregister("SetScale");
  83. }
  84. /*public void Add(ref GhostScalingEntityStruct entityView, EGID egid)
  85. { //If the cursor is near a block, it recreates the entity - nope
  86. Console.WriteLine("Entity " + egid + " added: " + entityView.ghostScale);
  87. ref var scale = ref entitiesDB.QueryEntity<BlockPlacementScaleEntityStruct>(egid);
  88. ref var scaling = ref entitiesDB.QueryEntity<ScalingEntityStruct>(egid);
  89. UpdateScale(ref scale, ref scaling, ref entityView);
  90. entitiesDB.PublishEntityChange<ScalingEntityStruct>(egid);
  91. entitiesDB.PublishEntityChange<BlockPlacementScaleEntityStruct>(egid);
  92. entitiesDB.PublishEntityChange<GhostScalingEntityStruct>(egid);
  93. }
  94. public void Remove(ref GhostScalingEntityStruct entityView, EGID egid)
  95. {
  96. }*/
  97. /*private bool PatchPrefix()
  98. {
  99. if (math.any(_scale < new float3(4e-5)))
  100. return true;
  101. return false; //Prevent updating
  102. }*/
  103. //ScaleGhostBlockEngine.UpdateScaling
  104. [HarmonyPatch]
  105. public class ScalePatch
  106. {
  107. static bool Prefix()
  108. {
  109. if (math.any(_scale < new float3(4e-5)))
  110. return true;
  111. return false; //Prevent updating
  112. }
  113. static MethodBase TargetMethod(HarmonyInstance instance)
  114. {
  115. return typeof(ScaleGhostBlockEngine).GetMethod("UpdateScaling",
  116. BindingFlags.NonPublic | BindingFlags.Instance);
  117. }
  118. }
  119. //RobocraftX.Blocks.Ghost.UniformScaleGhostBlockEngine.SimulatePhysicsStep - Does not update the ghost block but the outline still gets rounded
  120. //RobocraftX.Blocks.Ghost.GhostScalingSyncEngine.SimulatePhysicsStep (reflection) - Doesn't do anything immediately visible
  121. //RobocraftX.CR.MachineEditing.PlacementCursorEngine.<UpdateCursor>g__UpdatePlacementCursorScales|10_0
  122. //[HarmonyPatch(typeof(UniformScaleGhostBlockEngine))]
  123. //[HarmonyPatch("SimulatePhysicsStep")]
  124. //[HarmonyPatch]
  125. public class UniformScalePatch
  126. {
  127. static bool Prefix()
  128. {
  129. if (math.any(_scale < new float3(4e-5)))
  130. return true;
  131. return false; //Prevent updating
  132. }
  133. static MethodBase TargetMethod(HarmonyInstance instance)
  134. {
  135. return typeof(PlacementCursorEngine)
  136. .GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
  137. .First(m => m.Name.Contains("UpdatePlacementCursorScales"));
  138. }
  139. }
  140. public string Name { get; } = "SetScale";
  141. public string Description { get; } = "Set the scale for the next block to be placed.";
  142. }
  143. }