HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Problem with grouping units

08-11-2008, 05:20 AM#1
Sophismata
I am attempting to create a timer that will apply invisibility to a unit once it is alone in a 600 AoE.

The problem I'm having has to do with unit groupings.

To explain, there are two functions. The first is a filter for the second, I included it because it is referenced, but I don't think it is causing the problem.

The second function is on a timer, and designed to do the following:

1. Determine if there are any enemy or allied units in range of the source unit.
2. If this is true, do nothing, and wait for the timer to expire again.
3. If this is false (there are no nearby units), then:
4. Give the source unit Permanent Invisibility and Ghost
5. Turn on Trigger (Trigger is used to determine when a unit gets in range via the RegisterUnitInRange event).
6. Destroy the timer so that this function won't run again unless recreated elsewhere.


The problem I'm having is that the group is not getting changed between iterations of the timer. Each time the timer expires, it should create a group, add units to that group, check the group, then destroy the group so the next expiration has a fresh group.

However, once a unit is added to the group, every subsequent iteration of the timer will add that same unit (let's call it unit X) to the group. The group is getting destroyed, because the number of units returned after DestroyGroup(g) runs is 0, but on the next timer expiry, unit X is re-added to the group (and no other unit) regardless of where that unit is.

Collapse JASS:
function ELEUnCloak_filter takes nothing returns boolean
// Check unit is ALive and not Invulnerable
    return (GetUnitAbilityLevel(GetFilterUnit(), 'Avul') == 0 and GetWidgetLife(GetFilterUnit())>0.405)
endfunction

function ELEUnCloak takes nothing returns nothing
// Important - this function is only called once a unit has entered
// the 600 AoE. A trigger creates the timer and saves relevant data
// to the cache, including a pointer to itself.
    local string m = I2S(h2i(GetExpiredTimer()))
    local unit u = i2u(GetStoredInteger(udg_cache, m, "u"))
    local trigger t = i2t(GetStoredInteger(udg_cache, m, "trigger"))
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local boolexpr b = Filter(function ELEUnCloak_filter)
    local group g = CreateGroup()

// Group all units within 600 of the source unit's location
    call GroupEnumUnitsInRange(g, x, y, 600, b)

// CountUnitsInGroup is being used at the moment because I was sure
// that it worked, in case the problem was caused by my use of
// if FirstOfGroup(g) == null
    if CountUnitsInGroup(g) == 0 then
        call UnitAddAbility(u, 'Apiv')
        call UnitAddAbility(u, 'Agho')
// Clear the cache
        call FlushStoredMission(udg_cache, m)
// We are going to destroy this timer, so set a new key for the cache
        set m = I2S(h2i(t))
// Make sure our source unit is saved.
// Might not be neccessary, the Action funtion for the trigger calls it
// But the trigger already exists
        call StoreInteger(udg_cache, m, "source", h2i(u))
//Turn on the trigger.
        call EnableTrigger(t)
        call BJDebugMsg("Trigger Enabled")
// Probably will skip the pause once I can fix this problem. Was added
// In case the timer somehow wasn't getting destroyed, but this
// part of the IF statement has never triggered.
        call PauseTimer(GetExpiredTimer())
        call DestroyTimer(GetExpiredTimer())
    else
// This is just a debug. It _always_ returns 1 after a unit first enters
// the 600 range.
        call BJDebugMsg(I2S(CountUnitsInGroup(g)))
    endif

    call DestroyGroup(g)
// This returns 0, always.
    call BJDebugMsg(I2S(CountUnitsInGroup(g)))
    call DestroyBoolExpr(b)
    set u = null
    set t = null
    set b = null
    set g = null
endfunction
08-11-2008, 05:28 AM#2
darkwulfv
Well... you aren't removing the unit you're searching around from the group, so it will always return at least 1 unit. After GroupEnuming, remove the unit from the group. call GroupRemoveUnit(g, u)
08-11-2008, 05:30 AM#3
Sophismata
I will try that, but the group is getting destroyed. The Debug Message afterwards returns 0 units for the groups.

I have also used ClearGroup() as well, but Unit X is always re-added.


Going to give GroupRemoveUnit a shot now, though.

Edit:


Ahhhhhhhhh.... I just reread your post after cofee and breakfast, and I understand it.

Thanks a million!

(It's so frickin' obvious, now, too).


I should probably avoid mapwork at 4 in the morning.

Once again, thanks.
08-11-2008, 05:48 AM#4
darkwulfv
No, see, you check if the units in the group are 0, and if so add invisibility. But that will NEVER happen, because the source unit will ALWAYS be in that group.