Skip to content

Commit 52fcfdf

Browse files
committed
Refactor ejection code and cleanup
1 parent 8661d06 commit 52fcfdf

3 files changed

Lines changed: 118 additions & 117 deletions

File tree

scripts/globals/dynamis/dynamis_system.lua

Lines changed: 33 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -27,32 +27,6 @@ local function debugTickPrint(message)
2727
end
2828
end
2929

30-
-----------------------------------
31-
-- Global Dynamis Variables --
32-
-----------------------------------
33-
-- Come back when I do tav
34-
-- local function getDynamisTavWinParam(player)
35-
-- local zmComplete = player:getCurrentMission(xi.mission.log_id.ZILART) >= xi.mission.id.zilart.AWAKENING
36-
-- local copComplete = player:getCurrentMission(xi.mission.log_id.COP) >= xi.mission.id.cop.DAWN
37-
-- local anComplete = player:hasCompletedQuest(xi.quest.log_id.JEUNO, xi.quest.id.jeuno.APOCALYPSE_NIGH)
38-
39-
-- if anComplete then
40-
-- -- AN requires ZM and CoP
41-
-- return 3
42-
-- elseif zmComplete then
43-
-- if copComplete then
44-
-- -- ZM and CoP
45-
-- return 2
46-
-- end
47-
48-
-- -- ZM only
49-
-- return 1
50-
-- end
51-
52-
-- -- Not ZM complete
53-
-- return 0
54-
-- end
55-
5630
-----------------------------------
5731
-- onZoneTick Dynamis Functions --
5832
-----------------------------------
@@ -280,8 +254,6 @@ end
280254
-----------------------------------
281255
-- Dynamis Zone Functions --
282256
-----------------------------------
283-
-- Cleanup Done
284-
-- Re-wrote the function to be used for everything not just GMs
285257
xi.dynamis.addMinutesToDynamis = function(zone, minutes)
286258
local zoneId = zone:getID()
287259
local varExpiration = string.format('[DYNA]ExpirationTime_%s', zoneId)
@@ -324,7 +296,6 @@ xi.dynamis.addMinutesToDynamis = function(zone, minutes)
324296
end
325297
end
326298

327-
-- Cleanup Done
328299
xi.dynamis.addTimeToDynamis = function(zone, mob)
329300
local zoneId = zone:getID()
330301
local mobID = mob:getID()
@@ -342,7 +313,6 @@ xi.dynamis.addTimeToDynamis = function(zone, mob)
342313
end
343314
end
344315

345-
-- Cleanup Done
346316
xi.dynamis.getDynaTimeRemaining = function(zoneExpiration)
347317
local timeRemaining = (zoneExpiration - GetSystemTime()) -- Returns difference.
348318
-- xi.dynamis.debugPrint('Dynamis Time Remaining Check | Expiration: ' .. tostring(zoneExpiration) .. ' | CurrentTime: ' .. tostring(GetSystemTime()) .. ' | Result: ' .. tostring(timeRemaining))
@@ -415,6 +385,39 @@ xi.dynamis.dynamisTimeWarning = function(zone, zoneExpiration)
415385
end
416386
end
417387

