2021-02-08 23:26:56 +01:00
-----------------------------------
2021-02-10 11:44:01 +01:00
-- Instance
2021-02-08 23:26:56 +01:00
-----------------------------------
2021-07-07 21:15:31 +03:00
-- TOAU storyline missions
2021-06-29 13:39:02 +03:00
-- Salvage
2021-07-07 21:15:31 +03:00
-- WOTG storyline missions
2021-06-29 13:39:02 +03:00
-- Certain Campaign Ops
-- Moblin Maze Mongers
-- The Notorious Monster battles that occur when Sandworm sucks in players using Doomvoid
--
-- Instance zones:
-- - ILRUSI_ATOLL = 55,
-- - PERIQIA = 56,
-- - THE_ASHU_TALIF = 60,
-- - LEBROS_CAVERN = 63,
-- - MAMOOL_JA_TRAINING_GROUNDS = 66,
-- - LEUJAOAM_SANCTUM = 69,
-- - ZHAYOLM_REMNANTS = 73,
-- - ARRAPAGO_REMNANTS = 74,
-- - BHAFLAU_REMNANTS = 75,
-- - SILVER_SEA_REMNANTS = 76,
-- - NYZUL_ISLE = 77,
-- - EVERBLOOM_HOLLOW = 86,
-- - RUHOTZ_SILVERMINES = 93,
-- - GHOYUS_REVERIE = 129,
-- - MAQUETTE_ABDHALJS_LEGION_A = 183,
-- - RALA_WATERWAYS_U = 259,
-- - YORCIA_WEALD_U = 264,
-- - CIRDAS_CAVERNS_U = 271,
2022-08-10 13:41:22 +03:00
-- - OUTER_RAKAZNAR_U1 = 275,
2021-06-29 13:39:02 +03:00
-- - MAQUETTE_ABDHALJS_LEGION_B = 287, -- See: ambuscade.lua
-- - DYNAMIS_SAN_DORIA_D = 294,
-- - DYNAMIS_BASTOK_D = 295,
-- - DYNAMIS_WINDURST_D = 296,
-- - DYNAMIS_JEUNO_D = 297,
-----------------------------------
2021-04-02 17:02:01 -04:00
xi = xi or { }
xi.instance = { }
2016-03-06 17:20:11 -07:00
2021-06-29 13:39:02 +03:00
--[[
[ zoneId ] =
{
2021-07-07 21:15:31 +03:00
{
instanceIdInDatabase ,
onTrigger startEvent args ( to be unpacked ) ,
2021-07-08 16:57:43 +03:00
onEventFinish valid entry args for registrant ( to be unpacked ) ,
event args for joining party members ( to be unpacked )
2021-07-07 21:15:31 +03:00
}
2021-06-29 13:39:02 +03:00
} ,
--]]
xi.instance . lookup =
{
[ xi.zone . ILRUSI_ATOLL ] =
{
-- Assault: Golden Salvage
-- Assault: Lamia No.13
-- Assault: Extermination
-- Assault: Demolition Duty
-- Assault: Searat Salvation
-- Assault: Apkallu Seizure
-- Assault: Lost and Found
-- Assault: Deserter
-- Assault: Desperately Seeking Cephalopods
-- Assault: Bellerophon's Bliss
} ,
[ xi.zone . PERIQIA ] =
{
2021-10-21 20:31:59 -05:00
{ 5600 , { 143 , 79 , - 6 , 0 , 99 , 3 , 0 } , { 143 , 4 } , { 147 , 3 } } , -- Shades of Vengeance (TOAU31)
2021-10-24 20:13:06 -05:00
{ 5601 , { 143 , 31 , - 4 , 0 , 70 , 0 , 1 } , { 143 , 4 } , { 147 , 0 } } , -- Assault: Seagull Grounded
2021-06-29 13:39:02 +03:00
-- Assault: Requiem
-- Assault: Saving Private Ryaaf
-- Assault: Shooting Down the Baron
-- Assault: Stop the Bloodshed
-- Assault: Defuse the Threat
-- Assault: Operation: Snake Eyes
-- Assault: Wake the Puppet
-- Assault: The Price is Right
} ,
[ xi.zone . THE_ASHU_TALIF ] =
{
2021-07-08 16:57:43 +03:00
{ 6000 , { 221 , 53 , - 6 , 0 , 99 , 6 , 0 } , { 221 , 4 } , { 222 , 6 } } , -- The Black Coffin (TOAU 15)
{ 6001 , { 221 , 54 , - 9 , 0 , 99 , 6 , 0 } , { 221 , 4 } , { 222 , 6 } } , -- Against All Odds
2021-07-08 08:57:44 +03:00
-- Testing the Waters (TOAU 34)
-- Legacy of the Lost (TOAU 35)
2021-06-29 13:39:02 +03:00
-- Assault: Royal Painter Escort
-- Assault: Scouting the Ashu Talif
-- Assault: Targeting the Captain
} ,
[ xi.zone . LEBROS_CAVERN ] =
{
2021-10-21 20:31:59 -05:00
{ 6300 , { 203 , 21 , - 4 , 0 , 50 , 0 , 1 } , { 203 , 4 } , { 208 , 0 } } , -- Assault: Excavation Duty
2021-06-29 13:39:02 +03:00
-- Assault: Lebros Supplies
-- Assault: Troll Fugitives
-- Assault: Evade and Escape
-- Assault: Siegemaster Assassination
-- Assault: Apkallu Breeding
-- Assault: Wamoura Farm Raid
-- Assault: Egg Conservation
-- Assault: Operation: Black Pearl
-- Assault: Better Than One
} ,
[ xi.zone . MAMOOL_JA_TRAINING_GROUNDS ] =
{
2022-09-17 10:50:57 -04:00
{ 6600 , { 505 , 11 , - 4 , 0 , 60 , 0 , 1 } , { 505 , 4 } , { 511 , 0 } } , -- Assault: Imperial Agent Rescue
2021-06-29 13:39:02 +03:00
-- Assault: Preemptive Strike
-- Assault: Sagelord Elimination
-- Assault: Breaking Morale
-- Assault: The Double Agent
-- Assault: Imperial Treasure Retrieval
-- Assault: Blitzkrieg
-- Assault: Marids in the Mist
-- Assault: Azure Ailments
-- Assault: The Susanoo Shuffle
} ,
[ xi.zone . LEUJAOAM_SANCTUM ] =
{
2022-09-17 10:50:57 -04:00
{ 6900 , { 140 , 1 , - 4 , 0 , 50 , 0 , 1 } , { 140 , 4 } , { 147 , 0 } } , -- Assault: Leujaoam Cleansing
2021-06-29 13:39:02 +03:00
-- Assault: Orichalcum Survey
-- Assault: Escort Professor Chanoix
-- Assault: Shanarha Grass Conservation
-- Assault: Counting Sheep
-- Assault: Supplies Recovery
-- Assault: Azure Experiments
-- Assault: Imperial Code
-- Assault: Red Versus Blue
-- Assault: Bloody Rondo
} ,
[ xi.zone . ZHAYOLM_REMNANTS ] =
{
2025-02-04 15:45:33 -06:00
{ 7300 , { 407 , 0 , - 6 , 0 , 0 , 7 } , { 407 , 4 } , { 411 , 7 } } , -- Salvage I, Zhayolm Remnants
2021-06-29 13:39:02 +03:00
} ,
[ xi.zone . ARRAPAGO_REMNANTS ] =
{
2025-02-04 15:45:33 -06:00
{ 7400 , { 408 , 0 , - 6 , 0 , 0 , 8 } , { 408 , 4 } , { 411 , 8 } } , -- Salvage I, Arrapago Remnants
2021-06-29 13:39:02 +03:00
} ,
[ xi.zone . BHAFLAU_REMNANTS ] =
{
2025-02-04 15:45:33 -06:00
{ 7500 , { 409 , 0 , - 6 , 0 , 0 , 9 } , { 409 , 4 } , { 411 , 9 } } , -- Salvage I, Bhaflau Remnants
2021-06-29 13:39:02 +03:00
} ,
[ xi.zone . SILVER_SEA_REMNANTS ] =
{
2025-02-04 15:45:33 -06:00
{ 7600 , { 410 , 0 , - 6 , 0 , 0 , 10 } , { 410 , 4 } , { 411 , 10 } } , -- Salvage I, Silver Sea Remnants
2021-06-29 13:39:02 +03:00
} ,
[ xi.zone . NYZUL_ISLE ] =
{
2025-04-20 02:19:22 -06:00
{ 7700 , { 405 , 58 , - 6 , 0 , 99 , 5 , 0 } , { 116 , 1 } , { 411 , 5 } } , -- Path of Darkness
{ 7701 , { 405 , 59 , - 10 , 0 , 99 , 5 , 0 } , { 116 , 1 } , { 411 , 5 } } , -- Nashmeira's Plea
{ 7702 , { 405 , 60 , - 34 , 0 , 99 , 5 , 1 , 0 , 14 } , { 116 , 1 } , { 411 , 5 } } , -- Waking the Colossus/Divine Interference
2021-06-29 13:39:02 +03:00
-- Forging a New Myth
2025-04-20 02:19:22 -06:00
{ 7704 , { 405 , 51 , - 4 , 0 , 75 , 5 , 1 } , { 116 , 2 } , { 411 , 5 } } , -- Nyzul Isle Investigation
2021-06-29 13:39:02 +03:00
} ,
[ xi.zone . EVERBLOOM_HOLLOW ] =
{
-- Honor Under Fire
-- Bonds That Never Die
-- A Nation on the Brink
-- Dungeons and Dancers
2021-07-07 21:15:31 +03:00
-- Campaign Ops:
2021-06-29 13:39:02 +03:00
-- Brave Dawn I (San d'Oria)
-- Brave Dawn II (San d'Oria)
-- Brave Dawn III (San d'Oria)
-- Granite Rose I (San d'Oria)
-- Granite Rose II (San d'Oria)
-- Granite Rose III (San d'Oria)
-- Pit Spider I (San d'Oria)
-- Pit Spider II (San d'Oria)
-- Pit Spider III (San d'Oria)
2021-07-07 21:15:31 +03:00
-- Doomvoid - King Arthro
-- Doomvoid - Lambton Worm
2021-06-29 22:28:38 +03:00
-- Moblin Maze Mongers
2021-06-29 13:39:02 +03:00
} ,
[ xi.zone . RUHOTZ_SILVERMINES ] =
{
2021-07-08 16:57:43 +03:00
{ 9300 , { 3 , 0 , 0 , 19 } , { 3 , 4 } , { 4 , 1 } } , -- Light in the Darkness (WOTG Bastok Quest 3)
{ 9301 , { 203 , 0 , 0 , 36 } , { 203 , 4 } , { 201 , 1 } } , -- Fire in the Hole (WOTG Bastok Quest 6)
2021-06-29 13:39:02 +03:00
-- { 0, { 0, 0, 34 } }, -- Seeing Blood-red (SCH AF3)
-- { 0, { 0, 23, 0 } }, -- Distorter of Time
2021-07-07 21:15:31 +03:00
-- Campaign Ops:
2021-06-29 13:39:02 +03:00
-- Brave Dawn I (Bastok)
-- Brave Dawn II (Bastok)
-- Brave Dawn III (Bastok)
-- By Light of Fire I (Bastok)
-- Granite Rose I (Bastok)
-- Granite Rose II (Bastok)
-- Granite Rose III (Bastok)
-- Pit Spider I (Bastok)
-- Pit Spider II (Bastok)
2021-07-07 21:15:31 +03:00
-- Doomvoid - Lambton Worm
-- Doomvoid - Guivre
-- Moblin Maze Mongers
2021-06-29 13:39:02 +03:00
} ,
[ xi.zone . GHOYUS_REVERIE ] =
{
-- A Feast for Gnats
-- A Manifest Problem
-- In a Haze of Glory
-- Sins of the Mothers
2021-07-07 21:15:31 +03:00
-- Campaign Ops:
2021-06-29 13:39:02 +03:00
-- Brave Dawn I (Windurst)
-- Brave Dawn II (Windurst)
-- Brave Dawn III (Windurst)
-- Granite Rose I (Windurst)
-- Granite Rose II (Windurst)
-- Pit Spider I (Windurst)
-- Pit Spider II (Windurst)
2021-07-07 21:15:31 +03:00
-- Doomvoid - Lambton Worm
-- Doomvoid - Serket
2021-06-29 13:39:02 +03:00
} ,
[ xi.zone . MAQUETTE_ABDHALJS_LEGION_A ] =
{
2021-07-08 17:08:35 +03:00
-- Hall of An (Leader entry: { 8009, 0, 0, 0, 0, 6, 1 }, Party entry: { 8003, 0, 0, 0, 0, 6, 1 })
2021-06-29 13:39:02 +03:00
-- Hall of Ki
-- Hall of Im
-- Hall of Muru
-- Hall of Mul
} ,
[ xi.zone . RALA_WATERWAYS_U ] =
{
-- { 0, 0 }, -- Endeavoring to Awaken
-- { 1, 0 }, -- Endeavoring to Awaken
-- -- Blank
2021-09-15 10:10:37 +03:00
{ 25900 , { 5511 , 258 , 8 } , { 5511 , 8 } , { 258 , 8 } } , -- Behind the Sluices
2021-06-29 13:39:02 +03:00
-- { 4, 0 }, -- Stonewalled
-- { 5, 0 }, -- The Gates
-- { 6, 0 }, -- Saved by the Bell
-- { 7, 0 }, -- Quiescence
-- { 8, 0 }, -- The Charlatan
-- { 9, 0 }, -- Yggdrasil Beckons
-- { 10, 0 }, -- Yggdrasil Beckons
-- { 11, 0 }, -- Watery Grave
-- { 12, 0 }, -- Mistress of Ceremonies
-- { 13, 0 }, -- A Barrel of Laughs
-- { 14, 0 }, -- Sinister Reign
-- { 15, 0 }, -- The Ygnas Directive 6
-- { 16, 0 }, -- Skirmishes
-- { 17, 0 }, -- Fractures
-- { 18, 0 }, -- Alluvion skirmishes
-- { 19, 0 }, -- The Silent Forest
-- { 20, 0 }, -- Wind of Eternity
} ,
[ xi.zone . YORCIA_WEALD_U ] =
{
} ,
[ xi.zone . CIRDAS_CAVERNS_U ] =
{
} ,
2022-08-10 13:41:22 +03:00
[ xi.zone . OUTER_RAKAZNAR_U1 ] =
2021-06-29 13:39:02 +03:00
{
} ,
[ xi.zone . DYNAMIS_SAN_DORIA_D ] =
{
} ,
[ xi.zone . DYNAMIS_BASTOK_D ] =
{
} ,
[ xi.zone . DYNAMIS_WINDURST_D ] =
{
} ,
[ xi.zone . DYNAMIS_JEUNO_D ] =
{
} ,
}
2025-04-20 02:19:22 -06:00
local getInstanceName = function ( player , instanceId )
return switch ( instanceId ) : caseof
{
[ 7702 ] = function ( )
if player : getQuestStatus ( xi.questLog . AHT_URHGAN , xi.quest . id.ahtUrhgan . DIVINE_INTERFERENCE ) >= xi.questStatus . QUEST_ACCEPTED then
return 1 -- Divine Interference
else
return 0 -- Waking the Colossus
end
end ,
}
end
2021-07-07 21:15:31 +03:00
-- Party leader registering
2021-07-08 15:33:49 +03:00
local checkRegistryReqs = function ( player , instanceId )
2021-07-07 21:15:31 +03:00
local instanceObj = GetCachedInstanceScript ( instanceId )
2023-08-28 21:02:28 -04:00
if type ( instanceObj.registryRequirements ) == ' function ' then
2021-07-07 21:15:31 +03:00
return instanceObj.registryRequirements ( player )
else
2023-08-28 21:02:28 -04:00
print ( ' xi.instance: checkReqs: registryRequirements function not set for instance: ' .. instanceId )
2021-07-07 21:15:31 +03:00
return false
end
2021-06-29 13:39:02 +03:00
end
2021-07-07 21:15:31 +03:00
-- Further players joining
2021-07-08 15:33:49 +03:00
local checkEntryReqs = function ( player , instanceId )
2021-07-07 21:15:31 +03:00
local instanceObj = GetCachedInstanceScript ( instanceId )
2023-08-28 21:02:28 -04:00
if type ( instanceObj.entryRequirements ) == ' function ' then
2021-07-07 21:15:31 +03:00
return instanceObj.entryRequirements ( player )
else
2023-08-28 21:02:28 -04:00
print ( ' xi.instance: checkReqs: entryRequirements function not set for instance: ' .. instanceId )
2021-07-07 21:15:31 +03:00
return false
end
end
2021-06-29 13:39:02 +03:00
2026-05-25 22:11:21 -06:00
-- Clear up after possible failed loads
xi.instance . clearInstance = function ( player )
player : setLocalVar ( ' INSTANCE_REQUESTED ' , 0 )
local existingInstance = player : getInstance ( )
if existingInstance then
existingInstance : fail ( )
end
end
2021-07-07 21:15:31 +03:00
xi.instance . onTrade = function ( player , npc , trade )
end
2021-06-29 13:39:02 +03:00
2021-07-07 21:15:31 +03:00
xi.instance . onTrigger = function ( player , npc , instanceZoneID )
local zoneLookup = xi.instance . lookup [ instanceZoneID ]
2021-06-29 22:28:38 +03:00
2026-05-25 22:11:21 -06:00
xi.instance . clearInstance ( player )
2021-09-15 10:10:37 +03:00
2021-07-07 21:15:31 +03:00
-- Find the first instance you're valid for
-- TODO: Handle being valid for multiple instances from the same entrance
local chosenEntry
for _ , entry in ipairs ( zoneLookup ) do
2023-08-02 02:11:11 +02:00
local instanceId = entry [ 1 ]
2021-07-08 15:33:49 +03:00
local hasValidEntry = checkRegistryReqs ( player , instanceId )
2023-08-02 02:11:11 +02:00
2021-07-07 21:15:31 +03:00
if hasValidEntry then
chosenEntry = entry
break
end
end
if chosenEntry == nil then
return false
end
-- Play the cs + args for that instance
2023-08-02 02:11:11 +02:00
local instanceId = chosenEntry [ 1 ]
2021-07-07 21:15:31 +03:00
local instanceTriggerArgs = chosenEntry [ 2 ]
2023-08-02 02:11:11 +02:00
local hasValidEntry = checkRegistryReqs ( player , instanceId )
2021-07-07 21:15:31 +03:00
if hasValidEntry then
2023-08-28 21:02:28 -04:00
player : setLocalVar ( ' INSTANCE_ID ' , instanceId )
2025-04-20 02:19:22 -06:00
if instanceTriggerArgs [ 8 ] ~= nil then
instanceTriggerArgs [ 8 ] = getInstanceName ( player , instanceId )
end
2021-07-07 21:15:31 +03:00
player : startEvent ( unpack ( instanceTriggerArgs ) )
2023-08-02 02:11:11 +02:00
2021-07-07 21:15:31 +03:00
return true
else
return false
end
2021-06-29 13:39:02 +03:00
end
2023-07-23 11:24:44 -04:00
xi.instance . onEventUpdate = function ( player , csid , option , npc )
2023-08-28 21:02:28 -04:00
local instanceId = player : getLocalVar ( ' INSTANCE_ID ' )
2023-08-02 02:11:11 +02:00
local party = player : getParty ( )
local ID = zones [ player : getZoneID ( ) ]
2021-07-07 21:15:31 +03:00
if party ~= nil then
for _ , v in pairs ( party ) do
2024-04-16 14:20:55 -05:00
if
v : getID ( ) ~= player : getID ( ) and
v : getZoneID ( ) == player : getZoneID ( )
then
2021-07-07 21:15:31 +03:00
-- Check entry requirements for party
2022-11-05 11:00:40 -04:00
if not checkEntryReqs ( v , instanceId ) then
2021-07-07 21:15:31 +03:00
player : messageText ( npc , ID.text . MEMBER_NO_REQS , false )
player : instanceEntry ( npc , 1 )
2023-08-02 02:11:11 +02:00
2021-07-07 21:15:31 +03:00
return false
end
2022-11-22 14:42:58 -05:00
2021-07-07 21:15:31 +03:00
-- Check everyone is in range
2024-04-16 14:20:55 -05:00
if v : checkDistance ( player ) > 50 then
2021-07-07 21:15:31 +03:00
player : messageText ( npc , ID.text . MEMBER_TOO_FAR , false )
player : instanceEntry ( npc , 1 )
2023-08-02 02:11:11 +02:00
2021-07-07 21:15:31 +03:00
return false
end
end
end
end
2023-08-28 21:02:28 -04:00
if player : getLocalVar ( ' INSTANCE_REQUESTED ' ) == 0 then
2021-07-07 21:15:31 +03:00
player : createInstance ( instanceId )
2023-08-28 21:02:28 -04:00
player : setLocalVar ( ' INSTANCE_REQUESTED ' , 1 )
2021-07-07 21:15:31 +03:00
end
2024-04-19 07:17:21 -05:00
if
player : getInstance ( ) ~= nil or
( player : getLocalVar ( ' INSTANCE_REQUESTED ' ) > 0 and
player : getLocalVar ( ' INSTANCE_REQUESTED ' ) < 10 )
then
-- return true so we don't immediately call the cancel event update (since instances don't immediately load), but
-- increment variable to eventually return false if instance fails to load and trigger onInstanceCreatedCallback
player : setLocalVar ( ' INSTANCE_REQUESTED ' , player : getLocalVar ( ' INSTANCE_REQUESTED ' ) + 1 )
return true
else
return false
end
2021-07-07 21:15:31 +03:00
end
2024-12-01 15:55:23 -05:00
-- 'Default' behavior. It's up to each instance whether or not they want to use this logic
2026-05-25 22:11:21 -06:00
-- Can pass instance cutscene information directly if accessible from container, otherwise will try and find it from the player's instance
xi.instance . onInstanceCreatedCallback = function ( player , instance , entryInfo )
2021-07-08 16:10:19 +03:00
local instanceId = instance : getID ( )
2026-05-25 22:11:21 -06:00
if entryInfo == nil then
-- Collect cs for party members
for _ , entry in ipairs ( xi.instance . lookup [ instance : getZone ( ) : getID ( ) ] ) do
local entryInstanceId = entry [ 1 ]
if instanceId == entryInstanceId then
entryInfo = entry
2023-08-02 02:11:11 +02:00
2026-05-25 22:11:21 -06:00
break
end
2021-07-08 16:10:19 +03:00
end
2021-07-08 15:33:49 +03:00
end
2021-07-07 21:15:31 +03:00
-- If you're in the official entrance zone, try and playout the
-- entrance animation. Otherwise: go straight to the instance
if player : getZoneID ( ) == instance : getEntranceZoneID ( ) then
2024-04-16 14:20:55 -05:00
-- join initiating player as commander
player : setInstance ( instance )
2021-07-07 21:15:31 +03:00
-- This packet will trigger the end of the blocking
-- cutscene and xi.instance.onEventFinish will handle
-- the transportation
2021-07-08 15:33:49 +03:00
for _ , v in ipairs ( player : getParty ( ) ) do
2024-04-16 14:20:55 -05:00
if v : getZoneID ( ) == player : getZoneID ( ) then
if v : getID ( ) ~= player : getID ( ) then
-- player will be brought into instance either way
-- this makes the animation trigger reliably
v : release ( )
2026-05-25 22:11:21 -06:00
v : startEvent ( unpack ( entryInfo.memberEvent or entryInfo [ 4 ] ) )
2022-11-22 14:42:58 -05:00
2024-04-30 18:24:46 -05:00
v : setInstance ( instance )
local npc = player : getEventTarget ( )
if npc ~= nil then
v : instanceEntry ( npc , 4 )
end
2024-04-16 14:20:55 -05:00
end
v : timer ( 35000 , function ( playerArg )
-- failsafe to bring all players into instance
-- if a player doesn't receive the event packet, the whole party will be stuck in blackscreen
-- timer is destroyed if onEventFinish works properly and player gets zoned
-- a properly-functioning event loop will take 20s to zoning into the instance
2024-04-19 07:17:21 -05:00
-- this _should_ be completely unnecessary due to the looping logic with INSTANCE_REQUESTED, but just in case
2024-04-16 14:20:55 -05:00
local instanceArg = playerArg : getInstance ( )
if instanceArg then
print ( fmt ( ' Player {} failed to cleanly transition into instance event, forcing entry via setPos. ' , playerArg : getName ( ) ) )
playerArg : setPos ( 0 , 0 , 0 , 0 , instanceArg : getZone ( ) : getID ( ) )
end
end )
2021-07-11 21:52:51 +03:00
end
2021-07-08 15:33:49 +03:00
end
2024-04-16 14:20:55 -05:00
-- finally, send commander in
2026-05-25 22:11:21 -06:00
player : startEvent ( unpack ( entryInfo.memberEvent or entryInfo [ 4 ] ) ) -- will fail if previous event is working as it should, otherwise catches secondary event to enter
2024-04-16 14:20:55 -05:00
local npc = player : getEventTarget ( )
if npc ~= nil then
player : instanceEntry ( npc , 4 )
end
2021-07-07 21:15:31 +03:00
else
2021-07-08 15:33:49 +03:00
for _ , v in ipairs ( player : getParty ( ) ) do
2021-07-08 16:10:19 +03:00
v : setInstance ( instance )
2021-07-08 15:33:49 +03:00
v : setPos ( 0 , 0 , 0 , 0 , instance : getZone ( ) : getID ( ) )
end
2021-07-07 21:15:31 +03:00
end
2021-06-29 13:39:02 +03:00
end
2026-05-25 22:11:21 -06:00
-- Default instance behavior. Unpacks the csid and option from the lookup table.
-- Can pass instance custcene information directly if accessible from container,
-- otherwise will try and find it from the player's instance and a table lookup.
xi.instance . onEventFinish = function ( player , csid , option , npc , instanceInfo )
2021-07-07 21:15:31 +03:00
local instance = player : getInstance ( )
2023-08-02 02:11:11 +02:00
2021-07-07 21:15:31 +03:00
if instance then
2026-05-25 22:11:21 -06:00
if not instanceInfo then
instanceInfo = xi.instance . lookup [ instance : getZone ( ) : getID ( ) ] [ 1 ] [ 3 ]
end
local csidEntry , optionEntry = unpack ( instanceInfo )
2023-08-02 02:11:11 +02:00
2021-07-07 21:15:31 +03:00
if csid == csidEntry and option == optionEntry then
2021-07-08 15:33:49 +03:00
for _ , v in ipairs ( player : getParty ( ) ) do
v : setPos ( 0 , 0 , 0 , 0 , instance : getZone ( ) : getID ( ) )
end
2022-11-22 14:42:58 -05:00
2021-07-07 21:15:31 +03:00
return true
end
end
2022-11-22 14:42:58 -05:00
2021-07-07 21:15:31 +03:00
return false
2021-06-29 13:39:02 +03:00
end
2021-06-30 09:05:38 +03:00
local function setInstanceLastTimeUpdateMessage ( instance , players , remainingTimeLimit , text )
2023-08-02 02:11:11 +02:00
local message = 0
2020-02-22 19:37:33 -08:00
local lastTimeUpdate = instance : getLastTimeUpdate ( )
2021-02-08 23:26:56 +01:00
if lastTimeUpdate == 0 and remainingTimeLimit < 600 then
message = 600
elseif lastTimeUpdate == 600 and remainingTimeLimit < 300 then
message = 300
elseif lastTimeUpdate == 300 and remainingTimeLimit < 60 then
message = 60
elseif lastTimeUpdate == 60 and remainingTimeLimit < 30 then
message = 30
elseif lastTimeUpdate == 30 and remainingTimeLimit < 10 then
message = 10
end
if message ~= 0 then
for i , player in pairs ( players ) do
2021-02-09 17:02:02 +01:00
if remainingTimeLimit >= 60 then
2021-07-08 08:57:44 +03:00
player : messageSpecial ( text.TIME_REMAINING_MINUTES , message / 60 )
2021-02-08 23:26:56 +01:00
else
2021-07-08 08:57:44 +03:00
player : messageSpecial ( text.TIME_REMAINING_SECONDS , message )
2021-02-08 23:26:56 +01:00
end
end
2022-11-22 14:42:58 -05:00
2021-02-08 23:26:56 +01:00
instance : setLastTimeUpdate ( message )
end
end
2021-06-30 09:05:38 +03:00
xi.instance . updateInstanceTime = function ( instance , elapsed , text )
2023-08-02 02:11:11 +02:00
local players = instance : getChars ( )
local remainingTimeLimit = instance : getTimeLimit ( ) * 60 - ( elapsed / 1000 )
local wipeTime = instance : getWipeTime ( )
2020-03-19 18:41:42 -07:00
2022-11-13 10:26:06 -05:00
if
remainingTimeLimit < 0 or
2023-08-02 02:11:11 +02:00
( wipeTime ~= 0 and ( elapsed - wipeTime ) / 1000 > 180
2022-11-13 10:26:06 -05:00
)
then
2020-02-22 19:37:33 -08:00
instance : fail ( )
2023-08-02 02:11:11 +02:00
2020-02-22 19:37:33 -08:00
return
2016-03-06 17:20:11 -07:00
end
2020-03-19 18:41:42 -07:00
2021-02-08 23:26:56 +01:00
if wipeTime == 0 then
2020-02-22 19:37:33 -08:00
local wipe = true
2023-08-02 02:11:11 +02:00
2021-02-08 23:26:56 +01:00
for i , player in pairs ( players ) do
if player : getHP ( ) ~= 0 then
2020-02-22 19:37:33 -08:00
wipe = false
break
2016-03-06 17:20:11 -07:00
end
end
2022-11-22 14:42:58 -05:00
2021-02-09 17:02:02 +01:00
if wipe then
2021-02-08 23:26:56 +01:00
for i , player in pairs ( players ) do
2021-06-30 09:05:38 +03:00
player : messageSpecial ( text.PARTY_FALLEN , 3 )
2016-03-06 17:20:11 -07:00
end
2022-11-22 14:42:58 -05:00
2020-02-22 19:37:33 -08:00
instance : setWipeTime ( elapsed )
2016-03-06 17:20:11 -07:00
end
else
2021-02-08 23:26:56 +01:00
for i , player in pairs ( players ) do
if player : getHP ( ) ~= 0 then
instance : setWipeTime ( 0 )
break
2016-03-06 17:20:11 -07:00
end
end
end
2022-11-22 14:42:58 -05:00
2021-06-30 09:05:38 +03:00
setInstanceLastTimeUpdateMessage ( instance , players , remainingTimeLimit , text )
2016-03-06 17:20:11 -07:00
end