• 🏆 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 Check, Leaks, MUI, etc

Status
Not open for further replies.
Level 12
Joined
May 20, 2009
Messages
822
Just want to check if there's still any leaks in this and if it is MUI or not.

  • Star Call
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
    • Actions
      • Custom script: local unit u = null
      • Custom script: local unit trigunit = null
      • Custom script: local unit dumunit = null
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Ability being cast) Equal to Star Call
        • Then - Actions
          • Custom script: set u = GetSpellTargetUnit()
          • Custom script: set trigunit = GetTriggerUnit()
          • Set SC_Target = (Target unit of ability being cast)
          • Set SC_Point = (Position of SC_Target)
          • Unit - Create 1 Dummy Caster for (Owner of (Triggering unit)) at SC_Point facing SC_Point
          • Custom script: call RemoveLocation(udg_SC_Point)
          • Custom script: set dumunit = GetLastCreatedUnit()
          • Set SC_Target = (Target unit of ability being cast)
          • -------- This is the Important part. Choose your effect, then set the Wait to the Duration of the effect. --------
          • Special Effect - Create a special effect attached to the origin of SC_Target using Abilities\Spells\NightElf\Starfall\StarfallTarget.mdl
          • Special Effect - Destroy (Last created special effect)
          • Wait 0.90 game-time seconds
          • Custom script: set udg_SC_Target = u
          • Custom script: set udg_SC_Caster = trigunit
          • Custom script: set udg_SC_DummyCaster = dumunit
          • Set SC_Point = (Position of SC_Target)
          • Set SC_Owner = (Owner of SC_Caster)
          • Set SC_Level = (Level of Star Call for SC_Caster)
          • -------- END VARIABLE --------
          • Unit - Set level of Shadow Strike for SC_DummyCaster to SC_Level
          • Unit - Order SC_DummyCaster to Night Elf Warden - Shadow Strike SC_Target
          • Unit - Add a 3.00 second Generic expiration timer to SC_DummyCaster
          • Custom script: call RemoveLocation(udg_SC_Point)
          • Custom script: set dumunit = null
          • Custom script: set trigunit = null
          • Custom script: set u = null
        • Else - Actions
 
Level 13
Joined
Dec 21, 2010
Messages
541
why make custom scripts like these??
Custom script: local unit u = null
Custom script: local unit trigunit = null
Custom script: local unit dumunit = null
if you already have the variables like these?
SC_Target
SC_Caster
SC_DummyCaster

It doesn't make any sense... it's like redundant ...you can just set them to no unit at the end of your trigger..

  • Star Call
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Star Call
    • Actions
      • Set - SC_Caster = Triggering unit
      • Set - SC_Level = (Level of Star Call for SC_Caster)
      • Set - SC_Target = (Target unit of ability being cast)
      • Set - SC_Point = (Position of SC_Target)
      • Unit - Create 1 Dummy Caster for (Owner of (SC_Caster)) at SC_Point facing SC_Point
      • Set - SC_DummyCaster = Last created unit
      • Special Effect - Create a special effect attached to the origin of SC_Target using Abilities\Spells\NightElf\Starfall\StarfallTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • Unit - Set level of Shadow Strike for SC_DummyCaster to SC_Level
      • Unit - Order SC_DummyCaster to Night Elf Warden - Shadow Strike SC_Target
      • Unit - Add a 3.00 second Generic expiration timer to SC_DummyCaster
      • Custom script: call RemoveLocation(udg_SC_Point)
      • Set - SC_Caster = no unit
      • Set - SC_Target = no unit
      • Set - SC_DummyCaster = no unit
      • Set - SC_Level = 0
and no need to use WAIT,,, just add 0.9 casting time to the Shadow Strike ability that you add to the dummy....make sure the ability has 99999 range, no mana cost and no cooldown.. make sure the dummy has 0.00 art - animation cast point and backswing...
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Here is the CustomPolledWait():
JASS:
function CustomPolledWait takes real duration returns nothing
    local timer t

    if duration > 0 then
        set t = CreateTimer()
        call TimerStart(t, duration, false, null)
        loop
            set duration = TimerGetRemaining(t)
            exitwhen duration <= 0
            
            
            if duration > bj_POLLED_WAIT_SKIP_THRESHOLD then
                call TriggerSleepAction(0.1 * duration)
            else
                call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
            endif
        endloop
        
        call DestroyTimer(t)
        set t = null
    endif
