Пример #1
0
        public static void SpawnQuestItems(NWPlaceable oChest, NWPlayer oPC)
        {
            int    questID            = oChest.GetLocalInt("QUEST_ID");
            int    questStateSequence = oChest.GetLocalInt("QUEST_SEQUENCE");
            string questItemResref    = oChest.GetLocalString("QUEST_ITEM_RESREF");

            if (questID <= 0 || questStateSequence <= 0 || string.IsNullOrWhiteSpace(questItemResref))
            {
                return;
            }

            PCQuestStatus status     = DataService.Single <PCQuestStatus>(x => x.PlayerID == oPC.GlobalID && x.QuestID == questID);
            QuestState    questState = DataService.Get <QuestState>(status.CurrentQuestStateID);

            if (questStateSequence != questState.Sequence)
            {
                return;
            }
            if (_.GetIsObjectValid(_.GetItemPossessedBy(oPC.Object, questItemResref)) == FALSE)
            {
                return;
            }

            // PC is on the correct quest, correct state, the chest creates quest items, and the PC does not already have the quest item.
            // Spawn it.

            _.CreateItemOnObject(questItemResref, oChest.Object);
        }
Пример #2
0
        public bool Run(params object[] args)
        {
            NWPlaceable container = Object.OBJECT_SELF;

            container.IsUseable = false;

            NWPlayer      oPC     = (_.GetLastOpenedBy());
            int           questID = container.GetLocalInt("QUEST_ID");
            PCQuestStatus status  = DataService.Single <PCQuestStatus>(x => x.PlayerID == oPC.GlobalID && x.QuestID == questID);

            oPC.FloatingText("Please place the items you would like to turn in for this quest into the container. If you want to cancel this process, move away from the container.");

            string text = "Required Items: \n\n";

            var itemProgress = DataService.Where <PCQuestItemProgress>(x => x.PCQuestStatusID == status.ID);

            foreach (PCQuestItemProgress item in itemProgress)
            {
                ItemVO tempItemModel = QuestService.GetTempItemInformation(item.Resref, item.Remaining);
                text += tempItemModel.Quantity + "x " + tempItemModel.Name + "\n";
            }

            oPC.SendMessage(text);
            return(true);
        }
Пример #3
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);
        }
Пример #4
0
        public int GetPlayerQuestJournalID(NWObject oPC, int questID)
        {
            PCQuestStatus status = _db.PCQuestStatus.Single(x => x.PlayerID == oPC.GlobalID && x.QuestID == questID);

            if (status == null)
            {
                return(-1);
            }
            return(status.CurrentQuestState.JournalStateID);
        }
Пример #5
0
        private static void HandleTriggerAndPlaceableQuestLogic(NWPlayer oPC, NWObject oObject)
        {
            if (!oPC.IsPlayer)
            {
                return;
            }
            string questMessage       = oObject.GetLocalString("QUEST_MESSAGE");
            int    questID            = oObject.GetLocalInt("QUEST_ID");
            int    questSequence      = oObject.GetLocalInt("QUEST_SEQUENCE");
            string visibilityObjectID = oObject.GetLocalString("VISIBILITY_OBJECT_ID");

            if (questID <= 0)
            {
                oPC.SendMessage("QUEST_ID variable not set on object. Please inform admin this quest is bugged. (QuestID: " + questID + ")");
                return;
            }

            if (questSequence <= 0)
            {
                oPC.SendMessage("QUEST_SEQUENCE variable not set on object. Please inform admin this quest is bugged. (QuestID: " + questID + ")");
                return;
            }

            PCQuestStatus pcQuestStatus = DataService.SingleOrDefault <PCQuestStatus>(x => x.PlayerID == oPC.GlobalID && x.QuestID == questID);

            if (pcQuestStatus == null)
            {
                return;
            }

            QuestState questState = DataService.Get <QuestState>(pcQuestStatus.CurrentQuestStateID);

            if (questState.Sequence != questSequence ||
                (questState.QuestTypeID != (int)QuestType.UseObject &&
                 questState.QuestTypeID != (int)QuestType.ExploreArea))
            {
                return;
            }


            if (!string.IsNullOrWhiteSpace(questMessage))
            {
                _.DelayCommand(1.0f, () =>
                {
                    oPC.SendMessage(questMessage);
                });
            }

            AdvanceQuestState(oPC, oObject, questID);

            if (!string.IsNullOrWhiteSpace(visibilityObjectID))
            {
                ObjectVisibilityService.AdjustVisibility(oPC, oObject, false);
            }
        }
