Beispiel #1
0
        public bool CanAcceptQuest(NWPlayer oPC, Quest quest, bool sendMessage)
        {
            PCQuestStatus status = _data.SingleOrDefault <PCQuestStatus>(x => x.PlayerID == oPC.GlobalID && x.QuestID == quest.ID);

            if (status != null)
            {
                if (status.CompletionDate != null)
                {
                    if (sendMessage)
                    {
                        oPC.SendMessage("You have already completed this quest.");
                    }
                    return(false);
                }
                else
                {
                    if (sendMessage)
                    {
                        oPC.SendMessage("You have already accepted this quest.");
                    }
                    return(false);
                }
            }

            if (!DoesPlayerMeetPrerequisites(oPC, quest.ID))
            {
                if (sendMessage)
                {
                    oPC.SendMessage("You do not meet the prerequisites necessary to accept this quest.");
                }
                return(false);
            }

            var questState = _data.Where <QuestState>(x => x.QuestID == quest.ID).First();

            if (!DoesPlayerHaveRequiredKeyItems(oPC, questState.ID))
            {
                if (sendMessage)
                {
                    oPC.SendMessage("You do not have the required key items to accept this quest.");
                }
                return(false);
            }

            PCRegionalFame fame = _data.SingleOrDefault <PCRegionalFame>(x => x.PlayerID == oPC.GlobalID && x.FameRegionID == quest.FameRegionID);

            if (fame != null)
            {
                if (fame.Amount < quest.RequiredFameAmount)
                {
                    if (sendMessage)
                    {
                        oPC.SendMessage("You do not have enough fame to accept this quest.");
                    }
                    return(false);
                }
            }

            return(true);
        }
Beispiel #2
0
        public void AcceptQuest(NWPlayer player, NWObject questOwner, int questID)
        {
            if (!player.IsPlayer)
            {
                return;
            }

            Quest quest = _data.Single <Quest>(x => x.ID == questID);

            if (!CanAcceptQuest(player, quest, true))
            {
                return;
            }

            var questState = _data.Single <QuestState>(x => x.QuestID == questID && x.Sequence == 1);
            var status     = new PCQuestStatus
            {
                CurrentQuestStateID = questState.ID
            };

            // Give temporary key item at start of quest.
            if (quest.StartKeyItemID != null)
            {
                _keyItem.GivePlayerKeyItem(player, (int)quest.StartKeyItemID);
            }

            if (!string.IsNullOrWhiteSpace(quest.MapNoteTag))
            {
                _mapPin.AddWaypointMapPin(player, quest.MapNoteTag, quest.Name, "QST_MAP_NOTE_" + questID);
            }

            status.QuestID  = quest.ID;
            status.PlayerID = player.GlobalID;
            _data.SubmitDataChange(status, DatabaseActionType.Insert);
            CreateExtendedQuestDataEntries(status);

            _.AddJournalQuestEntry(quest.JournalTag, 1, player.Object, FALSE);
            player.SendMessage("Quest '" + quest.Name + "' accepted. Refer to your journal for more information on this quest.");


            if (!string.IsNullOrWhiteSpace(quest.OnAcceptRule) && questOwner != null)
            {
                App.ResolveByInterface <IQuestRule>("QuestRule." + quest.OnAcceptRule, rule =>
                {
                    string[] args = null;
                    if (!string.IsNullOrWhiteSpace(quest.OnAcceptArgs))
                    {
                        args = quest.OnAcceptArgs.Split(',');
                    }
                    rule.Run(player, questOwner, questID, args);
                });
            }
        }
Beispiel #3
0
        public void AdvanceQuestState(NWPlayer player, NWObject questOwner, int questID)
        {
            if (!player.IsPlayer)
            {
                return;
            }

            PCQuestStatus questStatus = _data.SingleOrDefault <PCQuestStatus>(x => x.PlayerID == player.GlobalID && x.QuestID == questID);

            if (questStatus == null)
            {
                player.SendMessage("You have not accepted this quest yet.");
                return;
            }

            if (questStatus.CompletionDate != null)
            {
                return;
            }

            Quest      quest        = _data.Get <Quest>(questStatus.QuestID);
            QuestState currentState = _data.Get <QuestState>(questStatus.CurrentQuestStateID);
            QuestState nextState    = _data.SingleOrDefault <QuestState>(x => x.QuestID == quest.ID && x.Sequence == currentState.Sequence + 1);

            // Either complete the quest or move to the new state.
            if (nextState == null) // We assume this is the last state in the quest, so it must be time to complete it.
            {
                RequestRewardSelectionFromPC(player, questOwner, questID);
            }
            else
            {
                _.AddJournalQuestEntry(quest.JournalTag, nextState.JournalStateID, player, FALSE);
                questStatus.CurrentQuestStateID = nextState.ID;
                player.SendMessage("Objective for quest '" + quest.Name + "' complete! Check your journal for information on the next objective.");

                CreateExtendedQuestDataEntries(questStatus);
                _data.SubmitDataChange(questStatus, DatabaseActionType.Update);

                if (!string.IsNullOrWhiteSpace(quest.OnAdvanceRule) && questOwner != null)
                {
                    App.ResolveByInterface <IQuestRule>("QuestRule." + quest.OnAdvanceRule, rule =>
                    {
                        string[] args = null;
                        if (!string.IsNullOrWhiteSpace(quest.OnAdvanceArgs))
                        {
                            args = quest.OnAdvanceArgs.Split(',');
                        }
                        rule.Run(player, questOwner, questID, args);
                    });
                }
            }
        }
