Forum rules - please read before posting.

Sub Quest (Sub Objective)

Hi there,

I'm working on implementing a list of quests (Objectives) in Adventure Creator and aiming for a structure like:

QuestA
QuestB
--SubQuest1
--SubQuest2
QuestC
(The two dashes represent an indent)

I followed the instructions from this post: Quest Objectives and sub-Objectives (https://adventure-creator.fandom.com/wiki/Quest_Objectives_and_sub-Objectives)

Here's what I've done so far:

  • Created QuestSystem.cs.
  • Attached the script to an empty game object.
  • Created a Global Variable (String type).
  • Assigned the ID of the Global Variable to the public field in the QuestSystem.cs script.
  • Added a "Label" element in my Quest (Objective) menu and set its type to "Global Variable".

However, I've encountered a few issues:

  • When I run the game and any subQuest is set to "started", the Main Quest appears in the menu, but it's listed below the subQuest.
  • If I start one subQuest and then trigger another main Quest, the order becomes jumbled when I subsequently start one of the subQuests of the new main Quest.
  • The title of the sub-quest isn't formatted properly. Instead of a neatly separated title, it literally shows as "quest/subquest", including the slash, as shown below:

Quest/SubQuestB2
QuestC
Quest/SubQuestB1
QuestB

  • And the 'Label' element displays 'Quest/subquest', and I'm unsure about its intended behavior.

If I've overlooked something or if there's a solution to these issues, I'd be extremely grateful for any guidance. Thank you in advance.

Comments

  • Currently, Objectives in an InventoryBox are listed in the order in which they are first started. I shall look into providing options to list them by e.g. last updated, etc.

    Regarding the slashes being visible: the intent with the script is to have the String variable / Label element to replace the list with one that uses the Descriptions instead, but a typo caused the Titles to be used here as well.

    To simplify things, here's a variant that does away with the Label element / String variable. This time, move the names-with-slashes to the Objective's Description field, and remove the "Quest/" from the title:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    namespace AC
    {
    
        public class QuestSystemNew : MonoBehaviour
        {
    
            #region Variables
    
            private Quest[] quests;
    
            #endregion
    
    
            #region UnityStandards
    
            private void OnEnable ()
            {
                DontDestroyOnLoad (gameObject);
                GenerateQuests ();
    
                EventManager.OnObjectiveUpdate += OnObjectiveUpdate;
            }
    
    
            private void OnDisable ()
            {
                EventManager.OnObjectiveUpdate -= OnObjectiveUpdate;
            }
    
            #endregion
    
    
            #region PrivateFunctions
    
            private void GenerateQuests ()
            {
                List<Quest> questsList = new List<Quest>();
                foreach (Objective objective in KickStarter.inventoryManager.objectives)
                {
                    if (!objective.description.Contains ("/"))
                    {
                        Quest quest = new Quest (objective);
                        questsList.Add (quest);
                    }
                }
    
                quests = questsList.ToArray ();
            }
    
    
            private void OnObjectiveUpdate (Objective objective, ObjectiveState state)
            {
                foreach (Quest quest in quests)
                {
                    quest.OnObjectiveUpdate (objective.ID);
                }
            }
    
            #endregion
    
    
            [System.Serializable]
            private class Quest
            {
    
                #region Variables
    
                private int mainObjectiveID;
                private List<int> subObjectiveIDs = new List<int>();
    
                #endregion
    
    
                #region Constructors
    
                public Quest (Objective mainObjective)
                {
                    mainObjectiveID = mainObjective.ID;
                    subObjectiveIDs = new List<int>();
    
                    string requiredPrefix = mainObjective.description + "/";
                    foreach (Objective objective in KickStarter.inventoryManager.objectives)
                    {
                        if (objective != mainObjective && objective.description.StartsWith (requiredPrefix))
                        {
                            // Is a sub-objective
                            subObjectiveIDs.Add (objective.ID);
                        }
                    }
                }
    
                #endregion
    
    
                #region PublicFunctions
    
                public void OnObjectiveUpdate (int objectiveID)
                {
                    if (!subObjectiveIDs.Contains (objectiveID) || !IsValid ()) return;
                    AutoUpdateMainState ();
                }
    
                #endregion
    
    
                #region PrivateFunctions        
    
                private void AutoUpdateMainState ()
                {
                    int completedSubObjectives = 0;
                    int failedSubObjectives = 0;
                    int activeSubObjectives = 0;
    
                    foreach (int subObjectiveID in subObjectiveIDs)
                    {
                        ObjectiveState subObjectiveState = KickStarter.runtimeObjectives.GetObjectiveState (subObjectiveID);
                        if (subObjectiveState == null)
                        {
                            continue;
                        }
    
                        switch (subObjectiveState.stateType)
                        {
                            case ObjectiveStateType.Active:
                                activeSubObjectives ++;
                                break;
    
                            case ObjectiveStateType.Complete:
                                completedSubObjectives ++;
                                break;
    
                            case ObjectiveStateType.Fail:
                                failedSubObjectives ++;
                                break;
    
                            default:
                                break;
                        }
                    }
    
                    int totalSubObjectives = subObjectiveIDs.Count;
    
                    if (completedSubObjectives == totalSubObjectives)
                    {
                        // Completed all sub-objectives, main is completed
                        KickStarter.runtimeObjectives.SetObjectiveState (mainObjectiveID, ObjectiveStateType.Complete);
                    }
                    else if (failedSubObjectives > 0)
                    {
                        // Failed a sub-objectives, main is failed
                        KickStarter.runtimeObjectives.SetObjectiveState (mainObjectiveID, ObjectiveStateType.Fail);
                    }
                    else if (activeSubObjectives > 0)
                    {
                        // Main is active
                        KickStarter.runtimeObjectives.SetObjectiveState (mainObjectiveID, ObjectiveStateType.Active);
                    }
                    else
                    {
                        // Main is inactive
                    }
                }
    
    
                private bool IsValid ()
                {
                    if (mainObjectiveID < 0 ||
                        subObjectiveIDs.Contains (mainObjectiveID) ||
                        subObjectiveIDs.Count == 0)
                    {
                        return false;
                    }
                    return true;
                }
    
                #endregion
    
            }
        }
    
    }
    
  • Thank you so much for your help! The option to list the objectives in different orders would indeed be a great addition to the system. Thank you again for updating Adventure Creator.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.