public static void AcceptQuest(NWPlayer player, NWObject questOwner, int questID) { if (!player.IsPlayer) { return; } Quest quest = DataService.Single <Quest>(x => x.ID == questID); if (!CanAcceptQuest(player, quest, true)) { return; } var questState = DataService.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) { KeyItemService.GivePlayerKeyItem(player, (int)quest.StartKeyItemID); } if (!string.IsNullOrWhiteSpace(quest.MapNoteTag)) { MapPinService.AddWaypointMapPin(player, quest.MapNoteTag, quest.Name, "QST_MAP_NOTE_" + questID); } status.QuestID = quest.ID; status.PlayerID = player.GlobalID; DataService.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) { var rule = GetQuestRule(quest.OnAcceptRule); string[] args = null; if (!string.IsNullOrWhiteSpace(quest.OnAcceptArgs)) { args = quest.OnAcceptArgs.Split(','); } rule.Run(player, questOwner, questID, args); } }
/// <summary> /// Determines whether a player has finished all requirements for a quest. /// Requirements: /// - Player must be on the last quest state /// - Player must have no remaining kill targets /// - Player must have no remaining required items /// - Player must have no remaining required key items /// </summary> /// <param name="player">The player we're checking</param> /// <param name="questID">The ID number of the quest.</param> /// <returns>true if player can complete a quest, false otherwise.</returns> public static bool CanPlayerCompleteQuest(NWPlayer player, int questID) { // Has the player even accepted this quest? var pcStatus = DataService.SingleOrDefault <PCQuestStatus>(x => x.PlayerID == player.GlobalID && x.QuestID == questID); if (pcStatus == null) { return(false); } // Is the player on the final state of this quest? var finalState = DataService.GetAll <QuestState>().Where(x => x.QuestID == questID).OrderBy(o => o.Sequence).Last(); if (pcStatus.CurrentQuestStateID != finalState.ID) { return(false); } // Are there any remaining kill targets for this quest and player? var killTargetCount = DataService.Where <PCQuestKillTargetProgress>(x => x.PlayerID == player.GlobalID && x.PCQuestStatusID == pcStatus.ID).Count; if (killTargetCount > 0) { return(false); } // Are there any remaining item requirements? var itemCount = DataService.Where <PCQuestItemProgress>(x => x.PlayerID == player.GlobalID && x.PCQuestStatusID == pcStatus.ID).Count; if (itemCount > 0) { return(false); } // Are there any remaining key item requirements? var requiredKeyItems = DataService.Where <QuestRequiredKeyItem>(x => x.QuestID == questID && x.QuestStateID == finalState.ID) .Select(s => s.KeyItemID).ToArray(); bool hasAllKeyItems = KeyItemService.PlayerHasAllKeyItems(player, requiredKeyItems); if (!hasAllKeyItems) { return(false); } // Met all requirements. We can complete this quest. return(true); }
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); }); }
/// <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); }); }
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)); }
/// <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)); }