388+
xi.dynamis.zoneOnZoneInEra = function(player, prevZone)
389+
local zoneId = player:getZoneID()
390+
local zoneExpiration = GetServerVariable(string.format('[DYNA]ExpirationTime_%s', zoneId))
391+
local info = xi.dynamis.dynaInfoEra[zoneId]
392+
local ID = zones[zoneId]
393+
394+
xi.dynamis.debugPrint(string.format('------------xi.dynamis.zoneOnZoneInEra------------'))
395+
-- usually happens when zoning in with !zone command
396+
-- If player is in void, move player to entry.
397+
if
398+
player:getXPos() == 0 and
399+
player:getYPos() == 0 and
400+
player:getZPos() == 0
401+
then
402+
player:setPos(unpack(info.entryPos))
403+
end
404+
405+
local expirationTime = xi.dynamis.getDynaTimeRemaining(zoneExpiration)
406+
xi.dynamis.debugPrint(string.format('expirationTime calculation: %s | zoneExpiration: %s | currentTime: %s', tostring(expirationTime), tostring(zoneExpiration), tostring(GetSystemTime())))
407+
-- Send message letting player know how long they have.
408+
player:timer(5000, function(playerArg)
409+
playerArg:messageSpecial(ID.text.DYNAMIS_TIME_UPDATE_2, math.floor(utils.clamp(expirationTime, 0, expirationTime) / 60), 1)
410+
end)
411+
412+
-- Update hourglass if player has one - will only update endTime if it was extended (zoneExpiration > current endTime)
413+
xi.dynamis.debugPrint(string.format('Updating hourglass for player'))
414+
xi.dynamis.updatePlayerHourglass(player)
415+
416+
-- Check for dreamland SJ restriction and apply if necessary
417+
xi.dynamis.applyEntryRestrictions(player, zoneId)
418+
return -1
419+
end
420+
418421
-----------------------------------
419422
-- Dynamis Player Functions --
420423
-----------------------------------
@@ -497,52 +500,6 @@ xi.dynamis.registerPlayer = function(player)
497500
xi.dynamis.recordLockout(player)
498501
end
499502

500-
-- TODO Cleanup
501-
xi.dynamis.ejectPlayer = function(player, forceEject)
502-
xi.dynamis.debugPrint('Ejecting player: ' .. tostring(player:getName()) .. ' | forceEject: ' .. tostring(forceEject))
503-
local zoneId = player:getZoneID()
504-
if forceEject == nil then
505-
forceEject = false
506-
end
507-
508-
if player:getCurrentRegion() == xi.region.DYNAMIS then
509-
if player:getLocalVar('Received_Eject_Warning') ~= 1 then
510-
player:delStatusEffectSilent(xi.effect.BATTLEFIELD)
511-
if not forceEject then
512-
player:timer(2000, function(playerArg)
513-
playerArg:messageSpecial(xi.dynamis.getZoneMessageID('NO_LONGER_HAVE_CLEARANCE', zoneId), 0, 30) -- Wait 1 second, send no clearance message.
514-
end)
515-
516-
player:setLocalVar('Received_Eject_Warning', 1)
517-
player:timer(30000, function(playerArgTwo)
518-
playerArgTwo:setCharVar(string.format('[DYNA]EjectPlayer_%s', zoneId), -1) -- Reset player's eject timer.
519-
playerArgTwo:disengage() -- Force disengage.
520-
playerArgTwo:timer(2000, function(playerArgThree)
521-
playerArgThree:startCutscene(100) -- Wait 2 seconds then play exit CS.
522-
end)
523-
end)
524-
else
525-
player:timer(2000, function(playerArgFour)
526-
playerArgFour:messageSpecial(xi.dynamis.getZoneMessageID('NO_LONGER_HAVE_CLEARANCE', zoneId), 0, 0)
527-
playerArgFour:setCharVar(string.format('[DYNA]EjectPlayer_%s', zoneId), -1) -- Reset player's eject timer.
528-
playerArgFour:disengage() -- Force disengage.
529-
playerArgFour:timer(4000, function(playerArgFive)
530-
playerArgFive:startCutscene(100) -- Wait 2 seconds then play exit CS.
531-
end)
532-
end) -- Wait 1 second, send no clearance message.
533-
end
534-
end
535-
end
536-
end
537-
538-
xi.dynamis.ejectAllPlayers = function(zone)
539-
print('Ejecting all players from Dynamis zone: ' .. tostring(zone:getID()))
540-
local playersInZone = zone:getPlayers()
541-
for _, player in pairs(playersInZone) do
542-
xi.dynamis.ejectPlayer(player) -- Runs the ejectPlayer function per player.
543-
end
544-
end
545-
546503
-- Reset all player-related dynamis charvars
547504
-- GM Command Only
548505
xi.dynamis.resetPlayerVars = function(playerEntity, dynaZone)
@@ -566,42 +523,6 @@ xi.dynamis.sjQMOnTrigger = function(npc)
566523
zone:setLocalVar('SJUnlocked', 1)
567524
end
568525

