require( "common" ) MobData = { PhaseStartHP = 850, PhaseStartStep = 1, BonusTime = 600, ExplodeDelay = 30, ExplodeNextWaitMin = 5, ExplodeNextWaitMax = 30, BurnDuration = 30, BurnNextWaitMin = 5, BurnNextWaitMax = 30, PhaseData = { [1] = { Duration = 135, -- 135, NextStep = 2, StepFunc = "Trin_PNeutral", OnStartAb = nil, OnStartAbStr = 0, OnStartAbDuration = 0, OnEndStepFunc = nil, PhaseAddCap = 45, DefenseFactor = 1, DamageFactor = 1, SpawnList = { }, }, [2] = { Duration = 135, -- 135, NextStep = 3, StepFunc = "Trin_POffense", OnStartAb = nil, OnStartAbStr = 0, OnStartAbDuration = 0, OnEndStepFunc = "Trin_POffenseExpire", PhaseAddCap = 45, DefenseFactor = 0.75, DamageFactor = 1.25, SpawnList = { [1] = { MobInx = "B_Trinity01", OnSelf = false, OnRandom = false, X = 1383, Y = 1595, D = 0, OnEntrace = "SlaveA_Entrance", }, [2] = { MobInx = "B_Trinity02", OnSelf = false, OnRandom = false, X = 1852, Y = 1453, D = 0, OnEntrace = "SlaveB_Entrance", }, }, }, [3] = { Duration = 135, -- 135, NextStep = 4, StepFunc = "Trin_PNeutral", OnStartAb = nil, OnStartAbStr = 0, OnStartAbDuration = 0, OnEndStepFunc = nil, PhaseAddCap = 45, DefenseFactor = 1, DamageFactor = 1, SpawnList = { }, }, [4] = { Duration = 135, -- 135, NextStep = 5, StepFunc = "Trin_PDefense", OnStartAb = "StaMobImmortal", OnStartAbStr = 1, OnStartAbDuration = 4000000, OnEndStepFunc = "Trin_PDefenseExpire", PhaseAddCap = 45, DefenseFactor = 1.25, DamageFactor = 0.75, SpawnList = { [1] = { MobInx = "B_Trinity03", OnSelf = false, OnRandom = true, X = 0, Y = 0, D = 0, OnEntrace = nil, }, [2] = { MobInx = "B_Trinity03", OnSelf = false, OnRandom = true, X = 0, Y = 0, D = 0, OnEntrace = nil, }, [3] = { MobInx = "B_Trinity03", OnSelf = false, OnRandom = true, X = 0, Y = 0, D = 0, OnEntrace = nil, }, [4] = { MobInx = "B_Trinity03", OnSelf = false, OnRandom = true, X = 0, Y = 0, D = 0, OnEntrace = nil, }, [5] = { MobInx = "B_Trinity03", OnSelf = false, OnRandom = true, X = 0, Y = 0, D = 0, OnEntrace = nil, }, }, }, [5] = { Duration = 135, -- 135, NextStep = 6, StepFunc = "Trin_POffense", OnStartAb = nil, OnStartAbStr = 0, OnStartAbDuration = 0, OnEndStepFunc = "Trin_POffenseExpire", PhaseAddCap = 45, DefenseFactor = 0.75, DamageFactor = 1.25, SpawnList = { [1] = { MobInx = "B_Trinity01", OnSelf = false, OnRandom = false, X = 1383, Y = 1595, D = 0, OnEntrace = "SlaveA_Entrance", }, [2] = { MobInx = "B_Trinity02", OnSelf = false, OnRandom = false, X = 1852, Y = 1453, D = 0, OnEntrace = "SlaveB_Entrance", }, }, }, [6] = { Duration = 5, NextStep = 1, StepFunc = "Trin_PUltimate", OnStartAb = "StaMobImmortal", OnStartAbStr = 0, OnStartAbDuration = 4000000, OnEndStepFunc = "Trin_PUltimateExpire", PhaseAddCap = 0, DefenseFactor = 1, DamageFactor = 1, SpawnList = { }, }, }, } TrinData = { HP = 8377200, MaxHP = 8377200, HPRegen = 837720, AC = 4816, MR = 5274, TH = 1531, TB = 1020, MinWC = 254100, MaxWC = 381150, RunSpeed = 300, MobExp = 234567890, ItemDropIndex = "B_Trinity00", AggroRange = 1000000, } SlaveData = { AC = 9999999, MR = 9999999, } TrinReward = { Position = { X = 1593, Y = 1594, Radius = 500 }, BoxData = { { Index = "Box_Trinity", ItemDropMobIndex = "BH_Humar_X" }, { Index = "Box_Trinity", ItemDropMobIndex = "BH_Humar_X" }, { Index = "Box_Trinity", ItemDropMobIndex = "BH_Humar_X" }, { Index = "Box_Trinity", ItemDropMobIndex = "BH_Humar_X" }, { Index = "Box_Trinity", ItemDropMobIndex = "BH_Humar_X" }, { Index = "Box_Trinity", ItemDropMobIndex = "BH_Humar_X" }, { Index = "Box_Trinity", ItemDropMobIndex = "Box_Trinity" }, { Index = "Box_Trinity", ItemDropMobIndex = "BH_Humar_X" }, { Index = "Box_Trinity", ItemDropMobIndex = "BH_Humar_X" }, { Index = "Box_Trinity", ItemDropMobIndex = "BH_Humar_X" }, { Index = "Box_Trinity", ItemDropMobIndex = "BH_Humar_X" }, { Index = "Box_Trinity", ItemDropMobIndex = "BH_Humar_X" }, } } --------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------- --------> B_Trinity00.lua <-------- --------> 1.0 - 27-08-2015 <-------- --------> * Initial base for HP check and phase changing <-------- --------> * Initial data for phase and mobs <-------- --------> 1.1 - 29-08-2015 <-------- --------> * Added damage per phase and timer for bonus chests <-------- --------> 1.2 - 31-08-2015 <-------- --------> * Cleaned code and other changes/fixes <-------- --------> <-------- --------> Copyright @ Warren Dawes / Daniel Lyew <-------- --------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------- MemBlock = {} function PlayerChat( MapIndex, Handle, Chat ) cExecCheck("PlayerChat") local PlayerName = cGetPlayerName( Handle ) cAssertLog( PlayerName .. ":" .. Chat ) end function Main( MapIndex ) cExecCheck("Main") return ReturnAI.CPP end function PlayerLogout( Field, PlayerHandle ) cExecCheck("PlayerLogout") if Field ~= nil then cTimerEnd( PlayerHandle, 0 ) end end function PlayerMapLogin( MapIndex, Handle ) cExecCheck("PlayerMapLogin") local Var = MemBlock[MapIndex] if Var == nil then cAssertLog( MapIndex .. "-> MemBlock[MapIndex] is nil on PlayerMapLogin" ) return end if Handle == nil then cAssertLog( MapIndex .. "-> Handle is nil on PlayerMapLogin" ) return end if cIsObjectDead( Handle ) ~= nil then cAssertLog( MapIndex .. "-> Handle is dead on PlayerMapLogin" ) return end if Var.Timer.Active then local CurrentSecond = cCurSec() if Var.Timer.BonusTime >= CurrentSecond then local RemainTime = Var.Timer.BonusTime - CurrentSecond cTimer_Obj( Handle, RemainTime ) else Var.Timer.Active = false Var.Timer.Start = 0 Var.Timer.BonusTime = MobData.BonusTime end end end --------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------- --> Main method called from zone function B_Trinity00( Handle, MapIndex ) cExecCheck("B_Trinity00") if cIsObjectDead( Handle ) ~= nil then return ReturnAI.CPP end local Var = MemBlock[Handle] --> First call to this script if Var == nil then --> If not in proper map if MapIndex ~= "B_Trini" then return ReturnAI.CPP end --> Initiate all vars MemBlock[Handle] = {} Var = MemBlock[Handle] Var.Handle = Handle Var.MapIndex = MapIndex Var.Timer = {} Var.Timer.Active = false Var.Timer.Start = 0 Var.Timer.BonusTime = MobData.BonusTime Var.Debug = {} Var.Debug.Wait = cCurSec() + 1 Var.Debug.SM = false --> DPSData Var.DPS = {} Var.DPS.Wait = cCurSec() + 1 Var.DPS.LastHP = nil Var.DPS.PhaseAdd = 0 Var.DPS.DamageList = {} -- Checking Players Var.PlyCountCheck = {} Var.PlyCountCheck.Wait = cCurSec() + 1 --> PhaseData Var.PhaseOn = false Var.PhaseStep = MobData.PhaseStartStep Var.PhaseStepFunc = MobData.PhaseData[Var.PhaseStep].StepFunc Var.PhaseExpire = cCurSec() + MobData.PhaseData[Var.PhaseStep].Duration Var.PhaseData = {} Var.PhaseData.Adds = false Var.PhaseData.AddsList = {} Var.PhaseData.AddsTick = cCurSec() Var.PhaseData.RegenAni = false Var.PhaseData.NextRegenTick = cCurSec() Var.PhaseData.Teleported = false Var.PhaseData.TeleportedHeal = false Var.PhaseData.PrtedToPlayer = false Var.PhaseData.PrtedToPlayerHeal = false Var.PhaseData.RecoverHP = true Var.PhaseData.SkillDelay = 0 Var.PhaseData.ExplodeSet = false Var.PhaseData.ExplodeExpire = {} Var.PhaseData.ExplodeDamage = 100 -- Percent of HP Var.PhaseData.ExplodeHandle = nil Var.PhaseData.BurnExpire = cCurSec() Var.PhaseData.BurnSet = cCurSec() + math.random(MobData.BurnNextWaitMin, MobData.BurnNextWaitMax) Var.PhaseData.BurnTick = cCurSec() Var.PhaseData.BurnMin = 500 Var.PhaseData.BurnMax = 1000 --> TrinityData Var.TrinData = {} Var.TrinData.AC = TrinData.AC Var.TrinData.MR = TrinData.MR -- Var.TrinData.MinWC = TrinData.MinWC -- Var.TrinData.MaxWC = TrinData.MaxWC -- Var.TrinData.MinMA = TrinData.MinMA -- Var.TrinData.MaxMA = TrinData.MaxMA Var.TrinData.TH = TrinData.TH Var.TrinData.TB = TrinData.TB --> Set stats cSetNPCParam( Var.Handle, "MaxHP", TrinData.MaxHP ) cSetNPCParam( Var.Handle, "HP", TrinData.HP ) cSetNPCParam( Var.Handle, "HPRegen", TrinData.HPRegen ) cSetNPCParam( Var.Handle, "AC", TrinData.AC ) cSetNPCParam( Var.Handle, "MR", TrinData.MR ) -- cSetNPCParam( Var.Handle, "MinWC", TrinData.MinWC ) -- cSetNPCParam( Var.Handle, "MaxWC", TrinData.MaxWC ) -- cSetNPCParam( Var.Handle, "MinMA", TrinData.MinMA ) -- cSetNPCParam( Var.Handle, "MaxMA", TrinData.MaxMA ) cSetNPCParam( Var.Handle, "RunSpeed", TrinData.RunSpeed ) cSetNPCParam( Var.Handle, "MobExp", TrinData.MobExp ) cSetItemDropMobID( Var.Handle, TrinData.ItemDropIndex ) -- Var.TrinData.STR = TrinData.STR -- Var.TrinData.END = TrinData.END -- Var.TrinData.DEX = TrinData.DEX -- Var.TrinData.INT = TrinData.INT -- Var.TrinData.SPR = TrinData.SPR cAIScriptFunc( Var.Handle, "ObjectDied", "Trin_Dead" ) cAIScriptFunc( Var.Handle, "MobDamaged", "Trin_Damaged" ) Var.StepFunc = "Trin_HPCheck" end --> Set field script funcs --local FieldVar = MemBlock[MapIndex] -- --if FieldVar == nil then -- MemBlock[MapIndex] = {} -- FieldVar = MemBlock[MapIndex] -- FieldVar.MapIndex = MapIndex -- FieldVar.Timer = {} -- FieldVar.Timer.Active = false -- FieldVar.Timer.Start = 0 -- FieldVar.Timer.BonusTime = MobData.BonusTime -- -- cSetFieldScript ( FieldVar.MapIndex, "AIScript/B_Trinity00" ) -- cFieldScriptFunc( FieldVar.MapIndex, "MapLogin", "PlayerMapLogin" ) -- cFieldScriptFunc( FieldVar.MapIndex, "MapLogout","PlayerLogout" ) --end return _G[Var.StepFunc]( Var ) end function Trin_HPCheck( Var ) cExecCheck("Trin_HPCheck") local hp, maxhp = cObjectHP( Var.Handle ) --> If dead - exit loop if hp == nil then return ReturnAI.CPP end --> Alive timer --if Var.Timer.Active then -- local TimerSecond = cCurSec() -- if Var.Timer.NextTick <= TimerSecond then -- -- if Var.Timer.BonusTime > 0 then -- Var.Timer.BonusTime = Var.Timer.BonusTime - (TimerSecond - Var.Timer.NextTick) -- -- Trin_TimerSet( Var, Var.Timer.BonusTime ) -- -- Var.Timer.NextTick = TimerSecond + Var.Timer.Tick -- else -- Var.Timer.BonusTime = 0 -- -- cVanishTimer( Var.MapIndex ) -- -- Var.Timer.Active = false -- end -- end --end local hppercent = ((hp / maxhp) * 1000) --> DPS Check if Var.DPS.LastHP == nil then Var.DPS.LastHP = hp end if Var.DPS.Wait <= cCurSec() then if Var.DPS.LastHP >= hp then local dps_rate = (((Var.DPS.LastHP - hp) / maxhp) * 1000) local dps_add = ((dps_rate / 1000) * MobData.PhaseData[Var.PhaseStep].Duration) --> If the add for the current phase < cap if Var.DPS.PhaseAdd < MobData.PhaseData[Var.PhaseStep].PhaseAddCap then local dps_old_add = Var.DPS.PhaseAdd Var.DPS.PhaseAdd = Var.DPS.PhaseAdd + dps_add --> If dps add >= cap - we reset phaseadd to equal cap and revert add to be remainder until cap if Var.DPS.PhaseAdd >= MobData.PhaseData[Var.PhaseStep].PhaseAddCap then dps_add = MobData.PhaseData[Var.PhaseStep].PhaseAddCap - dps_old_add Var.DPS.PhaseAdd = MobData.PhaseData[Var.PhaseStep].PhaseAddCap end Var.PhaseExpire = Var.PhaseExpire + dps_add end end Var.DPS.Wait = cCurSec() + 1 Var.DPS.LastHP = hp end -- if Var.PlyCountCheck.Wait <= cCurSec() then -- -- if cObjectCount( Var.MapIndex, ObjectType.Player ) <= 0 then -- Trin_PhaseReset( Var ) -- end -- -- Var.PlyCountCheck.Wait = cCurSec() + 1 -- end --> Phase Check if hppercent > MobData.PhaseStartHP then if Var.PhaseOn then Trin_PhaseReset( Var ) end elseif hppercent <= MobData.PhaseStartHP then if not Var.PhaseOn or Var.PhaseExpire <= cCurSec() then Trin_PhaseStep( Var ) end end --> Call phase method return _G[Var.PhaseStepFunc]( Var ) end --. Trin add manage function Trin_OffenseAddManage( Var ) cExecCheck("Trin_OffenseAddManage") --> Get handle of alt slaves local HandleAdd1 = cGetNPCHandle( Var.MapIndex, MobData.PhaseData[Var.PhaseStep].SpawnList[1].MobInx ) local HandleAdd2 = cGetNPCHandle( Var.MapIndex, MobData.PhaseData[Var.PhaseStep].SpawnList[2].MobInx ) cExecCheck("Trin_OffenseAddManage:408") --> Manage first slave if HandleAdd1 ~= nil and HandleAdd2 ~= nil then --> Get distance between local DistanceBetween = cDistanceSquar( HandleAdd1, HandleAdd2 ) local CurrentSecond = cCurSec() cExecCheck("Trin_OffenseAddManage:417") if cIsObjectDead( HandleAdd1 ) == nil and cIsObjectDead( HandleAdd2 ) == nil then if Var.PhaseData.AddsTick <= CurrentSecond then if DistanceBetween <= 1000000 then local PlayerList = { cGetPlayerList( Var.MapIndex ) } for i=1, #PlayerList do if cIsObjectDead( PlayerList[i] ) == nil then local RandomDamage = math.random(500, 1000) Trin_DamagePlayer( PlayerList[i], RandomDamage, Var.Handle ) end end cExecCheck("Trin_OffenseAddManage:434") --> Remove far abstate if applied to handle1 if cAbstateRestTime( HandleAdd1, "StaKQWaterArrow_Blue" ) ~= nil then cResetAbstate( HandleAdd1, "StaKQWaterArrow_Blue" ) end --> Apply close abstate if not applied to handle1 if cAbstateRestTime( HandleAdd1, "StaKQWaterArrow_Red" ) == nil then cSetAbstate( HandleAdd1, "StaKQWaterArrow_Red", 1, 400000000 ) end --> Remove far abstate if applied to handle2 if cAbstateRestTime( HandleAdd2, "StaKQWaterArrow_Blue" ) ~= nil then cResetAbstate( HandleAdd2, "StaKQWaterArrow_Blue" ) end --> Apply close abstate if not applied to handle2 if cAbstateRestTime( HandleAdd2, "StaKQWaterArrow_Red" ) == nil then cSetAbstate( HandleAdd2, "StaKQWaterArrow_Red", 1, 400000000 ) end else --> Remove close abstate if applied to handle1 if cAbstateRestTime( HandleAdd1, "StaKQWaterArrow_Red" ) ~= nil then cResetAbstate( HandleAdd1, "StaKQWaterArrow_Red" ) end --> Apply far abstate if not applied if cAbstateRestTime( HandleAdd1, "StaKQWaterArrow_Blue" ) == nil then cSetAbstate( HandleAdd1, "StaKQWaterArrow_Blue", 1, 400000000 ) end --> Remove close abstate if applied to handle1 if cAbstateRestTime( HandleAdd2, "StaKQWaterArrow_Red" ) ~= nil then cResetAbstate( HandleAdd2, "StaKQWaterArrow_Red" ) end --> Apply far abstate if not applied if cAbstateRestTime( HandleAdd2, "StaKQWaterArrow_Blue" ) == nil then cSetAbstate( HandleAdd2, "StaKQWaterArrow_Blue", 1, 400000000 ) end end Var.PhaseData.AddsTick = CurrentSecond + 1 end else cExecCheck("Trin_OffenseAddManage:482") cResetAbstate( HandleAdd1, "StaKQWaterArrow_Red" ) cResetAbstate( HandleAdd1, "StaKQWaterArrow_Blue" ) cResetAbstate( HandleAdd2, "StaKQWaterArrow_Red" ) cResetAbstate( HandleAdd2, "StaKQWaterArrow_Blue" ) end end end --> SlaveA Entrance function SlaveA_Entrance( Handle, MapIndex ) cExecCheck("SlaveA_Entrance") local Var = MemBlock[Handle] cSetNPCParam( Handle, "AC", SlaveData.AC ) --> First call to this script if Var == nil then cAIScriptSet( Handle ) return ReturnAI.CPP end return ReturnAI.CPP end --> SlaveB Entrance function SlaveB_Entrance( Handle, MapIndex ) cExecCheck("SlaveB_Entrance") local Var = MemBlock[Handle] cSetNPCParam( Handle, "MR", SlaveData.MR ) --> First call to this script if Var == nil then cAIScriptSet( Handle ) return ReturnAI.CPP end return ReturnAI.CPP end --> Trin damaged function Trin_Damaged( MapIndex, AttackerHandle, MaxHP, CurHP, DefenderHandle ) cExecCheck("Trin_Damaged") if DefenderHandle == nil then return end if MapIndex == nil then return end if MaxHP == nil or CurHP == nil then return end local Var = MemBlock[DefenderHandle] if Var == nil then return end if not Var.Timer.Active then local CurrentSecond = cCurSec() Var.Timer.Active = true Var.Timer.Start = CurrentSecond Var.Timer.BonusTime = Var.Timer.BonusTime + CurrentSecond --local FieldVar = MemBlock[MapIndex] -- --if FieldVar ~= nil then -- FieldVar.Timer = Var.Timer --end -- --local PlayerList = { cGetPlayerList( Var.MapIndex ) } -- --if Var.Timer.BonusTime >= CurrentSecond then -- -- local RemainTime = Var.Timer.BonusTime - CurrentSecond -- -- for i=1, #PlayerList do -- cTimer_Obj( PlayerList[i], RemainTime ) -- end --end end if AttackerHandle == nil then return end end --> Trin dead function Trin_Dead( MapIndex, KillerHandle, DeadHandle ) cExecCheck("Trin_Dead") --> Check if mapindex is not nil if MapIndex == nil then cAIScriptSet( DeadHandle ) return end --> Check if deadhandle is not nil if DeadHandle == nil then cAIScriptSet( DeadHandle ) return end local Var = MemBlock[DeadHandle] --> Check if var is not nil if Var == nil then cAIScriptSet( DeadHandle ) return end --> Remove current adds for k, v in pairs(Var.PhaseData.AddsList) do cNPCVanish( Var.PhaseData.AddsList[k] ) end --> Spawn chests if bonustime > 0 if Var.Timer.BonusTime >= cCurSec() then Trin_ChestSpawn( Var ) end --> Clear timers cVanishTimer( Var.MapIndex ) --local FieldVar = MemBlock[Var.MapIndex] -- --if FieldVar ~= nil then -- FieldVar.Timer.Active = false -- FieldVar.Timer.Start = 0 -- FieldVar.Timer.BonusTime = MobData.BonusTime --end --> Reset AIScript for handle cAIScriptSet( DeadHandle ) MemBlock[DeadHandle] = nil return ReturnAI.CPP end --> Step phase function Trin_PhaseStep( Var ) cExecCheck("Trin_PhaseStep") --> Phase expire method if MobData.PhaseData[Var.PhaseStep].OnEndStepFunc ~= nil then _G[MobData.PhaseData[Var.PhaseStep].OnEndStepFunc]( Var ) end --cNoticeString( Var.MapIndex, "FromStep = " .. Var.PhaseStep .. ", FromStepFunc = " .. Var.PhaseStepFunc ) --> DPS step Var.DPS.PhaseAdd = 0 --> Phase step Var.PhaseOn = true Var.PhaseStep = MobData.PhaseData[Var.PhaseStep].NextStep; Var.PhaseStepFunc = MobData.PhaseData[Var.PhaseStep].StepFunc Var.PhaseExpire = cCurSec() + MobData.PhaseData[Var.PhaseStep].Duration Var.PhaseData.Adds = false Var.PhaseData.PrtedToPlayer = false Var.PhaseData.PrtedToPlayerHeal = false Var.PhaseData.ExplodeSet = false Var.PhaseData.ExplodeExpire = { } Var.PhaseData.ExplodeHandle = nil if MobData.PhaseData[Var.PhaseStep].OnStartAb ~= nil then cSetAbstate(Var.Handle, MobData.PhaseData[Var.PhaseStep].OnStartAb, MobData.PhaseData[Var.PhaseStep].OnStartAbStr, MobData.PhaseData[Var.PhaseStep].OnStartAbDuration) end --> Phase adds if not Var.PhaseData.Adds then Var.PhaseData.Adds = true --> Spawn adds for current phase local SpawnList = MobData.PhaseData[Var.PhaseStep].SpawnList --> Iterate through each add to spawn and add to adds list for i=1, #SpawnList do local AddHandle if SpawnList[i].OnSelf then AddHandle = cMobRegen_Obj( SpawnList[i].MobInx, Var.Handle ) table.insert( Var.PhaseData.AddsList, AddHandle ) elseif SpawnList[i].OnRandom then local PlayerList = { cGetPlayerList( Var.MapIndex ) } local RandomNum = math.random(1, #PlayerList) AddHandle = cMobRegen_Obj( SpawnList[i].MobInx, PlayerList[RandomNum] ) table.insert( Var.PhaseData.AddsList, AddHandle ) else AddHandle = cMobRegen_XY( Var.MapIndex, SpawnList[i].MobInx, SpawnList[i].X, SpawnList[i].Y, SpawnList[i].D ) table.insert( Var.PhaseData.AddsList, AddHandle ) end if SpawnList[i].OnEntrace ~= nil then if cAIScriptSet( AddHandle, Var.Handle ) == nil then cAssertLog( "ERROR->cSetAIScript() FAILED FOR TRINITY SLAVE" ) end if cAIScriptFunc( AddHandle, "Entrance", SpawnList[i].OnEntrace ) == nil then cAssertLog( "ERROR->cAIScriptFunc() FAILED FOR TRINITY SLAVE" ) end end end end --cNoticeString( Var.MapIndex, "ToStep = " .. Var.PhaseStep .. ", ToStepFunc = " .. Var.PhaseStepFunc ) end --> Reset state of phase and other params function Trin_PhaseReset( Var ) cExecCheck("Trin_PhaseReset") --> Phase expire method if MobData.PhaseData[Var.PhaseStep].OnEndStepFunc ~= nil then _G[MobData.PhaseData[Var.PhaseStep].OnEndStepFunc]( Var ) end --> Timer reset Var.Timer.Active = false Var.Timer.Start = 0 Var.Timer.BonusTime = MobData.BonusTime --> DPS reset Var.DPS.PhaseAdd = 0 Var.DPS.LastHP = nil --> Phase reset Var.PhaseOn = false Var.PhaseStep = MobData.PhaseStartStep Var.PhaseStepFunc = MobData.PhaseData[Var.PhaseStep].StepFunc Var.PhaseExpire = cCurSec() + MobData.PhaseData[Var.PhaseStep].Duration Var.PhaseData.Adds = false --> Reset 100% damage if Var.PhaseData.ExplodeExpire[Var.Handle] ~= nil then local ExplodeTarget = Var.PhaseData.ExplodeExpire[Var.Handle].Target if cIsObjectDead( ExplodeTarget ) == nil then cResetAbstate( ExplodeTarget, "StaCount30" ) end end Var.PhaseData.ExplodeSet = false Var.PhaseData.ExplodeExpire = { } Var.PhaseData.ExplodeHandle = nil Var.PhaseData.RegenAni = false cRunTo( Var.Handle, 1593, 1594, 1000 ) for k, v in pairs(Var.PhaseData.AddsList) do cNPCVanish( Var.PhaseData.AddsList[k] ) end Var.PhaseData.AddsList = {} --> Reset DPS List for k, v in pairs(Var.DPS.DamageList) do if cIsObjectDead( Var.DPS.DamageList[k] ) == nil then cAggroReset( Var.Handle, Var.DPS.DamageList[k] ) end end Var.DPS.DamageList = {} if MobData.PhaseData[Var.PhaseStep].OnStartAb ~= nil then cSetAbstate(Var.Handle, MobData.PhaseData[Var.PhaseStep].OnStartAb, MobData.PhaseData[Var.PhaseStep].OnStartAbStr, MobData.PhaseData[Var.PhaseStep].OnStartAbDuration) end end --> Player list check function Trin_PlayerCheck( Var ) cExecCheck("Trin_PlayerCheck") local RaidLevel = 1 local AggroSize = cAggroListSize( Var.Handle ) if AggroSize ~= nil then RaidLevel = RaidLevel + AggroSize end local NewAC = RaidLevel * TrinData.AC cSetNPCParam( Var.Handle, "AC", NewAC ) Var.TrinData.AC = NewAC local NewMR = RaidLevel * TrinData.MR cSetNPCParam( Var.Handle, "MR", NewMR ) Var.TrinData.MR = NewMR -- local NewMinWC = RaidLevel * TrinData.MinWC -- cSetNPCParam( Var.Handle, "MinWC", NewMinWC ) -- Var.TrinData.MinWC = NewMinWC -- local NewMaxWC = RaidLevel * TrinData.MaxWC -- cSetNPCParam( Var.Handle, "MaxWC", NewMaxWC ) -- Var.TrinData.MaxWC = NewMaxWC -- local NewMinMA = RaidLevel * TrinData.MinMA -- cSetNPCParam( Var.Handle, "MinMA", NewMinMA ) -- Var.TrinData.MinMA = NewMinMA -- local NewMaxMA = RaidLevel * TrinData.MaxMA -- cSetNPCParam( Var.Handle, "MaxMA", NewMaxMA ) -- Var.TrinData.MaxMA = NewMaxMA local NewTH = RaidLevel * TrinData.TH cSetNPCParam( Var.Handle, "TH", NewTH ) Var.TrinData.TH = NewTH local NewTB = RaidLevel * TrinData.TB cSetNPCParam( Var.Handle, "TB", NewTB ) Var.TrinData.TB = NewTB -- local NewSTR = RaidLevel * TrinData.STR -- cSetNPCParam( Var.Handle, "STR", NewSTR ) -- Var.TrinData.STR = NewSTR -- local NewEND = RaidLevel * TrinData.END -- cSetNPCParam( Var.Handle, "END", NewEND ) -- Var.TrinData.END = NewEND -- local NewDEX = RaidLevel * TrinData.DEX -- cSetNPCParam( Var.Handle, "DEX", NewDEX ) -- Var.TrinData.DEX = NewDEX -- local NewINT = RaidLevel * TrinData.INT -- cSetNPCParam( Var.Handle, "INT", NewINT ) -- Var.TrinData.INT = NewINT -- local NewSPR = RaidLevel * TrinData.SPR -- cSetNPCParam( Var.Handle, "SPR", NewSPR ) -- Var.TrinData.SPR = NewSPR end --> Neutral state method called when in neutral phase function Trin_PNeutral( Var ) cExecCheck("Trin_PNeutral") Trin_PlayerCheck( Var ) return ReturnAI.CPP end --> Offense state method called when in offense phase function Trin_POffense( Var ) cExecCheck("Trin_POffense") Trin_PlayerCheck( Var ) --> Phase specific stats local NewAC = Var.TrinData.AC * MobData.PhaseData[Var.PhaseStep].DefenseFactor cSetNPCParam( Var.Handle, "AC", NewAC ) Var.TrinData.AC = NewAC local NewMR = Var.TrinData.MR * MobData.PhaseData[Var.PhaseStep].DefenseFactor cSetNPCParam( Var.Handle, "MR", NewMR ) Var.TrinData.MR = NewMR -- local NewMinWC = Var.TrinData.MinWC * MobData.PhaseData[Var.PhaseStep].DamageFactor -- cSetNPCParam( Var.Handle, "MinWC", NewMinWC ) -- Var.TrinData.MinWC = NewMinWC -- local NewMaxWC = Var.TrinData.MaxWC * MobData.PhaseData[Var.PhaseStep].DamageFactor -- cSetNPCParam( Var.Handle, "MaxWC", NewMaxWC ) -- Var.TrinData.MaxWC = NewMaxWC -- local NewMinMA = Var.TrinData.MinMA * MobData.PhaseData[Var.PhaseStep].DamageFactor -- cSetNPCParam( Var.Handle, "MinMA", NewMinMA ) -- Var.TrinData.MinMA = NewMinMA -- local NewMaxMA = Var.TrinData.MaxMA * MobData.PhaseData[Var.PhaseStep].DamageFactor -- cSetNPCParam( Var.Handle, "MaxMA", NewMaxMA ) -- Var.TrinData.MaxMA = NewMaxMA -- local NewSTR = Var.TrinData.STR * MobData.PhaseData[Var.PhaseStep].DamageFactor -- cSetNPCParam( Var.Handle, "STR", NewSTR ) -- Var.TrinData.STR = NewSTR -- local NewEND = Var.TrinData.END * MobData.PhaseData[Var.PhaseStep].DefenseFactor -- cSetNPCParam( Var.Handle, "END", NewEND ) -- Var.TrinData.END = NewEND -- local NewINT = Var.TrinData.INT * MobData.PhaseData[Var.PhaseStep].DamageFactor -- cSetNPCParam( Var.Handle, "INT", NewINT ) -- Var.TrinData.INT = NewINT -- local NewSPR = Var.TrinData.SPR * MobData.PhaseData[Var.PhaseStep].DamageFactor -- cSetNPCParam( Var.Handle, "SPR", NewSPR ) -- Var.TrinData.SPR = NewSPR Trin_OffenseAddManage( Var ) --> Explode set local AggroList = { cAggroList( Var.Handle, 10000000 ) } if AggroList ~= nil and #AggroList > 0 then for i=#AggroList, 1, -1 do if cIsObjectDead( AggroList[i] ) ~= nil then cAggroReset( Handle, AggroList[i] ) table.remove(AggroList, i) end end if #AggroList == 0 then Var.PhaseData.ExplodeExpire[Var.Handle] = nil return ReturnAI.CPP end local ExplodeTarget = cTargetHandle( Var.Handle ) if ExplodeTarget ~= nil then local CurHP, MaxHP = cObjectHP( ExplodeTarget ) if Var.PhaseData.ExplodeExpire[Var.Handle] == nil then --Trin_TimerSet( Var.MapIndex, MobData.ExplodeDelay ) Var.PhaseData.ExplodeExpire[Var.Handle] = { Expire = cCurSec() + MobData.ExplodeDelay, Expired = false, NextWait = cCurSec() + MobData.ExplodeDelay + math.random(MobData.ExplodeNextWaitMin, MobData.ExplodeNextWaitMax), Target = ExplodeTarget, MaxHP = MaxHP } cSetAbstate( ExplodeTarget, "StaCount30", 1, 30000 ) end end if not Var.PhaseData.ExplodeExpire[Var.Handle].Expired and Var.PhaseData.ExplodeExpire[Var.Handle].Expire <= cCurSec() then local RandomTarget = cTargetHandle( Var.Handle ) local ExpireTarget = Var.PhaseData.ExplodeExpire[Var.Handle].Target local ExpireDamage = Var.PhaseData.ExplodeExpire[Var.Handle].MaxHP local DamageList = {} if ExpireTarget ~= nil and cIsObjectDead( ExpireTarget ) == nil then local PlayerList = { cGetPlayerList( Var.MapIndex ) } table.insert( DamageList, ExpireTarget ) for i=1, #PlayerList do if PlayerList[i] ~= nil and cIsObjectDead( PlayerList[i] ) == nil then local TargetX, TargetY = cObjectLocate( PlayerList[i] ) local NearList = { cGetPlayerList( Var.MapIndex ) } for j=1, #NearList do if NearList[j] ~= nil and cIsObjectDead( NearList[j] ) == nil then local DistanceBetween = cDistanceSquar( PlayerList[i], NearList[j] ) if DistanceBetween <= 25000 then table.insert( DamageList, NearList[j] ) end end end end end elseif RandomTarget ~= nil and cIsObjectDead( RandomTarget ) == nil then local PlayerList = { cGetPlayerList( Var.MapIndex ) } table.insert( DamageList, ExpireTarget ) for i=1, #PlayerList do if PlayerList[i] ~= nil and cIsObjectDead( PlayerList[i] ) == nil then local TargetX, TargetY = cObjectLocate( PlayerList[i] ) local NearList = { cGetPlayerList( Var.MapIndex ) } for j=1, #NearList do if NearList[j] ~= nil and cIsObjectDead( NearList[j] ) == nil then local DistanceBetween = cDistanceSquar( PlayerList[i], NearList[j] ) if DistanceBetween <= 25000 then table.insert( DamageList, NearList[j] ) end end end end end end for i=1, #DamageList do Trin_DamagePlayer( DamageList[i], (ExpireDamage / #DamageList), Var.Handle ) end Var.PhaseData.ExplodeExpire[Var.Handle].Expired = true else if Var.PhaseData.ExplodeExpire[Var.Handle].NextWait <= cCurSec() then Var.PhaseData.ExplodeExpire[Var.Handle] = nil end end end return ReturnAI.CPP end function Trin_POffenseExpire( Var ) cExecCheck("Trin_POffenseExpire") local RemainHP = 0 --> Total remaining HP for k, v in pairs(Var.PhaseData.AddsList) do local HP, MaxHP = cObjectHP( Var.PhaseData.AddsList[k] ) if HP ~= nil then RemainHP = RemainHP + HP cNPCVanish( Var.PhaseData.AddsList[k] ) end end Var.PhaseData.AddsList = {} --> Distribute damage if RemainHP > 0 then local PlayerList = { cAggroList( Var.Handle, 10000000 ) } for i=1, #PlayerList do local DamageValue = (RemainHP / #PlayerList) Trin_DamagePlayer( PlayerList[i], DamageValue, Var.Handle ) end end local PlayerList = { cGetPlayerList( Var.MapIndex ) } for i=1, #PlayerList do cResetAbstate( PlayerList[i], "StaCount30" ) end end --> Defense state method called when in defense phase function Trin_PDefense( Var ) cExecCheck("Trin_PDefense") Trin_PlayerCheck( Var ) --> Phase specific stats local NewAC = Var.TrinData.AC * MobData.PhaseData[Var.PhaseStep].DefenseFactor cSetNPCParam( Var.Handle, "AC", NewAC ) Var.TrinData.AC = NewAC local NewMR = Var.TrinData.MR * MobData.PhaseData[Var.PhaseStep].DefenseFactor cSetNPCParam( Var.Handle, "MR", NewMR ) Var.TrinData.MR = NewMR -- local NewMinWC = Var.TrinData.MinWC * MobData.PhaseData[Var.PhaseStep].DamageFactor -- cSetNPCParam( Var.Handle, "MinWC", NewMinWC ) -- Var.TrinData.MinWC = NewMinWC -- local NewMaxWC = Var.TrinData.MaxWC * MobData.PhaseData[Var.PhaseStep].DamageFactor -- cSetNPCParam( Var.Handle, "MaxWC", NewMaxWC ) -- Var.TrinData.MaxWC = NewMaxWC -- local NewMinMA = Var.TrinData.MinMA * MobData.PhaseData[Var.PhaseStep].DamageFactor -- cSetNPCParam( Var.Handle, "MinMA", NewMinMA ) -- Var.TrinData.MinMA = NewMinMA -- local NewMaxMA = Var.TrinData.MaxMA * MobData.PhaseData[Var.PhaseStep].DamageFactor -- cSetNPCParam( Var.Handle, "MaxMA", NewMaxMA ) -- Var.TrinData.MaxMA = NewMaxMA -- local NewSTR = Var.TrinData.STR * MobData.PhaseData[Var.PhaseStep].DamageFactor -- cSetNPCParam( Var.Handle, "STR", NewSTR ) -- Var.TrinData.STR = NewSTR -- local NewEND = Var.TrinData.END * MobData.PhaseData[Var.PhaseStep].DefenseFactor -- cSetNPCParam( Var.Handle, "END", NewEND ) -- Var.TrinData.END = NewEND -- local NewINT = Var.TrinData.INT * MobData.PhaseData[Var.PhaseStep].DamageFactor -- cSetNPCParam( Var.Handle, "INT", NewINT ) -- Var.TrinData.INT = NewINT -- local NewSPR = Var.TrinData.SPR * MobData.PhaseData[Var.PhaseStep].DamageFactor -- cSetNPCParam( Var.Handle, "SPR", NewSPR ) -- Var.TrinData.SPR = NewSPR --> Check if immortal abstate applied and heal while immortal local x, y = cObjectLocate( Var.Handle ) if not Var.PhaseData.TeleportedHeal then if x ~= nil and y ~= nil then cEffectRegen_XY( Var.MapIndex, "BlinkCasting", x, y, 0, 5000, 0) cCastTeleport( Var.Handle, "SpecificCoord", 1591, 487, 310 ) cEffectRegen_XY( Var.MapIndex, "EglackMad_Skill06_N", 1591, 487, 0, 5000, 0) end Var.PhaseData.TeleportedHeal = true end local CloneList = { cFindNearestMobList( Var.MapIndex, MobData.PhaseData[Var.PhaseStep].SpawnList[1].MobInx ) } local CloneAlive = 0 for k, v in pairs(CloneList) do if cIsObjectDead( CloneList[k] ) == nil then CloneAlive = CloneAlive + 1 end end if CloneAlive > 0 then if Var.PhaseData.NextRegenTick <= cCurSec() then local HP, MaxHP = cObjectHP( Var.Handle ) if HP ~= nil then if x ~= nil and y ~= nil then cEffectRegen_XY( Var.MapIndex, "B_HelgaHeal", x, y, 0, 5000, 0 ) end if Var.PhaseData.RecoverHP then cSetMobAttr( Var.Handle, "Recover", 0 ) Var.PhaseData.RecoverHP = false end cHeal( Var.Handle, ((0.001 * CloneAlive) * MaxHP) ) end Var.PhaseData.NextRegenTick = cCurSec() + 1 end else if not Var.PhaseData.RecoverHP then cResetAbstate( Var.Handle, "StaMobImmortal" ) if not Var.PhaseData.PrtedToPlayerHeal then local PlayerList = { cGetPlayerList( Var.MapIndex ) } local AttemptCount = 0 while true do if AttemptCount >= 50 then break end local RandomNum = math.random(1, #PlayerList) local Player = PlayerList[RandomNum] local x, y = cObjectLocate( Player ) if x ~= nil and y ~= nil and cIsObjectDead( Player) == nil then cEffectRegen_XY( Var.MapIndex, "BlinkCasting", x, y, 0, 5000, 0) cCastTeleport( Var.Handle, "SpecificCoord", x, y, 0 ) cEffectRegen_XY( Var.MapIndex, "EglackMad_Skill06_N", x, y, 0, 5000, 0) Var.PhaseData.PrtedToPlayerHeal = true break end AttemptCount = AttemptCount + 1 end end cSetMobAttr( Var.Handle, "Recover", 1 ) Var.PhaseData.RecoverHP = true end end --> Set burn period if not set if Var.PhaseData.BurnSet <= cCurSec() then Var.PhaseData.BurnExpire = cCurSec() + MobData.BurnDuration Var.PhaseData.BurnSet = cCurSec() + MobData.BurnDuration + math.random(MobData.BurnNextWaitMin, MobData.BurnNextWaitMax) end if Var.PhaseData.BurnExpire >= cCurSec() then if Var.PhaseData.BurnTick <= cCurSec() then local PlayerList = { cGetPlayerList( Var.MapIndex ) } for i=1, #PlayerList do if PlayerList[i] ~= nil and cIsObjectDead( PlayerList[i] ) == nil then local PlayerBase = cGetBaseClass( PlayerList[i] ) if PlayerBase == BasicClass.Cleric or PlayerBase == BasicClass.Mage or PlayerBase == BasicClass.Archer then local AbStr, AbRemain = cGetAbstate( PlayerList[i], "StaKQSpringArrow" ) if AbStr == nil then cSetAbstate( PlayerList[i], "StaKQSpringArrow", 1, (MobData.BurnDuration * 1000)) end local TargetX, TargetY = cObjectLocate( PlayerList[i] ) local NearList = { cGetPlayerList( Var.MapIndex ) } for j=1, #NearList do if NearList[j] ~= nil and cIsObjectDead( NearList[j] ) == nil then local DistanceBetween = cDistanceSquar( PlayerList[i], NearList[j] ) if DistanceBetween <= 100000 then cDirectionalArrow( NearList[j], TargetX, TargetY ) local Damage = math.random(Var.PhaseData.BurnMin, Var.PhaseData.BurnMax) Trin_DamagePlayer( NearList[j], Damage, PlayerList[i] ) Trin_DamagePlayer( PlayerList[i], Damage, Var.Handle ) else cDelDirectionalArrow( NearList[j] ) end end end end end end Var.PhaseData.BurnTick = cCurSec() + 1 end end if Var.PhaseData.RecoverHP then return ReturnAI.CPP else return ReturnAI.END end end --> Defense expire function Trin_PDefenseExpire( Var ) cExecCheck("Trin_PDefenseExpire") Var.PhaseData.TeleportedHeal = false for i=1, #Var.PhaseData.AddsList do cNPCVanish( Var.PhaseData.AddsList[i] ) end Var.PhaseData.AddsList = {} if MobData.PhaseData[Var.PhaseStep].OnStartAb ~= nil then cResetAbstate( Var.Handle, MobData.PhaseData[Var.PhaseStep].OnStartAb ) end if not Var.PhaseData.PrtedToPlayerHeal then local PlayerList = { cGetPlayerList( Var.MapIndex ) } local AttemptCount = 0 while true do if AttemptCount >= 50 then break end local RandomNum = math.random(1, #PlayerList) local Player = PlayerList[RandomNum] local x, y = cObjectLocate( Player ) if x ~= nil and y ~= nil and cIsObjectDead( Player) == nil then cEffectRegen_XY( Var.MapIndex, "BlinkCasting", x, y, 0, 5000, 0) cCastTeleport( Var.Handle, "SpecificCoord", x, y, 0 ) cEffectRegen_XY( Var.MapIndex, "EglackMad_Skill06_N", x, y, 0, 5000, 0) Var.PhaseData.PrtedToPlayerHeal = true break end AttemptCount = AttemptCount + 1 end end if not Var.PhaseData.RecoverHP then cSetMobAttr( Var.Handle, "Recover", 1 ) Var.PhaseData.RecoverHP = true end local PlayerList = { cGetPlayerList( Var.MapIndex ) } for i=1, #PlayerList do cDelDirectionalArrow( PlayerList[i] ) cResetAbstate( PlayerList[i], "StaKQSpringArrow" ) end end --> Ultimate phase function Trin_PUltimate( Var ) cExecCheck("Trin_PUltimate") if not Var.PhaseData.Teleported then local x, y = cObjectLocate( Var.Handle ) if x ~= nil and y ~= nil then cEffectRegen_XY( Var.MapIndex, "BlinkCasting", x, y, 0, 5000, 0) cCastTeleport( Var.Handle, "SpecificCoord", 1593, 1594, 287 ) cEffectRegen_XY( Var.MapIndex, "EglackMad_Skill06_N", 1593, 1594, 0, 5000, 0) --cSetAbstate( Var.Handle, "StaImmortal", 1, (MobData.PhaseData[Var.PhaseStep].Duration * 1000) ) --cMapFog( Var.MapIndex, 500, 2000 ) end Var.PhaseData.SkillDelay = cCurSec() + 2 Var.PhaseData.Teleported = true end if Var.PhaseData.SkillDelay <= cCurSec() then --> Mobweapon rate cMobWeaponRate( Var.Handle, 1000, 1000, 1000, 1000 ) --> Skillindex use cSkillBlast( Var.Handle, Var.Handle, "WindyWitch_Skill03_W" ) --cSkillBlast( Handle, Handle, "ArkMine_Kn_Skill01_W" ) --cNPCSkillUse( Handle, Handle, "ArkMine_Kn_Skill01_W" ) Var.PhaseData.SkillDelay = cCurSec() + MobData.PhaseData[Var.PhaseStep].Duration end return ReturnAI.CPP end --> Ultimate phase expire function Trin_PUltimateExpire( Var ) cExecCheck("Trin_PUltimateExpire") Var.PhaseData.Teleported = false if MobData.PhaseData[Var.PhaseStep].OnStartAb ~= nil then cResetAbstate( Var.Handle, MobData.PhaseData[Var.PhaseStep].OnStartAb ) end if not Var.PhaseData.PrtedToPlayer then local PlayerList = { cGetPlayerList( Var.MapIndex ) } local RandomNum = math.random(1, #PlayerList) local Player = PlayerList[RandomNum] local x, y = cObjectLocate( Player ) if x ~= nil and y ~= nil then cEffectRegen_XY( Var.MapIndex, "BlinkCasting", x, y, 0, 5000, 0) cCastTeleport( Var.Handle, "SpecificCoord", x, y, 0 ) cEffectRegen_XY( Var.MapIndex, "EglackMad_Skill06_N", x, y, 0, 5000, 0) end Var.PhaseData.PrtedToPlayer = true end --cResetAbstate( Var.Handle, "StaMobImmortal" ) end --> Timer to players function Trin_TimerSet( MapIndex, LastTime ) cExecCheck("Trin_TimerSet") cTimer( MapIndex, LastTime ) end function Trin_DamagePlayer( DamagePlayer, DamageAmount, DamageAggro ) cExecCheck("Trin_DamagePlayer") if DamagePlayer == nil then return end local CurHP, MaxHP = cObjectHP( DamagePlayer ) if CurHP == nil then return end if CurHP - DamageAmount <= 0 then cDamaged( DamagePlayer, (CurHP - 1), DamageAggro ) else if DamageAmount > 65535 then cDamaged( DamagePlayer, 65535, DamageAggro ) else cDamaged( DamagePlayer, DamageAmount, DamageAggro ) end end end --> Chest spawn function Trin_ChestSpawn( Var ) cExecCheck("Trin_ChestSpawn") -- local x, y = cObjectLocate( Var.Handle ) for i = 1, #TrinReward.BoxData do local BoxHandle = cMobRegen_Circle( Var.MapIndex, TrinReward.BoxData[i].Index, TrinReward.Position.X, TrinReward.Position.Y, TrinReward.Position.Radius ) if BoxHandle ~= nil then cSetItemDropMobID( BoxHandle, TrinReward.BoxData[i].ItemDropMobIndex ) end end -- for i = 1, 20 do -- local BoxHandle = cMobRegen_Circle( Var.MapIndex, TrinBox_DummyMobInx, x, y, TrinBox[1].Radius ) -- if BoxHandle ~= nil and TrinBox_DummyDropInx ~= nil then -- cSetItemDropMobID( BoxHandle, TrinBox_DummyDropInx ) -- end -- end end