Earth Panda Spellpack
by kenny!
v1
Introduction:
These are some spells i have been working on due to my boredom the past couple of weeks. Alone they were nothing special, however they make a pretty cool spellpack.
This spellpack includes:
- Seismic Slam;
- Stone Guardians;
- Stone Skin; and
- Earth Prison.
Technical Details:
- These spells are done in vJASS, therefore need NewGen World Editor.
- They are MUI/MPI and all that.
- They are leakless and lagless (expect for some first cast lag which i may fix).
- They do not require any other systems.
- They have been built around a theme (Earth / Interruption spells) and therefore they work pretty well together.
- They are pretty cool.
The Spells:
Seismic Slam:
Import Difficulty: Easy-Medium
Description:
Leaps forward, spinning in the air at a tremendous rate towards a target location. Upon impact, enemy ground units in the area are dealt damage and stunned.
Level 1 - Deals 50 Damage, 0.45 second stun. Leap takes 1.30 seconds. Maximum distance of 300.
Level 2 - Deals 100 Damage, 0.60 second stun. Leap takes 1.15 seconds. Maximum distance of 450.
Level 3 - Deals 150 Damage, 0.75 second stun. Leap takes 1.00 seconds. Maximum distance of 600.
Level 4 - Deals 200 damage, 0.90 second stun. Leap takes 0.85 seconds. Maximum distance of 750.
Cooldown: 18 seconds
Screenshot:
He's jumping not lying down...
The script
JASS:
scope SeismicSlam initializer Init
globals
// Configurables:
// Skills:
private constant integer Abil_id = 039;A000039;
// Raw code of the main hero ability.
private constant integer Abil2_id = 039;A007039;
// Raw code of the stomp used at the end.
private constant integer Flytrick = 039;Amrf039;
// Raw code for "Crow Form". Does not need to be changed in most cases.
// Units:
private constant integer Dummy_id = 039;u001039;
// Raw code of the dummy "spinning" unit used for the leap.
private constant integer Treedummy_id = 039;u000039;
// Raw code of the dummy unit used to destroy trees.
// Others:
private constant real Interval = 0.04 // Interval for periodic timer.
private constant real Diff = 0.00 // Distance from cast point that the unit will land.
private constant real Timescale = 3.00 // How fast the unit spins.
private constant string End_anim = "spell slam"
// End animation of the unit.
private constant string Dirt_sfx = "NewDirtEXNofire.mdx"
// Effect made at the end of the spell on land.
private constant string Water_sfx = "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl"
// Same as above but for landing on water.
private constant boolean Destroytrees = true
// Whether or not to destroy trees.
private constant boolean AllowPreload = true
// Whether or not to allow preloading of the effects.
endglobals
//=======================================================================
private function Area takes integer lvl returns real
return 225.00 // Area of effect for destroying trees.
endfunction
private function Airtime takes integer lvl returns real
return 1.45-(0.15*lvl) // Air time of the leap.
endfunction
//=======================================================================//
// DO NOT TOUCH PAST THIS POINT UNLESS YOU KNOW WHAT YOUR ARE DOING!! //
//=======================================================================//
private keyword Data
globals
private integer Total = 0
private Data array D
private timer Timer = null
private rect Rect1 = null
private boolexpr Treefilt = null
private boolexpr Truefilt = null
private unit Treedummy = null
private real Game_maxX = 0.00
private real Game_minX = 0.00
private real Game_maxY = 0.00
private real Game_minY = 0.00
endglobals
//=======================================================================
private function KillEnumDestructables takes nothing returns nothing
call KillDestructable(GetEnumDestructable())
endfunction
private function TreeCheck takes nothing returns boolean
local destructable dest = GetFilterDestructable()
local boolean result
if GetDestructableLife(dest) > 0.405 then
call ShowUnit(Treedummy,true)
call SetUnitX(Treedummy,GetWidgetX(dest))
call SetUnitY(Treedummy,GetWidgetY(dest))
set result = IssueTargetOrder(Treedummy,"harvest",dest)
call IssueImmediateOrder(Treedummy,"stop")
call ShowUnit(Treedummy,false)
return result
endif
set dest = null
return false
endfunction
//=======================================================================
private function SafeX takes real x returns real
if x<Game_minX then
return Game_minX
elseif x>Game_maxX then
return Game_maxX
endif
return x
endfunction
private function SafeY takes real y returns real
if y<Game_minY then
return Game_minY
elseif y>Game_maxY then
return Game_maxY
endif
return y
endfunction
//=======================================================================
private function MoveDist takes real Maxdist, integer lvl returns real
return Maxdist/(Airtime(lvl)/Interval)
endfunction
private function ConvertCount takes integer i, integer lvl returns real
return (50.00/(Airtime(lvl)/Interval))*i
endfunction
//=======================================================================
private struct Data
unit cast
unit dum
real castx
real casty
real cos
real sin
real maxdist
real movedist
integer i = 1
integer lvl
static method create takes nothing returns Data
local Data d = Data.allocate()
local location loc
local real angle
local real targx
local real targy
set d.cast = GetTriggerUnit()
set d.castx = GetUnitX(d.cast)
set d.casty = GetUnitY(d.cast)
set loc = GetSpellTargetLoc()
set angle = Atan2((GetLocationY(loc)-d.casty),(GetLocationX(loc)-d.castx))
set d.cos = Cos(angle)
set d.sin = Sin(angle)
set targx = GetLocationX(loc)-Diff*d.cos
set targy = GetLocationY(loc)-Diff*d.sin
set d.lvl = GetUnitAbilityLevel(d.cast,Abil_id)
set d.maxdist = SquareRoot((targx-d.castx)*(targx-d.castx)+(targy-d.casty)*(targy-d.casty))
set d.movedist = MoveDist(d.maxdist,d.lvl)
set d.dum = CreateUnit(GetOwningPlayer(d.cast),Dummy_id,d.castx,d.casty,angle*bj_RADTODEG)
call UnitAddAbility(d.dum,Flytrick)
call UnitRemoveAbility(d.dum,Flytrick)
call SetUnitTimeScale(d.dum,Timescale)
call SetUnitPathing(d.dum,false)
call PauseUnit(d.dum,true)
call ShowUnit(d.cast,false)
set Total = Total + 1
if Total == 1 then
call TimerStart(Timer,Interval,true,function Data.Update)
endif
set D[Total] = d
call RemoveLocation(loc)
set loc = null
return d
endmethod
static method Update takes nothing returns nothing
local integer i = 1
local real count
local real height
local real speed
local real newx
local real newy
loop
exitwhen i > Total
if D<i>.i < (Airtime(D<i>.lvl) / Interval) then
set count = ConvertCount(D<i>.i,D<i>.lvl)
set height = (count-25.00) * (count-25.00)
set speed = D<i>.i * D<i>.movedist
set newx = D<i>.castx + speed * D<i>.cos
set newy = D<i>.casty + speed * D<i>.sin
call SetUnitPosition(D<i>.dum,SafeX(newx),SafeY(newy))
call SetUnitPosition(D<i>.cast,SafeX(newx),SafeY(newy))
call SetUnitFlyHeight(D<i>.dum,625.00-height,0.00)
call SetUnitFlyHeight(D<i>.cast,625.00-height,0.00)
set D<i>.i = D<i>.i + 1
else
call D<i>.destroy()
set D<i> = D[Total]
set Total = Total - 1
set i = i - 1
endif
set i = i + 1
endloop
if Total <= 0 then
call PauseTimer(Timer)
set Total = 0
endif
endmethod
private method onDestroy takes nothing returns nothing
local real newx = GetUnitX(.dum) + Diff * .cos
local real newy = GetUnitY(.dum) + Diff * .sin
local unit u = CreateUnit(GetOwningPlayer(.cast),Treedummy_id,newx,newy,0.00)
call SetUnitFlyHeight(.dum,GetUnitDefaultFlyHeight(.cast),0.00)
call PauseUnit(.dum,false)
call SetUnitPathing(.dum,true)
if Destroytrees then
call SetRect(Rect1,newx-Area(.lvl),newy-Area(.lvl),newx+Area(.lvl),newy+Area(.lvl))
call EnumDestructablesInRect(Rect1,Treefilt,function KillEnumDestructables)
endif
call UnitAddAbility(u,Abil2_id)
call SetUnitAbilityLevel(u,Abil2_id,.lvl)
call IssueImmediateOrder(u,"stomp")
call UnitApplyTimedLife(u,039;BTLF039;,1.00)
if IsTerrainPathable(GetUnitX(u),GetUnitY(u),PATHING_TYPE_FLOATABILITY) then
call DestroyEffect(AddSpecialEffect(Dirt_sfx,newx,newy))
elseif not IsTerrainPathable(GetUnitX(u),GetUnitY(u),PATHING_TYPE_WALKABILITY) then
call DestroyEffect(AddSpecialEffect(Water_sfx,newx,newy))
endif
call RemoveUnit(.dum)
call SetUnitPosition(.cast,newx,newy)
call ShowUnit(.cast,true)
call SetUnitAnimation(.cast,End_anim)
if GetLocalPlayer() == GetOwningPlayer(.cast) then
call ClearSelection()
call SelectUnit(.cast,true)
endif
set .cast = null
set .dum = null
set u = null
endmethod
endstruct
//=======================================================================
private function Actions takes nothing returns nothing
call Data.create()
endfunction
//=======================================================================
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == Abil_id
endfunction
//=======================================================================
private function TrueFilt takes nothing returns boolean
return true
endfunction
//=======================================================================
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
local integer i = 0
set Timer = CreateTimer()
set Rect1 = Rect(0.00,0.00,1.00,1.00)
set Treefilt = Filter(function TreeCheck)
set Game_maxX = GetRectMaxX(bj_mapInitialPlayableArea)-64.00
set Game_maxY = GetRectMaxY(bj_mapInitialPlayableArea)-64.00
set Game_minX = GetRectMinX(bj_mapInitialPlayableArea)+64.00
set Game_minY = GetRectMinY(bj_mapInitialPlayableArea)+64.00
set Truefilt = Filter(function TrueFilt)
loop
call TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,Truefilt)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(trig,Condition(function Conditions))
call TriggerAddAction(trig,function Actions)
set Treedummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),Treedummy_id,0.00,0.00,0.00)
call SetUnitPathing(Treedummy,false)
call ShowUnit(Treedummy,false)
if AllowPreload then
call KillUnit(CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),Dummy_id,0.00,0.00,0.00))
call DestroyEffect(AddSpecialEffect(Dirt_sfx,0.00,0.00))
call DestroyEffect(AddSpecialEffect(Water_sfx,0.00,0.00))
endif
endfunction
endscope</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>
Stone Guardians:
Import Difficulty: Easy-Medium
Credits: emjlr3 for formula help.
Description:
Calls forth stone guardians to protect the target unit. These guardians will damage any enemy unit that comes near the target, knocking them back in the process. The target unit gets +2 armour for each stone guardian if the Stone Panda has at least one level into Stone Skin.
Lasts 12 seconds.
Level 1 - Summons 2 guardians, each guardian deals 45 damage and knocks a unit back a very short distance.
Level 2 - Summons 3 guardians, each guardian deals 55 damage and knocks a unit back a very short distance.
Level 3 - Summons 4 guardians, each guardian deals 65 damage and knocks a unit back a short distance.
Level 4 - Summons 5 guardians, each guardian deals 75 damage and knocks a unit back a short distance.
Cooldown: 28/24/20/16 seconds
Screenshot:
The script:
JASS:
scope StoneGuardians initializer Init
globals
// Configurables:
// Skills:
private constant integer Abil_id = 039;A008039;
// Raw code for the main hero ability.
private constant integer Abil2_id = 039;A00B039;
// Raw code for the Stone Skin hero ability.
private constant integer Abil3_id = 039;A00C039;
// Raw code for the SG Armour Bonus ability.
// Units:
private constant integer Dummy_id = 039;u002039;
// Raw code for the stone guardian dummy unit.
// Others:
private constant real Interval = 0.04 // Interval for periodic timer.
private constant real Height = 30.00 // height of the stones.
private constant real Collision = 60.00 // How close a unit must be to get hit by a stone.
private constant real Distance = 150.00 // Distance from the target at which units are created.
private constant string Start_sfx = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
// Special effect used when the stones are created.
private constant string Dirt_sfx = "Dust.mdx"
// Special effect used for when units are knocked back.
private constant string Water_sfx = "SlideWater.mdx"
// Same as above but for when units are on water.
private constant string Point = "origin"
// Attachment point for Dirt_sfx and Water_sfx.
private constant boolean Allowmove = false
// Whether or not units are allowed to move while being knocked back.
private constant boolean AllowPreload = false
// Whether or not to allow preloading of the effects.
// Attack/Damage/Weapon types of damage dealt.
private constant attacktype A_type = ATTACK_TYPE_CHAOS
private constant damagetype D_type = DAMAGE_TYPE_UNIVERSAL
private constant weapontype W_type = WEAPON_TYPE_WHOKNOWS
endglobals
//=======================================================================
private function MaxDuration takes integer lvl returns real
return 12.00 // Duration of the stone guardians.
endfunction
private function KnockDuration takes integer lvl returns real
return 1.00 // Knockback duration.
endfunction
private function KnockDistance takes integer lvl returns real
return 100.00+(25.00*lvl) // Knockback distance.
endfunction
private function StoneNumber takes integer lvl returns integer
return 1+(1*lvl) // Number of stones per level. Try to keep it under 9 if you dont know how to change it.
endfunction
private function Damage takes integer lvl returns real
return 35.00+(10.00*lvl) // Damage dealt when stones hit units.
endfunction
private function Speed takes integer lvl returns real
return 325.00-(25.00*lvl) // The speed at which the stones rotate around the target.
endfunction
//=======================================================================//
// DO NOT TOUCH PAST THIS POINT UNLESS YOU KNOW WHAT YOUR ARE DOING!! //
//=======================================================================//
private keyword Data
private keyword Knock
globals
private boolexpr Enemyfilt
private boolexpr Truefilt
private timer Timer = null
private integer DT = 0
private integer KT = 0
private Data array D
private Knock array K
private real Game_maxX = 0.00
private real Game_minX = 0.00
private real Game_maxY = 0.00
private real Game_minY = 0.00
endglobals
//=======================================================================
private function IsPointOutside takes real x, real y returns boolean
return (x > Game_maxX or y > Game_maxY or x < Game_minX or y < Game_minY)
endfunction
private function TerrainType takes unit u returns integer
local real x = GetUnitX(u)
local real y = GetUnitY(u)
if IsTerrainPathable(x,y,PATHING_TYPE_FLOATABILITY) then
return 1
elseif not IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY) then
return 2
endif
return 0
endfunction
//=======================================================================
private struct Data
unit cast
unit targ
unit array stone[10]
integer stones = 0
integer alive = 0
integer dead = 0
integer lvl = 0
real time = 0.00
real speed = 0.00
real array ang[10]
group g = CreateGroup()
private method onDestroy takes nothing returns nothing
local integer i = 1
loop
exitwhen i > .stones
if GetWidgetLife(.stone<i>) > 0.405 then
call KillUnit(.stone<i>)
set .stone<i> = null
endif
set i = i + 1
endloop
if GetUnitAbilityLevel(.targ,Abil3_id) > 0 then
call UnitRemoveAbility(.targ,Abil3_id)
endif
set .cast = null
call GroupClear(.g)
call DestroyGroup(.g)
endmethod
endstruct
//=======================================================================
private struct Knock
unit targ
real speed = 0.00
real decrease = 0.00
real cos = 0.00
real sin = 0.00
effect sfx
integer sfxmode
private method onDestroy takes nothing returns nothing
set .targ = null
if .sfx != null then
call DestroyEffect(.sfx)
set .sfx = null
endif
endmethod
endstruct
//=======================================================================
private function FilterEnemies takes nothing returns boolean
return GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) == false
endfunction
//=======================================================================
private function Update takes nothing returns nothing
local integer h = 1
local integer i = 1
local integer j = 1
local Knock k = 0
local integer newmode
local real targx
local real targy
local real newx
local real newy
local real dist
local real ang
local real diff
local unit u
loop
exitwhen i > DT
if D<i>.time > MaxDuration(D<i>.lvl) or D<i>.dead == D<i>.stones or GetWidgetLife(D<i>.targ) < 0.405 then
call D<i>.destroy()
set D<i> = D[DT]
set DT = DT - 1
set i = i - 1
else
set targx = GetUnitX(D<i>.targ)
set targy = GetUnitY(D<i>.targ)
if GetUnitAbilityLevel(D<i>.targ,Abil3_id) > 0 then
call SetUnitAbilityLevel(D<i>.targ,Abil3_id,D<i>.alive)
elseif GetUnitAbilityLevel(D<i>.targ,Abil3_id) == 0 and GetUnitAbilityLevel(D<i>.cast,Abil2_id) > 0 then
call UnitAddAbility(D<i>.targ,Abil3_id)
call SetUnitAbilityLevel(D<i>.targ,Abil3_id,D<i>.alive)
endif
loop
exitwhen j > D<i>.stones
if GetWidgetLife(D<i>.stone[j]) > 0.405 then
call SetUnitX(D<i>.stone[j],targx + Distance * Cos(D<i>.ang[j]*bj_DEGTORAD))
call SetUnitY(D<i>.stone[j],targy + Distance * Sin(D<i>.ang[j]*bj_DEGTORAD))
call SetUnitFlyHeight(D<i>.stone[j],GetUnitFlyHeight(D<i>.targ)+Height,0.00)
set D<i>.ang[j] = D<i>.ang[j] + D<i>.speed
call GroupEnumUnitsInRange(D<i>.g,GetUnitX(D<i>.stone[j]),GetUnitY(D<i>.stone[j]),Collision,Enemyfilt)
loop
set u = FirstOfGroup(D<i>.g)
exitwhen u == null
call GroupRemoveUnit(D<i>.g,u)
if IsUnitEnemy(u,GetOwningPlayer(D<i>.cast)) and (GetUnitFlyHeight(u) >= (GetUnitFlyHeight(D<i>.stone[j])-(Height*2.00)) and GetUnitFlyHeight(u) <= (GetUnitFlyHeight(D<i>.stone[j])+(Height*2.00))) then
call UnitDamageTarget(D<i>.cast,u,Damage(D<i>.lvl),false,false,A_type,D_type,W_type)
set k = Knock.create()
set k.targ = u
set ang = Atan2(GetUnitY(k.targ)-GetUnitY(D<i>.stone[j]),GetUnitX(k.targ)-GetUnitX(D<i>.stone[j]))
set k.speed = (2.00*KnockDistance(D<i>.lvl)) / (KnockDuration(D<i>.lvl)/Interval)
set k.decrease = k.speed / (KnockDuration(D<i>.lvl)/Interval)
set k.sfxmode = TerrainType(k.targ)
if k.sfxmode == 1 then
set k.sfx = AddSpecialEffectTarget(Dirt_sfx,k.targ,Point)
elseif k.sfxmode == 2 then
set k.sfx = AddSpecialEffectTarget(Water_sfx,k.targ,Point)
endif
set k.cos = Cos(ang)
set k.sin = Sin(ang)
set KT = KT + 1
set K[KT] = k
call KillUnit(D<i>.stone[j])
set D<i>.dead = D<i>.dead + 1
set D<i>.alive = D<i>.alive - 1
set u = null
endif
endloop
endif
set j = j + 1
endloop
set j = 1
// Thanks to emjlr3 for his help with this. Below is basically his idea.
loop
exitwhen j > D<i>.stones
if GetWidgetLife(D<i>.stone[j]) > 0.405 then
if j != D<i>.stones and D<i>.alive != 1 then
set h = j + 1
loop
exitwhen h == j or GetWidgetLife(D<i>.stone[h]) > 0.405
if h > D<i>.stones then
set h = 1
else
set h = h + 1
endif
endloop
if h != j then
if h > j then
set diff = D<i>.ang[h] - D<i>.ang[j]
else
set diff = D<i>.ang[j] - D<i>.ang[h]
endif
if diff > (360.00 / D<i>.alive) then
set D<i>.ang[j] = D<i>.ang[j] + 1.00
elseif diff < (360.00 / D<i>.alive) then
set D<i>.ang[j] = D<i>.ang[j] - 1.00
endif
endif
endif
endif
set j = j + 1
endloop
set D<i>.time = D<i>.time + Interval
set j = 1
endif
set i = i + 1
endloop
set i = 1
loop
exitwhen i > KT
set newmode = K<i>.sfxmode
set newx = GetUnitX(K<i>.targ)
set newy = GetUnitY(K<i>.targ)
set K<i>.sfxmode = TerrainType(K<i>.targ)
if K<i>.sfxmode == 1 and newmode == 2 then
call DestroyEffect(K<i>.sfx)
set K<i>.sfx = AddSpecialEffectTarget(Dirt_sfx,K<i>.targ,Point)
elseif K<i>.sfxmode == 2 and newmode == 1 then
call DestroyEffect(K<i>.sfx)
set K<i>.sfx = AddSpecialEffectTarget(Water_sfx,K<i>.targ,Point)
endif
if K<i>.speed <= 0.00 or IsPointOutside(newx,newy) or GetWidgetLife(K<i>.targ) < 0.405 then
call K<i>.destroy()
set K<i> = K[KT]
set KT = KT - 1
set i = i - 1
else
set newx = newx + K<i>.speed * K<i>.cos
set newy = newy + K<i>.speed * K<i>.sin
if Allowmove then
call SetUnitX(K<i>.targ,newx)
call SetUnitY(K<i>.targ,newy)
else
call SetUnitPosition(K<i>.targ,newx,newy)
endif
set K<i>.speed = K<i>.speed - K<i>.decrease
endif
set i = i + 1
endloop
if DT <= 0 and KT <= 0 then
call PauseTimer(Timer)
set DT = 0
set KT = 0
endif
endfunction
//=======================================================================
private function Actions takes nothing returns nothing
local Data d = Data.create()
local integer i = 1
local real targx
local real targy
local real newx
local real newy
local real ang
set d.cast = GetTriggerUnit()
set d.targ = GetSpellTargetUnit()
set targx = GetUnitX(d.targ)
set targy = GetUnitY(d.targ)
set d.lvl = GetUnitAbilityLevel(d.cast,Abil_id)
set d.speed = Speed(d.lvl) / (1.00/Interval)
set d.stones = StoneNumber(d.lvl)
set d.alive = d.stones
set ang = 360.00 / d.stones
loop
exitwhen i > d.stones
set newx = targx + Distance * Cos((ang*i)*bj_DEGTORAD)
set newy = targy + Distance * Sin((ang*i)*bj_DEGTORAD)
set d.stone<i>= CreateUnit(GetOwningPlayer(d.cast),Dummy_id,newx,newy,0.00)
call DestroyEffect(AddSpecialEffect(Start_sfx,newx,newy))
call SetUnitFlyHeight(d.stone<i>,GetUnitFlyHeight(d.targ)+Height,0.00)
set d.ang<i> = ang * i
set i = i + 1
endloop
if GetUnitAbilityLevel(d.cast,Abil2_id) > 0 then
call UnitAddAbility(d.targ,Abil3_id)
call SetUnitAbilityLevel(d.targ,Abil3_id,d.stones)
endif
set DT = DT + 1
if DT == 1 and KT == 0 then
call TimerStart(Timer,Interval,true,function Update)
endif
set D[DT] = d
endfunction
//=======================================================================
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == Abil_id
endfunction
//=======================================================================
private function TrueFilt takes nothing returns boolean
return true
endfunction
//=======================================================================
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
local integer i = 0
local unit dum = null
set Timer = CreateTimer()
set Enemyfilt = Filter(function FilterEnemies)
set Truefilt = Filter(function TrueFilt)
set Game_maxX = GetRectMaxX(bj_mapInitialPlayableArea)-64.00
set Game_maxY = GetRectMaxY(bj_mapInitialPlayableArea)-64.00
set Game_minX = GetRectMinX(bj_mapInitialPlayableArea)+64.00
set Game_minY = GetRectMinY(bj_mapInitialPlayableArea)+64.00
loop
call TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,Truefilt)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(trig,Condition(function Conditions))
call TriggerAddAction(trig,function Actions)
if AllowPreload then
set dum = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),Dummy_id,0.00,0.00,0.00)
call UnitAddAbility(dum,Abil3_id)
call KillUnit(dum)
call DestroyEffect(AddSpecialEffect(Start_sfx,0.00,0.00))
endif
set dum = null
endfunction
endscope</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>
Change Log:
- 2nd Feb 09 - Updated the spells to include preloading, which helps a little. Also made a few minor improvements to the coding of the spell.