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.

BlockMod.cs 9.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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.Players;
  9. using GamecraftModdingAPI.Utility;
  10. using IllusionPlugin;
  11. using RobocraftX.CommandLine.Custom;
  12. using Unity.Mathematics;
  13. using uREPL;
  14. using Main = GamecraftModdingAPI.Main;
  15. namespace BlockMod
  16. {
  17. public class BlockMod : IPlugin
  18. {
  19. private Block[] blocks = new Block[0];
  20. private Block refBlock;
  21. public void OnApplicationStart()
  22. {
  23. Main.Init();
  24. GameClient.SetDebugInfo("BlockModInfo", GetBlockInfo);
  25. RegisterBlockCommand("scaleBlocks",
  26. "Scales the blocks you're looking at, relative to current size (current scale * new scale)." +
  27. " The block you're looking at stays where it is, everything else is moved next to it.",
  28. (scaleX, scaleY, scaleZ, blocks, refBlock) =>
  29. {
  30. if (!GameState.IsBuildMode()) return; //Scaling & positioning is weird in simulation
  31. if (CheckNoBlocks(blocks)) return;
  32. // ReSharper disable once PossibleNullReferenceException
  33. float3 reference = refBlock.Position;
  34. float3 scale = new float3(scaleX, scaleY, scaleZ);
  35. foreach (var block in blocks)
  36. {
  37. block.Scale *= scale;
  38. block.Position = reference + (block.Position - reference) * scale;
  39. }
  40. Logging.CommandLog("Blocks scaled.");
  41. });
  42. RegisterBlockCommand("scaleIndividually", "Scales the blocks you're looking at, but doesn't move them." +
  43. "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.",
  44. (scaleX, scaleY, scaleZ, blocks, refBlock) =>
  45. {
  46. if (!GameState.IsBuildMode()) return; //Scaling & positioning is weird in simulation
  47. float3 scale = new float3(scaleX, scaleY, scaleZ);
  48. foreach (var block in blocks)
  49. block.Scale *= scale;
  50. });
  51. RegisterBlockCommand("moveBlocks", "Moves the blocks around.", (x, y, z, blocks, refBlock) =>
  52. {
  53. if (GameState.IsBuildMode())
  54. foreach (var block in blocks)
  55. block.Position += new float3(x, y, z);
  56. else if (GameState.IsSimulationMode())
  57. foreach (var body in GetSimBodies(blocks))
  58. body.Position += new float3(x, y, z);
  59. });
  60. RegisterBlockCommand("colorBlocks", "Colors the blocks you're looking at",
  61. (color, darkness, blocks, refBlock) =>
  62. {
  63. if (!Enum.TryParse(color, true, out BlockColors clr))
  64. {
  65. Logging.CommandLogWarning("Color " + color + " not found");
  66. }
  67. foreach (var block in blocks)
  68. block.Color = new BlockColor {Color = clr, Darkness = darkness};
  69. });
  70. CommandBuilder.Builder("selectBlocksLookedAt", "Selects blocks (1 or more) to change. Only works in build mode, however the blocks can be changed afterwards." +
  71. " Paramter: whether one (true) or all connected (false) blocks should be selected.")
  72. .Action<bool>(single =>
  73. {
  74. refBlock = new Player(PlayerType.Local).GetBlockLookedAt();
  75. blocks = single ? new[] {refBlock} : refBlock?.GetConnectedCubes() ?? new Block[0];
  76. Logging.CommandLog(blocks == null ? "Selection cleared." : blocks.Length + " blocks selected.");
  77. }).Build();
  78. CommandBuilder.Builder("selectBlocksWithID", "Selects blocks with a specific object ID.")
  79. .Action<char>(id =>
  80. blocks = (refBlock = ObjectIdentifier.GetByID(id).FirstOrDefault())?.GetConnectedCubes() ??
  81. new Block[0]).Build();
  82. CommandBuilder.Builder("selectSelectedBlocks", "Selects blocks that are box selected by the player.")
  83. .Action(() =>
  84. {
  85. blocks = new Player(PlayerType.Local).GetSelectedBlocks();
  86. refBlock = blocks.Length > 0 ? blocks[0] : null;
  87. }).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(string name, string desc, Action<string, byte, Block[], Block> action)
  159. {
  160. RuntimeCommands.Register<string, byte>(name, (a1, a2) =>
  161. {
  162. if (CheckNoBlocks(blocks)) return;
  163. action(a1, a2, blocks, refBlock);
  164. }, desc);
  165. ConsoleCommands.RegisterWithChannel<string, byte>(name, (a1, a2, ch) =>
  166. {
  167. var blks = SelectBlocks(ch);
  168. if (CheckNoBlocks(blks)) return;
  169. action(a1, a2, blks, blks[0]);
  170. }, BinaryChannelUtilities.ChannelType.Object, desc);
  171. }
  172. private void RegisterBlockCommand(string name, string desc, Action<float, float, float, Block[], Block> action)
  173. {
  174. RuntimeCommands.Register<float, float, float>(name, (x, y, z) =>
  175. {
  176. if (CheckNoBlocks(blocks)) return;
  177. action(x, y, z, blocks, refBlock);
  178. },
  179. desc);
  180. ConsoleCommands.RegisterWithChannel<float, float, float>(name, (x, y, z, ch) =>
  181. {
  182. var blks = SelectBlocks(ch);
  183. if (CheckNoBlocks(blks)) return;
  184. action(x, y, z, blks, blks[0]);
  185. }, BinaryChannelUtilities.ChannelType.Object, desc);
  186. }
  187. public void OnApplicationQuit()
  188. {
  189. }
  190. public void OnLevelWasLoaded(int level)
  191. {
  192. }
  193. public void OnLevelWasInitialized(int level)
  194. {
  195. }
  196. public void OnUpdate()
  197. {
  198. }
  199. public void OnFixedUpdate()
  200. {
  201. }
  202. public string Name { get; } = "BlockMod";
  203. public string Version { get; } = "v1.0.0";
  204. }
  205. }