private static void Load() { On.Celeste.Strawberry.Added += StrawberryOnAdded; IL.Celeste.SpeedrunTimerDisplay.DrawTime += SetSaveStateColor; IL.Celeste.Level.Reload += LevelOnReload; SaveLoadAction.Add(new SaveLoadAction(ReColor, ReColor)); }
private void ClearState(bool clearEndPoint) { if (Engine.Scene is Level level && IsNotCollectingHeart(level) && !level.Completed) { level.Frozen = false; level.PauseLock = false; } RoomTimerManager.Instance.ClearPbTimes(clearEndPoint); playingEventInstances.Clear(); savedModSessions = null; savedLevel = null; savedEntities?.Clear(); savedEntities = null; savedOrderedTrackerEntities?.Clear(); savedOrderedTrackerEntities = null; savedOrderedTrackerComponents?.Clear(); savedOrderedTrackerComponents = null; preCloneTask = null; DeepClonerUtils.ClearSharedDeepCloneState(); // Mod SaveLoadAction.OnClearState(); SavedByTas = false; State = States.None; }
// public for TAS Mod // ReSharper disable once MemberCanBePrivate.Global public bool LoadState() { if (!(Engine.Scene is Level level)) { return(false); } if (level.Paused || state != States.None || !IsSaved) { return(false); } state = States.Loading; // External RoomTimerManager.Instance.ResetTime(); DeathStatisticsManager.Instance.Died = false; // Mod SaveLoadAction.OnLoadState(level); level.SetFieldValue("transition", null); // 允许切换房间时读档 level.Displacement.Clear(); // 避免冲刺后读档残留爆破效果 TrailManager.Clear(); // 清除冲刺的残影 UnloadLevelEntities(level); RestoreLevelEntities(level); RestoreCassetteBlockManager(level); RestoreLevel(level); // restore all mod sessions foreach (EverestModule module in Everest.Modules) { if (savedModSessions.TryGetValue(module, out EverestModuleSession savedModSession)) { module._Session = savedModSession.DeepCloneYaml(module.SessionType); } } // 修复问题:未打开自动读档时,死掉按下确认键后读档完成会接着执行 Reload 复活方法 if (level.RendererList.Renderers.FirstOrDefault(renderer => renderer is ScreenWipe) is ScreenWipe wipe) { wipe.Cancel(); } level.Frozen = true; // 加一个转场等待,避免太突兀 level.TimerStopped = true; // 停止计时器 level.DoScreenWipe(true, () => { RestoreLevel(level); RoomTimerManager.Instance.SavedEndPoint?.ReadyForTime(); foreach (EventInstance instance in playingEventInstances) { instance.start(); } state = States.None; }); return(true); }
public void OnUnload() { DeepCloneUtils.Clear(); SaveLoadAction.OnUnload(); EventInstanceUtils.OnUnhook(); On.Celeste.Level.Update -= CheckButtonsOnLevelUpdate; On.Monocle.Scene.Begin -= ClearStateWhenSwitchScene; On.Celeste.PlayerDeadBody.End -= AutoLoadStateWhenDeath; }
public void OnLoad() { DeepClonerUtils.Config(); SaveLoadAction.OnLoad(); EventInstanceUtils.OnHook(); StateMarkUtils.OnLoad(); On.Celeste.Level.Update += CheckButtonsAndUpdateBackdrop; On.Monocle.Scene.Begin += ClearStateWhenSwitchScene; On.Celeste.PlayerDeadBody.End += AutoLoadStateWhenDeath; }
// public for TAS Mod // ReSharper disable once MemberCanBePrivate.Global UnusedMethodReturnValue.Global public bool SaveState() { if (!(Engine.Scene is Level level)) { return(false); } if (!IsAllowSave(level, level.GetPlayer())) { return(false); } ClearState(false); savedLevel = level.ShallowClone(); savedLevel.Session = level.Session.DeepClone(); savedLevel.Camera = level.Camera.DeepClone(); savedEntities = DeepCloneEntities(GetEntitiesExcludingGlobal(level)); savedCassetteBlockManager = level.Entities.FindFirst <CassetteBlockManager>()?.ShallowClone(); // External savedFreezeTimer = Engine.FreezeTimer; savedTimeRate = Engine.TimeRate; savedGlitchValue = Glitch.Value; savedDistortAnxiety = Distort.Anxiety; savedDistortGameRate = Distort.GameRate; // Mod SaveLoadAction.OnSaveState(level); // save all mod sessions savedModSessions = new Dictionary <EverestModule, EverestModuleSession>(); foreach (EverestModule module in Everest.Modules) { if (module._Session != null) { savedModSessions[module] = module._Session.DeepCloneYaml(module.SessionType); } } return(LoadState()); }
private void ClearState(bool clearEndPoint = true) { if (Engine.Scene is Level level && IsNotCollectingHeart(level)) { level.Frozen = false; level.PauseLock = false; } try { RoomTimerManager.Instance.ClearPbTimes(clearEndPoint); } catch (NullReferenceException) { } savedModSessions = null; savedLevel = null; savedEntities = null; savedCassetteBlockManager = null; // Mod SaveLoadAction.OnClearState(); state = States.None; }
private bool LoadState(bool tas) { if (!(Engine.Scene is Level level)) { return(false); } if (level.PausedNew() || State != States.None || !IsSaved) { return(false); } if (tas && !SavedByTas) { return(false); } State = States.Loading; DeepClonerUtils.SetSharedDeepCloneState(preCloneTask?.Result); // 修复问题:死亡瞬间读档 PlayerDeadBody 没被清除,导致读档完毕后 madeline 自动 retry level.Entities.UpdateLists(); // External RoomTimerManager.Instance.ResetTime(); DeathStatisticsManager.Instance.Died = false; level.Displacement.Clear(); // 避免冲刺后读档残留爆破效果 // Remove dash displacement effect level.Particles.Clear(); level.ParticlesBG.Clear(); level.ParticlesFG.Clear(); TrailManager.Clear(); // 清除冲刺的残影 // Remove dash trail UnloadLevelEntities(level); GC.Collect(); GC.WaitForPendingFinalizers(); RestoreLevelEntities(level); RestoreCassetteBlockManager1(level); // 停止播放主音乐,等待播放节奏音乐 RestoreLevel(level); // Mod 和其他 SaveLoadAction.OnLoadState(level); // restore all mod sessions foreach (EverestModule module in Everest.Modules) { if (savedModSessions.TryGetValue(module, out EverestModuleSession savedModSession)) { module._Session = savedModSession.DeepCloneShared(); } } // 修复问题:未打开自动读档时,死掉按下确认键后读档完成会接着执行 Reload 复活方法 // Fix: When AutoLoadStateAfterDeath is off, if manually LoadState() after death, level.Reload() will still be executed. ClearScreenWipe(level); if (tas) { LoadStateComplete(level); return(true); } level.Frozen = true; // 加一个转场等待,避免太突兀 // Add a pause to avoid being too abrupt level.TimerStopped = true; // 停止计时器 // Stop timer level.DoScreenWipe(true, () => { // 修复问题:死亡后出现黑屏的一瞬间手动读档后游戏崩溃,因为 ScreenWipe 执行了 level.Reload() 方法 // System.NullReferenceException: 未将对象引用设置到对象的实例。 // 在 Celeste.CameraTargetTrigger.OnLeave(Player player) // 在 Celeste.Player.Removed(Scene scene) ClearScreenWipe(level); LoadStateEnd(level); }); return(true); }
private bool SaveState(bool tas) { if (!(Engine.Scene is Level level)) { return(false); } if (!IsAllowSave(level, level.GetPlayer())) { return(false); } // 不允许玩家在黑屏时保存状态,因为如果在黑屏结束一瞬间之前保存,读档后没有黑屏等待时间感觉会很突兀 if (!tas && level.Wipe != null) { return(false); } // 不允许在春游图打开章节面板时存档 if (inGameOverworldHelperIsOpen.Value?.GetValue(null) as bool? == true) { return(false); } ClearState(false); SavedByTas = tas; savedLevel = level.ShallowClone(); savedLevel.FormationBackdrop = level.FormationBackdrop.ShallowClone(); savedLevel.Session = level.Session.DeepCloneShared(); savedLevel.Camera = level.Camera.DeepCloneShared(); // Renderer savedLevel.Bloom = level.Bloom.DeepCloneShared(); savedLevel.Background = level.Background.DeepCloneShared(); savedLevel.Foreground = level.Foreground.DeepCloneShared(); // savedLevel.HudRenderer = level.HudRenderer.DeepCloneShared(); // savedLevel.SubHudRenderer = level.SubHudRenderer.DeepCloneShared(); // savedLevel.Displacement = level.Displacement.DeepCloneShared(); // 只需浅克隆 savedLevel.Lighting = level.Lighting.ShallowClone(); // 无需克隆,且里面有 camera // savedLevel.GameplayRenderer = level.GameplayRenderer.DeepCloneShared(); // Renderer nullable // savedLevel.Wipe = level.Wipe.DeepCloneShared(); savedLevel.SetFieldValue("transition", level.GetFieldValue("transition").DeepCloneShared()); savedLevel.SetFieldValue("skipCoroutine", level.GetFieldValue("skipCoroutine").DeepCloneShared()); savedLevel.SetFieldValue("onCutsceneSkip", level.GetFieldValue("onCutsceneSkip").DeepCloneShared()); // savedLevel.SetPropertyValue<Scene>("RendererList", level.RendererList.DeepCloneShared()); savedEntities = GetEntitiesNeedDeepClone(level).DeepCloneShared(); savedOrderedTrackerEntities = new Dictionary <Type, Dictionary <Entity, int> >(); foreach (Entity savedEntity in savedEntities) { Type type = savedEntity.GetType(); if (savedOrderedTrackerEntities.ContainsKey(type)) { continue; } if (level.Tracker.Entities.ContainsKey(type) && level.Tracker.Entities[type].Count > 0) { List <Entity> clonedEntities = level.Tracker.Entities[type].DeepCloneShared(); Dictionary <Entity, int> dictionary = new Dictionary <Entity, int>(); for (var i = 0; i < clonedEntities.Count; i++) { dictionary[clonedEntities[i]] = i; } savedOrderedTrackerEntities[type] = dictionary; } } savedOrderedTrackerComponents = new Dictionary <Type, Dictionary <Component, int> >(); foreach (Component component in savedEntities.SelectMany(entity => entity.Components)) { Type type = component.GetType(); if (savedOrderedTrackerComponents.ContainsKey(type)) { continue; } if (level.Tracker.Components.ContainsKey(type) && level.Tracker.Components[type].Count > 0) { List <Component> clonedComponents = level.Tracker.Components[type].DeepCloneShared(); Dictionary <Component, int> dictionary = new Dictionary <Component, int>(); for (var i = 0; i < clonedComponents.Count; i++) { dictionary[clonedComponents[i]] = i; } savedOrderedTrackerComponents[type] = dictionary; } } // External savedFreezeTimer = Engine.FreezeTimer; savedTimeRate = Engine.TimeRate; savedDeltaTime = Engine.DeltaTime; savedRawDeltaTime = Engine.RawDeltaTime; savedFrameCounter = Engine.FrameCounter; savedGlitchValue = Glitch.Value; savedDistortAnxiety = Distort.Anxiety; savedDistortGameRate = Distort.GameRate; // Mod 和其他 SaveLoadAction.OnSaveState(level); // save all mod sessions savedModSessions = new Dictionary <EverestModule, EverestModuleSession>(); foreach (EverestModule module in Everest.Modules) { if (module._Session != null) { savedModSessions[module] = module._Session.DeepCloneShared(); } } DeepClonerUtils.ClearSharedDeepCloneState(); return(LoadState(tas)); }
public static void Add(SaveLoadAction saveLoadAction) { All.Add(saveLoadAction); }