HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Lag when a unit dies???

06-12-2006, 02:09 PM#1
GALLED
Hi

I'm make a Spell called "Mass Entangle", that create in a circle roots ands herbs that when a unit passed over the area is entangled.

The Code is:

Enredaderas
Collapse JASS:
function Trig_Enredaderas_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A021' 
endfunction

function Trig_Enredaderas_Actions takes nothing returns nothing
local integer level = GetUnitAbilityLevelSwapped('A021', GetTriggerUnit())
local unit hierba
local unit caster = GetTriggerUnit()
local real x = GetLocationX(GetSpellTargetLoc())
local real y = GetLocationY(GetSpellTargetLoc())
local real radio = 150 + 50*level
local integer i
local real vidahierba = 2.25 + 0.75*level

//For draw the herbs like a circle
set i = 0
loop
    exitwhen (i>=radio)

//First draw the cross

    set hierba = CreateUnitAtLoc( GetOwningPlayer(caster), 'hpea',Location(x+i,y), bj_UNIT_FACING )
    call UnitApplyTimedLife( hierba,'BTLF', vidahierba)
    call UnitAddAbilityBJ( 'A026', hierba )
    call SetUnitAbilityLevelSwapped( 'A026', hierba, level )
    call GroupAddUnitSimple( hierba, udg_Enredaderas_Group )
    set hierba = null

    set hierba = CreateUnitAtLoc( GetOwningPlayer(caster), 'hpea',Location(x,y+i), bj_UNIT_FACING )
    call UnitApplyTimedLife( hierba,'BTLF', vidahierba)
    call UnitAddAbilityBJ( 'A026', hierba )
    call SetUnitAbilityLevelSwapped( 'A026', hierba, level )
    call GroupAddUnitSimple( hierba, udg_Enredaderas_Group )
    set hierba = null

    set hierba = CreateUnitAtLoc( GetOwningPlayer(caster), 'hpea',Location(x-i,y), bj_UNIT_FACING )
    call UnitApplyTimedLife( hierba,'BTLF', vidahierba)
    call UnitAddAbilityBJ( 'A026', hierba )
    call SetUnitAbilityLevelSwapped( 'A026', hierba, level )
    call GroupAddUnitSimple( hierba, udg_Enredaderas_Group )
    set hierba = null

    set hierba = CreateUnitAtLoc( GetOwningPlayer(caster), 'hpea',Location(x,y-i), bj_UNIT_FACING )
    call UnitApplyTimedLife( hierba,'BTLF', vidahierba)
    call UnitAddAbilityBJ( 'A026', hierba )
    call SetUnitAbilityLevelSwapped( 'A026', hierba, level )
    call GroupAddUnitSimple( hierba, udg_Enredaderas_Group )
    set hierba = null

//Then draw the lines who biseccioned the lasts lines

    set hierba = CreateUnitAtLoc( GetOwningPlayer(caster), 'hpea',Location(x+(i/SquareRoot(2)),y+(i/SquareRoot(2))), bj_UNIT_FACING )
    call UnitApplyTimedLife( hierba,'BTLF', vidahierba)
    call UnitAddAbilityBJ( 'A026', hierba )
    call SetUnitAbilityLevelSwapped( 'A026', hierba, level )
    call GroupAddUnitSimple( hierba, udg_Enredaderas_Group )
    set hierba = null

    set hierba = CreateUnitAtLoc( GetOwningPlayer(caster), 'hpea',Location(x-(i/SquareRoot(2)),y+i/SquareRoot(2)), bj_UNIT_FACING )
     call UnitApplyTimedLife( hierba,'BTLF', vidahierba)
    call UnitAddAbilityBJ( 'A026', hierba )
    call SetUnitAbilityLevelSwapped( 'A026', hierba, level )
    call GroupAddUnitSimple( hierba, udg_Enredaderas_Group )
    set hierba = null

    set hierba = CreateUnitAtLoc( GetOwningPlayer(caster), 'hpea',Location(x+(i/SquareRoot(2)),y-(i/SquareRoot(2))), bj_UNIT_FACING )
    call UnitApplyTimedLife( hierba,'BTLF', vidahierba)
    call UnitAddAbilityBJ( 'A026', hierba )
    call SetUnitAbilityLevelSwapped( 'A026', hierba, level )
    call GroupAddUnitSimple( hierba, udg_Enredaderas_Group )
    set hierba = null

    set hierba = CreateUnitAtLoc( GetOwningPlayer(caster), 'hpea',Location(x-(i/SquareRoot(2)),y-(i/SquareRoot(2))), bj_UNIT_FACING )
    call UnitApplyTimedLife( hierba,'BTLF', vidahierba)
    call UnitAddAbilityBJ( 'A026', hierba )
    call SetUnitAbilityLevelSwapped( 'A026', hierba, level )
    call GroupAddUnitSimple( hierba, udg_Enredaderas_Group )
    set hierba = null

