Files
beyond/Assets/Scripts/Triggers/PortalTrigger.cs

221 lines
7.3 KiB
C#

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<string> excludedLevels = new List<string>();
private Dictionary<string, bool> m_originalDialogueStates = new Dictionary<string, bool>();
#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<DialogueSystemTrigger>();
m_genericTrigger = GetComponent<bTriggerGenericAction>();
// ### 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
/// <summary>
/// This is called by Lua from dialogue or directly by OnPressAction. It begins the fade out.
/// </summary>
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();
}
/// <summary>
/// This is called after the fade-out animation has finished. It loads the scene.
/// </summary>
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<string>();
}
[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
}
}