Пример #6
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);
                });
            }
        }
Пример #7
0
        public void Accept(NWPlayer player, NWObject questSource)
        {
            if (!player.IsPlayer)
            {
                return;
            }

            if (!CanAccept(player))
            {
                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.PCQuestStatus.GetByPlayerAndQuestIDOrDefault(player.GlobalID, QuestID);
            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.
            status.QuestState = 1;
            status.QuestID    = QuestID;
            status.PlayerID   = player.GlobalID;

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

            var state = GetState(1);

            foreach (var objective in state.GetObjectives())
            {
                objective.Initialize(player, QuestID);
            }

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

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

            // Run any quest-specific code.
            _onAccept?.Invoke(player, questSource);

            // Notify to subscribers that a quest has just been accepted.
            MessageHub.Instance.Publish(new OnQuestAccepted(player, QuestID));
        }
Пример #8
0
        /// <summary>
        /// Progresses a player to the next state if they meet all requirements to do so.
        /// </summary>
        /// <param name="player">The player object</param>
        /// <param name="trigger">The trigger or placeable being used/entered.</param>
        private static void HandleTriggerAndPlaceableQuestLogic(NWPlayer player, NWObject trigger)
        {
            if (!player.IsPlayer)
            {
                return;
            }
            string questMessage       = trigger.GetLocalString("QUEST_MESSAGE");
            int    questID            = trigger.GetLocalInt("QUEST_ID");
            int    questState         = trigger.GetLocalInt("QUEST_STATE");
            string visibilityObjectID = trigger.GetLocalString("VISIBILITY_OBJECT_ID");

            if (questID <= 0)
            {
                player.SendMessage("QUEST_ID variable not set on object. Please inform admin this quest is bugged. (QuestID: " + questID + ")");
                return;
            }

            if (questState <= 0)
            {
                player.SendMessage("QUEST_STATE variable not set on object. Please inform admin this quest is bugged. (QuestID: " + questID + ")");
                return;
            }

            PCQuestStatus pcQuestStatus = DataService.PCQuestStatus.GetByPlayerAndQuestIDOrDefault(player.GlobalID, questID);

            if (pcQuestStatus == null)
            {
                return;
            }


            if (pcQuestStatus.QuestState != questState)
            {
                return;
            }

            if (!string.IsNullOrWhiteSpace(questMessage))
            {
                DelayCommand(1.0f, () =>
                {
                    player.SendMessage(questMessage);
                });
            }

            var quest = GetQuestByID(questID);

            quest.Advance(player, trigger);

            if (!string.IsNullOrWhiteSpace(visibilityObjectID))
            {
                ObjectVisibilityService.AdjustVisibility(player, trigger, false);
            }
        }
Пример #9
0
        /// <summary>
        /// Get the journal state ID number for the current quest state the player is on.
        /// </summary>
        /// <param name="oPC">The player object</param>
        /// <param name="questID">The ID number of the quest</param>
        /// <returns>The ID number of the journal entry</returns>
        public static int GetPlayerQuestJournalID(NWObject oPC, int questID)
        {
            PCQuestStatus status = DataService.PCQuestStatus.GetByPlayerAndQuestID(oPC.GlobalID, questID);

            if (status == null)
            {
                return(-1);
            }
            var state = DataService.QuestState.GetByID(status.CurrentQuestStateID);

            return(state.JournalStateID);
        }
Пример #10
0
        public static int GetPlayerQuestJournalID(NWObject oPC, int questID)
        {
            PCQuestStatus status = DataService.Single <PCQuestStatus>(x => x.PlayerID == oPC.GlobalID && x.QuestID == questID);

            if (status == null)
            {
                return(-1);
            }
            var state = DataService.Get <QuestState>(status.CurrentQuestStateID);

            return(state.JournalStateID);
        }
Пример #11
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);
                    });
                }
            }
        }
        public void GetByID_OneItem_ReturnsPCQuestStatus()
        {
            // Arrange
            var           id     = Guid.NewGuid();
            PCQuestStatus entity = new PCQuestStatus {
                ID = id
            };

            // Act
            MessageHub.Instance.Publish(new OnCacheObjectSet <PCQuestStatus>(entity));

            // Assert
            Assert.AreNotSame(entity, _cache.GetByID(id));
        }
