HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Loop Speed vs Timer

05-25-2006, 02:18 AM#1
MysticGeneral
I have this code:
Collapse JASS:
function Trig_BOOM_Actions takes nothing returns nothing
local unit TE = udg_PlayerHero[0]
local integer who = GetHandleInt( TE, "whoC")
local unit X = udg_CTarget[who]
local unit Y = null
local integer Z = 0
local integer i = 0
local boolean NoD = false
local unit array Uar
local integer array Iar
      call DisplayTextToPlayer(Player(0), 0, 0, I2S(who) )
loop
  exitwhen udg_UnitTargetModifier[Ix(who, 30, i)] < 1               // I have this because the
    set Uar[i] = udg_UnitTarget[Ix(who, 30, i)]                     // next call after this trigger
    set Iar[i] = udg_UnitTargetModifier[Ix(who, 30, i)]             // resets all the globals to null
    set i = i + 1
endloop
set i = 0
loop
  exitwhen Iar[i] == 0
      set Z = Iar[i]
      set Y = Uar[i]
      call DisplayTextToPlayer(Player(0), 0, 0, GetUnitName(Y) + " " + I2S(Z) )
      call CastSpellUnit( who, udg_PlayerHero[who], Y, 'A009', "shockwave" )   // This is where I can
        if NoD == false then                                                   // Tell it lags.
          call Slide(X, udg_PlayerHero[who], 40.00, 0.40)
          call SpecialACD(who, udg_CTarget[who], 0.40)
          call SetHandleReal( TE, "5mod", 2.00 )
          call DamageUnit( who, X, 1.00 )
          set NoD = true
        endif
      call SetHandleReal( TE, "5mod", 0.10 * Z)
      call DamageUnit( who, Y, 1.00 )
    set i = i + 1
endloop
    call FlushHandleLocals( TE )
endfunction

The problem with it is that there's about a .3 second delay inbetween each loop. I can tell because the shockwaves all come out at different times, and is noticeable by the human eye.

I wanted to know if using a timer would make it run smoother? I want the shockwaves to all appear to come out at once, instead of consecutively.

Uhhh, shortening code for me is also welcome.

P.S. Those displays are for testing purposes. Forgot to remove it.

EDIT:
The reason the SFX was lagging was because of my IF/THEN inbetween that loop. I'm still curious - would it be faster to loop or use a timer?
05-25-2006, 04:49 AM#2
SentryIII
I don't think it has anything to do with the trigger. As far as I can tell, you have a single unit (udg_PlayerHero[who], the value of who does not change in the loop) casting that spell multiple times (within the loop) similtaneously. It's impossible to do in the WC3 engine. You'll have to create a few temporary dummy units to cast that spell.

Then again, I don't use handles and I don't know how they work. :p
05-25-2006, 05:08 AM#3
emjlr3
shockwave is a very laggy spell cuz of the terrain deform, try carrion swarm
05-25-2006, 07:01 AM#4
PitzerMike
Indeed, timers are always smoother than loops + waits (also because waits are terribly inaccurate).
However, the callback function of the timer can't take arguments so you'll have to either use globals or gamecache to pass arguments to that callback function.
05-25-2006, 05:27 PM#5
MysticGeneral
I've actually fixed it. I also tried timers after fixing it. It seems to be working the same. I'm pretty sure that the timer function is faster, though. When using loops in a function you've called, you'll notice a slight delay before anything happens (I don't know why). When I used a timer, there was no noticeable delay.
05-26-2006, 07:37 AM#6
Rising_Dusk
I believe each unit has a casting point.
Most of which are around .3ish; you should look into making sure that is 0.00, then trying this.
Code:
Animation - Cast Point
Animation - Cast Backswing
They're both at the relative top of the object editor for whatever unit you have casting the spells.
((Making a note on the above, I've never confirmed what I'm saying, but I remember that it existed and felt you might consider looking into it. Just a suggestion. :P))

In my personal experience, timers are the way to go, but loops have their benefits as well (No attached variables and the such, you can use locals in the main function for the spell).
Sometimes it's convenient using one or the other, to be honest I've never had severe issues using either.
05-26-2006, 04:03 PM#7
Vexorian
Check if CastSpellUnit has waits . There is no other explanation for the difference unless it is what Risising Dusk said
05-26-2006, 04:37 PM#8
MysticGeneral
I always set dummy casters to have 0 cast point, cast swing, and animation blending. No waits in the CastSpellUnit function either. I don't know, it looks fine to me anyways, just a very slight noticeable delay. (You wouldn't normally notice it unless you spam the spell)
05-26-2006, 04:44 PM#9
Rising_Dusk
Well... CastSpellUnit is a function.
Try using an order native, might be the ticket you're looking for.

call IssuePointOrder(udg_PlayerHero[who], "shockwave", TargetX, TargetY)

I don't know what CastSpellUnit actually does, but I imagine in the loop calling the function is what's slowing it down ever so slightly.
If using a direct order yields the same result... Then I have no idea what to tell you.
05-26-2006, 05:52 PM#10
MysticGeneral
Here is the new script. It still delays and does not use CastSpellUnit().

