From ce35daa929cffef575223cd048eb9f7eda300964 Mon Sep 17 00:00:00 2001 From: jamesbradleym Date: Wed, 1 Jan 2025 11:35:44 -0500 Subject: [PATCH] implement A Generous General Co-authored-by: jamesbradleym Co-authored-by: hookstar --- .../quests/otherAreas/A_Generous_General.lua | 269 ++++++++++++++++++ .../Oldton_Movalpolos/DefaultActions.lua | 1 + scripts/zones/Oldton_Movalpolos/IDs.lua | 10 +- .../mobs/Bugbear_Porterman.lua | 23 ++ .../mobs/Dread_Dealing_Dredodak.lua | 23 ++ .../mobs/Goblin_Preceptor.lua | 23 ++ .../mobs/Grimoire_Guru_Grimogek.lua | 23 ++ scripts/zones/Southern_San_dOria/IDs.lua | 1 + 8 files changed, 370 insertions(+), 3 deletions(-) create mode 100644 scripts/quests/otherAreas/A_Generous_General.lua create mode 100644 scripts/zones/Oldton_Movalpolos/mobs/Bugbear_Porterman.lua create mode 100644 scripts/zones/Oldton_Movalpolos/mobs/Dread_Dealing_Dredodak.lua create mode 100644 scripts/zones/Oldton_Movalpolos/mobs/Goblin_Preceptor.lua create mode 100644 scripts/zones/Oldton_Movalpolos/mobs/Grimoire_Guru_Grimogek.lua diff --git a/scripts/quests/otherAreas/A_Generous_General.lua b/scripts/quests/otherAreas/A_Generous_General.lua new file mode 100644 index 00000000000..956a3ae66e8 --- /dev/null +++ b/scripts/quests/otherAreas/A_Generous_General.lua @@ -0,0 +1,269 @@ +----------------------------------- +-- A Generous General +----------------------------------- +-- Log ID: 4, Quest ID: 109 +----------------------------------- +-- Oldton zone !pos 566 -12 685 106 +-- Faulpie !gotoid 17719379 +-- iron box !pos -141 7 157 11 +----------------------------------- +local oldtonID = zones[xi.zone.OLDTON_MOVALPOLOS] +local southernSanDoriaID = zones[xi.zone.SOUTHERN_SAN_DORIA] +----------------------------------- +local quest = Quest:new(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.A_GENEROUS_GENERAL) + +local function mobsToSpawn() + local mobs = {} + for i = 0, 6 do + table.insert(mobs, oldtonID.mob.GENEROUS_GENERAL_OFFSET + i) + end + return mobs +end + +local function isWithinZoneCoordinates(player) + local pos = player:getPos() + return pos.x >= -323.0 and + pos.x <= -321.0 and + pos.y >= 6.0 and + pos.y <= 9.0 and + pos.z >= 261.0 and + pos.z <= -258.0 +end + +quest.reward = +{ + item = xi.item.CHOPLIXS_COIF, + title = xi.title.MOBLIN_KINSMAN, +} + +quest.sections = +{ + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_AVAILABLE and + player:getQuestStatus(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.AN_AFFABLE_ADAMANTKING) ~= xi.questStatus.QUEST_ACCEPTED and + player:getQuestStatus(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.AN_UNDERSTANDING_OVERLORD) ~= xi.questStatus.QUEST_ACCEPTED and + player:getQuestStatus(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.A_MORAL_MANIFEST) ~= xi.questStatus.QUEST_ACCEPTED and + quest:getVar(player, 'ConquestWait') == 0 and + not player:hasItem(xi.item.CHOPLIXS_COIF) and + player:getMainLvl() >= 60 + end, + + [xi.zone.OLDTON_MOVALPOLOS] = + { + onZoneIn = function(player, prevZone) + if isWithinZoneCoordinates(player) then + return 60 + end + end, + + onEventFinish = + { + [60] = function(player, csid, option, npc) + if option == 0 then + quest:begin(player) -- begin quest + elseif option == 1 then + quest:setVarExpiration(player, 'ConquestWait', NextConquestTally()) -- if player declines they must wait until next conquest tally + end + end, + }, + }, + }, + + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_ACCEPTED + end, + + [xi.zone.SOUTHERN_SAN_DORIA] = + { + ['Faulpie'] = + { + onTrigger = function(player, npc) + local prog = quest:getVar(player, 'Prog') + local partsWait = quest:getVar(player, 'partsWait') + if prog == 0 then + return quest:progressEvent(770) -- tells player what items are needed + elseif prog == 1 then + return quest:event(771):importantOnce() -- reminder to get buffalo hide and sheep leather or cancel quest + elseif + prog >= 2 and + partsWait ~= 0 -- player is currently waiting for parts + then + if partsWait <= os.time() then + return quest:progressEvent(775) -- ready to go + else + return quest:event(773):importantOnce() -- player must wait till vana midnight and zone(era only) + end + elseif prog == 3 then + return quest:event(774):importantOnce() -- Get another part for 100000 gil or give up + end + end, + + onTrade = function(player, npc, trade) + if + npcUtil.tradeHasExactly(trade, { xi.item.BUFFALO_HIDE, xi.item.SQUARE_OF_SHEEP_LEATHER, { 'gil', 10000 } }) and + quest:getVar(player, 'Prog') == 1 + then + return quest:progressEvent(772) + end + end, + }, + + onEventFinish = + { + [770] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 1) + end, + + [771] = function(player, csid, option, npc) + if option == 100 then + player:messageSpecial(southernSanDoriaID.text.QUEST_CANCELLED) + quest:cleanup(player) -- reset progress + player:delQuest(quest.areaId, quest.questId) + end + end, + + [772] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 2) + quest:setVar(player, 'partsWait', getVanaMidnight()) + player:confirmTrade() + player:delGil(10000) + end, + + [774] = function(player, csid, option, npc) + if option == 0 then + if player:getGil() > 100000 then + quest:setVar(player, 'partsWait', getVanaMidnight()) + player:delGil(100000) + else + player:messageSpecial(southernSanDoriaID.text.NOT_HAVE_ENOUGH_GIL) + end + elseif option == 100 then + player:messageSpecial(zones[player:getZoneID()].text.QUEST_CANCELLED) + quest:cleanup(player) -- reset progress + player:delQuest(quest.areaId, quest.questId) + end + end, + + [775] = function(player, csid, option, npc) + if npcUtil.giveItem(player, xi.item.GOBLIN_COIF_CUTTING) then -- only progress vars if player receives parts + if quest:getVar(player, 'Prog') == 2 then + quest:setVar(player, 'Prog', 3) -- only progress if current prog is 2, otherwise player is already at, or beyond, Prog 3 + end + + quest:setVar(player, 'partsWait', 0) + end + end, + }, + }, + + [xi.zone.OLDTON_MOVALPOLOS] = + { + onZoneIn = function(player, prevZone) + if + isWithinZoneCoordinates(player) and + quest:getVar(player, 'Prog') == 3 and + player:getEquipID(xi.slot.HEAD) == xi.item.GOBLIN_COIF + then + return 61 -- Give player Goblin Recommendation Letter + end + end, + + ['Iron_Box'] = + { + onTrigger = function(player, npc) + if not player:getEquipID(xi.slot.HEAD) == xi.item.GOBLIN_COIF then + return + end + + if player:hasKeyItem(xi.ki.GOBLIN_RECOMMENDATION_LETTER) then + return quest:progressEvent(62) + elseif quest:getVar(player, 'Prog') == 5 then + return quest:progressEvent(63) + end + end, + + onTrade = function(player, npc, trade) + if + npcUtil.tradeHasExactly(trade, { xi.item.GOBLIN_COIF }) and + quest:getVar(player, 'Prog') == 6 + then + return quest:progressEvent(64) -- reward player with Choplix's Coif + end + end, + }, + + onEventFinish = + { + [61] = function(player, csid, option, npc) + npcUtil.giveKeyItem(player, xi.ki.GOBLIN_RECOMMENDATION_LETTER) + quest:setVar(player, 'Prog', 4) + end, + + [62] = function(player, csid, option, npc) + if npcUtil.popFromQM(player, npc, mobsToSpawn(), { claim = true, hide = 0 }) then + player:messageSpecial(oldtonID.text.RECOMMENDATION_LETTER) + end + end, + + [63] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 6) + end, + + [64] = function(player, csid, option, npc) + if quest:complete(player) then + player:confirmTrade() + quest:setVarExpiration(player, 'ConquestWait', NextConquestTally()) + quest:setVar(player, 'generousGeneralZone', 1) + end + end, + }, + + ['Goblin_Preceptor'] = + { + onMobDeath = function(mob, player, optParams) + for i = oldtonID.mob.GENEROUS_GENERAL_OFFSET, oldtonID.mob.GENEROUS_GENERAL_OFFSET + 6 do + DespawnMob(i) + end + + if quest:getVar(player, 'Prog') == 4 then + quest:setVar(player, 'Prog', 5) + player:delKeyItem(xi.ki.GOBLIN_RECOMMENDATION_LETTER) + end + end, + } + }, + }, + + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_COMPLETED + end, + + [xi.zone.OLDTON_MOVALPOLOS] = + { + onZoneIn = function(player, prevZone) + local pos = player:getPos() + if + isWithinZoneCoordinates(player) and + quest:getVar(player, 'generousGeneralZone') == 1 and + player:getEquipID(xi.slot.HEAD) == xi.item.CHOPLIXS_COIF + then + return 65 + end + end, + + onEventFinish = + { + [65] = function(player, csid, option, npc) + if npcUtil.giveItem(player, xi.item.GOLD_BEASTCOIN) then + quest:setVar(player, 'generousGeneralZone', 0) + end + end, + } + }, + } +} + +return quest diff --git a/scripts/zones/Oldton_Movalpolos/DefaultActions.lua b/scripts/zones/Oldton_Movalpolos/DefaultActions.lua index 5f5ba8add28..447b87bc3fd 100644 --- a/scripts/zones/Oldton_Movalpolos/DefaultActions.lua +++ b/scripts/zones/Oldton_Movalpolos/DefaultActions.lua @@ -1,5 +1,6 @@ local ID = zones[xi.zone.OLDTON_MOVALPOLOS] return { + ['Iron_Box'] = { messageSpecial = ID.text.NOTHING_OUT_OF_ORDINARY }, ['Rakorok'] = { text = ID.text.RAKOROK_DIALOGUE }, } diff --git a/scripts/zones/Oldton_Movalpolos/IDs.lua b/scripts/zones/Oldton_Movalpolos/IDs.lua index 73fa4f1669b..c5f5693f02e 100644 --- a/scripts/zones/Oldton_Movalpolos/IDs.lua +++ b/scripts/zones/Oldton_Movalpolos/IDs.lua @@ -12,6 +12,7 @@ zones[xi.zone.OLDTON_MOVALPOLOS] = GIL_OBTAINED = 6391, -- Obtained gil. KEYITEM_OBTAINED = 6393, -- Obtained key item: . KEYITEM_LOST = 6394, -- Lost key item: . + NOT_HAVE_ENOUGH_GIL = 6395, -- You do not have enough gil. FELLOW_MESSAGE_OFFSET = 6419, -- I'm ready. I suppose. CARRIED_OVER_POINTS = 7001, -- You have carried over login point[/s]. LOGIN_CAMPAIGN_UNDERWAY = 7002, -- The [/January/February/March/April/May/June/July/August/September/October/November/December] Login Campaign is currently underway! @@ -19,6 +20,7 @@ zones[xi.zone.OLDTON_MOVALPOLOS] = MEMBERS_LEVELS_ARE_RESTRICTED = 7023, -- Your party is unable to participate because certain members' levels are restricted. CONQUEST_BASE = 7064, -- Tallying conquest results... FISHING_MESSAGE_OFFSET = 7583, -- You can't fish here. + NOTHING_OUT_OF_ORDINARY = 7693, -- There is nothing out of the ordinary here. MINING_IS_POSSIBLE_HERE = 7714, -- Mining is possible here if you have . RAKOROK_DIALOGUE = 7738, -- Nsy pipul. Gattohre! I bisynw! ALTANA_DIE = 7740, -- Aaaltaaanaaa... Diiieee!!! @@ -29,14 +31,16 @@ zones[xi.zone.OLDTON_MOVALPOLOS] = }, mob = { - BUGALLUG = GetFirstID('Bugallug'), - BUGBEAR_STRONGMAN = GetTableOfIDs('Bugbear_Strongman'), - GOBLIN_WOLFMAN = GetFirstID('Goblin_Wolfman'), + BUGALLUG = GetFirstID('Bugallug'), + BUGBEAR_STRONGMAN = GetTableOfIDs('Bugbear_Strongman'), + GOBLIN_WOLFMAN = GetFirstID('Goblin_Wolfman'), + GENEROUS_GENERAL_OFFSET = GetFirstID('Goblin_Preceptor'), }, npc = { SCRAWLED_WRITING = GetFirstID('Scrawled_Writing'), OVERSEER_BASE = GetFirstID('Conquest_Banner'), + IRON_BOX = GetFirstID('Iron_Box'), TREASURE_CHEST = GetFirstID('Treasure_Chest'), MINING = GetTableOfIDs('Mining_Point'), }, diff --git a/scripts/zones/Oldton_Movalpolos/mobs/Bugbear_Porterman.lua b/scripts/zones/Oldton_Movalpolos/mobs/Bugbear_Porterman.lua new file mode 100644 index 00000000000..5b6c59eeb58 --- /dev/null +++ b/scripts/zones/Oldton_Movalpolos/mobs/Bugbear_Porterman.lua @@ -0,0 +1,23 @@ +----------------------------------- +-- Area: Oldton Movalpolos +-- NM: Bugbear Porterman +-- Note: QNM for A Generous General +----------------------------------- +mixins = { require('scripts/mixins/job_special') } +----------------------------------- +local entity = {} + +entity.onMobInitialize = function(mob) + mob:setMobMod(xi.mobMod.IDLE_DESPAWN, 180) -- 3 min despawn +end + +entity.onMobEngage = function(mob, target) +end + +entity.onMobDeath = function(mob, player, optParams) +end + +entity.onMobDespawn = function(mob) +end + +return entity diff --git a/scripts/zones/Oldton_Movalpolos/mobs/Dread_Dealing_Dredodak.lua b/scripts/zones/Oldton_Movalpolos/mobs/Dread_Dealing_Dredodak.lua new file mode 100644 index 00000000000..3411e8df92f --- /dev/null +++ b/scripts/zones/Oldton_Movalpolos/mobs/Dread_Dealing_Dredodak.lua @@ -0,0 +1,23 @@ +----------------------------------- +-- Area: Oldton Movalpolos +-- NM: Dread Dealing Dredodak +-- Note: QNM for A Generous General +----------------------------------- +mixins = { require('scripts/mixins/job_special') } +----------------------------------- +local entity = {} + +entity.onMobInitialize = function(mob) + mob:setMobMod(xi.mobMod.IDLE_DESPAWN, 180) -- 3 min despawn +end + +entity.onMobEngage = function(mob, target) +end + +entity.onMobDeath = function(mob, player, optParams) +end + +entity.onMobDespawn = function(mob) +end + +return entity diff --git a/scripts/zones/Oldton_Movalpolos/mobs/Goblin_Preceptor.lua b/scripts/zones/Oldton_Movalpolos/mobs/Goblin_Preceptor.lua new file mode 100644 index 00000000000..edba5a520b2 --- /dev/null +++ b/scripts/zones/Oldton_Movalpolos/mobs/Goblin_Preceptor.lua @@ -0,0 +1,23 @@ +----------------------------------- +-- Area: Oldton Movalpolos +-- NM: Goblin Preceptor +-- Note: QNM for A Generous General +----------------------------------- +mixins = { require('scripts/mixins/job_special') } +----------------------------------- +local entity = {} + +entity.onMobInitialize = function(mob) + mob:setMobMod(xi.mobMod.IDLE_DESPAWN, 180) -- 3 min despawn +end + +entity.onMobEngage = function(mob, target) +end + +entity.onMobDeath = function(mob, player, optParams) +end + +entity.onMobDespawn = function(mob) +end + +return entity diff --git a/scripts/zones/Oldton_Movalpolos/mobs/Grimoire_Guru_Grimogek.lua b/scripts/zones/Oldton_Movalpolos/mobs/Grimoire_Guru_Grimogek.lua new file mode 100644 index 00000000000..5a0be22ce2c --- /dev/null +++ b/scripts/zones/Oldton_Movalpolos/mobs/Grimoire_Guru_Grimogek.lua @@ -0,0 +1,23 @@ +----------------------------------- +-- Area: Oldton Movalpolos +-- NM: Grimoire Guru Grimogek +-- Note: QNM for A Generous General +----------------------------------- +mixins = { require('scripts/mixins/job_special') } +----------------------------------- +local entity = {} + +entity.onMobInitialize = function(mob) + mob:setMobMod(xi.mobMod.IDLE_DESPAWN, 180) -- 3 min despawn +end + +entity.onMobEngage = function(mob, target) +end + +entity.onMobDeath = function(mob, player, optParams) +end + +entity.onMobDespawn = function(mob) +end + +return entity diff --git a/scripts/zones/Southern_San_dOria/IDs.lua b/scripts/zones/Southern_San_dOria/IDs.lua index 9ee357d9244..902f7cd8f3b 100644 --- a/scripts/zones/Southern_San_dOria/IDs.lua +++ b/scripts/zones/Southern_San_dOria/IDs.lua @@ -33,6 +33,7 @@ zones[xi.zone.SOUTHERN_SAN_DORIA] = GP_OBTAINED = 6843, -- Obtained: guild points. NOT_HAVE_ENOUGH_GP = 6844, -- You do not have enough guild points. RENOUNCE_CRAFTSMAN = 6860, -- You have successfully renounced your status as a [craftsman/artisan/adept] of the [Carpenters'/Blacksmiths'/Goldsmiths'/Weavers'/Tanners'/Boneworkers'/Alchemists'/Culinarians'] Guild. + QUEST_CANCELLED = 6920, -- The quest has been canceled! CONQUEST_BASE = 7066, -- Tallying conquest results... YOU_ACCEPT_THE_MISSION = 7230, -- You accept the mission. ORIGINAL_MISSION_OFFSET = 7241, -- Bring me one of those axes, and your mission will be a success. No running away now; we've a proud country to defend!