Files
2024-11-20 15:21:28 +01:00

1146 lines
45 KiB
C#

// Copyright (c) Pixel Crushers. All rights reserved.
using UnityEngine;
using System;
using System.Collections.Generic;
namespace PixelCrushers.QuestMachine
{
#region Quest Proxy
/// <summary>
/// Runtime-serializable proxy object for Quest. To save or export a procedurally-generated quest,
/// Quest Machine copies its data to a QuestProxy which it then serializes using JsonUtility.
/// Quests that are instantiated from assets, on the other hand, are saved in a more compact form
/// using QuestStateSerializer.
/// </summary>
[Serializable]
public class QuestProxy
{
public static bool includeCanvasRect = false;
public bool isInstance;
public string id;
public string displayName;
public string iconPath;
public string group;
public string[] labels;
public string giver;
public bool isTrackable;
public bool track;
public bool isAbandonable;
public bool rememberIfAbandoned;
public QuestConditionSetProxy autostartConditionSet;
public QuestConditionSetProxy offerConditionSet;
public QuestContentProxy[] offerUnmetContentList;
public QuestContentProxy[] offerContentList;
public int maxTimes;
public int timesAccepted;
public float cooldownSecs;
public float cooldownSecsRemain;
public QuestState state;
public QuestStateInfoProxy[] stateInfoList;
public QuestCounterProxy[] counterList;
public QuestNodeProxy[] nodeList;
public TagDictionary tags;
public QuestIndicatorStateRecordProxy[] indicators;
public string goalEntity;
public QuestProxy() { }
public QuestProxy(Quest quest)
{
CopyFrom(quest);
}
public void CopyFrom(Quest quest)
{
if (quest == null)
{
Debug.LogWarning("Quest Machine: QuestProxy.CopyFrom source quest is null.");
return;
}
isInstance = quest.isInstance;
id = StringField.GetStringValue(quest.id);
displayName = StringField.GetStringValue(quest.title);
iconPath = QuestMachine.GetImagePath(quest.icon);
group = StringField.GetStringValue(quest.group);
labels = StringFieldsToStrings(quest.labels);
giver = StringField.GetStringValue(quest.questGiverID);
isTrackable = quest.isTrackable;
track = quest.showInTrackHUD;
isAbandonable = quest.isAbandonable;
rememberIfAbandoned = quest.rememberIfAbandoned;
autostartConditionSet = new QuestConditionSetProxy(quest.autostartConditionSet);
offerConditionSet = new QuestConditionSetProxy(quest.offerConditionSet);
offerUnmetContentList = QuestContentProxy.NewArray(quest.offerConditionsUnmetContentList);
offerContentList = QuestContentProxy.NewArray(quest.offerContentList);
maxTimes = quest.maxTimes;
timesAccepted = quest.timesAccepted;
cooldownSecs = quest.cooldownSeconds;
cooldownSecsRemain = quest.cooldownSecondsRemaining;
state = quest.GetState();
stateInfoList = QuestStateInfoProxy.NewArray(quest.stateInfoList);
counterList = QuestCounterProxy.NewArray(quest.counterList);
nodeList = QuestNodeProxy.NewArray(quest.nodeList);
tags = new TagDictionary(quest.tagDictionary);
indicators = QuestIndicatorStateRecordProxy.NewArray(quest.indicatorStates);
goalEntity = quest.goalEntityTypeName;
}
public void CopyTo(Quest quest)
{
if (quest == null)
{
Debug.LogWarning("Quest Machine: QuestProxy.CopyTo destination quest is null.");
return;
}
quest.isInstance = isInstance;
quest.id = new StringField(id);
quest.title = new StringField(displayName);
quest.group = new StringField(group);
quest.labels = StringsToStringFields(labels);
quest.icon = QuestMachine.GetImage(iconPath);
quest.questGiverID = new StringField(giver);
quest.isTrackable = isTrackable;
quest.showInTrackHUD = track;
quest.isAbandonable = isAbandonable;
quest.rememberIfAbandoned = rememberIfAbandoned;
quest.autostartConditionSet = autostartConditionSet.CreateConditionSet();
quest.offerConditionSet = offerConditionSet.CreateConditionSet();
quest.offerConditionsUnmetContentList = QuestContentProxy.CreateList(offerUnmetContentList);
quest.offerContentList = QuestContentProxy.CreateList(offerContentList);
quest.maxTimes = maxTimes;
quest.timesAccepted = timesAccepted;
quest.UpdateCooldown();
quest.cooldownSeconds = cooldownSecs;
quest.cooldownSecondsRemaining = cooldownSecsRemain;
quest.stateInfoList = QuestStateInfoProxy.CreateList(stateInfoList);
quest.counterList = QuestCounterProxy.CreateList(counterList);
quest.nodeList = QuestNodeProxy.CreateList(nodeList);
quest.tagDictionary = new TagDictionary(tags);
quest.indicatorStates = QuestIndicatorStateRecordProxy.ArrayToDictionary(indicators);
quest.goalEntityTypeName = goalEntity;
quest.SetRuntimeReferences();
quest.SetState(state, false);
QuestNodeProxy.CopyStatesTo(nodeList, quest);
}
private string[] StringFieldsToStrings(List<StringField> stringFields)
{
if (stringFields == null) return new string[0];
var strings = new string[stringFields.Count];
for (int i = 0; i < stringFields.Count; i++)
{
strings[i] = StringField.GetStringValue(stringFields[i]);
}
return strings;
}
private List<StringField> StringsToStringFields(string[] strings)
{
var stringFields = new List<StringField>();
if (strings == null) return stringFields;
for (int i = 0; i < strings.Length; i++)
{
stringFields.Add(new StringField(strings[i]));
}
return stringFields;
}
}
#endregion
#region QuestConditionSet Proxy
[Serializable]
public class QuestConditionSetProxy
{
public QuestConditionProxy[] conds;
public ConditionCountMode mode;
public int min;
public int numTrue;
public QuestConditionSetProxy() { }
public QuestConditionSetProxy(QuestConditionSet conditionSet)
{
CopyFrom(conditionSet);
}
public void CopyFrom(QuestConditionSet conditionSet)
{
if (conditionSet == null)
{
Debug.LogWarning("Quest Machine: QuestConditionSetProxy.CopyFrom source is null.");
return;
}
conds = QuestConditionProxy.NewArray(conditionSet.conditionList);
mode = conditionSet.conditionCountMode;
min = conditionSet.minConditionCount;
numTrue = conditionSet.numTrueConditions;
}
public void CopyTo(QuestConditionSet conditionSet)
{
if (conditionSet == null)
{
Debug.LogWarning("Quest Machine: QuestConditionSetProxy.CopyTo destination is null.");
return;
}
conditionSet.conditionList = QuestConditionProxy.CreateList(conds);
conditionSet.conditionCountMode = mode;
conditionSet.minConditionCount = min;
conditionSet.numTrueConditions = numTrue;
}
public QuestConditionSet CreateConditionSet()
{
var result = new QuestConditionSet();
CopyTo(result);
return result;
}
}
[Serializable]
public class QuestConditionProxy
{
public string t;
public string s;
// To reduce proxy data size, we specially handle the most common cases (counter & message conditions).
public const string CounterTypeString = "Counter";
public const string MessageTypeString = "Message";
public const string TimerTypeString = "Timer";
public QuestConditionProxy() { }
public QuestConditionProxy(QuestCondition questCondition)
{
CopyFrom(questCondition);
}
public void CopyFrom(QuestCondition questCondition)
{
if (questCondition == null)
{
Debug.LogWarning("Quest Machine: QuestConditionProxy.CopyFrom source is null.");
return;
}
t = questCondition.GetType().FullName;
questCondition.OnBeforeProxySerialization();
if (questCondition is CounterQuestCondition)
{
t = CounterTypeString;
s = GetCounterQuestConditionProxyData(questCondition as CounterQuestCondition);
}
else if (questCondition is MessageQuestCondition)
{
t = MessageTypeString;
s = GetMessageQuestConditionProxyData(questCondition as MessageQuestCondition);
}
else if (questCondition is TimerQuestCondition)
{
t = TimerTypeString;
s = GetTimerQuestConditionProxyData(questCondition as TimerQuestCondition);
}
else
{
s = JsonUtility.ToJson(questCondition);
}
}
public static QuestConditionProxy[] NewArray(List<QuestCondition> conditions)
{
if (conditions == null)
{
Debug.LogWarning("Quest Machine: QuestConditionProxy.NewArray source is null.");
return new QuestConditionProxy[0];
}
var array = new QuestConditionProxy[conditions.Count];
for (int i = 0; i < array.Length; i++)
{
array[i] = new QuestConditionProxy(conditions[i]);
}
return array;
}
public static List<QuestCondition> CreateList(QuestConditionProxy[] conditionsProxy)
{
var list = new List<QuestCondition>();
if (conditionsProxy == null)
{
Debug.LogWarning("Quest Machine: QuestConditionProxy.CreateList source is null.");
return list;
}
for (int i = 0; i < conditionsProxy.Length; i++)
{
var conditionProxy = conditionsProxy[i];
if (conditionProxy == null || string.IsNullOrEmpty(conditionProxy.t) || string.IsNullOrEmpty(conditionProxy.s)) continue;
QuestCondition condition = null;
if (string.Equals(conditionProxy.t, CounterTypeString))
{
condition = ScriptableObjectUtility.CreateScriptableObject(RuntimeTypeUtility.GetWrapperType(typeof(CounterQuestCondition))) as CounterQuestCondition;
ApplyCounterQuestConditionProxyData(condition as CounterQuestCondition, conditionProxy.s);
}
else if (string.Equals(conditionProxy.t, MessageTypeString))
{
condition = ScriptableObjectUtility.CreateScriptableObject(RuntimeTypeUtility.GetWrapperType(typeof(MessageQuestCondition))) as MessageQuestCondition;
ApplyMessageQuestConditionProxyData(condition as MessageQuestCondition, conditionProxy.s);
}
else if (string.Equals(conditionProxy.t, TimerTypeString))
{
condition = ScriptableObjectUtility.CreateScriptableObject(RuntimeTypeUtility.GetWrapperType(typeof(TimerQuestCondition))) as TimerQuestCondition;
ApplyTimerQuestConditionProxyData(condition as TimerQuestCondition, conditionProxy.s);
}
else
{
var baseType = RuntimeTypeUtility.GetTypeFromName(conditionProxy.t);
var type = RuntimeTypeUtility.GetWrapperType(baseType) ?? baseType;
condition = ScriptableObject.CreateInstance(type) as QuestCondition;
if (condition != null) JsonUtility.FromJsonOverwrite(conditionProxy.s, condition);
}
if (condition != null)
{
condition.OnAfterProxyDeserialization();
list.Add(condition);
}
}
return list;
}
private static string GetCounterQuestConditionProxyData(CounterQuestCondition counterQuestCondition)
{
return (int)counterQuestCondition.counterValueMode + ";" + (int)counterQuestCondition.requiredCounterValue.valueType + ";" +
counterQuestCondition.requiredCounterValue.literalValue + ";" + counterQuestCondition.requiredCounterValue.counterIndex + ";" +
counterQuestCondition.counterIndex + ";" + (counterQuestCondition.alreadyTrue ? "1" : "0");
}
private static void ApplyCounterQuestConditionProxyData(CounterQuestCondition counterQuestCondition, string s)
{
if (counterQuestCondition == null || s == null) return;
var fields = s.Split(';');
if (fields.Length < 5) return;
counterQuestCondition.counterValueMode = (CounterValueConditionMode)SafeConvert.ToInt(fields[0]);
var valueType = (QuestNumber.ValueType)SafeConvert.ToInt(fields[1]);
switch (valueType)
{
case QuestNumber.ValueType.Literal:
counterQuestCondition.requiredCounterValue = new QuestNumber(SafeConvert.ToInt(fields[2]));
break;
case QuestNumber.ValueType.CounterValue:
case QuestNumber.ValueType.CounterMinValue:
case QuestNumber.ValueType.CounterMaxValue:
counterQuestCondition.requiredCounterValue = new QuestNumber();
counterQuestCondition.requiredCounterValue.valueType = valueType;
counterQuestCondition.requiredCounterValue.counterIndex = SafeConvert.ToInt(fields[3]);
break;
default:
counterQuestCondition.requiredCounterValue = new QuestNumber();
break;
}
counterQuestCondition.counterIndex = SafeConvert.ToInt(fields[4]);
counterQuestCondition.alreadyTrue = (fields.Length > 5) ? (fields[5] == "1") : false;
}
private static string GetMessageQuestConditionProxyData(MessageQuestCondition messageQuestCondition)
{
var valueType = (messageQuestCondition.value != null) ? messageQuestCondition.value.valueType : MessageValueType.None;
var s = ((int)messageQuestCondition.senderSpecifier).ToString() + ";" + messageQuestCondition.senderID + ";" +
((int)messageQuestCondition.targetSpecifier).ToString() + ";" + messageQuestCondition.targetID + ";" +
messageQuestCondition.message + ";" + messageQuestCondition.parameter + ";" + (int)valueType +
";" + (messageQuestCondition.alreadyTrue ? "1" : "0");
switch (valueType)
{
case MessageValueType.Int:
s += ";" + messageQuestCondition.value.intValue;
break;
case MessageValueType.String:
s += ";" + messageQuestCondition.value.stringValue;
break;
}
return s;
}
private static void ApplyMessageQuestConditionProxyData(MessageQuestCondition messageQuestCondition, string s)
{
if (messageQuestCondition == null || s == null) return;
var fields = s.Split(';');
if (fields.Length < 7) return;
messageQuestCondition.senderSpecifier = (QuestMessageParticipant)SafeConvert.ToInt(fields[0]);
messageQuestCondition.senderID = new StringField(fields[1]);
messageQuestCondition.targetSpecifier = (QuestMessageParticipant)SafeConvert.ToInt(fields[2]);
messageQuestCondition.targetID = new StringField(fields[3]);
messageQuestCondition.message = new StringField(fields[4]);
messageQuestCondition.parameter = new StringField(fields[5]);
var valueType = (MessageValueType)SafeConvert.ToInt(fields[6]);
switch (valueType)
{
case MessageValueType.Int:
messageQuestCondition.value = new MessageValue(SafeConvert.ToInt(fields[7]));
break;
case MessageValueType.String:
messageQuestCondition.value = new MessageValue(fields[7]);
break;
default:
messageQuestCondition.value = new MessageValue();
break;
}
messageQuestCondition.alreadyTrue = (fields.Length > 7) ? (fields[7] == "1") : false;
}
private static string GetTimerQuestConditionProxyData(TimerQuestCondition timerQuestCondition)
{
return timerQuestCondition.counterIndex.ToString() + ";" + (timerQuestCondition.alreadyTrue ? "1" : "0");
}
private static void ApplyTimerQuestConditionProxyData(TimerQuestCondition timerQuestCondition, string s)
{
if (timerQuestCondition == null || s == null) return;
var fields = s.Split(';');
if (fields.Length < 1) return;
timerQuestCondition.counterIndex = SafeConvert.ToInt(fields[0]);
timerQuestCondition.alreadyTrue = (fields.Length > 1) ? (fields[1] == "1") : false;
}
}
#endregion
#region QuestContent Proxy
[Serializable]
public class QuestContentProxy
{
public string t;
public string s;
// To reduce proxy data size, we specially handle the most common cases (counter & message conditions).
public const string HeadingTypeString = "Head";
public const string BodyTypeString = "Body";
public const string IconTypeString = "Icon";
public const string ButtonTypeString = "Button";
public QuestContentProxy() { }
public QuestContentProxy(QuestContent content)
{
CopyFrom(content);
}
public void CopyFrom(QuestContent content)
{
if (content == null)
{
Debug.LogWarning("Quest Machine: QuestContentProxy.CopyFrom source is null.");
return;
}
t = content.GetType().FullName;
content.OnBeforeProxySerialization();
if (content is HeadingTextQuestContent)
{
t = HeadingTypeString;
s = GetHeadingTextQuestContentProxyData(content as HeadingTextQuestContent);
}
else if (content is BodyTextQuestContent)
{
t = BodyTypeString;
s = GetBodyTextQuestContentProxyData(content as BodyTextQuestContent);
}
else if(content is IconQuestContent)
{
t = IconTypeString;
s = GetIconQuestContentProxyData(content as IconQuestContent);
}
else if (content is ButtonQuestContent)
{
t = ButtonTypeString;
s = GetButtonQuestContentProxyData(content as ButtonQuestContent);
}
else
{
s = JsonUtility.ToJson(content);
}
}
public static QuestContentProxy[] NewArray(List<QuestContent> contentList)
{
if (contentList == null)
{
Debug.LogWarning("Quest Machine: QuestContentProxy.NewArray source is null.");
return new QuestContentProxy[0];
}
var array = new QuestContentProxy[contentList.Count];
for (int i = 0; i < array.Length; i++)
{
array[i] = new QuestContentProxy(contentList[i]);
}
return array;
}
public static List<QuestContent> CreateList(QuestContentProxy[] contentListProxy)
{
var list = new List<QuestContent>();
if (contentListProxy == null)
{
Debug.LogWarning("Quest Machine: QuestContentProxy.CreateList source is null.");
return list;
}
for (int i = 0; i < contentListProxy.Length; i++)
{
var contentProxy = contentListProxy[i];
if (contentProxy == null || string.IsNullOrEmpty(contentProxy.t) || string.IsNullOrEmpty(contentProxy.s)) continue;
QuestContent content = null;
if (string.Equals(contentProxy.t, HeadingTypeString))
{
content = ScriptableObjectUtility.CreateScriptableObject(RuntimeTypeUtility.GetWrapperType(typeof(HeadingTextQuestContent))) as HeadingTextQuestContent;
ApplyHeadingTextQuestContentProxyData(content as HeadingTextQuestContent, contentProxy.s);
}
else if (string.Equals(contentProxy.t, BodyTypeString))
{
content = ScriptableObjectUtility.CreateScriptableObject(RuntimeTypeUtility.GetWrapperType(typeof(BodyTextQuestContent))) as BodyTextQuestContent;
ApplyBodyTextQuestContentProxyData(content as BodyTextQuestContent, contentProxy.s);
}
else if (string.Equals(contentProxy.t, IconTypeString))
{
content = ScriptableObjectUtility.CreateScriptableObject(RuntimeTypeUtility.GetWrapperType(typeof(IconQuestContent))) as IconQuestContent;
ApplyIconQuestContentProxyData(content as IconQuestContent, contentProxy.s);
}
else if (string.Equals(contentProxy.t, ButtonTypeString))
{
content = ScriptableObjectUtility.CreateScriptableObject(RuntimeTypeUtility.GetWrapperType(typeof(ButtonQuestContent))) as ButtonQuestContent;
ApplyButtonQuestContentProxyData(content as ButtonQuestContent, contentProxy.s);
}
else
{
var baseType = RuntimeTypeUtility.GetTypeFromName(contentProxy.t);
var type = RuntimeTypeUtility.GetWrapperType(baseType) ?? baseType;
content = ScriptableObject.CreateInstance(type) as QuestContent;
if (content != null) JsonUtility.FromJsonOverwrite(contentProxy.s, content);
}
if (content != null)
{
content.OnAfterProxyDeserialization();
list.Add(content);
}
}
return list;
}
public static QuestContentSet CreateContentSet(QuestContentProxy[] uiContentListProxy)
{
var container = new QuestContentSet();
container.contentList = CreateList(uiContentListProxy);
return container;
}
private static string GetHeadingTextQuestContentProxyData(HeadingTextQuestContent headingTextQuestContent)
{
return headingTextQuestContent.headingLevel + ";" +
StringField.GetStringValue(headingTextQuestContent.originalText) + ";" +
(headingTextQuestContent.useQuestTitle ? "1" : "0");
}
private static void ApplyHeadingTextQuestContentProxyData(HeadingTextQuestContent headingTextQuestContent, string s)
{
if (headingTextQuestContent == null || s == null) return;
var fields = s.Split(';');
if (fields.Length < 2) return;
headingTextQuestContent.headingLevel = SafeConvert.ToInt(fields[0]);
headingTextQuestContent.originalText = new StringField(fields[1]);
headingTextQuestContent.useQuestTitle = (fields.Length == 3) ? (fields[2] == "1") : false;
}
private static string GetBodyTextQuestContentProxyData(BodyTextQuestContent bodyTextQuestContent)
{
return StringField.GetStringValue(bodyTextQuestContent.originalText);
}
private static void ApplyBodyTextQuestContentProxyData(BodyTextQuestContent bodyTextQuestContent, string s)
{
if (bodyTextQuestContent == null || s == null) return;
bodyTextQuestContent.originalText = new StringField(s);
}
private static string GetIconQuestContentProxyData(IconQuestContent iconQuestContent)
{
// Note: Procedural quest generation doesn't provide a way to specify color tint, so we don't serialize color.
return iconQuestContent.count + ";" + ((iconQuestContent.image != null) ? iconQuestContent.image.name : string.Empty) + ";" +
StringField.GetStringValue(iconQuestContent.originalText);
}
private static void ApplyIconQuestContentProxyData(IconQuestContent iconQuestContent, string s)
{
if (iconQuestContent == null || s == null) return;
var fields = s.Split(';');
if (fields.Length < 3) return;
iconQuestContent.count = SafeConvert.ToInt(fields[0]);
iconQuestContent.image = string.IsNullOrEmpty(fields[1]) ? null : QuestMachine.GetImage(fields[1]);
iconQuestContent.color = Color.white;
iconQuestContent.originalText = new StringField(fields[2]);
}
private static string GetButtonQuestContentProxyData(ButtonQuestContent buttonQuestContent)
{
// Note: Procedural quest generation doesn't provide a way to specify color tint, so we don't serialize color.
return buttonQuestContent.count + ";" + ((buttonQuestContent.image != null) ? buttonQuestContent.image.name : string.Empty) + ";" +
StringField.GetStringValue(buttonQuestContent.originalText) + ";" + JsonUtility.ToJson(buttonQuestContent.m_actionsProxy);
}
private static void ApplyButtonQuestContentProxyData(ButtonQuestContent buttonQuestContent, string s)
{
if (buttonQuestContent == null || s == null) return;
var fields = s.Split(';');
if (fields.Length < 4) return;
buttonQuestContent.count = SafeConvert.ToInt(fields[0]);
buttonQuestContent.image = string.IsNullOrEmpty(fields[1]) ? null : QuestMachine.GetImage(fields[1]);
buttonQuestContent.color = Color.white;
buttonQuestContent.originalText = new StringField(fields[2]);
buttonQuestContent.m_actionsProxy = JsonUtility.FromJson<QuestActionProxyContainer>(fields[3]);
}
}
#endregion
#region QuestCounter Proxy
[Serializable]
public class QuestCounterProxy
{
public string name;
public int val;
public int min;
public int max;
public bool rand;
public QuestCounterUpdateMode mode;
public QuestCounterMessageEventProxy[] messages;
public QuestCounterProxy() { }
public QuestCounterProxy(QuestCounter counter)
{
CopyFrom(counter);
}
public void CopyFrom(QuestCounter counter)
{
if (counter == null)
{
Debug.LogWarning("Quest Machine: QuestCounterProxy.CopyFrom source is null.");
return;
}
name = StringField.GetStringValue(counter.name);
val = counter.currentValue;
min = counter.minValue;
max = counter.maxValue;
rand = counter.randomizeInitialValue;
mode = counter.updateMode;
messages = QuestCounterMessageEventProxy.NewArray(counter.messageEventList);
}
public void CopyTo(QuestCounter counter)
{
if (counter == null)
{
Debug.LogWarning("Quest Machine: QuestCounterProxy.CopyTo destination is null.");
return;
}
counter.name = new StringField(name);
counter.SetValue(val, QuestCounterSetValueMode.DontInformListeners);
counter.minValue = min;
counter.maxValue = max;
counter.randomizeInitialValue = rand;
counter.updateMode = mode;
counter.messageEventList = QuestCounterMessageEventProxy.CreateList(messages);
}
public static QuestCounterProxy[] NewArray(List<QuestCounter> counters)
{
if (counters == null)
{
Debug.LogWarning("Quest Machine: QuestCounterProxy.NewArray source is null.");
return new QuestCounterProxy[0];
}
var array = new QuestCounterProxy[counters.Count];
for (int i = 0; i < array.Length; i++)
{
array[i] = new QuestCounterProxy(counters[i]);
}
return array;
}
public static List<QuestCounter> CreateList(QuestCounterProxy[] countersProxy)
{
var list = new List<QuestCounter>();
if (countersProxy == null)
{
Debug.LogWarning("Quest Machine: QuestCounterProxy.CreateList source is null.");
return list;
}
for (int i = 0; i < countersProxy.Length; i++)
{
var counter = new QuestCounter();
countersProxy[i].CopyTo(counter);
list.Add(counter);
}
return list;
}
}
[Serializable]
public class QuestCounterMessageEventProxy
{
public QuestMessageParticipant sndSpec;
public string snd;
public QuestMessageParticipant tgtSpec;
public string tgt;
public string msg;
public string parm;
public QuestCounterMessageEvent.Operation op;
public int val;
public QuestCounterMessageEventProxy() { }
public QuestCounterMessageEventProxy(QuestCounterMessageEvent messageEvent)
{
CopyFrom(messageEvent);
}
public void CopyFrom(QuestCounterMessageEvent messageEvent)
{
if (messageEvent == null)
{
Debug.LogWarning("Quest Machine: QuestCounterMessageEventProxy.CopyFrom source is null.");
return;
}
sndSpec = messageEvent.senderSpecifier;
snd = StringField.GetStringValue(messageEvent.senderID);
tgtSpec = messageEvent.targetSpecifier;
tgt = StringField.GetStringValue(messageEvent.targetID);
msg = StringField.GetStringValue(messageEvent.message);
parm = StringField.GetStringValue(messageEvent.parameter);
op = messageEvent.operation;
val = messageEvent.literalValue;
}
public void CopyTo(QuestCounterMessageEvent messageEvent)
{
if (messageEvent == null)
{
Debug.LogWarning("Quest Machine: QuestCounterMessageEventProxy.CopyTo destination is null.");
return;
}
messageEvent.senderSpecifier = sndSpec;
messageEvent.senderID = new StringField(snd);
messageEvent.targetSpecifier = tgtSpec;
messageEvent.targetID = new StringField(tgt);
messageEvent.message = new StringField(msg);
messageEvent.parameter = new StringField(parm);
messageEvent.operation = op;
messageEvent.literalValue = val;
}
public static QuestCounterMessageEventProxy[] NewArray(List<QuestCounterMessageEvent> messageEvents)
{
if (messageEvents == null)
{
Debug.LogWarning("Quest Machine: QuestCounterMessageEventProxy.NewArray source is null.");
return new QuestCounterMessageEventProxy[0];
}
var array = new QuestCounterMessageEventProxy[messageEvents.Count];
for (int i = 0; i < array.Length; i++)
{
array[i] = new QuestCounterMessageEventProxy(messageEvents[i]);
}
return array;
}
public static List<QuestCounterMessageEvent> CreateList(QuestCounterMessageEventProxy[] messageEventsProxy)
{
var list = new List<QuestCounterMessageEvent>();
if (messageEventsProxy == null)
{
Debug.LogWarning("Quest Machine: QuestCounterMessageEventProxy.CreateList source is null.");
return list;
}
for (int i = 0; i < messageEventsProxy.Length; i++)
{
var messageEvent = new QuestCounterMessageEvent();
messageEventsProxy[i].CopyTo(messageEvent);
list.Add(messageEvent);
}
return list;
}
}
#endregion
#region QuestStateInfo Proxy
[Serializable]
public class QuestStateInfoProxy
{
public QuestActionProxy[] acn;
public QuestContentProxy[] dlg;
public QuestContentProxy[] jrl;
public QuestContentProxy[] hud;
public QuestStateInfoProxy() { }
public QuestStateInfoProxy(QuestStateInfo stateInfo)
{
CopyFrom(stateInfo);
}
public void CopyFrom(QuestStateInfo stateInfo)
{
if (stateInfo == null)
{
Debug.LogWarning("Quest Machine: QuestStateInfoProxy.CopyFrom source is null.");
return;
}
acn = QuestActionProxy.NewArray(stateInfo.actionList);
dlg = GetNewArrayForCategory(stateInfo, QuestContentCategory.Dialogue);
jrl = GetNewArrayForCategory(stateInfo, QuestContentCategory.Journal);
hud = GetNewArrayForCategory(stateInfo, QuestContentCategory.HUD);
}
private QuestContentProxy[] GetNewArrayForCategory(QuestStateInfo stateInfo, QuestContentCategory category)
{
var index = (int)category;
return (0 <= index && index < stateInfo.categorizedContentList.Count)
? QuestContentProxy.NewArray(stateInfo.categorizedContentList[index].contentList)
: new QuestContentProxy[0];
}
public void CopyTo(QuestStateInfo stateInfo)
{
if (stateInfo == null)
{
Debug.LogWarning("Quest Machine: QuestStateInfoProxy.CopyTo destination is null.");
return;
}
stateInfo.actionList = QuestActionProxy.CreateList(acn);
stateInfo.categorizedContentList = new List<QuestContentSet>();
for (int i = 0; i < QuestStateInfo.NumContentCategories ; i++)
{
var contentSet = QuestContentProxy.CreateContentSet(GetContentListProxy((QuestContentCategory)i));
stateInfo.categorizedContentList.Add(contentSet);
}
}
private QuestContentProxy[] GetContentListProxy(QuestContentCategory category)
{
switch (category)
{
case QuestContentCategory.Dialogue:
return dlg;
case QuestContentCategory.Journal:
return jrl;
case QuestContentCategory.HUD:
return hud;
default:
if (Debug.isDebugBuild) Debug.LogWarning("Quest Machine: Unsupported content category '" + category + "' when deserializing quest. Please contact the developer.");
return null;
}
}
public static QuestStateInfoProxy[] NewArray(List<QuestStateInfo> stateInfoList)
{
if (stateInfoList == null)
{
Debug.LogWarning("Quest Machine: QuestStateInfoProxy.NewArray source is null.");
return new QuestStateInfoProxy[0];
}
var array = new QuestStateInfoProxy[stateInfoList.Count];
for (int i = 0; i < array.Length; i++)
{
array[i] = new QuestStateInfoProxy(stateInfoList[i]);
}
return array;
}
public static List<QuestStateInfo> CreateList(QuestStateInfoProxy[] stateInfoListProxy)
{
var list = new List<QuestStateInfo>();
if (stateInfoListProxy == null)
{
Debug.LogWarning("Quest Machine: QuestStateInfoProxy.CreateList source is null.");
return list;
}
for (int i = 0; i < stateInfoListProxy.Length; i++)
{
var counter = new QuestStateInfo();
stateInfoListProxy[i].CopyTo(counter);
list.Add(counter);
}
return list;
}
}
#endregion
#region QuestAction Proxy
[Serializable]
public class QuestActionProxy
{
public string t;
public string s;
public QuestActionProxy() { }
public QuestActionProxy(QuestAction action)
{
CopyFrom(action);
}
public void CopyFrom(QuestAction action)
{
if (action == null)
{
Debug.LogWarning("Quest Machine: QuestActionProxy.CopyFrom source is null.");
return;
}
t = action.GetType().FullName;
action.OnBeforeProxySerialization();
s = JsonUtility.ToJson(action);
}
public static QuestActionProxy[] NewArray(List<QuestAction> actionList)
{
if (actionList == null)
{
Debug.LogWarning("Quest Machine: QuestActionProxy.NewArray source is null.");
return new QuestActionProxy[0];
}
var array = new QuestActionProxy[actionList.Count];
for (int i = 0; i < array.Length; i++)
{
array[i] = new QuestActionProxy(actionList[i]);
}
return array;
}
public static List<QuestAction> CreateList(QuestActionProxy[] actionListProxy)
{
var list = new List<QuestAction>();
if (actionListProxy == null)
{
Debug.LogWarning("Quest Machine: QuestActionProxy.CreateList source is null.");
return list;
}
for (int i = 0; i < actionListProxy.Length; i++)
{
var actionProxy = actionListProxy[i];
if (actionProxy == null || string.IsNullOrEmpty(actionProxy.t) || string.IsNullOrEmpty(actionProxy.s)) continue;
var baseType = RuntimeTypeUtility.GetTypeFromName(actionProxy.t);
var type = RuntimeTypeUtility.GetWrapperType(baseType) ?? baseType;
var action = ScriptableObject.CreateInstance(type) as QuestAction;
if (action != null)
{
JsonUtility.FromJsonOverwrite(actionProxy.s, action);
action.OnAfterProxyDeserialization();
list.Add(action);
}
}
return list;
}
}
[Serializable]
public class QuestActionProxyContainer
{
public QuestActionProxy[] actions;
public QuestActionProxyContainer() { }
public QuestActionProxyContainer(List<QuestAction> actionList)
{
var count = (actionList == null) ? 0 : actionList.Count;
var actions = new QuestActionProxy[count];
for (int i = 0; i < count; i++)
{
actions[i] = new QuestActionProxy(actionList[i]);
}
}
public static List<QuestAction> CreateList(QuestActionProxyContainer proxy)
{
if (proxy == null || proxy.actions == null) return new List<QuestAction>();
return QuestActionProxy.CreateList(proxy.actions);
}
}
#endregion
#region QuestNode Proxy
[Serializable]
public class QuestNodeProxy
{
public string id;
public string intName;
public QuestNodeType type;
public bool optional;
public QuestNodeState state;
public string speaker;
public QuestStateInfoProxy[] states;
public QuestConditionSetProxy conds;
public TagDictionary tags;
public int[] childIdx;
public string r;
public QuestNodeProxy() { }
public QuestNodeProxy(QuestNode node)
{
CopyFrom(node);
}
public void CopyFrom(QuestNode node)
{
if (node == null)
{
Debug.LogWarning("Quest Machine: QuestNodeProxy.CopyFrom source is null.");
return;
}
id = StringField.GetStringValue(node.id);
intName = StringField.GetStringValue(node.internalName);
type = node.nodeType;
optional = node.isOptional;
state = node.GetState();
speaker = StringField.GetStringValue(node.speaker);
states = QuestStateInfoProxy.NewArray(node.stateInfoList);
conds = new QuestConditionSetProxy(node.conditionSet);
tags = new TagDictionary(node.tagDictionary);
childIdx = node.childIndexList.ToArray();
r = QuestProxy.includeCanvasRect ? ((int)node.canvasRect.x + ";" + (int)node.canvasRect.y + ";" + (int)node.canvasRect.width + ";" + (int)node.canvasRect.height) : string.Empty;
}
public void CopyTo(QuestNode node)
{
if (node == null)
{
Debug.LogWarning("Quest Machine: QuestNodeProxy.CopyTo destination is null.");
return;
}
node.id = new StringField(id);
node.internalName = new StringField(intName);
node.nodeType = type;
node.isOptional = optional;
node.speaker = new StringField(speaker);
node.stateInfoList = QuestStateInfoProxy.CreateList(states);
node.conditionSet = conds.CreateConditionSet();
node.tagDictionary = new TagDictionary(tags);
node.childIndexList = new List<int>(childIdx);
if (QuestProxy.includeCanvasRect && !string.IsNullOrEmpty(r))
{
var fields = r.Split(';');
if (fields.Length == 4)
{
node.canvasRect = new Rect(SafeConvert.ToFloat(fields[0]), SafeConvert.ToFloat(fields[1]), SafeConvert.ToFloat(fields[2]), SafeConvert.ToFloat(fields[3]));
}
}
}
public static QuestNodeProxy[] NewArray(List<QuestNode> nodes)
{
if (nodes == null)
{
Debug.LogWarning("Quest Machine: QuestNodeProxy.NewArray source is null.");
return new QuestNodeProxy[0];
}
var array = new QuestNodeProxy[nodes.Count];
for (int i = 0; i < array.Length; i++)
{
array[i] = new QuestNodeProxy(nodes[i]);
}
return array;
}
public static List<QuestNode> CreateList(QuestNodeProxy[] nodesProxy)
{
var list = new List<QuestNode>();
if (nodesProxy == null)
{
Debug.LogWarning("Quest Machine: QuestNodeProxy.CreateList source is null.");
return list;
}
for (int i = 0; i < nodesProxy.Length; i++)
{
var node = new QuestNode();
nodesProxy[i].CopyTo(node);
list.Add(node);
}
return list;
}
public static void CopyStatesTo(QuestNodeProxy[] nodesProxy, Quest quest)
{
if (nodesProxy == null || quest == null || quest.nodeList == null) return;
for (int i = 0; i < Mathf.Min(nodesProxy.Length, quest.nodeList.Count); i++)
{
quest.nodeList[i].SetState(nodesProxy[i].state, false);
}
}
}
#endregion
#region Quest Indicator State Records Proxy
[Serializable]
public class QuestIndicatorStateRecordProxy
{
public string id;
public QuestIndicatorState indicator;
public QuestIndicatorStateRecordProxy(string id, QuestIndicatorState indicator)
{
this.id = id;
this.indicator = indicator;
}
public static QuestIndicatorStateRecordProxy[] NewArray(Dictionary<string, QuestIndicatorState> indicatorRecords)
{
if (indicatorRecords == null) return null;
var array = new QuestIndicatorStateRecordProxy[indicatorRecords.Count];
int i = 0;
foreach (var kvp in indicatorRecords)
{
array[i] = new QuestIndicatorStateRecordProxy(kvp.Key, kvp.Value);
i++;
}
return array;
}
public static Dictionary<string, QuestIndicatorState> ArrayToDictionary(QuestIndicatorStateRecordProxy[] array)
{
var dict = new Dictionary<string, QuestIndicatorState>();
if (array == null) return dict;
for (int i = 0; i < array.Length; i++)
{
if (array[i] == null) continue;
dict.Add(array[i].id, array[i].indicator);
}
return dict;
}
}
#endregion
}