Beispiel #4
0
        private static void RequestRewardSelectionFromPC(NWPlayer oPC, NWObject questOwner, int questID)
        {
            if (!oPC.IsPlayer)
            {
                return;
            }

            Quest quest = DataService.Single <Quest>(x => x.ID == questID);

            if (quest.AllowRewardSelection)
            {
                oPC.SetLocalInt("QST_REWARD_SELECTION_QUEST_ID", questID);
                DialogService.StartConversation(oPC, oPC, "QuestRewardSelection");
            }
            else
            {
                CompleteQuest(oPC, questOwner, questID, null);
            }
        }
Beispiel #5
0
        public static void CompleteQuest(NWPlayer player, NWObject questOwner, int questID, ItemVO selectedItem)
        {
            if (!player.IsPlayer)
            {
                return;
            }

            Quest         quest   = DataService.Single <Quest>(x => x.ID == questID);
            PCQuestStatus pcState = DataService.Single <PCQuestStatus>(x => x.PlayerID == player.GlobalID && x.QuestID == questID);

            QuestState finalState = DataService.GetAll <QuestState>().Where(x => x.QuestID == questID).OrderBy(o => o.Sequence).Last();

            if (finalState == null)
            {
                player.SendMessage("Could not find final state of quest. Please notify an admin this quest is bugged. (QuestID: " + questID + ")");
                return;
            }

            pcState.CurrentQuestStateID = finalState.ID;
            pcState.CompletionDate      = DateTime.UtcNow;

            if (selectedItem == null)
            {
                var rewardItems = DataService.Where <QuestRewardItem>(x => x.QuestID == questID);
                foreach (QuestRewardItem reward in rewardItems)
                {
                    _.CreateItemOnObject(reward.Resref, player.Object, reward.Quantity);
                }
            }
            else
            {
                _.CreateItemOnObject(selectedItem.Resref, player.Object, selectedItem.Quantity);
            }

            if (quest.RewardGold > 0)
            {
                _.GiveGoldToCreature(player.Object, quest.RewardGold);
            }

            if (quest.RewardKeyItemID != null)
            {
                KeyItemService.GivePlayerKeyItem(player, (int)quest.RewardKeyItemID);
            }

            if (quest.RemoveStartKeyItemAfterCompletion && quest.StartKeyItemID != null)
            {
                KeyItemService.RemovePlayerKeyItem(player, (int)quest.StartKeyItemID);
            }

            if (!string.IsNullOrWhiteSpace(quest.MapNoteTag))
            {
                MapPinService.DeleteMapPin(player, "QST_MAP_NOTE_" + questID);
            }

            if (quest.RewardFame > 0)
            {
                PCRegionalFame     fame   = DataService.SingleOrDefault <PCRegionalFame>(x => x.PlayerID == player.GlobalID && x.FameRegionID == quest.FameRegionID);
                DatabaseActionType action = DatabaseActionType.Update;

                if (fame == null)
                {
                    fame = new PCRegionalFame
                    {
                        PlayerID     = player.GlobalID,
                        FameRegionID = quest.FameRegionID,
                        Amount       = 0
                    };

                    action = DatabaseActionType.Insert;
                }

                fame.Amount += quest.RewardFame;
                DataService.SubmitDataChange(fame, action);
            }

            player.SendMessage("Quest '" + quest.Name + "' complete!");
            DataService.SubmitDataChange(pcState, DatabaseActionType.Update);
            _.RemoveJournalQuestEntry(quest.JournalTag, player, FALSE);

            if (!string.IsNullOrWhiteSpace(quest.OnCompleteRule) && questOwner != null)
            {
                var rule = GetQuestRule(quest.OnCompleteRule);

                string[] args = null;
                if (!string.IsNullOrWhiteSpace(quest.OnCompleteArgs))
                {
                    args = quest.OnCompleteArgs.Split(',');
                }
                rule.Run(player, questOwner, questID, args);
            }

            MessageHub.Instance.Publish(new QuestCompletedMessage(player, questID));
        }
