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.

151 lines
4.5KB

  1. using System.Collections.Generic;
  2. using RobocraftX.Common;
  3. using RobocraftX.Schedulers;
  4. using RobocraftX.SimulationModeState;
  5. using Svelto.ECS;
  6. using Svelto.Tasks;
  7. using Svelto.Tasks.Lean;
  8. using RobocraftX.Blocks;
  9. using RobocraftX.Common.Loading;
  10. using RobocraftX.ScreenshotTaker;
  11. using Techblox.Environment.Transition;
  12. using Techblox.GameSelection;
  13. using TechbloxModdingAPI.Blocks;
  14. using TechbloxModdingAPI.Engines;
  15. using TechbloxModdingAPI.Utility;
  16. namespace TechbloxModdingAPI.App
  17. {
  18. public class GameGameEngine : IApiEngine, IReactOnAddAndRemove<LoadingActionEntityStruct>
  19. {
  20. public WrappedHandler<GameEventArgs> EnterGame;
  21. public WrappedHandler<GameEventArgs> ExitGame;
  22. public string Name => "TechbloxModdingAPIGameInfoMenuEngine";
  23. public bool isRemovable => false;
  24. public EntitiesDB entitiesDB { set; private get; }
  25. private bool enteredGame;
  26. public void Dispose()
  27. {
  28. ExitGame.Invoke(this, new GameEventArgs { GameName = GetGameData().saveName, GamePath = GetGameData().gameID });
  29. IsInGame = false;
  30. }
  31. public void Ready()
  32. {
  33. enteredGame = true;
  34. }
  35. // game functionality
  36. public bool IsInGame
  37. {
  38. get;
  39. private set;
  40. } = false;
  41. public void ExitCurrentGame(bool async = false)
  42. {
  43. if (async)
  44. {
  45. ExitCurrentGameAsync().RunOn(Lean.EveryFrameStepRunner_TimeRunningAndStopped);
  46. }
  47. else
  48. {
  49. entitiesDB.QueryEntity<GameSceneEntityStruct>(CommonExclusiveGroups.GameSceneEGID).WantsToQuit = true;
  50. entitiesDB.PublishEntityChange<GameSceneEntityStruct>(CommonExclusiveGroups.GameSceneEGID);
  51. }
  52. }
  53. public IEnumerator<TaskContract> ExitCurrentGameAsync()
  54. {
  55. /*
  56. while (Lean.EveryFrameStepRunner_RUNS_IN_TIME_STOPPED_AND_RUNNING.isStopping) { yield return Yield.It; }
  57. AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToMenu").Invoke(FullGameFields.Instance, new object[0]);*/
  58. yield return Yield.It;
  59. entitiesDB.QueryEntity<GameSceneEntityStruct>(CommonExclusiveGroups.GameSceneEGID).WantsToQuit = true;
  60. entitiesDB.PublishEntityChange<GameSceneEntityStruct>(CommonExclusiveGroups.GameSceneEGID);
  61. }
  62. public void SaveCurrentGame()
  63. {
  64. ref GameSceneEntityStruct gses = ref entitiesDB.QueryEntity<GameSceneEntityStruct>(CommonExclusiveGroups.GameSceneEGID);
  65. gses.LoadAfterSaving = false;
  66. gses.SaveNow = true;
  67. entitiesDB.PublishEntityChange<GameSceneEntityStruct>(CommonExclusiveGroups.GameSceneEGID);
  68. }
  69. public bool IsTimeRunningMode()
  70. {
  71. return TimeRunningModeUtil.IsTimeRunningMode(entitiesDB);
  72. }
  73. public bool IsTimeStoppedMode()
  74. {
  75. return TimeRunningModeUtil.IsTimeStoppedMode(entitiesDB);
  76. }
  77. public void ToggleTimeMode()
  78. {
  79. if (!entitiesDB.FoundInGroups<BlockTagEntityStruct>())
  80. throw new AppStateException("At least one block must exist in the world to enter simulation");
  81. SwitchAnimationUtil.Start(entitiesDB);
  82. }
  83. public EGID[] GetAllBlocksInGame(BlockIDs filter = BlockIDs.Invalid)
  84. {
  85. var allBlocks = entitiesDB.QueryEntities<BlockTagEntityStruct>();
  86. List<EGID> blockEGIDs = new List<EGID>();
  87. foreach (var (blocks, _) in allBlocks)
  88. {
  89. var (buffer, count) = blocks.ToBuffer();
  90. for (int i = 0; i < count; i++)
  91. {
  92. uint dbid;
  93. if (filter == BlockIDs.Invalid)
  94. dbid = (uint)filter;
  95. else
  96. dbid = entitiesDB.QueryEntity<DBEntityStruct>(buffer[i].ID).DBID;
  97. if (dbid == (ulong)filter)
  98. blockEGIDs.Add(buffer[i].ID);
  99. }
  100. }
  101. return blockEGIDs.ToArray();
  102. }
  103. public void EnableScreenshotTaker()
  104. {
  105. ref var local = ref entitiesDB.QueryEntity<ScreenshotModeEntityStruct>(ScreenshotTakerEgids.ScreenshotTaker);
  106. if (local.enabled)
  107. return;
  108. local.enabled = true;
  109. entitiesDB.PublishEntityChange<ScreenshotModeEntityStruct>(ScreenshotTakerEgids.ScreenshotTaker);
  110. }
  111. public GameSelectionComponent GetGameData()
  112. {
  113. return entitiesDB.QueryEntity<GameSelectionComponent>(GameSelectionConstants.GameSelectionEGID);
  114. }
  115. public void Add(ref LoadingActionEntityStruct entityComponent, EGID egid)
  116. {
  117. }
  118. public void Remove(ref LoadingActionEntityStruct entityComponent, EGID egid)
  119. { // Finished loading
  120. if (!enteredGame) return;
  121. EnterGame.Invoke(this, new GameEventArgs { GameName = GetGameData().saveName, GamePath = GetGameData().gameID });
  122. IsInGame = true;
  123. enteredGame = false;
  124. }
  125. }
  126. }