• 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!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • It's time for the first HD Modeling Contest of 2025. Join the theme discussion for Hive's HD Modeling Contest #7! Click here to post your idea!

[Trigger] Rapid temporary point removal

Level 12
Joined
Jul 5, 2014
Messages
532
Quick question: how fast can I remove points. Is it okay to rapidly remove and reuse them? Here's an example what I mean:

  • Quest Given
    • Events
      • Unit - A unit enters VillageBorder <gen>
    • Conditions
      • ((Entering unit) Equal to Hero1) or ((Entering unit) Equal to Hero2)
    • Actions
      • Trigger - Turn off (This trigger)
      • Set SingleUsePoint1 = (Center of Hero1VillageBorder <gen>)
      • Set SingleUsePoint2 = (Center of Hero2VillageBorder <gen>)
      • Cinematic - Turn cinematic mode On for (All players)
      • Cinematic - Fade out over 0.50 seconds using texture White Mask and color (0.00%, 0.00%, 0.00%) with 0.00% transparency
      • Wait 0.50 seconds
      • Unit - Move Hero1 instantly to (Center of Hero1VillageBorder <gen>)
      • Unit - Move Hero2 instantly to (Center of Hero2VillageBorder <gen>)
      • Custom script: call RemoveLocation(udg_SingleUsePoint1)
      • Custom script: call RemoveLocation(udg_SingleUsePoint2)
      • Cinematic - Fade in over 0.50 seconds using texture White Mask and color (0.00%, 0.00%, 0.00%) with 0.00% transparency
      • Wait 0.50 seconds
      • Cinematic - Fade in over 0.50 seconds using texture White Mask and color (0.00%, 0.00%, 0.00%) with 0.00% transparency
      • Set SingleUsePoint1 = (Center of Hero1TalkRico <gen>)
      • Set SingleUsePoint2 = (Center of Hero2TalkRico <gen>)
      • Unit - Order Hero1 to Move To SingleUsePoint1
      • Unit - Order Hero2 to Move To SingleUsePoint2
      • Wait 3.00 seconds
      • Cinematic - Send transmission to (All players) from Tinker 0363 <gen> named Rico: Play No sound and display Hello. Modify duration: Set to 1.00 seconds and Don't wait
      • Custom script: call RemoveLocation(udg_SingleUsePoint1)
      • Custom script: call RemoveLocation(udg_SingleUsePoint2)
 
Level 12
Joined
Jul 5, 2014
Messages
532
You can remove them infinitely fast. There is no limit.

Here is a fun function that creates a point just for the purpose of removing it:
  • Custom script: call RemoveLocation(GetUnitLoc(GetTriggerUnit()))
I'm not entirely sure what does what in that script (I'm very basic on custom scripts). I only asked the removal due to the quick use and reuse. Like, will they remember the old point if I
1. order a unit to go to the point,
2. remove the point the moment they start moving
3. reassign the "temp_point" to a different point?

Or they will start moving toward the new point?
 
Level 24
Joined
Feb 27, 2019
Messages
783
I'm not entirely sure what does what in that script (I'm very basic on custom scripts). I only asked the removal due to the quick use and reuse. Like, will they remember the old point if I
1. order a unit to go to the point,
2. remove the point the moment they start moving
3. reassign the "temp_point" to a different point?

Or they will start moving toward the new point?
They remember the old point.

You can use the new point for something else immediately after.
 

Uncle

Warcraft Moderator
Level 71
Joined
Aug 10, 2018
Messages
7,533
I see. That's dandy for me, I don't have to use a dozen on variables, just 2-4. Thanks.
Basically, but there are situations where you will want to use a unique Point variable (or any kind of leakable variable) or restructure your Actions to avoid issues. This Event is a particular trouble causer:
  • Events
    • Unit - A unit Dies
For some reason this Event breaks the trigger queue rule and will run it's logic immediately, injecting it's Actions into whichever trigger caused it to run. So for example...

Trigger A:
  • Events
    • Unit - A unit Starts the effect of an ability
  • Conditions
  • Actions
    • Set Variable TempPoint = (Position of (Casting unit))
    • Unit - Kill (Target unit of ability being cast)
    • Special Effect - Create a special effect at TempPoint
    • Custom script: call RemoveLocation( udg_TempPoint )
Trigger B:
  • Events
    • Unit - A unit Dies
  • Conditions
  • Actions
    • Set Variable TempPoint = (Position of (Dying unit))
    • Item - Create an item at TempPoint
    • Custom script: call RemoveLocation( udg_TempPoint )
Both of these triggers appear to be following all of the rules.

