• 🏆 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!

[Solved] Lingering Special Effect

Status
Not open for further replies.
Level 3
Joined
Apr 20, 2021
Messages
19
So I made a fairly simple custom spell called Sabotage that allows a specific unit-type, the Scout, to cast on a Supply Crate to set it on fire. I used the Rejuvenation skill as a base and changed its stats accordingly. The burning special effect that is supposed to envelop the Supply Crate wouldn't work for some reason so I attempted to use a trigger to do that.

1619003253296.png



This works fine, except there's a slight problem. Whenever another Scout uses the same Sabotage ability before the previous Sabotage ability finishes destroying a Supply Crate, it will leave an irremovable flame special effect on the ground. I believe it has something to do with the game detecting the latest special effect being the most recent and therefore ignores the special effect placed beforehand. Could anyone help me fix this problem?

1619003713578.png
 
Level 21
Joined
Mar 29, 2020
Messages
1,237
you are using "destroy last created special effect". once a new special effect is created during those 12 seconds (like this being casted again) the game looses track of the first special effect and only tries to destroy the second one twice. you have to keep track of the special effects somehow.

one way you can do what you are trying to do is by creating a dummy unit with it's model being the fire (instead of the special effect) and have a "generic expiration timer" for 12 seconds that kills the dummy. this way you don't need any pesky "wait"s in your trigger.
 
Level 3
Joined
Apr 20, 2021
Messages
19
you are using "destroy last created special effect". once a new special effect is created during those 12 seconds (like this being casted again) the game looses track of the first special effect and only tries to destroy the second one twice. you have to keep track of the special effects somehow.

one way you can do what you are trying to do is by creating a dummy unit with it's model being the fire (instead of the special effect) and have a "generic expiration timer" for 12 seconds that kills the dummy. this way you don't need any pesky "wait"s in your trigger.
I'll see if I can successfully attempt your advice. A question though; is it better to have a "Generic Expiration Timer" than a "Wait"? If so, why? Many thanks for helping!
 
Level 4
Joined
Jun 28, 2012
Messages
23
A bit complicated but avoid using wait because it pauses the thread and you don't want to do that, you would prefer using timer in your example, or a dummy unit, easier in GUI's case.
DUMMYUNIT.png

Just create an unit with whatever model you want, with no movement speed and voilà !
 
Last edited:
Level 21
Joined
Mar 29, 2020
Messages
1,237
a generic expiration timer is much better when it is relevant bc nothing can get messed up. when you wait and then do x to last created unit, or variable x - in the meanwhile (from when the trigger went off and untill it finishes "waiting") a different unit could have been created, and so the handle "last create unit" no longer points to the unit you meant. likewise, meanwhile the variable you were using (if you were) could have been written over.

when you use an expiration timer - it is "stuck" to the unit itself. you don't need to keep track of it. but it is only useful for killing units. waits have many more purposes, but because of the above liablity it is often useful to find a different way to do it. If you want to use waits you probably need some sort of unit indexer so you can keep track of the units in question.
 
Level 3
Joined
Apr 20, 2021
Messages
19
you are using "destroy last created special effect". once a new special effect is created during those 12 seconds (like this being casted again) the game looses track of the first special effect and only tries to destroy the second one twice. you have to keep track of the special effects somehow.

one way you can do what you are trying to do is by creating a dummy unit with it's model being the fire (instead of the special effect) and have a "generic expiration timer" for 12 seconds that kills the dummy. this way you don't need any pesky "wait"s in your trigger.
I'll see if I can successfully attempt your advice. A question though; is it better to have a "Generic Expiration Timer" than a "Wait"? If so, why? Many thanks for helping!
a generic expiration timer is much better when it is relevant bc nothing can get messed up. when you wait and then do x to last created unit, or variable x - in the meanwhile (from when the trigger went off and untill it finishes "waiting") a different unit could have been created, and so the handle "last create unit" no longer points to the unit you meant. likewise, meanwhile the variable you were using (if you were) could have been written over.

when you use an expiration timer - it is "stuck" to the unit itself. you don't need to keep track of it. but it is only useful for killing units. waits have many more purposes, but because of the above liablity it is often useful to find a different way to do it. If you want to use waits you probably need some sort of unit indexer so you can keep track of the units in question.
Very useful information! I'll make sure to implement that into My future triggers.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,517
I attached a map with a simple system you can use.

So using your above trigger as an example:
  • Example
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Sabotage
    • Actions
      • Special Effect - Create a special effect at (Position of (Target unit of ability being cast)) using Environment\LargeBuildingFire\LargeBuildingFire1.mdl
      • Set VariableSet CE_Duration = 12.00
      • Trigger - Run CE With Duration <gen> (ignoring conditions)
This will automatically destroy the special effect after 12.00 seconds without any issues.

How to use:
1: Copy and paste the ControlledEffects folder into your map.
2: Then in your desired trigger:
First Create the special effect, then Set the CE_Duration variable to however long you want the effect to last, and finally Run the trigger CE With Duration (ignoring conditions).

You can also use the system to add delays to your special effects so that they're created after a set amount of time. There are examples of this and other useful features in the demo map.

If you can't open the map (I'm using the latest version of wc3) here is what the CE With Duration trigger looks like:
  • CE With Duration
    • Events
    • Conditions
    • Actions
      • Custom script: local effect sfx = GetLastCreatedEffectBJ()
      • Wait CE_Duration seconds
      • Custom script: call DestroyEffect(sfx)
      • Custom script: set sfx = null
CE_Duration is a Real variable.
 

Attachments

  • Controlled Effects v.1.w3m
    18.5 KB · Views: 10
Last edited:
Status
Not open for further replies.
Top