From 788188acd9ad1731745e0fe612a6a11f850c367d Mon Sep 17 00:00:00 2001 From: claywar Date: Mon, 2 Sep 2024 12:47:33 -0400 Subject: [PATCH] Fix issues identified from TQuest definition Fix Quest definitions to properly represent heirarchy f Add additional definition types, fixes Make onTrigger function def return optional --- scripts/quests/ahtUrhgan/Olduum.lua | 12 +++--- .../ahtUrhgan/Three_Men_and_a_Closet.lua | 5 ++- scripts/quests/bastok/A_Question_of_Faith.lua | 2 +- .../bastok/Lure_of_the_Wildcat_Bastok.lua | 3 ++ .../quests/bastok/Teak_Me_to_the_Stars.lua | 17 ++++---- .../quests/crystalWar/The_Price_of_Valor.lua | 4 ++ scripts/quests/jeuno/Chocobos_Wounds.lua | 4 +- .../quests/otherAreas/A_Hard_Days_Knight.lua | 6 ++- .../otherAreas/Give_a_Moogle_a_Break.lua | 38 ++++++++++-------- .../Knocking_on_Forbidden_Doors.lua | 10 ++--- .../quests/otherAreas/Moogles_in_the_Wild.lua | 40 +++++++++++-------- .../otherAreas/RQ4_His_Name_is_Valgeir.lua | 2 +- scripts/quests/otherAreas/Test_My_Mettle.lua | 2 +- .../quests/otherAreas/The_Moogles_Picnic.lua | 40 +++++++++++-------- scripts/quests/sandoria/The_Pickpocket.lua | 2 +- .../quests/windurst/Overnight_Delivery.lua | 2 +- scripts/quests/windurst/The_Fanged_One.lua | 2 +- scripts/specs/core/CBaseEntity.lua | 2 +- scripts/specs/types/Quest.lua | 18 ++++----- 19 files changed, 122 insertions(+), 89 deletions(-) diff --git a/scripts/quests/ahtUrhgan/Olduum.lua b/scripts/quests/ahtUrhgan/Olduum.lua index c9c50803db0..e890c2614b4 100644 --- a/scripts/quests/ahtUrhgan/Olduum.lua +++ b/scripts/quests/ahtUrhgan/Olduum.lua @@ -20,8 +20,8 @@ local keyItems = xi.ki.ELECTROLOCOMOTIVE, } -quest.hasKeyItem = function(player) - for i, v in pairs(keyItems) do +local hasQuestKeyItem = function(player) + for _, v in pairs(keyItems) do if player:hasKeyItem(v) then return true end @@ -68,7 +68,7 @@ quest.sections = ['Dkhaaya'] = { onTrigger = function(player, npc) - if quest.hasKeyItem(player) then + if hasQuestKeyItem(player) then return quest:progressEvent(6) else return quest:event(5) @@ -94,7 +94,7 @@ quest.sections = onTrade = function(player, npc, trade) if not player:hasItem(xi.item.OLDUUM_RING) and - not quest.hasKeyItem(player) and + not hasQuestKeyItem(player) and npcUtil.tradeHasExactly(trade, xi.item.PICKAXE) then if math.random(1, 10) > 5 then @@ -135,7 +135,7 @@ quest.sections = ['Dkhaaya'] = { onTrigger = function(player, npc) - if quest.hasKeyItem(player) then + if hasQuestKeyItem(player) then return quest:progressEvent(8) elseif player:hasItem(xi.item.OLDUUM_RING) or @@ -202,7 +202,7 @@ quest.sections = onTrade = function(player, npc, trade) if not player:hasItem(xi.item.OLDUUM_RING) and - not quest.hasKeyItem(player) and + not hasQuestKeyItem(player) and npcUtil.tradeHasExactly(trade, xi.item.PICKAXE) then if math.random(1, 10) > 5 then diff --git a/scripts/quests/ahtUrhgan/Three_Men_and_a_Closet.lua b/scripts/quests/ahtUrhgan/Three_Men_and_a_Closet.lua index 1897e5782d3..488a1761167 100644 --- a/scripts/quests/ahtUrhgan/Three_Men_and_a_Closet.lua +++ b/scripts/quests/ahtUrhgan/Three_Men_and_a_Closet.lua @@ -19,7 +19,8 @@ quest.sections = -- Section: Begin quest { check = function(player, status, vars) - return status == xi.questStatus.QUEST_AVAILABLE and player:getQuestStatus(xi.questLog.AHT_URHGAN, xi.quest.id.ahtUrhgan.GOT_IT_ALL) == xi.questStatus.QUEST_COMPLETED + return status == xi.questStatus.QUEST_AVAILABLE and + player:getQuestStatus(xi.questLog.AHT_URHGAN, xi.quest.id.ahtUrhgan.GOT_IT_ALL) == xi.questStatus.QUEST_COMPLETED end, [xi.zone.AHT_URHGAN_WHITEGATE] = @@ -27,7 +28,7 @@ quest.sections = ['Kubhe_Ijyuhla'] = { onTrigger = function(player, npc) - return quest:progressEvent(player, 836) + return quest:progressEvent(836) end }, diff --git a/scripts/quests/bastok/A_Question_of_Faith.lua b/scripts/quests/bastok/A_Question_of_Faith.lua index 28dee380a9d..fc85872747f 100644 --- a/scripts/quests/bastok/A_Question_of_Faith.lua +++ b/scripts/quests/bastok/A_Question_of_Faith.lua @@ -113,7 +113,7 @@ quest.sections = { [6] = function(player, csid, option, npc) player:delKeyItem(xi.ki.DAWN_TALISMAN) - return quest:messageSpecial(ID.text.WAS_TAKEN_FROM_YOU, 0, xi.ki.DAWN_TALISMAN) + player:messageSpecial(ID.text.WAS_TAKEN_FROM_YOU, 0, xi.ki.DAWN_TALISMAN) end, }, }, diff --git a/scripts/quests/bastok/Lure_of_the_Wildcat_Bastok.lua b/scripts/quests/bastok/Lure_of_the_Wildcat_Bastok.lua index 1195a20ac27..9048a23bbbb 100644 --- a/scripts/quests/bastok/Lure_of_the_Wildcat_Bastok.lua +++ b/scripts/quests/bastok/Lure_of_the_Wildcat_Bastok.lua @@ -41,6 +41,9 @@ local wildcatNpcData = ['Vaghron'] = { 19, 503 }, -- !pos -39.162 -1 -92.147 234 } +---@param player CBaseEntity +---@param npc CBaseEntity +---@return QuestReturnType? local wildcatOnTrigger = function(player, npc) local npcData = wildcatNpcData[npc:getName()] diff --git a/scripts/quests/bastok/Teak_Me_to_the_Stars.lua b/scripts/quests/bastok/Teak_Me_to_the_Stars.lua index 3a24aacc7ad..3b6d584a31f 100644 --- a/scripts/quests/bastok/Teak_Me_to_the_Stars.lua +++ b/scripts/quests/bastok/Teak_Me_to_the_Stars.lua @@ -25,14 +25,17 @@ quest.sections = [xi.zone.METALWORKS] = { - onTrigger = function(player, npc) - local option = 0 - if player:hasCompletedMission(xi.mission.id.cop.THE_CALL_OF_THE_WYRMKING) then - option = 2 -- additional dialogue regarding Crystal propulsion unit and hooded scientists as mentioned in cop wyrmking mission - end + ['Raibaht'] = + { + onTrigger = function(player, npc) + local option = 0 + if player:hasCompletedMission(xi.mission.log_id.COP, xi.mission.id.cop.THE_CALL_OF_THE_WYRMKING) then + option = 2 -- additional dialogue regarding Crystal propulsion unit and hooded scientists as mentioned in cop wyrmking mission + end - return quest:progressEvent(864, 0, xi.item.GARHADA_TEAK_LUMBER, 0, 0, 0, 0, option) - end, + return quest:progressEvent(864, 0, xi.item.GARHADA_TEAK_LUMBER, 0, 0, 0, 0, option) + end, + }, onEventFinish = { diff --git a/scripts/quests/crystalWar/The_Price_of_Valor.lua b/scripts/quests/crystalWar/The_Price_of_Valor.lua index 891174ab03c..03f74abf4a7 100644 --- a/scripts/quests/crystalWar/The_Price_of_Valor.lua +++ b/scripts/quests/crystalWar/The_Price_of_Valor.lua @@ -160,6 +160,10 @@ quest.sections = elseif questProgress == 5 then if quest:getLocalVar(player, 'nmDefeated') == 0 then local zoneObj = player:getZone() + if not zoneObj then + return + end + local mobObj = zoneObj:queryEntitiesByName('Madthrasher_Zradbodd')[1] if not mobObj:isSpawned() then diff --git a/scripts/quests/jeuno/Chocobos_Wounds.lua b/scripts/quests/jeuno/Chocobos_Wounds.lua index 6bf0f6bf032..80cdb9097a5 100644 --- a/scripts/quests/jeuno/Chocobos_Wounds.lua +++ b/scripts/quests/jeuno/Chocobos_Wounds.lua @@ -163,7 +163,9 @@ quest.sections = quest:setVar(player, 'Timer', os.time() + 45) quest:setVar(player, 'Prog', 4) - return quest:event(99) + -- TODO: This needs retail verification to confirm no zoning + -- event has occurred + player:startEvent(99) end, [60] = function(player, csid, option, npc) diff --git a/scripts/quests/otherAreas/A_Hard_Days_Knight.lua b/scripts/quests/otherAreas/A_Hard_Days_Knight.lua index 59f4dc0971b..8b597c3432b 100644 --- a/scripts/quests/otherAreas/A_Hard_Days_Knight.lua +++ b/scripts/quests/otherAreas/A_Hard_Days_Knight.lua @@ -135,14 +135,16 @@ quest.sections = { [631] = function(player, csid, option, npc) if quest:getVar(player, 'Prog') == 2 then - return quest:progressEvent(632) + -- TODO: This is most likely not retail accurate, and need to check captures + -- for forced zoning events. + player:startEvent(632) end end, [632] = function(player, csid, option, npc) player:confirmTrade() quest:setVar(player, 'Prog', 0) - return quest:keyItem(xi.ki.TEMPLE_KNIGHT_KEY) + npcUtil.giveKeyItem(player, xi.ki.TEMPLE_KNIGHT_KEY) end }, }, diff --git a/scripts/quests/otherAreas/Give_a_Moogle_a_Break.lua b/scripts/quests/otherAreas/Give_a_Moogle_a_Break.lua index a4a716dff11..ce4d9a7d1ce 100644 --- a/scripts/quests/otherAreas/Give_a_Moogle_a_Break.lua +++ b/scripts/quests/otherAreas/Give_a_Moogle_a_Break.lua @@ -16,19 +16,22 @@ quest.reward = -- Since there are so many zones with interactions: quest.sections = {} -quest.sections[1] = {} -quest.sections[1].check = function(player, status, vars) - local bedPlacedTime = quest:getVar(player, 'bedPlacedTime') - - return status == xi.questStatus.QUEST_AVAILABLE and - xi.moghouse.isInMogHouseInHomeNation(player) and - player:getFameLevel(player:getNation()) >= 3 and - not quest:getMustZone(player) and - quest:getLocalVar(player, 'questSeen') == 0 and - bedPlacedTime ~= 0 and - os.time() > bedPlacedTime + 60 -end +quest.sections[1] = +{ + check = function(player, status, vars) + local bedPlacedTime = quest:getVar(player, 'bedPlacedTime') + + return status == xi.questStatus.QUEST_AVAILABLE and + xi.moghouse.isInMogHouseInHomeNation(player) and + player:getFameLevel(player:getNation()) >= 3 and + not quest:getMustZone(player) and + quest:getLocalVar(player, 'questSeen') == 0 and + bedPlacedTime ~= 0 and + os.time() > bedPlacedTime + 60 + end +} +---@type TQuestZoneSection local questAvailable = { ['Moogle'] = @@ -50,11 +53,14 @@ local questAvailable = }, } -quest.sections[2] = {} -quest.sections[2].check = function(player, status, vars) - return status == xi.questStatus.QUEST_ACCEPTED -end +quest.sections[2] = +{ + check = function(player, status, vars) + return status == xi.questStatus.QUEST_ACCEPTED + end +} +---@type TQuestZoneSection local questAccepted = { ['Moogle'] = diff --git a/scripts/quests/otherAreas/Knocking_on_Forbidden_Doors.lua b/scripts/quests/otherAreas/Knocking_on_Forbidden_Doors.lua index c2b3c46b742..1bcfa68a161 100644 --- a/scripts/quests/otherAreas/Knocking_on_Forbidden_Doors.lua +++ b/scripts/quests/otherAreas/Knocking_on_Forbidden_Doors.lua @@ -47,7 +47,7 @@ quest.sections = { ['Chemioue'] = { - onTrigger = function(player, csid, option, npc) + onTrigger = function(player, npc) if quest:getVar(player, 'Prog') == 0 then return quest:progressEvent(536) end @@ -141,13 +141,13 @@ quest.sections = quest:getVar(player, 'Prog') == 3 and npcUtil.popFromQM(player, npc, misareauxID.mob.ALSHA, { claim = true, hide = 0 }) then - return quest:messageSpecial(misareauxID.text.FOUL_STENCH) + player:messageSpecial(misareauxID.text.FOUL_STENCH) end end, [558] = function(player, csid, option, npc) quest:setVar(player, 'Prog', 5) - return quest:keyItem(xi.ki.BETTER_HUMES_AND_MANNEQUINS) + npcUtil.giveKeyItem(player, xi.ki.BETTER_HUMES_AND_MANNEQUINS) end, }, }, @@ -156,7 +156,7 @@ quest.sections = { ['Fyi_Chalmwoh'] = { - onTrigger = function(player, csid, option, npc) + onTrigger = function(player, npc) if quest:getVar(player, 'Prog') == 5 then return quest:progressEvent(321, { [0] = 704, [1] = xi.mannequin.getMannequins(player), @@ -189,7 +189,7 @@ quest.sections = { ['Fyi_Chalmwoh'] = { - onTrigger = function(player, csid, option, npc) + onTrigger = function(player, npc) return quest:progressEvent(321, { [1] = xi.mannequin.getMannequins(player), [2] = xi.mannequin.cost.PURCHASE, [3] = xi.mannequin.cost.TRADE, diff --git a/scripts/quests/otherAreas/Moogles_in_the_Wild.lua b/scripts/quests/otherAreas/Moogles_in_the_Wild.lua index a82819093b0..ed92f141fe5 100644 --- a/scripts/quests/otherAreas/Moogles_in_the_Wild.lua +++ b/scripts/quests/otherAreas/Moogles_in_the_Wild.lua @@ -16,20 +16,23 @@ quest.reward = -- Since there are so many zones with interactions: quest.sections = {} -quest.sections[1] = {} -quest.sections[1].check = function(player, status, vars) - local bedPlacedTime = quest:getVar(player, 'bedPlacedTime') - - return status == xi.questStatus.QUEST_AVAILABLE and - player:hasCompletedQuest(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.THE_MOOGLE_PICNIC) and - xi.moghouse.isInMogHouseInHomeNation(player) and - player:getFameLevel(player:getNation()) >= 7 and - not quest:getMustZone(player) and - quest:getLocalVar(player, 'questSeen') == 0 and - bedPlacedTime ~= 0 and - os.time() > bedPlacedTime + 60 -end +quest.sections[1] = +{ + check = function(player, status, vars) + local bedPlacedTime = quest:getVar(player, 'bedPlacedTime') + + return status == xi.questStatus.QUEST_AVAILABLE and + player:hasCompletedQuest(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.THE_MOOGLE_PICNIC) and + xi.moghouse.isInMogHouseInHomeNation(player) and + player:getFameLevel(player:getNation()) >= 7 and + not quest:getMustZone(player) and + quest:getLocalVar(player, 'questSeen') == 0 and + bedPlacedTime ~= 0 and + os.time() > bedPlacedTime + 60 + end +} +---@type TQuestZoneSection local questAvailable = { ['Moogle'] = @@ -51,11 +54,14 @@ local questAvailable = }, } -quest.sections[2] = {} -quest.sections[2].check = function(player, status, vars) - return status == xi.questStatus.QUEST_ACCEPTED -end +quest.sections[2] = +{ + check = function(player, status, vars) + return status == xi.questStatus.QUEST_ACCEPTED + end +} +---@type TQuestZoneSection local questAccepted = { ['Moogle'] = diff --git a/scripts/quests/otherAreas/RQ4_His_Name_is_Valgeir.lua b/scripts/quests/otherAreas/RQ4_His_Name_is_Valgeir.lua index 83d3f9cf9c5..1a994cbf762 100644 --- a/scripts/quests/otherAreas/RQ4_His_Name_is_Valgeir.lua +++ b/scripts/quests/otherAreas/RQ4_His_Name_is_Valgeir.lua @@ -72,7 +72,7 @@ quest.sections = if player:hasKeyItem(xi.ki.ARAGONEU_PIZZA) and -- No free ride after delivering Pizza. player:getZPos() > 38.5 and -- Pos check. - quest:setVar(player, 'Prog') == 0 -- Hasn't taken the free ride. + quest:getVar(player, 'Prog') == 0 -- Hasn't taken the free ride. then return quest:progressEvent(230) -- Free ride. 1 time only. Non-Mandatory step. end diff --git a/scripts/quests/otherAreas/Test_My_Mettle.lua b/scripts/quests/otherAreas/Test_My_Mettle.lua index ac8dce83938..3a3546ad447 100644 --- a/scripts/quests/otherAreas/Test_My_Mettle.lua +++ b/scripts/quests/otherAreas/Test_My_Mettle.lua @@ -76,7 +76,7 @@ quest.sections = quest:setVar(player, 'Reward', betAmount * rewardMultiplier[vanaHoursRemaining]) quest:begin(player) else - return quest:messageSpecial(selbinaID.text.DONT_HAVE_ENOUGH_GIL) + player:messageSpecial(selbinaID.text.DONT_HAVE_ENOUGH_GIL) end end end, diff --git a/scripts/quests/otherAreas/The_Moogles_Picnic.lua b/scripts/quests/otherAreas/The_Moogles_Picnic.lua index db45950a414..7f57c2cc5dc 100644 --- a/scripts/quests/otherAreas/The_Moogles_Picnic.lua +++ b/scripts/quests/otherAreas/The_Moogles_Picnic.lua @@ -16,20 +16,23 @@ quest.reward = -- Since there are so many zones with interactions: quest.sections = {} -quest.sections[1] = {} -quest.sections[1].check = function(player, status, vars) - local bedPlacedTime = quest:getVar(player, 'bedPlacedTime') - - return status == xi.questStatus.QUEST_AVAILABLE and - player:hasCompletedQuest(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.GIVE_A_MOOGLE_A_BREAK) and - xi.moghouse.isInMogHouseInHomeNation(player) and - player:getFameLevel(player:getNation()) >= 5 and - not quest:getMustZone(player) and - quest:getLocalVar(player, 'questSeen') == 0 and - bedPlacedTime ~= 0 and - os.time() > bedPlacedTime + 60 -end +quest.sections[1] = +{ + check = function(player, status, vars) + local bedPlacedTime = quest:getVar(player, 'bedPlacedTime') + + return status == xi.questStatus.QUEST_AVAILABLE and + player:hasCompletedQuest(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.GIVE_A_MOOGLE_A_BREAK) and + xi.moghouse.isInMogHouseInHomeNation(player) and + player:getFameLevel(player:getNation()) >= 5 and + not quest:getMustZone(player) and + quest:getLocalVar(player, 'questSeen') == 0 and + bedPlacedTime ~= 0 and + os.time() > bedPlacedTime + 60 + end +} +---@type TQuestZoneSection local questAvailable = { ['Moogle'] = @@ -51,11 +54,14 @@ local questAvailable = }, } -quest.sections[2] = {} -quest.sections[2].check = function(player, status, vars) - return status == xi.questStatus.QUEST_ACCEPTED -end +quest.sections[2] = +{ + check = function(player, status, vars) + return status == xi.questStatus.QUEST_ACCEPTED + end +} +---@type TQuestZoneSection local questAccepted = { ['Moogle'] = diff --git a/scripts/quests/sandoria/The_Pickpocket.lua b/scripts/quests/sandoria/The_Pickpocket.lua index fc5b2cc4952..4625f4ca01f 100644 --- a/scripts/quests/sandoria/The_Pickpocket.lua +++ b/scripts/quests/sandoria/The_Pickpocket.lua @@ -192,7 +192,7 @@ quest.sections = { ['Esca'] = { - onTrigger = function(player, npc, trade) + onTrigger = function(player, npc) if player:hasItem(xi.item.GILT_GLASSES) then return quest:event(123) else diff --git a/scripts/quests/windurst/Overnight_Delivery.lua b/scripts/quests/windurst/Overnight_Delivery.lua index 2bf745eb175..c86ee02e38f 100644 --- a/scripts/quests/windurst/Overnight_Delivery.lua +++ b/scripts/quests/windurst/Overnight_Delivery.lua @@ -185,7 +185,7 @@ quest.sections = [346] = function(player, csid, option, npc) player:delQuest(quest.areaId, quest.questId) player:delKeyItem(xi.ki.SMALL_BAG) - quest:setVar('dueDate', 0) + quest:setVar(player, 'dueDate', 0) quest:setVar(player, 'Prog', 256) end, diff --git a/scripts/quests/windurst/The_Fanged_One.lua b/scripts/quests/windurst/The_Fanged_One.lua index 1c4f8cad89a..57d1b54dd2e 100644 --- a/scripts/quests/windurst/The_Fanged_One.lua +++ b/scripts/quests/windurst/The_Fanged_One.lua @@ -96,7 +96,7 @@ quest.sections = player:delKeyItem(xi.ki.OLD_TIGERS_FANG) player:unlockJob(xi.job.RNG) npcUtil.giveKeyItem(player, xi.ki.JOB_GESTURE_RANGER) - return quest:messageSpecial(windurstWoodsID.text.PERIH_VASHAI_DIALOG) + player:messageSpecial(windurstWoodsID.text.PERIH_VASHAI_DIALOG) end end, }, diff --git a/scripts/specs/core/CBaseEntity.lua b/scripts/specs/core/CBaseEntity.lua index 9f69f54b7fc..7e9b25cc548 100644 --- a/scripts/specs/core/CBaseEntity.lua +++ b/scripts/specs/core/CBaseEntity.lua @@ -283,7 +283,7 @@ end function CBaseEntity:startOptionalCutscene(EventID, p0, p1, p2, p3, p4, p5, p6, p7, textTable) end ----@param ... integer? +---@param ... integer|table? ---@return nil function CBaseEntity:updateEvent(...) end diff --git a/scripts/specs/types/Quest.lua b/scripts/specs/types/Quest.lua index 6f2404c8b98..0fe9734904f 100644 --- a/scripts/specs/types/Quest.lua +++ b/scripts/specs/types/Quest.lua @@ -4,10 +4,10 @@ ---@meta -- Definitions for quest.sections{} ----@class TQuestSectionList : TQuestZoneSection[] +---@alias TQuestSectionList TQuestSection[] ---@class TQuestSection ----@field check fun(player: CBaseEntity, status: { [integer]: xi.questStatus }, vars: { [string]: integer }): boolean +---@field check fun(player: CBaseEntity, status: xi.questStatus, vars: { [string]: integer }): boolean ---@field [xi.zone] TQuestZoneSection -- TODO: Below here, we can most likely be generic and reuse these definitions for Hidden Quests, Missions, @@ -16,27 +16,27 @@ ---@field onZoneIn? TQuestOnZoneIn ---@field onZoneOut? TQuestOnZoneFunction ---@field afterZoneIn? TQuestOnZoneFunction ----@field [string]? TQuestZoneEntity +---@field [string]? TQuestZoneEntity|QuestReturnType|fun(player: CBaseEntity, npc: CBaseEntity): QuestReturnType? ---@field onEventUpdate? TQuestEventSection ---@field onEventFinish? TQuestEventSection ---@field onTriggerAreaEnter? TQuestTriggerAreaSection ---@field onTriggerAreaLeave? TQuestTriggerAreaSection ---@class TQuestOnZoneIn ----@field [integer] fun(player: CBaseEntity, prevZone: xi.zone): integer +---@field [integer] fun(player: CBaseEntity, prevZone: xi.zone): integer? ---@class TQuestOnZoneFunction ----@field [integer] fun(player: CBaseEntity): QuestReturnType +---@field [integer] fun(player: CBaseEntity): QuestReturnType? ---@class TQuestTriggerAreaSection ----@field [integer] fun(player: CBaseEntity, triggerArea: CTriggerArea): QuestReturnType +---@field [integer] fun(player: CBaseEntity, triggerArea: CTriggerArea): QuestReturnType? ---@class TQuestZoneEntity ----@field onTrade? fun(player: CBaseEntity, npc: CBaseEntity, trade: CTradeContainer): QuestReturnType ----@field onTrigger? fun(player: CBaseEntity, npc: CBaseEntity): QuestReturnType +---@field onTrade? QuestReturnType|fun(player: CBaseEntity, npc: CBaseEntity, trade: CTradeContainer): QuestReturnType? +---@field onTrigger? QuestReturnType|fun(player: CBaseEntity, npc: CBaseEntity): QuestReturnType? ---@field onMobDeath? fun(mob: CBaseEntity, player: CBaseEntity, optParams: { isKiller: boolean, noKiller: boolean, isWeaponSkillKill: boolean, weaponskillUsed: xi.weaponskill, weaponskillDamage: integer }) ---@class TQuestEventSection ---@field [integer] fun(player: CBaseEntity, csid: integer, option: integer, npc: CBaseEntity) ----@alias QuestReturnType TInteractionEvent|TInteractionKeyItem|TInteractionMessage|TInteractionSequence|TInteractionNoAction? +---@alias QuestReturnType TInteractionEvent|TInteractionKeyItem|TInteractionMessage|TInteractionSequence|TInteractionAction|TInteractionNoAction?