private IEnumerator Sequence(List <QuestsTrackerSection> visibleSections, List <QuestsTrackerSection> newSections) { yield return(new WaitUntil(() => outAnimDone)); ClearSectionRoutines(); if (progressRoutine != null) { StopCoroutine(progressRoutine); } progressRoutine = StartCoroutine(ProgressSequence()); //Progress of currently visible sections for (int i = 0; i < visibleSections.Count; i++) { sectionRoutines.Add(StartCoroutine(visibleSections[i].Sequence())); } yield return(WaitForTaskRoutines()); //Show and progress of new tasks for (int i = 0; i < newSections.Count; i++) { newSections[i].gameObject.SetActive(true); sectionRoutines.Add(StartCoroutine(newSections[i].Sequence())); } OnLayoutRebuildRequested?.Invoke(); yield return(WaitForTaskRoutines()); OnLayoutRebuildRequested?.Invoke(); //The entry should exit automatically if questCompleted or no progress, therefore the use of MinValue DateTime tasksIdleTime = (quest.isCompleted || !hasProgressedThisUpdate) ? DateTime.MinValue : DateTime.Now; yield return(new WaitUntil(() => isProgressAnimationDone && !isPinned && (DateTime.Now - tasksIdleTime) > TimeSpan.FromSeconds(3))); if (quest.isCompleted) { OnQuestCompleted?.Invoke(quest); } for (int i = 0; i < rewardsToNotify.Count; i++) { OnRewardObtained?.Invoke(rewardsToNotify[i]); } rewardsToNotify.Clear(); isReadyForDisposal = true; }
/// <summary> /// Update progress in a quest /// </summary> /// <param name="progressedQuest"></param> public void UpdateQuestProgress(QuestModel progressedQuest) { if (!progressedQuest.canBePinned) { pinnedQuests.Remove(progressedQuest.id); } //Alex: Edge case. Quests has no sections/tasks, we ignore the UpdateQuestProgress and remove the cached one. if (progressedQuest.sections == null || progressedQuest.sections.Length == 0) { quests.Remove(progressedQuest.id); return; } //Alex: Edge case. Progressed quest was not included in the initialization. We dont invoke quests events if (!quests.TryGetValue(progressedQuest.id, out QuestModel oldQuest)) { RestoreProgressFlags(progressedQuest); quests.Add(progressedQuest.id, progressedQuest); if (!progressedQuest.isCompleted) { OnNewQuest?.Invoke(progressedQuest.id); QuestsControllerAnalytics.SendQuestDiscovered(progressedQuest); } return; } quests[progressedQuest.id] = progressedQuest; progressedQuest.oldProgress = oldQuest.progress; for (int index = 0; index < progressedQuest.sections.Length; index++) { QuestSection newQuestSection = progressedQuest.sections[index]; bool oldQuestSectionFound = oldQuest.TryGetSection(newQuestSection.id, out QuestSection oldQuestSection); for (int index2 = 0; index2 < newQuestSection.tasks.Length; index2++) { QuestTask currentTask = newQuestSection.tasks[index2]; if (oldQuestSectionFound) { bool oldTaskFound = oldQuestSection.TryGetTask(currentTask.id, out QuestTask oldTask); currentTask.justProgressed = !oldTaskFound || currentTask.progress != oldTask.progress; if (currentTask.justProgressed) { QuestsControllerAnalytics.SendTaskProgressed(progressedQuest, newQuestSection, currentTask); } currentTask.justUnlocked = !oldTaskFound || (currentTask.status != QuestsLiterals.Status.BLOCKED && oldTask.status == QuestsLiterals.Status.BLOCKED); currentTask.oldProgress = oldTaskFound ? oldTask.progress : 0; if (oldTaskFound && oldTask.status != QuestsLiterals.Status.COMPLETED && currentTask.status == QuestsLiterals.Status.COMPLETED) { QuestsControllerAnalytics.SendTaskCompleted(progressedQuest, newQuestSection, currentTask); } } else { currentTask.justProgressed = false; currentTask.justUnlocked = false; currentTask.oldProgress = 0; } } } // If quest is not blocked anymore or being secret has been just started, we call NewQuest event. if (!progressedQuest.isCompleted && ((oldQuest.status == QuestsLiterals.Status.BLOCKED && progressedQuest.status != QuestsLiterals.Status.BLOCKED) || (progressedQuest.visibility == QuestsLiterals.Visibility.SECRET && oldQuest.status == QuestsLiterals.Status.NOT_STARTED && progressedQuest.status != QuestsLiterals.Status.NOT_STARTED))) { OnNewQuest?.Invoke(progressedQuest.id); QuestsControllerAnalytics.SendQuestDiscovered(progressedQuest); } OnQuestUpdated?.Invoke(progressedQuest.id, HasProgressed(progressedQuest, oldQuest)); if (!oldQuest.isCompleted && progressedQuest.isCompleted) { QuestsControllerAnalytics.SendQuestCompleted(progressedQuest); } if (progressedQuest.rewards == null) { progressedQuest.rewards = new QuestReward[0]; } for (int index = 0; index < progressedQuest.rewards.Length; index++) { QuestReward newReward = progressedQuest.rewards[index]; //Alex: Edge case. New quest reported contains a reward that was previously not contained. // If it's completed, we call the RewardObtained event bool oldRewardFound = oldQuest.TryGetReward(newReward.id, out QuestReward oldReward); bool rewardObtained = (!oldRewardFound && newReward.status == QuestsLiterals.RewardStatus.OK) || (newReward.status != oldReward.status && newReward.status == QuestsLiterals.RewardStatus.OK); if (rewardObtained) { OnRewardObtained?.Invoke(progressedQuest.id, newReward.id); QuestsControllerAnalytics.SendRewardObtained(progressedQuest, newReward); } } RestoreProgressFlags(progressedQuest); }