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

[Spell] What is the deal with the wait function?

Status
Not open for further replies.
Level 3
Joined
Nov 19, 2014
Messages
39
So I use the wait function quite often in spells, especially when creating/destroying special effects, but sometimes the trigger bugs and the special effect stays forever without being destroyed.

this is basically what I'm doing:

Event: Unit starts the effect of an ability

Condition: Ability being cast equal to xxx

Action:
-Create a special effect on unit ...
-Wait xxx seconds
-Destroy last created special effect

What is wrong with this ?
 
Level 14
Joined
Jul 1, 2008
Messages
1,314
you can save your last created special effect before the wait into a special effect variable and then "destroy this variable" after the wait.

You should consider every "Last created" thing or whatsoever to be lost after a wait action. Save all you want to keep in to variables.
 
Level 3
Joined
Nov 19, 2014
Messages
39
Thank you for all the responses. But if I use Jass like Emm-A- suggested, it wont change anything because if we suppose two players cast the ability with a small time delay (smaller than the wait time) or if the spell's cd is less than the wait time and is casted twice, then in the multiplayer case one of the effects will stay and the other will be destroyed and in the latter case only the second effect will be destroyed and the initial will stay. So the problem persists anyways.
 
Level 14
Joined
Jul 1, 2008
Messages
1,314
But if I use Jass like Emm-A- suggested, it wont change anything
This makes no sense at all, unless you are able to look into the future, which does not make any sense either...

Anyway, do what Chaosy and DracoL1ch suggested and insert these actions.
1. at the beginning of the trigger:
  • Custom Script: local effect e
2. Right after you created your effect or at least before the wait:
  • Custom Script: set e = bj_lastCreatedEffect
3. When you want to destroy your effect:
  • Custom Script: call DestroyEffect(e)
  • Custom Script: set e = null
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Ofcourse it makes sense.
You tell someone to change the road, but you haven't explained the difference in their destiny. To him, the destiny remains the same... because you didn't tell him to use local variables.

Local variables can, as shown, also be used in GUI, and even better, be used to "shadow globals".
The usage of global variables is exactly the same as local variables.
As long as the name is the same, it will act like the lowest scope variable of that identifier.

So if you have a global variable called "TempEffect" (which translates to the identifier "udg_TempEffect"), you can use "Custom Script: local effect udg_TempEffect" and the global variable will now act as a local variable.
So you store the last created special effect in the global variable (using the GUI Set Variable action) just before you do the wait, and you nullify that variable after you are done with it and after you destroyed the special effect.

So:
  • Actions:
    • Custom script: local effect udg_TempEffect
    • Special Effect - Create new Special effect bla bla bla
    • Set TempEffect = (Last Created Special Effect)
    • Wait (123.456) seconds of game-time. (idc about it's leak)
    • Special Effect - Destroy TempEffect
    • Custom script: set udg_TempEffect = null
 
Level 19
Joined
Jul 2, 2011
Messages
2,162
using wait can also cause out of sync between two computers as people's computers measure time slightly differently

it's best to use wait in game, which asks each computer to listen for a notification from the game that time has passed.

as for special effects? create a array that holds special effects. then cycle through the effects insuring no effect ever persists

30 as example
int w=0

destroy array w
create special effect
array effect w =last created effect
w++
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
That wont solve the problem.
You want to give each effect a life cycle, not a cleanup that destroys all effects now and then.

If you really want to do it properly, you could be doing it using timers, storing the effect on their index and cleaning everything up after they expire.

If you download and install JNGP 2.0 and insert TimerUtils, you can use this:
JASS:
struct SpecialEffect
    
    readonly timer t
    public effect e
    
    private static method create takes nothing returns thistype
        return 0
    endmethod
    
    private static method onExpire takes nothing returns nothing
        local thistype this = GetTimerData(GetExpiredTimer())
        
        call DestroyEffect(.e)
        
        call ReleaseTimer(.t)
        set .t = null
        set .e = null
        call .deallocate()
    endmethod
    
    public static method addTimedLife takes effect e, real duration returns thistype
        local thistype this = .allocate()
        
        set .e = e
        set .t = NewTimerEx(this)
        call TimerStart(.t, duration, false, function thistype.onExpire)
        
        return this
    endmethod
    
    public method cancel takes nothing returns nothing
        call ReleaseTimer(.t)
        set .t = null
        set .e = null
        call .deallocate()
    endmethod
    
endstruct

All you have to do then is "Custom script: call SpecialEffect.addTimedLife(udg_TempEffect, 123.456)"
Instead of udg_TempEffect, you could also do bj_lastCreatedEffect in this case.
The 123.456 is just the duration, you can choose whatever you want.
 
Level 3
Joined
Nov 19, 2014
Messages
39
It made sense because I tried storing the special effect into a variable and making the trigger, but that didn't change anything. I didn't use custom scripting, I just used the Set variable function, but apparently I have to use custom scripting.

Anyways I fixed this simply by putting the special effect as a buff inside the spell in the object editor (which I thought I had already done), but this isn't going to work on all spells so I guess I need to start learning jass :C.
 
Level 3
Joined
Nov 19, 2014
Messages
39
You can do it the simple way (what I have shown in this post).
It is just a less optimal solution because the duration will not be perfectly accurate.

I appreciate it mate, I will apply your suggestion in case I encounter this problem again in the future. Btw, are you by any chance interested in map developing ?
You seem to know much about jass and other relevant stuff.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Hence why they are horrible in multiplayer maps... having a delay of sometimes a few seconds... ye B.net network sucks.

I appreciate it mate, I will apply your suggestion in case I encounter this problem again in the future. Btw, are you by any chance interested in map developing ?
You seem to know much about jass and other relevant stuff.
Knowledge isnt the problem. Time is.
 
Level 3
Joined
Nov 19, 2014
Messages
39
I also have a question about metamorphosis, can a certain animation be played during the transformation? if I don't play an animation, the transformation looks abrupt and rigid, the unit stands still unanimated for 1.5 seconds and then the alternate form appears. I tried using triggers and editing the animation names and neither worked.
 
Status
Not open for further replies.
Top