Json saving system-QuestList not being saved

Hi.
I have a small issue with the QuestList. It is not being saved. I have followed the gitlab commit but it doesn’t seem to work for me. It is the only thing that is not saved. As soon as I change scene it is removed. I think it might have to do with the old CaptureState in QuestStatus.cs but apparently if i try to remove it it gives me an error.

namespace RPG.Quests
{
    
    public class QuestStatus 
    {
        Quest quest;
        List<string> completedObjectives = new List<string>();

        [System.Serializable]
        class QuestStatusRecord
        {
            public string questName;
            public List<string> completedObjectives;
        }

        public QuestStatus(Quest quest)
        {
            this.quest = quest;
        }

        public QuestStatus(object objectState)
        {
           QuestStatusRecord state = objectState as QuestStatusRecord;
           quest = Quest.GetByName(state.questName);
           completedObjectives = state.completedObjectives;
        }

        public Quest GetQuest()
        {
            return quest;
        }

        public bool IsComplete()
        {
            foreach( var objective in quest.GetObjectives())
            {
                if(!completedObjectives.Contains(objective.reference))
                {
                    return false;
                }
            }
            return true;
        }

        public int GetCompletedCount()
        {
            return completedObjectives.Count;
        }

        public bool IsObjectiveComplete(string objective)
        {
            return completedObjectives.Contains(objective);
        }

        public void CompleteObjective(string objective)
        {
            if(quest.HasObjective(objective))
            {
                completedObjectives.Add(objective);
            }
        }

        public object CaptureState()
        {
            QuestStatusRecord state = new QuestStatusRecord();
            state.questName = quest.name;
            state.completedObjectives = completedObjectives;
            return state; 
        }
        public QuestStatus(JToken objectState)
        {
            if (objectState is JObject state)
            {
                IDictionary<string, JToken> stateDict = state;
                quest = Quest.GetByName(stateDict["questName"].ToObject<string>());
                completedObjectives.Clear();
                if (stateDict["completedObjectives"] is JArray completedState)
                {
                    IList<JToken> completedStateArray = completedState;
                    foreach (JToken objective in completedStateArray)
                    {
                        completedObjectives.Add(objective.ToObject<string>());
                    }
                }
            }
        }
        public JToken CaptureAsJToken()
        {
            JObject state = new JObject();
            IDictionary<string, JToken> stateDict = state;
            stateDict["questName"] = quest.name;
            JArray completedState = new JArray();
            IList<JToken> completedStateArray = completedState;
            foreach (string objective in completedObjectives)
            {
                completedStateArray.Add(JToken.FromObject(objective));
            }
            stateDict["completedObjectives"] = completedState;
            return state;
        }

    }

}
namespace RPG.Quests
{
    public class QuestList : MonoBehaviour, IPredicateEvaluator, IJsonSaveable 
    {
        List<QuestStatus> statuses = new List<QuestStatus>();

        public event Action onUpdate;
        private void Update() 
        {
            CompleteObjectivesByPredicates();
            
        }


        public void AddQuest(Quest quest)
        {
            if(HasQuest(quest)) return;
            QuestStatus newStatus = new QuestStatus(quest);
            statuses.Add(newStatus);
            if (onUpdate != null)
            {
                onUpdate();
            }
            
        }

        public void CompleteObjective(Quest quest, string objective)
        {
            QuestStatus status = GetQuestStatus(quest);
            status.CompleteObjective(objective);
            if(status.IsComplete())
            {
                GiveReward(quest);
            }
            if (onUpdate != null)
            {
                onUpdate();
            }
        }


        public bool HasQuest(Quest quest)
        {
            return GetQuestStatus(quest) != null;
        }

        public IEnumerable<QuestStatus> GetStatuses()
        {
            return statuses;
        }

        private QuestStatus GetQuestStatus(Quest quest)
        {
            foreach (QuestStatus status in statuses)
            {
                if (status.GetQuest() == quest)
                {
                    return status;
                }
            }
            return null;
        }

        private void GiveReward(Quest quest)
        {
            foreach (var reward in quest.GetRewards())
            {
                bool success = GetComponent<Inventory>().AddToFirstEmptySlot(reward.item, reward.number);
                if(!success)
                {
                    GetComponent<ItemDropper>().DropItem(reward.item, reward.number);
                }

            }
        }

        private void CompleteObjectivesByPredicates()
        {
            foreach (QuestStatus status in statuses)
            {
               if (status.IsComplete()) continue;
               Quest quest = status.GetQuest();
               foreach (var objective in quest.GetObjectives())
               {
                   if(status.IsObjectiveComplete(objective.reference)) continue;
                   if (!objective.usesCondition) continue;
                   if (objective.completionCondition.Check(GetComponents<IPredicateEvaluator>()))
                   {
                       CompleteObjective(quest, objective.reference);
                    }
               }
            }
        }

    
        public JToken CaptureAsJToken()
        {
            JArray state = new JArray();
            IList<JToken> stateList = state;
            foreach (QuestStatus status in statuses)
            {
                stateList.Add(status.CaptureAsJToken());
            }
            return state;
        }

        public void RestoreFromJToken(JToken state)
        {
            if (state is JArray stateArray)
            {
                statuses.Clear();
                IList<JToken> stateList = stateArray;
                foreach (JToken token in stateList)
                {
                    statuses.Add(new QuestStatus(token));
                }
            }
        }
        

        public bool? Evaluate(string predicate, string[] parameters)
        {
            
            switch(predicate)
            {
                case "HasQuest":
                return HasQuest(Quest.GetByName(parameters[0]));
                case "CompletedQuest":
                if(parameters[0]==null) return false;
                    Quest questToTest = Quest.GetByName(parameters[0]);
                    if(questToTest==null) return false;
                    if(!HasQuest(questToTest)) return false; 
                    return GetQuestStatus(questToTest).IsComplete();
            }
            return null;
        }
    }
}

I left out the OnUpdate event in QuestList

        public void RestoreFromJToken(JToken state)
        {
            if (state is JArray stateArray)
            {
                statuses.Clear();
                IList<JToken> stateList = stateArray;
                foreach (JToken token in stateList)
                {
                    statuses.Add(new QuestStatus(token));
                }
                onUpdate?.Invoke(); //Add this
            }
        }

Yes. It works now. Thank you very much!

It was technically working, but without the onUpdate?.Invoke() it wasn’t updating the UI, which made it legitimately look as if it wasn’t working.

Yes. I forgot the Update completely.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms