HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Attaching Handles to Units

02-24-2006, 05:21 AM#1
emjlr3
working on an ability, basically it sucks unit with a range of casting point in towards the center, of the units get to close to the center, it spits them back out, here is the code:
Collapse JASS:
function Black_Hole_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetSummonedUnit()) == 'u001'         
endfunction

function Black_Hole_Filter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0     
endfunction

function Black_Hole_Effects2 takes nothing returns nothing
    local timer t2 = GetExpiredTimer() 
    local unit u = GetHandleUnit(u,"u")
    local unit v = GetHandleUnit(u,"v")
    local unit w   
    local group g = GetHandleGroup(u,"g")    
    local location l        
    local location m = GetUnitLoc(v) 
    local location n  
    
    loop
        set w = FirstOfGroup(g)
        exitwhen w == null
        set l = GetUnitLoc(w)
        if DistanceBetweenPoints(l, m) <= 775.00 and GetUnitState(u, UNIT_STATE_LIFE) > 0 then
            set n = PolarProjectionBJ(l, ( DistanceBetweenPoints(l, m) + 10), AngleBetweenPoints(l, m))
            call SetUnitPositionLoc( w, n )
            call RemoveLocation(n)
        else
            call GroupRemoveUnit(g,w)
        endif
        call RemoveLocation(l)
    endloop
    call SetHandleHandle(u,"g",g)
 
    call RemoveLocation(m)
    call RemoveLocation(n)
    set m = null
    set n = null
    set l = null
    set u = null
    set v = null    
    set t2 = null        
endfunction

function Black_Hole_Effects takes nothing returns nothing
    local timer t = GetExpiredTimer()    
    local unit u = GetHandleUnit(u, "u")
    local unit v = GetHandleUnit(u, "v")
    local unit w
    local location l = GetUnitLoc(v)
    local location m    
    local location n
    local group g = CreateGroup()
    set g = GroupEnumUnitsInRangeOfLoc(g,l,375+(125*GetUnitAbilityLevel(u,'A000')),Condition(function Black_Hole_Filter))   
    loop
        set w = FirstOfGroup(g)
        exitwhen w == null                
        call GroupRemoveUnit(g,w)                            
        set m = GetUnitLoc(w)               
        if DistanceBetweenPoints(l, m) <= 200.00 then                
            call GroupAddUnit(GetHandleGroup(u,"g"),w)                    
        endif
        if IsUnitInGroup(w,GetHandleGroup(u,"g"))==false then                                  
            set n = PolarProjectionBJ(l, ( DistanceBetweenPoints(l, m) - (3.75+(1.25*GetUnitAbilityLevel(u,'A000')))), AngleBetweenPoints(l, m))                      
            call SetUnitPositionLoc( w, n )
            call RemoveLocation(n)
        endif                          
        call RemoveLocation(m)       
    endloop  
  
    set u = null
    set v = null
    set m = null
    call RemoveLocation(l)
    set l = null
    call DestroyGroup(g)
    set g = null
    set t = null
    set n = null
endfunction

function Black_Hole_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local timer t = CreateTimer()
    local timer t2 = CreateTimer()
    local group g = CreateGroup()    
     
    call SetHandleHandle(u, "u", u)
    call SetHandleHandle(u, "v", GetSummonedUnit())
    call SetHandleHandle(u,"g",g)
    call TimerStart(t, 0.05, true, function Black_Hole_Effects)
    call TimerStart(t2, 0.05, true, function Black_Hole_Effects2)
    call TriggerSleepAction(5)    
    call PauseTimer(t)
    call PauseTimer(t2)    
    call FlushHandleLocals(u)

    call DestroyTimer(t) 
    call DestroyTimer(t2)
    set t = null  
    set t2 = null
    set u = null
    call DestroyGroup(g)
    set g = null     
endfunction

//===========================================================================
function InitTrig_Black_Hole takes nothing returns nothing
    set gg_trg_Black_Hole = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Black_Hole, EVENT_PLAYER_UNIT_SUMMON )
    call TriggerAddCondition( gg_trg_Black_Hole, Condition( function Black_Hole_Conditions ) )
    call TriggerAddAction( gg_trg_Black_Hole, function Black_Hole_Actions )
endfunction

im getting all sorts of crazy errors starting with the first

local unit u = GetHandleUnit(u,"u")

any and all help appreciated, ty

