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;
        }
 private void LoadStateComplete(Level level)
 {
     RestoreLevel(level);
     RestoreCassetteBlockManager2(level);
     EndPoint.All.ForEach(point => point.ReadyForTime());
     foreach (EventInstance instance in playingEventInstances)
     {
         instance.start();
     }
     playingEventInstances.Clear();
     DeepClonerUtils.ClearSharedDeepCloneState();
     State = States.None;
 }
        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));
        }