| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511 |
- using Server.MirObjects;
- using System.Text.RegularExpressions;
- using Server.MirEnvir;
- namespace Server.MirDatabase
- {
- public class QuestInfo
- {
- protected static Envir Envir
- {
- get { return Envir.Main; }
- }
- protected static Envir EditEnvir
- {
- get { return Envir.Edit; }
- }
- protected static MessageQueue MessageQueue
- {
- get { return MessageQueue.Instance; }
- }
- public int Index;
- public uint NpcIndex;
- public NPCInfo NpcInfo;
- private uint _finishNpcIndex;
- public uint FinishNpcIndex
- {
- get { return _finishNpcIndex == 0 ? NpcIndex : _finishNpcIndex; }
- set { _finishNpcIndex = value; }
- }
- public NPCObject FinishNPC
- {
- get
- {
- return Envir.NPCs.Single(x => x.ObjectID == FinishNpcIndex);
- }
- }
- public string
- Name = string.Empty,
- Group = string.Empty,
- FileName = string.Empty,
- GotoMessage = string.Empty,
- KillMessage = string.Empty,
- ItemMessage = string.Empty,
- FlagMessage = string.Empty;
- public List<string> Description = new List<string>();
- public List<string> TaskDescription = new List<string>();
- public List<string> ReturnDescription = new List<string>();
- public List<string> CompletionDescription = new List<string>();
- public int RequiredMinLevel, RequiredMaxLevel, RequiredQuest;
- public RequiredClass RequiredClass = RequiredClass.None;
- public QuestType Type;
- public int TimeLimitInSeconds = 0;
- public List<QuestItemTask> CarryItems = new List<QuestItemTask>();
- public List<QuestKillTask> KillTasks = new List<QuestKillTask>();
- public List<QuestItemTask> ItemTasks = new List<QuestItemTask>();
- public List<QuestFlagTask> FlagTasks = new List<QuestFlagTask>();
- //TODO: ZoneTasks
- //TODO: EscortTasks
- public uint GoldReward;
- public uint ExpReward;
- public uint CreditReward;
- public List<QuestItemReward> FixedRewards = new List<QuestItemReward>();
- public List<QuestItemReward> SelectRewards = new List<QuestItemReward>();
- private Regex _regexMessage = new Regex("\"([^\"]*)\"");
- public QuestInfo() { }
- public QuestInfo(BinaryReader reader)
- {
- Index = reader.ReadInt32();
- Name = reader.ReadString();
- Group = reader.ReadString();
- FileName = reader.ReadString();
- RequiredMinLevel = reader.ReadInt32();
- RequiredMaxLevel = reader.ReadInt32();
- if (RequiredMaxLevel == 0) RequiredMaxLevel = ushort.MaxValue;
- RequiredQuest = reader.ReadInt32();
- RequiredClass = (RequiredClass)reader.ReadByte();
- Type = (QuestType)reader.ReadByte();
- GotoMessage = reader.ReadString();
- KillMessage = reader.ReadString();
- ItemMessage = reader.ReadString();
- FlagMessage = reader.ReadString();
- if (Envir.LoadVersion > 90)
- {
- TimeLimitInSeconds = reader.ReadInt32();
- }
- LoadInfo();
- }
- public void Save(BinaryWriter writer)
- {
- writer.Write(Index);
- writer.Write(Name);
- writer.Write(Group);
- writer.Write(FileName);
- writer.Write(RequiredMinLevel);
- writer.Write(RequiredMaxLevel);
- writer.Write(RequiredQuest);
- writer.Write((byte)RequiredClass);
- writer.Write((byte)Type);
- writer.Write(GotoMessage);
- writer.Write(KillMessage);
- writer.Write(ItemMessage);
- writer.Write(FlagMessage);
- writer.Write(TimeLimitInSeconds);
- }
- public void LoadInfo(bool clear = false)
- {
- if (clear) ClearInfo();
- if (!Directory.Exists(Settings.QuestPath)) return;
- string fileName = Path.Combine(Settings.QuestPath, FileName + ".txt");
- if (File.Exists(fileName))
- {
- List<string> lines = File.ReadAllLines(fileName).ToList();
- ParseFile(lines);
- }
- else
- MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.FileNotFoundQuest), fileName, Name));
- }
- public void ClearInfo()
- {
- Description.Clear();
- KillTasks = new List<QuestKillTask>();
- ItemTasks = new List<QuestItemTask>();
- FlagTasks = new List<QuestFlagTask>();
- FixedRewards = new List<QuestItemReward>();
- SelectRewards = new List<QuestItemReward>();
- ExpReward = 0;
- GoldReward = 0;
- CreditReward = 0;
- }
- public void ParseFile(List<string> lines)
- {
- const string
- descriptionCollectKey = "[@DESCRIPTION]",
- descriptionTaskKey = "[@TASKDESCRIPTION]",
- descriptionReturnKey = "[@RETURNDESCRIPTION]",
- descriptionCompletionKey = "[@COMPLETION]",
- carryItemsKey = "[@CARRYITEMS]",
- killTasksKey = "[@KILLTASKS]",
- itemTasksKey = "[@ITEMTASKS]",
- flagTasksKey = "[@FLAGTASKS]",
- fixedRewardsKey = "[@FIXEDREWARDS]",
- selectRewardsKey = "[@SELECTREWARDS]",
- expRewardKey = "[@EXPREWARD]",
- goldRewardKey = "[@GOLDREWARD]",
- creditRewardKey = "[@CREDITREWARD]";
- List<string> headers = new List<string>
- {
- descriptionCollectKey, descriptionTaskKey, descriptionCompletionKey,
- carryItemsKey, killTasksKey, itemTasksKey, flagTasksKey,
- fixedRewardsKey, selectRewardsKey, expRewardKey, goldRewardKey, creditRewardKey, descriptionReturnKey
- };
- int currentHeader = 0;
- while (currentHeader < headers.Count)
- {
- for (int i = 0; i < lines.Count; i++)
- {
- string line = lines[i].ToUpper();
- if (line != headers[currentHeader].ToUpper()) continue;
- for (int j = i + 1; j < lines.Count; j++)
- {
- string innerLine = lines[j];
- if (innerLine.StartsWith("[") || innerLine.StartsWith("//")) break;
- if (string.IsNullOrEmpty(lines[j])) continue;
- switch (line)
- {
- case descriptionCollectKey:
- Description.Add(innerLine);
- break;
- case descriptionTaskKey:
- TaskDescription.Add(innerLine);
- break;
- case descriptionReturnKey:
- ReturnDescription.Add(innerLine);
- break;
- case descriptionCompletionKey:
- CompletionDescription.Add(innerLine);
- break;
- case carryItemsKey:
- QuestItemTask t = ParseItem(innerLine);
- if (t != null) CarryItems.Add(t);
- break;
- case killTasksKey:
- QuestKillTask t1 = ParseKill(innerLine);
- if (t1 != null) KillTasks.Add(t1);
- break;
- case itemTasksKey:
- QuestItemTask t2 = ParseItem(innerLine);
- if (t2 != null) ItemTasks.Add(t2);
- break;
- case flagTasksKey:
- QuestFlagTask t3 = ParseFlag(innerLine);
- if (t3 != null) FlagTasks.Add(t3);
- break;
- case fixedRewardsKey:
- {
- ParseReward(FixedRewards, innerLine);
- break;
- }
- case selectRewardsKey:
- {
- ParseReward(SelectRewards, innerLine);
- break;
- }
- case expRewardKey:
- uint.TryParse(innerLine, out ExpReward);
- break;
- case goldRewardKey:
- uint.TryParse(innerLine, out GoldReward);
- break;
- case creditRewardKey:
- uint.TryParse(innerLine, out CreditReward);
- break;
- }
- }
- }
- currentHeader++;
- }
- }
- public void ParseReward(List<QuestItemReward> list, string line)
- {
- if (line.Length < 1) return;
- string[] split = line.Split(' ');
- ushort count = 1;
- if (split.Length > 1) ushort.TryParse(split[1], out count);
- ItemInfo mInfo = Envir.GetItemInfo(split[0]);
- if (mInfo == null)
- {
- mInfo = Envir.GetItemInfo(split[0] + "(M)");
- if (mInfo != null) list.Add(new QuestItemReward() { Item = mInfo, Count = count });
- mInfo = Envir.GetItemInfo(split[0] + "(F)");
- if (mInfo != null) list.Add(new QuestItemReward() { Item = mInfo, Count = count });
- }
- else
- {
- list.Add(new QuestItemReward() { Item = mInfo, Count = count });
- }
- }
- public QuestKillTask ParseKill(string line)
- {
- if (line.Length < 1) return null;
- string[] split = line.Split(' ');
- int count = 1;
- string message = "";
- MonsterInfo mInfo = Envir.GetMonsterInfo(split[0]);
- if (split.Length > 1) int.TryParse(split[1], out count);
- var match = _regexMessage.Match(line);
- if (match.Success)
- {
- message = match.Groups[1].Captures[0].Value;
- }
- return mInfo == null ? null : new QuestKillTask() { Monster = mInfo, Count = count, Message = message };
- }
- public QuestItemTask ParseItem(string line)
- {
- if (line.Length < 1) return null;
- string[] split = line.Split(' ');
- ushort count = 1;
- string message = "";
- ItemInfo mInfo = Envir.GetItemInfo(split[0]);
- if (split.Length > 1) ushort.TryParse(split[1], out count);
- var match = _regexMessage.Match(line);
- if (match.Success)
- {
- message = match.Groups[1].Captures[0].Value;
- }
- //if (mInfo.StackSize <= 1)
- //{
- // //recursively add item if cant stack???
- //}
- return mInfo == null ? null : new QuestItemTask { Item = mInfo, Count = count, Message = message };
- }
- public QuestFlagTask ParseFlag(string line)
- {
- if (line.Length < 1) return null;
- string[] split = line.Split(' ');
- int number = -1;
- string message = "";
- int.TryParse(split[0], out number);
- if (number < 0 || number > Globals.FlagIndexCount - 1000) return null;
- var match = _regexMessage.Match(line);
- if (match.Success)
- {
- message = match.Groups[1].Captures[0].Value;
- }
- return new QuestFlagTask { Number = number, Message = message };
- }
- public bool CanAccept(PlayerObject player)
- {
- if (RequiredMinLevel > player.Level || RequiredMaxLevel < player.Level)
- return false;
- if (RequiredQuest > 0 && !player.CompletedQuests.Contains(RequiredQuest))
- return false;
- switch (player.Class)
- {
- case MirClass.Warrior:
- if (!RequiredClass.HasFlag(RequiredClass.Warrior))
- return false;
- break;
- case MirClass.Wizard:
- if (!RequiredClass.HasFlag(RequiredClass.Wizard))
- return false;
- break;
- case MirClass.Taoist:
- if (!RequiredClass.HasFlag(RequiredClass.Taoist))
- return false;
- break;
- case MirClass.Assassin:
- if (!RequiredClass.HasFlag(RequiredClass.Assassin))
- return false;
- break;
- case MirClass.Archer:
- if (!RequiredClass.HasFlag(RequiredClass.Archer))
- return false;
- break;
- }
- return true;
- }
- public ClientQuestInfo CreateClientQuestInfo(PlayerObject viewer = null)
- {
- var description = LinkFormatter.ReplacePlaceholders(Description, (type, index) => EnsureLinkInfo(viewer, type, index)) ?? new List<string>();
- var taskDescription = LinkFormatter.ReplacePlaceholders(TaskDescription, (type, index) => EnsureLinkInfo(viewer, type, index)) ?? new List<string>();
- var returnDescription = LinkFormatter.ReplacePlaceholders(ReturnDescription, (type, index) => EnsureLinkInfo(viewer, type, index)) ?? new List<string>();
- var completionDescription = LinkFormatter.ReplacePlaceholders(CompletionDescription, (type, index) => EnsureLinkInfo(viewer, type, index)) ?? new List<string>();
- return new ClientQuestInfo
- {
- Index = Index,
- NPCIndex = NpcIndex,
- FinishNPCIndex = FinishNpcIndex,
- Name = Name,
- Group = Group,
- Description = description,
- TaskDescription = taskDescription,
- ReturnDescription = returnDescription,
- CompletionDescription = completionDescription,
- MinLevelNeeded = RequiredMinLevel,
- MaxLevelNeeded = RequiredMaxLevel,
- ClassNeeded = RequiredClass,
- QuestNeeded = RequiredQuest,
- Type = Type,
- TimeLimitInSeconds = TimeLimitInSeconds,
- RewardGold = GoldReward,
- RewardExp = ExpReward,
- RewardCredit = CreditReward,
- RewardsFixedItem = FixedRewards,
- RewardsSelectItem = SelectRewards
- };
- }
- private void EnsureLinkInfo(PlayerObject viewer, string linkType, int index)
- {
- if (viewer?.Connection == null) return;
- switch (linkType)
- {
- case "ITEM":
- var itemInfo = Envir.GetItemInfo(index);
- if (itemInfo != null)
- viewer.Connection.CheckItemInfo(itemInfo);
- break;
- case "MONSTER":
- viewer.Connection.CheckMonsterInfo(index);
- break;
- case "NPC":
- viewer.Connection.CheckNPCInfo(index);
- break;
- }
- }
- public static void FromText(string text)
- {
- string[] data = text.Split(new[] { ',' });
- if (data.Length < 10) return;
- QuestInfo info;
- bool isNew = false;
- if (!int.TryParse(data[0], out var index))
- {
- index = -1;
- }
- if (index == -1 || (info = EditEnvir.QuestInfoList.FirstOrDefault(it => it.Index == index)) == null)
- {
- info = new QuestInfo() { Index = ++EditEnvir.QuestIndex };
- isNew = true;
- }
- info.Name = data[1];
- info.Group = data[2];
- byte temp;
- byte.TryParse(data[3], out temp);
- info.Type = (QuestType)temp;
- info.FileName = data[4];
- info.GotoMessage = data[5];
- info.KillMessage = data[6];
- info.ItemMessage = data[7];
- info.FlagMessage = data[8];
- int.TryParse(data[9], out info.RequiredMinLevel);
- int.TryParse(data[10], out info.RequiredMaxLevel);
- int.TryParse(data[11], out info.RequiredQuest);
- byte.TryParse(data[12], out temp);
- info.RequiredClass = (RequiredClass)temp;
- if (isNew) EditEnvir.QuestInfoList.Add(info);
- }
- public string ToText()
- {
- return string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12}",
- Index, Name, Group, (byte)Type, FileName, GotoMessage, KillMessage, ItemMessage, FlagMessage, RequiredMinLevel, RequiredMaxLevel, RequiredQuest, (byte)RequiredClass);
- }
- public override string ToString()
- {
- return string.Format("{0}: {1}", Index, Name);
- }
- }
- public class QuestKillTask
- {
- public MonsterInfo Monster;
- public int Count;
- public string Message;
- }
- public class QuestItemTask
- {
- public ItemInfo Item;
- public ushort Count;
- public string Message;
- }
- public class QuestFlagTask
- {
- public int Number;
- public string Message;
- }
- }
|