//Then adicional lines

    set hierba = CreateUnitAtLoc( GetOwningPlayer(caster), 'hpea',Location(x+(i/2),y+(SquareRoot(3)*i/2)), bj_UNIT_FACING )
    call UnitApplyTimedLife( hierba,'BTLF', vidahierba)
    call UnitAddAbilityBJ( 'A026', hierba )
    call SetUnitAbilityLevelSwapped( 'A026', hierba, level )
    call GroupAddUnitSimple( hierba, udg_Enredaderas_Group )
    set hierba = null

    set hierba = CreateUnitAtLoc( GetOwningPlayer(caster), 'hpea',Location(x-(i/2),y+(SquareRoot(3)*i/2)), bj_UNIT_FACING )
    call UnitApplyTimedLife( hierba,'BTLF', vidahierba)
    call UnitAddAbilityBJ( 'A026', hierba )
    call SetUnitAbilityLevelSwapped( 'A026', hierba, level )
    call GroupAddUnitSimple( hierba, udg_Enredaderas_Group )
    set hierba = null

    set hierba = CreateUnitAtLoc( GetOwningPlayer(caster), 'hpea',Location(x+(i/2),y-(SquareRoot(3)*i/2)), bj_UNIT_FACING )
    call UnitApplyTimedLife( hierba,'BTLF', vidahierba)
    call UnitAddAbilityBJ( 'A026', hierba )
    call SetUnitAbilityLevelSwapped( 'A026', hierba, level )
    call GroupAddUnitSimple( hierba, udg_Enredaderas_Group )
    set hierba = null

    set hierba = CreateUnitAtLoc( GetOwningPlayer(caster), 'hpea',Location(x-(i/2),y-(SquareRoot(3)*i/2)), bj_UNIT_FACING )
    call UnitApplyTimedLife( hierba,'BTLF', vidahierba)
    call UnitAddAbilityBJ( 'A026', hierba )
    call SetUnitAbilityLevelSwapped( 'A026', hierba, level )
    call GroupAddUnitSimple( hierba, udg_Enredaderas_Group )
    set hierba = null


    set i = i + 50

endloop

endfunction

//===========================================================================
function InitTrig_Enredaderas takes nothing returns nothing
    set gg_trg_Enredaderas = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Enredaderas, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Enredaderas, Condition( function Trig_Enredaderas_Conditions ) )
    call TriggerAddAction( gg_trg_Enredaderas, function Trig_Enredaderas_Actions )
endfunction

EnredaderasEffect
Trigger:
EnredaderasEffect
Collapse Events
Time - Every 0.10 seconds of game time
Collapse Conditions
(Enredaderas_Group is empty) Equal to False
Collapse Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
(Enredaderas_Group is empty) Equal to False
Collapse Then - Actions
Collapse Unit Group - Pick every unit in Enredaderas_Group and do (Actions)
Collapse Loop - Actions
Set Hierba_pos = (Position of (Picked unit))
Set Enredados_Group = (Units within 100.00 of Hierba_pos matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is dead) Equal to False) and (((Matching unit) belongs to an enemy of (Owner of (Picked unit))) Equal to True))))
Unit - Order (Picked unit) to Night Elf Keeper Of The Grove - Entangling Roots (Random unit from Enredados_Group)
Custom script: call RemoveLocation(udg_Hierba_pos)
Custom script: call DestroyGroup(udg_Enredados_Group)
Collapse Else - Actions
Custom script: call DestroyGroup(udg_Enredaderas_Group)

Well, the spell works very well, but when the herbs dies (or when his timer life is over) cause lag. Wtf Wtf Why??? Somebody can help me???