569-
-----------------------------------
570-
-- Dynamis Player/Zone Functions --
571-
-----------------------------------
572-
xi.dynamis.zoneOnZoneInEra = function(player, prevZone)
573-
local zoneId = player:getZoneID()
574-
local zoneExpiration = GetServerVariable(string.format('[DYNA]ExpirationTime_%s', zoneId))
575-
local info = xi.dynamis.dynaInfoEra[zoneId]
576-
local ID = zones[zoneId]
577-
578-
xi.dynamis.debugPrint(string.format('------------xi.dynamis.zoneOnZoneInEra------------'))
579-
-- usually happens when zoning in with !zone command
580-
-- If player is in void, move player to entry.
581-
if
582-
player:getXPos() == 0 and
583-
player:getYPos() == 0 and
584-
player:getZPos() == 0
585-
then
586-
player:setPos(unpack(info.entryPos))
587-
end
588-
589-
local expirationTime = xi.dynamis.getDynaTimeRemaining(zoneExpiration)
590-
xi.dynamis.debugPrint(string.format('expirationTime calculation: %s | zoneExpiration: %s | currentTime: %s', tostring(expirationTime), tostring(zoneExpiration), tostring(GetSystemTime())))
591-
-- Send message letting player know how long they have.
592-
player:timer(5000, function(playerArg)
593-
playerArg:messageSpecial(ID.text.DYNAMIS_TIME_UPDATE_2, math.floor(utils.clamp(expirationTime, 0, expirationTime) / 60), 1)
594-
end)
595-
596-
-- Update hourglass if player has one - will only update endTime if it was extended (zoneExpiration > current endTime)
597-
xi.dynamis.debugPrint(string.format('Updating hourglass for player'))
598-
xi.dynamis.updatePlayerHourglass(player)
599-
600-
-- Check for dreamland SJ restriction and apply if necessary
601-
xi.dynamis.applyEntryRestrictions(player, zoneId)
602-
return -1
603-
end
604-
605526
-----------------------------------
606527
-- Dynamis Zone Validation --
607528
-----------------------------------
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
2+
-----------------------------------
3+
-- Dynamis Eject Functions
4+
-----------------------------------
5+
local ejectWarningTimer = 2000
6+
7+
-- Send eject warning message with delay
8+
xi.dynamis.sendEjectWarning = function(player, zoneId, delayMs, isForceEject)
9+
player:timer(delayMs, function(playerArg)
10+
local param = (isForceEject) and 0 or 30
11+
playerArg:messageSpecial(xi.dynamis.getZoneMessageID('NO_LONGER_HAVE_CLEARANCE', zoneId), 0, param)
12+
end)
13+
end
14+
15+
-- Eject actions (charvar reset, disengage, cutscene)
16+
xi.dynamis.performEjectActions = function(player, zoneId, cutsceneDelayMs)
17+
player:setCharVar(string.format('[DYNA]EjectPlayer_%s', zoneId), -1)
18+
player:disengage()
19+
player:timer(cutsceneDelayMs, function(playerArg)
20+
playerArg:startCutscene(100)
21+
end)
22+
end
23+
24+
-- Execute non-force eject with grace period
25+
xi.dynamis.executeGracePeriodEject = function(player, zoneId)
26+
local ejectGracePeriodMs = 30000 -- 30 seconds
27+
xi.dynamis.sendEjectWarning(player, zoneId, ejectWarningTimer, false)
28+
player:setLocalVar('Received_Eject_Warning', 1)
29+
player:timer(ejectGracePeriodMs, function(playerArgTwo)
30+
xi.dynamis.performEjectActions(playerArgTwo, zoneId, ejectWarningTimer)
31+
end)
32+
end
33+
34+
-- Eject a player from Dynamis with optional force eject
35+
xi.dynamis.ejectPlayer = function(player, forceEject)
36+
xi.dynamis.debugPrint('Ejecting player: ' .. tostring(player:getName()) .. ' | forceEject: ' .. tostring(forceEject))
37+
local zoneId = player:getZoneID()
38+
if forceEject == nil then
39+
forceEject = false
40+
end
41+
42+
if player:getCurrentRegion() ~= xi.region.DYNAMIS then
43+
return
44+
end
45+
46+
if player:getLocalVar('Received_Eject_Warning') == 1 then
47+
return
48+
end
49+
50+
if forceEject then
51+
xi.dynamis.sendEjectWarning(player, zoneId, ejectWarningTimer, true)
52+
player:timer(ejectWarningTimer, function(playerArg)
53+
xi.dynamis.performEjectActions(playerArg, zoneId, 4000) -- 4 Second delay for force eject
54+
end)
55+
else
56+
xi.dynamis.executeGracePeriodEject(player, zoneId)
57+
end
58+
end
59+
60+
xi.dynamis.ejectAllPlayers = function(zone)
61+
print('Ejecting all players from Dynamis zone: ' .. tostring(zone:getID()))
62+
local playersInZone = zone:getPlayers()
63+
for _, player in pairs(playersInZone) do
64+
xi.dynamis.ejectPlayer(player) -- Runs the ejectPlayer function per player.
65+
end
66+
end

