HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

boolexpr condition?

11-13-2007, 02:14 AM#1
Salbrismind
In jasscraft I found the event called DistanceBetweenUnits but one of the parameters is "boolexpr Conditions". What do I need to put in that spot?

Basically I want to have the trigger go off when a unit moves outside the range I provide (1000).

Also what is the difference between:

"TriggerRegisterDistanceBetweenUnits"
"TriggerRegisterUnitInRange"

Thanks in advance of any help.
11-13-2007, 02:26 AM#2
Tiku
Im not too sure the difference, but boolexpr is like:
Collapse JASS:
local boolexpr check = Condition(function IsUnitImmune)

and the function:
Collapse JASS:
function IsUnitImmune takes nothing returns boolean
    return IsUnitType(GetFilterUnit(), UNIT_TYPE_ANCIENT) == false
endfunction

Condition(function IsUnitImmune) is the boolexpr, and you need to have Condition(FUNCTION NAME) to work, which is just another condition

put something in the slot, to check what kind of unit you would like: in my case i put to check if the unit isnt UNIT_TYPE_ANCIENT :D
11-13-2007, 07:32 PM#3
Salbrismind
What event would I use then to check if a unit leaves the range of another? Are these the proper events?

Collapse JASS:
function TriggerRegisterDistanceBetweenUnits takes trigger trig, unit whichUnit, boolexpr condition, real range returns event
    return TriggerRegisterUnitInRange(trig, whichUnit, range, condition)
endfunction

This is what it says in JassCraft.
And the other:

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

If they are the right ones how do I make it so It will run the trigger when a unit leaves the range?
11-14-2007, 01:22 AM#4
Pyrogasm
Call the second function like it does in the first and use a global variable in the conditionfunc:
Collapse JASS:
globals
   private unit OtherUnit
endglobals

function ConditionFilter takes nothing returns boolean
   return GetFilterUnit() == OtherUnit
endfunction

//...
set OtherUnit = Whatever
call TriggerRegisterUnitInRange(gg_trg_Your_Trigger, FirstUnit, YourRange, Condition(function ConditionFilter))
11-14-2007, 07:16 PM#5
Salbrismind
Quote:
Originally Posted by Pyrogasm
Call the second function like it does in the first and use a global variable in the conditionfunc:
Collapse JASS:
globals
   private unit OtherUnit
endglobals

function ConditionFilter takes nothing returns boolean
   return GetFilterUnit() == OtherUnit
endfunction

//...
set OtherUnit = Whatever
call TriggerRegisterUnitInRange(gg_trg_Your_Trigger, FirstUnit, YourRange, Condition(function ConditionFilter))

That's super weird. What exactly does the condition function do? And it returns a boolean? What does the "filter" control, say if I put false/true in it's place what would happen?
11-16-2007, 07:06 PM#6
Salbrismind
I've been waiting 2 days to bumb this so here it is. CAN SOMEONE PLEASE ANSWER MY LAST QUESTIONS?
11-16-2007, 11:54 PM#7
Pyrogasm
The condition returns a boolean to filter the range event so the trigger doesn't fire if it shouldn't. What it's doing is comparing the unit being filtered (GetFilterUnit()) to a global that is set to the unit you want to fire the event for.

If the "return" is a true statement, the trigger's actions will fire. If it's false, it will not run.
11-17-2007, 01:33 AM#8
Salbrismind
Quote:
Originally Posted by Pyrogasm
The condition returns a boolean to filter the range event so the trigger doesn't fire if it shouldn't. What it's doing is comparing the unit being filtered (GetFilterUnit()) to a global that is set to the unit you want to fire the event for.

If the "return" is a true statement, the trigger's actions will fire. If it's false, it will not run.

In other words, in that example the unit that is put in the condition function is the one that leaves the range? And basically it asks if it leaves the range? Well what if I wanted it so it would trigger if any left the range?

Mainly, the thing I'm confused with is that by looking at that code the filter thingy does nothing except add "otherunit" for the event to understand. So using that condition function gives the event the information to compare? But it doesn't compare the information for it, correct? Such that the function does calculate the distance between the 2 units, but just gives the event the name of the otherunit to compare, am i right to say that?
11-17-2007, 02:13 AM#9
Malf
It would be so much easier to explain it for you in GUI.

Let's say I want SomeUnit to die if he comes near <YOURUNIT>

Trigger:
Trigger
Collapse Events
Event - A unit comes within X range of <YOURUNIT>
Collapse Conditions
Condition - Triggering Unit Equal to SomeUnit
Collapse Actions
Unit - Kill TriggeringUnit

The condition will check if the triggering unit is SomeUnit. If it is true, the trigger will fire off.
________________
Converted to JASS

Collapse JASS:

function ConditionFilter takes nothing returns boolean
    return GetTriggerUnit() == SomeUnit //If the triggering unit is SomeUnit, fire off the trigger
