コード例 #1
0
        /// <summary>
        /// Track or hide an active <see cref="Quest.Quest"/>.
        /// </summary>
        public void QuestTrack(ushort questId, bool tracked)
        {
            if (GlobalQuestManager.GetQuestInfo(questId) == null)
            {
                throw new ArgumentException($"Invalid quest {questId}!");
            }

            Quest.Quest quest = GetQuest(questId, GetQuestFlags.Active);
            if (quest == null)
            {
                throw new QuestException($"Player {player.CharacterId} tried to track quest {questId} which they don't have!");
            }

            if (quest.State != QuestState.Accepted && quest.State != QuestState.Achieved)
            {
                throw new QuestException($"Player {player.CharacterId} tried to track quest {questId} with invalid state!");
            }

            if (tracked)
            {
                quest.Flags |= QuestFlags.Tracked;
            }
            else
            {
                quest.Flags &= ~QuestFlags.Tracked;
            }

            log.Trace($"Updated tracked state of quest {questId} to {tracked}.");
        }
コード例 #2
0
        /// <summary>
        /// Share supplied <see cref="Quest.Quest"/> with another <see cref="Player"/>.
        /// </summary>
        public void QuestShare(ushort questId)
        {
            QuestInfo info = GlobalQuestManager.GetQuestInfo(questId);

            if (info == null)
            {
                throw new ArgumentException($"Invalid quest {questId}!");
            }

            Quest.Quest quest = GetQuest(questId);
            if (quest == null)
            {
                throw new QuestException($"Player {player.CharacterId} tried to share quest {questId} which they don't have!");
            }

            if (!quest.CanShare())
            {
                throw new QuestException($"Player {player.CharacterId} tried to share quest {questId} which can't be shared!");
            }

            Player recipient = player.GetVisible <Player>(player.TargetGuid);

            if (recipient == null)
            {
                throw new QuestException($"Player {player.CharacterId} tried to share quest {questId} to an invalid player!");
            }

            // TODO

            log.Trace($"Shared quest {questId} with player {recipient.Name}.");
        }