(note this is not fully optimized so there may be some leaks here or there)
02-24-2006, 06:17 AM#2
Anitarf
local unit u = GetHandleUnit(u,"u")

So, you define u as a unit attached to u, which is at the time not yet defined, since you're still defining it? Makes no sense.
02-24-2006, 12:07 PM#3
Vexorian
yep that's the problem, and there isn't any logic behind that operation
02-24-2006, 01:47 PM#4
emjlr3
I jkust figured since I stored u as the triggerunit of the spell, and attached it to the trigger unit of the spell, then set a local unit u = to this in a different function would not be a problem, I just did it so I just kept all my u's as teh trigger unit, so i did not get confused, I am not exactly sure what I am supposed to change here
02-24-2006, 02:17 PM#5
Vexorian
your post doesn't make any sense,

The code you posted doesn't make any sense either

Collapse Oh my god!:
    local unit u = GetTriggerUnit()
    local timer t = CreateTimer()
    local timer t2 = CreateTimer()
    local group g = CreateGroup()    
     
    call SetHandleHandle(u, "u", u)

Why, and exactly why do you link a unit to itself? what's exactly what you want to do?
02-24-2006, 02:27 PM#6
Blade.dk
I think that what you want to do is to attach the unit to the timer so you can use it in the expiration function? So it would be like this:

Collapse JASS:

function Black_Hole_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetSummonedUnit()) == 'u001'         
endfunction

function Black_Hole_Filter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0     
endfunction

function Black_Hole_Effects2 takes nothing returns nothing
    local timer t2 = GetExpiredTimer() 
    local unit u = GetHandleUnit(t2,"u")
    local unit v = GetHandleUnit(t2,"v")
    local unit w   
    local group g = GetHandleGroup(t2,"g")    
    local location l        
    local location m = GetUnitLoc(v) 
    local location n  
    
    loop
        set w = FirstOfGroup(g)
        exitwhen w == null
        set l = GetUnitLoc(w)
        if DistanceBetweenPoints(l, m) <= 775.00 and GetUnitState(u, UNIT_STATE_LIFE) > 0 then
            set n = PolarProjectionBJ(l, ( DistanceBetweenPoints(l, m) + 10), AngleBetweenPoints(l, m))
            call SetUnitPositionLoc( w, n )
            call RemoveLocation(n)
        else
            call GroupRemoveUnit(g,w)
        endif
        call RemoveLocation(l)
    endloop
    call SetHandleHandle(t2,"g",g)
 
    call RemoveLocation(m)
    call RemoveLocation(n)
    set m = null
    set n = null
    set l = null
    set u = null
    set v = null    
    set t2 = null        
endfunction

function Black_Hole_Effects takes nothing returns nothing
    local timer t = GetExpiredTimer()    
    local unit u = GetHandleUnit(t, "u")
    local unit v = GetHandleUnit(t, "v")
    local unit w
    local location l = GetUnitLoc(v)
    local location m    
    local location n
    local group g = CreateGroup()
    set g = GroupEnumUnitsInRangeOfLoc(g,l,375+(125*GetUnitAbilityLevel(u,'A000')),Condition(function Black_Hole_Filter))   
    loop
        set w = FirstOfGroup(g)
        exitwhen w == null                
        call GroupRemoveUnit(g,w)                            
        set m = GetUnitLoc(w)               
        if DistanceBetweenPoints(l, m) <= 200.00 then                
            call GroupAddUnit(GetHandleGroup(u,"g"),w)                    
        endif
        if IsUnitInGroup(w,GetHandleGroup(t,"g"))==false then                                  
            set n = PolarProjectionBJ(l, ( DistanceBetweenPoints(l, m) - (3.75+(1.25*GetUnitAbilityLevel(u,'A000')))), AngleBetweenPoints(l, m))                      
            call SetUnitPositionLoc( w, n )
            call RemoveLocation(n)
        endif                          
        call RemoveLocation(m)       
    endloop  
  
    set u = null
    set v = null
    set m = null
    call RemoveLocation(l)
    set l = null
    call DestroyGroup(g)
    set g = null
    set t = null
    set n = null
endfunction

