| 06-20-2007, 08:32 PM | #1 |
Hi, I'm new to using local triggers. I want the local trigger to have 2 events, one when a unit comes in range, and one timer-like. So i did like this: JASS:function SomeFunction_Conditions takes nothing returns boolean return GetUnitState(GetTriggerUnit(), UNIT_STATE_LIFE) > 0 endfunction function SomeFunction_Actions takes nothing returns nothing local trigger t = GetTriggeringTrigger() //do stuff here call TriggerRemoveCondition(t, GetHandleTriggerCondition(t, "tc")) call TriggerRemoveAction(t, GetHandleTriggerAction(t, "ta")) call FlushHandleLocals(t) call DestroyTimer(GetExpiredTimer()) set t = null endfunction function SomeFunction takes nothing returns nothing local trigger trig = CreateTrigger() local triggercondition tc local triggeraction ta local unit u = GetTriggerUnit() local timer t = CreateTimer() call TriggerRegisterUnitInRange(trig, u, 100, null) call TriggerRegisterTimerExpireEvent(trig, t) set tc = TriggerAddCondition(trig, Condition(function SomeFunction_Conditions)) set ta = TriggerAddAction(trig, function SomeFunction_Actions) call TimerStart(t, 2, false, null) set trig = null set tc = null set ta = null set u = null set t = null endfunction 1.) Would trigger fire when timer expires? I mean, would it ignore the conditions because in that second (timer) event there's no triggering unit 2.) Do I have any leaks here? 3.) Is there a more efficient way to do this? Did I forgot to remove stuff from gamecache? 4.) Is it ok to add a GetHandleTriggerCondition and GetHandleTriggerAction to handle vars? Would it work? 5.) Does the order in adding stuff (events, conditions, actions) matter? I mean, can I mix the order? Would it change something? That's all for now....thanks in advance |
| 06-20-2007, 08:41 PM | #2 |
1) No. 2) You don't destroy the trigger. 5) Doesn't matter. |
| 06-20-2007, 08:44 PM | #3 |
The answer to 1 is no, but you can fix that with some EventId's. |
| 06-20-2007, 08:52 PM | #4 |
From what I know you don't need to remove conditions unless you actually want to go for adding another in their place. 3. http://www.wc3campaigns.net/showthread.php?t=93797 Probably not much of a difference efficiency-vise, but better as you don't have to use the gamecache to store neither conditions nor actions. Just remember to remove the trigger itself. Also I would recommend using not IsUnitType(GetTriggerUnit(), UNIT_TYPE_DEAD) instead of GetUnitState(GetTriggerUnit(), UNIT_STATE_LIFE) > 0. Again not more efficient, but better because GetUnitState can sometimes be tricked when it comes to dead units. 4. It's ok, but, considering the conditions deal above, not really needed. |
| 06-20-2007, 09:00 PM | #5 |
GetWidgetLife(u) > 0.405 is fast and safe. |
| 06-20-2007, 10:20 PM | #6 |
> safe Not really. If you increase a dead unit's life using triggers at some point then GetWidgetLife will make it look like the unit is alive. While this is not so likely to happen, it's not impossible either. Simply a trigger that increases the life of all units in one region can cause it. |
| 06-21-2007, 07:28 AM | #7 | |
Thanks guys. Whoops i forgot to put DestroyTrigger, sry i usually do that. Quote:
EventId's? What's that? How do I do it then? Hehe this is pretty screwed up......I'll try to understand Vex's way..... Anyways thanks for help guys, SFilip you have been most helpful! |
| 06-21-2007, 08:13 AM | #8 |
'eventid' is a handle type, which all the other event types are an extension of. The native GetTriggerEventId returns an eventid type, which can be compared to any event type to allow you to determine which event fired a trigger. Now I didn't actually look at the specifics of your example before and you don't use what I would call 'normal' event registration (for lack of a better term). What you would need to do is test whether those events do give ids and what they are if they do. You could then use this information to check if the unit is alive or the trigger was fired by the timer expiration. However, in this case it might not be necessary. GetTriggerUnit() should return null when there isn't one, so you can just check the life or GetTriggerUnit() == null. |
| 06-21-2007, 08:22 AM | #9 |
Yeeaah, that's a better solution! Thanks blu! Uhmm if I put something like this: return IsUnitEnemy(GetTriggerUnit(), Player(0)) and IsUnitType(GetTriggerUnit(), UNIT_TYPE_DEAD) or GetTriggerUnit() == null What would "or" refer to? Would it be a right way to do it, or do I have to use And/Or? Another question, if I'm not using t timer at all, just for firing trigger, is it ok if i use TriggerRegisterTimerEvent? That way I don't have to destroy anything, right? |
| 06-21-2007, 08:31 AM | #10 |
You know I've never bothered to find out the order of processing of logical operands. I would guess at linear (ie that would first check the and, then or the result), but it is best to add brackets to ensure the correct order of operation. So in that case I'm guessing you want return (IsUnitEnemy(GetTriggerUnit(), Player(0)) and IsUnitType(GetTriggerUnit(), UNIT_TYPE_DEAD)) or GetTriggerUnit() == null. |
| 06-21-2007, 10:21 AM | #11 |
yep, thanks :D |
| 06-21-2007, 07:50 PM | #12 | |
Quote:
Left to right. Even enclosed in brackets. JASS:f1() and f2 or (f3() and f4())
as you can see, everything is done left to right. Execution stops if a conclusion can be reached without further execution. brakets also do not control order of execution, they only group things together. thus: f1() and (f2()) is the same as f1() and f2(). To me, this is quite odd. And possibly usefull. like: JASS:if (IsUnitSpecial(u) or MakeUnitSpecial(u)) then //MakeUnitSpecial returns true on sucsess and false on failure, thus an else can be used to handle errors. endif |
| 06-21-2007, 07:56 PM | #13 | |
Ok I meant grouping not execution, but yeah processed left to right (as I assumed) groups them that way. Quote:
Yes. It's termed 'short circuit' boolean evaluation. It allows stuff life: if astring != "" and GetStoredInteger(agamecache,"hi",astring) then Because the gamecache functions crash on an empty string, but short circuiting allows you to prevent that. |
| 06-21-2007, 08:25 PM | #14 | |
Yeah, I learned about and or not in school, "not" has the highest priority, then comes "and" and after that "or". Those JASS optimizations are ok, because if one statement in "and" isn't true, then the result will definetly be false, so it skips an unnecessary check. Can someone answer to the question I asked? Quote:
|
| 06-22-2007, 12:58 PM | #15 | |
Quote:
Well if you have a timer which exists solely to run a trigger then it doesn't really matter. You can register the event if you want it to be a trigger, or you can just TimerStart it and have it call a function. Neither way requires destroying anything (as long as it's intended to run all game) so I'm not sure what that part is about. |