endfunction

Put it in the map header file and use a custom script: "call CustomPolledWait(0.9)" to do the wait.

I never heard of adding Casting Time to Dummy abilities.
I am not quite sure if that would open glitches but it seems legit.
 
Level 12
Joined
May 20, 2009
Messages
822
I am guessing that is not TriggerSleepAction? If so it will leak a handle index every call due to a bug with PolledWaitBJ. The work around is to call a custom implementation that nulls the local declared local timer before returning.

How big of a leak are we talking here?

Let's say the spell is cast every 17 seconds for a 30 minute game. Could that cause a visible difference in frame-rate/performance at 15, 20, 25-minute marks?

why make custom scripts like these??
Custom script: local unit u = null
Custom script: local unit trigunit = null
Custom script: local unit dumunit = null
if you already have the variables like these?
SC_Target
SC_Caster
SC_DummyCaster

It doesn't make any sense... it's like redundant ...you can just set them to no unit at the end of your trigger..

  • Star Call
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Star Call
    • Actions
      • Set - SC_Caster = Triggering unit
      • Set - SC_Level = (Level of Star Call for SC_Caster)
      • Set - SC_Target = (Target unit of ability being cast)
      • Set - SC_Point = (Position of SC_Target)
      • Unit - Create 1 Dummy Caster for (Owner of (SC_Caster)) at SC_Point facing SC_Point
      • Set - SC_DummyCaster = Last created unit
      • Special Effect - Create a special effect attached to the origin of SC_Target using Abilities\Spells\NightElf\Starfall\StarfallTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • Unit - Set level of Shadow Strike for SC_DummyCaster to SC_Level
      • Unit - Order SC_DummyCaster to Night Elf Warden - Shadow Strike SC_Target
      • Unit - Add a 3.00 second Generic expiration timer to SC_DummyCaster
      • Custom script: call RemoveLocation(udg_SC_Point)
      • Set - SC_Caster = no unit
      • Set - SC_Target = no unit
      • Set - SC_DummyCaster = no unit
      • Set - SC_Level = 0
and no need to use WAIT,,, just add 0.9 casting time to the Shadow Strike ability that you add to the dummy....make sure the ability has 99999 range, no mana cost and no cooldown.. make sure the dummy has 0.00 art - animation cast point and backswing...

You know, that's a good point. But I already went to the trouble of making this and I think the implementation is pretty clever, for me anyway. So I'll keep it as-is. Without the wait, I actually don't even need any variable other then the point.

Besides, there might be a case that just using casting time won't cut it so this would be nice to have laying around.

Well... I never use dummies any more :D
Every reason why I would do that is replaced by one of my systems.

There might be a problem if they are interrupted for some weird reason.

With this spell? Before, I was using "Finishes Casting an Ability" so I didn't have to use a wait. But that had a weird side-effect if the casting was interrupted before the casting finished. So that's why I had to use this wait function.

Also... You don't use dummies? How's that possible? Buffs are a very important aspect of custom spells and allow for numerous functionality's. If you're not having a buff being put on a unit, you're missing out on a lot of features and mechanic combinations. And pretty much the only way a buff can be put on a unit is by another unit casting an ability.

EDIT2:

I have one more spell that is actually causing me some problems. The first cast is completely fine, but the second time it's cast no effects are done to units in the AoE:

