• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Trigger] is there a way to remove an event?

Status
Not open for further replies.
Level 13
Joined
Mar 13, 2013
Messages
299
I'm trying to change incinerate to do aoe damage on hit rather on death. Here's what I have:

  • Incinerate init
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • And - All (Conditions) are true
        • Conditions
          • (Unit-type of (Attacking unit)) Equal to Firelord
          • (Level of Incinerate (Arrow) for (Attacking unit)) Greater than 0
    • Actions
      • Trigger - Add to Incinerate <gen> the event (Unit - (Attacked unit) Takes damage)
and then:

  • Incinerate
    • Events
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units within 200.00 of (Position of (Attacked unit)) matching (((Matching unit) belongs to an enemy of (Owner of (Attacking unit))) Equal to True)) and do (Actions)
        • Loop - Actions
          • Unit Group - Add (Picked unit) to grp
      • Set x = (Number of units in grp)
      • Unit Group - Pick every unit in grp and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Level of Incinerate (Arrow) for (Attacking unit)) Equal to 1
            • Then - Actions
              • Set y = (Min(3.00, (45.00 / (Real(x)))))
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Level of Incinerate (Arrow) for (Attacking unit)) Equal to 2
                • Then - Actions
                  • Set y = (Min(8.00, (45.00 / (Real(x)))))
                • Else - Actions
                  • Set y = (Min(15.00, (45.00 / (Real(x)))))
          • Unit - Set life of (Picked unit) to ((Life of (Picked unit)) - y)
      • Unit Group - Remove all units from grp
of course, this builds and builds so that successive attacks on a unit make the damage double/triple/quadruple and so on (since it keeps adding the same event). Is there a way to remove the event added in the first trigger? Obviously, simply using the orb of fire ability data wouldn't work since there is a damage cap (and I want it to do reduced damage to buildings, which I haven't really started working on yet..).
 
Level 13
Joined
Mar 13, 2013
Messages
299
You simply can't. Why not just use 'Trigger - Turn off trigger' and 'Trigger - Turn on trigger' whenever you want the trigger to run. There is no reliable way to remove events neither in GUI nor in any type of JASS.

So it's best to turn it on and off when you need to.
i want the trigger to run when a unit takes damage. unfortunately, there is no way to do this unless you specify the unit. And there is no way to do that unless the unit is known beforehand (impossible for this purpose) or you add the unit dynamically to a trigger.

unless I'm missing something?
 
Level 19
Joined
Jul 14, 2011
Messages
875
Another solution is creating a trigger for every unit you want the event to affect, and then destroying it when you're done but that wouldn't be very practical.
I'd recommend a damage detection system, as Nichilus suggested. There was a few, last time I checked and they were really easy to use.
 
Level 18
Joined
Jul 3, 2010
Messages
536
To actually answer the original question, you can't remove event. You can, however, be pro-active about not adding the event mulitple times, which achieves the same effect like this:
  • Create a global variable unit group eg. Incinerate_Group.
  • Change the Actions of the first trigger to this:
    • Actions
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • ((Attacked unit) is in Incinerate_Group) Equal to False
      • Then - Actions
        • Unit Group - Add (Attacked unit) to Incinerate_Group
        • Trigger - Add to Incinerate <gen> the event (Unit - (Attacked unit) Takes damage)
      • Else - Actions
Units should no longer get registered multiple times.
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
That will still register too many units throughout the game, since the event is not removed when unit dies but stays.
So over the course of the game, that trigger may crash.

That's why DDS has been created - to take care of all units taking damage in the map without having to register that event for each unit.
It will also help him with future spells when he needs to negate dmg, etc.
 
Level 15
Joined
Aug 7, 2013
Messages
1,337
You need to destroy the trigger and then rebuild it to remove events. This works completely leak-lessly in JASS however it can introduce some instability if done incorrectly (do not ask me how to do it correctly as I do not know).

By instability you mean it can cause the game to crash if the trigger is destroyed at an inappropriate time?
 
Level 19
Joined
Jul 14, 2011
Messages
875
Yes, something like it can still have executions queued up when you destroy it resulting in bad stuff happening. No one explain to me what exactly happened because they thought I was too stupid for some silly reason.

Do you mean this bug? As far as I know it was patched, but I dont remember where I read it. I was wrong.

Vexorian said:
The bug with DestroyTrigger: apparentally in some situations, DestroyTrigger sets the trigger's handle index as free twice. And one of the times is some time after the destruction.

If no variables point to that trigger, there is a chance a handle would be created before that delay. And that handle would get the trigger's index.

But the problem is that when the delay ends, a process called by DestroyTrigger would mark that space as free again.

So next handle created will replace that one.

Instead if one or more local variables is not set to null, it won't be able to mark the space as free. It will leak but it would prevent the problem.

Link to thread.
Link to the 'research' thread.
 
Last edited:

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
As far as I know it was patched, but I dont remember where I read it.
There were no official patch notes regarding it. However there were patches since that time so it is quite possible it was patched at some stage (hidden change).

I was wrong
Again its all so vague. There is no "chance" in computer science. Leaking is not a good alternative either.

Why is something so easy in SC2 so hard in WC3...
 
Level 19
Joined
Jul 14, 2011
Messages
875
There were multiple conclusions by cohadar and masda in multiple threads, but I couldnt find them all and they werent nearly as consistent and 'logical' as Vex's, from what I remember. Anyways, if anyone has a more indepth and justified explanation to the actual cause of the problem he hasnt posted it anywhere from what I could find.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
if you remove trigger, event still will be in game
No it will not be in the game. I ran a test whereby I made a trigger and kept attaching "specific unit takes damage" events to it. These were done for unique units (units which I created, attached the event and then removed). The result was substantial handle index leak with it appearing that the event objects were leaking and the unit handle indices being recycled. This also reflected on process virtual memory size. Destroying the trigger fixed all of this with no handle index leaks and no increase in process virtual memory size.
 
Status
Not open for further replies.
Top