endfunction

function TriggerActions takes nothing returns nothing
    call KillUnit(GetTriggerUnit())
    OR
    call KillUnit(SomeUnit)
   //Works either way since this trigger would only fire if the triggering unit was equal to SomeUnit.
endfunction

function InitTrig_Trigger takes nothing returns nothing
    set gg_trg_Trigger = CreateTrigger()
    call TriggerRegisterUnitInRange(gg_trg_Trigger, <YOURUNIT>, 300, Condition(function ConditionFilter))
    call TriggerAddAction(gg_trg_Trigger,function TriggerActions)
endfunction

Condition functions are called when you register them as conditions for a trigger. They must return boolean.

When they are called you need to return a boolean expression, e.g IsUnitType(GetTriggerUnit(),UNIT_TYPE_MECHANICAL) would cause the trigger to check if the triggering unit was a mechanical unit. If it wasn't, the trigger won't fire off at all.

Here's another example:
Trigger:
Trigger
Collapse Events
Event - A unit dies
Collapse Conditions
Condition - Unit type of Dying Unit Equal to Hero
Collapse Actions
Do something

Registers when a unit dies with a condition that explicitly checks if the dying unit was a hero. The trigger will then ONLY GO OFF if the conditions are met, in other words it will go off whenever a hero dies.
11-17-2007, 03:03 AM#10
Salbrismind
Oh, that sounds much simplier. Now then that begs the question: How would I turn this around to make the trigger run when a unit moves outside the range of another?
11-17-2007, 07:05 AM#11
Pyrogasm
It would be much easier to just periodically run a check to see the distance between them:
Collapse JASS:
library DistanceTriggerStuff
    globals
        private constant real CheckInterval = 0.10

        public unit Unit1
        public unit Unit2
        private timer T = CreateTimer()
        TData array AllData
        private integer N = 0
    endglobals

    private function Callback takes nothing returns nothing
        local integer I = 0
        local TData TD
        local real X
        local real Y
        local real X2
        local real Y2

        loop
            set I = I+1
            exitwhen I>N

            set TD = AllData[i]
            set X = GetUnitX(TD.U)
            set Y = GetUnitY(TD.U)
            set X2 = GetUnitX(TD.U2)
            set Y2 = GetUnitY(TD.U2)

            if (X-X2)*(X-X2)+(Y-Y2)*(Y-Y2) > TD.BreakDistance)= then
                if (GetWidgetLife(TD.U) > 0.405 and GetWidgetLife(TD.U2) > 0.405) then
                    set Unit1 = TD.U
                    set Unit2 = TD.U2
                    if TD.Trig == null then
                        call TD.destroy()
                    elseif TriggerEvaluate(TD.Trig) then
                        call TriggerExecute(TD.Trig)
                    endif
                endif
            endif
        endloop
    endfunction

    private struct TData
        real BreakDist = 0.00
        unit U = null
        unit U2 = null
        trigger Trig = null
        integer StackNumber

        static method create takes trigger RegisterTrig, unit U, unit U2, real BreakDistance returns nothing
            local TData TD = TData.allocate()
            set TD.Trig = RegisterTrig
            set TD.U = U
            set TD.U2 = U2
            set TD.BreakDist = BreakDist*BreakDistance

            set N = N+1
            set AllData[N] = TD
            set TD.StackNumber = N
            if N == 1 then
                call TimerStart(T, CheckInterval, true, function Callback)
            endif
        endmethod

        method onDestroy takes nothing returns nothing
            if N > 1 then
                set AllData[this.StackNumber] = AllData[N]
                set AllData[N].StackNumber = this.StackNumber
            endif
            set N = N-1
        endmethod
    endstruct

    function TriggerRegisterUnitDistanceEvent takes trigger RegisterTrig, unit U, unit U2, real BreakDist returns nothing
        local TData TD = TData.create()
    endfunction

    function GetDistanceUnit1 takes nothing returns unit
        return Unit1
    endfunction

    function GetDistanceUnit2 takes nothing returns unit
        return Unit2
    endfunction
endlibrary

Sorry if there are any errors... but that might work.
11-17-2007, 04:46 PM#12
Salbrismind
Thanks for the help, but if those events don't work I do have a much better solution then your 1000 line code there. It's a simple trigger with a periodic of 0.05 or so and it calculates the distance from the centre to each unit and if any are past 6000 then it does it's triggers.

In other words I can solve this, but I wanted an easier solution.

-Thanks
11-18-2007, 03:14 AM#13
Pyrogasm
That's exactly what the code I posted does.
11-18-2007, 05:05 PM#14
Salbrismind
Quote:
Originally Posted by Pyrogasm
That's exactly what the code I posted does.

It probably does but that is horridly confusing and I don't feel like trying to figure it all out.