function Black_Hole_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local timer t = CreateTimer()
    local timer t2 = CreateTimer()
    local group g = CreateGroup()    
     
    call SetHandleHandle(t, "u", u)
    call SetHandleHandle(t, "v", GetSummonedUnit())
    call SetHandleHandle(t,"g",g)

    call SetHandleHandle(t2, "u", u)
    call SetHandleHandle(t2, "v", GetSummonedUnit())
    call SetHandleHandle(t2,"g",g)

    call TimerStart(t, 0.05, true, function Black_Hole_Effects)
    call TimerStart(t2, 0.05, true, function Black_Hole_Effects2)
    call TriggerSleepAction(5)    
    call PauseTimer(t)
    call PauseTimer(t2)    
    call FlushHandleLocals(t)
    call FlushHandleLocals(t2)

    call DestroyTimer(t) 
    call DestroyTimer(t2)
    set t = null  
    set t2 = null
    set u = null
    call DestroyGroup(g)
    set g = null     
endfunction

//===========================================================================
function InitTrig_Black_Hole takes nothing returns nothing
    set gg_trg_Black_Hole = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Black_Hole, EVENT_PLAYER_UNIT_SUMMON )
    call TriggerAddCondition( gg_trg_Black_Hole, Condition( function Black_Hole_Conditions ) )
    call TriggerAddAction( gg_trg_Black_Hole, function Black_Hole_Actions )
endfunction

02-24-2006, 04:16 PM#7
emjlr3
Daelin told me I could attach things to units, because the idea was I wanted to be able to add units to group g in function Black_Hole_Effects, as well as manipulate units in group g in function Black_Hole_Effects2, Daelin said by doing this(linking everything to the trigger unit), i could freely use both units u and v, as well as group g in each function

with what you suggested Blade, I dont think I can do this, since group g attacked to t and group g attached to t2 are two different groups, or am i wrong?
02-24-2006, 04:24 PM#8
Vexorian
They are the same group
02-24-2006, 04:30 PM#9
emjlr3
so they are interchangable, and adding a unit to (t,"g") and calling it in the other function with (t2,"g") will give me the same exact group, let me update the code a bit and see if I got this

Collapse JASS:
function Black_Hole_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetSummonedUnit()) == 'u001'         
endfunction

function Black_Hole_Filter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0     
endfunction

function Black_Hole_Effects2 takes nothing returns nothing
    local timer t2 = GetExpiredTimer() 
    local unit u = GetHandleUnit(t2,"u")
    local unit v = GetHandleUnit(t2,"v")
    local unit w   
    local group g = GetHandleGroup(t2,"g")    
    local location l        
    local location m = GetUnitLoc(v) 
    local location n  
    
    loop
        set w = FirstOfGroup(g)
        exitwhen w == null
        set l = GetUnitLoc(w)
        if DistanceBetweenPoints(l, m) <= 775.00 and GetUnitState(u, UNIT_STATE_LIFE) > 0 then
            set n = PolarProjectionBJ(l, ( DistanceBetweenPoints(l, m) + 10), AngleBetweenPoints(l, m))
            call SetUnitPositionLoc( w, n )
            call RemoveLocation(n)
        else
            call GroupRemoveUnit(g,w)
        endif
        call RemoveLocation(l)
    endloop
    call SetHandleHandle(t2,"g",g)
 
    call RemoveLocation(m)
    call RemoveLocation(n)
    set m = null
    set n = null
    set l = null
    set u = null
    set v = null    
    set t2 = null        
endfunction

function Black_Hole_Effects takes nothing returns nothing
    local timer t = GetExpiredTimer()    
    local unit u = GetHandleUnit(t, "u")
    local unit v = GetHandleUnit(t, "v")
    local unit w
    local location l = GetUnitLoc(v)
    local location m    
    local location n
    local group g = CreateGroup()
    set g = GroupEnumUnitsInRangeOfLoc(g,l,375+(125*GetUnitAbilityLevel(u,'A000')),Condition(function Black_Hole_Filter))   
    loop
        set w = FirstOfGroup(g)
        exitwhen w == null                
        call GroupRemoveUnit(g,w)                            
        set m = GetUnitLoc(w)               
        if DistanceBetweenPoints(l, m) <= 200.00 then                
            call GroupAddUnit(GetHandleGroup(t,"g"),w)                    
        endif
        if IsUnitInGroup(w,GetHandleGroup(t,"g"))==false then                                  
            set n = PolarProjectionBJ(l, ( DistanceBetweenPoints(l, m) - (3.75+(1.25*GetUnitAbilityLevel(u,'A000')))), AngleBetweenPoints(l, m))                      
            call SetUnitPositionLoc( w, n )
            call RemoveLocation(n)
        endif                          
        call RemoveLocation(m)       
    endloop  
  
    set u = null
    set v = null
    set m = null
    call RemoveLocation(l)
    set l = null
    call DestroyGroup(g)
    set g = null
    set t = null
    set n = null
