You might want to use Starts the effect of an ability instead of Begins casting an ability.
Wellz, here is my entry.
Icon
|
Tooltip
|
| Learn Mother Nature's Recipe (Q) - [Level 1]
Creates a swarm of moving treants
which will move towards the target point,
and after some time,
they will freeze and transform into trees,
blocking the way of enemies.
Level 1 - 7 seconds.
Level 2 - 5 seconds.
Level 3 - 3 seconds. |
[jass=Code]library MotherNaturesRecipe initializer onInit requires TimerUtils
globals
private constant integer ABILID_SPELL = 'A000' //raw code of the spell
private constant integer ABILID_LOCUST = 'Aloc' //raw code of the locust ability
private constant boolean BOOL_TREEREMOVE = false //remove trees or kill them?
private constant integer UNITID_UNITSUMMONED = 'efon' //raw code of the summoned unit
private constant integer DESTID_TREESUMMONED = 'WTst' //raw code of the summoned tree
private constant integer INTEGER_MAXSUMMONS = 23 //maximum number of units at one time
private constant integer INTEGER_TREEMAXVAR = 10 //number of variations of the tree model
private constant real REAL_MAXDISTANCE = 1500 //maximum distance away
private constant real REAL_MAXFROMNORM = 900 //maximum distance from the normal target loc, for the moving orders
private constant real REAL_MAXANGLE = 180 //maximum angle of the polar projection
private constant real REAL_TREESCALE = 1.10 //scaling of the tree
private constant real REAL_TREETIME = 10 //the time the trees last
private constant string MODELPATH_ONSUMMON = "Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl"//the fx which is spawned when a treant is created or dies
private constant string MODELPATH_ONTREE = "Abilities\\Spells\\NightElf\\ThornsAura\\ThornsAura.mdl"//the fx which is spawned when the tree is created
private constant string MODELPATH_BODYFX = "Abilities\\Spells\\Undead\\UnholyFrenzy\\UnholyFrenzyTarget.mdl" //a fx which is attached to the summoned unit
private constant string MODELPATH_ATTACH = "origin" //attaching point
endglobals
//===========================================================================
// Time formula
private function REAL_TIME takes integer lvl returns real
return 9.-(2*lvl) // the time before the treant are transformed
endfunction
//===========================================================================
// Real code, don't touch
//===========================================================================
// Conditions
private constant function spellConditions takes nothing returns boolean
return GetSpellAbilityId()==ABILID_SPELL
endfunction
//===========================================================================
// treantData struct
private struct treantData
unit t
unit o
destructable d
timer tmr
//===========================================================================
// onDestroy method
method onDestroy takes nothing returns nothing
call ReleaseTimer(.tmr)
endmethod
//===========================================================================
// initTreant method, the method which creates and orders the treant
static method initTreant takes unit p,real x,real y,real tx,real ty,real angle returns treantData
local treantData td=treantData.allocate()
local real px=tx+(GetRandomReal(-REAL_MAXFROMNORM,REAL_MAXFROMNORM))*Cos(angle+(GetRandomReal(-REAL_MAXANGLE,REAL_MAXANGLE)))
local real py=ty+(GetRandomReal(-REAL_MAXFROMNORM,REAL_MAXFROMNORM))*Sin(angle+(GetRandomReal(-REAL_MAXANGLE,REAL_MAXANGLE)))
set td.t=CreateUnit(GetOwningPlayer(p),UNITID_UNITSUMMONED,x,y,0)
call UnitAddAbility(td.t,ABILID_LOCUST)
call DestroyEffect(AddSpecialEffectTarget(MODELPATH_ONSUMMON,td.t,MODELPATH_ATTACH))
call AddSpecialEffectTarget(MODELPATH_BODYFX,td.t,MODELPATH_ATTACH)
call IssuePointOrder(td.t,"move",px,py)
set td.tmr=NewTimer()
call SetTimerData(td.tmr,td)
call TimerStart(td.tmr,REAL_TIME(GetUnitAbilityLevel(GetTriggerUnit(),ABILID_SPELL)),false,function treantData.transform)
set td.o=p
return 0
endmethod
//===========================================================================
// Transformation from treant to tree function
static method transform takes nothing returns nothing
local treantData td=GetTimerData(GetExpiredTimer())
set td.d=CreateDestructable(DESTID_TREESUMMONED,GetUnitX(td.t),GetUnitY(td.t),GetUnitFacing(td.t),REAL_TREESCALE,INTEGER_TREEMAXVAR)
call DestroyEffect(AddSpecialEffect(MODELPATH_ONSUMMON,GetUnitX(td.t),GetUnitY(td.t)))
call ShowUnit(td.t,false)
call KillUnit(td.t)
call DestroyEffect(AddSpecialEffectTarget(MODELPATH_ONTREE,td.d,MODELPATH_ATTACH))
call TimerStart(td.tmr,REAL_TREETIME,false,function treantData.remove)
endmethod
//===========================================================================
// Removal of the trees
static method remove takes nothing returns nothing
local treantData td=GetTimerData(GetExpiredTimer())
call KillDestructable(td.d)
if BOOL_TREEREMOVE then
call RemoveDestructable(td.d)
endif
call td.destroy()
endmethod
endstruct
//===========================================================================
// Main function, intializes all treants and starts timers
private function onSpellEffect takes nothing returns nothing
local integer i=-1
local location l=GetSpellTargetLoc()
local real x=GetUnitX(GetTriggerUnit())
local real y=GetUnitY(GetTriggerUnit())
local real tx=GetLocationX(l)
local real ty=GetLocationY(l)
local real angle=Atan2(ty-y,tx-x)
local treantData array td
loop
set i=i+1
exitwhen i>INTEGER_MAXSUMMONS
set td
=treantData.initTreant(GetTriggerUnit(),x,y,tx,ty,angle)
endloop
call RemoveLocation(l)
set l=null
endfunction
//===========================================================================
// Initialization function
private function onInit takes nothing returns nothing
local trigger t=CreateTrigger()
local integer 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 spellConditions))
call TriggerAddAction(t,function onSpellEffect)
endfunction
endlibrary[/code]