Beispiel #6
0
        /// <summary>
        /// Progresses a player to the next state of a quest.
        /// If they're on the last state of the quest, it will be completed for them.
        /// </summary>
        /// <param name="player">The player to advance.</param>
        /// <param name="questOwner">The quest giver object.</param>
        /// <param name="questID">The ID number of the quest.</param>
        public static void AdvanceQuestState(NWPlayer player, NWObject questOwner, int questID)
        {
            if (!player.IsPlayer)
            {
                return;
            }

            // Retrieve the player's current quest state.
            PCQuestStatus questStatus = DataService.SingleOrDefault <PCQuestStatus>(x => x.PlayerID == player.GlobalID && x.QuestID == questID);

            // Can't find a state? Notify the player they haven't accepted the quest.
            if (questStatus == null)
            {
                player.SendMessage("You have not accepted this quest yet.");
                return;
            }

            // If this quest has already been completed, exit early.
            // This is used in case a module builder incorrectly configures a quest.
            // We don't want to risk giving duplicate rewards.
            if (questStatus.CompletionDate != null)
            {
                return;
            }

            // Retrieve the quest, the current state, and the next state of the quest from the cache.
            Quest      quest        = DataService.Get <Quest>(questStatus.QuestID);
            QuestState currentState = DataService.Get <QuestState>(questStatus.CurrentQuestStateID);
            QuestState nextState    = DataService.SingleOrDefault <QuestState>(x => x.QuestID == quest.ID && x.Sequence == currentState.Sequence + 1);

            // If there's no state after this one, the assumption is that it's time to complete the quest.
            if (nextState == null)
            {
                // We'll request a reward selection from the player if the quest is configured that way.
                // Otherwise, this method will simply complete the quest outright.
                RequestRewardSelectionFromPC(player, questOwner, questID);
            }
            // We found another state to this quest. Let's advance their progress now.
            else
            {
                // Update the player's journal
                _.AddJournalQuestEntry(quest.JournalTag, nextState.JournalStateID, player, FALSE);

                // Progress player's quest status to the next state.
                questStatus.CurrentQuestStateID = nextState.ID;

                // Notify the player they've progressed.
                player.SendMessage("Objective for quest '" + quest.Name + "' complete! Check your journal for information on the next objective.");

                // Create any extended data entries for the next state of the quest.
                CreateExtendedQuestDataEntries(questStatus);

                // Submit all of these changes to the cache/DB.
                DataService.SubmitDataChange(questStatus, DatabaseActionType.Update);

                // If this quest has a custom rule configured, run that now.
                if (!string.IsNullOrWhiteSpace(quest.OnAdvanceRule) && questOwner != null)
                {
                    var rule = GetQuestRule(quest.OnAdvanceRule);

                    string[] args = null;
                    if (!string.IsNullOrWhiteSpace(quest.OnAdvanceArgs))
                    {
                        args = quest.OnAdvanceArgs.Split(',');
                    }
                    rule.Run(player, questOwner, questID, args);
                }

                // Notify subscribers we've advanced the player's quest status.
                MessageHub.Instance.Publish(new OnQuestAdvanced(player, questID, currentState.Sequence + 1));
            }
        }