Thanks in advance
06-12-2006, 02:20 PM#2
Jacek
I don't have time to get into it but you are leaking alot of locations (your "Location(X,Y)" functions
06-12-2006, 02:26 PM#3
GALLED
But the leak (and are a major leak!) are just when the herbs (unit hierba) dies! Why?
06-12-2006, 02:26 PM#4
Captain Griffen
You keep nullifying the unit variable. It only has to be nullified at the end; doing it in the middle may even make it unusable afterwards. You also use a lot of BJs; recommend that you extract and look at the Blizzard.j and common.j files.

Suggest that you remove all the dead herbs from the unit group.
06-13-2006, 01:04 PM#5
BertTheJasser
1. Create a dummy unit at the target xy.
2. Create a local trigger.
3. Add this event to the trigger with your dummy unit as 'whichUnit'.

Collapse JASS:
native TriggerRegisterUnitInRange takes trigger whichTrigger, unit whichUnit, real range, boolexpr filter returns event

4. Add the triggeraction you want and attach/store it to the trigger.
5. Attach/store everything you need in the triggeraction to the trigger.
6. Refer via 'GetTriggerUnit()' to the unit that eneters the region (in triggeraction func)
7. Do your depending actions.
8. PM as you did not get anything. ;D
============================
9. Add a Expiration timer to the dummy unit with the dur of the spell.
10. Add a triggerevent when a unit dies withethe dummy unit as arguament aswell as the created trigger and the evnet 'EVENT_UNIT_DEATH'
11. Differ in the triggeraction via 'GetTriggerEventId()' (beware the leak!) if the spell is finished or a unit enetered.
12. Finish. Remove the stored triggeraction from the trigger. Flush everything attached to the trigger. Destroy the trigger. Remove the dummy unit.
13. Do your depending actions as alöready said.
06-13-2006, 01:18 PM#6
Vexorian
GetTriggerEventId() doesn't leak...
06-14-2006, 08:35 AM#7
BertTheJasser
I thougth he migth store it into a var and he (maybe/probably) forgets to nullify.
Sorry for the missunderstanding(?).
06-14-2006, 01:21 PM#8
Vexorian
I am still not sure if you have to set that kind of handle (including players) to null, since the leak seems to be about reference kidnapping and these handles always got the same handle id . Some one should test this
06-14-2006, 05:12 PM#9
BertTheJasser
Hmm... yes someone should, but I myself can not, as I do not have expirience with memory/leak stuff.
06-14-2006, 11:59 PM#10
GALLED
Well, i'm change the code for the spell:

Collapse JASS:

//---------------------------------------------------------------------

function PolarProjectionX takes real punto, real distancia, real angulo returns real
   return punto+distancia*Cos(angulo*bj_DEGTORAD)
endfunction

function PolarProjectionY takes real punto, real distancia, real angulo returns real
   return punto+distancia*Sin(angulo*bj_DEGTORAD)
endfunction

function Trig_Enredaderas_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A021' 
endfunction

function EnredaderasEffect takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit hierba 
local unit enredado 
local location p 
local group hg = GetHandleGroup(t,"hg")
local group tg = hg
local group eg = CreateGroup()

loop
    set hierba = FirstOfGroup(tg)
    exitwhen hierba==null
    call GroupRemoveUnit(hg,hierba)
    set p = GetUnitLoc(hierba)
    set eg = GetUnitsInRangeOfLocAll(100, p)
    loop
        set enredado = FirstOfGroup(eg)
        exitwhen enredado==null
        call GroupRemoveUnit(eg,enredado)
        if IsUnitEnemy(enredado,GetOwningPlayer(hierba))==true then
              call IssueTargetOrder(hierba,"entanglingroots",enredado)
        endif
    endloop 
endloop

set t = null
call RemoveLocation(p)
set hg = null
call DestroyGroup(tg)
call DestroyGroup(eg)
set hierba = null
set enredado = null

endfunction

function Trig_Enredaderas_Actions takes nothing returns nothing

local timer t = CreateTimer()
local unit caster = GetTriggerUnit()
local integer level = GetUnitAbilityLevelSwapped('A021', caster)
local unit hierba
local unit enredado
local group hg = CreateGroup() 
local real x = GetLocationX(GetSpellTargetLoc())
local real y = GetLocationY(GetSpellTargetLoc())
local real radio = 150 + 50*level
local integer angulo
local integer j
local real vidahierba = 2.25 + 0.75*level