However, the final outcome of Trigger A will actually be a combination of both Trigger A and Trigger B:
  • Events
    • Unit - A unit Starts the effect of an ability
  • Conditions
  • Actions
    • Set Variable TempPoint = (Position of (Casting unit))
    • Unit - Kill (Target unit of ability being cast)
    • Set Variable TempPoint = (Position of (Dying unit))
    • Item - Create an item at TempPoint
    • Custom script: call RemoveLocation( udg_TempPoint )
    • Special Effect - Create a special effect at TempPoint
    • Custom script: call RemoveLocation( udg_TempPoint )
This is a broken mess. The first TempPoint is immediately leaking because it never gets removed. Fortunately, the second TempPoint will work properly, creating an item and getting removed. But then the Special Effect will fail because it's being created at a now removed Point. (it'll spawn at the center of the map as a fallback plan) Lastly, it attempts to remove TempPoint again even though it was already removed. Not good!

The expected behavior of triggers is that Trigger A would execute all of it's Actions first THEN Trigger B would run afterwards - but that isn't the case here. So just be aware of the fact that there are some exceptions to the rules. Generally speaking though, you'll be able to reuse variables.

Also, the rule of thumb for memory leaks:
Set Variable, Use Variable, Remove Variable
Never break this order! The sooner you remove the leak the better.
 
Last edited:
Level 12
Joined
Jul 5, 2014
Messages
532
Basically, but there are situations where you will want to use a unique Point variable (or any kind of leakable variable) or restructure your Actions to avoid issues. This Event is a particular trouble causer:
  • Events
    • Unit - A unit Dies
For some reason this Event breaks the trigger queue rule and will run it's logic immediately, injecting it's Actions into whichever trigger caused it to run. So for example...

Trigger A:
  • Events
    • Unit - A unit Starts the effect of an ability
  • Conditions
  • Actions
    • Set Variable TempPoint = (Position of (Casting unit))
    • Unit - Kill (Target unit of ability being cast)
    • Special Effect - Create a special effect at TempPoint
    • Custom script: call RemoveLocation( udg_TempPoint )
Trigger B:
  • Events
    • Unit - A unit Dies
  • Conditions
  • Actions
    • Set Variable TempPoint = (Position of (Dying unit))
    • Item - Create an item at TempPoint
    • Custom script: call RemoveLocation( udg_TempPoint )
Both of these triggers appear to be following all of the rules.

However, the final outcome of Trigger A will actually be a combination of both Trigger A and Trigger B:
  • Events
    • Unit - A unit Starts the effect of an ability
  • Conditions
  • Actions
    • Set Variable TempPoint = (Position of (Casting unit))
    • Unit - Kill (Target unit of ability being cast)
    • Set Variable TempPoint = (Position of (Dying unit))
    • Item - Create an item at TempPoint
    • Custom script: call RemoveLocation( udg_TempPoint )
    • Special Effect - Create a special effect at TempPoint
    • Custom script: call RemoveLocation( udg_TempPoint )
This is a broken mess. The first TempPoint is immediately leaking because it never gets removed. Fortunately, the second TempPoint will work properly, creating an item and getting removed. But then the Special Effect will fail because it's being created at a now removed Point. (it'll spawn at the center of the map as a fallback plan) Lastly, it attempts to remove TempPoint again even though it was already removed. Not good!

The expected behavior of triggers is that Trigger A would execute all of it's Actions first THEN Trigger B would run afterwards - but that isn't the case here. So just be aware of the fact that there are some exceptions to the rules. Generally speaking though, you'll be able to reuse variables.

Also, the rule of thumb for memory leaks:
Set Variable, Use Variable, Remove Variable
Never break this order! The sooner you remove the leak the better.
Hmm, I guess they're not a good idea to use with multiple triggers at once, just within one at a time.
 

Uncle

Warcraft Moderator
Level 71
Joined
Aug 10, 2018
Messages
7,533
Hmm, I guess they're not a good idea to use with multiple triggers at once, just within one at a time.
You should still reuse variables, just understand when it's not a good idea to do so. The example I provided was one particular case and it may actually be the only case - I can't remember. Regardless, it's a rare edge case that you should simply workaround.

I would say:
1) You should reuse variables.
2) You should understand when it's not safe to reuse variables.
3) You should remember this example when you experience bugs -> "Maybe this issue is related?"
 
Level 12
Joined
Jul 5, 2014
Messages
532
You should still reuse variables, just understand when it's not a good idea to do so. The example I provided was one particular case and it may actually be the only case - I can't remember. Regardless, it's a rare edge case that you should simply workaround.

