void IMessageHandler.OnMessage(MessageArgs messageArgs) { if (!isChecking || messageArgs.values == null || messageArgs.values.Length < 2 || requiredQuestID == null) { return; } var questID = messageArgs.parameter; if (!StringField.Equals(requiredQuestID, questID)) { return; } var questNodeID = QuestMachineMessages.ArgToString(messageArgs.values[0]); if (!string.IsNullOrEmpty(questNodeID)) { return; } var stateValue = messageArgs.values[1]; var state = (stateValue != null && stateValue.GetType() == typeof(QuestState)) ? (QuestState)stateValue : QuestState.WaitingToStart; if (state == requiredState) { SetTrue(); } }
//------------------------------------------------------------------ // Load: private static void ReadQuestDataFromStream(BinaryReader binaryReader, Quest quest) { if (quest == null) { return; } var state = (QuestState)binaryReader.ReadByte(); ReadTagDictionaryFromStream(binaryReader, quest.tagDictionary, quest.name); quest.questGiverID.value = binaryReader.ReadString(); quest.timesAccepted = binaryReader.ReadInt32(); quest.cooldownSecondsRemaining = (float)binaryReader.ReadDouble(); quest.showInTrackHUD = binaryReader.ReadBoolean(); ReadConditionSetDataFromStream(binaryReader, quest.autostartConditionSet); ReadConditionSetDataFromStream(binaryReader, quest.offerConditionSet); if (state == QuestState.WaitingToStart) { quest.SetState(state, false); return; } // Don't load the info below if waiting to start: for (int i = 0; i < quest.counterList.Count; i++) { quest.counterList[i].SetValue(binaryReader.ReadInt32(), QuestCounterSetValueMode.DontInformListeners); } for (int i = 0; i < quest.nodeList.Count; i++) { ReadQuestNodeDataFromStream(binaryReader, quest.nodeList[i]); } ReadQuestIndicatorsFromStream(binaryReader, quest.indicatorStates); quest.SetRuntimeReferences(); quest.SetState(state, false); QuestMachineMessages.QuestStateChanged(quest, quest.id, quest.GetState()); }
private bool IsRequiredValue(MessageArgs messageArgs) { if (value == null) { return(true); } if (value.valueType == MessageValueType.None) { return(true); } if (messageArgs.firstValue == null) { return(false); } switch (value.valueType) { case MessageValueType.String: return(QuestMachineMessages.ArgToString(messageArgs.firstValue) == runtimeStringValue); case MessageValueType.Int: return(QuestMachineMessages.ArgToInt(messageArgs.firstValue) == value.intValue); default: Debug.LogError("Quest Machine: Unhandled MessageValueType " + value.valueType + ". Please contact the developer.", quest); return(false); } }
void IMessageHandler.OnMessage(MessageArgs messageArgs) { if (!isChecking) { return; } if (messageArgs.values == null || messageArgs.values.Length < 2 || requiredQuestID == null) { return; } var questID = messageArgs.parameter; if (!string.Equals(questID, StringField.GetStringValue(requiredQuestID))) { return; } var questNodeID = QuestMachineMessages.ArgToString(messageArgs.values[0]); if (!string.Equals(questNodeID, requiredQuestNodeID.value)) { return; } var stateValue = messageArgs.values[1]; var state = (stateValue != null && stateValue.GetType() == typeof(QuestNodeState)) ? (QuestNodeState)stateValue : QuestNodeState.Inactive; if (state == requiredState) { SetTrue(); } }
protected virtual void ShowOfferQuest(Quest quest) { if (questDialogueUI == null) { if (Debug.isDebugBuild) { Debug.LogWarning("Quest Machine: There is no Quest Dialogue UI.", this); } } else if (quest == null) { if (Debug.isDebugBuild) { Debug.LogWarning("Quest Machine: The quest passed to ShowOfferQuest() is null.", this); } } else if (playerQuestListContainer == null) { if (Debug.isDebugBuild) { Debug.LogWarning("Quest Machine: There is no Player Quest List Container. Can't offer quest '" + quest.title + "'.", this); } } else { quest.greeterID = StringField.GetStringValue(playerTextInfo.id); QuestMachineMessages.DiscussQuest(player, this, id, quest.id); playerQuestListContainer.DeleteQuest(quest.id); // Clear any old instance of repeatable quests first. questDialogueUI.ShowOfferQuest(myQuestGiverTextInfo, quest, OnAcceptQuest, OnQuestBackButton); QuestMachineMessages.DiscussedQuest(player, this, id, quest.id); } }
/// <summary> /// If onlyTrackOneQuestAtATime is true and the specified quest is /// now being tracked, disable tracking on other quests. /// </summary> /// <param name="questID"></param> public virtual void CheckTrackingToggles(string questID) { if (!onlyTrackOneQuestAtATime) { return; } var quest = FindQuest(questID); if (quest == null || !quest.showInTrackHUD) { return; } var changed = false; for (int i = 0; i < questList.Count; i++) { if (questList[i] == null || !questList[i].showInTrackHUD || Equals(questList[i].id, questID)) { continue; } questList[i].showInTrackHUD = false; changed = true; } if (changed) { QuestMachineMessages.RefreshUIs(quest); } }
protected virtual void Awake() { myID = StringField.GetStringValue(QuestMachineMessages.GetID(gameObject)); InitializeQuestIndicatorUI(); InitializeStates(); RegisterWithMessageSystem(); }
/// <summary> /// Adds an instance of a quest to a quester's list. If the quest's maxTimes are reached, /// deletes the quest from the giver. Otherwise starts cooldown timer until it can be /// given again. /// </summary> /// <param name="quest">Quest to give to quester.</param> /// <param name="questerTextInfo">Quester's text info.</param> /// <param name="questerQuestListContainer">Quester's quest list container.</param> public virtual void GiveQuestToQuester(Quest quest, QuestParticipantTextInfo questerTextInfo, QuestListContainer questerQuestListContainer) { if (quest == null) { Debug.LogWarning("Quest Machine: " + name + ".GiveQuestToQuester - quest is null.", this); return; } if (questerTextInfo == null) { Debug.LogWarning("Quest Machine: " + name + ".GiveQuestToQuester - questerTextInfo is null.", this); return; } if (questerQuestListContainer == null) { Debug.LogWarning("Quest Machine: " + name + ".GiveQuestToQuester - questerQuestListContainer is null.", this); return; } // Make a copy of the quest for the quester: var questInstance = quest.Clone(); // Update the version on this QuestGiver: quest.timesAccepted++; if (quest.timesAccepted >= quest.maxTimes) { DeleteQuest(quest.id); } else { quest.StartCooldown(); } // Add the copy to the quester and activate it: questInstance.AssignQuestGiver(myQuestGiverTextInfo); questInstance.AssignQuester(questerTextInfo); questInstance.timesAccepted = 1; if (questerQuestListContainer.questList.Count > 0) { for (int i = questerQuestListContainer.questList.Count - 1; i >= 0; i--) { var inJournal = questerQuestListContainer.questList[i]; if (inJournal == null) { continue; } if (StringField.Equals(inJournal.id, quest.id) && inJournal.GetState() != QuestState.Active) { questInstance.timesAccepted++; questerQuestListContainer.DeleteQuest(inJournal); } } } questerQuestListContainer.deletedStaticQuests.Remove(StringField.GetStringValue(questInstance.id)); questerQuestListContainer.AddQuest(questInstance); questInstance.SetState(QuestState.Active); QuestMachineMessages.RefreshIndicators(questInstance); }
public void OnMessage(MessageArgs messageArgs) { if (QuestMachine.debug) { Debug.Log("Quest Machine: QuestCounter[" + name + "].OnMessage(" + messageArgs.message + ", " + messageArgs.parameter + ")", m_quest); } switch (messageArgs.message) { case DataSynchronizer.DataSourceValueChangedMessage: m_currentValue = messageArgs.intValue; break; case QuestMachineMessages.SetQuestCounterMessage: m_currentValue = messageArgs.intValue; break; case QuestMachineMessages.IncrementQuestCounterMessage: m_currentValue += messageArgs.intValue; break; default: if (messageEventList == null) { break; } for (int i = 0; i < messageEventList.Count; i++) { var messageEvent = messageEventList[i]; if (messageEvent != null && messageArgs.Matches(messageEvent.message, messageEvent.parameter) && QuestMachineMessages.IsRequiredID(messageArgs.sender, QuestMachineTags.ReplaceTags(messageEvent.senderID, m_quest)) && QuestMachineMessages.IsRequiredID(messageArgs.target, QuestMachineTags.ReplaceTags(messageEvent.targetID, m_quest))) { switch (messageEvent.operation) { case QuestCounterMessageEvent.Operation.ModifyByLiteralValue: m_currentValue += messageEvent.literalValue; break; case QuestCounterMessageEvent.Operation.ModifyByParameter: m_currentValue += messageArgs.intValue; break; case QuestCounterMessageEvent.Operation.SetToLiteralValue: m_currentValue = messageEvent.literalValue; break; case QuestCounterMessageEvent.Operation.SetToParameter: m_currentValue = messageArgs.intValue; break; } } } break; } SetValue(m_currentValue, QuestCounterSetValueMode.DontInformDataSync); }
/// <summary> /// Starts dialogue with the player. The content of the dialogue will depend on the quest giver's /// offerable quests and the player's quests. /// </summary> /// <param name="player">Player conversing with this QuestGiver. If null, searches the scene for a GameObject tagged Player.</param> public virtual void StartDialogue(GameObject player) { if (questDialogueUI == null && Debug.isDebugBuild) { Debug.LogWarning("Quest Machine: Can't start dialogue with " + name + ". Quest Giver doesn't have access to a quest dialogue UI.", this); return; } // If player isn't specified, find it in the scene and find relevant quest journal: if (player == null) { player = FindPlayerGameObject(); } if (player == null && Debug.isDebugBuild) { Debug.LogWarning("Quest Machine: Can't start dialogue with " + name + ". No quester specified.", this); return; } playerQuestListContainer = player.GetComponent <QuestListContainer>(); if (playerQuestListContainer == null) { var playerID = player.GetComponent <QuestMachineID>(); if (playerID != null && playerID.questListContainer != null) { playerQuestListContainer = playerID.questListContainer; } else { var playerJournalObject = FindPlayerJournalGameObject(); playerQuestListContainer = (playerJournalObject != null) ? playerJournalObject.GetComponent <QuestListContainer>() : null; } } if (playerQuestListContainer == null && Debug.isDebugBuild) { Debug.LogWarning("Quest Machine: Can't start dialogue with " + name + ". Quester " + player.name + " doesn't have a Quest Journal and can't find one in scene.", this); return; } QuestMachineTags.fallbackTextTable = textTable; // Setup player info: this.player = player; playerTextInfo = new QuestParticipantTextInfo(QuestMachineMessages.GetID(player), QuestMachineMessages.GetDisplayName(player), null, null); // Greet before recording quests in case Greet message changes a quest state: QuestMachineMessages.Greet(player, this, id); // Record quests related to this player and me: RecordQuestsByState(); StartMostRelevantDialogue(); // Note: Sends Greeted immediately after opening dialogue UI, not when closing it: QuestMachineMessages.Greeted(player, this, id); }
public void OnToggleTracking(bool value, object data) { var quest = data as Quest; if (quest == null) { return; } quest.showInTrackHUD = value; QuestMachineMessages.RefreshUIs(quest); }
/// <summary> /// Adds a quest to this quest giver's list. /// </summary> /// <param name="quest"></param> public override Quest AddQuest(Quest quest) { if (quest == null) { return(null); } var instance = base.AddQuest(quest); instance.AssignQuestGiver(myQuestGiverTextInfo); QuestMachineMessages.RefreshUIs(this); return(instance); }
public override void Execute() { if (quest == null) { if (Debug.isDebugBuild) { Debug.LogWarning("Quest Machine: AlertQuestAction was passed a null quest."); } return; } QuestMachineMessages.QuestAlert(quest, quest.id, contentList); }
public void ClearQuestIndicatorStates() { if (indicatorStates == null) { return; } foreach (var kvp in indicatorStates) { MessageSystem.SendMessageWithTarget(this, kvp.Key, QuestMachineMessages.SetIndicatorStateMessage, id, QuestIndicatorState.None); } indicatorStates.Clear(); QuestMachineMessages.RefreshIndicators(questGiverID); }
protected virtual void ShowActiveQuest(Quest quest) { QuestParameterDelegate backButtonDelegate = null; if (activeQuests.Count + offerableQuests.Count >= 2) { backButtonDelegate = OnQuestBackButton; allowBackButton = true; // May turn in quest and be left with only 1. In this case, still allow back button. } quest.greeterID = StringField.GetStringValue(playerTextInfo.id); QuestMachineMessages.DiscussQuest(player, this, id, quest.id); questDialogueUI.ShowActiveQuest(myQuestGiverTextInfo, quest, OnContinueActiveQuest, backButtonDelegate); QuestMachineMessages.DiscussedQuest(player, this, id, quest.id); }
void IMessageHandler.OnMessage(MessageArgs messageArgs) { if (!(QuestMachineMessages.IsRequiredID(messageArgs.sender, runtimeSenderID) && QuestMachineMessages.IsRequiredID(messageArgs.target, runtimeTargetID) && IsRequiredValue(messageArgs))) { return; } if (QuestMachine.debug) { Debug.Log("Quest Machine: MessageQuestCondition.OnMessage( " + messageArgs.message + ", " + messageArgs.parameter + ")", quest); } SetTrue(); }
/// <summary> /// Adds an instance of a quest to a quester's list. If the quest's maxTimes are reached, /// deletes the quest from the giver. Otherwise starts cooldown timer until it can be /// given again. /// </summary> /// <param name="quest">Quest to give to quester.</param> /// <param name="questerQuestListContainer">Quester's quest list container.</param> public virtual void GiveQuestToQuester(Quest quest, QuestListContainer questerQuestListContainer) { if (quest == null) { return; } if (questerQuestListContainer == null) { Debug.LogWarning("Quest Machine: " + name + ".GiveQuestToQuester - quester (QuestListContainer) is null.", this); return; } var questerTextInfo = new QuestParticipantTextInfo(QuestMachineMessages.GetID(questerQuestListContainer.gameObject), QuestMachineMessages.GetDisplayName(questerQuestListContainer.gameObject), null, null); GiveQuestToQuester(quest, questerTextInfo, questerQuestListContainer); }
public override void Execute() { switch (state) { case ControlState.Start: QuestMachineMessages.StartSpawner(spawnerName); break; case ControlState.Stop: QuestMachineMessages.StopSpawner(spawnerName); break; case ControlState.Despawn: QuestMachineMessages.DespawnSpawner(spawnerName); break; } }
public virtual void AbandonQuest(Quest quest) { if (quest == null || !quest.isAbandonable) { return; } if (quest.rememberIfAbandoned) { quest.SetState(QuestState.Abandoned); } else { DeleteQuest(quest.id); } QuestMachineMessages.QuestAbandoned(this, quest.id); if (questJournalUI != null) { questJournalUI.SelectQuest(null); } RepaintUIs(); }
public void SetValue(int newValue, QuestCounterSetValueMode setValueMode = QuestCounterSetValueMode.InformListeners) { m_currentValue = Mathf.Clamp(newValue, minValue, maxValue); if (setValueMode != QuestCounterSetValueMode.DontInformListeners) { var informDataSync = (updateMode == QuestCounterUpdateMode.DataSync) && (setValueMode != QuestCounterSetValueMode.DontInformDataSync); if (informDataSync) { MessageSystem.SendMessage(this, DataSynchronizer.RequestDataSourceChangeValueMessage, name, currentValue); } QuestMachineMessages.QuestCounterChanged(this, questID, name, currentValue); try { changed(this); } catch (Exception e) // Don't let exceptions in user-added events break our code. { if (Debug.isDebugBuild) { Debug.LogException(e); } } } }
public virtual void OnMessage(MessageArgs messageArgs) { var target = messageArgs.targetString; if (!(string.IsNullOrEmpty(target) || string.Equals(target, myID) || StringField.Equals(QuestMachineMessages.GetID(target), myID))) { return; } switch (messageArgs.message) { case QuestMachineMessages.SetIndicatorStateMessage: SetIndicatorState(messageArgs.parameter, (QuestIndicatorState)messageArgs.firstValue); break; case QuestMachineMessages.RefreshIndicatorMessage: case QuestMachineMessages.RefreshUIsMessage: Repaint(); break; } }
/// <summary> /// Sets the quest node to a quest state and performs all related activities /// such as enabling connections and executing actions. This may cause other /// nodes to advance their states, too. /// </summary> /// <param name="newState">New state.</param> public void SetState(QuestNodeState newState, bool informListeners = true) { if (QuestMachine.debug) { Debug.Log("Quest Machine: " + ((quest != null) ? quest.GetEditorName() : "Quest") + "." + GetEditorName() + ".SetState(" + newState + ")", quest); } m_state = newState; SetConditionChecking(newState == QuestNodeState.Active); if (!informListeners) { return; } // Execute state actions: var stateInfo = GetStateInfo(m_state); if (stateInfo != null && stateInfo.actionList != null) { for (int i = 0; i < stateInfo.actionList.Count; i++) { if (stateInfo.actionList[i] == null) { continue; } stateInfo.actionList[i].Execute(); } } // Notify that state changed: QuestMachineMessages.QuestNodeStateChanged(this, quest.id, id, m_state); try { stateChanged(this); } catch (Exception e) // Don't let exceptions in user-added events break our code. { if (Debug.isDebugBuild) { Debug.LogException(e); } } // Handle special node types: switch (m_state) { case QuestNodeState.Active: if (nodeType != QuestNodeType.Condition) { // Automatically switch non-Condition nodes to True state: SetState(QuestNodeState.True); } break; case QuestNodeState.True: // If it's an endpoint, set the overall quest state: switch (nodeType) { case QuestNodeType.Success: if (quest != null) { quest.SetState(QuestState.Successful); } break; case QuestNodeType.Failure: if (quest != null) { quest.SetState(QuestState.Failed); } break; } break; } }
/// <summary> /// Sets the quest state. This may also affect the states of the quest's nodes. /// </summary> /// <param name="newState">The new quest state.</param> public void SetState(QuestState newState, bool informListeners = true) { if (QuestMachine.debug) { Debug.Log("Quest Machine: " + GetEditorName() + ".SetState(" + newState + ", informListeners=" + informListeners + ")", this); } m_state = newState; SetStartChecking(newState == QuestState.WaitingToStart); SetCounterListeners(newState == QuestState.Active || (newState == QuestState.WaitingToStart && (hasAutostartConditions || hasOfferConditions))); if (newState != QuestState.Active) { StopNodeListeners(); } if (!informListeners) { return; } // Execute state actions: var stateInfo = GetStateInfo(m_state); if (stateInfo != null && stateInfo.actionList != null) { for (int i = 0; i < stateInfo.actionList.Count; i++) { if (stateInfo.actionList[i] != null) { stateInfo.actionList[i].Execute(); } } } // Notify that state changed: QuestMachineMessages.QuestStateChanged(this, id, m_state); try { stateChanged(this); } catch (Exception e) // Don't let exceptions in user-added events break our code. { if (Debug.isDebugBuild) { Debug.LogException(e); } } // If going active, activate the start node: if (m_state == QuestState.Active && startNode != null) { startNode.SetState(QuestNodeState.Active); } // If inactive, clear the indicators: if (m_state != QuestState.Active) { ClearQuestIndicatorStates(); } // If done, set all active nodes to inactive: if (m_state == QuestState.Successful || m_state == QuestState.Failed || m_state == QuestState.Abandoned) { for (int i = 0; i < nodeList.Count; i++) { if (nodeList[i].GetState() == QuestNodeState.Active) { nodeList[i].SetState(QuestNodeState.Inactive); } } } }
/// <summary> /// Sends a message to the Message System. If the message contains a /// colon (:), the part after the colon is sent as the parameter. If /// it contains a second colon, the part after the second colon is sent /// as a value. /// </summary> /// <param name="message"></param> public void SendToMessageSystem(string message) { QuestMachineMessages.SendCompositeMessage(this, message); }
public override void ApplyData(string data) { if (!includeInSavedGameData) { return; } if (string.IsNullOrEmpty(data)) { return; } try { QuestMachine.isLoadingGame = true; var saveData = SaveSystem.Deserialize <SaveData>(data); if (saveData == null) { return; } // Clear current quest list: DestroyQuestInstances(); // Adds them to deletedStaticQuests, but that's OK since we're going to restore deletedStaticQuests. // Restore dynamic quests: for (int i = 0; i < saveData.proceduralQuests.Count; i++) { try { var questProxy = JsonUtility.FromJson <QuestProxy>(saveData.proceduralQuests[i]); if (questProxy == null) { continue; } var quest = ScriptableObject.CreateInstance <Quest>(); quest.name = questProxy.displayName; questProxy.CopyTo(quest); AddQuest(quest); } catch (Exception e) { if (Debug.isDebugBuild) { Debug.LogWarning("Quest Machine: Unable to restore quest from serialized quest proxy. Message: " + e.Message + "\nData: " + saveData.proceduralQuests[i], this); } } } // Restore list of deleted static quests: deletedStaticQuests.Clear(); deletedStaticQuests.AddRange(saveData.deletedStaticQuests); // Restore static quests: for (int i = 0; i < Mathf.Min(saveData.staticQuestIds.Count, saveData.staticQuestData.Count); i++) { var questID = saveData.staticQuestIds[i]; var questData = saveData.staticQuestData[i]; if (string.IsNullOrEmpty(questID) || questData == null || questData.bytes == null) { continue; } if (deletedStaticQuests.Contains(questID)) { continue; } var quest = QuestMachine.GetQuestAsset(questID); if (quest == null) { quest = originalQuestList.Find(x => string.Equals(StringField.GetStringValue(x.id), questID)); } if (quest == null && Debug.isDebugBuild) { Debug.LogError("Quest Machine: " + name + " Can't find quest " + saveData.staticQuestIds[i] + ". Is it registered with Quest Machine?", this); } if (quest == null) { continue; } quest = quest.Clone(); try { QuestStateSerializer.DeserializeInto(quest, questData.bytes, true); } catch (Exception e) { try { if (Debug.isDebugBuild) { Debug.LogWarning("Quest Machine: Unable to restore quest: " + quest.name + ". Message: " + e.Message, this); } Destroy(quest); } catch (Exception) { } quest = quest.Clone(); } AddQuest(quest); } QuestMachineMessages.RefreshIndicator(this, QuestMachineMessages.GetID(this)); } finally { QuestMachine.isLoadingGame = false; } }