//For draw the herbs like a circle
set angulo = 0
loop
    exitwhen (angulo>360)

   set j=0
   loop
   exitwhen (j>=radio)
    set hierba = CreateUnit( GetOwningPlayer(caster), 'hpea',PolarProjectionX(x,j,angulo),PolarProjectionY(y,j,angulo), bj_UNIT_FACING )
    call UnitApplyTimedLife( hierba,'BTLF', vidahierba)
    call UnitAddAbilityBJ( 'A026', hierba )
    call SetUnitAbilityLevelSwapped( 'A026', hierba, level )
    call GroupAddUnit(hg,hierba)
    set j=j+50
   endloop
set angulo = angulo + 30

endloop
  
    call SetHandleHandle(t,"hg",hg)
    call TimerStart(t,0.1,true,function EnredaderasEffect)
    call TriggerSleepAction(vidahierba)
    call FlushHandleLocals(t)
    call DestroyTimer(t)
    call DestroyGroup(hg)
    set t=null
    set caster = null
    set hierba = null
    set enredado = null
endfunction

//===========================================================================
function InitTrig_Enredaderas takes nothing returns nothing
local trigger gg_trg_Enredaderas
    set gg_trg_Enredaderas = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Enredaderas, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Enredaderas, Condition( function Trig_Enredaderas_Conditions ) )
    call TriggerAddAction( gg_trg_Enredaderas, function Trig_Enredaderas_Actions )
endfunction

and this one for avoid the leak:
Collapse JASS:
function Trig_EnredaderasDie_Conditions takes nothing returns boolean
    if ( not ( GetUnitTypeId(GetDyingUnit()) == 'hpea' ) ) then
        return false
    endif
    return true
endfunction

function Trig_EnredaderasDie_Actions takes nothing returns nothing
    call TriggerSleepAction(0.5)
    call RemoveUnit( GetDyingUnit() )
endfunction

//===========================================================================
function InitTrig_EnredaderasDie takes nothing returns nothing
    set gg_trg_EnredaderasDie = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_EnredaderasDie, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_EnredaderasDie, Condition( function Trig_EnredaderasDie_Conditions ) )
    call TriggerAddAction( gg_trg_EnredaderasDie, function Trig_EnredaderasDie_Actions )
endfunction


But, now it doesn't works!!! The entangling roots doesn't entangle!!!

What i'm doing bad???

(Ah!, create a dummy unit, when a unit aproach the entangles doesn't sound bad, but it's suposed that the dummycasters are the herbs..)
06-15-2006, 07:30 AM#11
BertTheJasser
Collapse JASS:
    set p = GetUnitLoc(hierba)
    set eg = GetUnitsInRangeOfLocAll(100, p)
This means that you only pick units that are in rnage of 100 of one of the "circleunits".

Collapse JASS:
    loop
        set enredado = FirstOfGroup(eg)
        exitwhen enredado==null
        call GroupRemoveUnit(eg,enredado)
        if IsUnitEnemy(enredado,GetOwningPlayer(hierba))==true then
              call IssueTargetOrder(hierba,"entanglingroots",enredado)
        endif
    endloop 
And this means, that, if there are more than one unit in rnage only one unit will be entangled, as entangling roots needs alil delay (not 100% sure).

Collapse JASS:
local group hg = GetHandleGroup(t,"hg")
local group tg = hg
local group eg = CreateGroup()
And THIS is the actually thing why the spell does not work.
tg is just a "link" to hg and not a new group, so in your code, you remove units from the "link" AND from the actually group at once. You must create a new group and add via
Collapse JASS:
set tg=CreateGroup()
set bj_wantDestroyGroup=false
call GroupAddGroup(hg,tg)
//...do the things
call DestroyGroup(tg)
set tg=null
every single unit to the new group

I guess this should do the job. ;D

Btw: Get rid of all that nasty BJ/swapped functions.
06-15-2006, 02:25 PM#12
GALLED
Yes, this one is my problem now
Quote:
Originally Posted by BertTheJasser

Collapse JASS:
    loop
        set enredado = FirstOfGroup(eg)
        exitwhen enredado==null
        call GroupRemoveUnit(eg,enredado)
        if IsUnitEnemy(enredado,GetOwningPlayer(hierba))==true then
              call IssueTargetOrder(hierba,"entanglingroots",enredado)
        endif
    endloop 