Пример #13
0
        private void HandleTriggerAndPlaceableQuestLogic(NWPlayer oPC, NWObject oObject)
        {
            if (!oPC.IsPlayer)
            {
                return;
            }
            string questMessage  = oObject.GetLocalString("QUEST_MESSAGE");
            int    questID       = oObject.GetLocalInt("QUEST_ID");
            int    questSequence = oObject.GetLocalInt("QUEST_SEQUENCE");

            if (questID <= 0)
            {
                oPC.SendMessage("QUEST_ID variable not set on object. Please inform admin this quest is bugged.");
                return;
            }

            if (questSequence <= 0)
            {
                oPC.SendMessage("QUEST_SEQUENCE variable not set on object. Please inform admin this quest is bugged. (QuestID: " + questID + ")");
                return;
            }

            PCQuestStatus pcQuestStatus = _db.PCQuestStatus.Single(x => x.PlayerID == oPC.GlobalID && x.QuestID == questID);

            if (pcQuestStatus == null)
            {
                return;
            }

            QuestState questState = pcQuestStatus.CurrentQuestState;

            if (questState.Sequence == questSequence ||
                (questState.QuestTypeID != (int)QuestType.UseObject &&
                 questState.QuestTypeID != (int)QuestType.ExploreArea))
            {
                return;
            }


            if (!string.IsNullOrWhiteSpace(questMessage))
            {
                oPC.DelayCommand(() =>
                {
                    oPC.SendMessage(questMessage);
                }, 1.0f);
            }

            AdvanceQuestState(oPC, questID);
        }
Пример #14
0
        public void AdvanceQuestState(NWPlayer oPC, int questID)
        {
            if (!oPC.IsPlayer)
            {
                return;
            }

            PCQuestStatus questStatus = _db.PCQuestStatus.Single(x => x.PlayerID == oPC.GlobalID && x.QuestID == questID);

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

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

            Quest quest = questStatus.Quest;

            // Find the next quest state.
            foreach (QuestState nextState in quest.QuestStates)
            {
                if (nextState.Sequence == questStatus.CurrentQuestState.Sequence + 1)
                {
                    // Either complete the quest or move to the new state.
                    if (nextState.IsFinalState)
                    {
                        RequestRewardSelectionFromPC(oPC, questID);
                        return;
                    }
                    else
                    {
                        _.AddJournalQuestEntry(quest.JournalTag, nextState.JournalStateID, oPC.Object, FALSE);
                        questStatus.CurrentQuestStateID = nextState.QuestStateID;
                        oPC.SendMessage("Objective for quest '" + quest.Name + "' complete! Check your journal for information on the next objective.");
                        _db.SaveChanges();

                        CreateExtendedQuestDataEntries(questStatus, questID, nextState.Sequence);
                        return;
                    }
                }
            }

            // Shouldn't reach this point unless configuration for the quest is broken.
            oPC.SendMessage("There was an error advancing you to the next objective for quest '" + quest.Name + "'. Please inform an admin this quest is bugged. (QuestID = " + questID + ")");
        }
Пример #15
0
        public static void RequestItemsFromPC(NWPlayer oPC, NWObject questOwner, int questID)
        {
            if (!oPC.IsPlayer)
            {
                return;
            }

            PCQuestStatus pcStatus = DataService.SingleOrDefault <PCQuestStatus>(x => x.PlayerID == oPC.GlobalID && x.QuestID == questID);

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

            QuestState questState       = DataService.Get <QuestState>(pcStatus.CurrentQuestStateID);
            var        requiredKeyItems = DataService.Where <QuestRequiredKeyItem>(x => x.QuestStateID == pcStatus.CurrentQuestStateID);

            foreach (QuestRequiredKeyItem ki in requiredKeyItems)
            {
                if (!KeyItemService.PlayerHasKeyItem(oPC, ki.KeyItemID))
                {
                    oPC.SendMessage("You are missing a required key item.");
                    return;
                }
            }

            if (questState.QuestTypeID != (int)QuestType.CollectItems)
            {
                oPC.SendMessage("The quest state you are currently on is not configured to collect items. Please inform an admin of this issue. (QuestID: " + questID + ")");
                return;
            }

            Location    location  = oPC.Location;
            NWPlaceable collector = (_.CreateObject(OBJECT_TYPE_PLACEABLE, "qst_item_collect", location));

            collector.SetLocalObject("QUEST_OWNER", questOwner);

            collector.AssignCommand(() =>
            {
                _.SetFacingPoint(oPC.Position);
            });
            collector.SetLocalInt("QUEST_ID", questID);

            oPC.AssignCommand(() =>
            {
                _.ActionInteractObject(collector.Object);
            });
        }
