using System.Collections; using AibisDream.Framework; using UnityEngine; namespace AibisDream.FixSystem { /// /// Directs Fix scene mode transitions. This is a scene cue board, not a gameplay state machine: /// cues orchestrate cameras, timelines, UI masks, bubbles and interaction setup. /// public class FixSceneDirector { public FixSceneMode CurrentMode { get; private set; } public bool HasMode { get; private set; } public bool IsTransitioning { get; private set; } private readonly FixSystemData _data; private IFixSceneCue _currentCue; public FixSceneDirector(FixSystemData data) { _data = data; } public IEnumerator Init(FixSceneMode initMode) { _data.curMode = initMode; _data.args = ""; yield return TransitionInternal(initMode, "", FixTransitionMode.Animated); } public IEnumerator TransitionTo(FixSceneMode nextMode, string args = "") { yield return TransitionInternal(nextMode, args, FixTransitionMode.Animated); } public IEnumerator TransitionToImmediate(FixSceneMode nextMode, string args = "") { yield return TransitionInternal(nextMode, args, FixTransitionMode.Immediate); } public IEnumerator QuitCurrentMode() { if (_currentCue != null) { var transition = new FixTransition(CurrentMode, FixSceneMode.Default, "", FixTransitionMode.Animated); yield return _currentCue.Exit(transition); } _data.curMode = FixSceneMode.Default; _data.args = ""; _currentCue = null; CurrentMode = FixSceneMode.Default; HasMode = false; IsTransitioning = false; } private IEnumerator TransitionInternal(FixSceneMode nextMode, string args, FixTransitionMode mode) { if (IsTransitioning && mode == FixTransitionMode.Animated) { Debug.LogWarning($"[FixSceneDirector] Transition ignored while another transition is running: {CurrentMode} -> {nextMode}"); yield break; } if (HasMode && CurrentMode.Equals(nextMode)) { yield break; } IsTransitioning = true; var transition = new FixTransition(HasMode ? CurrentMode : null, nextMode, args, mode); if (mode == FixTransitionMode.Animated && _currentCue != null) { yield return _currentCue.Exit(transition); } _currentCue = CreateCue(nextMode, args); CurrentMode = nextMode; HasMode = true; _data.curMode = nextMode; _data.args = args ?? ""; EnumEventSystem.Global.Send(EventEnum.FixSceneModeChanged, nextMode); if (mode == FixTransitionMode.Immediate) { yield return _currentCue.EnterImmediate(transition); } else { yield return _currentCue.Enter(transition); } IsTransitioning = false; } private static IFixSceneCue CreateCue(FixSceneMode nextMode, string args) { IFixSceneCue res = nextMode switch { FixSceneMode.Default => new DefaultCue(), FixSceneMode.Clinic => new ClinicCue(), FixSceneMode.BodyModule => new BodyModuleCue(), FixSceneMode.Memory => new MemoryCue(), FixSceneMode.Eye => new EyeCue(), FixSceneMode.UF => new UfCue(), FixSceneMode.Expression => new ExpressionCue(), FixSceneMode.Emo => new EmoCue(), FixSceneMode.Op => new OpCue(), FixSceneMode.EmoCut => new EmoCutCue(), FixSceneMode.MemoryCut => new MemoryCutCue(), FixSceneMode.LogicCut => new LogicCutCue(), FixSceneMode.Dream => new DreamCue(), FixSceneMode.AnalysisMode => new AnalysisModeCue(), FixSceneMode.Sales => new SalesCue(), FixSceneMode.BlockPuzzle => new BlockPuzzleCue(), _ => new DefaultCue() }; res.SetArgs(args); return res; } } }