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); }
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); }
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); }
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); }
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); } }
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); }); } }
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)); }
/// <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); } }
/// <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); }
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); }
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)); }
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); }
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 + ")"); }
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); }); }
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); }); }
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)); }
/// <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); }); }
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)); }
/// <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); }
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); }
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); }
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); }
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)); }
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); }
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."); }
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(); }
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)); } }