Beispiel #1
0
        private void QuestAdd(QuestInfo info, Quest.Quest quest, Item item)
        {
            if (quest?.State == QuestState.Accepted || quest?.State == QuestState.Achieved)
            {
                throw new QuestException($"Player {player.CharacterId} tried to start quest {info.Entry.Id} which is already in progress!");
            }

            // if quest has already been completed make sure it's repeatable and the reset period has elapsed
            if (quest?.State == QuestState.Completed)
            {
                if (info.Entry.QuestRepeatPeriodEnum == 0u)
                {
                    throw new QuestException($"Player {player.CharacterId} tried to start quest {info.Entry.Id} which they have already completed!");
                }

                DateTime?resetTime = GetQuest((ushort)info.Entry.Id, GetQuestFlags.Completed).Reset;
                if (DateTime.UtcNow < resetTime)
                {
                    throw new QuestException($"Player {player.CharacterId} tried to start quest {info.Entry.Id} which hasn't reset yet!");
                }
            }

            if (item != null)
            {
                if (info.Entry.Id != item.Entry.Quest2IdActivation)
                {
                    throw new QuestException($"Player {player.CharacterId} tried to start quest {info.Entry.Id} from invalid item {item.Entry.Id}!");
                }

                // TODO: consume charge
            }
            else
            {
                // make sure the player is in range of a quest giver or they are eligible for a communicator message that starts the quest
                if (!GlobalQuestManager.Instance.GetQuestGivers((ushort)info.Entry.Id)
                    .Any(c => player.GetVisibleCreature <WorldEntity>(c).Any()))
                {
                    if (!info.IsCommunicatorReceived())
                    {
                        throw new QuestException($"Player {player.CharacterId} tried to start quest {info.Entry.Id} without quest giver!");
                    }

                    if (!GlobalQuestManager.Instance.GetQuestCommunicatorMessages((ushort)info.Entry.Id)
                        .Any(m => m.Meets(player)))
                    {
                        throw new QuestException($"Player {player.CharacterId} tried to start quest {info.Entry.Id} without communicator message!");
                    }
                }
            }

            // server doesn't send an error message for prerequisites since the client does the exact same checks
            // it's assumed that a player could never get here without cheating in some way
            if (!MeetsPrerequisites(info))
            {
                throw new QuestException($"Player {player.CharacterId} tried to start quest {info.Entry.Id} without meeting the prerequisites!");
            }

            QuestAdd(info);
        }