Пример #16
0
        public void RequestItemsFromPC(NWPlayer oPC, NWObject questOwner, int questID, int sequenceID)
        {
            if (!oPC.IsPlayer)
            {
                return;
            }

            PCQuestStatus pcStatus = _db.PCQuestStatus.Single(x => x.PlayerID == oPC.GlobalID && x.QuestID == questID);

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

            QuestState questState = pcStatus.CurrentQuestState;

            if (questState.Sequence != sequenceID)
            {
                oPC.SendMessage("SequenceID mismatch. Please inform an admin there is a bug with this quest. (QuestID = " + questID + ")");
                return;
            }

            foreach (QuestRequiredKeyItemList ki in questState.QuestRequiredKeyItemLists)
            {
                if (!_keyItem.PlayerHasKeyItem(oPC, ki.KeyItemID))
                {
                    oPC.SendMessage("You are missing a required key item.");
                    return;
                }
            }

            Location    location  = oPC.Location;
            NWPlaceable collector = NWPlaceable.Wrap(_.CreateObject(OBJECT_TYPE_PLACEABLE, "qst_item_collect", location));

            collector.AssignCommand(() =>
            {
                _.SetFacingPoint(oPC.Position);
            });
            collector.SetLocalInt("QUEST_ID", questID);
            _.CreateItemOnObject(SubmitQuestItemResref, collector.Object);

            oPC.AssignCommand(() =>
            {
                _.ActionInteractObject(collector.Object);
            });
        }
Пример #17
0
        public void Complete(NWPlayer player, NWObject questSource, IQuestReward selectedReward)
        {
            if (!player.IsPlayer)
            {
                return;
            }
            if (!CanComplete(player))
            {
                return;
            }

            PCQuestStatus pcState = DataService.PCQuestStatus.GetByPlayerAndQuestID(player.GlobalID, QuestID);

            // Mark player as being on the last state of the quest.
            pcState.QuestState     = GetStates().Count();
            pcState.CompletionDate = DateTime.UtcNow;
            pcState.TimesCompleted++;

            // No selected reward, simply give all available rewards to the player.
            if (selectedReward == null)
            {
                foreach (var reward in Rewards)
                {
                    reward.GiveReward(player);
                }
            }
            // There is a selected reward. Give that reward and any rewards which are not selectable to the player.
            else
            {
                // Non-selectable rewards (gold, GP, etc) are granted to the player.
                foreach (var reward in Rewards.Where(x => !x.IsSelectable))
                {
                    reward.GiveReward(player);
                }

                selectedReward.GiveReward(player);
            }

            DataService.SubmitDataChange(pcState, DatabaseActionType.Update);
            _onComplete?.Invoke(player, questSource);

            player.SendMessage("Quest '" + Name + "' complete!");
            RemoveJournalQuestEntry(JournalTag, player, false);
            MessageHub.Instance.Publish(new OnQuestCompleted(player, QuestID));
        }
Пример #18
0
        /// <summary>
        /// Spawns a container and forces a player to open it. They are then instructed to insert any
        /// quest items inside.
        /// </summary>
        /// <param name="oPC">The player we're requesting items from.</param>
        /// <param name="questOwner">The quest giver object</param>
        /// <param name="questID">The ID number of the quest</param>
        public static void RequestItemsFromPC(NWPlayer oPC, NWObject questOwner, int questID)
        {
            if (!oPC.IsPlayer)
            {
                return;
            }

            PCQuestStatus pcStatus = DataService.PCQuestStatus.GetByPlayerAndQuestIDOrDefault(oPC.GlobalID, questID);

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

            var quest      = GetQuestByID(questID);
            var questState = quest.GetState(pcStatus.QuestState);
            var collectKeyItemObjectives = questState.GetObjectives().Where(x => x.GetType() == typeof(CollectKeyItemObjective)).Cast <CollectKeyItemObjective>();

            foreach (var ki in collectKeyItemObjectives)
            {
                if (!KeyItemService.PlayerHasKeyItem(oPC, ki.KeyItemID))
                {
                    oPC.SendMessage("You are missing a required key item.");
                    return;
                }
            }

            Location    location  = oPC.Location;
            NWPlaceable collector = CreateObject(ObjectType.Placeable, "qst_item_collect", location);

            collector.SetLocalObject("QUEST_OWNER", questOwner);

            collector.AssignCommand(() =>
            {
                SetFacingPoint(oPC.Position);
            });
            collector.SetLocalInt("QUEST_ID", questID);

            oPC.AssignCommand(() =>
            {
                ActionInteractObject(collector.Object);
            });
        }
