Magically import images and more into Gamecraft as blocks
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.

115 lines
4.0KB

  1. using System;
  2. using System.Diagnostics;
  3. using System.IO;
  4. using System.Net;
  5. using System.Text;
  6. using Unity.Mathematics;
  7. using GamecraftModdingAPI;
  8. using GamecraftModdingAPI.Blocks;
  9. using GamecraftModdingAPI.Commands;
  10. using GamecraftModdingAPI.Players;
  11. using GamecraftModdingAPI.Utility;
  12. namespace Pixi.Robots
  13. {
  14. public static class RobotCommands
  15. {
  16. private static double blockSize = 0.2;
  17. public static void CreateRobotFileCommand()
  18. {
  19. CommandBuilder.Builder()
  20. .Name("PixiBotFile")
  21. .Description("Converts a robot file from RCBUP into Gamecraft blocks. Larger robots will freeze your game until conversion completes.")
  22. .Action<string>(ImportRobotFile)
  23. .Build();
  24. }
  25. public static void CreateRobotCRFCommand()
  26. {
  27. CommandBuilder.Builder()
  28. .Name("PixiBot")
  29. .Description("Downloads a robot from Robocraft's Factory and converts it into Gamecraft blocks. Larger robots will freeze your game until conversion completes.")
  30. .Action<string>(ImportRobotOnline)
  31. .Build();
  32. }
  33. private static void ImportRobotFile(string filepath)
  34. {
  35. string file;
  36. try
  37. {
  38. file = File.ReadAllText(filepath);
  39. }
  40. catch (Exception e)
  41. {
  42. Logging.CommandLogError($"Failed to load robot data. Reason: {e.Message}");
  43. Logging.MetaLog(e);
  44. return;
  45. }
  46. RobotStruct? robot = CubeUtility.ParseRobotInfo(file);
  47. if (!robot.HasValue)
  48. {
  49. Logging.CommandLogError($"Failed to parse robot data. File format was not recognised.");
  50. return;
  51. }
  52. float3 position = new Player(PlayerType.Local).Position;
  53. position.y += (float)blockSize;
  54. CubeInfo[] cubes = CubeUtility.ParseCubes(robot.Value);
  55. for (int c = 0; c < cubes.Length; c++) // sometimes I wish this were C++
  56. {
  57. CubeInfo cube = cubes[c];
  58. float3 realPosition = (cube.position * (float)blockSize) + position;
  59. Block newBlock = Block.PlaceNew(cube.block, realPosition, cube.rotation, cube.color, cube.darkness, scale: cube.scale);
  60. // the goal is for this to never evaluate to true (ie all cubes are translated correctly)
  61. if (!string.IsNullOrEmpty(cube.placeholder) && cube.block == BlockIDs.TextBlock)
  62. {
  63. newBlock.Specialise<TextBlock>().Text = cube.placeholder;
  64. }
  65. }
  66. Logging.CommandLog($"Placed {robot.Value.name} by {robot.Value.addedByDisplayName} ({cubes.Length} cubes) beside you");
  67. }
  68. private static void ImportRobotOnline(string robotName)
  69. {
  70. Stopwatch timer = Stopwatch.StartNew();
  71. // download robot data
  72. RobotStruct robot;
  73. try
  74. {
  75. RobotBriefStruct[] botList = RoboAPIUtility.ListRobots(robotName);
  76. if (botList.Length == 0)
  77. throw new Exception("Failed to find robot");
  78. robot = RoboAPIUtility.QueryRobotInfo(botList[0].itemId);
  79. }
  80. catch (Exception e)
  81. {
  82. Logging.CommandLogError($"Failed to download robot data. Reason: {e.Message}");
  83. Logging.MetaLog(e);
  84. timer.Stop();
  85. return;
  86. }
  87. timer.Stop();
  88. Logging.MetaLog($"Completed API calls in {timer.ElapsedMilliseconds}ms");
  89. float3 position = new Player(PlayerType.Local).Position;
  90. position.y += (float)blockSize;
  91. CubeInfo[] cubes = CubeUtility.ParseCubes(robot);
  92. for (int c = 0; c < cubes.Length; c++) // sometimes I wish this were C++
  93. {
  94. CubeInfo cube = cubes[c];
  95. float3 realPosition = (cube.position * (float)blockSize) + position;
  96. Block newBlock = Block.PlaceNew(cube.block, realPosition, cube.rotation, cube.color, cube.darkness, scale: cube.scale);
  97. // the goal is for this to never evaluate to true (ie all cubes are translated correctly)
  98. if (!string.IsNullOrEmpty(cube.placeholder) && cube.block == BlockIDs.TextBlock)
  99. {
  100. newBlock.Specialise<TextBlock>().Text = cube.placeholder;
  101. }
  102. }
  103. Logging.CommandLog($"Placed {robot.name} by {robot.addedByDisplayName} ({cubes.Length} cubes) beside you");
  104. }
  105. }
  106. }