Name | Type | is_array | initial_value |
//TESH.scrollpos=53
//TESH.alwaysfold=0
library TimerUtils initializer init
//*********************************************************************
//* TimerUtils (red+blue+orange flavors for 1.24b+) 2.0
//* ----------
//*
//* To implement it , create a custom text trigger called TimerUtils
//* and paste the contents of this script there.
//*
//* To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass) More scripts: htt://www.wc3c.net
//*
//* For your timer needs:
//* * Attaching
//* * Recycling (with double-free protection)
//*
//* set t=NewTimer() : Get a timer (alternative to CreateTimer)
//* set t=NewTimerEx(x) : Get a timer (alternative to CreateTimer), call
//* Initialize timer data as x, instead of 0.
//*
//* ReleaseTimer(t) : Relese a timer (alt to DestroyTimer)
//* SetTimerData(t,2) : Attach value 2 to timer
//* GetTimerData(t) : Get the timer's value.
//* You can assume a timer's value is 0
//* after NewTimer.
//*
//* Multi-flavor:
//* Set USE_HASH_TABLE to true if you don't want to complicate your life.
//*
//* If you like speed and giberish try learning about the other flavors.
//*
//********************************************************************
//================================================================
globals
//How to tweak timer utils:
// USE_HASH_TABLE = true (new blue)
// * SAFEST
// * SLOWEST (though hash tables are kind of fast)
//
// USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = true (orange)
// * kinda safe (except there is a limit in the number of timers)
// * ALMOST FAST
//
// USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = false (red)
// * THE FASTEST (though is only faster than the previous method
// after using the optimizer on the map)
// * THE LEAST SAFE ( you may have to tweak OFSSET manually for it to
// work)
//
private constant boolean USE_HASH_TABLE = true
private constant boolean USE_FLEXIBLE_OFFSET = false
private constant integer OFFSET = 0x100000
private integer VOFFSET = OFFSET
//Timers to preload at map init:
private constant integer QUANTITY = 256
//Changing this to something big will allow you to keep recycling
// timers even when there are already AN INCREDIBLE AMOUNT of timers in
// the stack. But it will make things far slower so that's probably a bad idea...
private constant integer ARRAY_SIZE = 8190
endglobals
//==================================================================================================
globals
private integer array data[ARRAY_SIZE]
private hashtable ht
endglobals
//It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
function SetTimerData takes timer t, integer value returns nothing
static if(USE_HASH_TABLE) then
// new blue
call SaveInteger(ht,0,GetHandleId(t), value)
elseif (USE_FLEXIBLE_OFFSET) then
// orange
static if (DEBUG_MODE) then
if(GetHandleId(t)-VOFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
set data[GetHandleId(t)-VOFFSET]=value
else
// new red
static if (DEBUG_MODE) then
if(GetHandleId(t)-OFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
set data[GetHandleId(t)-OFFSET]=value
endif
endfunction
function GetTimerData takes timer t returns integer
static if(USE_HASH_TABLE) then
// new blue
return LoadInteger(ht,0,GetHandleId(t) )
elseif (USE_FLEXIBLE_OFFSET) then
// orange
static if (DEBUG_MODE) then
if(GetHandleId(t)-VOFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
return data[GetHandleId(t)-VOFFSET]
else
// new red
static if (DEBUG_MODE) then
if(GetHandleId(t)-OFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
return data[GetHandleId(t)-OFFSET]
endif
endfunction
//==========================================================================================
globals
private timer array tT[ARRAY_SIZE]
private integer tN = 0
private constant integer HELD=0x28829022
//use a totally random number here, the more improbable someone uses it, the better.
private boolean didinit = false
endglobals
private keyword init
//==========================================================================================
// I needed to decide between duplicating code ignoring the "Once and only once" rule
// and using the ugly textmacros. I guess textmacros won.
//
//! textmacro TIMERUTIS_PRIVATE_NewTimerCommon takes VALUE
// On second thought, no.
//! endtextmacro
function NewTimerEx takes integer value returns timer
if (tN==0) then
if (not didinit) then
//This extra if shouldn't represent a major performance drawback
//because QUANTITY rule is not supposed to be broken every day.
call init.evaluate()
set tN = tN - 1
else
//If this happens then the QUANTITY rule has already been broken, try to fix the
// issue, else fail.
debug call BJDebugMsg("NewTimer: Warning, Exceeding TimerUtils_QUANTITY, make sure all timers are getting recycled correctly")
set tT[0]=CreateTimer()
static if( not USE_HASH_TABLE) then
debug call BJDebugMsg("In case of errors, please increase it accordingly, or set TimerUtils_USE_HASH_TABLE to true")
static if( USE_FLEXIBLE_OFFSET) then
if (GetHandleId(tT[0])-VOFFSET<0) or (GetHandleId(tT[0])-VOFFSET>=ARRAY_SIZE) then
//all right, couldn't fix it
call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
return null
endif
else
if (GetHandleId(tT[0])-OFFSET<0) or (GetHandleId(tT[0])-OFFSET>=ARRAY_SIZE) then
//all right, couldn't fix it
call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
return null
endif
endif
endif
endif
else
set tN=tN-1
endif
call SetTimerData(tT[tN],value)
return tT[tN]
endfunction
function NewTimer takes nothing returns timer
return NewTimerEx(0)
endfunction
//==========================================================================================
function ReleaseTimer takes timer t returns nothing
if(t==null) then
debug call BJDebugMsg("Warning: attempt to release a null timer")
return
endif
if (tN==ARRAY_SIZE) then
debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!")
//stack is full, the map already has much more troubles than the chance of bug
call DestroyTimer(t)
else
call PauseTimer(t)
if(GetTimerData(t)==HELD) then
debug call BJDebugMsg("Warning: ReleaseTimer: Double free!")
return
endif
call SetTimerData(t,HELD)
set tT[tN]=t
set tN=tN+1
endif
endfunction
private function init takes nothing returns nothing
local integer i=0
local integer o=-1
local boolean oops = false
if ( didinit ) then
return
else
set didinit = true
endif
static if( USE_HASH_TABLE ) then
set ht = InitHashtable()
loop
exitwhen(i==QUANTITY)
set tT[i]=CreateTimer()
call SetTimerData(tT[i], HELD)
set i=i+1
endloop
set tN = QUANTITY
else
loop
set i=0
loop
exitwhen (i==QUANTITY)
set tT[i] = CreateTimer()
if(i==0) then
set VOFFSET = GetHandleId(tT[i])
static if(USE_FLEXIBLE_OFFSET) then
set o=VOFFSET
else
set o=OFFSET
endif
endif
if (GetHandleId(tT[i])-o>=ARRAY_SIZE) then
exitwhen true
endif
if (GetHandleId(tT[i])-o>=0) then
set i=i+1
endif
endloop
set tN = i
exitwhen(tN == QUANTITY)
set oops = true
exitwhen not USE_FLEXIBLE_OFFSET
debug call BJDebugMsg("TimerUtils_init: Failed a initialization attempt, will try again")
endloop
if(oops) then
static if ( USE_FLEXIBLE_OFFSET) then
debug call BJDebugMsg("The problem has been fixed.")
//If this message doesn't appear then there is so much
//handle id fragmentation that it was impossible to preload
//so many timers and the thread crashed! Therefore this
//debug message is useful.
elseif(DEBUG_MODE) then
call BJDebugMsg("There were problems and the new timer limit is "+I2S(i))
call BJDebugMsg("This is a rare ocurrence, if the timer limit is too low:")
call BJDebugMsg("a) Change USE_FLEXIBLE_OFFSET to true (reduces performance a little)")
call BJDebugMsg("b) or try changing OFFSET to "+I2S(VOFFSET) )
endif
endif
endif
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library SPELLPACK initializer init
globals
hashtable HS
endglobals
function CameraStop takes nothing returns nothing
local timer z = GetExpiredTimer()
local group gg = LoadGroupHandle(HS,GetHandleId(z),0)
local unit t
loop
set t = FirstOfGroup(gg)
exitwhen t == null
call CameraClearNoiseForPlayer(GetOwningPlayer(t))
call GroupRemoveUnit(gg,t)
endloop
call DestroyGroup(gg)
call DestroyTimer(z)
call FlushChildHashtable(HS,GetHandleId(z))
set z = null
set gg = null
endfunction
function ShakeGroupCamera takes real time, real x, real y, real range, real shake returns nothing
local group g = CreateGroup()
local unit t
local timer z = CreateTimer()
call SaveGroupHandle(HS,GetHandleId(z),0,CreateGroup())
call GroupEnumUnitsInRange(g,x,y,range,null)
loop
set t = FirstOfGroup(g)
exitwhen t == null
if IsUnitType(t,UNIT_TYPE_HERO) == true then
call CameraSetEQNoiseForPlayer(GetOwningPlayer(t),shake)
call GroupAddUnit(LoadGroupHandle(HS,GetHandleId(z),0),t)
endif
call GroupRemoveUnit(g,t)
endloop
call TimerStart(z,time,false,function CameraStop)
set g = null
set z = null
endfunction
function PolarX takes real x, real dist, real angle returns real
return x+dist*Cos(angle*bj_DEGTORAD)
endfunction
function PolarY takes real y, real dist, real angle returns real
return y+dist*Sin(angle*bj_DEGTORAD)
endfunction
function Angle takes real x1, real y1, real x2, real y2 returns real
return bj_RADTODEG * Atan2(y2-y1, x2-x1)
endfunction
private function MultiInstanceFilter takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(GetTriggerUnit()))==true and GetUnitAbilityLevel(GetFilterUnit(),'Avul') != 1 and GetWidgetLife(GetFilterUnit()) > 0.45 and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)==false
endfunction
function Distance takes real x1, real y1, real x2, real y2 returns real
return SquareRoot((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))
endfunction
private function init takes nothing returns nothing
set HS = InitHashtable()
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope HeavenlyBeam initializer init
globals
private constant integer SPELLID = 'A003' // Raw code of spell id
private constant integer MISSILE = 'h00B' // Raw code of dummy model
private constant integer SKYBOMB = 'h00D' // Raw code of dummy model
private constant integer SKYRING = 'h00E' // Raw code of dummy model
private constant integer ICENOVA = 'h00F' // Raw code of dummy model
private constant integer FREEZINGRING = 'h007' // Raw code of dummy model
private constant integer LIGHTCANDY = 'h003' // Raw code of dummy model
private constant integer AURAID = 'h00C' // Raw code of dummy model
private constant integer DUST = 'h004' // Raw code of dummy model
private constant integer MAXHIT = 5 // Number of beam
private constant string EFFECT2 = "war3mapImported\\SkyExplosion.mdx"
endglobals
private struct starfall
unit c
unit t
unit d
real curve
real angle
real rate
real speed
method destroy takes nothing returns nothing
call .deallocate()
endmethod
method damage takes nothing returns real
local real r = GetUnitAbilityLevel(c,SPELLID) * 10 // deal 10 damage per level of ability per beam
return r
endmethod
static method onLoop2 takes nothing returns nothing
local timer z = GetExpiredTimer()
local starfall this = GetTimerData(z)
local real a
local real x
local real y
if angle < 0 then
set angle = angle + rate
endif
set a = Angle(GetUnitX(d),GetUnitY(d),GetUnitX(t),GetUnitY(t)) - angle
set x = PolarX(GetUnitX(d),speed,a)
set y = PolarY(GetUnitY(d),speed,a)
call SetUnitPosition(d,x,y)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),MISSILE,x,y,a)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',0.5)
if Distance(x,y,GetUnitX(t),GetUnitY(t)) <= 50 then
call RemoveUnit(d)
call UnitDamageTarget(c,t,damage(),true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_MAGIC,null)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),DUST,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,2.5,2.5,2.5)
call SetUnitVertexColor(bj_lastCreatedUnit,100,100,255,50)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),FREEZINGRING,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,1,1,1)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call SetUnitVertexColor(bj_lastCreatedUnit,255,255,255,255)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYRING,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,1,1,1)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),ICENOVA,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,2,2,2)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call DestroyEffect(AddSpecialEffect(EFFECT2,GetUnitX(t),GetUnitY(t)))
call ReleaseTimer(z)
call .destroy()
endif
endmethod
static method onLoop takes nothing returns nothing
local timer z = GetExpiredTimer()
local starfall this = GetTimerData(z)
local real a
local real x
local real y
if angle > 0 then
set angle = angle - rate
endif
set a = Angle(GetUnitX(d),GetUnitY(d),GetUnitX(t),GetUnitY(t)) - angle
set x = PolarX(GetUnitX(d),speed,a)
set y = PolarY(GetUnitY(d),speed,a)
call SetUnitPosition(d,x,y)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),MISSILE,x,y,a)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',0.5)
if Distance(x,y,GetUnitX(t),GetUnitY(t)) <= 50 then
call RemoveUnit(d)
call UnitDamageTarget(c,t,damage(),true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_MAGIC,null)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),DUST,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,2.5,2.5,2.5)
call SetUnitVertexColor(bj_lastCreatedUnit,100,100,255,50)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),FREEZINGRING,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,1.5,1.5,1.5)
call SetUnitVertexColor(bj_lastCreatedUnit,255,255,255,255)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call SetUnitVertexColor(bj_lastCreatedUnit,255,255,255,255)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYRING,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,1,1,1)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),ICENOVA,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,2,2,2)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call DestroyEffect(AddSpecialEffect(EFFECT2,GetUnitX(t),GetUnitY(t)))
call ReleaseTimer(z)
call .destroy()
endif
endmethod
static method create takes unit caster, unit target, real AngleC, real CRate, real speeds returns thistype
local starfall this = starfall.allocate()
local timer z = NewTimer()
local real a
set c = caster
set t = target
set a = Angle(GetUnitX(c),GetUnitY(c),GetUnitX(t),GetUnitY(t))
set d = CreateUnit(GetOwningPlayer(c),MISSILE,PolarX(GetUnitX(c),70,a),PolarY(GetUnitY(c),70,a),AngleC)
call SetUnitScale(d,1.5,1.5,1.5)
set rate = CRate
set angle = AngleC
set speed = speeds
call SetTimerData(z,this)
if angle >= 0 then
call TimerStart(z,0.04,true,function starfall.onLoop)
else
call TimerStart(z,0.04,true,function starfall.onLoop2)
endif
return this
endmethod
endstruct
private struct data
unit c
unit t
integer hit = MAXHIT
method destroy takes nothing returns nothing
call PauseUnit(c,false)
call .deallocate()
endmethod
static method onAction takes nothing returns nothing
local timer z = GetExpiredTimer()
local data this = GetTimerData(z)
local real r
local real a = Angle(GetUnitX(c),GetUnitY(c),GetUnitX(t),GetUnitY(t))
if GetRandomReal(1,100) <= 50 then
set r = GetRandomReal(-70,-15)
else
set r = GetRandomReal(15,70)
endif
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),LIGHTCANDY,PolarX(GetUnitX(c),70,a),PolarY(GetUnitY(c),70,a),a)
call SetUnitScale(bj_lastCreatedUnit,4,4,4)
call SetUnitVertexColor(bj_lastCreatedUnit,255,255,255,10)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call starfall.create(c,t,r,2.5,50)
set hit = hit - 1
if hit <= 0 then
call ReleaseTimer(z)
call .destroy()
endif
endmethod
static method onAction2 takes nothing returns nothing
local timer z = GetExpiredTimer()
call TimerStart(z,0.2,true,function data.onAction)
endmethod
static method onAction1 takes nothing returns nothing
local timer z = GetExpiredTimer()
local data this = GetTimerData(z)
call SetUnitAnimation(c,"spell one")
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),DUST,GetUnitX(c),GetUnitY(c),0)
call SetUnitScale(bj_lastCreatedUnit,3,3,3)
call SetUnitVertexColor(bj_lastCreatedUnit,255,255,255,50)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call TimerStart(z,0.6,true,function data.onAction2)
endmethod
static method create takes unit caster, unit target returns thistype
local data this = data.allocate()
local timer z = NewTimer()
set c = caster
set t = target
call PauseUnit(c,true)
call SetUnitAnimation(c,"spell one")
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),AURAID,GetUnitX(c),GetUnitY(c),270)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',2.5)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),AURAID,GetUnitX(c),GetUnitY(c),90)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',2.5)
call SetTimerData(z,this)
call TimerStart(z,0.05,false,function data.onAction1)
return this
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SPELLID
endfunction
private function Actions takes nothing returns nothing
call data.create(GetTriggerUnit(),GetSpellTargetUnit())
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer index
set index = 0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t,Condition(function Conditions))
call TriggerAddAction(t,function Actions)
set t = null
endfunction
endscope
//TESH.scrollpos=44
//TESH.alwaysfold=0
scope HeavenlyBlast initializer init
globals
private constant integer SPELLID = 'A000' // Raw code of spell id
private constant integer MISSILE = 'h00B' // Raw code of dummy model
private constant integer SKYBOMB = 'h00D' // Raw code of dummy model
private constant integer SKYRING = 'h00E' // Raw code of dummy model
private constant integer ICENOVA = 'h00F' // Raw code of dummy model
private constant integer FREEZINGRING = 'h007' // Raw code of dummy model
private constant integer LIGHTCANDY = 'h003' // Raw code of dummy model
private constant integer LIGHTSTRIKEARRAY = 'h008' // Raw code of dummy model
private constant integer AURAID = 'h00C' // Raw code of dummy model
private constant integer DUST = 'h004' // Raw code of dummy model
private constant string EFFECT2 = "war3mapImported\\SkyExplosion.mdx"
endglobals
private struct data
unit c
unit t
unit d
real angle
real time = 2
method destroy takes nothing returns nothing
call RemoveUnit(d)
call .deallocate()
endmethod
method damage takes nothing returns real
local real r = GetUnitAbilityLevel(c,SPELLID) * 100 // deal 100 damage per level of ability
return r
endmethod
static method onAction3 takes nothing returns nothing
local timer z = GetExpiredTimer()
local data this = GetTimerData(z)
local real x = PolarX(GetUnitX(t),40,angle)
local real y = PolarY(GetUnitY(t),40,angle)
call SetUnitPosition(t,x,y)
call SetUnitPosition(d,x,y)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),MISSILE,x,y,angle)
call SetUnitScale(bj_lastCreatedUnit,4,4,4)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',0.5)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),LIGHTSTRIKEARRAY,x,y,angle)
call SetUnitScale(bj_lastCreatedUnit,2,2,2)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',0.4)
set time = time - 0.04
if time <= 0 then
call UnitDamageTarget(c,t,damage(),true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_MAGIC,null)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),DUST,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,2.5,2.5,2.5)
call SetUnitVertexColor(bj_lastCreatedUnit,100,100,255,50)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),FREEZINGRING,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,3,3,3)
call SetUnitTimeScale(bj_lastCreatedUnit,0.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,5.5,5.5,5.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,5.5,5.5,5.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYRING,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,1.5,1.5,1.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),ICENOVA,GetUnitX(t),GetUnitY(t),0)
call SetUnitScale(bj_lastCreatedUnit,3,3,3)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call DestroyEffect(AddSpecialEffect(EFFECT2,GetUnitX(t),GetUnitY(t)))
call ReleaseTimer(z)
call .destroy()
endif
endmethod
static method onAction takes nothing returns nothing
local timer z = GetExpiredTimer()
local data this = GetTimerData(z)
local real a = Angle(GetUnitX(d),GetUnitY(d),GetUnitX(t),GetUnitY(t))
local real x = PolarX(GetUnitX(d),50,a)
local real y = PolarY(GetUnitY(d),50,a)
call SetUnitPosition(d,x,y)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),MISSILE,x,y,a)
call SetUnitScale(bj_lastCreatedUnit,4,4,4)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',0.5)
set time = time - 0.04
if Distance(GetUnitX(d),GetUnitY(d),GetUnitX(t),GetUnitY(t)) <= 50 then
set angle = a
call TimerStart(z,0.04,true,function data.onAction3)
endif
endmethod
static method onAction2 takes nothing returns nothing
local timer z = GetExpiredTimer()
local data this = GetTimerData(z)
local real a = Angle(GetUnitX(c),GetUnitY(c),GetUnitX(t),GetUnitY(t))
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),LIGHTCANDY,PolarX(GetUnitX(c),70,a),PolarY(GetUnitY(c),70,a),a)
call SetUnitScale(bj_lastCreatedUnit,4,4,4)
call SetUnitVertexColor(bj_lastCreatedUnit,255,255,255,255)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set d = CreateUnit(GetOwningPlayer(c),MISSILE,PolarX(GetUnitX(c),70,a),PolarY(GetUnitY(c),70,a),a)
call SetUnitScale(d,8,8,8)
call PauseUnit(c,false)
call TimerStart(z,0.04,true,function data.onAction)
endmethod
static method onAction1 takes nothing returns nothing
local timer z = GetExpiredTimer()
local data this = GetTimerData(z)
call SetUnitAnimation(c,"spell")
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),DUST,GetUnitX(c),GetUnitY(c),0)
call SetUnitScale(bj_lastCreatedUnit,3,3,3)
call SetUnitVertexColor(bj_lastCreatedUnit,255,255,255,50)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call TimerStart(z,0.6,true,function data.onAction2)
endmethod
static method create takes unit caster, unit target returns thistype
local data this = data.allocate()
local timer z = NewTimer()
set c = caster
set t = target
call PauseUnit(c,true)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),AURAID,GetUnitX(c),GetUnitY(c),270)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',2.5)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),AURAID,GetUnitX(c),GetUnitY(c),90)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',2.5)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),AURAID,GetUnitX(c),GetUnitY(c),90)
call SetUnitScale(bj_lastCreatedUnit,4,4,4)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',2.5)
call SetTimerData(z,this)
call TimerStart(z,0.05,false,function data.onAction1)
return this
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SPELLID
endfunction
private function Actions takes nothing returns nothing
call data.create(GetTriggerUnit(),GetSpellTargetUnit())
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer index
set index = 0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t,Condition(function Conditions))
call TriggerAddAction(t,function Actions)
set t = null
endfunction
endscope
//TESH.scrollpos=392
//TESH.alwaysfold=0
scope GrandChariot initializer init
globals
private constant integer SPELLID = 'A001' // Raw code of spell id
private constant integer MISSILE = 'h00B' // Raw code of dummy model
private constant integer SKYBOMB = 'h00D' // Raw code of dummy model
private constant integer SKYRING = 'h00E' // Raw code of dummy model
private constant integer ICENOVA = 'h00F' // Raw code of dummy model
private constant integer LIGHTCANDY = 'h003' // Raw code of dummy model
private constant integer FIRAGA = 'h00P' // Raw code of dummy model
private constant integer MEGABLAST = 'h00J' // Raw code of dummy model
private constant integer MAGICCIRCLE90 = 'h00H' // Raw code of dummy model
private constant integer SHADOW = 'h00G' // Raw code of dummy model
private constant integer GALAXY = 'h00I' // Raw code of dummy model
private constant string EFFECT2 = "war3mapImported\\SkyExplosion.mdx"
private constant real RADIUS = 350 // Radius of each 7 blast
endglobals
private struct data
unit c
real targetx
real targety
unit array e[8]
lightning array l[7]
integer count = 3
method destroy takes nothing returns nothing
local integer i = 1
loop
exitwhen i > 7
call UnitApplyTimedLife(e[i],'BTLF',1)
if i != 7 then
call DestroyLightning(l[i])
endif
set i = i + 1
endloop
call PauseUnit(c,false)
call SetUnitTimeScale(c,1)
call SetUnitAnimation(c,"stand")
call .deallocate()
endmethod
method damage takes nothing returns real
local real r = GetUnitAbilityLevel(c,SPELLID) * 100 // deal 100 damage per level of ability
return r
endmethod
static method onAction takes nothing returns nothing
local timer z = GetExpiredTimer()
local data this = GetTimerData(z)
local real r
local real a = Angle(GetUnitX(c),GetUnitY(c),targetx,targety)
local integer i = 1
local real x = targetx
local real y = targety
local real xx
local real yy
local group g
local group go
local unit v
loop
exitwhen i > 7
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),LIGHTCANDY,GetUnitX(e[i]),GetUnitY(e[i]),a)
call SetUnitFlyHeight(bj_lastCreatedUnit,GetUnitFlyHeight(e[i]),0)
call SetUnitScale(bj_lastCreatedUnit,4,4,4)
call SetUnitVertexColor(bj_lastCreatedUnit,255,255,255,15)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set i = i + 1
endloop
if count == 2 then
call ShakeGroupCamera(1,targetx,targety,1200,10)
set xx = PolarX(x,560,a + 100)
set yy = PolarY(y,560,a + 100)
set g = CreateGroup()
set go = CreateGroup()
call GroupEnumUnitsInRange(g,xx,yy,RADIUS,null)
loop
set v = FirstOfGroup(g)
exitwhen v == null
if IsUnitEnemy(v,GetOwningPlayer(c)) == true and IsUnitType(v,UNIT_TYPE_STRUCTURE) == false and GetWidgetLife(v) > 0.45 and GetUnitAbilityLevel(c,'Avul') <= 0 and IsUnitInGroup(v,go) == false then
call UnitDamageTarget(c,v,damage(),true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_MAGIC,null)
call GroupAddUnit(go,v)
endif
call GroupRemoveUnit(g,v)
endloop
call GroupClear(g)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),FIRAGA,xx,yy,a)
call SetUnitScale(bj_lastCreatedUnit,2,2,2)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),MEGABLAST,xx,yy,a)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYRING,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,1,1,1)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),ICENOVA,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,1.5,1.5,1.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call DestroyEffect(AddSpecialEffect(EFFECT2,xx,yy))
set xx = PolarX(x,530,a + 50)
set yy = PolarY(y,530,a + 50)
call GroupEnumUnitsInRange(g,xx,yy,RADIUS,null)
loop
set v = FirstOfGroup(g)
exitwhen v == null
if IsUnitEnemy(v,GetOwningPlayer(c)) == true and IsUnitType(v,UNIT_TYPE_STRUCTURE) == false and GetWidgetLife(v) > 0.45 and GetUnitAbilityLevel(c,'Avul') <= 0 and IsUnitInGroup(v,go) == false then
call UnitDamageTarget(c,v,damage(),true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_MAGIC,null)
call GroupAddUnit(go,v)
endif
call GroupRemoveUnit(g,v)
endloop
call GroupClear(g)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),FIRAGA,xx,yy,a)
call SetUnitScale(bj_lastCreatedUnit,2,2,2)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),MEGABLAST,xx,yy,a)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call DestroyEffect(AddSpecialEffect(EFFECT2,xx,yy))
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYRING,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,1,1,1)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),ICENOVA,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,1.5,1.5,1.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set xx = PolarX(x,350,a + 25)
set yy = PolarY(y,350,a + 25)
call GroupEnumUnitsInRange(g,xx,yy,RADIUS,null)
loop
set v = FirstOfGroup(g)
exitwhen v == null
if IsUnitEnemy(v,GetOwningPlayer(c)) == true and IsUnitType(v,UNIT_TYPE_STRUCTURE) == false and GetWidgetLife(v) > 0.45 and GetUnitAbilityLevel(c,'Avul') <= 0 and IsUnitInGroup(v,go) == false then
call UnitDamageTarget(c,v,damage(),true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_MAGIC,null)
if IsUnitInGroup(v,go) == false then
call GroupAddUnit(go,v)
endif
endif
call GroupRemoveUnit(g,v)
endloop
call GroupClear(g)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),FIRAGA,xx,yy,a)
call SetUnitScale(bj_lastCreatedUnit,2,2,2)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),MEGABLAST,xx,yy,a)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call DestroyEffect(AddSpecialEffect(EFFECT2,xx,yy))
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYRING,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,1,1,1)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),ICENOVA,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,1.5,1.5,1.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set xx = PolarX(x,0,a - 90)
set yy = PolarY(y,0,a - 90)
call GroupEnumUnitsInRange(g,xx,yy,RADIUS,null)
loop
set v = FirstOfGroup(g)
exitwhen v == null
if IsUnitEnemy(v,GetOwningPlayer(c)) == true and IsUnitType(v,UNIT_TYPE_STRUCTURE) == false and GetWidgetLife(v) > 0.45 and GetUnitAbilityLevel(c,'Avul') <= 0 and IsUnitInGroup(v,go) == false then
call UnitDamageTarget(c,v,damage(),true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_MAGIC,null)
if IsUnitInGroup(v,go) == false then
call GroupAddUnit(go,v)
endif
endif
call GroupRemoveUnit(g,v)
endloop
call GroupClear(g)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),FIRAGA,xx,yy,a)
call SetUnitScale(bj_lastCreatedUnit,2,2,2)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),MEGABLAST,xx,yy,a)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call DestroyEffect(AddSpecialEffect(EFFECT2,xx,yy))
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYRING,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,1,1,1)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),ICENOVA,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,1.5,1.5,1.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set xx = PolarX(x,180,a - 85)
set yy = PolarY(y,180,a - 85)
call GroupEnumUnitsInRange(g,xx,yy,RADIUS,null)
loop
set v = FirstOfGroup(g)
exitwhen v == null
if IsUnitEnemy(v,GetOwningPlayer(c)) == true and IsUnitType(v,UNIT_TYPE_STRUCTURE) == false and GetWidgetLife(v) > 0.45 and GetUnitAbilityLevel(c,'Avul') <= 0 and IsUnitInGroup(v,go) == false then
call UnitDamageTarget(c,v,damage(),true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_MAGIC,null)
if IsUnitInGroup(v,go) == false then
call GroupAddUnit(go,v)
endif
endif
call GroupRemoveUnit(g,v)
endloop
call GroupClear(g)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),FIRAGA,xx,yy,a)
call SetUnitScale(bj_lastCreatedUnit,2,2,2)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),MEGABLAST,xx,yy,a)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call DestroyEffect(AddSpecialEffect(EFFECT2,xx,yy))
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYRING,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,1,1,1)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),ICENOVA,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,1.5,1.5,1.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set xx = PolarX(x,320,a - 80)
set yy = PolarY(y,320,a - 80)
call GroupEnumUnitsInRange(g,xx,yy,RADIUS,null)
loop
set v = FirstOfGroup(g)
exitwhen v == null
if IsUnitEnemy(v,GetOwningPlayer(c)) == true and IsUnitType(v,UNIT_TYPE_STRUCTURE) == false and GetWidgetLife(v) > 0.45 and GetUnitAbilityLevel(c,'Avul') <= 0 and IsUnitInGroup(v,go) == false then
call UnitDamageTarget(c,v,damage(),true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_MAGIC,null)
if IsUnitInGroup(v,go) == false then
call GroupAddUnit(go,v)
endif
endif
call GroupRemoveUnit(g,v)
endloop
call GroupClear(g)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),FIRAGA,xx,yy,a)
call SetUnitScale(bj_lastCreatedUnit,2,2,2)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),MEGABLAST,xx,yy,a)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call DestroyEffect(AddSpecialEffect(EFFECT2,xx,yy))
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYRING,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,1,1,1)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),ICENOVA,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,1.5,1.5,1.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set xx = PolarX(x,700,a - 65)
set yy = PolarY(y,700,a - 65)
call GroupEnumUnitsInRange(g,xx,yy,RADIUS,null)
loop
set v = FirstOfGroup(g)
exitwhen v == null
if IsUnitEnemy(v,GetOwningPlayer(c)) == true and IsUnitType(v,UNIT_TYPE_STRUCTURE) == false and GetWidgetLife(v) > 0.45 and GetUnitAbilityLevel(c,'Avul') <= 0 and IsUnitInGroup(v,go) == false then
call UnitDamageTarget(c,v,damage(),true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_MAGIC,null)
if IsUnitInGroup(v,go) == false then
call GroupAddUnit(go,v)
endif
endif
call GroupRemoveUnit(g,v)
endloop
call GroupClear(g)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),FIRAGA,xx,yy,a)
call SetUnitScale(bj_lastCreatedUnit,2,2,2)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),MEGABLAST,xx,yy,a)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYBOMB,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,3.5,3.5,3.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call DestroyEffect(AddSpecialEffect(EFFECT2,xx,yy))
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SKYRING,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,1,1,1)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),ICENOVA,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,1.5,1.5,1.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call DestroyGroup(g)
call DestroyGroup(go)
endif
set count = count - 1
if count <= 0 then
call ReleaseTimer(z)
call .destroy()
endif
set g = null
set go = null
endmethod
static method onAction3 takes nothing returns nothing
local timer z = GetExpiredTimer()
call TimerStart(z,0.2,true,function data.onAction)
endmethod
static method onAction2 takes nothing returns nothing
local timer z = GetExpiredTimer()
local data this = GetTimerData(z)
local real a = Angle(GetUnitX(c),GetUnitY(c),targetx,targety)
local real x = PolarX(GetUnitX(c),50,a)
local real y = PolarY(GetUnitY(c),50,a)
local real xx = PolarX(x,460,a + 90)
local real yy = PolarY(y,460,a + 90)
local real xx2 = PolarX(x,325,a + 90)
local real yy2 = PolarY(y,325,a + 90)
set l[1] = AddLightningEx("SPLK",true,xx,yy,95,xx2,yy2,230)
set xx = PolarX(x,200,a + 90)
set yy = PolarY(y,200,a + 90)
set l[2] = AddLightningEx("SPLK",true,xx2,yy2,230,xx,yy,220)
set xx2 = PolarX(x,180,a + 90)
set yy2 = PolarY(y,180,a + 90)
set l[3] = AddLightningEx("SPLK",true,xx,yy,220,xx2,yy2,95)
set xx = PolarX(x,0,a + 90)
set yy = PolarY(y,0,a + 90)
set l[4] = AddLightningEx("SPLK",true,xx2,yy2,95,xx,yy,65)
set xx2 = PolarX(x,180,a - 90)
set yy2 = PolarY(y,180,a - 90)
set l[5] = AddLightningEx("SPLK",true,xx,yy,65,xx2,yy2,140)
set xx = PolarX(x,450,a - 90)
set yy = PolarY(y,450,a - 90)
set l[6] = AddLightningEx("SPLK",true,xx2,yy2,140,xx,yy,250)
call TimerStart(z,1,false,function data.onAction3)
endmethod
static method onAction1 takes nothing returns nothing
local timer z = GetExpiredTimer()
local data this = GetTimerData(z)
local real a = Angle(GetUnitX(c),GetUnitY(c),targetx,targety)
local real x = PolarX(GetUnitX(c),50,a)
local real y = PolarY(GetUnitY(c),50,a)
local real xx = PolarX(x,460,a + 90)
local real yy = PolarY(y,460,a + 90)
set e[1] = CreateUnit(GetOwningPlayer(c),MAGICCIRCLE90,xx,yy,a)
call SetUnitFlyHeight(e[1],95,95)
set xx = PolarX(x,325,a + 90)
set yy = PolarY(y,325,a + 90)
set e[2] = CreateUnit(GetOwningPlayer(c),MAGICCIRCLE90,xx,yy,a)
call SetUnitFlyHeight(e[2],230,230)
set xx = PolarX(x,200,a + 90)
set yy = PolarY(y,200,a + 90)
set e[3] = CreateUnit(GetOwningPlayer(c),MAGICCIRCLE90,xx,yy,a)
call SetUnitFlyHeight(e[3],220,220)
set xx = PolarX(x,180,a + 90)
set yy = PolarY(y,180,a + 90)
set e[4] = CreateUnit(GetOwningPlayer(c),MAGICCIRCLE90,xx,yy,a)
call SetUnitFlyHeight(e[5],95,95)
set xx = PolarX(x,0,a + 90)
set yy = PolarY(y,0,a + 90)
set e[5] = CreateUnit(GetOwningPlayer(c),MAGICCIRCLE90,xx,yy,a)
call SetUnitFlyHeight(e[5],65,65)
set xx = PolarX(x,180,a - 90)
set yy = PolarY(y,180,a - 90)
set e[6] = CreateUnit(GetOwningPlayer(c),MAGICCIRCLE90,xx,yy,a)
call SetUnitFlyHeight(e[6],140,140)
set xx = PolarX(x,450,a - 90)
set yy = PolarY(y,450,a - 90)
set e[7] = CreateUnit(GetOwningPlayer(c),MAGICCIRCLE90,xx,yy,a)
call SetUnitFlyHeight(e[7],250,250)
call TimerStart(z,1,true,function data.onAction2)
endmethod
static method create takes unit caster, real x, real y returns thistype
local data this = data.allocate()
local timer z = NewTimer()
call SetSoundPosition(gg_snd_GrandChariot,x,y,0)
call StartSound(gg_snd_GrandChariot)
set c = caster
set targetx = x
set targety = y
call SetUnitTimeScale(c,0)
call PauseUnit(c,true)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SHADOW,GetUnitX(c),GetUnitY(c),270)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',5)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SHADOW,GetUnitX(c),GetUnitY(c),90)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',5)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SHADOW,GetUnitX(c),GetUnitY(c),90)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',5)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SHADOW,GetUnitX(c),GetUnitY(c),90)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',5)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),GALAXY,GetUnitX(c),GetUnitY(c),90)
call SetUnitTimeScale(bj_lastCreatedUnit,2)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',5)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SHADOW,targetx,targety,270)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',5)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SHADOW,targetx,targety,90)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',5)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SHADOW,targetx,targety,90)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',5)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SHADOW,targetx,targety,90)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',5)
call SetTimerData(z,this)
call TimerStart(z,0.05,false,function data.onAction1)
return this
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SPELLID
endfunction
private function Actions takes nothing returns nothing
call data.create(GetTriggerUnit(),GetSpellTargetX(),GetSpellTargetY())
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer index
set index = 0
call Preload("war3mapImported\\Skyraga.mdx")
loop
call TriggerRegisterPlayerUnitEvent(t, Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t,Condition(function Conditions))
call TriggerAddAction(t,function Actions)
set t = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope Altairis initializer init
globals
private constant integer SPELLID = 'A002' // Raw code of spell id
private constant integer DARKHOLE = 'h009' // Raw code of dummy model
private constant integer GALAXY2 = 'h00M' // Raw code of dummy model
private constant integer VOIDDROWN = 'h00O' // Raw code of dummy model
private constant integer FIRAGA = 'h00P' // Raw code of dummy model
private constant integer DUST = 'h004' // Raw code of dummy model
private constant integer SHADOWBALL = 'h00Q' // Raw code of dummy model
private constant integer SUPERBIGEXPLOSION = 'h00R' // Raw code of dummy model
private constant real RADIUS = 180 // Radius of dark hole ball will pick unit
private constant real DURATION = 4 // Duration of Blasting
endglobals
private struct data
unit c
unit d
unit e
real a
real scale = 0.3
real time = 2.75
real xx
real yy
group go
integer animate = 0
method destroy takes nothing returns nothing
call RemoveUnit(d)
call RemoveUnit(e)
call .deallocate()
endmethod
method damage takes nothing returns real
local real r = GetUnitAbilityLevel(c,SPELLID) * 100 // deal 100 damage per level of ability per second
return r
endmethod
static method onBlast takes nothing returns nothing
local timer z = GetExpiredTimer()
local data this = GetTimerData(z)
local group g = CreateGroup()
local unit v
set animate = animate + 1
call GroupEnumUnitsInRange(g,xx,yy,RADIUS + 200,null)
loop
set v = FirstOfGroup(g)
exitwhen v == null
if IsUnitEnemy(v,GetOwningPlayer(c)) == true and IsUnitType(v,UNIT_TYPE_STRUCTURE) == false and GetWidgetLife(v) > 0.45 and GetUnitAbilityLevel(c,'Avul') <= 0 then
call PauseUnit(v,true)
call UnitDamageTarget(c,v,damage() / 25,true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_MAGIC,null)
if IsUnitInGroup(v,go) == false then
call GroupAddUnit(go,v)
endif
endif
call GroupRemoveUnit(g,v)
endloop
if animate >= 5 then
set animate = 0
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),VOIDDROWN,xx,yy,0)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SUPERBIGEXPLOSION,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,1.7,1.7,1.7)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1.2)
endif
set time = time - 0.05
if time <= 0 then
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),FIRAGA,xx,yy,0)
call SetUnitScale(bj_lastCreatedUnit,4.5,4.5,4.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
loop
set v = FirstOfGroup(go)
exitwhen v == null
call PauseUnit(v,false)
call GroupRemoveUnit(go,v)
endloop
call DestroyGroup(go)
set go = null
call ReleaseTimer(z)
call .destroy()
endif
endmethod
static method onAction takes nothing returns nothing
local timer z = GetExpiredTimer()
local data this = GetTimerData(z)
local real x = PolarX(GetUnitX(d),40,a)
local real y = PolarY(GetUnitY(d),40,a)
local group g = CreateGroup()
local unit v
local integer count = 0
if IsTerrainPathable(x,y,PATHING_TYPE_FLYABILITY) == false then
call SetUnitPosition(d,x,y)
call SetUnitPosition(e,x,y)
endif
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),DUST,GetUnitX(d),GetUnitY(d),0)
call SetUnitScale(bj_lastCreatedUnit,3,3,3)
call SetUnitVertexColor(bj_lastCreatedUnit,255,255,255,5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call GroupEnumUnitsInRange(g,GetUnitX(d),GetUnitY(d),RADIUS,null)
loop
set v = FirstOfGroup(g)
exitwhen v == null
if IsUnitEnemy(v,GetOwningPlayer(c)) == true and IsUnitType(v,UNIT_TYPE_STRUCTURE) == false and GetWidgetLife(v) > 0.45 and GetUnitAbilityLevel(c,'Avul') <= 0 then
set count = count + 1
set xx = GetUnitX(v)
set yy = GetUnitY(v)
exitwhen true
endif
call GroupRemoveUnit(g,v)
endloop
if count >= 1 then
set time = DURATION
call ShakeGroupCamera(3,xx,yy,1400,10)
call PauseUnit(c,false)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SHADOWBALL,xx,yy,0)
call SetUnitVertexColor(bj_lastCreatedUnit,255,255,255,200)
call SetUnitScale(bj_lastCreatedUnit,2,2,2)
call SetUnitTimeScale(bj_lastCreatedUnit,2)
call SetUnitAnimation(bj_lastCreatedUnit,"birth")
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',3.3)
call SetUnitPosition(d,xx,yy)
call SetUnitScale(d,1.75,1.75,1.75)
call SetUnitPosition(e,xx,yy)
call TimerStart(z,0.04,true,function data.onBlast)
else
set time = time - 0.04
if time == 3 then
call PauseUnit(c,false)
endif
if time <= 0 then
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),SHADOWBALL,GetUnitX(d),GetUnitY(d),0)
call SetUnitVertexColor(bj_lastCreatedUnit,255,255,255,255)
call SetUnitScale(bj_lastCreatedUnit,1.8,1.8,1.8)
call SetUnitAnimation(bj_lastCreatedUnit,"death")
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call ReleaseTimer(z)
call .destroy()
endif
endif
endmethod
static method onAction3 takes nothing returns nothing
local timer z = GetExpiredTimer()
local data this = GetTimerData(z)
call SetUnitAnimation(c,"spell channel five")
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),DUST,GetUnitX(c),GetUnitY(c),0)
call SetUnitScale(bj_lastCreatedUnit,4,4,4)
call SetUnitVertexColor(bj_lastCreatedUnit,255,255,255,5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call SetUnitFlyHeight(d,0,150)
call TimerStart(z,0.04,true,function data.onAction)
endmethod
static method onAction2 takes nothing returns nothing
local timer z = GetExpiredTimer()
local data this = GetTimerData(z)
set time = time - 0.04
set scale = scale + 0.01
call SetUnitScale(d,scale,scale,0)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),VOIDDROWN,GetUnitX(c),GetUnitY(c),0)
call SetUnitScale(bj_lastCreatedUnit,1.5,1.5,1.5)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',0.5)
if time == 1 then
call SetUnitAnimation(c,"spell channel two")
endif
if time <= 0 then
set time = 4
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),VOIDDROWN,GetUnitX(c),GetUnitY(c),0)
call SetUnitScale(bj_lastCreatedUnit,2,2,2)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1.6)
call TimerStart(z,1.5,false,function data.onAction3)
endif
endmethod
static method onAction1 takes nothing returns nothing
local timer z = GetExpiredTimer()
local data this = GetTimerData(z)
set d = CreateUnit(GetOwningPlayer(c),DARKHOLE,GetUnitX(c),GetUnitY(c),a)
call SetUnitFlyHeight(d,150,0)
call SetUnitScale(d,scale,scale,scale)
call SetUnitAnimation(c,"spell channel one")
call TimerStart(z,0.04,true,function data.onAction2)
endmethod
static method create takes unit caster, real angle returns thistype
local data this = data.allocate()
local timer z = NewTimer()
set c = caster
set a = angle
call SetSoundPosition(gg_snd_Altirias,GetUnitX(c),GetUnitY(c),0)
call StartSound(gg_snd_Altirias)
set go = CreateGroup()
call PauseUnit(c,true)
set e = CreateUnit(GetOwningPlayer(c),GALAXY2,GetUnitX(c),GetUnitY(c),a)
call SetUnitVertexColor(e,255,255,255,100)
call SetUnitTimeScale(e,2)
call SetUnitScale(e,0.65,0.65,0.65)
call SetUnitFlyHeight(e,0,150)
call UnitApplyTimedLife(e,'BTLF',5)
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(c),DUST,GetUnitX(c),GetUnitY(c),0)
call SetUnitScale(bj_lastCreatedUnit,4,4,4)
call SetUnitVertexColor(bj_lastCreatedUnit,255,255,255,10)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',1)
call SetTimerData(z,this)
call TimerStart(z,0.05,false,function data.onAction1)
return this
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SPELLID
endfunction
private function Actions takes nothing returns nothing
call data.create(GetTriggerUnit(),Angle(GetUnitX(GetTriggerUnit()),GetUnitY(GetTriggerUnit()),GetSpellTargetX(),GetSpellTargetY()))
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer index
set index = 0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t,Condition(function Conditions))
call TriggerAddAction(t,function Actions)
set t = null
endfunction
endscope