191 lines
9.8 KiB (Stored with Git LFS)
C#
191 lines
9.8 KiB (Stored with Git LFS)
C#
// Copyright (c) Pixel Crushers. All rights reserved.
|
|
|
|
using UnityEngine;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace PixelCrushers.DialogueSystem
|
|
{
|
|
|
|
/// <summary>
|
|
/// Add this script to your Dialogue Manager to keep track of the
|
|
/// current conversation and dialogue entry. When you load a game,
|
|
/// it will resume the conversation at that point.
|
|
/// </summary>
|
|
[AddComponentMenu("")] // Use wrapper.
|
|
public class ConversationStateSaver : Saver
|
|
{
|
|
[Serializable]
|
|
public class Data
|
|
{
|
|
public int conversationID;
|
|
public int entryID;
|
|
public string actorName;
|
|
public string conversantName;
|
|
public List<string> actorGOs = null;
|
|
public List<SubtitlePanelNumber> actorGOPanels = null;
|
|
public List<int> actorIDs = null;
|
|
public List<SubtitlePanelNumber> actorIDPanels = null;
|
|
public List<string> panelOpenOnActorName = null;
|
|
public string accumulatedText;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Override to make default key value "ConversationState".
|
|
/// </summary>
|
|
public override string key
|
|
{
|
|
get
|
|
{
|
|
if (string.IsNullOrEmpty(m_runtimeKey))
|
|
{
|
|
m_runtimeKey = !string.IsNullOrEmpty(_internalKeyValue) ? _internalKeyValue : "ConversationState";
|
|
if (appendSaverTypeToKey)
|
|
{
|
|
var typeName = GetType().Name;
|
|
if (typeName.EndsWith("Saver")) typeName.Remove(typeName.Length - "Saver".Length);
|
|
m_runtimeKey += typeName;
|
|
}
|
|
}
|
|
return m_runtimeKey;
|
|
}
|
|
set
|
|
{
|
|
_internalKeyValue = value;
|
|
m_runtimeKey = value;
|
|
}
|
|
}
|
|
|
|
public override string RecordData()
|
|
{
|
|
if (!DialogueManager.isConversationActive) return string.Empty;
|
|
var data = new Data();
|
|
var state = DialogueManager.currentConversationState;
|
|
var entry = state.subtitle.dialogueEntry;
|
|
data.conversationID = entry.conversationID;
|
|
data.entryID = state.subtitle.dialogueEntry.id;
|
|
data.actorName = (DialogueManager.currentActor != null) ? DialogueManager.currentActor.name : string.Empty;
|
|
data.conversantName = (DialogueManager.currentConversant != null) ? DialogueManager.currentConversant.name : string.Empty;
|
|
var ui = DialogueManager.dialogueUI as StandardDialogueUI;
|
|
if (ui != null)
|
|
{
|
|
ui.conversationUIElements.standardSubtitleControls.RecordActorPanelCache(out data.actorGOs, out data.actorGOPanels, out data.actorIDs, out data.actorIDPanels, out data.panelOpenOnActorName);
|
|
data.accumulatedText = string.Empty;
|
|
for (int i = 0; i < ui.conversationUIElements.subtitlePanels.Length; i++)
|
|
{
|
|
var subtitlePanel = ui.conversationUIElements.subtitlePanels[i];
|
|
if (!subtitlePanel.isOpen && 0 <= i && i < data.panelOpenOnActorName.Count)
|
|
{
|
|
data.panelOpenOnActorName[i] = null;
|
|
}
|
|
if (subtitlePanel.isOpen && subtitlePanel.accumulateText)
|
|
{
|
|
data.accumulatedText = subtitlePanel.accumulatedText;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return SaveSystem.Serialize(data);
|
|
}
|
|
|
|
public override void ApplyData(string s)
|
|
{
|
|
if (!enabled || string.IsNullOrEmpty(s)) return;
|
|
var data = SaveSystem.Deserialize<Data>(s);
|
|
if (data == null) return;
|
|
var dialogueUI = DialogueManager.dialogueUI as StandardDialogueUI;
|
|
if (dialogueUI != null) dialogueUI.CloseImmediately();
|
|
DialogueManager.StopConversation();
|
|
var conversationID = data.conversationID;
|
|
var entryID = data.entryID;
|
|
var conversation = DialogueManager.masterDatabase.GetConversation(conversationID);
|
|
var actorName = DialogueLua.GetVariable("CurrentConversationActor").AsString;
|
|
var conversantName = DialogueLua.GetVariable("CurrentConversationConversant").AsString;
|
|
if (DialogueDebug.logInfo) Debug.Log("Dialogue System: ConversationStateSaver is resuming conversation " + conversation.Title + " with actor=" + actorName + " and conversant=" + conversantName + " at entry " + entryID + ".", this);
|
|
var actor = string.IsNullOrEmpty(actorName) ? null : GameObject.Find(actorName);
|
|
var conversant = string.IsNullOrEmpty(conversantName) ? null : GameObject.Find(conversantName);
|
|
var actorTransform = (actor != null) ? actor.transform : null;
|
|
var conversantTransform = (conversant != null) ? conversant.transform : null;
|
|
var ui = DialogueManager.dialogueUI as StandardDialogueUI;
|
|
if (ui != null)
|
|
{
|
|
ui.conversationUIElements.standardSubtitleControls.QueueSavedActorPanelCache(data.actorGOs, data.actorGOPanels, data.actorIDs, data.actorIDPanels);
|
|
}
|
|
DialogueManager.StartConversation(conversation.Title, actorTransform, conversantTransform, entryID);
|
|
if (ui != null)
|
|
{
|
|
for (int i = 0; i < ui.conversationUIElements.subtitlePanels.Length; i++)
|
|
{
|
|
var subtitlePanel = ui.conversationUIElements.subtitlePanels[i];
|
|
if (0 <= i && i < data.panelOpenOnActorName.Count && !string.IsNullOrEmpty(data.panelOpenOnActorName[i]))
|
|
{
|
|
var panelActorTransform = CharacterInfo.GetRegisteredActorTransform(data.panelOpenOnActorName[i]);
|
|
var dialogueActor = (panelActorTransform != null) ? panelActorTransform.GetComponent<DialogueActor>() : null;
|
|
var panelActor = DialogueManager.masterDatabase.GetActor(data.panelOpenOnActorName[i]);
|
|
Sprite portraitSprite = (panelActor != null) ? panelActor.GetPortraitSprite() : null;
|
|
string portraitName = data.panelOpenOnActorName[i];
|
|
if (dialogueActor != null)
|
|
{
|
|
var dialogueActorSprite = dialogueActor.GetPortraitSprite();
|
|
if (dialogueActorSprite != null) portraitSprite = dialogueActorSprite;
|
|
portraitName = dialogueActor.GetActorName();
|
|
}
|
|
else if (panelActor != null)
|
|
{
|
|
portraitSprite = panelActor.GetPortraitSprite();
|
|
portraitName = CharacterInfo.GetLocalizedDisplayNameInDatabase(portraitName);
|
|
}
|
|
if (!subtitlePanel.isOpen)
|
|
{
|
|
subtitlePanel.OpenOnStartConversation(portraitSprite, portraitName, dialogueActor);
|
|
}
|
|
}
|
|
if (subtitlePanel.accumulateText)
|
|
{
|
|
subtitlePanel.accumulatedText = data.accumulatedText;
|
|
}
|
|
}
|
|
|
|
// Restore continue button state:
|
|
// Note: Doesn't account for SetContinueMode() since we haven't been saving that info
|
|
// in RecordData() and we don't want to break older saves.
|
|
if (ShouldShouldContinueButton(DialogueManager.currentConversationState))
|
|
{
|
|
DialogueActor currentDialogueActor;
|
|
var currentPanel = ui.conversationUIElements.standardSubtitleControls.GetPanel(DialogueManager.currentConversationState.subtitle, out currentDialogueActor);
|
|
currentPanel.ShowContinueButton();
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool ShouldShouldContinueButton(ConversationState state)
|
|
{
|
|
switch (DialogueManager.displaySettings.subtitleSettings.continueButton)
|
|
{
|
|
default:
|
|
case DisplaySettings.SubtitleSettings.ContinueButtonMode.Always:
|
|
case DisplaySettings.SubtitleSettings.ContinueButtonMode.Optional:
|
|
case DisplaySettings.SubtitleSettings.ContinueButtonMode.OptionalBeforeResponseMenu:
|
|
case DisplaySettings.SubtitleSettings.ContinueButtonMode.OptionalBeforePCAutoresponseOrMenu:
|
|
case DisplaySettings.SubtitleSettings.ContinueButtonMode.OptionalForPC:
|
|
case DisplaySettings.SubtitleSettings.ContinueButtonMode.OptionalForPCOrBeforeResponseMenu:
|
|
case DisplaySettings.SubtitleSettings.ContinueButtonMode.OptionalForPCOrBeforePCAutoresponseOrMenu:
|
|
return true;
|
|
case DisplaySettings.SubtitleSettings.ContinueButtonMode.Never:
|
|
return false;
|
|
case DisplaySettings.SubtitleSettings.ContinueButtonMode.NotBeforeResponseMenu:
|
|
return state.hasPCResponses && !state.hasPCAutoResponse;
|
|
case DisplaySettings.SubtitleSettings.ContinueButtonMode.NotBeforePCAutoresponseOrMenu:
|
|
return state.hasPCResponses;
|
|
case DisplaySettings.SubtitleSettings.ContinueButtonMode.NotForPC:
|
|
case DisplaySettings.SubtitleSettings.ContinueButtonMode.NotForPCOrBeforeResponseMenu:
|
|
case DisplaySettings.SubtitleSettings.ContinueButtonMode.NotForPCOrBeforePCAutoresponseOrMenu:
|
|
return !state.hasPCResponses;
|
|
case DisplaySettings.SubtitleSettings.ContinueButtonMode.OnlyForPC:
|
|
return !state.HasNPCResponse;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|