HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Getting a random unit without a group.

12-28-2009, 02:39 AM#1
StRoNgFoE_2000
Sounds simple, but in all reality I'm having trouble coming up with a fail-proof or a simple method of simply getting a nearby unit without having to create a group and using the BJ function GroupPickRandomUnit.

--------------------------------------------------
One idea was to just use a global boolean and using a GroupEnum function without actually adding units to the group. The problem with this is, it will always affect the first unit to be added.

Crude Example:
Collapse JASS:
function linkedbysomeboolexpr takes nothing returns boolean
    local unit u = GetFilterUnit()
    if (TEMPBOOL) then
        set TEMPBOOL = false
        call DoSomething(u)
    endif
    set u = null
    return false
endfunction

// Do something to a unit
set TEMPBOOL = true
call GroupEnumUnitsInRange(TEMPGROUP, x, y, range, someboolexpr)

This method works, but only to the first unit to be added to the group. In my case, I have a check to see if a unit has a buff because I'm having a TEMPUNIT cast a spell on it. This doesn't always work because 5 units can cast a spell at the same time and affect the same unit, before the buff is applied.
--------------------------------------------------
Another idea I though of was having the units added to a global unit variable with array and just using a random integer to reference the unit variable depending on the number of units added.

Crude Example:
Collapse JASS:
function linkedbysomeboolexpr takes nothing returns boolean
    local unit u = GetFilterUnit()
    if (SomeCondition) then
        set TEMPINT = TEMPINT + 1
        set TEMPUNIT[TEMPINT] = u
    endif
    set u = null
    return false
endfunction

// Do something to a unit
set TEMPINT = 0
call GroupEnumUnitsInRange(TEMPGROUP, x, y, range, someboolexpr)
if (TEMPINT > 0) then
    call DoSomething(TEMPUNIT[GetRandomInt(1, TEMPINT)])
endif

I don't really care very much for this method either. Something tells me there has got to be a better way. Plus now there's a boatload of units stored in memory with no real purpose anymore unless I added even more code to null them all.
--------------------------------------------------

So any ideas from anyone out there? I just want to grab a nearby unit to cast a spell on, and it needs to be extremely fast. Both my methods require external global variables to pull it off, which isn't a problem but it's not very neat. There may be times where as many as 50 units are looking for a unit to cast a spell on, and this unit needs to be a random one that meets the conditions so spells get spread out more evenly.
12-28-2009, 04:10 PM#2
Anitarf
You could try inlining the logic from GroupPickRandomUnit but the method with the array is likely faster.
12-29-2009, 07:11 AM#3
StRoNgFoE_2000
Here's the way I've been doing things, and it's noticeably slow when dealing with large numbers of units... I don't know how much faster I can get with other methods of getting a random unit.

Collapse JASS:
call GroupEnumUnitsInRange(d.group, GetUnitX(d.caster), GetUnitY(d.caster), d.spellrange, d.spelltype)
set d.target = GroupPickRandomUnit(d.group)
call GroupClear(d.group)
if (d.target != null) then
    etc...

Problem is, when this work gets done many times a second it slows down the map. I'm assuming that using the method using the global unit array (with a random int for reference) would be faster than enumerating a bunch of units to a group and picking a random unit from the group, correct me if I'm wrong.
12-29-2009, 11:22 AM#4
Anitarf
Yes, like I said, the method that uses a global unit array which you posted in your first post is likely the fastest way to get a random unit in range.
12-29-2009, 12:47 PM#5
StRoNgFoE_2000
Sounds good, then that's how I'm gonna do it from now on. Thanks for the assistance.