scripts/globals/dynamis/npc_handlers.lua

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
-----------------------------------
44
-- Standard NPC interaction functions for dynamis entry zones
55
-- These are called from zone NPC scripts
6-
76
xi = xi or {}
87
xi.dynamis = xi.dynamis or {}
98

@@ -172,8 +171,25 @@ xi.dynamis.entryNpcOnTrade = function(player, npc, trade)
172171
end
173172
end
174173

174+
local function tavWinCutscene(player)
175+
-- Tavnazia Win CS are unique depending on how far you are in the story
176+
if player:hasCompletedQuest(xi.quest.log_id.JEUNO, xi.quest.id.jeuno.APOCALYPSE_NIGH) then
177+
return 3 -- AN (includes ZM and CoP)
178+
end
179+
180+
local zmComplete = player:getCurrentMission(xi.mission.log_id.ZILART) >= xi.mission.id.zilart.AWAKENING
181+
local copComplete = player:getCurrentMission(xi.mission.log_id.COP) >= xi.mission.id.cop.DAWN
182+
183+
if zmComplete and copComplete then
184+
return 2 -- ZM and CoP
185+
elseif zmComplete then
186+
return 1 -- ZM only
187+
end
188+
189+
return 0 -- Nothing complete
190+
end
191+
175192
-- This function is on every NPC that handles Dynamis entry.
176-
-- Cleanup Done
177193
xi.dynamis.entryNpcOnTriggerEra = function(player, npc)
178194
local zoneId = player:getZoneID()
179195
local entryInfo = xi.dynamis.entryInfoEra[zoneId]
@@ -213,7 +229,7 @@ xi.dynamis.entryNpcOnTriggerEra = function(player, npc)
213229
player:getCharVar(entryInfo.hasSeenWinCSVar) == 0
214230
then
215231
if zoneId == xi.zone.DYNAMIS_TAVNAZIA then
216-
-- player:startEvent(entryInfo.csWin, 0, getDynamisTavWinParam(player))
232+
player:startEvent(entryInfo.csWin, 0, tavWinCutscene(player))
217233
else
218234
player:startEvent(entryInfo.csWin)
219235
end
@@ -229,7 +245,6 @@ xi.dynamis.entryNpcOnTriggerEra = function(player, npc)
229245
player:messageSpecial(defaultMsg) -- default message for everything else
230246
end
231247

232-
-- Cleanup Done
233248
xi.dynamis.entryNpcOnEventUpdate = function(player, csid, option, npc)
234249
local zoneId = player:getZoneID()
235250
local entryInfo = xi.dynamis.entryInfoEra[zoneId]
@@ -288,7 +303,6 @@ xi.dynamis.entryNpcOnEventUpdate = function(player, csid, option, npc)
288303
player:messageSpecial(xi.dynamis.getZoneMessageID('UNABLE_TO_CONNECT', zoneId))
289304
end
290305

291-
-- Cleanup Done
292306
xi.dynamis.entryNpcOnEventFinishEra = function(player, csid, option)
293307
local zoneId = player:getZoneID()
294308
local entryInfo = xi.dynamis.entryInfoEra[zoneId]

0 commit comments

Comments
 (0)