From 49c6fdbd51317ec51d2952760fb7c8710fb818a5 Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Sat, 5 Mar 2022 01:02:41 -0500 Subject: [PATCH] Added functionality to handle NPC LSes in quests. Linked the rest of the sequences up for Man0l1. --- .../commands/NpcLinkshellChatCommand.lua | 11 +- Data/scripts/quests/man/man0l1.lua | 110 ++++++++++-------- Map Server/Actors/Chara/Player/Player.cs | 12 +- Map Server/Actors/Quest/Quest.cs | 45 ++++++- Map Server/Actors/Quest/QuestData.cs | 35 +++++- Map Server/Database.cs | 29 +++-- 6 files changed, 166 insertions(+), 76 deletions(-) diff --git a/Data/scripts/commands/NpcLinkshellChatCommand.lua b/Data/scripts/commands/NpcLinkshellChatCommand.lua index d1614e18..a9826adc 100644 --- a/Data/scripts/commands/NpcLinkshellChatCommand.lua +++ b/Data/scripts/commands/NpcLinkshellChatCommand.lua @@ -4,13 +4,14 @@ require ("global") NpcLinkshellChatCommand Script -Handler for when a player clicks a npc ls to talk to. If adding new linkshells to the handle, make sure to add -it to the handler table (with correct offset), and that your function is above the handler. If padding is needed -to hit some ID, add "nils". +Player class will go through all quests and see if there are active msgs for one. If there was, it will +return true and that quest must end the event (if needed). Otherwise if nothing caught the event, the +event is ended here. --]] function onEventStarted(player, command, eventType, eventName, npcLsId) - player:HandleNpcLS(npcLsId); - player:EndEvent(); + if (player:HandleNpcLs(npcLsId) == false) then + player:EndEvent(); + end end diff --git a/Data/scripts/quests/man/man0l1.lua b/Data/scripts/quests/man/man0l1.lua index 5c9e069a..f630ece2 100644 --- a/Data/scripts/quests/man/man0l1.lua +++ b/Data/scripts/quests/man/man0l1.lua @@ -56,7 +56,7 @@ ISANDOREL = 1000152; MERLZIRN = 1000472; MSK_TRIGGER = 1090001; --- Echo in Mrd Guild +-- Echo in MSK Guild NERVOUS_BARRACUDA = 1000096; INTIMIDATING_BARRACUDA = 1000097; OVEREAGER_BARRACUDA = 1000107; @@ -97,10 +97,18 @@ ECHO_EXIT_TRIGGER2 = 1090001; -- Quest Data CNTR_SEQ7_CUL = 1; -CNTR_SEQ7_MRD = 2; +CNTR_SEQ7_MSK = 2; CNTR_SEQ40_FSH = 3; CNTR_LS_MSG = 4; +-- Msg packs for the Npc LS +NPCLS_MSGS = { + {339}, + {80, 81, 82}, + {248, 249}, + {161, 162, 163, 164} +}; + function onStart(player, quest) quest:StartSequence(SEQ_000); @@ -138,18 +146,18 @@ function onStateChange(player, quest, sequence) quest:SetENpc(BADERON, QFLAG_PLATE); elseif (sequence == SEQ_007) then local subseqCUL = data:GetCounter(CNTR_SEQ7_CUL); - local subseqMRD = data:GetCounter(CNTR_SEQ7_MRD); + local subseqMSK = data:GetCounter(CNTR_SEQ7_MSK); -- Always active in this seqence quest:SetENpc(BADERON); quest:SetENpc(CHARLYS, subseqCUL == 0 and QFLAG_PLATE or QFLAG_NONE); -- Down and Up the MSK guild - quest:SetENpc(ISANDOREL, (subseqMRD == 0 or subseqMRD == 2) and QFLAG_PLATE or QFLAG_NONE); + quest:SetENpc(ISANDOREL, (subseqMSK == 0 or subseqMSK == 2) and QFLAG_PLATE or QFLAG_NONE); - if (subseqMRD == 1) then + if (subseqMSK == 1) then quest:SetENpc(MSK_TRIGGER, QFLAG_MAP, false, true); - elseif (subseqMRD == 2) then + elseif (subseqMSK == 2) then quest:SetENpc(MERLZIRN); end @@ -164,7 +172,7 @@ function onStateChange(player, quest, sequence) quest:SetENpc(ADVENTURER1); quest:SetENpc(ADVENTURER2); quest:SetENpc(ADVENTURER3); - quest:SetENpc(ECHO_EXIT_TRIGGER, subseqMRD == 3 and QFLAG_MAP or QFLAG_NONE, false, subseqMRD == 3); + quest:SetENpc(ECHO_EXIT_TRIGGER, subseqMSK == 3 and QFLAG_MAP or QFLAG_NONE, false, subseqMSK == 3); elseif (sequence == SEQ_035) then quest:SetENpc(NNMULIKA, QFLAG_PLATE); elseif (sequence == SEQ_040) then @@ -360,7 +368,7 @@ function seq000_onTalk(player, quest, npc, classId) callClientFunction(player, "delegateEvent", player, quest, "processEvent010_8"); elseif (classId == BADERON) then callClientFunction(player, "delegateEvent", player, quest, "processEvent020"); - player:SetNpcLS(1, 3); + quest:NewNpcLsMsg(1); quest:StartSequence(SEQ_003); player:EndEvent(); @@ -389,12 +397,12 @@ end function seq007_onTalk(player, quest, npc, classId) local data = quest:GetData(); local subseqCUL = data:GetCounter(CNTR_SEQ7_CUL); - local subseqMRD = data:GetCounter(CNTR_SEQ7_MRD); + local subseqMSK = data:GetCounter(CNTR_SEQ7_MSK); if (classId == BADERON) then if (subseqCUL == 1) then callClientFunction(player, "delegateEvent", player, quest, "processEvent027_3"); - elseif (subseqMRD == 4) then + elseif (subseqMSK == 4) then callClientFunction(player, "delegateEvent", player, quest, "processEvent027_4"); else callClientFunction(player, "delegateEvent", player, quest, "processEvent027_2"); @@ -402,8 +410,8 @@ function seq007_onTalk(player, quest, npc, classId) elseif (classId == CHARLYS) then if (subseqCUL == 0) then callClientFunction(player, "delegateEvent", player, quest, "processEvent030"); - data:IncCounter(CNTR_SEQ7_CUL); - if (data:GetCounter(CNTR_SEQ7_CUL) == 1 and data:GetCounter(CNTR_SEQ7_MSK) = 4) then + data:IncCounter(CNTR_SEQ7_CUL); + if (data:GetCounter(CNTR_SEQ7_MSK) == 4) then seq007_endSequence(player, quest); end --give 1000g @@ -411,14 +419,14 @@ function seq007_onTalk(player, quest, npc, classId) callClientFunction(player, "delegateEvent", player, quest, "processEvent030_2"); end elseif (classId == ISANDOREL) then - if (subseqMRD == 2) then + if (subseqMSK == 2) then callClientFunction(player, "delegateEvent", player, quest, "processEvent050"); - data:IncCounter(CNTR_SEQ7_MRD); + data:IncCounter(CNTR_SEQ7_MSK); GetWorldManager():WarpToPrivateArea(player, "PrivateAreaMasterPast", 3); - elseif (subseqMRD == 0) then + elseif (subseqMSK == 0) then callClientFunction(player, "delegateEvent", player, quest, "processEvent035"); - data:IncCounter(CNTR_SEQ7_MRD); - elseif (subseqMRD == 1) then + data:IncCounter(CNTR_SEQ7_MSK); + elseif (subseqMSK == 1) then callClientFunction(player, "delegateEvent", player, quest, "processEvent035_2"); end elseif (classId == MERLZIRN) then @@ -450,7 +458,7 @@ end function seq007_endSequence(player, quest) callClientFunction(player, "delegateEvent", player, quest, "processEvent033"); - player:SetNpcLS(1, 1); + quest:NewNpcLsMsg(1); end function seq080_085_onTalk(player, quest, npc, classId) @@ -482,14 +490,14 @@ function onPush(player, quest, npc) if (sequence == SEQ_007) then if (classId == MSK_TRIGGER) then callClientFunction(player, "delegateEvent", player, quest, "processEvent040"); - data:IncCounter(CNTR_SEQ7_MRD); + data:IncCounter(CNTR_SEQ7_MSK); player:EndEvent(); quest:UpdateENPCs(); GetWorldManager():DoZoneChange(player, 230, nil, 0, 15, -620.0, 29.476, -70.050, 0.791); elseif (classId == ECHO_EXIT_TRIGGER) then callClientFunction(player, "delegateEvent", player, quest, "processEvent060"); - data:IncCounter(CNTR_SEQ7_MRD); - if (data:GetCounter(CNTR_SEQ7_CUL) == 1 and data:GetCounter(CNTR_SEQ7_MSK) = 4) then + data:IncCounter(CNTR_SEQ7_MSK); + if (data:GetCounter(CNTR_SEQ7_CUL) == 1) then seq007_endSequence(player, quest); end player:EndEvent(); @@ -517,7 +525,7 @@ function onPush(player, quest, npc) callClientFunction(player, "delegateEvent", player, quest, "processEvent620"); -- Give 3000 gil player:EndEvent(); - data:SetCounter(CNTR_LS_MSG, 0); + quest:NewNpcLsMsg(1); quest:StartSequence(SEQ_070); end elseif (sequence == SEQ_085) then @@ -641,39 +649,43 @@ function onNotice(player, quest, target) quest:UpdateENPCs(); end -function onNpcLS(player, quest, npcLSId) +function onNpcLS(player, quest, from, msgStep) local sequence = quest:getSequence(); - callClientFunction(player, "delegateEvent", player, quest, "processEvent625"); - - if (npcLSId == 1) then - player:SetNpcLS(1, 1); - if (sequence == SEQ_003) then - player:SendGameMessageLocalizedDisplayName(quest, 298, 39, 1000015, nil); + local msgPack; + + if (from == 1) then + -- Get the right msg pack + if (sequence == SEQ_003) then + msgPack = 1; + elseif (sequence == SEQ_007 or sequence == SEQ_035) then + msgPack = 2; + elseif (sequence == SEQ_070 or sequence == SEQ_075) then + msgPack = 3; + elseif (sequence == SEQ_090 or sequence == SEQ_092) then + msgPack = 4; + end + + -- Quick way to handle all msgs nicely. + player:SendGameMessageLocalizedDisplayName(quest, NPCLS_MSGS[msgPack][msgStep], MESSAGE_TYPE_NPC_LINKSHELL, 1000015); + if (msgStep >= #NPCLS_MSGS[msgPack]) then + quest:EndOfNpcLsMsgs(); + else + quest:ReadNpcLsMsg(); + end + + -- Handle anything else + if (sequence == SEQ_003) then endTutorialMode(player); elseif (sequence == SEQ_007) then - player:SendGameMessageLocalizedDisplayName(quest, 80, 39, 1000015, nil); - player:SendGameMessageLocalizedDisplayName(quest, 81, 39, 1000015, nil); - player:SendGameMessageLocalizedDisplayName(quest, 82, 39, 1000015, nil); - quest:StartSequence(SEQ_035); + quest:StartSequenceForNpcLs(SEQ_035); elseif (sequence == SEQ_070) then - local lsStep = data:IncCounter(CNTR_LS_MSG); - if (lsStep == 1) then - player:SendGameMessageLocalizedDisplayName(quest, 80, 39, 1000015, nil); - elseif (lsStep == 2) then - player:SendGameMessageLocalizedDisplayName(quest, 80, 39, 1000015, nil); - elseif (lsStep == 3) then - player:SendGameMessageLocalizedDisplayName(quest, 80, 39, 1000015, nil); - else - player:SendGameMessageLocalizedDisplayName(quest, 80, 39, 1000015, nil); - quest:StartSequence(SEQ_075); - end - player:EndEvent(); + quest:StartSequenceForNpcLs(SEQ_075); elseif (sequence == SEQ_090) then - callClientFunction(player, "delegateEvent", player, quest, "processEvent637"); - player:EndEvent(); - quest:StartSequence(SEQ_092); + quest:StartSequenceForNpcLs(SEQ_092); end end + + player:EndEvent(); end function startMan0l1Content(player, quest) @@ -694,7 +706,7 @@ function startMan0l1Content(player, quest) end function getJournalInformation(player, quest) - return 0, quest:GetData():GetCounter(CNTR_SEQ7_CUL) * 5, quest:GetData():GetCounter(CNTR_SEQ7_MRD) * 5; + return 0, quest:GetData():GetCounter(CNTR_SEQ7_CUL) * 5, quest:GetData():GetCounter(CNTR_SEQ7_MSK) * 5; end function getJournalMapMarkerList(player, quest) diff --git a/Map Server/Actors/Chara/Player/Player.cs b/Map Server/Actors/Chara/Player/Player.cs index ce203b5d..2f0b74ad 100644 --- a/Map Server/Actors/Chara/Player/Player.cs +++ b/Map Server/Actors/Chara/Player/Player.cs @@ -1845,16 +1845,20 @@ namespace Meteor.Map.Actors return quests; } - public void HandleNpcLS(uint id) + public bool HandleNpcLs(uint id) { foreach (Quest quest in questScenario) { - if (quest != null) - quest.OnNpcLS(this, id); + if (quest != null && quest.HasNpcLsMsgs(id)) + { + quest.OnNpcLS(this); + return true; + } } + return false; } - public void SetNpcLS(uint npcLSId, uint state) + public void SetNpcLs(uint npcLSId, uint state) { bool isCalling, isExtra; isCalling = isExtra = false; diff --git a/Map Server/Actors/Quest/Quest.cs b/Map Server/Actors/Quest/Quest.cs index 690555ed..a9a9884d 100644 --- a/Map Server/Actors/Quest/Quest.cs +++ b/Map Server/Actors/Quest/Quest.cs @@ -35,6 +35,7 @@ namespace Meteor.Map.Actors.QuestNS private QuestState questState = null; private QuestData data = null; + // Creates a Static Quest for the StaticActors list. public Quest(uint actorID, string className, string classPath) : base(actorID) @@ -59,11 +60,11 @@ namespace Meteor.Map.Actors.QuestNS } // Creates a Instance Quest that has been started with data. - public Quest(Player owner, Quest staticQuest, ushort sequence, uint flags, ushort counter1, ushort counter2, ushort counter3, ushort counter4) : this(staticQuest) + public Quest(Player owner, Quest staticQuest, ushort sequence, uint flags, ushort counter1, ushort counter2, ushort counter3, ushort counter4, uint npcLsFrom, byte npcLsMsgStep) : this(staticQuest) { this.owner = owner; currentSequence = sequence; - data = new QuestData(owner, this, flags, counter1, counter2, counter3, counter4); + data = new QuestData(owner, this, flags, counter1, counter2, counter3, counter4, npcLsFrom, npcLsMsgStep); questState = new QuestState(owner, this); questState.UpdateState(); } @@ -137,6 +138,35 @@ namespace Meteor.Map.Actors.QuestNS } } + public void NewNpcLsMsg(uint from) + { + data.SetNpcLsFrom(from); + owner.SetNpcLs(from, Player.NPCLS_ALERT); + owner.SendGameMessage(Server.GetWorldManager().GetActor(), 25119, 0x20, (object)from); // A glow emanates from the linkpearl. + } + + public void ReadNpcLsMsg() + { + data.IncrementNpcLsMsgStep(); + owner.SetNpcLs(data.GetNpcLsFrom(), Player.NPCLS_ACTIVE); + } + + public void EndOfNpcLsMsgs() + { + owner.SetNpcLs(data.GetNpcLsFrom(), Player.NPCLS_INACTIVE); + data.ClearNpcLs(); + } + + public bool HasNpcLsMsgs(uint from) + { + return data.GetNpcLsFrom() == from; + } + + public int GetNpcLsMsgStep() + { + return data.GetMsgStep(); + } + public QuestState GetQuestState() { return questState; @@ -164,9 +194,9 @@ namespace Meteor.Map.Actors.QuestNS LuaEngine.GetInstance().CallLuaFunction(caller, this, "onNotice", true, triggerName); } - public void OnNpcLS(Player caller, uint npcLSId) + public void OnNpcLS(Player caller) { - LuaEngine.GetInstance().CallLuaFunction(caller, this, "onNpcLS", true, npcLSId); + LuaEngine.GetInstance().CallLuaFunction(caller, this, "onNpcLS", true, data.GetNpcLsFrom(), data.GetMsgStep()); } public object[] GetJournalInformation() @@ -213,6 +243,12 @@ namespace Meteor.Map.Actors.QuestNS questState.UpdateState(); } + public void StartSequenceForNpcLs(ushort sequence) + { + currentSequence = sequence; + questState.UpdateState(); + } + public void OnAccept() { data = new QuestData(owner, this); @@ -237,6 +273,5 @@ namespace Meteor.Map.Actors.QuestNS data = null; questState.UpdateState(); } - } } diff --git a/Map Server/Actors/Quest/QuestData.cs b/Map Server/Actors/Quest/QuestData.cs index 02d6800b..d0e97912 100644 --- a/Map Server/Actors/Quest/QuestData.cs +++ b/Map Server/Actors/Quest/QuestData.cs @@ -17,9 +17,12 @@ namespace Meteor.Map.Actors.QuestNS private ushort counter3; private ushort counter4; + private uint npcLsFrom = 0; + private byte npcLsMessageStep = 0; + public bool Dirty { get; private set; } = false; - public QuestData(Player owner, Quest parent, uint flags, ushort counter1, ushort counter2, ushort counter3, ushort counter4) + public QuestData(Player owner, Quest parent, uint flags, ushort counter1, ushort counter2, ushort counter3, ushort counter4, uint npcLsFrom, byte npcLsMessageStep) { this.owner = owner; this.parent = parent; @@ -28,6 +31,8 @@ namespace Meteor.Map.Actors.QuestNS this.counter2 = counter2; this.counter3 = counter3; this.counter4 = counter4; + this.npcLsFrom = npcLsFrom; + this.npcLsMessageStep = npcLsMessageStep; } public QuestData(Player owner, Quest parent) @@ -160,6 +165,34 @@ namespace Meteor.Map.Actors.QuestNS return 0; } + public void SetNpcLsFrom(uint from) + { + npcLsFrom = from; + npcLsMessageStep = 1; + Dirty = true; + } + + public void IncrementNpcLsMsgStep() + { + npcLsMessageStep++; + Dirty = true; + } + + public uint GetNpcLsFrom() + { + return npcLsFrom; + } + + public byte GetMsgStep() + { + return npcLsMessageStep; + } + + public void ClearNpcLs() + { + npcLsFrom = 0; + } + public void ClearDirty() { Dirty = false; diff --git a/Map Server/Database.cs b/Map Server/Database.cs index 9749097b..7eaabf8c 100644 --- a/Map Server/Database.cs +++ b/Map Server/Database.cs @@ -591,7 +591,7 @@ namespace Meteor.Map query = @" UPDATE characters_quest_scenario - SET sequence = @sequence, flags = @flags, counter1 = @counter1, counter2 = @counter2, counter3 = @counter3 + SET sequence = @sequence, flags = @flags, counter1 = @counter1, counter2 = @counter2, counter3 = @counter3, counter4 = @counter4, npcLsFrom = @npcLsFrom, npcLsMsgStep = @npcLsMsgStep WHERE characterId = @charaId and questId = @questId "; @@ -600,14 +600,14 @@ namespace Meteor.Map cmd.Parameters.AddWithValue("@questId", 0xFFFFF & quest.Id); cmd.Parameters.AddWithValue("@sequence", quest.GetSequence()); - 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.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.Parameters.AddWithValue("@counter4", qData.GetCounter(4)); + cmd.Parameters.AddWithValue("@npcLsFrom", qData.GetNpcLsFrom()); + cmd.Parameters.AddWithValue("@npcLsMsgStep", qData.GetMsgStep()); + cmd.ExecuteNonQuery(); } catch (MySqlException e) @@ -1216,7 +1216,10 @@ namespace Meteor.Map flags, counter1, counter2, - counter3 + counter3, + counter4, + npcLsFrom, + npcLsMsgStep FROM characters_quest_scenario WHERE characterId = @charId"; cmd = new MySqlCommand(query, conn); @@ -1232,11 +1235,13 @@ namespace Meteor.Map ushort counter1 = reader.GetUInt16("counter1"); ushort counter2 = reader.GetUInt16("counter2"); ushort counter3 = reader.GetUInt16("counter3"); - //ushort counter4 = reader.GetUInt16("counter4"); + ushort counter4 = reader.GetUInt16("counter4"); + ushort npsLsFrom = reader.GetUInt16("npcLsFrom"); + byte npcLsMsgStep = reader.GetByte("npcLsMsgStep"); Quest baseQuest = (Quest) Server.GetStaticActors(questId); player.playerWork.questScenario[index] = questId; - player.questScenario[index] = new Quest(player, baseQuest, sequence, flags, counter1, counter2, counter3, 0); + player.questScenario[index] = new Quest(player, baseQuest, sequence, flags, counter1, counter2, counter3, counter4, npsLsFrom, npcLsMsgStep); } }