I'll post all of the custom quest classes I have. I don't see what could be interfering with the entry. But maybe you can
Code: Select all
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PixelCrushers.DialogueSystem;
public class CustomQuestLogWindow : StandardUIQuestLogWindow
{
/*
protected override void ShowQuests(QuestState questStateMask)
{
currentQuestStateMask = questStateMask;
// If we're viewing active quests, also include preempted ones, which report as unassigned:
var mask = questStateMask;
if (mask == QuestState.Active) mask = mask | QuestState.Unassigned;
noQuestsMessage = GetNoQuestsMessage(questStateMask);
List<QuestInfo> questList = new List<QuestInfo>();
if (useGroups)
{
var records = QuestLog.GetAllGroupsAndQuests(mask, true);
foreach (var record in records)
{
if (!IsQuestVisible(record.questTitle)) continue;
// If it's really unassigned and not preempted, skip it:
if (QuestLog.CurrentQuestState(record.questTitle) == "unassigned" || QuestLog.CurrentQuestState(record.questTitle) == "ready") continue;
questList.Add(GetQuestInfo(record.groupName, record.questTitle));
}
}
else
{
string[] titles = QuestLog.GetAllQuests(mask, true, null);
foreach (var title in titles)
{
if (!IsQuestVisible(title)) continue;
// If it's really unassigned and not preempted, skip it:
if (QuestLog.CurrentQuestState(title) == "unassigned" || QuestLog.CurrentQuestState(title) == "ready") continue;
questList.Add(GetQuestInfo(string.Empty, title));
}
}
quests = questList.ToArray();
OnQuestListUpdated();
}*/
protected override void ShowQuests(QuestState questStateMask)
{
// Added: If showing active quests, also consider unassigned quests
// so we can include preempted.
if ((questStateMask & QuestState.Active) != 0)
{
questStateMask |= QuestState.Unassigned;
}
currentQuestStateMask = questStateMask;
noQuestsMessage = GetNoQuestsMessage(questStateMask);
List<QuestInfo> questList = new List<QuestInfo>();
if (useGroups)
{
var records = QuestLog.GetAllGroupsAndQuests(questStateMask, true);
foreach (var record in records)
{
if (!IsQuestVisible(record.questTitle)) continue;
if (IsQuestUnassignedOrReady(record.questTitle)) continue; // Added: Skip unassigned and ready quests.
questList.Add(GetQuestInfo(record.groupName, record.questTitle));
}
}
else
{
string[] titles = QuestLog.GetAllQuests(questStateMask, true, null);
foreach (var title in titles)
{
if (!IsQuestVisible(title)) continue;
if (IsQuestUnassignedOrReady(title)) continue; // Added: Skip unassigned and ready quests.
questList.Add(GetQuestInfo(string.Empty, title));
}
}
quests = questList.ToArray();
OnQuestListUpdated();
}
// Added: This tells us if a quest's state is 'unassigned' or 'ready' (i.e., don't show).
private bool IsQuestUnassignedOrReady(string quest)
{
var stateString = QuestLog.CurrentQuestState(quest);
return stateString == "unassigned" || stateString == "ready";
}
protected override QuestInfo GetQuestInfo(string group, string title)
{
FormattedText description = FormattedText.Parse(QuestLog.GetQuestDescription(title), DialogueManager.masterDatabase.emphasisSettings);
FormattedText localizedTitle = FormattedText.Parse(QuestLog.GetQuestTitle(title), DialogueManager.masterDatabase.emphasisSettings);
FormattedText heading = (questHeadingSource == QuestHeadingSource.Description) ? description : localizedTitle;
bool abandonable = QuestLog.IsQuestAbandonable(title) && isShowingActiveQuests;
bool trackable = QuestLog.IsQuestTrackingAvailable(title) && isShowingActiveQuests;
bool track = QuestLog.IsQuestTrackingEnabled(title);
int entryCount = QuestLog.GetQuestEntryCount(title);
FormattedText[] entries = new FormattedText[entryCount];
QuestState[] entryStates = new QuestState[entryCount];
for (int i = 0; i < entryCount; i++)
{
entries[i] = FormattedText.Parse(QuestLog.GetQuestEntry(title, i + 1), DialogueManager.masterDatabase.emphasisSettings);
entryStates[i] = QuestLog.GetQuestEntryState(title, i + 1);
// Added: If quest is preempted, change its entryStates[i] to Active:
if (QuestLog.CurrentQuestEntryState(title, i + 1) == "preempted")
{
entryStates[i] = QuestState.Active;
}
}
return new QuestInfo(group, title, heading, description, entries, entryStates, trackable, track, abandonable);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PixelCrushers.DialogueSystem;
public class CustomQuestTracker : StandardUIQuestTracker
{
// Need to define these again because they're private in the parent class:
private List<StandardUIQuestTrackTemplate> _unusedInstances = new List<StandardUIQuestTrackTemplate>();
private int _siblingIndexCounter = 0;
protected override IEnumerator RefreshAtEndOfFrame()
{
yield return new WaitForEndOfFrame();
// Move instances to the unused list:
_unusedInstances.AddRange(instantiatedItems);
instantiatedItems.Clear();
_siblingIndexCounter = 0;
// Add quests, drawing from unused list when possible:
int numTracked = 0;
QuestState flags = (showActiveQuests ? QuestState.Active : 0) |
(showCompletedQuests ? QuestState.Success | QuestState.Failure : 0) | QuestState.Unassigned;
foreach (string quest in QuestLog.GetAllQuests(flags))
{
if (QuestLog.IsQuestTrackingEnabled(quest) &&
QuestLog.CurrentQuestState(quest) != "unassigned" &&
QuestLog.CurrentQuestState(quest) != "ready")
{
AddQuestTrack(quest);
numTracked++;
}
}
if (container != null)
{
container.gameObject.SetActive(showContainerIfEmpty || numTracked > 0);
}
// Destroy remaining unused instances:
for (int i = 0; i < _unusedInstances.Count; i++)
{
Destroy(_unusedInstances[i].gameObject);
}
_unusedInstances.Clear();
refreshCoroutine = null;
}
protected override void AddQuestTrack(string quest)
{
if (container == null || questTrackTemplate == null) return;
var questDescription = (questDescriptionSource == QuestDescriptionSource.Title)
? QuestLog.GetQuestTitle(quest)
: QuestLog.GetQuestDescription(quest);
var heading = FormattedText.Parse(questDescription, DialogueManager.masterDatabase.emphasisSettings).text;
GameObject go;
if (_unusedInstances.Count > 0)
{
// Try to use an unused instance:
go = _unusedInstances[0].gameObject;
_unusedInstances.RemoveAt(0);
}
else
{
// Otherwise instantiate one:
go = Instantiate(questTrackTemplate.gameObject) as GameObject;
if (go == null)
{
Debug.LogError(string.Format("{0}: {1} couldn't instantiate quest track template", new object[] { DialogueDebug.Prefix, name }));
return;
}
}
go.name = heading;
go.transform.SetParent(container.transform, false);
go.SetActive(true);
var questTrack = go.GetComponent<StandardUIQuestTrackTemplate>();
instantiatedItems.Add(questTrack);
if (questTrack != null)
{
questTrack.Initialize();
// Handle special quest states
var questStateString = QuestLog.CurrentQuestState(quest);
var questState = (questStateString == "preempted") ? QuestState.Active
: (questStateString == "complete") ? QuestState.Active // Could be Success
: QuestLog.GetQuestState(quest);
questTrack.SetDescription(heading, questState);
int entryCount = QuestLog.GetQuestEntryCount(quest);
for (int i = 1; i <= entryCount; i++)
{
var entryState = QuestLog.GetQuestEntryState(quest, i);
var entryText = FormattedText.Parse(GetQuestEntryText(quest, i, entryState), DialogueManager.masterDatabase.emphasisSettings).text;
if (!string.IsNullOrEmpty(entryText))
{
questTrack.AddEntryDescription(entryText, entryState);
}
}
questTrack.transform.SetSiblingIndex(_siblingIndexCounter++);
}
}
protected override string GetQuestEntryText(string quest, int entryNum, QuestState entryState)
{
var questStateString = QuestLog.CurrentQuestEntryState(quest, entryNum);
var isPreempted = questStateString == "preempted";
var isReallyUnassigned = questStateString == "unassigned";
if (isReallyUnassigned || entryState == QuestState.Abandoned)
{
return string.Empty;
}
else if ((entryState == QuestState.Success || entryState == QuestState.Failure) && !showCompletedEntryText)
{
return string.Empty;
}
else if (entryState == QuestState.Success)
{
return string.Empty;
}
else if (entryState == QuestState.Failure)
{
return string.Empty;
}
else if (entryState == QuestState.Active || isPreempted)
{
var text = DialogueLua.GetQuestField(quest, QuestLog.GetQuestEntry(quest, entryNum)).asString;
if (!string.IsNullOrEmpty(text)) return text;
}
return QuestLog.GetQuestEntry(quest, entryNum);
}
}
using PixelCrushers.DialogueSystem;
using UnityEngine;
using Beebyte.Obfuscator;
public class CustomQuestStateCode : MonoBehaviour
{
public const string QuestStatePreempted = "preempted";
public const string QuestStateReady = "ready";
public const string QuestStateComplete = "complete";
private void Start()
{
QuestLog.StringToState = CustomStringToState;
QuestLog.StringToState = MakeReadyState;
QuestLog.StringToState = CustomActiveState;
}
public static QuestState CustomStringToState(string s)
{
if (s == "preempted") return QuestState.Unassigned;
else return QuestLog.DefaultStringToState(s);
}
public static QuestState CustomActiveState(string s)
{
if (s == "complete") return QuestState.Active;
else return QuestLog.DefaultStringToState(s);
}
public static QuestState MakeReadyState(string s)
{
if (s == "ready") return QuestState.Unassigned;
else return QuestLog.DefaultStringToState(s);
}
public void OnQuestTrackingEnabled(string questName)
{
ManagerSupp.instance.SaveLua();
}
public void OnQuestTrackingDisabled(string questName)
{
ManagerSupp.instance.SaveLua();
}
}
using UnityEngine;
using UnityEngine.Events;
using System;
namespace PixelCrushers.DialogueSystem
{
/// <summary>
/// This is a subclass of QuestStateListener. It defines and uses
/// CustomQuestStateIndicatorLevel that checks quest states by their string value.
/// It also uses a custom editor script to hide the base class's
/// QuestStateIndicatorLevel.
/// </summary>
public class CustomQuestStateListener : QuestStateListener
{
[Serializable]
public class CustomQuestStateIndicatorLevel
{
[Tooltip("Quest state to listen for.")]
public string questState;
[Tooltip("Conditions that must also be true.")]
public Condition condition;
[Tooltip("Indicator level to use when this quest state is reached.")]
public int indicatorLevel;
public UnityEvent onEnterState = new UnityEvent();
}
public CustomQuestStateIndicatorLevel[] customQuestStateIndicatorLevels = new CustomQuestStateIndicatorLevel[0];
[Serializable]
public class CustomQuestEntryStateIndicatorLevel
{
[Tooltip("Quest entry number.")]
public int entryNumber;
[Tooltip("Quest entry state to listen for.")]
public string questState;
[Tooltip("Conditions that must also be true.")]
public Condition condition;
[Tooltip("Indicator level to use when this quest state is reached.")]
public int indicatorLevel;
public UnityEvent onEnterState = new UnityEvent();
}
public CustomQuestEntryStateIndicatorLevel[] customQuestEntryStateIndicatorLevels = new CustomQuestEntryStateIndicatorLevel[0];
/// <summary>
/// Update the current quest state indicator based on the specified quest state indicator
/// levels and quest entry state indicator levels.
///
/// In this version, we ignore questStateIndicatorLevels[] and instead use
/// customQuestStateIndicatorLevels[].
/// </summary>
public override void UpdateIndicator()
{
// Check quest state:
var questState = QuestLog.CurrentQuestState(questName); // Get string version of quest state.
for (int i = 0; i < customQuestStateIndicatorLevels.Length; i++)
{
var questStateIndicatorLevel = customQuestStateIndicatorLevels[i]; // Check custom value.
if (questState == questStateIndicatorLevel.questState && questStateIndicatorLevel.condition.IsTrue(null))
{
if (DialogueDebug.logInfo) Debug.Log("Dialogue System: " + name + ": Quest '" + questName + "' changed to state " + questState + ".", this);
if (questStateIndicator != null) questStateIndicator.SetIndicatorLevel(this, questStateIndicatorLevel.indicatorLevel);
questStateIndicatorLevel.onEnterState.Invoke();
}
}
// Check quest entry states:
for (int i = 0; i < questEntryStateIndicatorLevels.Length; i++)
{
var questEntryStateIndicatorLevel = customQuestEntryStateIndicatorLevels[i];
var questEntryState = QuestLog.CurrentQuestEntryState(questName, questEntryStateIndicatorLevel.entryNumber);
if (questEntryState == questEntryStateIndicatorLevel.questState && questEntryStateIndicatorLevel.condition.IsTrue(null))
{
if (DialogueDebug.logInfo) Debug.Log("Dialogue System: " + name + ": Quest '" + questName + "' entry " + questEntryStateIndicatorLevel.entryNumber + " changed to state " + questEntryState + ".", this);
if (questStateIndicator != null) questStateIndicator.SetIndicatorLevel(this, questEntryStateIndicatorLevel.indicatorLevel);
questEntryStateIndicatorLevel.onEnterState.Invoke();
}
}
}
}
}
using UnityEditor;
namespace PixelCrushers.DialogueSystem
{
/// <summary>
/// This custom editor hides the base class's QuestStateIndicatorLevel and
/// QuestEntryStateIndicatorLevel arrays since the subclass uses new arrays.
/// </summary>
[CustomEditor(typeof(CustomQuestStateListener), true)]
public class CustomQuestStateListenerEditor : Editor
{
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(serializedObject.FindProperty("questName"), true);
EditorGUILayout.PropertyField(serializedObject.FindProperty("customQuestStateIndicatorLevels"), true);
EditorGUILayout.PropertyField(serializedObject.FindProperty("customQuestEntryStateIndicatorLevels"), true);
serializedObject.ApplyModifiedProperties();
}
}
}
Again, that's all I know of that references quest entries that have been changed. In my dialogue, I start with checking if unassigned, get the quest and set queststate to active, when I pick up the flowers this is run under lua
if (CurrentQuestState("Something for Rose") == "active") then
SetQuestState("Something for Rose", "preempted")
ShowAlert("Rose might like these flowers")
SetQuestEntryState("Something for Rose", 2, "preempted")
UpdateTracker()
end
Entry 1 is active and Entry 2 is unassigned. I have the field for entry2 set for text. All of this is how your example has it.
Everything works except for showing entry2.
Also, I'm not sure if it has to be this way, if it does then I'll have to live with it, but now the quests do not allow tracking to be disabled at all, and they are greyed out. Can still click them and see details but they have on color. Like it's using the completed or failed heading or something.