endfunction

function Black_Hole_Actions takes nothing returns nothing    
    local timer t = CreateTimer()
    local timer t2 = CreateTimer()
    local group g = CreateGroup()    
     
    call SetHandleHandle(t, "u", GetTriggerUnit())
    call SetHandleHandle(t, "v", GetSummonedUnit())
    call SetHandleHandle(t,"g",g)

    call SetHandleHandle(t2, "u", GetTriggerUnit())
    call SetHandleHandle(t2, "v", GetSummonedUnit())
    call SetHandleHandle(t2,"g",g)

    call TimerStart(t, 0.05, true, function Black_Hole_Effects)
    call TimerStart(t2, 0.05, true, function Black_Hole_Effects2)
    call TriggerSleepAction(5)    
    call PauseTimer(t)
    call PauseTimer(t2)    
    call FlushHandleLocals(t)
    call FlushHandleLocals(t2)

    call DestroyTimer(t) 
    call DestroyTimer(t2)
    set t = null  
    set t2 = null    
    call DestroyGroup(g)
    set g = null     
endfunction

//===========================================================================
function InitTrig_Black_Hole takes nothing returns nothing
    set gg_trg_Black_Hole = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Black_Hole, EVENT_PLAYER_UNIT_SUMMON )
    call TriggerAddCondition( gg_trg_Black_Hole, Condition( function Black_Hole_Conditions ) )
    call TriggerAddAction( gg_trg_Black_Hole, function Black_Hole_Actions )
endfunction

(i havent got access to WE ATM so I cant check to see if it will save)
03-01-2006, 02:39 AM#10
emjlr3
bump

I tried in WE, and got it to save, this is what I have

Collapse JASS:
function Black_Hole_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetSummonedUnit()) == 'u001'         
endfunction

function Black_Hole_Filter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0     
endfunction

function Black_Hole_Effects2 takes nothing returns nothing
    local timer t2 = GetExpiredTimer() 
    local unit u = GetHandleUnit(t2,"u")
    local unit v = GetHandleUnit(t2,"v")
    local unit w    
    local group g = GetHandleGroup(t2,"g")    
    local location l        
    local location m = GetUnitLoc(v) 
    local location n  
    
    loop
        set w = FirstOfGroup(g)
        exitwhen w == null
        set l = GetUnitLoc(w)
        if DistanceBetweenPoints(l, m) <= 775.00 and GetUnitState(u, UNIT_STATE_LIFE) > 0 then
            set n = PolarProjectionBJ(l, ( DistanceBetweenPoints(l, m) + 10), AngleBetweenPoints(l, m))
            call SetUnitPositionLoc( w, n )
            call RemoveLocation(n)
        else
            call GroupRemoveUnit(GetHandleGroup(t2,"g"),w)
        endif
        call RemoveLocation(l)
    endloop    
 
    call RemoveLocation(m)
    call RemoveLocation(n)
    set m = null
    set n = null
    set l = null
    set u = null
    set v = null    
    set t2 = null        
endfunction

function Black_Hole_Effects takes nothing returns nothing
    local timer t = GetExpiredTimer()    
    local unit u = GetHandleUnit(t, "u")
    local unit v = GetHandleUnit(t, "v")
    local unit w
    local location l = GetUnitLoc(v)
    local location m    
    local location n
    local group g = CreateGroup()

    local boolexpr b = Condition(function Black_Hole_Filter)    
    call GroupEnumUnitsInRangeOfLoc(g,l,375+(125*GetUnitAbilityLevel(u,'A000')),b)   
    loop
        set w = FirstOfGroup(g)
        exitwhen w == null                
        call GroupRemoveUnit(g,w)                            
        set m = GetUnitLoc(w)               
        if DistanceBetweenPoints(l, m) <= 200.00 then                
            call GroupAddUnit(GetHandleGroup(t,"g"),w)                    
        endif
        if IsUnitInGroup(w,GetHandleGroup(t,"g"))==false then                                  
            set n = PolarProjectionBJ(l, ( DistanceBetweenPoints(l, m) - (3.75+(1.25*GetUnitAbilityLevel(u,'A000')))), AngleBetweenPoints(l, m))                      
            call SetUnitPositionLoc( w, n )
            call RemoveLocation(n)
        endif                          
        call RemoveLocation(m)       
    endloop  
  
    set u = null
    set v = null
    set m = null
    call RemoveLocation(l)
    set l = null
    call DestroyGroup(g)
    set g = null
    set t = null
    set n = null
    call DestroyBoolExpr(b)
    set b= null