Beispiel #7
0
        /// <summary>
        /// Accepts a quest for a player. This updates their journal entry and marks all necessary flags
        /// on the player.
        /// </summary>
        /// <param name="player">The player who is accepting the quest.</param>
        /// <param name="questOwner">The quest giver object.</param>
        /// <param name="questID">The ID number of the quest to accept.</param>
        public static void AcceptQuest(NWPlayer player, NWObject questOwner, int questID)
        {
            if (!player.IsPlayer)
            {
                return;
            }

            // Retrieve quest from the cache.
            Quest quest = DataService.Single <Quest>(x => x.ID == questID);

            // Check whether player can accept the quest. Send a message if they can't.
            if (!CanAcceptQuest(player, quest, true))
            {
                return;
            }

            // By this point, it's assumed the player will accept the quest.
            // However, if this quest is repeatable we must first update the existing entry.
            var status = DataService.SingleOrDefault <PCQuestStatus>(x => x.QuestID == questID &&
                                                                     x.PlayerID == player.GlobalID);
            bool foundExisting = status != null;

            // Didn't find an existing state so we'll create a new object.
            if (status == null)
            {
                status = new PCQuestStatus();
            }
            else
            {
                status.CompletionDate = null;
            }

            // Retrieve the first quest state for this quest.
            var questState = DataService.Single <QuestState>(x => x.QuestID == questID && x.Sequence == 1);

            status.CurrentQuestStateID = questState.ID;

            // Give temporary key item at start of quest.
            if (quest.StartKeyItemID != null)
            {
                KeyItemService.GivePlayerKeyItem(player, (int)quest.StartKeyItemID);
            }

            // Add a map pin if specified by the quest.
            if (!string.IsNullOrWhiteSpace(quest.MapNoteTag))
            {
                MapPinService.AddWaypointMapPin(player, quest.MapNoteTag, quest.Name, "QST_MAP_NOTE_" + questID);
            }

            status.QuestID  = quest.ID;
            status.PlayerID = player.GlobalID;

            // Insert or update player's quest status.
            DataService.SubmitDataChange(status, foundExisting ? DatabaseActionType.Update : DatabaseActionType.Insert);

            // Create extended quest entries, if necessary.
            CreateExtendedQuestDataEntries(status);

            // Add the journal entry to the player.
            _.AddJournalQuestEntry(quest.JournalTag, 1, player.Object, FALSE);

            // Notify them that they've accepted a quest.
            player.SendMessage("Quest '" + quest.Name + "' accepted. Refer to your journal for more information on this quest.");

            // If this quest runs any custom rules, do those now.
            if (!string.IsNullOrWhiteSpace(quest.OnAcceptRule) && questOwner != null)
            {
                var rule = GetQuestRule(quest.OnAcceptRule);

                string[] args = null;
                if (!string.IsNullOrWhiteSpace(quest.OnAcceptArgs))
                {
                    args = quest.OnAcceptArgs.Split(',');
                }
                rule.Run(player, questOwner, questID, args);
            }

            // Notify to subscribers that a quest has just been accepted.
            MessageHub.Instance.Publish(new OnQuestAccepted(player, questID));
        }
Beispiel #8
0
        /// <summary>
        /// Returns true if player can accept a quest with the given ID.
        /// Returns false if player cannot accept the quest.
        /// </summary>
        /// <param name="oPC">The player to check</param>
        /// <param name="quest">The quest to check.</param>
        /// <param name="sendMessage">If true, a message will be sent to player about why they can't accept the quest.</param>
        /// <returns>true if player can accept quest. false otherwise.</returns>
        public static bool CanAcceptQuest(NWPlayer oPC, Quest quest, bool sendMessage)
        {
            // Retrieve the player's current quest status for this quest.
            // If they haven't accepted it yet, this will be null.
            PCQuestStatus status = DataService.SingleOrDefault <PCQuestStatus>(x => x.PlayerID == oPC.GlobalID &&
                                                                               x.QuestID == quest.ID);

            // If the status is null, it's assumed that the player hasn't accepted it yet.
            if (status != null)
            {
                // If the quest isn't repeatable, prevent the player from accepting it after it's already been completed.
                if (status.CompletionDate != null)
                {
                    // If it's repeatable, then we don't care if they've already completed it.
                    if (!quest.IsRepeatable)
                    {
                        if (sendMessage)
                        {
                            oPC.SendMessage("You have already completed this quest.");
                        }
                        return(false);
                    }
                }
                // If the player already accepted the quest, prevent them from accepting it again.
                else
                {
                    if (sendMessage)
                    {
                        oPC.SendMessage("You have already accepted this quest.");
                    }
                    return(false);
                }
            }

            // Check whether the player meets all necessary prerequisites.
            if (!DoesPlayerMeetPrerequisites(oPC, quest.ID))
            {
                if (sendMessage)
                {
                    oPC.SendMessage("You do not meet the prerequisites necessary to accept this quest.");
                }
                return(false);
            }

            // Retrieve the first state of the quest.
            var questState = DataService.Where <QuestState>(x => x.QuestID == quest.ID).First();

            // If this quest requires key items, ensure player has acquired them.
            if (!DoesPlayerHaveRequiredKeyItems(oPC, questState.ID))
            {
                if (sendMessage)
                {
                    oPC.SendMessage("You do not have the required key items to accept this quest.");
                }
                return(false);
            }

            // Retrieve the player's fame information. Treat a missing record as having 0 fame for this region.
            PCRegionalFame fame       = DataService.SingleOrDefault <PCRegionalFame>(x => x.PlayerID == oPC.GlobalID && x.FameRegionID == quest.FameRegionID);
            int            fameAmount = fame == null ? 0 : fame.Amount;

            // Ensure player has necessary fame for accepting this quest.
            if (fameAmount < quest.RequiredFameAmount)
            {
                if (sendMessage)
                {
                    oPC.SendMessage("You do not have enough fame to accept this quest.");
                }
                return(false);
            }

            return(true);
        }