And this means, that, if there are more than one unit in rnage only one unit will be entangled, as entangling roots needs alil delay (not 100% sure).

How to make the unit hierba entangles all the units around 100 range? Now only works once. (The dummyspell has 0 of cooldown)
06-15-2006, 02:27 PM#13
harshateja
Why bother doing that? You might as well use ForGroup because it will work.
06-15-2006, 03:01 PM#14
GALLED
So, i'm change the code to this one:
Collapse JASS:

function PolarProjectionX takes real punto, real distancia, real angulo returns real
   return punto+distancia*Cos(angulo*bj_DEGTORAD)
endfunction

function PolarProjectionY takes real punto, real distancia, real angulo returns real
   return punto+distancia*Sin(angulo*bj_DEGTORAD)
endfunction

function Trig_Enredaderas_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A021' 
endfunction

function EnredaderasEffect takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit dumb 
local unit enredado
local unit caster = GetHandleUnit(t,"caster")
local real x = GetHandleReal(t,"x")
local real y = GetHandleReal(t,"y")
local real x1 
local real y1 
local real radio = GetHandleReal(t,"radio")
local integer level = GetHandleInt(t,"level")
local group eg = CreateGroup()

    set eg = GetUnitsInRangeOfLocAll(radio, Location(x,y))
    set enredado = FirstOfGroup(eg)
    loop
        set enredado = FirstOfGroup(eg)
        set x1 = GetUnitX(enredado)
        set y1 = GetUnitY(enredado)
        exitwhen enredado==null
        call GroupRemoveUnit(eg,enredado)
        if IsUnitAliveBJ(enredado) and IsUnitAlly(enredado,GetOwningPlayer(caster))==false then
         set dumb = CreateUnit( GetOwningPlayer(caster), 'h00C',x1,y1, bj_UNIT_FACING )
    
              call UnitAddAbility( dumb, 'A026' )
              call SetUnitAbilityLevel(dumb, 'A026', level )
              call IssueTargetOrder(dumb,"entanglingroots",enredado)
              call UnitApplyTimedLife( dumb,'BTLF', 1)
        set dumb = null

        endif
    endloop 


set t = null
call RemoveLocation(Location(x,y))
call DestroyGroup(eg)
set enredado = null
set caster = null

endfunction

function Trig_Enredaderas_Actions takes nothing returns nothing

local timer t = CreateTimer()
local unit caster = GetTriggerUnit()
local integer level = GetUnitAbilityLevelSwapped('A021', caster)
local unit hierba
local real x = GetLocationX(GetSpellTargetLoc())
local real y = GetLocationY(GetSpellTargetLoc())
local real radio = 150 + 50*level
local integer angulo
local integer j
local real vidahierba = 2.25 + 0.75*level

//For draw the herbs like a circle
set angulo = 0
loop
    exitwhen (angulo>360)

   set j=0
   loop
   exitwhen (j>=radio)
    set hierba = CreateUnit( GetOwningPlayer(caster), 'hpea',PolarProjectionX(x,j,angulo),PolarProjectionY(y,j,angulo), bj_UNIT_FACING )
    set j=j+50
   endloop
set angulo = angulo + 30

endloop
call IssueImmediateOrder( caster, "stop" )  
    call SetHandleHandle(t,"caster",caster)
    call SetHandleHandle(t,"radio",radio)
    call SetHandleHandle(t,"level",level)
    call SetHandleHandle(t,"x",x)
    call SetHandleHandle(t,"y",y)
    call TimerStart(t,0.1,true,function EnredaderasEffect)
    call TriggerSleepAction(vidahierba)
    call FlushHandleLocals(t)
    call DestroyTimer(t)
    set t=null
    set caster = null
    set hierba = null
endfunction

//===========================================================================
function InitTrig_Enredaderas takes nothing returns nothing
local trigger gg_trg_Enredaderas
    set gg_trg_Enredaderas = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Enredaderas, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Enredaderas, Condition( function Trig_Enredaderas_Conditions ) )
    call TriggerAddAction( gg_trg_Enredaderas, function Trig_Enredaderas_Actions )
endfunction

And has the same problem: Only entangles once. And when a unit aproaches to the herbs doesen't entangles that unit. So what happends?? How i can make the dummyunits or the herbs entangles some unit around it?
06-16-2006, 12:16 AM#15
GALLED
Fiuuuuuu!!!!!

