scope ExpandingSphere
globals
private constant integer AbilityID = 'A000'
private constant real Interval = XE_ANIMATION_PERIOD
private constant real Height = 60
private constant integer MaxInstances = 8190
private constant string LightningType = "DRAB"
private constant real Length = 90
private constant real LengthAdd = 0
private constant real SpinSpeed = 0.11
private constant real SpinSpeedAdd = 0
private constant real LightningColorR = 1
private constant real LightningColorG = 1
private constant real LightningColorB = 1
private constant real LightningColorA = 1
private constant string BallModel = "Abilities\\Spells\\Other\\Parasite\\ParasiteMissile.mdl"
private constant real StartScale = 0.2
private constant real StartScaleAdd = 0
private constant real GrowScale = 0.09
private constant real GrowScaleAdd = 0
private constant real MaxScale = 18
private constant real MaxScaleAdd = 0
private constant integer BallColorR = 255
private constant integer BallColorG = 255
private constant integer BallColorB = 255
private constant integer BallColorA = 255
private constant string EndEffect = "Objects\\Spawnmodels\\Undead\\UDeathMedium\\UDeath.mdl"
private constant real EndScale = 1.6
private constant real EndScaleAdd = 0
private constant real EndZ = 100
private constant real EndZAdd = 0
private constant real EndTimeAfter = 1
private constant real EndTimeAfterAdd = 0
private constant integer EndColorR = 255
private constant integer EndColorG = 255
private constant integer EndColorB = 255
private constant integer EndColorA = 255
private constant real Range = 240
private constant real RangeAdd = 0
private constant real Damage = 200
private constant real DamageAdd = 100
//! textmacro ExpandingSphereDamageSettings
set .dtype = DAMAGE_TYPE_MAGIC
set .atype = ATTACK_TYPE_HERO
set .damageTrees = true
set .damageNeutral = false
//! endtextmacro
endglobals
//! textmacro ExpandingSphereStart
debug call BJDebugMsg("|cffFFCC00"+GetUnitName(.caster)+"|r starts to cast 'Expanding Sphere'")
//! endtextmacro
//! textmacro ExpandingSpherePeriodic
debug call BJDebugMsg("Periodic event of 'Expanding Sphere' (casted by |cffFFCC00"+GetUnitName(.caster)+"|r)")
//! endtextmacro
//! textmacro ExpandingSphereEnd
debug call BJDebugMsg("|cffFFCC00"+GetUnitName(.caster)+"|r finished casting 'Expanding Sphere'")
//! endtextmacro
private struct ES[MaxInstances]
real array x[17]
real array y[17]
real array z[17]
unit caster
lightning array l[16]
integer level
real scale
real radians = 0
real array dist[16]
delegate xefx ball
static delegate xedamage dmg
static location loc = Location(0,0)
static method create takes unit caster, real x, real y returns ES
local ES this = ES.allocate()
set .caster = caster
set .level = GetUnitAbilityLevel(caster,AbilityID)-1
set .scale = StartScale+StartScaleAdd*.level
set .x[16] = x
set .y[16] = y
set .ball = xefx.create(x,y,0)
set .fxpath = BallModel
set .red = EndColorR
set .green = EndColorG
set .blue = EndColorB
set .alpha = EndColorA
set .dist[0] = -(Length + LengthAdd*.level)/2
set .x[0] = x + .dist[0]
set .y[0] = y
return this
endmethod
static method EndSpell takes nothing returns nothing
local ES this = GetTimerData(GetExpiredTimer())
//! runtextmacro ExpandingSphereEnd()
call ReleaseTimer(GetExpiredTimer())
call .ball.destroy()
call .destroy()
endmethod
static method Loop takes nothing returns nothing
local timer t = GetExpiredTimer()
local ES this = GetTimerData(t)
local integer i = 1
local xefx EndSFX
//! runtextmacro ExpandingSpherePeriodic()
set .ball.scale = .scale
set .scale = .scale + GrowScale+GrowScaleAdd*.level
if .scale >= MaxScale + MaxScaleAdd*.level then
call PauseTimer(t)
set EndSFX = xefx.create(.x[16],.y[16],0)
set EndSFX.fxpath = EndEffect
set EndSFX.z = EndZ+EndZAdd*.level
set EndSFX.scale = EndScale+EndScaleAdd*.level
set EndSFX.red = EndColorR
set EndSFX.green = EndColorG
set EndSFX.blue = EndColorB
set EndSFX.alpha = EndColorA
set i = 0
loop
call DestroyLightning(.l[i])
set i = i + 1
exitwhen i == 16
endloop
if Damage+DamageAdd*.level > 0 then
call .damageAOE(.caster,.x[16],.y[16],Range+RangeAdd*.level,Damage+DamageAdd*.level)
endif
call TimerStart(t,EndTimeAfter+EndTimeAfterAdd*.level,false,function ES.EndSpell)
return
endif
set .x[0] = .x[16]+ .dist[0]*Sin(.radians)
set .y[0] = .y[16]+ .dist[0]*Cos(.radians)
loop
if i <= 7 then
set .x[i] = .x[16]+ .dist[i]*Sin(.radians)
set .y[i] = .y[16]+ .dist[i]*Cos(.radians)
call MoveLightningEx(.l[i-1],true,.x[i],.y[i],.z[i],.x[i-1],.y[i-1],.z[i-1])
elseif i == 8 then
set .y[i] = .y[16]+ .dist[i]*Sin(.radians)
set .z[i] = .z[16]+ .dist[i]*Cos(.radians)
call MoveLightningEx(.l[i-1],true,.x[0],.y[0],.z[0],.x[i-1],.y[i-1],.z[i-1])
else
set .y[i] = .y[16]+ .dist[i]*Sin(.radians)
set .z[i] = .z[16]+ .dist[i]*Cos(.radians)
call MoveLightningEx(.l[i-1],true,.x[i],.y[i],.z[i],.x[i-1],.y[i-1],.z[i-1])
endif
set i = i + 1
exitwhen i >= 16
endloop
call MoveLightningEx(.l[15],true,.x[8],.y[8],.z[8],.x[15],.y[15],.z[15])
set .radians = .radians + SpinSpeed+SpinSpeedAdd*.level
endmethod
static method StartSpell takes nothing returns nothing
local ES this = ES.create(GetTriggerUnit(),GetSpellTargetX(),GetSpellTargetY())
local timer t = NewTimer()
local integer i = 1
//! runtextmacro ExpandingSphereStart()
call MoveLocation(.loc,.x[16],.y[16])
set .z[16] = GetLocationZ(.loc)
call SetTimerData(t,this)
set .z[0] = .z[16] + Height
set .ball.z = (Length + LengthAdd*.level)/2 + SquareRoot(((Length + LengthAdd*.level)*(Length + LengthAdd*.level))/2) + Height
set .z[16] = .z[16]+.ball.z
loop
if i <= 7 then
set .x[i] = .x[i-1] + (Length+LengthAdd*.level)*Cos(bj_PI/4*(i-1))
set .y[i] = .y[16]
set .z[i] = .z[i-1] + (Length+LengthAdd*.level)*Sin(bj_PI/4*(i-1))
set .l[i-1] = AddLightningEx(LightningType,true,.x[i],.y[i],.z[i],.x[i-1],.y[i-1],.z[i-1])
set .dist[i] = .x[i]-.x[16]
elseif i == 8 then
set .x[i] = .x[16] - (Length + LengthAdd*.level)/2
set .y[i] = .y[16] - (Length + LengthAdd*.level)/2 - SquareRoot(((Length + LengthAdd*.level)*(Length + LengthAdd*.level))/2)
set .z[i] = .z[16]
set .l[i-1] = AddLightningEx(LightningType,true,.x[0],.y[0],.z[0],.x[i-1],.y[i-1],.z[i-1])
set .dist[i] = .y[i]-.y[16]
else
set .x[i] = .x[i-1] + (Length+LengthAdd*.level)*Cos(bj_PI/4*(i-1))
set .y[i] = .y[i-1] + (Length+LengthAdd*.level)*Sin(bj_PI/4*(i-1))
set .z[i] = .z[8]
set .l[i-1] = AddLightningEx(LightningType,true,.x[i],.y[i],.z[i],.x[i-1],.y[i-1],.z[i-1])
set .dist[i] = .y[i]-.y[16]
endif
call SetLightningColor(.l[i-1],LightningColorR,LightningColorG,LightningColorB,LightningColorA)
set i = i + 1
exitwhen i >= 16
endloop
set .l[15] = AddLightningEx(LightningType,true,.x[15],.y[15],.z[15],.x[8],.y[8],.z[8])
call SetLightningColor(.l[15],LightningColorR,LightningColorG,LightningColorB,LightningColorA)
call TimerStart(t,Interval,true,function ES.Loop)
endmethod
static method onInit takes nothing returns nothing
local trigger tr = CreateTrigger()
call XE_PreloadAbility(AbilityID)
call TriggerRegisterAnyUnitEventBJ(tr,EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition(tr,Condition(function ES.IsSpell))
call TriggerAddAction(tr,function ES.StartSpell)
set tr = null
set .dmg = xedamage.create()
//! runtextmacro ExpandingSphereDamageSettings()
endmethod
static method IsSpell takes nothing returns boolean
return GetSpellAbilityId() == AbilityID
endmethod
endstruct
endscope