Tools for building games mainly focused on changing block properties. And noclip.
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.

235 lines
10KB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Gamecraft.Wires.ChannelsCommon;
  5. using GamecraftModdingAPI;
  6. using GamecraftModdingAPI.Blocks;
  7. using GamecraftModdingAPI.Commands;
  8. using GamecraftModdingAPI.Engines;
  9. using GamecraftModdingAPI.Players;
  10. using GamecraftModdingAPI.Utility;
  11. using HarmonyLib;
  12. using IllusionPlugin;
  13. using RobocraftX.Character.Weapons;
  14. using RobocraftX.CommandLine.Custom;
  15. using RobocraftX.Common.Players;
  16. using Svelto.ECS;
  17. using Svelto.ECS.Internal;
  18. using Unity.Mathematics;
  19. using uREPL;
  20. using Main = GamecraftModdingAPI.Main;
  21. namespace BlockMod
  22. {
  23. public class BlockMod : IPlugin
  24. {
  25. private Block[] blocks = new Block[0];
  26. private Block refBlock;
  27. public void OnApplicationStart()
  28. {
  29. Main.Init();
  30. GameClient.SetDebugInfo("BlockModInfo", GetBlockInfo);
  31. RegisterBlockCommand("scaleBlocks",
  32. "Scales the blocks you're looking at, relative to current size (current scale * new scale)." +
  33. " The block you're looking at stays where it is, everything else is moved next to it.",
  34. (scaleX, scaleY, scaleZ, blocks, refBlock) =>
  35. {
  36. if (!GameState.IsBuildMode()) return; //Scaling & positioning is weird in simulation
  37. if (CheckNoBlocks(blocks)) return;
  38. // ReSharper disable once PossibleNullReferenceException
  39. float3 reference = refBlock.Position;
  40. float3 scale = new float3(scaleX, scaleY, scaleZ);
  41. foreach (var block in blocks)
  42. {
  43. block.Scale *= scale;
  44. block.Position = reference + (block.Position - reference) * scale;
  45. }
  46. Logging.CommandLog("Blocks scaled.");
  47. });
  48. RegisterBlockCommand("scaleIndividually", "Scales the blocks you're looking at, but doesn't move them." +
  49. "The scale is relative, 1 means no change. Look at a block previously scaled to scale all of the blocks that were connected to it.",
  50. (scaleX, scaleY, scaleZ, blocks, refBlock) =>
  51. {
  52. if (!GameState.IsBuildMode()) return; //Scaling & positioning is weird in simulation
  53. float3 scale = new float3(scaleX, scaleY, scaleZ);
  54. foreach (var block in blocks)
  55. block.Scale *= scale;
  56. });
  57. RegisterBlockCommand("moveBlocks", "Moves the blocks around.", (x, y, z, blocks, refBlock) =>
  58. {
  59. if (GameState.IsBuildMode())
  60. foreach (var block in blocks)
  61. block.Position += new float3(x, y, z);
  62. else if (GameState.IsSimulationMode())
  63. foreach (var body in GetSimBodies(blocks))
  64. body.Position += new float3(x, y, z);
  65. });
  66. RegisterBlockCommand("colorBlocks", "Colors the blocks you're looking at",
  67. (color, darkness, blocks, refBlock) =>
  68. {
  69. if (!Enum.TryParse(color, true, out BlockColors clr))
  70. {
  71. Logging.CommandLogWarning("Color " + color + " not found");
  72. }
  73. foreach (var block in blocks)
  74. block.Color = new BlockColor {Color = clr, Darkness = darkness};
  75. });
  76. CommandBuilder.Builder("selectBlocksLookedAt", "Selects blocks (1 or more) to change. Only works in build mode, however the blocks can be changed afterwards." +
  77. " Paramter: whether one (true) or all connected (false) blocks should be selected.")
  78. .Action<bool>(single =>
  79. {
  80. refBlock = new Player(PlayerType.Local).GetBlockLookedAt();
  81. blocks = single ? new[] {refBlock} : refBlock?.GetConnectedCubes() ?? new Block[0];
  82. Logging.CommandLog(blocks == null ? "Selection cleared." : blocks.Length + " blocks selected.");
  83. }).Build();
  84. CommandBuilder.Builder("selectBlocksWithID", "Selects blocks with a specific object ID.")
  85. .Action<char>(id =>
  86. blocks = (refBlock = ObjectIdentifier.GetByID(id).FirstOrDefault())?.GetConnectedCubes() ??
  87. new Block[0]).Build();
  88. RegisterBlockCommand("pushBlocks", "Adds velocity to the selected blocks. Only works in simulation.",
  89. (x, y, z, blocks, refBlock) =>
  90. {
  91. foreach (var block in GetSimBodies(blocks))
  92. block.Velocity += new float3(x, y, z);
  93. });
  94. RegisterBlockCommand("pushRotateBlocks",
  95. "Adds angular velocity to the selected blocks. Only works in simulation.",
  96. (x, y, z, blocks, refBlock) =>
  97. {
  98. foreach (var block in GetSimBodies(blocks))
  99. block.AngularVelocity += new float3(x, y, z);
  100. });
  101. CommandBuilder.Builder("pushPlayer", "Adds velocity to the player.")
  102. .Action<float, float, float>((x, y, z) =>
  103. {
  104. new Player(PlayerType.Local).Velocity += new float3(x, y, z);
  105. }).Build();
  106. CommandBuilder.Builder("pushRotatePlayer", "Adds angular velocity to the player.")
  107. .Action<float, float, float>((x, y, z) =>
  108. {
  109. new Player(PlayerType.Local).AngularVelocity += new float3(x, y, z);
  110. }).Build();
  111. }
  112. private string GetBlockInfo()
  113. {
  114. if (GameState.IsBuildMode())
  115. {
  116. var block = new Player(PlayerType.Local).GetBlockLookedAt();
  117. float3 pos = block.Position;
  118. float3 rot = block.Rotation;
  119. float3 scale = block.Scale;
  120. return $"Block: {block.Type} at {pos.x:F} {pos.y:F} {pos.z:F}\n" +
  121. $"- Rotation: {rot.x:F}° {rot.y:F}° {rot.z:F}°\n" +
  122. $"- Color: {block.Color.Color} darkness: {block.Color.Darkness}\n" +
  123. $"- Scale: {scale.x:F} {scale.y:F} {scale.z:F}\n" +
  124. $"- Label: {block.Label}";
  125. }
  126. if (GameState.IsSimulationMode())
  127. {
  128. var body = new Player(PlayerType.Local).GetSimBodyLookedAt();
  129. float3 pos = body.Position;
  130. float3 rot = body.Rotation;
  131. float3 vel = body.Velocity;
  132. float3 ave = body.AngularVelocity;
  133. float3 com = body.CenterOfMass;
  134. return $"Body at {pos.x:F} {pos.y:F} {pos.z:F}\n" +
  135. $"- Rotation: {rot.x:F}° {rot.y:F}° {rot.z:F}°\n" +
  136. $"- Velocity: {vel.x:F} {vel.y:F} {vel.z:F}\n" +
  137. $"- Angular velocity: {ave.x:F} {ave.y:F} {ave.z:F}\n" +
  138. $"- {(body.Static ? "Static body" : $"Mass: {body.Mass:F} center: {com.x:F} {com.y:F} {com.z:F}")}";
  139. }
  140. return "Switching modes...";
  141. }
  142. private bool CheckNoBlocks(Block[] blocks)
  143. {
  144. if (blocks.Length == 0)
  145. {
  146. Logging.CommandLogWarning("No blocks selected. Use selectBlocks first.");
  147. return true;
  148. }
  149. return false;
  150. }
  151. private IEnumerable<SimBody> GetSimBodies(Block[] blocks)
  152. => blocks.Select(block => block.GetSimBody()).Distinct();
  153. private Block[] SelectBlocks(byte id)
  154. {
  155. var blocks = ObjectIdentifier.GetBySimID(id).SelectMany(block => block.GetConnectedCubes()).ToArray();
  156. return blocks;
  157. }
  158. //private void RegisterBlockCommand<T>(string name, string desc, T action) where T : Delegate
  159. private void RegisterBlockCommand(string name, string desc, Action<string, byte, Block[], Block> action)
  160. {
  161. /*switch (action)
  162. {
  163. case Action<Block[], Block> act
  164. break;
  165. case Action<float, float, float, Block[], Block> act:
  166. break;
  167. default:
  168. Logging.LogWarning("Unexpected parameters for command: " + name);
  169. break;
  170. }*/
  171. RuntimeCommands.Register<string, byte>(name, (a1, a2) =>
  172. {
  173. if (CheckNoBlocks(blocks)) return;
  174. action(a1, a2, blocks, refBlock);
  175. }, desc);
  176. ConsoleCommands.RegisterWithChannel<string, byte>(name, (a1, a2, ch) =>
  177. {
  178. var blks = SelectBlocks(ch);
  179. if (CheckNoBlocks(blks)) return;
  180. action(a1, a2, blks, blks[0]);
  181. }, BinaryChannelUtilities.ChannelType.Object, desc);
  182. }
  183. private void RegisterBlockCommand(string name, string desc, Action<float, float, float, Block[], Block> action)
  184. {
  185. RuntimeCommands.Register<float, float, float>(name, (x, y, z) =>
  186. {
  187. if (CheckNoBlocks(blocks)) return;
  188. action(x, y, z, blocks, refBlock);
  189. },
  190. desc);
  191. ConsoleCommands.RegisterWithChannel<float, float, float>(name, (x, y, z, ch) =>
  192. {
  193. var blks = SelectBlocks(ch);
  194. if (CheckNoBlocks(blks)) return;
  195. action(x, y, z, blks, blks[0]);
  196. }, BinaryChannelUtilities.ChannelType.Object, desc);
  197. }
  198. public void OnApplicationQuit()
  199. {
  200. }
  201. public void OnLevelWasLoaded(int level)
  202. {
  203. }
  204. public void OnLevelWasInitialized(int level)
  205. {
  206. }
  207. public void OnUpdate()
  208. {
  209. }
  210. public void OnFixedUpdate()
  211. {
  212. }
  213. public string Name { get; } = "BlockMod";
  214. public string Version { get; } = "v1.0.0";
  215. }
  216. }