Пример #19
0
        private void CreateExtendedQuestDataEntries(PCQuestStatus status, int questID, int sequenceID)
        {
            // Create entries for the PC kill targets.
            List <QuestKillTargetList> killTargets = _db.StoredProcedure <QuestKillTargetList>("GetQuestKillTargetsByQuestSequenceID",
                                                                                               new SqlParameter("QuestID", questID),
                                                                                               new SqlParameter("SequenceID", sequenceID));

            foreach (QuestKillTargetList kt in killTargets)
            {
                PCQuestKillTargetProgress pcKT = new PCQuestKillTargetProgress
                {
                    RemainingToKill = kt.Quantity,
                    NPCGroupID      = kt.NPCGroupID,
                    PCQuestStatusID = status.PCQuestStatusID,
                    PlayerID        = status.PlayerID
                };
                _db.PCQuestKillTargetProgresses.Add(pcKT);
                _db.SaveChanges();
            }
        }
        public void GetByID_TwoItems_ReturnsCorrectObject()
        {
            // Arrange
            var           id1     = Guid.NewGuid();
            var           id2     = Guid.NewGuid();
            PCQuestStatus entity1 = new PCQuestStatus {
                ID = id1
            };
            PCQuestStatus entity2 = new PCQuestStatus {
                ID = id2
            };

            // Act
            MessageHub.Instance.Publish(new OnCacheObjectSet <PCQuestStatus>(entity1));
            MessageHub.Instance.Publish(new OnCacheObjectSet <PCQuestStatus>(entity2));

            // Assert
            Assert.AreNotSame(entity1, _cache.GetByID(id1));
            Assert.AreNotSame(entity2, _cache.GetByID(id2));
        }
        public void GetByID_RemovedItem_ReturnsCorrectObject()
        {
            // Arrange
            var           id1     = Guid.NewGuid();
            var           id2     = Guid.NewGuid();
            PCQuestStatus entity1 = new PCQuestStatus {
                ID = id1
            };
            PCQuestStatus entity2 = new PCQuestStatus {
                ID = id2
            };

            // Act
            MessageHub.Instance.Publish(new OnCacheObjectSet <PCQuestStatus>(entity1));
            MessageHub.Instance.Publish(new OnCacheObjectSet <PCQuestStatus>(entity2));
            MessageHub.Instance.Publish(new OnCacheObjectDeleted <PCQuestStatus>(entity1));

            // Assert
            Assert.Throws <KeyNotFoundException>(() => { _cache.GetByID(id1); });
            Assert.AreNotSame(entity2, _cache.GetByID(id2));
        }
Пример #22
0
        /// <summary>
        /// Quests which require items, kill targets, etc. all need to have their entries added for this player's
        /// quest progress. This method handles that.
        /// </summary>
        /// <param name="status"></param>
        private static void CreateExtendedQuestDataEntries(PCQuestStatus status)
        {
            // Retrieve the quest and state information from the cache.
            var quest = DataService.Get <Quest>(status.QuestID);
            var state = DataService.Single <QuestState>(x => x.QuestID == quest.ID && x.ID == status.CurrentQuestStateID);

            // Retrieve the kill targets and required items necessary for this quest state.
            var killTargets   = DataService.Where <QuestKillTarget>(x => x.QuestStateID == state.ID);
            var requiredItems = DataService.Where <QuestRequiredItem>(x => x.QuestStateID == state.ID);

            // Create entries for the PC kill targets.
            foreach (var kt in killTargets)
            {
                PCQuestKillTargetProgress pcKT = new PCQuestKillTargetProgress
                {
                    RemainingToKill = kt.Quantity,
                    NPCGroupID      = kt.NPCGroupID,
                    PCQuestStatusID = status.ID,
                    PlayerID        = status.PlayerID
                };
                DataService.SubmitDataChange(pcKT, DatabaseActionType.Insert);
            }

            // Create entries for PC items required.
            foreach (var item in requiredItems)
            {
                PCQuestItemProgress itemProgress = new PCQuestItemProgress
                {
                    Resref                = item.Resref,
                    PlayerID              = status.PlayerID,
                    PCQuestStatusID       = status.ID,
                    Remaining             = item.Quantity,
                    MustBeCraftedByPlayer = item.MustBeCraftedByPlayer
                };
                DataService.SubmitDataChange(itemProgress, DatabaseActionType.Insert);
            }

            // Submit changes to the cache/DB.
            DataService.SubmitDataChange(status, DatabaseActionType.Update);
        }
