using System.Collections.Generic; using HarmonyLib; using RobocraftX; using RobocraftX.Common; using RobocraftX.Schedulers; using RobocraftX.SimulationModeState; using Svelto.ECS; using Svelto.Tasks; using Svelto.Tasks.Lean; using RobocraftX.Blocks; using RobocraftX.Common.Loading; using RobocraftX.Multiplayer; using RobocraftX.ScreenshotTaker; using Techblox.Environment.Transition; using Techblox.GameSelection; using TechbloxModdingAPI.Blocks; using TechbloxModdingAPI.Engines; using TechbloxModdingAPI.Input; using TechbloxModdingAPI.Players; using TechbloxModdingAPI.Utility; namespace TechbloxModdingAPI.App { public class GameGameEngine : IApiEngine, IReactOnAddAndRemove { public WrappedHandler EnterGame; public WrappedHandler ExitGame; public string Name => "TechbloxModdingAPIGameInfoMenuEngine"; public bool isRemovable => false; public EntitiesDB entitiesDB { set; private get; } private bool enteredGame; private bool loadingFinished; private bool playerJoined; public void Dispose() { ExitGame.Invoke(this, new GameEventArgs { GameName = GetGameData().saveName, GamePath = GetGameData().gameID }); IsInGame = false; loadingFinished = false; playerJoined = false; enteredGame = false; } public void Ready() { enteredGame = true; Player.Joined += OnPlayerJoined; } private void OnPlayerJoined(object sender, PlayerEventArgs args) { if (args.Player.Type != PlayerType.Local) return; playerJoined = true; Player.Joined -= OnPlayerJoined; CheckJoinEvent(); } // game functionality public bool IsInGame { get; private set; } = false; public void ExitCurrentGame(bool async = false) { if (async) { ExitCurrentGameAsync().RunOn(ClientLean.EveryFrameStepRunner_TimeRunningAndStopped); } else { entitiesDB.QueryEntity(CommonExclusiveGroups.GameSceneEGID).WantsToQuit = true; entitiesDB.PublishEntityChange(CommonExclusiveGroups.GameSceneEGID); } } public IEnumerator ExitCurrentGameAsync() { /* while (Lean.EveryFrameStepRunner_RUNS_IN_TIME_STOPPED_AND_RUNNING.isStopping) { yield return Yield.It; } AccessTools.Method(typeof(FullGameCompositionRoot), "SwitchToMenu").Invoke(FullGameFields.Instance, new object[0]);*/ yield return Yield.It; entitiesDB.QueryEntity(CommonExclusiveGroups.GameSceneEGID).WantsToQuit = true; entitiesDB.PublishEntityChange(CommonExclusiveGroups.GameSceneEGID); } public void SaveCurrentGame() { ref GameSceneEntityStruct gses = ref entitiesDB.QueryEntity(CommonExclusiveGroups.GameSceneEGID); gses.LoadAfterSaving = false; gses.SaveNow = true; entitiesDB.PublishEntityChange(CommonExclusiveGroups.GameSceneEGID); } public bool IsTimeRunningMode() { return TimeRunningModeUtil.IsTimeRunningMode(entitiesDB); } public bool IsTimeStoppedMode() { return TimeRunningModeUtil.IsTimeStoppedMode(entitiesDB); } public void ToggleTimeMode() { if (TimeRunningModeUtil.IsTimeStoppedMode(entitiesDB)) FakeInput.ActionInput(toggleMode: true); else { IEnumerator ReloadBuildModeTask() { SwitchAnimationUtil.Start(entitiesDB); while (SwitchAnimationUtil.IsFadeOutActive(entitiesDB)) yield return (TaskContract)Yield.It; FullGameFields._multiplayerParams.MultiplayerMode = MultiplayerMode.SinglePlayer; AccessTools.Method(typeof(FullGameCompositionRoot), "ReloadGame") .Invoke(FullGameFields.Instance, new object[] { }); } ReloadBuildModeTask().RunOn(ClientLean.UIScheduler); } } public EGID[] GetAllBlocksInGame(BlockIDs filter = BlockIDs.Invalid) { var allBlocks = entitiesDB.QueryEntities(); List blockEGIDs = new List(); foreach (var (blocks, _) in allBlocks) { var (buffer, count) = blocks.ToBuffer(); for (int i = 0; i < count; i++) { uint dbid; if (filter == BlockIDs.Invalid) dbid = (uint)filter; else dbid = entitiesDB.QueryEntity(buffer[i].ID).DBID; if (dbid == (ulong)filter) blockEGIDs.Add(buffer[i].ID); } } return blockEGIDs.ToArray(); } public void EnableScreenshotTaker() { ref var local = ref entitiesDB.QueryEntity(ScreenshotTakerEgids.ScreenshotTaker); if (local.enabled) return; local.enabled = true; entitiesDB.PublishEntityChange(ScreenshotTakerEgids.ScreenshotTaker); } public GameSelectionComponent GetGameData() { return entitiesDB.QueryEntity(GameSelectionConstants.GameSelectionEGID); } public void Add(ref LoadingActionEntityStruct entityComponent, EGID egid) { } public void Remove(ref LoadingActionEntityStruct entityComponent, EGID egid) { // Finished loading if (!enteredGame) return; enteredGame = false; loadingFinished = true; CheckJoinEvent(); } private void CheckJoinEvent() { if (!loadingFinished || !playerJoined) return; EnterGame.Invoke(this, new GameEventArgs { GameName = GetGameData().saveName, GamePath = GetGameData().gameID }); IsInGame = true; } } }