/// <summary> /// Complete an achieved <see cref="Quest"/> supplying an optional reward and whether the quest was completed from the communicator. /// </summary> public void QuestComplete(ushort questId, ushort reward, bool communicator) { QuestInfo questInfo = GlobalQuestManager.Instance.GetQuestInfo(questId); if (questInfo == null) { throw new ArgumentException($"Invalid quest {questId}!"); } if (DisableManager.Instance.IsDisabled(DisableType.Quest, questId)) { player.SendSystemMessage($"Unable to complete quest {questId} because it is disabled."); return; } Quest.Quest quest = GetQuest(questId, GetQuestFlags.Active); if (quest == null) { if (!questInfo.IsAutoComplete()) { throw new QuestException($"Player {player.CharacterId} tried to complete quest {questId} which they don't have!"); } QuestAdd(questId, null); quest = GetQuest(questId); quest.State = QuestState.Achieved; } if (quest.State != QuestState.Achieved) { throw new QuestException($"Player {player.CharacterId} tried to complete quest {questId} which wasn't complete!"); } if (communicator) { if (!quest.Info.IsCommunicatorReceived()) { throw new QuestException($"Player {player.CharacterId} tried to complete quest {questId} without communicator message!"); } } else { if (!GlobalQuestManager.Instance.GetQuestReceivers(questId).Any(c => player.GetVisibleCreature <WorldEntity>(c).Any())) { throw new QuestException($"Player {player.CharacterId} tried to complete quest {questId} without any quest receiver!"); } } // reclaim any quest specific items for (int i = 0; i < quest.Info.Entry.PushedItemIds.Length; i++) { uint itemId = quest.Info.Entry.PushedItemIds[i]; if (itemId != 0u) { player.Inventory.ItemDelete(itemId, quest.Info.Entry.PushedItemCounts[i]); } } RewardQuest(quest.Info, reward); quest.State = QuestState.Completed; // mark repeatable quests for reset switch ((QuestRepeatPeriod)quest.Info.Entry.QuestRepeatPeriodEnum) { case QuestRepeatPeriod.Daily: quest.Reset = GlobalQuestManager.Instance.NextDailyReset; break; case QuestRepeatPeriod.Weekly: quest.Reset = GlobalQuestManager.Instance.NextWeeklyReset; break; } activeQuests.Remove(questId); completedQuests.Add(questId, quest); player.AchievementManager.CheckAchievements(player, AchievementType.QuestComplete, questId); }