using UnityEngine;
using System.Collections.Generic;
namespace PixelCrushers.DialogueSystem
{
///
/// Adds three Lua functions:
/// - PushConversationPosition(): Saves the current conversation position on the top of a stack.
/// - PopConversationPosition(): Removes the conversation position on the top of the stack and returns to it.
/// - ClearConversationPositionStack(): Clears the stack.
///
[AddComponentMenu("")] // Use wrapper.
public class ConversationPositionStack : MonoBehaviour
{
[Tooltip("Clear stack when new conversation starts. Only applies if component is on Dialogue Manager.")]
public bool clearOnConversationStart = true;
[Tooltip("Typically leave unticked so temporary Dialogue Manager's don't unregister your functions.")]
public bool unregisterOnDisable = false;
[Tooltip("Push current dialogue entry instead of its follow-up entry. Use care if ticked; can cause to loop back on itself infinitely.")]
public bool pushCurrentEntry = false;
private static Stack s_stack = new Stack();
public static bool s_pushCurrentEntry = false;
#if UNITY_2019_3_OR_NEWER && UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
static void InitStaticVariables()
{
s_stack = new Stack();
}
#endif
private void OnEnable()
{
Lua.RegisterFunction("PushConversationPosition", null, SymbolExtensions.GetMethodInfo(() => PushConversationPosition()));
Lua.RegisterFunction("PopConversationPosition", null, SymbolExtensions.GetMethodInfo(() => PopConversationPosition()));
Lua.RegisterFunction("ClearConversationPositionStack", null, SymbolExtensions.GetMethodInfo(() => ClearConversationPositionStack()));
s_pushCurrentEntry = pushCurrentEntry;
}
private void OnDisable()
{
if (unregisterOnDisable)
{
Lua.UnregisterFunction("PushConversationPosition");
Lua.UnregisterFunction("PopConversationPosition");
Lua.UnregisterFunction("ClearConversationPositionStack");
}
}
private void OnConversationStart(Transform actor)
{
if (clearOnConversationStart) ClearConversationPositionStack();
}
public static void PushConversationPosition()
{
try
{
if (!DialogueManager.isConversationActive || DialogueManager.currentConversationState == null)
{
if (DialogueDebug.logWarnings) Debug.LogWarning("Dialogue System: PushConversationPosition() Lua function can't save the current conversation position because no conversation is active.");
}
else
{
var state = DialogueManager.currentConversationState;
var entry = s_pushCurrentEntry ? state.subtitle.dialogueEntry
: state.hasNPCResponse ? state.firstNPCResponse.destinationEntry
: state.hasPCResponses ? state.pcResponses[0].destinationEntry
: null;
if (entry == null)
{
if (DialogueDebug.logWarnings) Debug.LogWarning("Dialogue System: PushConversationPosition() Lua function can't save the current conversation position because it's invalid.");
}
else
{
s_stack.Push(entry);
if (DialogueDebug.logInfo) Debug.Log("Dialogue System: PushConversationPosition() Lua function saved entry " + entry.conversationID + ":" + entry.id + ": '" + entry.currentDialogueText + "'.");
}
}
}
catch (System.Exception e)
{
Debug.LogException(e);
throw e;
}
}
public static void PopConversationPosition()
{
try
{
if (!DialogueManager.isConversationActive || DialogueManager.currentConversationState == null)
{
if (DialogueDebug.logWarnings) Debug.LogWarning("Dialogue System: PopConversationPosition() Lua function can't restore a saved conversation position because no conversation is active.");
}
else if (s_stack.Count == 0)
{
if (DialogueDebug.logWarnings) Debug.LogWarning("Dialogue System: PopConversationPosition() Lua function can't restore a saved conversation position no positions are saved on the stack.");
}
else
{
var entry = s_stack.Pop();
if (DialogueDebug.logInfo) Debug.Log("Dialogue System: PopConversationPosition() Lua function is returning to entry " + entry.conversationID + ":" + entry.id + ": '" + entry.currentDialogueText + "'.");
DialogueManager.conversationModel.ForceNextStateToLinkToEntry(entry);
}
}
catch (System.Exception e)
{
Debug.LogException(e);
throw e;
}
}
public static void ClearConversationPositionStack()
{
if (DialogueDebug.logInfo) Debug.Log("Dialogue System: ClearConversationPosition() Lua function is clearing the conversation position stack.");
s_stack.Clear();
}
}
}