HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Help on boolexprs

08-19-2008, 06:25 PM#1
burningice95
How exactly do boolexprs work? This is what I am doing, but it gives me errors.

Collapse JASS:
 
private  function Filter takes nothing returns boolean
return  IsUnitAlly(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) and IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO) == false  and  GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) <= 0
endfunction


set g = GroupEnumUnitsInRange(g, GetUnitX(u), GetUnitY(u), Radius(level), Filter())


but I get the error, cannot convert boolean to boolexpr. I tried to make the fitler func. return bool expr but that just gave me the same problem.
08-19-2008, 06:29 PM#2
moyack
Collapse JASS:
private function Filter takes nothing returns boolean
return  IsUnitAlly(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) and IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO) == false  and  GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) <= 0
endfunction

function bla takes nothing returns nothing
    set g = CreateGroup()
    call GroupEnumUnitsInRange(g, GetUnitX(u), GetUnitY(u), Radius(level), Condition(function Filter))
    // do your stuff
    call DestroyGroup(g)
    set g = null
endfunction
08-19-2008, 06:32 PM#3
burningice95
That was fast, thanks!

New question: If I use a filter function after a wait, I assume I will be unable to use most event responses, right?
08-19-2008, 06:36 PM#4
moyack
sorry, I don't get it... what are you referring to responses?
08-19-2008, 06:58 PM#5
burningice95
How triggers forget what GetSpellAbilityUnit() refers to after a wait. Will filter functions forget them too?
08-19-2008, 07:11 PM#6
moyack
No, because the filter functions are constant, and are used in this case to fill the group variable with units, and because we have a variable storing the group variable... then there's no issues with waits.
08-19-2008, 07:15 PM#7
Anitarf
Spell event responses may not work after a wait (regardless of where they are, in the main function or in a filter), other event responses work after waits.
08-21-2008, 07:04 PM#8
Zerzax
You could potentially not use a filter, instead use loops to sort out the kind of unit you want, for example:

Code:
function bla takes nothing returns nothing
    local group g=CreateGroup() //your filter group
    local unit u
    set g2 = CreateGroup() //this is the group that will have the right units.
    
    call PolledWait(duration) //or whatever method of waiting you like

    call GroupEnumUnitsInRange(g, GetUnitX(u), GetUnitY(u), Radius(level), null) // All units included in this group, no filter
    loop
        set u=FirstofGroup(g)
        exitwhen u==null
        if IsUnitAlly(u, GetOwningPlayer(GetTriggerUnit())) and IsUnitType(u, UNIT_TYPE_HERO) == false  and  GetUnitState(u, UNIT_STATE_LIFE) <= 0 then
            call GroupAddUnit(g2, u)
        endif
        call GroupRemoveUnit(g, u)
    endloop

    // do your stuff
    call DestroyGroup(g)
    call DestroyGroup(g2)
    set g = null
    set g2 = null
    set u = null
endfunction

At this point g2, the group you want, has all the right units. You can wait as long as you want before doing this too. Just an idea, if you like it. More variables and handles yes, but definitely more efficient and inlined.
08-22-2008, 04:25 AM#9
burningice95
That's a good idea. The only reason that I won't use it is because this is for a a spell I plan on submitting, therefore it needs to be configurable, and a filter function is the best way to configure it.

So the Condition( function whatever ) basically converats from a boolean to a boolexpr?
08-22-2008, 04:40 AM#10
Bobo_The_Kodo
To make it do what Zerzax said and still make it configurable you could do something like:

Collapse JASS:
globals
    private constant boolean NotHeroes = true
    private constant boolean OnlyAllies = true
endglobals

...

if (not OnlyAllies or IsUnitAlly(u, GetOwningPlayer(GetTriggerUnit()))) and (not NotHeroes or not IsUnitType( u, UNIT_TYPE_HERO ) ) and GetWidgetLife( u ) > 0. then
08-22-2008, 04:54 AM#11
burningice95
where should that if/then statement go
08-22-2008, 04:56 AM#12
Bobo_The_Kodo
Where Zerzax had it, I haven't tested it, but it should work
08-22-2008, 07:02 PM#13
Zerzax
Yeah, Condition(boolean) takes that boolean and makes the boolexpr handle that will allow something to run (or in this case add the unit to the group). You can also use Filter(boolean), which will make a filterfunc, basically the same thing. The if/then statement should go inside that first loop that takes the right units from group 1 then adds them to group 2. You are always going to remove the units from group one, but when the right unit is in group 1 it is added to group 2. Make sense?
08-23-2008, 07:08 AM#14
ADOLF
Collapse JASS:
// modifed code from post#2

globals
 group gr_temp=CreateGroup()
 player p_temp=null
endglobals

private function Filter takes nothing returns boolean
 if IsUnitAlly(GetFilterUnit(), p_temp) and IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO)  and  GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) <= 0then
 // do you stuff
 endif
 return false
endfunction

function bla takes nothing returns nothing
    set p_temp=GetOwningPlayer(GetTriggerUnit())
    call GroupEnumUnitsInRange(gr_temp, GetUnitX(u), GetUnitY(u), Radius(level), Condition(function Filter))
endfunction

so it is more convenient (well if you should not keep units in group)
08-23-2008, 09:18 AM#15
Themerion
Quote:
Originally Posted by Zerxorwhatever
You could potentially not use a filter, instead use loops to sort out the kind of unit you want.

1) FirstOfGroup has some unpleasant issues with units being decayed/removed.
2) GroupEnumUnits is faster.