[/FONT]
// ********************************************************
// *
// * Chaosflare Orb v1.4
// * by Quilnez
// *
// * Description:
// * Summons the Chaosflare Orb at target point which
// * triggers the sky to periodically strike upon it
// * with powerful lightnings. The orb will convert it
// * into smaller electric pulses which will be released
// * at random direction. Enemy units got hit by these
// * pulses will receive minor damage and will be slowed
// * for a short duration.
// *
// * Requirement(s):
// * None
// *
// * How to import:
// * • Copy "Chaosflare Orb" trigger group to your map
// * • Delete variable creator trigger
// * • Export all necessary import data to your map
// * • Copy dummy unit (Object Editor) to your map
// * • Copy abilities and buff (Object Editor) to your map
// * • Configure the spell
// *
// * Credits:
// * • BTNDarkSphere By Darkfang
// * • Dark Lightning.mdx By JetFangInferno
// * • HydraLightingOrbGroundEffectV044.mdx By kellym0
// * • LightningStrikeLarge.mdx By Callahan
// * • Haunt.mdx By nGy
// * • Shockwave.mdx By Vestras
// * • VoidSkullAura_v5.mdx By xyzier_24
// * (All models are edited to fulfill the
// * needs of this spell)
// *
// ********************************************************
// ********************************************************
// * Configuration
// *
// * Dummy unit's raw code at object editor
constant function CfO__DummyID takes nothing returns integer
return 'h000'
endfunction
// *
// * Main ability's raw code at object editor
constant function CfO__SpellID takes nothing returns integer
return 'A000'
endfunction
// *
// * Slow ability's raw code at object editor
constant function CfO__SlowSpellID takes nothing returns integer
return 'A001'
endfunction
// *
// * Slow buff's raw code at object editor
constant function CfO__SlowBuffID takes nothing returns integer
return 'B000'
endfunction
// *
// * Main ability's order id
constant function CfO__OrderID takes nothing returns integer
return 852089 // blizzard
endfunction
// *
// * Slow ability's order id
constant function CfO__SlowSpellOrderID takes nothing returns integer
return 852096 // thunderclap
endfunction
// *
// * If true, the spell will be canceled if caster is given another order
constant function CfO__Channeling takes nothing returns boolean
return true
endfunction
// *
// * If true, the slow duration will be stackable
constant function CfO__Stacking takes nothing returns boolean
return true
endfunction
// *
// * Lightning strike effect model path
constant function CfO__LightningFX takes nothing returns string
return "war3mapImported\\DarkLightning.mdx"
endfunction
// *
// * Orb's aura effect model path
constant function CfO__AuraFX takes nothing returns string
return "war3mapImported\\VoidSkullAura_v5.mdx"
endfunction
// *
// * Wave effect model path (lightning strikes the ground)
constant function CfO__WaveFX takes nothing returns string
return "war3mapImported\\Shockwave.mdx"
endfunction
// *
// * Orb model path
constant function CfO__OrbFX takes nothing returns string
return "war3mapImported\\Haunt_v2.mdx"
endfunction
// *
// * Missile model path
constant function CfO__MissileFX takes nothing returns string
return "war3mapImported\\HydraLightingOrbGroundEffectV044.mdx"
endfunction
// *
// * Hit effect model path
constant function CfO__HitFX takes nothing returns string
return "war3mapImported\\ShockTarget.mdx"
endfunction
// *
// * Hit effect attachment point
constant function CfO__HitFXPt takes nothing returns string
return "origin"
endfunction
// *
// * Missile's launch Z height
constant function CfO__MissileHeight takes nothing returns real
return 15.0
endfunction
// *
// * Missile's scale
constant function CfO__MissileSize takes nothing returns real
return 1.0
endfunction
// *
// * Minimum delay for missiles to turn
constant function CfO__MissileTurnDelayMin takes nothing returns real
return 0.075
endfunction
// *
// * Maximum delay for missiles to turn
constant function CfO__MissileTurnDelayMax takes nothing returns real
return 0.5
endfunction
// *
// * Minimum turn amount (in radians) for missiles
constant function CfO__MissileTurnAmountMin takes nothing returns real
return 45.0*bj_DEGTORAD
endfunction
// *
// * Maximum turn amount (in radians) for missiles
constant function CfO__MissileTurnAmountMax takes nothing returns real
return 180.0*bj_DEGTORAD
endfunction
// *
// * How fast missiles may turn
constant function CfO__MissileTurnRate takes nothing returns real
return 10.0*bj_DEGTORAD
endfunction
// *
// * Orb's scale
constant function CfO__OrbSize takes nothing returns real
return 1.0
endfunction
// *
// * Orb's spawn Z height
constant function CfO__OrbHeight takes nothing returns real
return 150.0
endfunction
// *
// * Orb's aura's scale
constant function CfO__AuraSize takes nothing returns real
return 1.5
endfunction
// *
// * Orb's aura's Z height
constant function CfO__AuraHeight takes nothing returns real
return 0.0
endfunction
// *
// * Maximum range for misilles to hit a target
constant function CfO__HitRadius takes nothing returns real
return 100.0
endfunction
// *
// * Better to leave this one as it is
constant function CfO__Interval takes nothing returns real
return 0.03125
endfunction
// *
// * Spread factor for missile launching, must be between 0 - 1
constant function CfO__Accuracy takes nothing returns real
return 0.25
endfunction
// *
// * If true, each missile will home for one target
constant function CfO__Homing takes integer level returns boolean
return false
endfunction
// *
// * If true, each missile will look for another target after a hit
constant function CfO__SmartHoming takes nothing returns boolean
return false
endfunction
// *
// * Maximum range for missile to obtain a target
constant function CfO__DetectRadius takes integer level returns real
return 200.0
endfunction
// *
// * Delay before another lightning strikes the orb
constant function CfO__StrikeDelay takes integer level returns real
return 2.5
endfunction
// *
// * Delay between the strike and before the missiles are launched
constant function CfO__ReleaseDelay takes integer level returns real
return 0.375
endfunction
// *
// * Speed of missiles
constant function CfO__Velocity takes integer level returns real
return 30.0
endfunction
// *
// * Minimum wander distance for every missile
constant function CfO__DistanceMin takes integer level returns real
return 800.0
endfunction
// *
// * Maximum wander distance for every missile
constant function CfO__DistanceMax takes integer level returns real
return 1600.0
endfunction
// *
// * Damage dealt on hit
constant function CfO__Damage takes integer level returns real
return 15.0 * level
endfunction
// *
// * Orb's lifespan
constant function CfO__Duration takes integer level returns real
return 15.0
endfunction
// *
// * Number of missiles releashed per strike
constant function CfO__ReleaseCount takes integer level returns integer
return 4 + 2 * level
endfunction
// *
// * Slow duration
constant function CfO__SlowDuration takes integer level returns real
return 1.5
endfunction
// *
// * Attack type of dealt damage
constant function CfO__AttackType takes nothing returns attacktype
return ATTACK_TYPE_MAGIC
endfunction
// *
// * Damage type of dealt damage
constant function CfO__DamageType takes nothing returns damagetype
return DAMAGE_TYPE_LIGHTNING
endfunction
// *
// * Weapon type of dealt damage
constant function CfO__WeaponType takes nothing returns weapontype
return WEAPON_TYPE_WHOKNOWS
endfunction
// *
// * No need to touch this
function CfO__isAlive takes unit id returns boolean
return GetWidgetLife(id) > 0.405 and not IsUnitType(id, UNIT_TYPE_DEAD)
endfunction
// *
// * Classification of unit that can be a victim of the missiles
function CfO__Targets takes unit target, player source returns boolean
return CfO__isAlive(target) and IsUnitEnemy(target, source) and not(IsUnitType(target, UNIT_TYPE_STRUCTURE) or IsUnitType(target, UNIT_TYPE_MECHANICAL) or IsUnitType(target, UNIT_TYPE_FLYING) or IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE))
endfunction
// *
// * This is where you can do additional actions on damage event (missile hits a target)
function CfO__OnDamage takes unit target, unit caster, integer level returns nothing
endfunction
// *
// * This is where you can do additional actions when an orb is struck by lightning
// * caster = spell's caster, level = spell's level, x & y = location where the spell is located
function CfO__OnStrike takes unit caster, integer level, real x, real y returns nothing
endfunction
// *
// * This is where you can do additional actions when missiles are going to be released
// * caster = spell's caster, level = spell's level, x & y = location where the spell is located
function CfO__OnRelease takes unit caster, integer level, real x, real y returns nothing
endfunction
// *
// * This is where you can do additional actions before the spell is ended
// * caster = spell's caster, level = spell's level, x & y = location where the spell is located
function CfO__OnDispose takes unit caster, integer level, real x, real y returns nothing
endfunction
// *
// * This is where you can do additional actions before a missile is removed
// * caster = spell's caster, level = spell's level, x & y = location of the missile
function CfO__OnMissileDispose takes unit caster, integer level, real x, real y returns nothing
endfunction
// *
// * End of Configuration
// *
// ********************************************************
// Check whether passed coordinate is inside the world or not
function CfO__isInBound takes real x, real y returns boolean
return x > udg_CfO__WorldBounds[0] and x < udg_CfO__WorldBounds[1] and y > udg_CfO__WorldBounds[2] and y < udg_CfO__WorldBounds[3]
endfunction
// Allows custom filter by user to be used by unit enumeration filter
function CfO__filter takes nothing returns boolean
return CfO__Targets(GetFilterUnit(), udg_CfO__Owner[udg_CfO__Missile__Source[udg_CfO__TempInt]]) and not IsUnitInGroup(GetFilterUnit(), udg_CfO__Missile__Targets[udg_CfO__TempInt])
endfunction
function CfO__slow takes nothing returns nothing
local integer c
local integer h
local integer i = 1
local boolean dispose
loop
exitwhen i > udg_CfO__Slow__Count
set dispose = false
if CfO__isAlive(udg_CfO__Slow__Target[i]) then
set udg_CfO__Slow__Duration[i] = udg_CfO__Slow__Duration[i] - CfO__Interval()
if udg_CfO__Slow__Duration[i] <= 0 then
set h = GetHandleId(udg_CfO__Slow__Target[i])
if CfO__Stacking() then
set dispose = true
call SaveInteger(udg_CfO__Hashtable, h, 1, 0)
else
set c = LoadInteger(udg_CfO__Hashtable, h, 1) - 1
call SaveInteger(udg_CfO__Hashtable, h, 1, c)
if c == 0 then
set dispose = true
endif
endif
endif
else
set dispose = true
endif
if dispose then
call UnitRemoveAbility(udg_CfO__Slow__Target[i], CfO__SlowBuffID())
set udg_CfO__Slow__Target[i] = udg_CfO__Slow__Target[udg_CfO__Slow__Count]
set udg_CfO__Slow__Duration[i] = udg_CfO__Slow__Duration[udg_CfO__Slow__Count]
set udg_CfO__Slow__Target[udg_CfO__Slow__Count] = null
set udg_CfO__Slow__Count = udg_CfO__Slow__Count - 1
if udg_CfO__Slow__Count == 0 then
call PauseTimer(udg_CfO__Slow__Timer)
else
set i = i - 1
endif
endif
set i = i + 1
endloop
endfunction
function CfO__applySlow takes integer source, unit target returns nothing
local integer h
local integer c
set h = GetHandleId(target)
if CfO__Stacking() then
set c = LoadInteger(udg_CfO__Hashtable, h, 1)
if c == 0 then
set udg_CfO__Slow__Count = udg_CfO__Slow__Count + 1
set udg_CfO__Slow__Target[udg_CfO__Slow__Count] = target
set udg_CfO__Slow__Duration[udg_CfO__Slow__Count] = CfO__SlowDuration(udg_CfO__Level[source])
call SetUnitX(udg_CfO__Slow__Caster, GetUnitX(target))
call SetUnitY(udg_CfO__Slow__Caster, GetUnitY(target))
call IssueImmediateOrderById(udg_CfO__Slow__Caster, CfO__SlowSpellOrderID())
call SaveInteger(udg_CfO__Hashtable, h, 1, udg_CfO__Slow__Count)
else
set udg_CfO__Slow__Duration[c] = udg_CfO__Slow__Duration[c] + CfO__SlowDuration(udg_CfO__Level[source])
endif
else
set udg_CfO__Slow__Count = udg_CfO__Slow__Count + 1
set udg_CfO__Slow__Target[udg_CfO__Slow__Count] = target
set udg_CfO__Slow__Duration[udg_CfO__Slow__Count] = CfO__SlowDuration(udg_CfO__Level[source])
set c = LoadInteger(udg_CfO__Hashtable, h, 1) + 1
call SaveInteger(udg_CfO__Hashtable, h, 1, c)
if c == 1 then
call SetUnitX(udg_CfO__Slow__Caster, GetUnitX(target))
call SetUnitY(udg_CfO__Slow__Caster, GetUnitY(target))
call IssueImmediateOrderById(udg_CfO__Slow__Caster, CfO__SlowSpellOrderID())
endif
endif
if udg_CfO__Slow__Count == 1 then
call TimerStart(udg_CfO__Slow__Timer, CfO__Interval(), true, function CfO__slow)
endif
endfunction
// Periodic callback for missiles
function CfO__missile takes nothing returns nothing
local integer i = 1
local boolean dispose
local unit fog
loop
exitwhen i > udg_CfO__Missile__Count
set dispose = false
if udg_CfO__Missile__Distance[i] > udg_CfO__Velocity[udg_CfO__Missile__Source[i]] and CfO__isAlive(udg_CfO__Caster[udg_CfO__Missile__Source[i]]) then
// If don't have valid target
if udg_CfO__Missile__Target[i] == null or not CfO__isAlive(udg_CfO__Missile__Target[i]) then
if udg_CfO__Missile__TurnDelay[i] > CfO__Interval() then
set udg_CfO__Missile__TurnDelay[i] = udg_CfO__Missile__TurnDelay[i] - CfO__Interval()
else
set udg_CfO__Missile__TurnDelay[i] = GetRandomReal(CfO__MissileTurnDelayMin(), CfO__MissileTurnDelayMax())
set udg_CfO__Missile__AngleX[i] = udg_CfO__Missile__Angle[i] + GetRandomReal(CfO__MissileTurnAmountMin(), CfO__MissileTurnAmountMax()) * GetRandomInt(-1, 1)
endif
if CfO__Homing(udg_CfO__Level[udg_CfO__Missile__Source[i]]) then
set udg_CfO__TempInt = i
call GroupEnumUnitsInRange(udg_CfO__TempGroup, udg_CfO__Missile__X[i], udg_CfO__Missile__Y[i], CfO__DetectRadius(udg_CfO__Level[udg_CfO__Missile__Source[i]]), Filter(function CfO__filter))
set udg_CfO__Missile__Target[i] = GroupPickRandomUnit(udg_CfO__TempGroup)
call GroupClear(udg_CfO__TempGroup)
endif
else
// Set target angle to the location of target
set udg_CfO__Missile__AngleX[i] = Atan2(GetUnitY(udg_CfO__Missile__Target[i]) - udg_CfO__Missile__Y[i], GetUnitX(udg_CfO__Missile__Target[i]) - udg_CfO__Missile__X[i])
endif
// Adjust missile's angle to the target
if CfO__MissileTurnRate() > 0 and Cos(udg_CfO__Missile__Angle[i]-udg_CfO__Missile__AngleX[i]) < Cos(CfO__MissileTurnRate()) then
if Sin(udg_CfO__Missile__AngleX[i]-udg_CfO__Missile__Angle[i]) >= 0 then
set udg_CfO__Missile__Angle[i] = udg_CfO__Missile__Angle[i] + CfO__MissileTurnRate()
else
set udg_CfO__Missile__Angle[i] = udg_CfO__Missile__Angle[i] - CfO__MissileTurnRate()
endif
else
set udg_CfO__Missile__Angle[i] = udg_CfO__Missile__AngleX[i]
endif
set udg_CfO__Missile__X[i] = udg_CfO__Missile__X[i] + udg_CfO__Velocity[udg_CfO__Missile__Source[i]]*Cos(udg_CfO__Missile__Angle[i])
set udg_CfO__Missile__Y[i] = udg_CfO__Missile__Y[i] + udg_CfO__Velocity[udg_CfO__Missile__Source[i]]*Sin(udg_CfO__Missile__Angle[i])
set udg_CfO__Missile__Distance[i] = udg_CfO__Missile__Distance[i] - udg_CfO__Velocity[udg_CfO__Missile__Source[i]]
// Move missile and detect for reachable targets
if CfO__isInBound(udg_CfO__Missile__X[i], udg_CfO__Missile__Y[i]) then
call SetUnitX(udg_CfO__Missile__Dummy[i], udg_CfO__Missile__X[i])
call SetUnitY(udg_CfO__Missile__Dummy[i], udg_CfO__Missile__Y[i])
call GroupEnumUnitsInRange(udg_CfO__TempGroup, udg_CfO__Missile__X[i], udg_CfO__Missile__Y[i], CfO__HitRadius(), null)
loop
set fog = FirstOfGroup(udg_CfO__TempGroup)
exitwhen fog == null
call GroupRemoveUnit(udg_CfO__TempGroup, fog)
if CfO__Targets(fog, udg_CfO__Owner[udg_CfO__Missile__Source[i]]) and not IsUnitInGroup(fog, udg_CfO__Missile__Targets[i]) then
call GroupAddUnit(udg_CfO__Missile__Targets[i], fog)
call DestroyEffect(AddSpecialEffectTarget(CfO__HitFX(), fog, CfO__HitFXPt()))
call UnitDamageTarget(udg_CfO__Caster[udg_CfO__Missile__Source[i]], fog, udg_CfO__Damage[udg_CfO__Missile__Source[i]], false, false, CfO__AttackType(), CfO__DamageType(), CfO__WeaponType())
call CfO__OnDamage(fog, udg_CfO__Caster[udg_CfO__Missile__Source[i]], udg_CfO__Level[udg_CfO__Missile__Source[i]])
if CfO__isAlive(fog) then
call CfO__applySlow(udg_CfO__Missile__Source[i], fog)
endif
if CfO__SmartHoming() and CfO__Homing(udg_CfO__Level[udg_CfO__Missile__Source[i]]) then
set udg_CfO__Missile__Target[i] = null
endif
endif
endloop
else
set dispose = true
endif
else
set dispose = true
endif
if dispose then
call CfO__OnMissileDispose(udg_CfO__Caster[udg_CfO__Missile__Source[i]], udg_CfO__Level[udg_CfO__Missile__Source[i]], udg_CfO__Missile__X[i], udg_CfO__Missile__Y[i])
// Detach disposed missile from the system
call UnitApplyTimedLife(udg_CfO__Missile__Dummy[i], 'BTLF', 5.0)
call DestroyEffect(udg_CfO__Missile__Fx[i])
call DestroyGroup(udg_CfO__Missile__Targets[i])
set udg_CfO__MCount[udg_CfO__Missile__Source[i]] = udg_CfO__MCount[udg_CfO__Missile__Source[i]] - 1
if i != udg_CfO__Missile__Count then
// Deindex
set udg_CfO__Missile__Angle[i] = udg_CfO__Missile__Angle[udg_CfO__Missile__Count]
set udg_CfO__Missile__AngleX[i] = udg_CfO__Missile__AngleX[udg_CfO__Missile__Count]
set udg_CfO__Missile__X[i] = udg_CfO__Missile__X[udg_CfO__Missile__Count]
set udg_CfO__Missile__Y[i] = udg_CfO__Missile__Y[udg_CfO__Missile__Count]
set udg_CfO__Missile__Distance[i] = udg_CfO__Missile__Distance[udg_CfO__Missile__Count]
set udg_CfO__Missile__Source[i] = udg_CfO__Missile__Source[udg_CfO__Missile__Count]
set udg_CfO__Missile__Target[i] = udg_CfO__Missile__Target[udg_CfO__Missile__Count]
set udg_CfO__Missile__Targets[i] = udg_CfO__Missile__Targets[udg_CfO__Missile__Count]
set udg_CfO__Missile__TurnDelay[i] = udg_CfO__Missile__TurnDelay[udg_CfO__Missile__Count]
set udg_CfO__Missile__Dummy[i] = udg_CfO__Missile__Dummy[udg_CfO__Missile__Count]
set udg_CfO__Missile__Fx[i] = udg_CfO__Missile__Fx[udg_CfO__Missile__Count]
// Remove leaks
set udg_CfO__Missile__Dummy[udg_CfO__Missile__Count] = null
set udg_CfO__Missile__Target[udg_CfO__Missile__Count] = null
set udg_CfO__Missile__Targets[udg_CfO__Missile__Count] = null
set udg_CfO__Missile__Fx[udg_CfO__Missile__Count] = null
endif
set udg_CfO__Missile__Count = udg_CfO__Missile__Count - 1
if udg_CfO__Missile__Count == 0 then
call PauseTimer(udg_CfO__Missile__Timer)
exitwhen true
else
set i = i - 1
endif
endif
set i = i + 1
endloop
endfunction
// Launch an electric pulse to given direction
function CfO__launch takes integer source, real angle returns nothing
set udg_CfO__Missile__Count = udg_CfO__Missile__Count + 1
set udg_CfO__Missile__Angle[udg_CfO__Missile__Count] = angle*bj_DEGTORAD
set udg_CfO__Missile__AngleX[udg_CfO__Missile__Count] = udg_CfO__Missile__Angle[udg_CfO__Missile__Count] + GetRandomReal(CfO__MissileTurnAmountMin(), CfO__MissileTurnAmountMax()) * GetRandomInt(-1, 1)
set udg_CfO__Missile__X[udg_CfO__Missile__Count] = udg_CfO__X[source]
set udg_CfO__Missile__Y[udg_CfO__Missile__Count] = udg_CfO__Y[source]
set udg_CfO__Missile__Distance[udg_CfO__Missile__Count] = GetRandomReal(CfO__DistanceMin(udg_CfO__Level[source]), CfO__DistanceMax(udg_CfO__Level[source]))
set udg_CfO__Missile__Source[udg_CfO__Missile__Count] = source
set udg_CfO__Missile__Target[udg_CfO__Missile__Count] = null
set udg_CfO__Missile__Targets[udg_CfO__Missile__Count] = CreateGroup()
set udg_CfO__Missile__TurnDelay[udg_CfO__Missile__Count] = GetRandomReal(CfO__MissileTurnDelayMin(), CfO__MissileTurnDelayMax())
set udg_CfO__Missile__Dummy[udg_CfO__Missile__Count] = CreateUnit(udg_CfO__Owner[source], CfO__DummyID(), udg_CfO__X[source], udg_CfO__Y[source], angle)
set udg_CfO__Missile__Fx[udg_CfO__Missile__Count] = AddSpecialEffectTarget(CfO__MissileFX(), udg_CfO__Missile__Dummy[udg_CfO__Missile__Count], "origin")
if UnitAddAbility(udg_CfO__Missile__Dummy[udg_CfO__Missile__Count], 'Amrf') and UnitRemoveAbility(udg_CfO__Missile__Dummy[udg_CfO__Missile__Count], 'Amrf') then
endif
call SetUnitScale(udg_CfO__Missile__Dummy[udg_CfO__Missile__Count], CfO__MissileSize(), 1, 1)
call SetUnitFlyHeight(udg_CfO__Missile__Dummy[udg_CfO__Missile__Count], CfO__MissileHeight(), 0)
if udg_CfO__Missile__Count == 1 then
call TimerStart(udg_CfO__Missile__Timer, CfO__Interval(), true, function CfO__missile)
endif
endfunction
// Periodic callback for orbs
function CfO__periodic takes nothing returns nothing
local integer h
local integer i = 1
local integer j
local real space
loop
exitwhen i > udg_CfO__Count
// If the spell is still ongoing
if udg_CfO__Duration[i] > CfO__Interval() and CfO__isAlive(udg_CfO__Caster[i]) and (not CfO__Channeling() or GetUnitCurrentOrder(udg_CfO__Caster[i]) == CfO__OrderID()) then
set udg_CfO__Duration[i] = udg_CfO__Duration[i] - CfO__Interval()
if udg_CfO__StrikeDelay[i] > CfO__Interval() then
set udg_CfO__StrikeDelay[i] = udg_CfO__StrikeDelay[i] - CfO__Interval()
elseif udg_CfO__ReleaseDelay[i] > CfO__Interval() then
// Play "lightning strike" animation
if udg_CfO__ReleaseDelay[i] == udg_CfO__ReleaseDelayX[i] then
call DestroyEffect(AddSpecialEffectTarget(CfO__LightningFX(), udg_CfO__Orb[i], "origin"))
call DestroyEffect(AddSpecialEffect(CfO__WaveFX(), udg_CfO__X[i], udg_CfO__Y[i]))
call CfO__OnStrike(udg_CfO__Caster[i], udg_CfO__Level[i], udg_CfO__X[i], udg_CfO__Y[i])
endif
set udg_CfO__ReleaseDelay[i] = udg_CfO__ReleaseDelay[i] - CfO__Interval()
else
// Release electric pulses
set udg_CfO__StrikeDelay[i] = udg_CfO__StrikeDelayX[i]
set udg_CfO__ReleaseDelay[i] = udg_CfO__ReleaseDelayX[i]
call CfO__OnRelease(udg_CfO__Caster[i], udg_CfO__Level[i], udg_CfO__X[i], udg_CfO__Y[i])
set space = 360/udg_CfO__ReleaseCount[i]
set j = 0
loop
exitwhen j == udg_CfO__ReleaseCount[i]
set udg_CfO__MCount[i] = udg_CfO__MCount[i] + 1
call CfO__launch(i, space*j + GetRandomReal(-space*CfO__Accuracy(), space*CfO__Accuracy()))
set j = j + 1
endloop
endif
else
if udg_CfO__OrbFx[i] != null then
call CfO__OnDispose(udg_CfO__Caster[i], udg_CfO__Level[i], udg_CfO__X[i], udg_CfO__Y[i])
if CfO__Channeling() then
set h = GetHandleId(udg_CfO__Caster[i])
if LoadInteger(udg_CfO__Hashtable, h, 0) == i then
call SaveInteger(udg_CfO__Hashtable, h, 0, 0)
endif
endif
call UnitApplyTimedLife(udg_CfO__Orb[i], 'BTLF', 5)
call UnitApplyTimedLife(udg_CfO__Aura[i], 'BTLF', 5)
call DestroyEffect(udg_CfO__OrbFx[i])
call DestroyEffect(udg_CfO__AuraFx[i])
set udg_CfO__OrbFx[i] = null
endif
if udg_CfO__MCount[i] <= 0 then
if i != udg_CfO__Count then
// Index correction
if CfO__Channeling() then
call SaveInteger(udg_CfO__Hashtable, GetHandleId(udg_CfO__Caster[udg_CfO__Count]), 0, i)
endif
// Deindex
set udg_CfO__Caster[i] = udg_CfO__Caster[udg_CfO__Count]
set udg_CfO__Owner[i] = udg_CfO__Owner[udg_CfO__Count]
set udg_CfO__X[i] = udg_CfO__X[udg_CfO__Count]
set udg_CfO__Y[i] = udg_CfO__Y[udg_CfO__Count]
set udg_CfO__Orb[i] = udg_CfO__Orb[udg_CfO__Count]
set udg_CfO__OrbFx[i] = udg_CfO__OrbFx[udg_CfO__Count]
set udg_CfO__Aura[i] = udg_CfO__Aura[udg_CfO__Count]
set udg_CfO__AuraFx[i] = udg_CfO__AuraFx[udg_CfO__Count]
set udg_CfO__MCount[i] = udg_CfO__MCount[udg_CfO__Count]
set udg_CfO__Level[i] = udg_CfO__Level[udg_CfO__Count]
set udg_CfO__Velocity[i] = udg_CfO__Velocity[udg_CfO__Count]
set udg_CfO__Duration[i] = udg_CfO__Duration[udg_CfO__Count]
set udg_CfO__ReleaseDelayX[i] = udg_CfO__ReleaseDelayX[udg_CfO__Count]
set udg_CfO__StrikeDelayX[i] = udg_CfO__StrikeDelayX[udg_CfO__Count]
set udg_CfO__ReleaseDelay[i] = udg_CfO__ReleaseDelay[udg_CfO__Count]
set udg_CfO__StrikeDelay[i] = udg_CfO__StrikeDelay[udg_CfO__Count]
set udg_CfO__ReleaseCount[i] = udg_CfO__ReleaseCount[udg_CfO__Count]
// Remove leaks
set udg_CfO__Orb[udg_CfO__Count] = null
set udg_CfO__OrbFx[udg_CfO__Count] = null
set udg_CfO__Aura[udg_CfO__Count] = null
set udg_CfO__AuraFx[udg_CfO__Count] = null
set udg_CfO__Caster[udg_CfO__Count] = null
// Source index corrections
set j = 1
loop
exitwhen j > udg_CfO__Missile__Count
if udg_CfO__Missile__Source[j] == udg_CfO__Count then
set udg_CfO__Missile__Source[j] = i
endif
set j = j + 1
endloop
endif
set udg_CfO__Count = udg_CfO__Count - 1
if udg_CfO__Count == 0 then
call PauseTimer(udg_CfO__Timer)
else
set i = i - 1
endif
endif
endif
set i = i + 1
endloop
endfunction
// On cast event
function CfO__onCast takes nothing returns boolean
local integer h
local integer i
if GetSpellAbilityId() == CfO__SpellID() then
set udg_CfO__Count = udg_CfO__Count + 1
set udg_CfO__Caster[udg_CfO__Count] = GetTriggerUnit()
set udg_CfO__Owner[udg_CfO__Count] = GetTriggerPlayer()
set udg_CfO__X[udg_CfO__Count] = GetSpellTargetX()
set udg_CfO__Y[udg_CfO__Count] = GetSpellTargetY()
set udg_CfO__Orb[udg_CfO__Count] = CreateUnit(udg_CfO__Owner[udg_CfO__Count], CfO__DummyID(), udg_CfO__X[udg_CfO__Count], udg_CfO__Y[udg_CfO__Count], 0)
set udg_CfO__OrbFx[udg_CfO__Count] = AddSpecialEffectTarget(CfO__OrbFX(), udg_CfO__Orb[udg_CfO__Count], "origin")
set udg_CfO__Aura[udg_CfO__Count] = CreateUnit(udg_CfO__Owner[udg_CfO__Count], CfO__DummyID(), udg_CfO__X[udg_CfO__Count], udg_CfO__Y[udg_CfO__Count], 0)
set udg_CfO__AuraFx[udg_CfO__Count] = AddSpecialEffectTarget(CfO__AuraFX(), udg_CfO__Aura[udg_CfO__Count], "origin")
set udg_CfO__MCount[udg_CfO__Count] = 0
set udg_CfO__Level[udg_CfO__Count] = GetUnitAbilityLevel(udg_CfO__Caster[udg_CfO__Count], CfO__SpellID())
set udg_CfO__Velocity[udg_CfO__Count] = CfO__Velocity(udg_CfO__Level[udg_CfO__Count])
set udg_CfO__Damage[udg_CfO__Count] = CfO__Damage(udg_CfO__Level[udg_CfO__Count])
set udg_CfO__Duration[udg_CfO__Count] = CfO__Duration(udg_CfO__Level[udg_CfO__Count])
set udg_CfO__ReleaseDelayX[udg_CfO__Count] = CfO__ReleaseDelay(udg_CfO__Level[udg_CfO__Count])
set udg_CfO__StrikeDelayX[udg_CfO__Count] = CfO__StrikeDelay(udg_CfO__Level[udg_CfO__Count])
set udg_CfO__ReleaseDelay[udg_CfO__Count] = udg_CfO__ReleaseDelayX[udg_CfO__Count]
set udg_CfO__StrikeDelay[udg_CfO__Count] = udg_CfO__StrikeDelayX[udg_CfO__Count]
set udg_CfO__ReleaseCount[udg_CfO__Count] = CfO__ReleaseCount(udg_CfO__Level[udg_CfO__Count])
if UnitAddAbility(udg_CfO__Orb[udg_CfO__Count], 'Amrf') and UnitRemoveAbility(udg_CfO__Orb[udg_CfO__Count], 'Amrf') then
endif
call SetUnitScale(udg_CfO__Orb[udg_CfO__Count], CfO__OrbSize(), 1, 1)
call SetUnitFlyHeight(udg_CfO__Orb[udg_CfO__Count], CfO__OrbHeight(), 0)
if UnitAddAbility(udg_CfO__Aura[udg_CfO__Count], 'Amrf') and UnitRemoveAbility(udg_CfO__Aura[udg_CfO__Count], 'Amrf') then
endif
call SetUnitScale(udg_CfO__Aura[udg_CfO__Count], CfO__AuraSize(), 1, 1)
call SetUnitFlyHeight(udg_CfO__Aura[udg_CfO__Count], CfO__AuraHeight(), 0)
if CfO__Channeling() then
set h = GetHandleId(udg_CfO__Caster[udg_CfO__Count])
set i = LoadInteger(udg_CfO__Hashtable, h, 0)
if i != 0 then
set udg_CfO__Duration[i] = 0
endif
call SaveInteger(udg_CfO__Hashtable, h, 0, udg_CfO__Count)
endif
if udg_CfO__Count == 1 then
call TimerStart(udg_CfO__Timer, CfO__Interval(), true, function CfO__periodic)
endif
endif
return false
endfunction
function InitTrig_Chaosflare_Orb takes nothing returns nothing
// World bounds initialization
set udg_CfO__WorldBounds[0] = GetRectMinX(bj_mapInitialPlayableArea)
set udg_CfO__WorldBounds[1] = GetRectMaxX(bj_mapInitialPlayableArea)
set udg_CfO__WorldBounds[2] = GetRectMinY(bj_mapInitialPlayableArea)
set udg_CfO__WorldBounds[3] = GetRectMaxY(bj_mapInitialPlayableArea)
set udg_CfO__Timer = CreateTimer()
set udg_CfO__Slow__Timer = CreateTimer()
set udg_CfO__Missile__Timer = CreateTimer()
set gg_trg_Chaosflare_Orb = CreateTrigger()
set udg_CfO__Slow__Caster = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), CfO__DummyID(), 0, 0, 0)
call UnitAddAbility(udg_CfO__Slow__Caster, CfO__SlowSpellID())
call TriggerRegisterAnyUnitEventBJ(gg_trg_Chaosflare_Orb, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(gg_trg_Chaosflare_Orb, Condition(function CfO__onCast))
if CfO__Channeling() then
set udg_CfO__Hashtable = InitHashtable()
endif
endfunction
[FONT=Palatino Linotype]