Пример #23
0
        public bool CanAccept(NWPlayer player)
        {
            // Retrieve the player's current quest status for this quest.
            // If they haven't accepted it yet, this will be null.
            PCQuestStatus status = DataService.PCQuestStatus.GetByPlayerAndQuestIDOrDefault(player.GlobalID, QuestID);

            // 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 (!_repeatable)
                    {
                        player.SendMessage("You have already completed this quest.");
                        return(false);
                    }
                }
                // If the player already accepted the quest, prevent them from accepting it again.
                else
                {
                    player.SendMessage("You have already accepted this quest.");
                    return(false);
                }
            }

            // Check whether the player meets all necessary prerequisites.
            foreach (var prereq in Prerequisites)
            {
                if (!prereq.MeetsPrerequisite(player))
                {
                    player.SendMessage("You do not meet the prerequisites necessary to accept this quest.");
                    return(false);
                }
            }

            return(true);
        }
Пример #24
0
        public void Main()
        {
            NWPlaceable container = _.OBJECT_SELF;

            container.IsUseable = false;

            NWPlayer      oPC     = (_.GetLastOpenedBy());
            int           questID = container.GetLocalInt("QUEST_ID");
            PCQuestStatus status  = DataService.PCQuestStatus.GetByPlayerAndQuestID(oPC.GlobalID, questID);

            oPC.FloatingText("Please place the items you would like to turn in for this quest into the container. If you want to cancel this process, move away from the container.");

            string text = "Required Items: \n\n";

            var itemProgress = DataService.PCQuestItemProgress.GetAllByPCQuestStatusID(status.ID);

            foreach (PCQuestItemProgress item in itemProgress)
            {
                ItemVO tempItemModel = QuestService.GetTempItemInformation(item.Resref, item.Remaining);
                text += tempItemModel.Quantity + "x " + tempItemModel.Name + "\n";
            }

            oPC.SendMessage(text);
        }
Пример #25
0
        private void CreateExtendedQuestDataEntries(PCQuestStatus status)
        {
            var quest         = _data.Get <Quest>(status.QuestID);
            var state         = _data.Single <QuestState>(x => x.QuestID == quest.ID && x.ID == status.CurrentQuestStateID);
            var killTargets   = _data.Where <QuestKillTarget>(x => x.QuestStateID == state.ID);
            var requiredItems = _data.Where <QuestRequiredItem>(x => x.QuestStateID == state.ID);

            // Create entries for the PC kill targets.
            foreach (var kt in killTargets)
            {
                PCQuestKillTargetProgress pcKT = new PCQuestKillTargetProgress
                {
                    RemainingToKill = kt.Quantity,
                    NPCGroupID      = kt.NPCGroupID,
                    PCQuestStatusID = status.ID,
                    PlayerID        = status.PlayerID
                };
                _data.SubmitDataChange(pcKT, DatabaseActionType.Insert);
            }

            // Create entries for PC items required.
            foreach (var item in requiredItems)
            {
                PCQuestItemProgress itemProgress = new PCQuestItemProgress
                {
                    Resref                = item.Resref,
                    PlayerID              = status.PlayerID,
                    PCQuestStatusID       = status.ID,
                    Remaining             = item.Quantity,
                    MustBeCraftedByPlayer = item.MustBeCraftedByPlayer
                };
                _data.SubmitDataChange(itemProgress, DatabaseActionType.Insert);
            }

            _data.SubmitDataChange(status, DatabaseActionType.Update);
        }
Пример #26
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));
        }
Пример #27
0
        public static bool HasPlayerCompletedQuest(NWObject oPC, int questID)
        {
            PCQuestStatus status = DataService.Single <PCQuestStatus>(x => x.PlayerID == oPC.GlobalID && x.QuestID == questID);

            return(status?.CompletionDate != null);
        }
