From cfdc9ca3948969b513072949675f55a75c2e8550 Mon Sep 17 00:00:00 2001 From: Aeshur Date: Tue, 21 Apr 2026 18:10:46 -0400 Subject: [PATCH] [lua] Bonds of Mythril quest --- scripts/enum/item.lua | 1 + scripts/globals/quests.lua | 2 +- .../quests/crystalWar/Bonds_of_Mythril.lua | 245 ++++++++++++++++++ .../Castle_Zvahl_Keep_[S]/DefaultActions.lua | 3 +- scripts/zones/Castle_Zvahl_Keep_[S]/IDs.lua | 3 + sql/mob_groups.sql | 2 +- sql/mob_spawn_points.sql | 2 +- 7 files changed, 254 insertions(+), 4 deletions(-) create mode 100644 scripts/quests/crystalWar/Bonds_of_Mythril.lua diff --git a/scripts/enum/item.lua b/scripts/enum/item.lua index c8713a6ebbd..0c3b6cb8c87 100644 --- a/scripts/enum/item.lua +++ b/scripts/enum/item.lua @@ -7102,6 +7102,7 @@ xi.item = NASATYAS_RING = 15852, DASRAS_RING = 15853, GRIFFON_RING = 15856, + EXCELSIS_RING = 15857, GYOKUTO_OBI = 15860, DEDUCTIVE_BROCADE_OBI = 15861, ENTHRALLING_BROCADE_OBI = 15862, diff --git a/scripts/globals/quests.lua b/scripts/globals/quests.lua index cfdcfd4058d..7940603d12f 100644 --- a/scripts/globals/quests.lua +++ b/scripts/globals/quests.lua @@ -765,7 +765,7 @@ xi.quest.id = THE_YOUNG_AND_THE_THREADLESS = 56, SON_AND_FATHER = 57, THE_TRUTH_LIES_HID = 58, -- + Converted - BONDS_OF_MYTHRIL = 59, + BONDS_OF_MYTHRIL = 59, -- + Converted CHASING_SHADOWS = 60, -- + Converted FACE_OF_THE_FUTURE = 61, -- + Converted MANIFEST_DESTINY = 62, diff --git a/scripts/quests/crystalWar/Bonds_of_Mythril.lua b/scripts/quests/crystalWar/Bonds_of_Mythril.lua new file mode 100644 index 00000000000..98b60dddf8b --- /dev/null +++ b/scripts/quests/crystalWar/Bonds_of_Mythril.lua @@ -0,0 +1,245 @@ +----------------------------------- +-- Bonds of Mythril +----------------------------------- +-- !addquest 7 59 +-- Gentle Tiger : !pos -203.932 -9.998 2.237 87 +-- ??? (qm) : !pos -384.257 -51.999 -95.783 155 +-- Throne Room [S] : !pos -115.849 -8.657 0.000 156 +----------------------------------- + +local quest = Quest:new(xi.questLog.CRYSTAL_WAR, xi.quest.id.crystalWar.BONDS_OF_MYTHRIL) +local keepID = zones[xi.zone.CASTLE_ZVAHL_KEEP_S] + +quest.reward = +{ + item = xi.item.EXCELSIS_RING, + title = xi.title.TEMPERER_OF_MYTHRIL, +} + +quest.sections = +{ + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_AVAILABLE and + player:hasCompletedQuest(xi.questLog.CRYSTAL_WAR, xi.quest.id.crystalWar.THE_TRUTH_LIES_HID) and + player:getCurrentMission(xi.mission.log_id.WOTG) >= xi.mission.id.wotg.ADIEU_LILISETTE + end, + + [xi.zone.CASTLE_ZVAHL_BAILEYS_S] = + { + onZoneIn = function(player, prevZone) + if prevZone == xi.zone.CASTLE_ZVAHL_KEEP_S then + return 13 + end + end, + + onEventFinish = + { + [13] = function(player, csid, option, npc) + quest:begin(player) + end, + }, + }, + }, + + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_ACCEPTED and vars.Prog == 0 + end, + + [xi.zone.CASTLE_ZVAHL_KEEP_S] = + { + ['qm'] = quest:progressEvent(17), + + onEventFinish = + { + [17] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 1) + end, + }, + }, + }, + + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_ACCEPTED and vars.Prog == 1 + end, + + [xi.zone.CASTLE_ZVAHL_KEEP_S] = + { + ['qm'] = + { + onTrigger = function(player, npc) + if quest:getVar(player, 'ImpKills') >= 4 then + if npcUtil.popFromQM(player, npc, keepID.mob.GARGOUILLE_WARDEN, { hide = 0 }) then + quest:setVar(player, 'ImpKills', 0) + end + + return quest:messageSpecial(keepID.text.A_SHIVER_RUNS_DOWN) + end + + return quest:progressEvent(17) + end, + }, + + ['Keep_Imp'] = + { + onMobDeath = function(mob, player, optParams) + if quest:getVar(player, 'Prog') == 1 then + local impKills = quest:getVar(player, 'ImpKills') + quest:setVar(player, 'ImpKills', math.min(4, impKills + 1)) + end + end, + }, + + ['Gargouille_Warden'] = + { + onMobDeath = function(mob, player, optParams) + if quest:getVar(player, 'Prog') == 1 then + quest:setVar(player, 'Prog', 2) + end + end, + }, + }, + }, + + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_ACCEPTED and vars.Prog == 2 + end, + + [xi.zone.CASTLE_ZVAHL_KEEP_S] = + { + ['qm'] = quest:progressEvent(18), + + onEventFinish = + { + [18] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 3) + npcUtil.giveKeyItem(player, xi.ki.ZVAHL_PASSKEY) + end, + }, + }, + }, + + { + check = function(player, status) + return status == xi.questStatus.QUEST_ACCEPTED and + player:hasKeyItem(xi.ki.ZVAHL_PASSKEY) + end, + + [xi.zone.THRONE_ROOM_S] = + { + ['_4c1'] = + { + onTrigger = function(player, npc) + if quest:getVar(player, 'Prog') == 3 then + return quest:progressEvent(12) + end + end, + }, + + onEventFinish = + { + [12] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 4) + end, + + -- Bonds of Mythril battlefield is not implemented currently. + [32001] = function(player, csid, option, npc) + if + player:getLocalVar('battlefieldWin') == xi.battlefield.id.BONDS_OF_MYTHRIL and + quest:getVar(player, 'Prog') == 4 + then + quest:setVar(player, 'Prog', 5) + end + end, + }, + }, + }, + + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_ACCEPTED and vars.Prog == 5 + end, + + [xi.zone.BASTOK_MARKETS_S] = + { + ['Gentle_Tiger'] = + { + onTrigger = function(player, npc) + return quest:progressEvent(213, 87, 0, 2964, 0) + end, + }, + + onEventFinish = + { + [213] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 6) + player:setPos(52.272, -14.000, -0.017, 127, xi.zone.METALWORKS) + end, + }, + }, + }, + + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_ACCEPTED and vars.Prog == 6 + end, + + [xi.zone.METALWORKS] = + { + onZoneIn = function(player, prevZone) + return 972 + end, + + onEventFinish = + { + [972] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 7) + player:setPos(380.062, 0.753, 147.908, 194, xi.zone.NORTH_GUSTABERG_S) + end, + }, + }, + }, + + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_ACCEPTED and vars.Prog == 7 + end, + + [xi.zone.NORTH_GUSTABERG_S] = + { + onZoneIn = function(player, prevZone) + return 13 + end, + + onEventFinish = + { + [13] = function(player, csid, option, npc) + if quest:complete(player) then + player:delKeyItem(xi.ki.ZVAHL_PASSKEY) + end + end, + }, + }, + }, + + { + check = function(player, status) + return status == xi.questStatus.QUEST_COMPLETED + end, + + [xi.zone.BASTOK_MARKETS_S] = + { + ['Gentle_Tiger'] = quest:event(214):replaceDefault(), + }, + + [xi.zone.METALWORKS] = + { + ['Naji'] = quest:event(971):replaceDefault(), + }, + }, +} + +return quest diff --git a/scripts/zones/Castle_Zvahl_Keep_[S]/DefaultActions.lua b/scripts/zones/Castle_Zvahl_Keep_[S]/DefaultActions.lua index 2d3defd8860..7920a0329e7 100644 --- a/scripts/zones/Castle_Zvahl_Keep_[S]/DefaultActions.lua +++ b/scripts/zones/Castle_Zvahl_Keep_[S]/DefaultActions.lua @@ -1,6 +1,7 @@ --- local ID = zones[xi.zone.CASTLE_ZVAHL_KEEP_S] +local ID = zones[xi.zone.CASTLE_ZVAHL_KEEP_S] return { + ['qm'] = { messageSpecial = ID.text.NOTHING_OUT_OF_ORDINARY }, ['Rakke'] = { event = 29 }, ['Rikke'] = { event = 28 }, ['Rokke'] = { event = 30 }, diff --git a/scripts/zones/Castle_Zvahl_Keep_[S]/IDs.lua b/scripts/zones/Castle_Zvahl_Keep_[S]/IDs.lua index bca63874ede..558b129e138 100644 --- a/scripts/zones/Castle_Zvahl_Keep_[S]/IDs.lua +++ b/scripts/zones/Castle_Zvahl_Keep_[S]/IDs.lua @@ -15,10 +15,13 @@ zones[xi.zone.CASTLE_ZVAHL_KEEP_S] = LOGIN_CAMPAIGN_UNDERWAY = 7005, -- The [/January/February/March/April/May/June/July/August/September/October/November/December] Login Campaign is currently underway! LOGIN_NUMBER = 7006, -- In celebration of your most recent login (login no. ), we have provided you with points! You currently have a total of points. MEMBERS_LEVELS_ARE_RESTRICTED = 7026, -- Your party is unable to participate because certain members' levels are restricted. + NOTHING_OUT_OF_ORDINARY = 7340, -- You find nothing out of the ordinary. + A_SHIVER_RUNS_DOWN = 7341, -- A shiver runs down your spine... HOMEPOINT_SET = 7884, -- Home point set! }, mob = { + GARGOUILLE_WARDEN = GetFirstID('Gargouille_Warden'), }, npc = { diff --git a/sql/mob_groups.sql b/sql/mob_groups.sql index 4f4f867094b..73ca681baad 100644 --- a/sql/mob_groups.sql +++ b/sql/mob_groups.sql @@ -11283,7 +11283,7 @@ INSERT INTO `mob_groups` VALUES (158,2180,155,'Kaiser_Behemoth',0,128,0,0,0,0,NU INSERT INTO `mob_groups` VALUES (159,1324,155,'Ferreous_Coffin',0,128,0,0,0,0,NULL); INSERT INTO `mob_groups` VALUES (160,2403,155,'Lewenhart',0,128,0,0,0,0,NULL); INSERT INTO `mob_groups` VALUES (161,291,155,'Auroral_Alicorn',0,128,0,0,0,0,NULL); -INSERT INTO `mob_groups` VALUES (162,6881,155,'Gargouille_Warden',0,128,0,0,0,0,NULL); +INSERT INTO `mob_groups` VALUES (162,6881,155,'Gargouille_Warden',0,128,0,18800,0,0,NULL); INSERT INTO `mob_groups` VALUES (163,7167,155,'Goblin_Lansquenet',0,128,0,0,0,0,NULL); INSERT INTO `mob_groups` VALUES (164,7185,155,'Eurytos',0,128,0,0,0,0,NULL); INSERT INTO `mob_groups` VALUES (165,7186,155,'Boodlix',0,128,0,0,0,0,NULL); diff --git a/sql/mob_spawn_points.sql b/sql/mob_spawn_points.sql index d888e8831b8..5f97590311d 100644 --- a/sql/mob_spawn_points.sql +++ b/sql/mob_spawn_points.sql @@ -56347,7 +56347,7 @@ INSERT INTO `mob_spawn_points` VALUES (17412639,0,'Kaiser_Behemoth','Kaiser Behe INSERT INTO `mob_spawn_points` VALUES (17412640,0,'Ferreous_Coffin','Ferreous Coffin',159,0,0,0.000,0.000,0.000,0); INSERT INTO `mob_spawn_points` VALUES (17412641,0,'Lewenhart','Lewenhart',160,0,0,0.000,0.000,0.000,0); INSERT INTO `mob_spawn_points` VALUES (17412642,0,'Auroral_Alicorn','Auroral Alicorn',161,0,0,0.000,0.000,0.000,0); -INSERT INTO `mob_spawn_points` VALUES (17412643,0,'Gargouille_Warden','Gargouille Warden',162,0,0,-384.256,-52.500,-95.782,31); +INSERT INTO `mob_spawn_points` VALUES (17412643,0,'Gargouille_Warden','Gargouille Warden',162,80,80,-384.256,-52.500,-95.782,31); -- ------------------------------------------------------------ -- Throne Room [S] (Zone 156)