server-master/srcs/WingsAPI.Game.Extensions/Quests/QuestExtensions.cs
2026-02-10 18:21:30 +01:00

551 lines
No EOL
27 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PhoenixLib.Logging;
using WingsEmu.DTOs.Quests;
using WingsEmu.Game._enum;
using WingsEmu.Game.Algorithm;
using WingsEmu.Game.Characters;
using WingsEmu.Game.Configurations;
using WingsEmu.Game.Entities;
using WingsEmu.Game.Helpers.Damages;
using WingsEmu.Game.Networking;
using WingsEmu.Game.Quests;
using WingsEmu.Packets.Enums;
using WingsEmu.Packets.Enums.Character;
namespace WingsAPI.Game.Extensions.Quests
{
public static class QuestExtensions
{
private static readonly string _b64SqstIndex = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz{}";
private static readonly QuestType[] DialogQuestTypes =
{
QuestType.DIALOG,
QuestType.DIALOG_2,
QuestType.DELIVER_ITEM_TO_NPC,
QuestType.GIVE_ITEM_TO_NPC,
QuestType.GIVE_ITEM_TO_NPC_2,
QuestType.GIVE_NPC_GOLD,
QuestType.DIALOG_WHILE_WEARING,
QuestType.DIALOG_WHILE_HAVING_ITEM
};
public static string GenerateTargetQuest(this IClientSession session, short x, short y, short mapId, int questId) => $"target {x} {y} {mapId} {questId}";
public static string GenerateTargetOffQuest(this IClientSession session, short x, short y, short mapId, int questId) => $"targetoff {x} {y} {mapId} {questId}";
public static string GenerateQnpcPacket(this IClientSession session, short level, short npcVnum, short mapId) =>
$"qnpc {npcVnum}|{mapId}|{level} -1|-1|-1 -1|-1|-1 -1|-1|-1 -1|-1|-1 -1|-1|-1 -1|-1|-1 -1|-1|-1 -1|-1|-1 -1|-1|-1";
public static string GenerateQrPacket(this IClientSession session, CharacterQuest quest, IReadOnlyCollection<CharacterQuestGeneratedReward> rndRewards, QuestsRatesConfiguration questRates)
{
List<QuestPrizeDto> prizes = quest.Quest.Prizes;
if (prizes == null)
{
return "";
}
var qrPacket = new StringBuilder("qr ");
foreach (QuestPrizeDto prize in prizes)
{
switch (prize.RewardType)
{
case (byte)QuestRewardType.Reput:
case (byte)QuestRewardType.Exp:
case (byte)QuestRewardType.SecondExp:
case (byte)QuestRewardType.ThirdExp:
case (byte)QuestRewardType.JobExp:
case (byte)QuestRewardType.SecondJobExp:
qrPacket.Append($"{prize.RewardType.ToString()} 0 {prize.Data0.ToString()} ");
break;
case (byte)QuestRewardType.Gold:
qrPacket.Append($"{prize.RewardType.ToString()} 0 {prize.Data0 * questRates.GoldRate} ");
break;
case (byte)QuestRewardType.AllRewards:
qrPacket.Append(prize.Data0 == -1 ? "" : $"{prize.RewardType.ToString()} {prize.Data0.ToString()} 1 ");
qrPacket.Append(prize.Data1 == -1 ? "" : $"{prize.RewardType.ToString()} {prize.Data1.ToString()} 1 ");
qrPacket.Append(prize.Data2 == -1 ? "" : $"{prize.RewardType.ToString()} {prize.Data2.ToString()} 1 ");
qrPacket.Append(prize.Data3 == -1 ? "" : $"{prize.RewardType.ToString()} {prize.Data3.ToString()} 1 ");
break;
case (byte)QuestRewardType.SecondGold:
qrPacket.Append($"{prize.RewardType.ToString()} 0 {prize.Data0 * questRates.BaseGold * questRates.GoldRate} ");
break;
case (byte)QuestRewardType.ThirdGold:
qrPacket.Append($"{prize.RewardType.ToString()} 0 {prize.Data0 * quest.ObjectiveAmount.Sum(s => s.Value.RequiredAmount) * session.PlayerEntity.Level * questRates.GoldRate} ");
break;
case (byte)QuestRewardType.Unknow:
case (byte)QuestRewardType.ItemsDependingOnClass:
switch (session.PlayerEntity.Class)
{
case ClassType.Swordman:
qrPacket.Append(prize.Data0 == -1 ? "" : $"{prize.RewardType.ToString()} {prize.Data0.ToString()} {prize.Data4.ToString()} ");
break;
case ClassType.Archer:
qrPacket.Append(prize.Data1 == -1 ? "" : $"{prize.RewardType.ToString()} {prize.Data1.ToString()} {prize.Data4.ToString()} ");
break;
case ClassType.Magician:
qrPacket.Append(prize.Data2 == -1 ? "" : $"{prize.RewardType.ToString()} {prize.Data2.ToString()} {prize.Data4.ToString()} ");
break;
default:
qrPacket.Append(prize.Data3 == -1 ? "" : $"{prize.RewardType.ToString()} {prize.Data3.ToString()} {prize.Data4.ToString()} ");
break;
}
break;
}
}
foreach (CharacterQuestGeneratedReward rndReward in rndRewards)
{
qrPacket.Append($"{(byte)QuestRewardType.RandomReward} {rndReward.ItemVnum} {rndReward.Amount} ");
}
for (int i = prizes.Count(s => s.RewardType != (byte)QuestRewardType.RandomReward) + rndRewards.Count; i < 4; i++)
{
qrPacket.Append("0 0 0 ");
}
qrPacket.Append(quest.QuestId);
return qrPacket.ToString();
}
public static string GenerateQuestList(this IClientSession session, IQuestManager questManager, int? questToShowInfo = null)
{
IEnumerable<CharacterQuest> quests = session.PlayerEntity.GetCurrentQuests();
string header = "qstlist";
if (quests == null)
{
return header;
}
var packet = new StringBuilder();
foreach (CharacterQuest quest in quests)
{
packet.Append($" {session.GenerateQuestData(quest, questManager, qstlistCall: true, questToShowInfo: questToShowInfo)}");
}
int soundFlowerEmptySlot = session.GetEmptyQuestSlot(QuestSlotType.GENERAL, true);
for (int i = 0; i < session.PlayerEntity.GetPendingSoundFlowerQuests(); i++)
{
packet.Append($" {soundFlowerEmptySlot + i}.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0");
}
return $"{header}{packet}";
}
public static string GenerateQuestProgress(this IClientSession session, IQuestManager questManager, int questVnum)
{
CharacterQuest currentQuest = session.PlayerEntity.GetCurrentQuest(questVnum);
return currentQuest == null ? string.Empty : $"qsti {session.GenerateQuestData(currentQuest, questManager, session.PlayerEntity.IsQuestCompleted(currentQuest))}";
}
private static string GenerateQuestData(this IClientSession session, CharacterQuest characterQuest, IQuestManager questManager, bool isFinished = false, bool qstlistCall = false,
int? questToShowInfo = null)
{
int questSlot = session.GetQuestSlot(characterQuest);
if (questSlot == -1)
{
Log.Debug($"The slot for quest {characterQuest.QuestId} was not found.");
return "";
}
IReadOnlyList<QuestObjectiveDto> objectives;
bool statusAdded;
var data = new StringBuilder($"{questSlot}.{characterQuest.QuestId}");
switch (characterQuest.SlotType)
{
case QuestSlotType.MAIN:
data.Append($".{characterQuest.QuestId}");
break;
case QuestSlotType.GENERAL:
IReadOnlyCollection<int> questlines = questManager.GetQuestlines(characterQuest.QuestId);
data.Append($".{(questlines.Any() ? questlines.First() : characterQuest.QuestId)}");
break;
case QuestSlotType.SECONDARY:
data.Append(".0");
break;
}
data.Append($".{(byte)characterQuest.Quest.QuestType}");
switch (characterQuest.Quest.QuestType)
{
case QuestType.WIN_RAID_AND_TALK_TO_NPC:
case QuestType.DELIVER_ITEM_TO_NPC:
case QuestType.KILL_MONSTER_BY_VNUM:
case QuestType.GIVE_ITEM_TO_NPC:
case QuestType.GIVE_ITEM_TO_NPC_2:
case QuestType.DIALOG_WHILE_WEARING:
case QuestType.DIALOG_WHILE_HAVING_ITEM:
case QuestType.USE_ITEM_ON_TARGET:
case QuestType.CAPTURE_WITHOUT_KEEPING:
case QuestType.CAPTURE_AND_KEEP:
case QuestType.DROP_IN_TIMESPACE:
case QuestType.COMPLETE_TIMESPACE:
case QuestType.CRAFT_WITHOUT_KEEPING:
case QuestType.DROP_CHANCE:
case QuestType.DROP_CHANCE_2:
case QuestType.COLLECT:
case QuestType.DROP_HARDCODED:
case QuestType.KILL_X_MOBS_SOUND_FLOWER:
statusAdded = false;
objectives = characterQuest.Quest.Objectives;
foreach (QuestObjectiveDto objective in objectives)
{
CharacterQuestObjectiveDto questObjectiveDto = characterQuest.ObjectiveAmount[objective.ObjectiveIndex];
data.Append($".{questObjectiveDto.CurrentAmount}.{questObjectiveDto.RequiredAmount}");
if (!statusAdded)
{
data.Append($".{(isFinished ? 1 : 0)}");
statusAdded = true;
}
}
for (int i = objectives.Count; i < 5; i++)
{
data.Append(".0.0");
}
break;
case QuestType.DIALOG:
case QuestType.DIALOG_2:
case QuestType.NOTHING:
case QuestType.GO_TO_MAP:
case QuestType.GIVE_NPC_GOLD:
data.Append($".0.0.{(isFinished ? 1 : 0)}.0.0.0.0.0.0.0.0");
break;
case QuestType.KILL_PLAYER_IN_REGION:
case QuestType.DIE_X_TIMES:
case QuestType.EARN_REPUTATION:
case QuestType.COMPLETE_TIMESPACE_WITH_ATLEAST_X_POINTS:
break;
}
if (qstlistCall)
{
data.Append(characterQuest.QuestId != questToShowInfo ? ".0" : $".{(isFinished ? 0 : 1)}");
}
else
{
data.Append(".0");
}
return data.ToString();
}
public static bool IsQuestCompleted(this IPlayerEntity player, CharacterQuest characterQuest)
{
if (characterQuest == null)
{
return false;
}
IEnumerable<QuestObjectiveDto> objectives = characterQuest.Quest.Objectives;
switch (characterQuest.Quest.QuestType)
{
case QuestType.DELIVER_ITEM_TO_NPC:
case QuestType.GIVE_ITEM_TO_NPC:
case QuestType.GIVE_ITEM_TO_NPC_2:
case QuestType.KILL_MONSTER_BY_VNUM:
case QuestType.CAPTURE_WITHOUT_KEEPING:
case QuestType.CAPTURE_AND_KEEP:
case QuestType.CRAFT_WITHOUT_KEEPING:
case QuestType.DROP_CHANCE:
case QuestType.DROP_CHANCE_2:
case QuestType.DROP_IN_TIMESPACE:
case QuestType.COLLECT:
case QuestType.DROP_HARDCODED:
case QuestType.COMPLETE_TIMESPACE_WITH_ATLEAST_X_POINTS:
case QuestType.GIVE_NPC_GOLD:
case QuestType.COMPLETE_TIMESPACE:
case QuestType.KILL_X_MOBS_SOUND_FLOWER:
return !objectives.Any(s => characterQuest.ObjectiveAmount[s.ObjectiveIndex].CurrentAmount < characterQuest.ObjectiveAmount[s.ObjectiveIndex].RequiredAmount);
case QuestType.GO_TO_MAP:
return player.Position.IsInAoeZone(new Position(characterQuest.Quest.TargetMapX, characterQuest.Quest.TargetMapY), 2);
case QuestType.USE_ITEM_ON_TARGET:
return !objectives.Any(s => characterQuest.ObjectiveAmount[s.ObjectiveIndex].CurrentAmount <= 0);
case QuestType.DIALOG_WHILE_HAVING_ITEM:
return !objectives.Any(s => player.CountItemWithVnum(s.Data1) < characterQuest.ObjectiveAmount[s.ObjectiveIndex].RequiredAmount);
case QuestType.DIALOG:
case QuestType.DIALOG_2:
case QuestType.DIALOG_WHILE_WEARING:
if ((characterQuest.QuestId == (int)QuestsVnums.TALK_WEARING_KOVOLT_MASK_1 || characterQuest.QuestId == (int)QuestsVnums.TALK_WEARING_KOVOLT_MASK_2)
&& player.Class != ClassType.Adventurer) // Kovolt Mask
{
return true;
}
return !objectives.Any(s => characterQuest.ObjectiveAmount[s.ObjectiveIndex].CurrentAmount <= 0);
case QuestType.NOTHING:
return true;
// Not used for now
case QuestType.WIN_RAID_AND_TALK_TO_NPC:
case QuestType.DIE_X_TIMES:
case QuestType.EARN_REPUTATION:
case QuestType.KILL_PLAYER_IN_REGION:
break;
}
return false;
}
public static string GenerateSqstPacket(this IClientSession session, IQuestManager questManager, int sqstIndex)
{
IReadOnlyCollection<QuestNpcDto> blueAlertQuests = questManager.GetNpcBlueAlertQuests().ToList();
IReadOnlyCollection<CharacterQuest> completedBlueAlertQuests = session.PlayerEntity.GetCompletedQuests().Where(s => blueAlertQuests.Any(t => t.QuestId == s.QuestId)).ToList();
var sb = new StringBuilder();
sb.Append($"sqst {sqstIndex} ");
for (byte packetIndex = 0; packetIndex < 250; packetIndex++)
{
byte[] binary = { 0, 0, 0, 0, 0, 0 };
for (byte bitIndex = 0; bitIndex < 6; bitIndex++)
{
int questId = packetIndex * 6 + bitIndex + 1500 * sqstIndex;
if (completedBlueAlertQuests.Any(s => s.QuestId == questId))
{
if (bitIndex == 0)
{
binary[bitIndex] = 1;
}
else
{
binary[^bitIndex] = 1;
}
}
}
string binaryString = string.Join("", binary);
sb.Append(_b64SqstIndex.ElementAt(Convert.ToInt16(binaryString, 2)));
}
return sb.ToString();
}
public static void SendSqstPackets(this IClientSession session, IQuestManager questManager)
{
var packets = new List<string>();
int sqstPacketsAmount = (int)Math.Ceiling(questManager.GetNpcBlueAlertQuests().Max(s => s.QuestId ?? 0) / 1500.0);
for (int i = 0; i < sqstPacketsAmount; i++)
{
packets.Add(session.GenerateSqstPacket(questManager, i));
}
session.SendPackets(packets);
}
public static void SendSqstPacket(this IClientSession session, IQuestManager questManager, int sqstIndex) => session.SendPacket(session.GenerateSqstPacket(questManager, sqstIndex));
public static void UpdateQuestSqstPacket(this IClientSession session, IQuestManager questManager, int questVnum)
{
int sqstIndex = (int)Math.Floor(questVnum / 1500.0);
session.SendPacket(session.GenerateSqstPacket(questManager, sqstIndex));
}
public static void SendQuestsTargets(this IClientSession session)
{
IReadOnlyCollection<CharacterQuest> characterQuests = session.PlayerEntity.GetCurrentQuests().Where(s => s.Quest.TargetMapId != 0).ToList();
if (!characterQuests.Any())
{
return;
}
foreach (CharacterQuest characterQuest in characterQuests)
{
QuestDto quest = characterQuest.Quest;
session.SendTargetQuest(quest.TargetMapX, quest.TargetMapY, quest.TargetMapId, quest.Id);
}
}
public static void DeleteQuestTarget(this IClientSession session, CharacterQuest characterQuest)
{
if (characterQuest.Quest.TargetMapId == 0)
{
return;
}
session.SendTargetOffQuest(characterQuest.Quest.TargetMapX, characterQuest.Quest.TargetMapY, characterQuest.Quest.TargetMapId, characterQuest.QuestId);
}
public static void SendTargetQuest(this IClientSession session, short x, short y, short mapId, int questId) => session.SendPacket(session.GenerateTargetQuest(x, y, mapId, questId));
public static void SendTargetOffQuest(this IClientSession session, short x, short y, short mapId, int questId) => session.SendPacket(session.GenerateTargetOffQuest(x, y, mapId, questId));
public static void RefreshQuestList(this IClientSession session, IQuestManager questManager, int? questToShowInfo) =>
session.SendPacket(session.GenerateQuestList(questManager, questToShowInfo));
public static void RefreshQuestProgress(this IClientSession session, IQuestManager questManager, int questId) => session.SendPacket(session.GenerateQuestProgress(questManager, questId));
public static void SendQrPacket(this IClientSession session, CharacterQuest quest, IReadOnlyCollection<CharacterQuestGeneratedReward> rndRewards, QuestsRatesConfiguration questRates) =>
session.SendPacket(session.GenerateQrPacket(quest, rndRewards, questRates));
public static void SendQnpcPacket(this IClientSession session, short level, short npcVnum, short mapId) => session.SendPacket(session.GenerateQnpcPacket(level, npcVnum, mapId));
public static CharacterQuest GetQuestById(this IPlayerEntity character, int questId) => character.GetCurrentQuest(questId);
public static CharacterQuest GetQuestByActionSlot(this IClientSession session, int action, int slot) => action == 1 ? session.PlayerEntity.GetCurrentQuest(slot) : session.GetQuestBySlot(slot);
public static CharacterQuest GetQuestBySlot(this IClientSession session, int slot)
{
CharacterQuest quest;
if (slot < 0 || slot > 10)
{
Log.Debug($"[ERROR] PACKET QT: Invalid slot index: {slot.ToString()}");
return null;
}
if (slot < 5)
{
quest = session.PlayerEntity.GetCurrentQuests().Where(s => s.SlotType == QuestSlotType.GENERAL).ElementAtOrDefault(slot);
}
else if (slot == 5)
{
quest = session.PlayerEntity.GetCurrentQuests().Where(s => s.SlotType == QuestSlotType.MAIN).ElementAtOrDefault(0);
}
else
{
slot -= 6;
quest = session.PlayerEntity.GetCurrentQuests().Where(s => s.SlotType == QuestSlotType.SECONDARY).ElementAtOrDefault(slot);
}
return quest;
}
public static long GetLevelXpPercentage(this ICharacterAlgorithm characterAlgorithm, short percentage, short level) =>
Convert.ToInt64(characterAlgorithm.GetLevelXp(level) * (percentage / 100.0));
public static long GetSpecialistJobXpPercentage(this ICharacterAlgorithm characterAlgorithm, short percentage, short level, bool isFunSpecialist) =>
Convert.ToInt64(characterAlgorithm.GetSpecialistJobXp(level, isFunSpecialist) * (percentage / 100.0));
public static long GetHeroLevelXpPercentage(this ICharacterAlgorithm characterAlgorithm, short percentage, short level) =>
Convert.ToInt64(characterAlgorithm.GetHeroLevelXp(level) * (percentage / 100.0));
public static long GetJobXpPercentage(this ICharacterAlgorithm characterAlgorithm, short percentage, short level) => Convert.ToInt64(characterAlgorithm.GetJobXp(level) * (percentage / 100.0));
public static int GetEmptyQuestSlot(this IClientSession session, QuestSlotType slotType, bool isSoundFlower = false)
{
IReadOnlyCollection<CharacterQuest> quests = session.PlayerEntity.GetCurrentQuests().Where(s => s.SlotType == slotType).ToList();
int currentGeneralQuestsCount = quests.Count + session.PlayerEntity.GetPendingSoundFlowerQuests();
int slot = slotType switch
{
QuestSlotType.GENERAL => currentGeneralQuestsCount > (isSoundFlower ? 5 : 4) ? -1 : quests.Count,
QuestSlotType.MAIN => !quests.Any() ? 5 : -1,
QuestSlotType.SECONDARY => quests.Count > 4 ? -1 : quests.Count + 6,
_ => -1
};
return slot;
}
public static int GetQuestSlot(this IClientSession session, CharacterQuest characterQuest)
{
var quests = session.PlayerEntity.GetCurrentQuests().Where(s => s.SlotType == characterQuest.SlotType).ToList();
return characterQuest.SlotType switch
{
QuestSlotType.GENERAL => quests.IndexOf(characterQuest),
QuestSlotType.MAIN => 5,
QuestSlotType.SECONDARY => quests.IndexOf(characterQuest) + 6,
_ => -1
};
}
public static bool HasAlreadyQuestOrQuestline(this IClientSession session, QuestDto quest, IQuestManager questManager, INpcRunTypeQuestsConfiguration npcRunTypeQuestsConfiguration)
{
return session.PlayerEntity.HasQuestWithId(quest.Id)
|| session.PlayerEntity.GetCurrentQuests().SelectMany(s => questManager.GetQuestlines(s.QuestId)).Intersect(questManager.GetQuestlines(quest.Id)).Any()
|| session.HasRunningPeriodicQuest(quest, npcRunTypeQuestsConfiguration);
}
public static async Task<bool> HasCompletedPeriodicQuest(this IClientSession session, QuestDto quest, IQuestManager questManager, INpcRunTypeQuestsConfiguration npcRunTypeQuestsConfiguration,
IPeriodicQuestsConfiguration periodicQuestsConfiguration)
{
IEnumerable<CharacterQuestDto> completedQuests = session.PlayerEntity.GetCompletedPeriodicQuests();
PeriodicQuestSet periodicQuestSet = periodicQuestsConfiguration.GetPeriodicQuestSetByQuestId(quest.Id);
if (periodicQuestSet == null)
{
return completedQuests.Any(s => npcRunTypeQuestsConfiguration.HaveTheSameNpcRunType(s.QuestId, quest.Id));
}
bool couldAddKey = periodicQuestSet.PerNoswingsAccount is true
? await questManager.TryTakeDailyQuest(session.Account.MasterAccountId, periodicQuestSet.Id)
: await questManager.TryTakeDailyQuest(session.PlayerEntity.Id, periodicQuestSet.Id);
return completedQuests.Any(s => npcRunTypeQuestsConfiguration.HaveTheSameNpcRunType(s.QuestId, quest.Id)) || !couldAddKey;
}
public static bool HasRunningPeriodicQuest(this IClientSession session, QuestDto quest, INpcRunTypeQuestsConfiguration npcRunTypeQuestsConfiguration)
{
IEnumerable<CharacterQuestDto> activeQuests = session.PlayerEntity.GetCurrentQuests();
return activeQuests.Any(s => npcRunTypeQuestsConfiguration.HaveTheSameNpcRunType(s.QuestId, quest.Id));
}
public static PeriodicQuestSet GetPeriodicQuestSet(this QuestDto quest, IQuestManager questManager, IPeriodicQuestsConfiguration periodicQuestsConfiguration)
{
PeriodicQuestSet periodicQuestSet = periodicQuestsConfiguration.GetDailyQuests().FirstOrDefault(s => s.QuestVnums.Any(t => questManager.GetQuestById(t).NextQuestId == quest.Id));
return periodicQuestSet;
}
public static bool ShowNpcDialog(this IClientSession session, INpcEntity npcEntity, IQuestManager questManager)
{
IEnumerable<CharacterQuest> characterQuests = session.PlayerEntity.GetCurrentQuestsByTypes(DialogQuestTypes).ToArray();
if (!characterQuests.Any())
{
return true;
}
foreach (CharacterQuest characterQuest in characterQuests)
{
if (questManager.IsNpcBlueAlertQuest(characterQuest.QuestId) && (characterQuest.Quest.QuestType == QuestType.DIALOG || characterQuest.Quest.QuestType == QuestType.DIALOG_2))
{
continue;
}
foreach (QuestObjectiveDto objective in characterQuest.Quest.Objectives)
{
if (npcEntity.NpcVNum != (characterQuest.Quest.QuestType is QuestType.DELIVER_ITEM_TO_NPC ? objective.Data1 : objective.Data0))
{
continue;
}
CharacterQuestObjectiveDto questObjectiveDto = characterQuest.ObjectiveAmount[objective.ObjectiveIndex];
switch (characterQuest.Quest.QuestType)
{
case QuestType.DELIVER_ITEM_TO_NPC:
case QuestType.GIVE_ITEM_TO_NPC_2:
case QuestType.GIVE_ITEM_TO_NPC:
int amountLeft = questObjectiveDto.RequiredAmount - questObjectiveDto.CurrentAmount;
if (amountLeft == 0)
{
continue;
}
int amountInPossession = session.PlayerEntity.CountItemWithVnum(characterQuest.Quest.QuestType is QuestType.DELIVER_ITEM_TO_NPC ? objective.Data0 : objective.Data1);
if (amountInPossession == 0)
{
continue;
}
return false;
case QuestType.GIVE_NPC_GOLD:
int totalGoldToGive = questObjectiveDto.RequiredAmount;
if (session.PlayerEntity.Gold < totalGoldToGive)
{
continue;
}
return false;
case QuestType.DIALOG:
case QuestType.DIALOG_2:
return false;
}
}
}
return true;
}
}
}