Collapse JASS:
function Trig_Shock_Slash_Actions takes nothing returns nothing
local unit TE = udg_PlayerHero[0]
local integer who = GetHandleInt( TE, "whoC")
local unit X = udg_CTarget[who]
local unit Y = null
local integer Z = 0
local integer i = 0
local unit array Uar
local integer array Iar
loop
  exitwhen udg_UnitTargetModifier[Ix(who, 30, i)] < 1
    set Uar[i] = udg_UnitTarget[Ix(who, 30, i)]
    set Iar[i] = udg_UnitTargetModifier[Ix(who, 30, i)]
    set i = i + 1
endloop
set i = 0
loop
  exitwhen Iar[i] == 0
      set Z = Iar[i]
      set Y = Uar[i]
      call AddSFXTULP( "origin", Y, "Abilities\\Weapons\\Bolt\\BoltImpact.mdl" )
      call SetHandleReal( TE, "5mod", 0.10 * Z)
      call DamageUnit( who, Y, 1.00 )
    set i = i + 1
endloop
  call Slide(X, udg_PlayerHero[who], 40.00, 0.40)
  call SpecialACD(who, X, 0.40)
  call SetHandleReal( TE, "5mod", 2.00 )
  call DamageUnit( who, X, 1.00 )
    call FlushHandleLocals( TE )
endfunction

Here is the function "AddSFXTULP"

Collapse JASS:
function AddSFXTULP takes string where, unit which, string SFX returns nothing
call AddSpecialEffectTargetUnitBJ(where, which, SFX)
call DestroyEffectBJ( GetLastCreatedEffectBJ() )
endfunction

Here is DamageUnit (yeah, it might be this one -- lolz )

Collapse JASS:
function DamageUnit takes integer whoA, unit whoTD, real ActMod returns nothing  //ActMod = 1st mod
local unit TE = udg_PlayerHero[0]
local integer xA = S2I(StringFragment(udg_BaseDamage[whoA], 0, "-") ) // Base Minimum
local integer yA = S2I(StringFragment(udg_BaseDamage[whoA], 1, "-") ) // Base Max
local integer zA = GetRandomInt(xA, yA)
local integer xB = S2I(StringFragment(udg_WeaponDamageM[whoA], 0, "-") ) // Main Weapon Min
local integer yB = S2I(StringFragment(udg_WeaponDamageM[whoA], 1, "-") ) // Main Weapon Max
local integer zB = GetRandomInt(xB, yB)
local integer xC = S2I(StringFragment(udg_WeaponDamageS[whoA], 0, "-") ) // Secondary Weapon Min
local integer yC = S2I(StringFragment(udg_WeaponDamageM[whoA], 1, "-") ) // Secondary Weapon Max
local integer zC = GetRandomInt(xC, yC)

local integer zABa = R2I(I2R(zA + zB) * ActMod)
local real modB = 1.00
local real modC = 1.00
local real modD = 1.00
local real modE = 1.00
local real temp = I2R(zABa)
local real zABb
if GetHandleReal(TE, "5mod") >= 0.01 then
  set modE = GetHandleReal(TE, "5mod")
endif

set zABb = ((((temp * modB) * modC) * modD) * modE)

  call UnitDamageTargetBJ( udg_PlayerHero[whoA], whoTD, zABb, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL )
  call DisplayTextToPlayer(Player(whoA), 0, 0, R2S(zABb) )
endfunction

Yes, I do realize that the DamageUnit() can be GREATLY reduced. I'm not going to do that until my damage system is 100% completed. I use all those integers and reals as temporary references as to what I'm doing or what I plan on doing. So ignore the lengthy code on it as of now.
05-26-2006, 07:10 PM#11
Vexorian
FOr what is worth gamecache is slow but should be faster than string fragments
05-26-2006, 07:52 PM#12
Rising_Dusk
Just to let you know...
Replace...

Collapse JASS:
call AddSFXTULP( "origin", Y, "Abilities\\Weapons\\Bolt\\BoltImpact.mdl" )

function AddSFXTULP takes string where, unit which, string SFX returns nothing
    call AddSpecialEffectTargetUnitBJ(where, which, SFX)
    call DestroyEffectBJ( GetLastCreatedEffectBJ() )
endfunction

...with...

Collapse JASS:
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\Bolt\\BoltImpact.mdl", Y, "origin"))

You were looping two BJs inside of an unnecessary function before.
Little things like this add up and cause delays sometimes. :P
05-26-2006, 09:25 PM#13
MysticGeneral
Ahhh nice. Thanks, Rising_Dusk. I'll see if it still delays in a sec.
05-26-2006, 09:43 PM#14
blu_da_noob
Something that minor isn't going to cause a delay...
05-27-2006, 04:24 AM#15
Vexorian
fact is that nothing should really cause a delay, if anything just a freeze, but unless a Sync function or waits are used nothing should delay the thread