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.

251 lines
11KB

  1. using System;
  2. using System.Linq;
  3. using System.Reflection;
  4. using HarmonyLib;
  5. // test
  6. using Svelto.ECS;
  7. using RobocraftX.Blocks;
  8. using RobocraftX.Common;
  9. using RobocraftX.SimulationModeState;
  10. using GamecraftModdingAPI.Commands;
  11. using GamecraftModdingAPI.Events;
  12. using GamecraftModdingAPI.Utility;
  13. using GamecraftModdingAPI.Blocks;
  14. namespace GamecraftModdingAPI.Tests
  15. {
  16. // unused by design
  17. /// <summary>
  18. /// Modding API implemented as a standalone IPA Plugin.
  19. /// Ideally, GamecraftModdingAPI should be loaded by another mod; not itself
  20. /// </summary>
  21. public class GamecraftModdingAPIPluginTest
  22. #if DEBUG
  23. : IllusionPlugin.IEnhancedPlugin
  24. #endif
  25. {
  26. private static Harmony harmony { get; set; }
  27. public string[] Filter { get; } = new string[] { "Gamecraft", "GamecraftPreview" };
  28. public string Name { get; } = Assembly.GetExecutingAssembly().GetName().Name;
  29. public string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString();
  30. public string HarmonyID { get; } = "org.git.exmods.modtainers.gamecraftmoddingapi";
  31. public void OnApplicationQuit()
  32. {
  33. GamecraftModdingAPI.Main.Shutdown();
  34. }
  35. public void OnApplicationStart()
  36. {
  37. FileLog.Reset();
  38. Harmony.DEBUG = true;
  39. GamecraftModdingAPI.Main.Init();
  40. Logging.MetaDebugLog($"Version group id {(uint)ApiExclusiveGroups.versionGroup}");
  41. // in case Steam is not installed/running
  42. // this will crash the game slightly later during startup
  43. //SteamInitPatch.ForcePassSteamCheck = true;
  44. // in case running in a VM
  45. //MinimumSpecsCheckPatch.ForcePassMinimumSpecCheck = true;
  46. // disable some Gamecraft analytics
  47. //AnalyticsDisablerPatch.DisableAnalytics = true;
  48. // disable background music
  49. Logging.MetaDebugLog("Audio Mixers: "+string.Join(",", AudioTools.GetMixers()));
  50. //AudioTools.SetVolume(0.0f, "Music"); // The game now sets this from settings again after this is called :(
  51. Utility.VersionTracking.Enable();
  52. // debug/test handlers
  53. HandlerBuilder.Builder()
  54. .Name("appinit API debug")
  55. .Handle(EventType.ApplicationInitialized)
  56. .OnActivation(() => { Logging.Log("App Inited event!"); })
  57. .Build();
  58. HandlerBuilder.Builder("menuact API debug")
  59. .Handle(EventType.Menu)
  60. .OnActivation(() => { Logging.Log("Menu Activated event!"); })
  61. .OnDestruction(() => { Logging.Log("Menu Destroyed event!"); })
  62. .Build();
  63. HandlerBuilder.Builder("menuswitch API debug")
  64. .Handle(EventType.MenuSwitchedTo)
  65. .OnActivation(() => { Logging.Log("Menu Switched To event!"); })
  66. .Build();
  67. HandlerBuilder.Builder("gameact API debug")
  68. .Handle(EventType.Menu)
  69. .OnActivation(() => { Logging.Log("Game Activated event!"); })
  70. .OnDestruction(() => { Logging.Log("Game Destroyed event!"); })
  71. .Build();
  72. HandlerBuilder.Builder("gamerel API debug")
  73. .Handle(EventType.GameReloaded)
  74. .OnActivation(() => { Logging.Log("Game Reloaded event!"); })
  75. .Build();
  76. HandlerBuilder.Builder("gameswitch API debug")
  77. .Handle(EventType.GameSwitchedTo)
  78. .OnActivation(() => { Logging.Log("Game Switched To event!"); })
  79. .Build();
  80. HandlerBuilder.Builder("simulationswitch API debug")
  81. .Handle(EventType.SimulationSwitchedTo)
  82. .OnActivation(() => { Logging.Log("Game Mode Simulation Switched To event!"); })
  83. .Build();
  84. HandlerBuilder.Builder("buildswitch API debug")
  85. .Handle(EventType.BuildSwitchedTo)
  86. .OnActivation(() => { Logging.Log("Game Mode Build Switched To event!"); })
  87. .Build();
  88. HandlerBuilder.Builder("menu activated API error thrower test")
  89. .Handle(EventType.Menu)
  90. .OnActivation(() => { throw new Exception("Event Handler always throws an exception!"); })
  91. .Build();
  92. // debug/test commands
  93. if (Dependency.Hell("ExtraCommands"))
  94. {
  95. CommandBuilder.Builder()
  96. .Name("Exit")
  97. .Description("Close Gamecraft immediately, without any prompts")
  98. .Action(() => { UnityEngine.Application.Quit(); })
  99. .Build();
  100. CommandBuilder.Builder()
  101. .Name("SetFOV")
  102. .Description("Set the player camera's field of view")
  103. .Action((float d) => { UnityEngine.Camera.main.fieldOfView = d; })
  104. .Build();
  105. CommandBuilder.Builder()
  106. .Name("MoveLastBlock")
  107. .Description("Move the most-recently-placed block, and any connected blocks by the given offset")
  108. .Action((float x, float y, float z) =>
  109. {
  110. if (GameState.IsBuildMode())
  111. foreach (var block in Block.GetLastPlacedBlock().GetConnectedCubes())
  112. block.Position += new Unity.Mathematics.float3(x, y, z);
  113. else
  114. GamecraftModdingAPI.Utility.Logging.CommandLogError("Blocks can only be moved in Build mode!");
  115. }).Build();
  116. CommandBuilder.Builder()
  117. .Name("PlaceAluminium")
  118. .Description("Place a block of aluminium at the given coordinates")
  119. .Action((float x, float y, float z) => { Block.PlaceNew(Blocks.BlockIDs.AluminiumCube, new Unity.Mathematics.float3(x, y, z)); })
  120. .Build();
  121. System.Random random = new System.Random(); // for command below
  122. CommandBuilder.Builder()
  123. .Name("RandomizeSignalsInputs")
  124. .Description("Do the thing")
  125. .Action(() => {
  126. if (!GameState.IsSimulationMode())
  127. {
  128. Logging.CommandLogError("You must be in simulation mode for this to work!");
  129. return;
  130. }
  131. Tasks.Repeatable task = new Tasks.Repeatable(
  132. () => {
  133. uint count = 0;
  134. EGID[] eBlocks = Blocks.Signals.GetElectricBlocks();
  135. for (uint i = 0u; i < eBlocks.Length; i++)
  136. {
  137. uint[] ids = Blocks.Signals.GetSignalIDs(eBlocks[i]);
  138. for (uint j = 0u; j < ids.Length; j++)
  139. {
  140. Blocks.Signals.SetSignalByID(ids[j], (float)random.NextDouble());
  141. count++;
  142. }
  143. }
  144. Logging.MetaDebugLog($"Did the thing on {count} inputs");
  145. },
  146. () => { return GameState.IsSimulationMode(); });
  147. Tasks.Scheduler.Schedule(task);
  148. }).Build();
  149. CommandBuilder.Builder("getBlock")
  150. .Action(() => uREPL.Log.Output(new Player(Players.PlayerType.Local).GetBlockLookedAt()+"")).Build();
  151. CommandBuilder.Builder("changeToAluminium")
  152. .Action(() => new Player(Players.PlayerType.Local).GetBlockLookedAt().Type = BlockIDs.AluminiumCube)
  153. .Build();
  154. CommandBuilder.Builder("Error", "Throw an error to make sure SimpleCustomCommandEngine's wrapper catches it.")
  155. .Action(() => { throw new Exception("Error Command always throws an error"); })
  156. .Build();
  157. /*
  158. CommandManager.AddCommand(new SimpleCustomCommandEngine<float>((float d) => { UnityEngine.Camera.main.fieldOfView = d; },
  159. "SetFOV", "Set the player camera's field of view"));
  160. CommandManager.AddCommand(new SimpleCustomCommandEngine<float, float, float>(
  161. (x, y, z) => {
  162. bool success = GamecraftModdingAPI.Blocks.Movement.MoveConnectedBlocks(
  163. GamecraftModdingAPI.Blocks.BlockIdentifiers.LatestBlockID,
  164. new Unity.Mathematics.float3(x, y, z));
  165. if (!success)
  166. {
  167. GamecraftModdingAPI.Utility.Logging.CommandLogError("Blocks can only be moved in Build mode!");
  168. }
  169. }, "MoveLastBlock", "Move the most-recently-placed block, and any connected blocks by the given offset"));
  170. CommandManager.AddCommand(new SimpleCustomCommandEngine<float, float, float>(
  171. (x, y, z) => { Blocks.Placement.PlaceBlock(Blocks.BlockIDs.AluminiumCube, new Unity.Mathematics.float3(x, y, z)); },
  172. "PlaceAluminium", "Place a block of aluminium at the given coordinates"));
  173. System.Random random = new System.Random(); // for command below
  174. CommandManager.AddCommand(new SimpleCustomCommandEngine(
  175. () => {
  176. if (!GameState.IsSimulationMode())
  177. {
  178. Logging.CommandLogError("You must be in simulation mode for this to work!");
  179. return;
  180. }
  181. Tasks.Repeatable task = new Tasks.Repeatable(() => {
  182. uint count = 0;
  183. EGID[] eBlocks = Blocks.Signals.GetElectricBlocks();
  184. for (uint i = 0u; i < eBlocks.Length; i++)
  185. {
  186. uint[] ids = Blocks.Signals.GetSignalIDs(eBlocks[i]);
  187. for (uint j = 0u; j < ids.Length; j++)
  188. {
  189. Blocks.Signals.SetSignalByID(ids[j], (float)random.NextDouble());
  190. count++;
  191. }
  192. }
  193. Logging.MetaDebugLog($"Did the thing on {count} inputs");
  194. },
  195. () => { return GameState.IsSimulationMode(); });
  196. Tasks.Scheduler.Schedule(task);
  197. }, "RandomizeSignalsInputs", "Do the thing"));
  198. */
  199. }
  200. // dependency test
  201. if (Dependency.Hell("GamecraftScripting", new Version("0.0.1.0")))
  202. {
  203. Logging.LogWarning("You're in GamecraftScripting dependency hell");
  204. }
  205. else
  206. {
  207. Logging.Log("Compatible GamecraftScripting detected");
  208. }
  209. }
  210. public void OnFixedUpdate() { }
  211. public void OnLateUpdate() { }
  212. public void OnLevelWasInitialized(int level) { }
  213. public void OnLevelWasLoaded(int level) { }
  214. public void OnUpdate() { }
  215. }
  216. }