This was a really simple mistake...


  • I'm dumb. The problem was I was deindexing the wrong point variable.
  • [/HIDDEN]
  • EDIT3:
  • [quote="Wietlol, post: 2665611"]Here is the CustomPolledWait():
  • [code=jass]function CustomPolledWait takes real duration returns nothing
    • local timer t
    • if duration > 0 then
      • set t = CreateTimer()
      • call TimerStart(t, duration, false, null)
      • loop
        • set duration = TimerGetRemaining(t)
        • exitwhen duration <= 0
        • if duration > bj_POLLED_WAIT_SKIP_THRESHOLD then
          • call TriggerSleepAction(0.1 * duration)
        • else
          • call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
        • endif
      • endloop
      • call DestroyTimer(t)
      • set t = null
    • endif
  • endfunction[/code]
  • Put it in the map header file and use a custom script: "call CustomPolledWait(0.9)" to do the wait.
  • I never heard of adding Casting Time to Dummy abilities.
  • I am not quite sure if that would open glitches but it seems legit.[/QUOTE]
  • Also, thanks for that.
  • EDIT4: Wait a minute, does that wait go off of Fastest Game Speed Time, or Real-Time/Normal Game Speed Time?
 
Last edited:
Level 24
Joined
Aug 1, 2013
Messages
4,657
The wait that I showed is game time sleep.
Real time sleep is inside it which is neccesary to make it work.
If you want real life sleep, you use TriggerSleepAction(123.456) instead.

Both waits are still inaccurate and have a slight delay before they end so if you want perfect accuracy then you should use timers.
 
Level 12
Joined
May 20, 2009
Messages
822
It's accuracy is good enough for me. Thanks for the function, man. =)

So it appears that trigger is pretty much done. Unless someone else has any more suggestions.

venger07 said:
It doesn't make any sense... it's like redundant ...you can just set them to no unit at the end of your trigger..

Oh, and the reason why is because the only reason the globals are there is because there's no quick-n-easy way to use local variables in a GUI function. And if I only used the globals, it wouldn't be MUI with the Wait. And I remember I actually tried using the Casting Time, but Casting Time on Shadow Strike is weird. It's not like Casting Time on other spells, I think it's used in conjunction with the Decay Power data field to determine the time between when Decaying Damage is done.

I've set the casting time to 10+ seconds before on Shadow Strike for this very spell and it still just casts instantly before my special effect finishes playing. So that's why I have the wait.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
There is a better whay than what you do now.
It is called shadowing globals.
What you do is make a local variable with the same name as the global variable.
When you use a global variable in a function, it uses the data stored to that name.
When there is a local with that name, it uses that local. If there is no local, then it uses the global.

In this case, you want to use

  • Custom script: local unit udg_SC_Target
  • Custom script: local unit udg_SC_Caster
  • Custom script: local unit udg_SC_DummyCaster
Then you can use globals as locals.

I would also recommend you to put the ability condition in the condition tags.
 
Level 12
Joined
May 20, 2009
Messages
822
Wietlol said:
I would also recommend you to put the ability condition in the condition tags.

Eeh, I just put it there out of habit. It doesn't seem to make a difference to me.

Wietlol said:
There is a better whay than what you do now.
It is called shadowing globals.
What you do is make a local variable with the same name as the global variable.
When you use a global variable in a function, it uses the data stored to that name.
When there is a local with that name, it uses that local. If there is no local, then it uses the global.

In this case, you want to use

Custom script: local unit udg_SC_Target
Custom script: local unit udg_SC_Caster
Custom script: local unit udg_SC_DummyCaster

That seems INCREDIBLY useful. I'll have to try that tomorrow, maybe. But I'm too lazy to do it at the moment.
 
Level 5
Joined
Jan 27, 2014
Messages
164
> Eeh, I just put it there out of habit. It doesn't seem to make a difference to me.
It does if you're dealing with locals. Locals don't work well with GUI versions of if then else. (Which makes me suspect that your trigger in Post#1 might not work, or does it work?)
 
Level 12
Joined
May 20, 2009
Messages
822
> Eeh, I just put it there out of habit. It doesn't seem to make a difference to me.
It does if you're dealing with locals. Locals don't work well with GUI versions of if then else. (Which makes me suspect that your trigger in Post#1 might not work, or does it work?)

Declaring a Local in an ITE doesn't work, no. But setting them works fine. (Notice none of my locals are declared in the ITE) But now that you mention it, I wonder if those locals that I'm declaring are causing a leak? Or do they get automatically cleaned up with the trigger instance?
 
Status
Not open for further replies.
Top