diff --git a/Data/scripts/base/chara/npc/populace/PopulaceStandard.lua b/Data/scripts/base/chara/npc/populace/PopulaceStandard.lua index 77635106..90d06334 100644 --- a/Data/scripts/base/chara/npc/populace/PopulaceStandard.lua +++ b/Data/scripts/base/chara/npc/populace/PopulaceStandard.lua @@ -24,7 +24,6 @@ end function onEventStarted(player, npc, eventType, eventName) local defaultTalk = player:GetDefaultTalkQuest(npc); local tutorialTalk = player:GetTutorialQuest(npc); - local journalQuests = player:GetJournalQuestsForNpc(npc); local activeQuests = player:GetQuestsForNpc(npc); local possibleQuests = {}; @@ -35,9 +34,6 @@ function onEventStarted(player, npc, eventType, eventName) if (tutorialTalk ~= nil and eventType == ETYPE_TALK) then table.insert(possibleQuests, tutorialTalk); end - if (journalQuests ~= nil) then - table.insert(possibleQuests, unpack(journalQuests)); - end if (activeQuests ~= nil) then table.insert(possibleQuests, unpack(activeQuests)); end diff --git a/Data/scripts/quests/etc/etc3g0.lua b/Data/scripts/quests/etc/etc3g0.lua index d5f326b5..cacb5111 100644 --- a/Data/scripts/quests/etc/etc3g0.lua +++ b/Data/scripts/quests/etc/etc3g0.lua @@ -48,18 +48,19 @@ end function onFinish(player, quest) end -function onStateChange(player, quest, sequence) - if (sequence == 65536) then +function onStateChange(player, quest, sequence) + if (sequence == 65535) then quest:SetENpc(KINNISON, QFLAG_PLATE); end + local data = quest:GetData(); if (sequence == SEQ_000) then quest:SetENpc(KINNISON); - quest:SetENpc(SYBELL, (not quest:GetFlag(FLAG_TALKED_SYBELL) and QFLAG_PLATE or QFLAG_NONE)); - quest:SetENpc(KHUMA_MOSHROCA, (not quest:GetFlag(FLAG_TALKED_KHUMA_MOSHROCA) and QFLAG_PLATE or QFLAG_NONE)); - quest:SetENpc(NELLAURE, (not quest:GetFlag(FLAG_TALKED_NELLAURE) and QFLAG_PLATE or QFLAG_NONE)); - quest:SetENpc(MESTONNAUX, (not quest:GetFlag(FLAG_TALKED_MESTONNAUX) and QFLAG_PLATE or QFLAG_NONE)); - quest:SetENpc(LEFWYNE, (not quest:GetFlag(FLAG_TALKED_LEFWYNE) and QFLAG_PLATE or QFLAG_NONE)); + quest:SetENpc(SYBELL, (not data:GetFlag(FLAG_TALKED_SYBELL) and QFLAG_PLATE or QFLAG_NONE)); + quest:SetENpc(KHUMA_MOSHROCA, (not data:GetFlag(FLAG_TALKED_KHUMA_MOSHROCA) and QFLAG_PLATE or QFLAG_NONE)); + quest:SetENpc(NELLAURE, (not data:GetFlag(FLAG_TALKED_NELLAURE) and QFLAG_PLATE or QFLAG_NONE)); + quest:SetENpc(MESTONNAUX, (not data:GetFlag(FLAG_TALKED_MESTONNAUX) and QFLAG_PLATE or QFLAG_NONE)); + quest:SetENpc(LEFWYNE, (not data:GetFlag(FLAG_TALKED_LEFWYNE) and QFLAG_PLATE or QFLAG_NONE)); elseif (sequence == SEQ_001) then quest:SetENpc(KINNISON, QFLAG_PLATE); end @@ -74,67 +75,66 @@ function onTalk(player, quest, npc, eventName) if (npcClassId == KINNISON and not player:HasQuest(quest)) then local questAccepted = callClientFunction(player, "delegateEvent", player, quest, "processEventOffersStart"); if (questAccepted) then - player:AddQuest(quest); + player:AcceptQuest(quest); end player:EndEvent(); return; end -- Quest Progress + local data = quest:GetData(); if (seq == SEQ_000) then if (npcClassId == KINNISON) then callClientFunction(player, "delegateEvent", player, quest, "processEventOffersAfter"); elseif (npcClassId == SYBELL) then - if (not quest:GetFlag(FLAG_TALKED_SYBELL)) then + if (not data:GetFlag(FLAG_TALKED_SYBELL)) then callClientFunction(player, "delegateEvent", player, quest, "processEventSybellSpeak"); - quest:SetFlag(FLAG_TALKED_SYBELL); + data:SetFlag(FLAG_TALKED_SYBELL); incCounter = true; else callClientFunction(player, "delegateEvent", player, quest, "processEventSybellSpeakAfter"); end elseif (npcClassId == KHUMA_MOSHROCA) then - if (not quest:GetFlag(FLAG_TALKED_KHUMA_MOSHROCA)) then + if (not data:GetFlag(FLAG_TALKED_KHUMA_MOSHROCA)) then callClientFunction(player, "delegateEvent", player, quest, "processEventKhumaSpeak"); - quest:SetFlag(FLAG_TALKED_KHUMA_MOSHROCA); + data:SetFlag(FLAG_TALKED_KHUMA_MOSHROCA); incCounter = true; else callClientFunction(player, "delegateEvent", player, quest, "processEventKhumaSpeakAfter"); end elseif (npcClassId == NELLAURE) then - if (not quest:GetFlag(FLAG_TALKED_NELLAURE)) then + if (not data:GetFlag(FLAG_TALKED_NELLAURE)) then callClientFunction(player, "delegateEvent", player, quest, "processEventNellaureSpeak"); - quest:SetFlag(FLAG_TALKED_NELLAURE); + data:SetFlag(FLAG_TALKED_NELLAURE); incCounter = true; else callClientFunction(player, "delegateEvent", player, quest, "processEventNellaureSpeakAfter"); end elseif (npcClassId == MESTONNAUX) then - if (not quest:GetFlag(FLAG_TALKED_MESTONNAUX)) then + if (not data:GetFlag(FLAG_TALKED_MESTONNAUX)) then callClientFunction(player, "delegateEvent", player, quest, "processEventMestonnauxSpeak"); - quest:SetFlag(FLAG_TALKED_MESTONNAUX); + data:SetFlag(FLAG_TALKED_MESTONNAUX); incCounter = true; else callClientFunction(player, "delegateEvent", player, quest, "processEventMestonnauxSpeakAfter"); end elseif (npcClassId == LEFWYNE) then - if (not quest:GetFlag(FLAG_TALKED_LEFWYNE)) then + if (not data:GetFlag(FLAG_TALKED_LEFWYNE)) then callClientFunction(player, "delegateEvent", player, quest, "processEventLefwyneSpeak"); - quest:SetFlag(FLAG_TALKED_LEFWYNE); + data:SetFlag(FLAG_TALKED_LEFWYNE); incCounter = true; else callClientFunction(player, "delegateEvent", player, quest, "processEventLefwyneSpeakAfter"); end end - - + -- Increase objective counter & play relevant messages if (incCounter == true) then - quest:IncCounter(COUNTER_TALKED); - local counterAmount = quest:GetCounter(COUNTER_TALKED); + local counterAmount = data:IncCounter(COUNTER_TALKED); attentionMessage(player, 51061, 0, counterAmount, 5); -- You have heard word of the Seedseers. (... of 5) - if (seq000_checkCondition(quest)) then -- All Seers spoken to + if (seq000_checkCondition(data)) then -- All Seers spoken to attentionMessage(player, 25225, 110674); -- "Seeing the Seers" objectives complete! quest:UpdateENPCs(); -- Band-aid for a QFLAG_PLATE issue quest:StartSequence(SEQ_001); @@ -155,12 +155,12 @@ end -- Check if all seers are talked to -function seq000_checkCondition(quest) - return (quest:GetFlag(FLAG_TALKED_SYBELL) and - quest:GetFlag(FLAG_TALKED_KHUMA_MOSHROCA) and - quest:GetFlag(FLAG_TALKED_NELLAURE) and - quest:GetFlag(FLAG_TALKED_MESTONNAUX) and - quest:GetFlag(FLAG_TALKED_LEFWYNE)); +function seq000_checkCondition(data) + return (data:GetFlag(FLAG_TALKED_SYBELL) and + data:GetFlag(FLAG_TALKED_KHUMA_MOSHROCA) and + data:GetFlag(FLAG_TALKED_NELLAURE) and + data:GetFlag(FLAG_TALKED_MESTONNAUX) and + data:GetFlag(FLAG_TALKED_LEFWYNE)); end @@ -169,11 +169,11 @@ function getJournalMapMarkerList(player, quest) local possibleMarkers = {}; if (sequence == SEQ_000) then - if (not quest:GetFlag(FLAG_TALKED_SYBELL)) then table.insert(possibleMarkers, MRKR_SYBELL); end - if (not quest:GetFlag(FLAG_TALKED_KHUMA_MOSHROCA)) then table.insert(possibleMarkers, MRKR_KHUMA_MOSHROCA); end - if (not quest:GetFlag(FLAG_TALKED_NELLAURE)) then table.insert(possibleMarkers, MRKR_NELLAURE); end - if (not quest:GetFlag(FLAG_TALKED_MESTONNAUX)) then table.insert(possibleMarkers, MRKR_MESTONNAUX); end - if (not quest:GetFlag(FLAG_TALKED_LEFWYNE)) then table.insert(possibleMarkers, MRKR_LEFWYNE); end + if (not data:GetFlag(FLAG_TALKED_SYBELL)) then table.insert(possibleMarkers, MRKR_SYBELL); end + if (not data:GetFlag(FLAG_TALKED_KHUMA_MOSHROCA)) then table.insert(possibleMarkers, MRKR_KHUMA_MOSHROCA); end + if (not data:GetFlag(FLAG_TALKED_NELLAURE)) then table.insert(possibleMarkers, MRKR_NELLAURE); end + if (not data:GetFlag(FLAG_TALKED_MESTONNAUX)) then table.insert(possibleMarkers, MRKR_MESTONNAUX); end + if (not data:GetFlag(FLAG_TALKED_LEFWYNE)) then table.insert(possibleMarkers, MRKR_LEFWYNE); end elseif (sequence == SEQ_001) then table.insert(possibleMarkers, MRKR_KINNISON); end diff --git a/Map Server/Actors/Chara/Player/Player.cs b/Map Server/Actors/Chara/Player/Player.cs index 2a80d930..910cfda2 100644 --- a/Map Server/Actors/Chara/Player/Player.cs +++ b/Map Server/Actors/Chara/Player/Player.cs @@ -37,6 +37,7 @@ using Meteor.Map.actors.chara.ai.controllers; using Meteor.Map.actors.chara.ai.utils; using Meteor.Map.actors.chara.ai.state; using Meteor.Map.actors.chara; +using Meteor.Map.Actors.QuestNS; using Meteor.Map.packets.send; using Meteor.Map.packets.send.actor; using Meteor.Map.packets.send.events; @@ -277,7 +278,7 @@ namespace Meteor.Map.Actors CalculateBaseStats(); questStateManager = new QuestStateManager(this); - questStateManager.Init(); + questStateManager.Init(questScenario); } public List Create0x132Packets() @@ -806,7 +807,7 @@ namespace Meteor.Map.Actors foreach (Quest quest in questScenario) { if (quest != null) - quest.SaveData(); + quest.GetData().Save(); } } @@ -1418,33 +1419,253 @@ namespace Meteor.Map.Actors return -1; } - //For Lua calls, cause MoonSharp goes retard with uint - public void AddQuest(int id, bool isSilent = false) + #region Quests - Script Related + // Add quest from an active quest in the player's quest state. Quest scripts will use this to add a quest. + public bool AcceptQuest(Quest instance, bool isSilent = false) { - AddQuest((uint)id, isSilent); - } - public void CompleteQuest(int id) - { - CompleteQuest((uint)id); - } - public bool HasQuest(int id) - { - return HasQuest((uint)id); - } - public Quest GetQuest(int id) - { - return GetQuest((uint)id); - } - public bool IsQuestCompleted(int id) - { - return IsQuestCompleted((uint)id); - } - public bool CanAcceptQuest(int id) - { - return CanAcceptQuest((uint)id); - } - //For Lua calls, cause MoonSharp goes retard with uint + if (instance == null) + return false; + int freeSlot = GetFreeQuestSlot(); + + if (freeSlot == -1) + { + SendGameMessage(Server.GetWorldManager().GetActor(), 25234, 0x20); // "You cannot accept any more quests at this time." + return false; + } + + playerWork.questScenario[freeSlot] = instance.Id; + questScenario[freeSlot] = instance; + Database.SaveQuest(this, questScenario[freeSlot]); + SendQuestClientUpdate(freeSlot); + + if (!isSilent) + { + SendGameMessage(Server.GetWorldManager().GetActor(), 25224, 0x20, (object)questScenario[freeSlot].GetQuestId()); // " accepted." + } + + instance.OnAccept(); + + return true; + } + + // Replace a quest with another quest in the player's quest state. + public void ReplaceQuest(Quest oldQuestInstance, Quest newQuestInstance) + { + for (int i = 0; i < questScenario.Length; i++) + { + if (questScenario[i] != null && questScenario[i].Equals(oldQuestInstance)) + { + questScenario[i] = newQuestInstance; + playerWork.questScenario[i] = questScenario[i].Id; + Database.SaveQuest(this, questScenario[i]); + SendQuestClientUpdate(i); + break; + } + } + } + + public void CompleteQuest(Quest completed) + { + int slot = GetQuestSlot(completed); + if (slot >= 0) + { + // Remove the quest from the DB and update client work values + playerWork.questScenarioComplete[completed.GetQuestId() - 110001] = true; + Database.CompleteQuest(playerSession.GetActor(), completed.Id); + Database.RemoveQuest(this, completed.Id); + questScenario[slot] = null; + playerWork.questScenario[slot] = 0; + SendQuestClientUpdate(slot); + + // Reset active quest and quest state + completed.OnComplete(); + questStateManager.UpdateQuestCompleted(completed); + + // Msg Player + SendGameMessage(Server.GetWorldManager().GetActor(), 25086, 0x20, (object)completed.GetQuestId()); // " complete!" + } + + } + + public bool AbandonQuest(uint questId) + { + // Check if in an instance + if (CurrentArea.IsPrivate()) + { + SendGameMessage(Server.GetWorldManager().GetActor(), 25235, 0x20); // "Quests cannot be abandoned while from within an instance." + return false; + } + + // Get the quest object + int slot = GetQuestSlot(questId); + Quest abandoned = questScenario[slot]; + + if (abandoned == null) + return false; + + // Check if Main Scenario + if (abandoned.IsMainScenario()) + { + SendGameMessage(Server.GetWorldManager().GetActor(), 25233, 0x20); // "Main scenario quests cannot be abandoned." + return false; + } + + // Remove the quest from the DB and update client work values + Database.RemoveQuest(this, abandoned.Id); + questScenario[slot] = null; + playerWork.questScenario[slot] = 0; + SendQuestClientUpdate(slot); + + // Reset active quest and quest state + abandoned.OnAbandon(); + questStateManager.UpdateQuestAbandoned(); + + // Msg Player + SendGameMessage(this, Server.GetWorldManager().GetActor(), 25236, 0x20, (object)abandoned.GetQuestId()); // " abandoned." + return true; + } + + public bool HasQuest(Quest questInstance) + { + return GetQuestSlot(questInstance) != -1; + } + #endregion + + #region Quests - Debug/Misc Related + // Force-Add a quest by Id. Called be debug scripts. + public void AddQuest(uint id, bool isSilent = false) + { + Actor actor = Server.GetStaticActors((0xA0F00000 | id)); + AddQuest(actor.Name, isSilent); + } + + // Force-Add a quest by Name. Called be debug scripts. Will try to use an active quest, otherwise adds a new instance. + public void AddQuest(string name, bool isSilent = false) + { + Quest baseQuest = (Quest)Server.GetStaticActors(name); + Quest activeQuest = questStateManager.GetActiveQuest(baseQuest.GetQuestId()); + + int freeSlot = GetFreeQuestSlot(); + + if (freeSlot == -1) + return; + + playerWork.questScenario[freeSlot] = baseQuest.Id; + questScenario[freeSlot] = activeQuest ?? new Quest(this, baseQuest); + + if (activeQuest == null) + questStateManager.ForceAddActiveQuest(questScenario[freeSlot]); + + Database.SaveQuest(this, questScenario[freeSlot]); + SendQuestClientUpdate(freeSlot); + + if (!isSilent) + { + SendGameMessage(Server.GetWorldManager().GetActor(), 25224, 0x20, (object)questScenario[freeSlot].GetQuestId()); + } + + questScenario[freeSlot].OnAccept(); + } + + public void RemoveQuest(uint id) + { + for (int i = 0; i < questScenario.Length; i++) + { + if (questScenario[i] != null && questScenario[i].Id == (0xA0F00000 | id)) + { + Database.RemoveQuest(this, questScenario[i].Id); + questScenario[i] = null; + playerWork.questScenario[i] = 0; + SendQuestClientUpdate(i); + break; + } + } + } + + public void RemoveQuest(string name) + { + for (int i = 0; i < questScenario.Length; i++) + { + if (questScenario[i] != null && questScenario[i].Name.ToLower().Equals(name.ToLower())) + { + Database.RemoveQuest(this, questScenario[i].Id); + questScenario[i] = null; + playerWork.questScenario[i] = 0; + SendQuestClientUpdate(i); + break; + } + } + } + + public bool HasQuest(string name) + { + for (int i = 0; i < questScenario.Length; i++) + { + if (questScenario[i] != null && questScenario[i].Name.ToLower().Equals(name.ToLower())) + return true; + } + + return false; + } + + public bool HasQuest(uint id) + { + for (int i = 0; i < questScenario.Length; i++) + { + if (questScenario[i] != null && questScenario[i].Id == (0xA0F00000 | id)) + return true; + } + + return false; + } + + public Quest GetQuest(uint id) + { + for (int i = 0; i < questScenario.Length; i++) + { + if (questScenario[i] != null && questScenario[i].Id == (0xA0F00000 | id)) + return questScenario[i]; + } + + return null; + } + + public Quest GetQuest(string name) + { + for (int i = 0; i < questScenario.Length; i++) + { + if (questScenario[i] != null && questScenario[i].Name.ToLower().Equals(name.ToLower())) + return questScenario[i]; + } + + return null; + } + + public int GetQuestSlot(Quest quest) + { + for (int slot = 0; slot < questScenario.Length; slot++) + { + if (questScenario[slot] != null && questScenario[slot].Id == quest.Id) + return slot; + } + + return -1; + } + + public int GetQuestSlot(uint id) + { + for (int slot = 0; slot < questScenario.Length; slot++) + { + if (questScenario[slot] != null && questScenario[slot].GetQuestId() == id) + return slot; + } + + return -1; + } + #endregion + + #region Guildleves public void AddGuildleve(uint id) { int freeSlot = GetFreeGuildleveSlot(); @@ -1489,179 +1710,7 @@ namespace Meteor.Map.Actors } } } - } - - public void AddQuest(uint id, bool isSilent = false) - { - Actor actor = Server.GetStaticActors((0xA0F00000 | id)); - AddQuest(actor.Name, isSilent); - } - - public void AddQuest(string name, bool isSilent = false) - { - Quest baseQuest = (Quest) Server.GetStaticActors(name); - - if (baseQuest == null) - return; - - int freeSlot = GetFreeQuestSlot(); - - if (freeSlot == -1) - return; - - playerWork.questScenario[freeSlot] = baseQuest.Id; - questScenario[freeSlot] = new Quest(this, baseQuest); - Database.SaveQuest(this, questScenario[freeSlot]); - SendQuestClientUpdate(freeSlot); - - if (!isSilent) - { - SendGameMessage(Server.GetWorldManager().GetActor(), 25224, 0x20, (object)questScenario[freeSlot].GetQuestId()); - } - } - - public void CompleteQuest(uint id) - { - Actor actor = Server.GetStaticActors((0xA0F00000 | id)); - CompleteQuest(actor.Name); - } - - public void CompleteQuest(string name) - { - Actor actor = Server.GetStaticActors(name); - - if (actor == null) - return; - - uint id = actor.Id; - if (HasQuest(id)) - { - Database.CompleteQuest(playerSession.GetActor(), id); - SendGameMessage(Server.GetWorldManager().GetActor(), 25086, 0x20, (object)GetQuest(id).GetQuestId()); - RemoveQuest(id); - } - } - - //TODO: Add checks for you being in an instance or main scenario - public void AbandonQuest(uint id) - { - Quest quest = GetQuest(id); - RemoveQuestByQuestId(id); - quest.DoAbandon(); - } - - public void RemoveQuestByQuestId(uint id) - { - RemoveQuest((0xA0F00000 | id)); - } - - public void RemoveQuest(uint id) - { - if (HasQuest(id)) - { - for (int i = 0; i < questScenario.Length; i++) - { - if (questScenario[i] != null && questScenario[i].Id == id) - { - Database.RemoveQuest(this, questScenario[i].Id); - questScenario[i] = null; - playerWork.questScenario[i] = 0; - SendQuestClientUpdate(i); - break; - } - } - } - } - - public void ReplaceQuest(Quest oldQuest, string questCode) - { - for (int i = 0; i < questScenario.Length; i++) - { - if (questScenario[i] != null && questScenario[i].Equals(oldQuest)) - { - Quest baseQuest = (Quest) Server.GetStaticActors(questCode); - questScenario[i] = new Quest(this, baseQuest); - playerWork.questScenario[i] = questScenario[i].Id; - Database.SaveQuest(this, questScenario[i]); - SendQuestClientUpdate(i); - break; - } - } - } - - public bool CanAcceptQuest(string name) - { - if (!IsQuestCompleted(name) && !HasQuest(name)) - return true; - else - return false; - } - - public bool CanAcceptQuest(uint id) - { - Actor actor = Server.GetStaticActors((0xA0F00000 | id)); - return CanAcceptQuest(actor.Name); - } - - public bool IsQuestCompleted(string questName) - { - Actor actor = Server.GetStaticActors(questName); - return IsQuestCompleted(actor.Id); - } - - public bool IsQuestCompleted(uint questId) - { - return Database.IsQuestCompleted(this, 0xFFFFF & questId); - } - - public Quest GetQuest(uint id) - { - for (int i = 0; i < questScenario.Length; i++) - { - if (questScenario[i] != null && questScenario[i].Id == (0xA0F00000 | id)) - return questScenario[i]; - } - - return null; - } - - public Quest GetQuest(string name) - { - for (int i = 0; i < questScenario.Length; i++) - { - if (questScenario[i] != null && questScenario[i].Name.ToLower().Equals(name.ToLower())) - return questScenario[i]; - } - - return null; - } - - public bool HasQuest(string name) - { - for (int i = 0; i < questScenario.Length; i++) - { - if (questScenario[i] != null && questScenario[i].Name.ToLower().Equals(name.ToLower())) - return true; - } - - return false; - } - - public bool HasQuest(uint id) - { - for (int i = 0; i < questScenario.Length; i++) - { - if (questScenario[i] != null && questScenario[i].Id == (0xA0F00000 | id)) - return true; - } - - return false; - } - - public bool HasQuest(Quest quest) - { - return HasQuest(quest.className); - } + } public bool HasGuildleve(uint id) { @@ -1673,17 +1722,7 @@ namespace Meteor.Map.Actors return false; } - - public int GetQuestSlot(uint id) - { - for (int i = 0; i < questScenario.Length; i++) - { - if (questScenario[i] != null && questScenario[i].Id == (0xA0F00000 | id)) - return i; - } - - return -1; - } + #endregion public Quest GetDefaultTalkQuest(Npc npc) { @@ -1735,14 +1774,11 @@ namespace Meteor.Map.Actors return null; } - public Quest[] GetJournalQuestsForNpc(Npc npc) - { - return Array.FindAll(questScenario, e => e != null && e.IsQuestENPC(this, npc)); - } - public Quest[] GetQuestsForNpc(Npc npc) { - return questStateManager.GetQuestsForNpc(npc); + Quest[] quests = questStateManager.GetQuestsForNpc(npc); + Array.Sort(quests, (q1, q2) => (q1.HasData() ? 1 : 0) - (q2.HasData() ? 1 : 0)); + return quests; } public void HandleNpcLS(uint id) @@ -2765,6 +2801,7 @@ namespace Meteor.Map.Actors actionList.Add(new CommandResult(Id, 33909, 0, (ushort)charaWork.battleSave.skillLevel[classId - 1])); EquipAbilitiesAtLevel(classId, GetLevel(), actionList); + questStateManager.UpdateLevel(GetHighestLevel()); } } diff --git a/Map Server/Actors/Quest/Quest.cs b/Map Server/Actors/Quest/Quest.cs index 67d246df..ee594f85 100644 --- a/Map Server/Actors/Quest/Quest.cs +++ b/Map Server/Actors/Quest/Quest.cs @@ -20,69 +20,127 @@ along with Project Meteor Server. If not, see . */ using Meteor.Map.lua; -using Newtonsoft.Json; using System; using System.Collections.Generic; -namespace Meteor.Map.Actors +namespace Meteor.Map.Actors.QuestNS { class Quest : Actor { public const ushort SEQ_NOT_STARTED = 65535; public const ushort SEQ_COMPLETED = 65534; - private struct QuestData - { - public UInt32 flags; - public UInt16 counter1; - public UInt16 counter2; - public UInt16 counter3; - public UInt16 counter4; - - public QuestData(uint flags, ushort counter1, ushort counter2, ushort counter3) : this() - { - this.flags = flags; - this.counter1 = counter1; - this.counter2 = counter2; - this.counter3 = counter3; - } - } - - // This is only set on instance quests (non static) - private Player Owner; + private Player owner; private ushort currentSequence; - private QuestState QuestState; - private QuestData Data; + private QuestState questState = null; + private QuestData data = null; private bool dataDirty = false; + // Creates a Static Quest for the StaticActors list. + public Quest(uint actorID, string className, string classPath) + : base(actorID) + { + Name = className; + this.className = className; + this.classPath = classPath; + } + + // Creates a Static Quest from another Static Quest + public Quest(Quest staticQuest) + : this(staticQuest.Id, staticQuest.Name, staticQuest.classPath) + { } + + // Creates a Instance Quest that has been started. + public Quest(Player owner, Quest staticQuest, ushort sequence) : this(staticQuest) + { + this.owner = owner; + currentSequence = sequence; + questState = new QuestState(owner, this); + questState.UpdateState(); + } + + // Creates a Instance Quest that has not been started. + public Quest(Player owner, Quest staticQuest) : this(owner, staticQuest, SEQ_NOT_STARTED) + { } + + #region Getters + public uint GetQuestId() + { + return Id & 0xFFFFF; + } + + public override bool Equals(object obj) + { + if (obj != null && obj is Quest quest) + return quest.Id == this.Id; + return false; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + public bool IsInstance() + { + return questState != null; + } + + public bool IsMainScenario() + { + uint id = GetQuestId(); + return id >= 110001 && id <= 110021; + } + + public ushort GetSequence() + { + return currentSequence; + } + #endregion + + #region Quest Data + public void SetData(uint flags, ushort counter1, ushort counter2, ushort counter3, ushort counter4) + { + data = new QuestData(owner, this, flags, counter1, counter2, counter3, counter4); + } + + public QuestData GetData() + { + return data; + } + + public bool HasData() + { + return data != null; + } + #endregion + + #region Quest State public void SetENpc(uint classId, byte flagType = 0, bool isTalkEnabled = true, bool isPushEnabled = false, bool isEmoteEnabled = false, bool isSpawned = false) { - if (QuestState != null) - QuestState.AddENpc(classId, flagType, isTalkEnabled, isPushEnabled, isEmoteEnabled, isSpawned); + if (questState != null) + questState.AddENpc(classId, flagType, isTalkEnabled, isPushEnabled, isEmoteEnabled, isSpawned); } public void UpdateENPCs() { if (dataDirty) { - if (QuestState != null) - QuestState.UpdateState(); + if (questState != null) + questState.UpdateState(); dataDirty = false; } } public QuestState GetQuestState() { - return QuestState; - } - - public bool IsInstance() - { - return Owner != null; + return questState; } + #endregion + #region Script Callbacks public void OnTalk(Player caller, Npc npc) - { + { LuaEngine.GetInstance().CallLuaFunction(caller, this, "onTalk", true, npc); } @@ -106,17 +164,9 @@ namespace Meteor.Map.Actors LuaEngine.GetInstance().CallLuaFunction(caller, this, "onNpcLS", true, npcLSId); } - public bool IsQuestENPC(Player caller, Npc npc) - { - List returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(caller, this, "IsQuestENPC", true, npc, this); - bool scriptReturned = returned != null && returned.Count != 0 && returned[0].typeID == 3; - return scriptReturned || QuestState.HasENpc(npc.GetActorClassId()); - } - - public object[] GetJournalInformation() { - List returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(Owner, this, "getJournalInformation", true); + List returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(owner, this, "getJournalInformation", true); if (returned != null && returned.Count != 0) return LuaUtils.CreateLuaParamObjectList(returned); else @@ -125,212 +175,59 @@ namespace Meteor.Map.Actors public object[] GetJournalMapMarkerList() { - List returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(Owner, this, "getJournalMapMarkerList", true); + List returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(owner, this, "getJournalMapMarkerList", true); if (returned != null && returned.Count != 0) return LuaUtils.CreateLuaParamObjectList(returned); else return new object[0]; } + #endregion - public ushort GetSequence() + public bool IsQuestENPC(Player caller, Npc npc) { - return currentSequence; + List returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(caller, this, "IsQuestENPC", true, npc, this); + bool scriptReturned = returned != null && returned.Count != 0 && returned[0].typeID == 3; + return scriptReturned || questState.HasENpc(npc.GetActorClassId()); } public void StartSequence(ushort sequence) - { + { if (sequence == SEQ_NOT_STARTED) return; // Send the message that the journal has been updated if (currentSequence != SEQ_NOT_STARTED) - Owner.SendGameMessage(Server.GetWorldManager().GetActor(), 25116, 0x20, (object)GetQuestId()); + owner.SendGameMessage(Server.GetWorldManager().GetActor(), 25116, 0x20, (object)GetQuestId()); currentSequence = sequence; dataDirty = true; - UpdateENPCs(); + questState.UpdateState(); } - public void ClearData() - { - Data.flags = Data.counter1 = Data.counter2 = Data.counter3 = Data.counter4 = 0; - } - - public void SetFlag(int index) - { - if (index >= 0 && index < 32) - { - Data.flags |= (uint)(1 << index); - dataDirty = true; - } - } - - public void ClearFlag(int index) - { - if (index >= 0 && index < 32) - { - Data.flags &= (uint)~(1 << index); - dataDirty = true; - } - } - - public void IncCounter(int num) - { - dataDirty = true; - - switch (num) - { - case 0: - Data.counter1++; - return; - case 1: - Data.counter2++; - return; - case 2: - Data.counter3++; - return; - case 3: - Data.counter4++; - return; - } - - dataDirty = false; - } - - public void DecCounter(int num) - { - dataDirty = true; - - switch (num) - { - case 0: - Data.counter1--; - return; - case 1: - Data.counter2--; - return; - case 2: - Data.counter3--; - return; - case 3: - Data.counter4--; - return; - } - - dataDirty = false; - } - - public void SetCounter(int num, ushort value) - { - dataDirty = true; - - switch (num) - { - case 0: - Data.counter1 = value; - return; - case 1: - Data.counter2 = value; - return; - case 2: - Data.counter3 = value; - return; - case 3: - Data.counter4 = value; - return; - } - - dataDirty = false; - } - - public bool GetFlag(int index) - { - if (index >= 0 && index < 32) - return (Data.flags & (uint) (1 << index)) != 0; - return false; - } - - public uint GetFlags() - { - return Data.flags; - } - - public ushort GetCounter(int num) - { - switch (num) - { - case 0: - return Data.counter1; - case 1: - return Data.counter2; - case 2: - return Data.counter3; - case 3: - return Data.counter4; - } - - return 0; - } - - public void SaveData() - { - Database.SaveQuest(Owner, this); - } - - public Quest(uint actorID, string name) - : base(actorID) - { - Name = name; - } - - public Quest(Player owner, Quest baseQuest): this(owner, baseQuest, SEQ_NOT_STARTED, 0, 0, 0, 0) - {} - - public Quest(Player owner, Quest baseQuest, ushort sequence, uint flags, ushort counter1, ushort counter2, ushort counter3) - : base(baseQuest.Id) - { - Owner = owner; - Name = baseQuest.Name; - className = baseQuest.className; - classPath = baseQuest.classPath; - currentSequence = sequence; - QuestState = new QuestState(owner, this); - Data = new QuestData(flags, counter1, counter2, counter3); - } - - public uint GetQuestId() - { - return Id & 0xFFFFF; - } - - public void DoAccept() + public void OnAccept() { + data = new QuestData(owner, this); if (currentSequence == SEQ_NOT_STARTED) - LuaEngine.GetInstance().CallLuaFunction(Owner, this, "onStart", false); + LuaEngine.GetInstance().CallLuaFunction(owner, this, "onStart", false); else StartSequence(currentSequence); } - public void DoComplete() + public void OnComplete() { - LuaEngine.GetInstance().CallLuaFunctionForReturn(Owner, this, "onFinish", true); - Owner.SendDataPacket("attention", Server.GetWorldManager().GetActor(), "", 25225, (object)GetQuestId()); - Owner.SendGameMessage(Server.GetWorldManager().GetActor(), 25225, 0x20, (object)GetQuestId()); + LuaEngine.GetInstance().CallLuaFunctionForReturn(owner, this, "onFinish", true); currentSequence = SEQ_COMPLETED; + data = null; + questState.UpdateState(); } - public void DoAbandon() + public void OnAbandon() { - LuaEngine.GetInstance().CallLuaFunctionForReturn(Owner, this, "onFinish", false); - Owner.SendGameMessage(Owner, Server.GetWorldManager().GetActor(), 25236, 0x20, (object)GetQuestId()); + LuaEngine.GetInstance().CallLuaFunctionForReturn(owner, this, "onFinish", false); currentSequence = SEQ_NOT_STARTED; + data = null; + questState.UpdateState(); } - public override bool Equals(object obj) - { - if (obj is Quest quest) - return quest.Id == this.Id; - return false; - } } } diff --git a/Map Server/Actors/Quest/QuestData.cs b/Map Server/Actors/Quest/QuestData.cs new file mode 100644 index 00000000..6b0818db --- /dev/null +++ b/Map Server/Actors/Quest/QuestData.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Meteor.Map.Actors.QuestNS +{ + class QuestData + { + private Player owner; + private Quest parent; + + private uint flags; + private ushort counter1; + private ushort counter2; + private ushort counter3; + private ushort counter4; + private bool dataDirty = false; + + public QuestData(Player owner, Quest parent, uint flags, ushort counter1, ushort counter2, ushort counter3, ushort counter4) + { + this.owner = owner; + this.parent = parent; + this.flags = flags; + this.counter1 = counter1; + this.counter2 = counter2; + this.counter3 = counter3; + this.counter4 = counter4; + } + + public QuestData(Player owner, Quest parent) + { + this.owner = owner; + this.parent = parent; + flags = counter1 = counter2 = counter3 = counter4 = 0; + } + + public void ClearData() + { + flags = counter1 = counter2 = counter3 = counter4 = 0; + } + + public void SetFlag(int index) + { + if (index >= 0 && index < 32) + { + flags |= (uint)(1 << index); + dataDirty = true; + } + } + + public void ClearFlag(int index) + { + if (index >= 0 && index < 32) + { + flags &= (uint)~(1 << index); + dataDirty = true; + } + } + + public ushort IncCounter(int num) + { + dataDirty = true; + + switch (num) + { + case 0: + counter1++; + return counter1; + case 1: + counter2++; + return counter2; + case 2: + counter3++; + return counter3; + case 3: + counter4++; + return counter4; + } + + dataDirty = false; + return 0; + } + + public ushort DecCounter(int num) + { + dataDirty = true; + + switch (num) + { + case 0: + counter1--; + return counter1; + case 1: + counter2--; + return counter2; + case 2: + counter3--; + return counter3; + case 3: + counter4--; + return counter4; + } + + dataDirty = false; + return 0; + } + + public void SetCounter(int num, ushort value) + { + dataDirty = true; + + switch (num) + { + case 0: + counter1 = value; + return; + case 1: + counter2 = value; + return; + case 2: + counter3 = value; + return; + case 3: + counter4 = value; + return; + } + + dataDirty = false; + } + + public bool GetFlag(int index) + { + if (index >= 0 && index < 32) + return (flags & (uint)(1 << index)) != 0; + return false; + } + + public uint GetFlags() + { + return flags; + } + + public ushort GetCounter(int num) + { + switch (num) + { + case 0: + return counter1; + case 1: + return counter2; + case 2: + return counter3; + case 3: + return counter4; + } + + return 0; + } + + public void Save() + { + Database.SaveQuest(owner, parent); + } + } +} diff --git a/Map Server/Actors/Quest/QuestState.cs b/Map Server/Actors/Quest/QuestState.cs index 068083cd..d950b2ca 100644 --- a/Map Server/Actors/Quest/QuestState.cs +++ b/Map Server/Actors/Quest/QuestState.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Meteor.Map.Actors +namespace Meteor.Map.Actors.QuestNS { class QuestState { @@ -49,8 +49,8 @@ namespace Meteor.Map.Actors } } - private Player Owner; - private Quest Parent; + private readonly Player Owner; + private readonly Quest Parent; private Dictionary CurrentENPCs = new Dictionary(); private Dictionary OldENPCs = new Dictionary(); @@ -58,7 +58,6 @@ namespace Meteor.Map.Actors { Owner = owner; Parent = parent; - UpdateState(); } public void AddENpc(uint classId, byte flagType = 0, bool isTalkEnabled = true, bool isPushEnabled = false, bool isEmoteEnabled = false, bool isSpawned = false) @@ -105,8 +104,15 @@ namespace Meteor.Map.Actors CurrentENPCs = new Dictionary(); LuaEngine.GetInstance().CallLuaFunctionForReturn(Owner, Parent, "onStateChange", false, currentSeq); foreach (var enpc in OldENPCs) - Owner.playerSession.UpdateQuestNpcInInstance(enpc.Value); + Owner.playerSession.UpdateQuestNpcInInstance(enpc.Value, true); OldENPCs = null; } + + public void DeleteState() + { + foreach (var enpc in CurrentENPCs) + Owner.playerSession.UpdateQuestNpcInInstance(enpc.Value, true); + CurrentENPCs.Clear(); + } } } diff --git a/Map Server/Actors/Quest/QuestStateManager.cs b/Map Server/Actors/Quest/QuestStateManager.cs index e2e2bf7d..23452b88 100644 --- a/Map Server/Actors/Quest/QuestStateManager.cs +++ b/Map Server/Actors/Quest/QuestStateManager.cs @@ -7,7 +7,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Meteor.Map.Actors +namespace Meteor.Map.Actors.QuestNS { class QuestStateManager { @@ -21,16 +21,30 @@ namespace Meteor.Map.Actors private readonly Bitstream GCRankBitfield = new Bitstream(SCENARIO_MAX, true); private List ActiveQuests = new List(); + private Dictionary QuestStateTable = new Dictionary(); public QuestStateManager(Player player) { this.player = player; } - public void Init() + public void Init(Quest[] questScenario) { + // Preload any quests that the player loaded + if (questScenario != null) + { + foreach (var quest in questScenario) + { + if (quest != null) + { + ActiveQuests.Add(quest); + AvailableQuestsBitfield.Set(quest.GetQuestId() - SCENARIO_START); + } + } + } + // Init MinLv - QuestData[] minLvl = Server.GetQuestGamedataByMaxLvl(player.GetHighestLevel(), true); + QuestGameData[] minLvl = Server.GetQuestGamedataByMaxLvl(player.GetHighestLevel(), true); foreach (var questData in minLvl) MinLevelBitfield.Set(questData.Id - SCENARIO_START); @@ -43,28 +57,29 @@ namespace Meteor.Map.Actors else PrereqBitfield.Clear(questData.Id - SCENARIO_START); } + ComputeAvailable(); } public void UpdateLevel(int level) { - QuestData[] updated = Server.GetQuestGamedataByMaxLvl(level); + QuestGameData[] updated = Server.GetQuestGamedataByMaxLvl(level); foreach (var questData in updated) MinLevelBitfield.Set(questData.Id - SCENARIO_START); ComputeAvailable(); } - public void UpdateQuestComplete(Quest quest) + public void UpdateQuestCompleted(Quest quest) { - QuestData[] updated = Server.GetQuestGamedataByPrerequisite(quest.GetQuestId()); + QuestGameData[] updated = Server.GetQuestGamedataByPrerequisite(quest.GetQuestId()); foreach (var questData in updated) PrereqBitfield.Set(questData.Id - SCENARIO_START); ComputeAvailable(); } - public void QuestAdded(Quest quest) + public void UpdateQuestAbandoned() { - ActiveQuests.Remove(quest); + ComputeAvailable(); } private void ComputeAvailable() @@ -90,9 +105,9 @@ namespace Meteor.Map.Actors int index = i * 8 + shift; Quest quest = (Quest)Server.GetStaticActors(0xA0F00000 | (SCENARIO_START + (uint)index)); if (!AvailableQuestsBitfield.Get(index)) - ActiveQuests.Add(new Quest(player, quest)); + AddActiveQuest(quest); else - ActiveQuests.Remove(quest); + RemoveActiveQuest(quest); } } } @@ -100,6 +115,39 @@ namespace Meteor.Map.Actors AvailableQuestsBitfield.SetTo(result); } + public void ForceAddActiveQuest(Quest questInstance) + { + ActiveQuests.Add(questInstance); + QuestStateTable.Add(questInstance.Id, questInstance.GetQuestState()); + } + + private void AddActiveQuest(Quest staticQuest) + { + Quest instance = new Quest(player, staticQuest); + ActiveQuests.Add(instance); + QuestStateTable.Add(staticQuest.Id, instance.GetQuestState()); + } + + private void RemoveActiveQuest(Quest staticQuest) + { + // Do not remove quests in the player's journal + if (player.HasQuest(staticQuest.GetQuestId())) + return; + + ActiveQuests.Remove(staticQuest); + + if (QuestStateTable.ContainsKey(staticQuest.Id)) + { + QuestStateTable[staticQuest.Id].DeleteState(); + QuestStateTable.Remove(staticQuest.Id); + } + } + + public Quest GetActiveQuest(uint id) + { + return ActiveQuests.Find(quest => quest.GetQuestId() == id); + } + public Quest[] GetQuestsForNpc(Npc npc) { return ActiveQuests.FindAll(quest => quest.IsQuestENPC(player, npc)).ToArray(); diff --git a/Map Server/Actors/StaticActors.cs b/Map Server/Actors/StaticActors.cs index 73082cf8..c5b002c6 100644 --- a/Map Server/Actors/StaticActors.cs +++ b/Map Server/Actors/StaticActors.cs @@ -20,6 +20,7 @@ along with Project Meteor Server. If not, see . */ using Meteor.Common; +using Meteor.Map.Actors.QuestNS; using System; using System.Collections.Generic; using System.IO; @@ -98,7 +99,7 @@ namespace Meteor.Map.Actors if (actorType.Equals("Command")) actor = new Command(id, actorName); else if (actorType.Equals("Quest")) - actor = new Quest(id, actorName); + actor = new Quest(id, actorName, output); //else if (actorType.Equals("Status")) //mStaticActors.Add(id, new Status(id, actorName)); else if (actorType.Equals("Judge")) diff --git a/Map Server/DataObjects/QuestData.cs b/Map Server/DataObjects/QuestGameData.cs similarity index 82% rename from Map Server/DataObjects/QuestData.cs rename to Map Server/DataObjects/QuestGameData.cs index 3054f64f..98723b7b 100644 --- a/Map Server/DataObjects/QuestData.cs +++ b/Map Server/DataObjects/QuestGameData.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace Meteor.Map.DataObjects { - class QuestData + class QuestGameData { public uint Id { get; } public string ClassName { get; } @@ -15,7 +15,7 @@ namespace Meteor.Map.DataObjects public int MinLevel { get; } public int MinGCRank { get; } - public QuestData(uint id, string className, string name, uint prereq, int minLv, int minGcRank) + public QuestGameData(uint id, string className, string name, uint prereq, int minLv, int minGcRank) { Id = id; ClassName = className; diff --git a/Map Server/DataObjects/Session.cs b/Map Server/DataObjects/Session.cs index 299fa72c..28233d26 100644 --- a/Map Server/DataObjects/Session.cs +++ b/Map Server/DataObjects/Session.cs @@ -25,8 +25,8 @@ using Meteor.Map.Actors; using Meteor.Map.packets.send.actor; using System.Collections.Generic; using Meteor.Map.actors.chara.npc; -using static Meteor.Map.Actors.Quest; -using static Meteor.Map.Actors.QuestState; +using Meteor.Map.Actors.QuestNS; +using static Meteor.Map.Actors.QuestNS.QuestState; namespace Meteor.Map.DataObjects { diff --git a/Map Server/Database.cs b/Map Server/Database.cs index 129062ba..aab35607 100644 --- a/Map Server/Database.cs +++ b/Map Server/Database.cs @@ -28,12 +28,13 @@ using Meteor.Map.utils; using Meteor.Map.packets.send.player; using Meteor.Map.DataObjects; using Meteor.Map.Actors; +using Meteor.Map.Actors.QuestNS; using Meteor.Map.actors.chara.player; using Meteor.Map.packets.receive.supportdesk; using Meteor.Map.actors.chara.npc; using Meteor.Map.actors.chara.ai; using Meteor.Map.packets.send.actor.battle; -using Meteor.Map.DataObjects; + using System.Security.Cryptography; namespace Meteor.Map @@ -72,11 +73,11 @@ namespace Meteor.Map return id; } - public static Dictionary GetQuestGamedata() + public static Dictionary GetQuestGamedata() { using (var conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD))) { - Dictionary gamedataQuests = new Dictionary(); + Dictionary gamedataQuests = new Dictionary(); try { @@ -88,8 +89,7 @@ namespace Meteor.Map className, questName, prerequisite, - minLevel, - minGCRank + minLevel FROM gamedata_quests "; @@ -104,8 +104,8 @@ namespace Meteor.Map string name = reader.GetString("questName"); uint prerequisite = reader.GetUInt32("prerequisite"); ushort minLevel = reader.GetUInt16("minLevel"); - ushort minRank = reader.GetUInt16("minGCRank"); - gamedataQuests.Add(questId, new QuestData(questId, code, name, prerequisite, minLevel, minRank)); + //ushort minRank = reader.GetUInt16("minGCRank"); + gamedataQuests.Add(questId, new QuestGameData(questId, code, name, prerequisite, minLevel, 0)); } } } @@ -544,6 +544,8 @@ namespace Meteor.Map string query; MySqlCommand cmd; + QuestData qData = quest.GetData(); + using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD))) { try @@ -564,10 +566,14 @@ namespace Meteor.Map cmd.Parameters.AddWithValue("@slot", slot); cmd.Parameters.AddWithValue("@questId", 0xFFFFF & quest.Id); cmd.Parameters.AddWithValue("@sequence", quest.GetSequence()); - cmd.Parameters.AddWithValue("@flags", quest.GetFlags()); - cmd.Parameters.AddWithValue("@counter1", quest.GetCounter(1)); - cmd.Parameters.AddWithValue("@counter2", quest.GetCounter(2)); - cmd.Parameters.AddWithValue("@counter3", quest.GetCounter(3)); + + if (qData != null) + { + cmd.Parameters.AddWithValue("@flags", qData.GetFlags()); + cmd.Parameters.AddWithValue("@counter1", qData.GetCounter(1)); + cmd.Parameters.AddWithValue("@counter2", qData.GetCounter(2)); + cmd.Parameters.AddWithValue("@counter3", qData.GetCounter(3)); + } cmd.ExecuteNonQuery(); } @@ -1218,11 +1224,13 @@ namespace Meteor.Map ushort counter1 = reader.GetUInt16("counter1"); ushort counter2 = reader.GetUInt16("counter2"); ushort counter3 = reader.GetUInt16("counter3"); + //ushort counter4 = reader.GetUInt16("counter4"); Quest baseQuest = (Quest) Server.GetStaticActors(questId); player.playerWork.questScenario[index] = questId; - player.questScenario[index] = new Quest(player, baseQuest, sequence, flags, counter1, counter2, counter3); + player.questScenario[index] = new Quest(player, baseQuest, sequence); + player.questScenario[index].SetData(flags, counter1, counter2, counter3, 0); } } diff --git a/Map Server/Lua/LuaEngine.cs b/Map Server/Lua/LuaEngine.cs index 2a05fbd7..dc106826 100644 --- a/Map Server/Lua/LuaEngine.cs +++ b/Map Server/Lua/LuaEngine.cs @@ -27,7 +27,6 @@ using Meteor.Map.packets.receive.events; using Meteor.Map.packets.send; using Meteor.Map.packets.send.events; using MoonSharp.Interpreter; -using MoonSharp.Interpreter.Interop; using MoonSharp.Interpreter.Loaders; using System; using System.Collections.Generic; @@ -37,11 +36,11 @@ using Meteor.Map.actors.area; using System.Threading; using Meteor.Map.actors.chara.ai; using Meteor.Map.actors.chara.ai.controllers; -using Meteor.Map.DataObjects; using Meteor.Map.actors.chara.player; using Meteor.Map.Actors.Chara; using Meteor.Map.DataObjects.chara; using Meteor.Map.actors.chara; +using Meteor.Map.Actors.QuestNS; namespace Meteor.Map.lua { @@ -78,6 +77,7 @@ namespace Meteor.Map.lua UserData.RegisterType(); UserData.RegisterType(); UserData.RegisterType(); + UserData.RegisterType(); UserData.RegisterType(); UserData.RegisterType(); UserData.RegisterType(); diff --git a/Map Server/Map Server.csproj b/Map Server/Map Server.csproj index 8d421cd9..3698fc77 100644 --- a/Map Server/Map Server.csproj +++ b/Map Server/Map Server.csproj @@ -180,12 +180,13 @@ + - + diff --git a/Map Server/Server.cs b/Map Server/Server.cs index af4724bf..c3407354 100644 --- a/Map Server/Server.cs +++ b/Map Server/Server.cs @@ -50,7 +50,7 @@ namespace Meteor.Map private static WorldManager WorldManager; private static Dictionary GamedataItems; private static Dictionary GamedataGuildleves; - private static Dictionary GamedataQuests; + private static Dictionary GamedataQuests; private static StaticActors StaticActors; private PacketProcessor mProcessor; @@ -332,7 +332,7 @@ namespace Meteor.Map return null; } - public static QuestData GetQuestGamedata(uint id) + public static QuestGameData GetQuestGamedata(uint id) { if (GamedataQuests.ContainsKey(id)) return GamedataQuests[id]; @@ -341,7 +341,7 @@ namespace Meteor.Map } - public static QuestData[] GetQuestGamedataByMaxLvl(int lvl, bool all = false) + public static QuestGameData[] GetQuestGamedataByMaxLvl(int lvl, bool all = false) { if (all) return GamedataQuests.Values.Where(quest => quest.MinLevel > 0 && quest.MinLevel <= lvl).ToArray(); @@ -349,17 +349,17 @@ namespace Meteor.Map return GamedataQuests.Values.Where(quest => quest.MinLevel > 0 && quest.MinLevel == lvl).ToArray(); } - public static QuestData[] GetQuestGamedataByPrerequisite(uint questId) + public static QuestGameData[] GetQuestGamedataByPrerequisite(uint questId) { return GamedataQuests.Values.Where(quest => quest.PrerequisiteQuest == questId).ToArray(); } - public static QuestData[] GetQuestGamedataAllPrerequisite() + public static QuestGameData[] GetQuestGamedataAllPrerequisite() { return GamedataQuests.Values.Where(quest => quest.PrerequisiteQuest != 0).ToArray(); } - public static QuestData[] GetQuestGamedataAllGCRanked() + public static QuestGameData[] GetQuestGamedataAllGCRanked() { return GamedataQuests.Values.Where(quest => quest.MinGCRank != 0).ToArray(); }