Пример #28
0
        public void AcceptQuest(NWPlayer oPC, int questID)
        {
            if (!oPC.IsPlayer)
            {
                return;
            }

            PCQuestStatus status = _db.PCQuestStatus.Single(x => x.PlayerID == oPC.GlobalID && x.QuestID == questID);

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


            Quest quest = _db.Quests.Single(x => x.QuestID == questID);

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

            if (!DoesPlayerHaveRequiredKeyItems(oPC, quest.QuestStates.ElementAt(0).QuestRequiredKeyItemLists))
            {
                oPC.SendMessage("You do not have the required key items to accept this quest.");
                return;
            }

            PCRegionalFame fame = _db.PCRegionalFames.Single(x => x.PlayerID == oPC.GlobalID && x.FameRegionID == quest.FameRegionID);

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

            status = new PCQuestStatus();
            foreach (QuestState state in quest.QuestStates)
            {
                if (state.Sequence == 1)
                {
                    status.CurrentQuestStateID = state.QuestStateID;
                    break;
                }
            }

            if (status.CurrentQuestState == null)
            {
                oPC.SendMessage("There was an error accepting the quest '" + quest.Name + "'. Please inform an admin this quest is bugged. (QuestID: " + questID + ")");
                return;
            }

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

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

            status.QuestID  = quest.QuestID;
            status.PlayerID = oPC.GlobalID;
            _db.PCQuestStatus.Add(status);
            _db.SaveChanges();

            CreateExtendedQuestDataEntries(status, questID, 1);

            _.AddJournalQuestEntry(quest.JournalTag, 1, oPC.Object, FALSE);
            oPC.SendMessage("Quest '" + quest.Name + "' accepted. Refer to your journal for more information on this quest.");
        }
Пример #29
0
        public void CompleteQuest(NWPlayer player, int questID, ItemVO selectedItem)
        {
            if (!player.IsPlayer)
            {
                return;
            }

            Quest         quest   = _db.Quests.Single(x => x.QuestID == questID);
            PCQuestStatus pcState = _db.PCQuestStatus.Single(x => x.PlayerID == player.GlobalID && x.QuestID == questID);

            QuestState finalState = null;

            foreach (QuestState questState in quest.QuestStates)
            {
                if (questState.IsFinalState)
                {
                    finalState = questState;
                    break;
                }
            }

            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.QuestStateID;
            pcState.CompletionDate      = DateTime.UtcNow;

            if (selectedItem == null)
            {
                foreach (QuestRewardItem reward in quest.QuestRewardItems)
                {
                    _.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.RewardXP > 0)
            {
                // TODO: Skill-related exp rewards??
            }

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

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

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

            if (quest.RewardFame > 0)
            {
                PCRegionalFame fame = _db.PCRegionalFames.Single(x => x.PlayerID == player.GlobalID && x.FameRegionID == quest.FameRegionID);
                fame.Amount += quest.RewardFame;
            }

            player.SendMessage("Quest '" + quest.Name + "' complete!");
            _db.SaveChanges();
        }
Пример #30
0
        public void Advance(NWPlayer player, NWObject questSource)
        {
            if (!player.IsPlayer)
            {
                return;
            }

            // Retrieve the player's current quest state.
            PCQuestStatus questStatus = DataService.PCQuestStatus.GetByPlayerAndQuestIDOrDefault(player.GlobalID, 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;
            }

            var currentState = GetState(questStatus.QuestState);
            var lastState    = GetStates().Last();

            // If this is the last state, the assumption is that it's time to complete the quest.
            if (currentState == lastState)
            {
                RequestRewardSelectionFromPC(player, questSource);
            }
            else
            {
                // Progress player's quest status to the next state.
                questStatus.QuestState++;
                var nextState = GetState(questStatus.QuestState);

                // Update the player's journal
                AddJournalQuestEntry(JournalTag, questStatus.QuestState, player, false);

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

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

                // Create any extended data entries for the next state of the quest.
                foreach (var objective in nextState.GetObjectives())
                {
                    objective.Initialize(player, QuestID);
                }

                // Run any quest-specific code.
                _onAdvance?.Invoke(player, questSource, questStatus.QuestState);

                // Notify to subscribers that the player has advanced to the next state of the quest.
                MessageHub.Instance.Publish(new OnQuestAdvanced(player, QuestID, questStatus.QuestState));
            }
        }