diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index e3d52d46..c70f0d3f 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -894,6 +894,17 @@ namespace FFXIVClassic_Map_Server.Actors } + public int GetHighestLevel() + { + int max = 0; + foreach (short level in charaWork.battleSave.skillLevel) + { + if (level > max) + max = level; + } + return max; + } + public InventoryItem[] GetGearset(ushort classId) { return Database.GetEquipment(this, classId); @@ -1113,6 +1124,14 @@ namespace FFXIVClassic_Map_Server.Actors } } + //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)); diff --git a/FFXIVClassic Map Server/actors/quest/Quest.cs b/FFXIVClassic Map Server/actors/quest/Quest.cs index 6a6e6542..c69cd2c6 100644 --- a/FFXIVClassic Map Server/actors/quest/Quest.cs +++ b/FFXIVClassic Map Server/actors/quest/Quest.cs @@ -1,4 +1,5 @@ using FFXIVClassic.Common; +using FFXIVClassic_Map_Server.lua; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -79,7 +80,7 @@ namespace FFXIVClassic_Map_Server.Actors else questFlags &= (uint)~(1 << bitIndex); - //Inform update + DoCompletionCheck(); } public bool GetQuestFlag(int bitIndex) @@ -103,6 +104,8 @@ namespace FFXIVClassic_Map_Server.Actors currentPhase = phaseNumber; owner.SendGameMessage(Server.GetWorldManager().GetActor(), 25116, 0x20, (object)GetQuestId()); SaveData(); + + DoCompletionCheck(); } public uint GetQuestFlags() @@ -120,5 +123,21 @@ namespace FFXIVClassic_Map_Server.Actors Database.SaveQuest(owner, this); } + public void DoCompletionCheck() + { + List returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(owner, this, "isObjectivesComplete"); + if (returned.Count >= 1 && returned[0].typeID == 3) + { + owner.SendDataPacket("attention", Server.GetWorldManager().GetActor(), "", 25225, GetQuestId()); + owner.SendGameMessage(owner, Server.GetWorldManager().GetActor(), 25225, 0x20, (object)GetQuestId()); + } + } + + public void DoAbandon() + { + List returned = LuaEngine.GetInstance().CallLuaFunctionForReturn(owner, this, "onAbandonQuest"); + owner.SendGameMessage(owner, Server.GetWorldManager().GetActor(), 25236, 0x20, (object)GetQuestId()); + } + } } diff --git a/FFXIVClassic Map Server/lua/LuaEngine.cs b/FFXIVClassic Map Server/lua/LuaEngine.cs index 76db4e67..5b2cbf44 100644 --- a/FFXIVClassic Map Server/lua/LuaEngine.cs +++ b/FFXIVClassic Map Server/lua/LuaEngine.cs @@ -26,6 +26,7 @@ namespace FFXIVClassic_Map_Server.lua const string FILEPATH_COMMANDS = "./scripts/commands/{0}.lua"; const string FILEPATH_DIRECTORS = "./scripts/directors/{0}.lua"; const string FILEPATH_NPCS = "./scripts/unique/{0}/{1}/{2}.lua"; + const string FILEPATH_QUEST = "./scripts/quests/{0}/{1}.lua"; private static LuaEngine mThisEngine; private Dictionary mSleepingOnTime = new Dictionary(); @@ -141,6 +142,12 @@ namespace FFXIVClassic_Map_Server.lua { return String.Format(FILEPATH_ZONE, ((Area)target).zoneName); } + else if (target is Quest) + { + string initial = ((Quest)target).actorName.Substring(0, 3); + string questName = ((Quest)target).actorName; + return String.Format(FILEPATH_QUEST, initial, questName); + } else return ""; } @@ -256,6 +263,16 @@ namespace FFXIVClassic_Map_Server.lua if (target is Npc) return CallLuaFunctionNpcForReturn(player, (Npc)target, funcName, args); + object[] args2 = new object[args.Length + (player == null ? 1 : 2)]; + Array.Copy(args, 0, args2, (player == null ? 1 : 2), args.Length); + if (player != null) + { + args2[0] = player; + args2[1] = target; + } + else + args2[0] = target; + string luaPath = GetScriptPath(target); LuaScript script = LoadScript(luaPath); if (script != null) @@ -263,7 +280,7 @@ namespace FFXIVClassic_Map_Server.lua if (!script.Globals.Get(funcName).IsNil()) { //Run Script - DynValue result = script.Call(script.Globals[funcName], this); + DynValue result = script.Call(script.Globals[funcName], args2); List lparams = LuaUtils.CreateLuaParamList(result); return lparams; } diff --git a/data/scripts/quests/etc/etc5g0.lua b/data/scripts/quests/etc/etc5g0.lua new file mode 100644 index 00000000..5db6d721 --- /dev/null +++ b/data/scripts/quests/etc/etc5g0.lua @@ -0,0 +1,21 @@ +--Quest Flags +TALKED_PFARAHR = 0; + +function canAcceptQuest(player) + return (player:HasQuest("etc5g0") == false and player:GetHighestLevel() >= 1); +end + +function isObjectivesComplete(player, quest) + return (quest:GetPhase() == 2); +end + +function onAbandonQuest(player, quest) + vkorolon = GetWorldManager():GetActorInWorldByUniqueId("vkorolon"); + pfarahr = GetWorldManager():GetActorInWorldByUniqueId("pfarahr"); + if (vkorolon ~= nil and canAcceptQuest(player)) then + vkorolon:SetQuestGraphic(player, 0x2); + end + if (pfarahr ~= nil) then + pfarahr:SetQuestGraphic(player, 0x0); + end +end \ No newline at end of file