Now works fine!!!

Collapse JASS:

//---------------------------------------------------------------------
function Msg takes string s returns nothing
call DisplayTextToPlayer(Player(1),0,0,s)
endfunction

function PolarProjectionX takes real punto, real distancia, real angulo returns real
   return punto+distancia*Cos(angulo*bj_DEGTORAD)
endfunction

function PolarProjectionY takes real punto, real distancia, real angulo returns real
   return punto+distancia*Sin(angulo*bj_DEGTORAD)
endfunction

function Trig_Enredaderas_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A021' 
endfunction
function Trig_e_Func001001003001 takes nothing returns boolean
    return ( IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false )
endfunction

function Trig_e_Func001001003002001 takes nothing returns boolean
    return ( IsUnitDeadBJ(GetFilterUnit()) == false )
endfunction

function Trig_e_Func001001003002002 takes nothing returns boolean
    return ( IsUnitAlly(GetFilterUnit(), GetOwningPlayer(GetEnumUnit())) == false )
endfunction

function Trig_e_Func001001003002 takes nothing returns boolean
    return GetBooleanAnd( Trig_e_Func001001003002001(), Trig_e_Func001001003002002() )
endfunction

function Trig_e_Func001001003 takes nothing returns boolean
    return GetBooleanAnd( Trig_e_Func001001003001(), Trig_e_Func001001003002() )
endfunction

function amarrar takes nothing returns nothing
local real x1 = GetUnitX(GetEnumUnit())
local real y1 = GetUnitY(GetEnumUnit())
local group eg = GetUnitsInRangeOfLocMatching(100.00, Location(x1,y1), Condition(function Trig_e_Func001001003))
    call IssueTargetOrder( GetEnumUnit(), "entanglingroots", GroupPickRandomUnit(eg) )
    call RemoveLocation(Location(x1,y1))
    call DestroyGroup(eg)
endfunction

function EnredaderasEffect takes nothing returns nothing
local timer t = GetExpiredTimer()
local group hg = GetHandleGroup(t,"hg")

if CountUnitsInGroup(hg)>0  then
call ForGroup(hg,function amarrar)
else
call DestroyGroup(hg)
endif
set t = null
endfunction

function Trig_Enredaderas_Actions takes nothing returns nothing

local timer t = CreateTimer()
local unit caster = GetTriggerUnit()
local integer level = GetUnitAbilityLevelSwapped('A021', caster)
local unit hierba
local unit enredado
local group hg = CreateGroup() 
local real x = GetLocationX(GetSpellTargetLoc())
local real y = GetLocationY(GetSpellTargetLoc())
local real radio = 150 + 50*level
local integer angulo
local integer j
local real vidahierba = 2.25 + 0.75*level

//For draw the herbs like a circle
set angulo = 0
loop
    exitwhen (angulo>360)

   set j=0
   loop
   exitwhen (j>=radio)
    set hierba = CreateUnit( GetOwningPlayer(caster), 'hpea',PolarProjectionX(x,j,angulo),PolarProjectionY(y,j,angulo), bj_UNIT_FACING )
    call UnitApplyTimedLife( hierba,'BTLF', vidahierba)
    call UnitAddAbilityBJ( 'A026', hierba )
    call SetUnitAbilityLevelSwapped( 'A026', hierba, level )
    call GroupAddUnit(hg,hierba)
    set j=j+50
   endloop
set angulo = angulo + 30

endloop
    call IssueImmediateOrder( caster, "stop" )  
    call SetHandleHandle(t,"hg",hg)
    call TimerStart(t,0.1,true,function EnredaderasEffect)
    call TriggerSleepAction(vidahierba)
    call FlushHandleLocals(t)
    call DestroyTimer(t)
    call DestroyGroup(hg)
    set t=null
    set caster = null
    set hierba = null
    set enredado = null
endfunction

//===========================================================================
function InitTrig_Enredaderas takes nothing returns nothing
local trigger gg_trg_Enredaderas
    set gg_trg_Enredaderas = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Enredaderas, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Enredaderas, Condition( function Trig_Enredaderas_Conditions ) )
    call TriggerAddAction( gg_trg_Enredaderas, function Trig_Enredaderas_Actions )
endfunction

Can be some manner to optimize this spell??