コード例 #3
0
        /// <summary>
        /// Create a new <see cref="QuestManager"/> from existing <see cref="Character"/> database model.
        /// </summary>
        public QuestManager(Player owner, Character model)
        {
            player = owner;

            foreach (CharacterQuest questModel in model.CharacterQuest)
            {
                QuestInfo info = GlobalQuestManager.GetQuestInfo(questModel.QuestId);
                if (info == null)
                {
                    log.Error($"Player {player.CharacterId} has an invalid quest {questModel.QuestId}!");
                    continue;
                }

                var quest = new Quest.Quest(player, info, questModel);
                switch (quest.State)
                {
                case QuestState.Completed:
                    completedQuests.Add(quest.Id, quest);
                    break;

                case QuestState.Botched:
                case QuestState.Ignored:
                    inactiveQuests.Add(quest.Id, quest);
                    break;

                case QuestState.Accepted:
                case QuestState.Achieved:
                    activeQuests.Add(quest.Id, quest);
                    break;
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Complete single <see cref="QuestObjective"/> for supplied active <see cref="Quest.Quest"/>.
        /// </summary>
        public void QuestAchieveObjective(ushort questId, byte index)
        {
            if (GlobalQuestManager.GetQuestInfo(questId) == null)
            {
                throw new ArgumentException($"Invalid quest {questId}!");
            }

            Quest.Quest quest = GetQuest(questId);
            if (quest == null || quest.PendingDelete)
            {
                throw new QuestException();
            }

            if (quest.State != QuestState.Accepted)
            {
                throw new QuestException();
            }

            QuestObjective objective = quest.SingleOrDefault(o => o.Index == index);

            if (objective == null)
            {
                throw new QuestException();
            }

            quest.ObjectiveUpdate((QuestObjectiveType)objective.Entry.Type, objective.Entry.Data, objective.Entry.Count);
        }
コード例 #5
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.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.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);
        }
コード例 #6
0
        /// <summary>
        /// Ignore or acknowledge an inactive <see cref="Quest.Quest"/>.
        /// </summary>
        public void QuestIgnore(ushort questId, bool ignored)
        {
            if (GlobalQuestManager.GetQuestInfo(questId) == null)
            {
                throw new ArgumentException($"Invalid quest {questId}!");
            }

            // TODO:
        }
コード例 #7
0
        /// <summary>
        /// Add a <see cref="Quest.Quest"/> from supplied id, optionally supplying <see cref="Item"/> which was used to start the quest.
        /// </summary>
        public void QuestAdd(ushort questId, Item item)
        {
            QuestInfo info = GlobalQuestManager.GetQuestInfo(questId);

            if (info == null)
            {
                throw new ArgumentException($"Invalid quest {questId}!");
            }

            if (DisableManager.Instance.IsDisabled(DisableType.Quest, questId))
            {
                player.SendSystemMessage($"Unable to add quest {questId} because it is disabled.");
                return;
            }

            Quest.Quest quest = GetQuest(questId);
            QuestAdd(info, quest, item);
        }
コード例 #8
0
        public async Task QuestAddCommandHandler(CommandContext context, string command, string[] parameters)
        {
            if (parameters.Length != 1 || !ushort.TryParse(parameters[0], out ushort questId))
            {
                await SendHelpAsync(context);

                return;
            }

            QuestInfo info = GlobalQuestManager.GetQuestInfo(questId);

            if (info == null)
            {
                await context.SendMessageAsync($"Quest id {questId} is invalid!");

                return;
            }

            context.Session.Player.QuestManager.QuestAdd(info);
        }
コード例 #9
0
        /// <summary>
        /// Abandon an active <see cref="Quest.Quest"/>.
        /// </summary>
        public void QuestAbandon(ushort questId)
        {
            if (GlobalQuestManager.GetQuestInfo(questId) == null)
            {
                throw new ArgumentException($"Invalid quest {questId}!");
            }

            Quest.Quest quest = GetQuest(questId, GetQuestFlags.Active | GetQuestFlags.Inactive);
            if (quest == null || quest.PendingDelete)
            {
                throw new QuestException($"Player {player.CharacterId} tried to abandon quest {questId} which they don't have!");
            }

            if (!quest.CanAbandon())
            {
                throw new QuestException($"Player {player.CharacterId} tried to abandon quest {questId} which can't be abandoned!");
            }

            if (!quest.PendingCreate)
            {
                quest.EnqueueDelete(true);
            }
            else
            {
                switch (quest.State)
                {
                case QuestState.Accepted:
                case QuestState.Achieved:
                    activeQuests.Remove(questId);
                    break;

                case QuestState.Botched:
                    inactiveQuests.Remove(quest.Id);
                    break;
                }
            }

            quest.State = QuestState.Abandoned;

            log.Trace($"Abandoned quest {questId}.");
        }
コード例 #10
0
        /// <summary>
        /// Retry an inactive <see cref="Quest.Quest"/> that was previously failed.
        /// </summary>
        public void QuestRetry(ushort questId)
        {
            QuestInfo info = GlobalQuestManager.GetQuestInfo(questId);

            if (info == null)
            {
                throw new ArgumentException($"Invalid quest {questId}!");
            }

            Quest.Quest quest = GetQuest(questId, GetQuestFlags.Inactive);
            if (quest == null)
            {
                throw new QuestException($"Player {player.CharacterId} tried to restart quest {questId} which they don't have!");
            }

            if (quest.State != QuestState.Botched)
            {
                throw new QuestException($"Player {player.CharacterId} tried to restart quest {questId} which hasn't been failed!");
            }

            QuestAdd(info, quest, null);
        }
コード例 #11
0
        /// <summary>
        /// Complete all <see cref="QuestObjective"/>'s for supplied active <see cref="Quest.Quest"/>.
        /// </summary>
        public void QuestAchieve(ushort questId)
        {
            if (GlobalQuestManager.GetQuestInfo(questId) == null)
            {
                throw new ArgumentException($"Invalid quest {questId}!");
            }

            Quest.Quest quest = GetQuest(questId);
            if (quest == null || quest.PendingDelete)
            {
                throw new QuestException($"Player {player.CharacterId} tried to achieve quest {questId} which they don't have!");
            }

            if (quest.State != QuestState.Accepted)
            {
                throw new QuestException($"Player {player.CharacterId} tried to achieve quest {questId} with invalid state!");
            }

            foreach (QuestObjectiveEntry entry in quest.Info.Objectives)
            {
                quest.ObjectiveUpdate((QuestObjectiveType)entry.Type, entry.Data, entry.Count);
            }
        }
コード例 #12
0
        private static void Main()
        {
            Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));

            Console.Title = Title;
            log.Info("Initialising...");

            ConfigurationManager <WorldServerConfiguration> .Initialise("WorldServer.json");

            DatabaseManager.Initialise(ConfigurationManager <WorldServerConfiguration> .Config.Database);

            DisableManager.Instance.Initialise();

            GameTableManager.Initialise();
            MapManager.Initialise();
            SearchManager.Initialise();
            EntityManager.Initialise();
            EntityCommandManager.Initialise();
            GlobalMovementManager.Initialise();

            AssetManager.Initialise();
            PrerequisiteManager.Initialise();
            GlobalSpellManager.Initialise();
            GlobalQuestManager.Initialise();
            ServerManager.Initialise();

            ResidenceManager.Initialise();
            GlobalStorefrontManager.Initialise();

            // make sure the assigned realm id in the configuration file exists in the database
            RealmId = ConfigurationManager <WorldServerConfiguration> .Config.RealmId;
            if (ServerManager.Servers.All(s => s.Model.Id != RealmId))
            {
                throw new ConfigurationException($"Realm id {RealmId} in configuration file doesn't exist in the database!");
            }

            MessageManager.Initialise();
            SocialManager.Initialise();
            CommandManager.Initialise();
            NetworkManager <WorldSession> .Initialise(ConfigurationManager <WorldServerConfiguration> .Config.Network);

            WorldManager.Initialise(lastTick =>
            {
                NetworkManager <WorldSession> .Update(lastTick);
                MapManager.Update(lastTick);
                ResidenceManager.Update(lastTick);
                BuybackManager.Update(lastTick);
                GlobalQuestManager.Update(lastTick);
            });

            using (WorldServerEmbeddedWebServer.Initialise())
            {
                log.Info("Ready!");

                while (true)
                {
                    Console.Write(">> ");
                    string line = Console.ReadLine();
                    if (!CommandManager.HandleCommand(new ConsoleCommandContext(), line, false))
                    {
                        Console.WriteLine("Invalid command");
                    }
                }
            }
        }
コード例 #13
0
        /// <summary>
        /// Complete an achieved <see cref="Quest.Quest"/> supplying an optional reward and whether the quest was completed from the communicator.
        /// </summary>
        public void QuestComplete(ushort questId, ushort reward, bool communicator)
        {
            if (GlobalQuestManager.GetQuestInfo(questId) == 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)
            {
                throw new QuestException($"Player {player.CharacterId} tried to complete quest {questId} which they don't have!");
            }

            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.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.NextDailyReset;
                break;

            case QuestRepeatPeriod.Weekly:
                quest.Reset = GlobalQuestManager.NextWeeklyReset;
                break;
            }

            activeQuests.Remove(questId);
            completedQuests.Add(questId, quest);
        }