Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
Try this. As far as a trigger that fires, why not add the unit to the enters region event and then immediately check if it is in the region?
JASS:
function IsUnitNotInRect takes unit Unit,rect R returns boolean
local real X=GetUnitX(Unit)
local real Y=GetUnitY(Unit)
return X<GetRectMinX(R)or X>GetRectMaxX(R)or Y<GetRectMinY(R)or Y>GetRectMaxY(R)
endfunction
An event usually implies a change in some state. To statically determine if a unit is in a region, you would simply use IsUnitInRegion, or for a rect:
JASS:
function IsUnitInRect takes unit u, rect r returns boolean
local real x = GetUnitX(u)
local real y = GetUnitY(u)
return (x >= GetRectMinX(r)) and (x <= GetRectMaxX(r)) and (y >= GetRectMinY(r)) and (y <= GetRectMaxY(r))
endfunction
But it wouldn't make sense for a trigger to fire when a unit exists inside a region, because that would fire an infinite amount of times. Instead, go with a periodic timer and just check if the unit is still inside the region, or have a separate event that fires when a unit leaves and determine who is still inside based on that (add units to a group when they enter, remove them when they leave. do what you want with the group).
I'm not asking for a function that tells me if a unit is in a rect.
I'm asking for how to fire a trigger as a reaction to a unit being in a rect/region.
It wouldn't fire an infinite number of times--it'd just fire every trigger cycle. Which could potentially go on forever, until the trigger is disabled.
The unit has been in the region/rect for quite some time before I turn on the trigger.
Problem with timer is, is that I can't bind it to a player without doing it myself. Was hoping to use the standard jass trigger event API.
You want all existing units in the rect to trigger the enter event when you create the trigger? You'll have to handle them specifically or move them out and back in the rect.
TriggerEvaluate? You're going to have to manage that event yourself, since there isn't an event that reacts to a unit being inside a rect/region. Or you can always move the unit out and back in, but it would be better to just manage an event yourself.
Essentially, you would manage the data and firing yourself. Custom events are pretty useful since they allow you to emulate JASS trigger behavior.
First, you'll have some global trigger that manages the event. Whenever someone wants to register something to it, just add that code to the trigger, e.g.:
JASS:
globals
trigger customEvent = CreateTrigger()
endglobals
function RegisterSomeEvent takes code c returns nothing
call TriggerAddCondition(customEvent, Condition(c))
// with jasshelper enabled, this implies that c returns boolean
// you can also use TriggerAddAction + TriggerExecute instead
endfunction
Registering an event is as simple as adding some functions to the trigger. When you want the event to fire, simply use TriggerEvaluate(). If you want to pass data, just use globals and some wrappers. e.g.:
JASS:
globals
trigger customEvent = CreateTrigger()
unit triggerData = null
endglobals
function RegisterSomeEvent takes code c returns nothing
call TriggerAddCondition(customEvent, Condition(c))
endfunction
function FireSomeEvent takes nothing returns nothing
local unit temp = triggerData
set triggerData = GetTriggerUnit() // assign data
call TriggerEvaluate(customEvent)
set triggerData = temp // this is related to recursion, ask if you need an explanation
set temp = null
endfunction
function GetSomeEventTriggerUnit takes nothing returns unit
return triggerData
endfunction
In that sense, someone can easily have an interface to respond to that event:
JASS:
scope Example initializer Init
private function Act takes nothing returns boolean
local unit triggeringUnit = GetSomeEventTriggerUnit() // event data
// do some things
return false
endfunction
private function Init takes nothing returns nothing
call RegisterSomeEvent(function Act)
endfunction
endscope
Obviously, that is a very vague example which does nothing in particular. But it is useful when you want to create a system that exposes the user to an event-based interface, rather than relying on stub methods or extending structs, etc. (which uses triggers in the underlying code anyway).
Take for example, my Track system. I have custom events to register when a trackable is clicked or hovered. Of course, the user can register those events himself, but with custom events, I can expose the user to additional trigger data, such as the trackable's struct instance, the player who clicked it, etc.
Anyway, that should be what you're looking for. It is much better than evaluating an arbitrary trigger directly (what if you want more triggers to respond to the unit being in the region?), and it is better than forcing it through some weird method e.g. moving the unit out and away. You can also use something like TriggerRegisterVariableEvent. That is what is used to make custom GUI events in systems such as Bribe's DDS. You may want to check it out.
Yes there is a native that does exactly what you want.
JASS:
native IsUnitInRegion takes region whichRegion,unit whichUnit returns Boolean
Obviously this is not an event since there are already events to detect the change in this value. You may need to check periodically, or on map initialization for pre-placed units.
Thank you for your very comprehensive example Purgeandfire.
I am little confused as how to this would solve my problem, since my understanding it's just a circular solution, because
JASS:
function FireSomeEvent takes nothing returns nothing
local unit temp = triggerData
set triggerData = GetTriggerUnit() // assign data
call TriggerEvaluate(customEvent)
set triggerData = temp // this is related to recursion, ask if you need an explanation
set temp = null
endfunction
this function needs to be called. But how? When does it get called?
I've got all my functions/structures lined up, it's just getting the trigger to fire in the case I mentioned above--a reaction to a unit being in a region (that it has already entered).
We might be on different pages. I figured you would fire that when you turn on the trigger. You would just group the units in the rect/region and then fire the trigger for each unit that currently exists in the rect/region.
But it might be a little convoluted. Perhaps it would be better to just move them out and back in.
There is no non-infinite loop causing way to what you're asking to do. If you want to help up help you, please type some JASS code that explains what you want to do. It doesn't matter if you 'call' non-existent natives, it'll help us understand more.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.