endfunction

function Black_Hole_Actions takes nothing returns nothing    
    local timer t = CreateTimer()
    local timer t2 = CreateTimer()
    local group g = CreateGroup()    
     
    call SetHandleHandle(t, "u", GetTriggerUnit())
    call SetHandleHandle(t, "v", GetSummonedUnit())
    call SetHandleHandle(t,"g",g)

    call SetHandleHandle(t2, "u", GetTriggerUnit())
    call SetHandleHandle(t2, "v", GetSummonedUnit())
    call SetHandleHandle(t2,"g",g)

    call TimerStart(t, 0.05, true, function Black_Hole_Effects)
    call TimerStart(t2, 0.05, true, function Black_Hole_Effects2)
    call TriggerSleepAction(5)    
    call PauseTimer(t)
    call PauseTimer(t2)    
    call FlushHandleLocals(t)
    call FlushHandleLocals(t2)

    call DestroyTimer(t) 
    call DestroyTimer(t2)
    set t = null  
    set t2 = null    
    call DestroyGroup(g)
    set g = null     
endfunction

//===========================================================================
function InitTrig_Black_Hole takes nothing returns nothing
    set gg_trg_Black_Hole = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Black_Hole, EVENT_PLAYER_UNIT_SUMMON )
    call TriggerAddCondition( gg_trg_Black_Hole, Condition( function Black_Hole_Conditions ) )
    call TriggerAddAction( gg_trg_Black_Hole, function Black_Hole_Actions )
endfunction

still not working though, it seems to pull units in fine, but once a unit gets to that 200 mark, stuff screws up, and WC3 freezes, any ideas?
03-01-2006, 02:51 AM#11
Chuckle_Brother
Why even bother using handles? Just use tables, I have heard(from Vexorian's own mouth no less) that tables are superior.

P.S. Just about your first code, Vex didn't really give much explanation as to why it made no sense. Effectively what you were trying to do was get a unit that was attached to itself, but since it had no definition within the function that it was being pulled from itself there was no way it could ever have become existant in said function. If that makes any sense to anyone than I guess my work here is done.

Edit: Alright, I reviewed the code, and the only logical place that there should be an error at short distance is in this:
Collapse JASS:
if DistanceBetweenPoints(l, m) <= 200.00 then                
    call GroupAddUnit(GetHandleGroup(t,"g"),w)                    
endif

I'm not sure, but I don't think the game is liking this, I suggest buffering that group in a local then resetting the handle.

Of course I may be way off base, but it might be a place to start.
03-01-2006, 08:06 AM#12
Anitarf
The problem is in your Effects2 function, you get the group stored to the timer and then you try to loop through it directly. That won't work, why? Because for looping through the group, you must remove units from the group after you pick them; of course, this would remove them from the group, but you need the group to stay as it is, so you don't remove them, but now you get an infinite loop.

Of course, the loop shouldn't be infinite, the unit should be removed from the group when it's far away enough, however, you switched the locations m and l; they're defined exactly the opposite as in the other effect function, but you still use the same formula for getting n, so instead of the unit being pushed away, it starts infinitely jumping over the pushing unit.

So, fix the equation for n, and create another local group, add the group that is stored to the timer to this local group, and then loop through the local group, thus leaving the timer's group intact.
03-01-2006, 03:40 PM#13
emjlr3
alright fixed the removeunitgroup ( that was just dumb), fixed the polarprojection equation

and for looping through the unit group i first do
Collapse JASS:
local group g = GetHandleGroup(t2,"g")
so i actually loop through group g, not my handle group, so no units are removed from it unless the unit is more then 775 away, then i do

Collapse JASS:
call GroupRemoveUnit(GetHandleGroup(t2,"g"),w)

it seems to work fine, but now there is another problem, it seems that the part

Collapse JASS:
if IsUnitInGroup(w,GetHandleGroup(t,"g"))==false then


in function effects1 isnt working

the unts get sucked in until they are at 200 range, but then there seems to be a battle between the unit being sucked in and pushed back out for the duration, so it seems the unit are added to my handle group, but the function checking if they are in it or not is showing that they aren't

any more ideas... :(