using System.Collections.Generic; using Invector; using PixelCrushers.DialogueSystem; using Sirenix.OdinInspector; using UnityEngine; using System.Collections; namespace Beyond { [RequireComponent(typeof(DialogueSystemTrigger))] [RequireComponent(typeof(bTriggerGenericAction))] public class PortalTrigger : MonoBehaviour { private static bool s_luaMethodRegistered = false; private DialogueSystemTrigger m_dialogueTrigger; private bTriggerGenericAction m_genericTrigger; private string m_levelToLoad; [Title("Level Configuration")] [Tooltip("Assign your LevelLoaderData ScriptableObject here. This is the source for all level information.")] [Required] public LevelLoaderData levelLoaderData; [Title("Direct Loading")] [Tooltip("If true, the trigger will load the specified level directly without showing a dialogue.")] public bool useDirectLoad = false; [Tooltip("The name of the level to load directly.")] [ShowIf("useDirectLoad")] [ValueDropdown("GetLevelNamesForDropdown")] public string directLoadLevelName; [Title("Dialogue Configuration")] [Tooltip("A list of levels to temporarily hide from the dialogue-based level selection.")] [HideIf("useDirectLoad")] [ValueDropdown("GetLevelNamesForDropdown")] public List excludedLevels = new List(); private Dictionary m_originalDialogueStates = new Dictionary(); #region Lua & Dialogue Variable Management void SetDialogueVariable(string levelName, bool unlocked) { if (levelLoaderData == null) return; LevelData data = levelLoaderData.GetData(levelName); if (data != null && !string.IsNullOrEmpty(data.DialogueVariableName)) { DialogueLua.SetVariable(data.DialogueVariableName, unlocked); } } bool GetDialogueVariable(string levelName) { if (levelLoaderData == null) return false; LevelData data = levelLoaderData.GetData(levelName); if (data != null && !string.IsNullOrEmpty(data.DialogueVariableName)) { return DialogueLua.GetVariable(data.DialogueVariableName).asBool; } return false; } private void ExcludeSelectedLevels() { m_originalDialogueStates.Clear(); foreach (string levelName in excludedLevels) { bool originalState = GetDialogueVariable(levelName); m_originalDialogueStates[levelName] = originalState; if (originalState) { SetDialogueVariable(levelName, false); } } } private void RestoreExcludedLevels() { if (m_originalDialogueStates.Count == 0) return; foreach (var entry in m_originalDialogueStates) { SetDialogueVariable(entry.Key, entry.Value); } m_originalDialogueStates.Clear(); } private void RegisterLuaFunctions() { if (!s_luaMethodRegistered) { // Note: The Lua function is still named "LoadLevel" for consistency with your Dialogue entries. // It correctly calls our C# method StartLevelLoad. Lua.RegisterFunction("LoadLevel", this, SymbolExtensions.GetMethodInfo(() => StartLevelLoad((string)null))); s_luaMethodRegistered = true; } } private void UnregisterLuaFunctions() { if (s_luaMethodRegistered) { Lua.UnregisterFunction("LoadLevel"); s_luaMethodRegistered = false; } } #endregion #region Unity Lifecycle & Triggers protected void Start() { m_dialogueTrigger = GetComponent(); m_genericTrigger = GetComponent(); // ### FIX HERE ### // Changed "LoadLevel" to "LoadLevelScene" to match the renamed method. FadeCanvasGroup.Instance.OnLoadingFadeOutEnd.AddListener(LoadLevelScene); m_genericTrigger.OnPressActionInput.AddListener(OnPressAction); m_genericTrigger.OnPlayerExit.AddListener((go) => { RestoreExcludedLevels(); UnregisterLuaFunctions(); }); } private void OnDestroy() { if (FadeCanvasGroup.Instance != null) { // ### FIX HERE ### // Changed "LoadLevel" to "LoadLevelScene" to match the renamed method. FadeCanvasGroup.Instance.OnLoadingFadeOutEnd.RemoveListener(LoadLevelScene); } if (m_genericTrigger != null) { m_genericTrigger.OnPressActionInput.RemoveListener(OnPressAction); } RestoreExcludedLevels(); UnregisterLuaFunctions(); } private void OnPressAction() { if (useDirectLoad) { StartLevelLoad(directLoadLevelName); } else { RegisterLuaFunctions(); ExcludeSelectedLevels(); m_dialogueTrigger.OnUse(); } } #endregion #region Level Loading /// /// This is called by Lua from dialogue or directly by OnPressAction. It begins the fade out. /// private void StartLevelLoad(string name) { if (string.IsNullOrEmpty(name) || levelLoaderData.GetData(name) == null) { Debug.LogError($"Level '{name}' not found in LevelLoaderData or name is invalid."); return; } m_levelToLoad = name; FadeCanvasGroup.Instance.BeforeLoadingFade(); } /// /// This is called after the fade-out animation has finished. It loads the scene. /// private void LoadLevelScene() { if (string.IsNullOrEmpty(m_levelToLoad)) return; LevelData levelData = levelLoaderData.GetData(m_levelToLoad); if (levelData != null) { ProxySceneLoader.LoadScene(levelData.LevelName); } else { Debug.LogError($"Failed to find level data for '{m_levelToLoad}' during scene loading."); } } #endregion #region Editor & Debugging private IEnumerable GetLevelNamesForDropdown() { if (levelLoaderData != null) { return levelLoaderData.GetAllLevelNames(); } return new List(); } [Button("Unlock Level (For Debugging)")] public void UnlockLevel([ValueDropdown("GetLevelNamesForDropdown")] string levelName) { if(!string.IsNullOrEmpty(levelName)) { SetDialogueVariable(levelName, true); Debug.Log($"Set {levelName} to unlocked."); } } #endregion } }