using System; using AppleHills.Core.Settings; using Core; using Input; using Interactions; using System.Threading.Tasks; using UnityEngine; namespace Levels { /// /// Handles level switching when interacted with. Applies switch data and triggers scene transitions. /// public class LevelSwitch : InteractableBase { public LevelSwitchData switchData; private SpriteRenderer _iconRenderer; private IInteractionSettings _interactionSettings; private GameObject _menuObjectRef; /// /// Unity Awake callback. Sets up icon, interactable, and event handlers. /// internal override void OnManagedAwake() { base.OnManagedAwake(); Logging.Debug($"[LevelSwitch] Awake called for {gameObject.name} in scene {gameObject.scene.name}"); if (_iconRenderer == null) _iconRenderer = GetComponent(); // Initialize settings reference _interactionSettings = GameManager.GetSettingsObject(); ApplySwitchData(); } internal override void OnManagedStart() { Logging.Debug($"[LevelSwitch] OnManagedStart called for {gameObject.name}"); } internal override void OnSceneReady() { Logging.Debug($"[LevelSwitch] OnSceneReady called for {gameObject.name}"); } #if UNITY_EDITOR /// /// Unity OnValidate callback. Ensures icon and data are up to date in editor. /// void OnValidate() { if (_iconRenderer == null) _iconRenderer = GetComponent(); ApplySwitchData(); } #endif /// /// Applies the switch data to the level switch (icon, name, etc). /// public void ApplySwitchData() { if (switchData != null) { if (_iconRenderer != null) _iconRenderer.sprite = switchData.mapSprite; gameObject.name = switchData.targetLevelSceneName; // Optionally update other fields, e.g. description } } /// /// Main interaction logic: Spawn menu and switch input mode. /// protected override bool DoInteraction() { if (switchData == null || string.IsNullOrEmpty(switchData.targetLevelSceneName)) { Logging.Warning("LevelSwitch has no valid switchData!"); return false; } var menuPrefab = _interactionSettings?.LevelSwitchMenuPrefab; if (menuPrefab == null) { Debug.LogError("LevelSwitchMenu prefab not assigned in InteractionSettings!"); return false; } // Spawn the menu overlay _menuObjectRef = Instantiate(menuPrefab); var menu = _menuObjectRef.GetComponent(); if (menu == null) { Debug.LogError("LevelSwitchMenu component missing on prefab!"); Destroy(_menuObjectRef); return false; } // Setup menu with data and callbacks menu.Setup(switchData, OnLevelSelectedWrapper, OnMinigameSelected, OnMenuCancel, OnRestartSelected); // Switch input mode to UI only InputManager.Instance.SetInputMode(InputMode.UI); return true; // Menu spawned successfully } private void OnLevelSelectedWrapper() { _ = OnLevelSelected(); } private async Task OnLevelSelected() { var progress = new Progress(p => Logging.Debug($"Loading progress: {p * 100:F0}%")); await SceneManagerService.Instance.SwitchSceneAsync(switchData.targetLevelSceneName, progress); } private async void OnMinigameSelected() { var progress = new Progress(p => Logging.Debug($"Loading progress: {p * 100:F0}%")); await SceneManagerService.Instance.SwitchSceneAsync(switchData.targetMinigameSceneName, progress); } private async void OnRestartSelected() { // Clear all save data for the target level before reloading if (Core.SaveLoad.SaveLoadManager.Instance != null && !string.IsNullOrEmpty(switchData?.targetLevelSceneName)) { Core.SaveLoad.SaveLoadManager.Instance.ClearLevelData(switchData.targetLevelSceneName); Logging.Debug($"[LevelSwitch] Cleared save data for level: {switchData.targetLevelSceneName}"); } // Now reload the level with fresh state - skipSave=true prevents re-saving cleared data var progress = new Progress(p => Logging.Debug($"Loading progress: {p * 100:F0}%")); await SceneManagerService.Instance.SwitchSceneAsync(switchData.targetLevelSceneName, progress, autoHideLoadingScreen: true, skipSave: true); } private void OnMenuCancel() { InputManager.Instance.SetInputMode(InputMode.GameAndUI); } } }