I would say:
1) You should reuse variables.
2) You should understand when it's not safe to reuse variables.
3) You should remember this example when you experience bugs -> "Maybe this issue is related?"
I definitely intend to, just not using it in multiple triggers in the same time. Is this working? The trigger is basically "dropping" items to like they're dropped in the campaign, except if they're two particular items.

  • The Captains Items
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Item-type of (Item being manipulated)) Not equal to Captain's Helm) or ((Item-type of (Item being manipulated)) Not equal to Forgotten Glory)
        • Then - Actions
          • Set ItemDrop = (Center of Item1 <gen>)
          • Item - Create (Item-type of (Item carried by TheCaptain in slot 1)) at ItemDrop
          • Item - Remove (Item carried by TheCaptain in slot 1)
          • Custom script: call RemoveLocation(udg_Itemdrop)
          • Set ItemDrop = (Center of Item2 <gen>)
          • Item - Create (Item-type of (Item carried by TheCaptain in slot 2)) at ItemDrop
          • Item - Remove (Item carried by TheCaptain in slot 2)
          • Custom script: call RemoveLocation(udg_Itemdrop)
          • Set ItemDrop = (Center of Item3 <gen>)
          • Item - Create (Item-type of (Item carried by TheCaptain in slot 3)) at ItemDrop
          • Item - Remove (Item carried by TheCaptain in slot 3)
          • Custom script: call RemoveLocation(udg_Itemdrop)
          • Set ItemDrop = (Center of Item4 <gen>)
          • Item - Create (Item-type of (Item carried by TheCaptain in slot 4)) at ItemDrop
          • Item - Remove (Item carried by TheCaptain in slot 4)
          • Custom script: call RemoveLocation(udg_Itemdrop)
          • Set ItemDrop = (Center of Item5 <gen>)
          • Item - Create (Item-type of (Item carried by TheCaptain in slot 5)) at ItemDrop
          • Item - Remove (Item carried by TheCaptain in slot 5)
          • Custom script: call RemoveLocation(udg_Itemdrop)
          • Set ItemDrop = (Center of Item6 <gen>)
          • Item - Create (Item-type of (Item carried by TheCaptain in slot 6)) at ItemDrop
          • Item - Remove (Item carried by TheCaptain in slot 6)
          • Custom script: call RemoveLocation(udg_Itemdrop)
        • Else - Actions
          • Do nothing
 

Uncle

Warcraft Moderator
Level 71
Joined
Aug 10, 2018
Messages
7,533
That appears to be fine, assuming that:

1) ItemDrop isn't used in another trigger that would run (immediately) in response to item creation / item removal. Again, most of the time the trigger queue will prevent this from being an issue.

2) If an Item doesn't exist in the given inventory slot you're hoping that the Create/Remove actions have been designed to handle "bad" data. Luckily, the devs were pretty good about coding things to avoid user error.

Also, you'll get an error since you misspelled ItemDrop in your Custom Script.

Here's how I would do it, but I get a little obsessive about keeping things clean and organized:
  • The Captains Items
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Item-type of (Item being manipulated)) Not equal to Captain's Helm)
          • ((Item-type of (Item being manipulated)) Not equal to Forgotten Glory)
        • Then - Actions
          • For each Integer (ItemSlot) from 1 to 6 do (Actions)
            • Loop - Actions
              • Set ItemToDrop = (Item carried by TheCaptain in slot ItemSlot)
              • Item - Create (Item-type of ItemToDrop) at ItemDropPoint[ItemSlot]
              • Item - Remove ItemToDrop
        • Else - Actions
1) ItemDropPoint is a Point array variable that would have been setup beforehand. Points [1] to [6] are assigned to the Regions ItemDrop1 -> ItemDrop6.

2) The OR didn't make sense since you're using "Not equal to". So if it wasn't a Captain's Helm then it would immediately proceed to the Actions. In other words, it wouldn't check the second part of your OR since only one of these needs to be true.

3) Do Nothing is optional and has no effect. Not a big deal though, use it if you like the way it looks.
 
Last edited:

Uncle

Warcraft Moderator
Level 71
Joined
Aug 10, 2018
Messages
7,533
Are you sure? I just tested my less tidy version and the "Captain's Helm" item was dropped along with the others. The condition supposed to prevent the drop of this and Forgotten Glory. Does "item being manipulated" works without event? I can't think of anything else.
I assumed you had an Item Event or that this was being Run from another trigger that used an Item Event. But now I don't quite understand what you're trying to accomplish.

Do you want the Captain to drop everything BESIDES those two items? If so, your Conditions still don't make any sense.

I think this is what you want:
  • The Captains Items
    • Events
    • Conditions
    • Actions
      • For each Integer (ItemSlot) from 1 to 6 do (Actions)
        • Loop - Actions
          • Set ItemToDrop = (Item carried by TheCaptain in slot ItemSlot)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Item-type of ItemToDrop) Not equal to Captain's Helm)
              • ((Item-type of ItemToDrop) Not equal to Forgotten Glory)
            • Then - Actions
              • Item - Create (Item-type of ItemToDrop) at ItemDropPoint[ItemSlot]
              • Item - Remove ItemToDrop
            • Else - Actions
