private void SaveState(Level level, Player player) { ClearState(); loadState = SaveLoad.LoadState.Start; sessionCoreModeBackup = level.Session.CoreMode; savedSession = level.Session.DeepClone(); savedSession.CoreMode = level.CoreMode; level.Session.CoreMode = level.CoreMode; SavedPlayer = player; SavedLevel = level; SavedEntitiesDict = level.FindAllToDict <Entity>(out SavedDuplicateIdList); // save all mod sessions savedModSessions = new Dictionary <EverestModule, EverestModuleSession>(); foreach (EverestModule module in Everest.Modules) { if (module._Session != null) { savedModSessions[module] = module._Session.DeepCloneYaml <EverestModuleSession>(module.SessionType); } } RestoreEntityUtils.OnSaveState(level); Engine.Scene = new LevelLoader(level.Session, level.Session.RespawnPoint); }
public void OnUnload() { On.Celeste.AreaData.DoScreenWipe -= QuickLoadWhenDeath; On.Celeste.Level.Update -= LevelOnUpdate; On.Celeste.Overworld.ctor -= ClearStateAndPbTimes; On.Celeste.Player.Die -= PlayerOnDie; AttachEntityId2Utils.Unload(); RestoreEntityUtils.Unload(); }
// 尽快设置人物的位置与镜头,然后冻结游戏等待人物复活 // Set player position ASAP, then freeze game and wait for the player to respawn (? - euni) private void LoadStart(Level level) { level.Session.Inventory = savedSession.Inventory; level.Camera.CopyFrom(SavedLevel.Camera); level.CameraLockMode = SavedLevel.CameraLockMode; level.CameraOffset = SavedLevel.CameraOffset; level.CoreMode = savedSession.CoreMode; level.Session.CoreMode = sessionCoreModeBackup; RestoreWind(level); RestoreEntityUtils.OnLoadStart(level); }
private void ClearState() { if (Engine.Scene is Level level) { level.Frozen = false; } savedSession = null; savedModSessions = null; SavedPlayer = null; SavedLevel = null; SavedEntitiesDict.Clear(); SavedDuplicateIdList.Clear(); loadState = SaveLoad.LoadState.None; RestoreEntityUtils.OnClearState(); }
private void LevelOnUpdate(On.Celeste.Level.orig_Update orig, Level level) { if (!SpeedrunToolModule.Enabled) { orig(level); return; } Player player = level.Entities.FindFirst <Player>(); if (CheckButton(level, player)) { return; } // 章节切换时清除保存的状态以及房间计时器自定终点 // Clear the savestate and custom end point when switching chapters if (IsSaved && (savedSession.Area.ID != level.Session.Area.ID || savedSession.Area.Mode != level.Session.Area.Mode)) { ClearState(); RoomTimerManager.Instance.ClearPbTimes(); } // 尽快设置人物的位置与镜头,然后冻结游戏等待人物复活 // Set player position ASAP, then freeze game and wait for the player to respawn (? - euni) if (IsSaved && IsLoadStart && player != null) { LoadStart(level); // 调用 Level.Update 多次使所有 Entity 更新绘完毕后后再冻结游戏 // Wait for some frames so entities can be updated and rendered, then freeze game. for (int i = 0; i < 3; i++) { orig(level); } // 等所有 Entity 创建完毕并渲染完成后再统一在此时机还原状态 RestoreEntityUtils.AfterEntityAwake(level); // 冻结游戏等待 Madeline 复活 // Freeze the game wait for madeline respawn. if (player.StateMachine.State == Player.StIntroRespawn) { level.Frozen = true; level.PauseLock = true; loadState = SaveLoad.LoadState.Frozen; } else { loadState = SaveLoad.LoadState.PlayerRespawned; } return; } // 冻结时允许人物 Update 以便复活 // Allow player to respawn while level is frozen if (IsSaved && IsLoadFrozen) { UpdatePlayerWhenFreeze(level, player); } // 人物复活完毕后设置人物相关属性 // Set more player data after the player respawns if (IsSaved && (IsPlayerRespawned || IsLoadFrozen) && player != null && (player.StateMachine.State == Player.StNormal || player.StateMachine.State == Player.StSwim || player.StateMachine.State == Player.StFlingBird)) { RestoreEntityUtils.AfterPlayerRespawn(level); level.Frozen = false; level.PauseLock = false; // BadelinOldsite 追踪需要 level.TimeActive = SavedLevel.TimeActive; loadState = SaveLoad.LoadState.Complete; RestoreEntityUtils.OnLoadComplete(level); } orig(level); }