This will Create/Remove any Item carried by the Captain as long as it's NOT a Captain's Helm or Forgotten Glory.

Or better yet you could just Move the carried Item instead of creating a new copy and removing the original:
  • Item - Move ItemToDrop to ItemDropPoint[ItemSlot]
This will move it out of the unit's inventory and onto the ground.
 
Last edited:
Level 12
Joined
Jul 5, 2014
Messages
532
I assumed you had an Item Event or that this was being Run from another trigger that used an Item Event. But now I don't quite understand what you're trying to accomplish.
It's run by another trigger but apparently the "item being manipulated" needs an item event to work.

Yes, the goal is to drop all items except this two type (assuming they're in the inventory). What type of variable ItemToDrop and ItemSlot?
 

Uncle

Warcraft Moderator
Level 71
Joined
Aug 10, 2018
Messages
7,533
It's run by another trigger but apparently the "item being manipulated" needs an item event to work.

Yes, the goal is to drop all items except this two type (assuming they're in the inventory). What type of variable ItemToDrop and ItemSlot?
ItemToDrop is an Item variable and ItemSlot is an Integer variable. You can tell what they are by their values.

Anyway, what you were trying to do in your original trigger was incorrect.

Remember that triggers execute from top to bottom. So a trigger works like this:
1) An Event occurs causing the Trigger to run. Certain Event Responses are set based on the Event, these act like variables that track related data temporarily.
2) The Conditions run one by one, from top to bottom. If they're all true then the Actions happen. If one of them is false then everything stops and we skip #3.
3) The Actions happen one by one, from top to bottom.

So the If - Conditions in your original trigger have no relationship with anything below this line:
  • Then - Actions
They happen BEFORE the Then - Actions yet they're trying to interact with stuff that happens inside of there. But regardless, there is no (Item being manipulated) throughout the entire trigger anyway, since Event Responses are set in response to an Event occurring which did not happen. So you're asking if "no item" is NOT equal to Captain's Helm or Forgotten Glory. That doesn't really make any sense.

Note how in my implementation we use the If Then Else AFTER getting the Item from the captain, because our questions in the If - Conditions are related to that specific item. In other words, we have to ask the same two questions for each item -> Is item in slot 1 a ... , Is item in slot 2 a ... , Is item in slot 3 a ... , and so on for all 6 item slots.
 
Last edited:
Level 12
Joined
Jul 5, 2014
Messages
532
I assumed you had an Item Event or that this was being Run from another trigger that used an Item Event. But now I don't quite understand what you're trying to accomplish.

Do you want the Captain to drop everything BESIDES those two items? If so, your Conditions still don't make any sense.

I think this is what you want:
  • The Captains Items
    • Events
    • Conditions
    • Actions
      • For each Integer (ItemSlot) from 1 to 6 do (Actions)
        • Loop - Actions
          • Set ItemToDrop = (Item carried by TheCaptain in slot ItemSlot)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Item-type of ItemToDrop) Not equal to Captain's Helm)
              • ((Item-type of ItemToDrop) Not equal to Forgotten Glory)
            • Then - Actions
              • Item - Create (Item-type of ItemToDrop) at ItemDropPoint[ItemSlot]
              • Item - Remove ItemToDrop
            • Else - Actions
This will Create/Remove any Item carried by the Captain as long as it's NOT a Captain's Helm or Forgotten Glory.

Or better yet you could just Move the carried Item instead of creating a new copy and removing the original:
  • Item - Move ItemToDrop to ItemDropPoint[ItemSlot]
This will move it out of the unit's inventory and onto the ground.
Yes, that's working, thank you. All that left is the leak elimination. When it comes to array, do you clean up all six locations with a single "call RemoveLocation(udg_ItemDropPoint)"? I think I've read something about arrays count as one.
 

Uncle

Warcraft Moderator
Level 71
Joined
Aug 10, 2018
Messages
7,533
Yes, that's working, thank you. All that left is the leak elimination. When it comes to array, do you clean up all six locations with a single "call RemoveLocation(udg_ItemDropPoint)"? I think I've read something about arrays count as one.
You would have to clean up all six like so:
  • Custom script: call RemoveLocation( udg_ItemDropPoint[udg_ItemSlot] )
If you plan on reusing those Points then I suggest that you do NOT Remove them. There's nothing wrong with keeping them up and running for the entire game, they aren't actually considered a memory leak since they're "constant" -> they only get Set once.

That being said, if the Points are no longer needed then feel free to Remove them, it'll free up a tiny amount of memory and I suppose every little bit helps.
 
Last edited:
Top