**SOLVED**
I'm currently figuring out how T32 works and have trouble with optimizing my code.
I wrote a simple sequence ability where one action is done after the other always with a few milliseconds delay, like this:
The ability I have works fine. Just the coding is meh...
I used this as a basis:
and got this (simplified):
So how could I do this better? Like using only one Timer struct...
**UPDATE**
for completion the complete trigger
I'm currently figuring out how T32 works and have trouble with optimizing my code.
I wrote a simple sequence ability where one action is done after the other always with a few milliseconds delay, like this:
JASS:
call Action => start Timer0
Timer0 expires => call DoAttack => start Timer1
Timer1 expires => call StartProjectile; OnFinish => start Timer2
Timer2 expires => call DoRetreat (end)
The ability I have works fine. Just the coding is meh...
I used this as a basis:
JASS:
scope test initializer dotest
private struct teststruct
private integer endTick
private method periodic takes nothing returns nothing
call BJDebugMsg(I2S(this))
if this.endTick == T32_Tick then // no more this.ticksLeft stuff and incrementing.
call this.stopPeriodic() // never follow with a .startPeriodic() call
call this.destroy() // of any sort (when in the .periodic method).
endif
endmethod
implement T32x
static method create takes real duration returns thistype
local thistype this = thistype.allocate()
set this.endTick = T32_Tick + R2I(duration / T32_PERIOD)
return this
endmethod
endstruct
private function dotest takes nothing returns nothing
// Creates structs which display their integer id 32 times a second for x seconds.
call teststruct.create(3.0).startPeriodic()
call teststruct.create(5.0).startPeriodic()
endfunction
endscope
and got this (simplified):
JASS:
library
//...
private function DoRetreat takes BSMove s returns nothing
//...
endfunction
//=================================================
// TIMER 2
//=================================================
private struct RangedAttack_Timer2
private method periodic takes nothing returns nothing
//...
if this.endTick == T32_Tick then
call DoRetreat(bs)
//...
endmethod
endstruct
//=================================================
private function OnFinish takes projectile p returns nothing
call RangedAttack_Timer2.create(TIMER_DUR2, s).startPeriodic()
endfunction
private function StartProjectile takes BSMove s returns nothing
call OnFinish(...)
endfunction
//=================================================
// TIMER 1
//=================================================
private struct RangedAttack_Timer1
private method periodic takes nothing returns nothing
//...
if this.endTick == T32_Tick then
call StartProjectile(bs)
//...
endmethod
endstruct
//=================================================
private function DoAttack takes BSMove s returns nothing
call RangedAttack_Timer1.create(TIMER_DUR1, s).startPeriodic()
endfunction
//=================================================
// TIMER 0
//=================================================
private struct RangedAttack_Timer0
private method periodic takes nothing returns nothing
//...
if this.endTick == T32_Tick then
call DoAttack(bs)
//...
endmethod
endstruct
//=================================================
function Action takes BSMove s returns nothing
call RangedAttack_Timer0.create(TIMER_DUR0, s).startPeriodic()
endfunction
endlibrary
So how could I do this better? Like using only one Timer struct...
**UPDATE**
for completion the complete trigger
JASS:
library AttackRange initializer Init requires MovementSystem, SoundTools, UnitDataList
globals
private constant real SPEED = 3000.
private constant real TIMER_DUR1 = 0.1 // attack delay
private constant real TIMER_DUR2 = 0.2
private constant string SOUND_CHARGE = "Abilities\\Weapons\\CannonTowerMissile\\CannonTowerMissileLaunch1.wav"
private location loc = Location(0.00,0.00)
endglobals
//***********************************************************************
private function DoRetreat takes BSMove s returns nothing
call MoveReturn(s)
endfunction
private struct RangedAttack_Timer2
private integer endTick
private BSMove bs
private method periodic takes nothing returns nothing
if this.endTick == T32_Tick then // no more this.ticksLeft stuff and incrementing.
call DoRetreat(bs)
set this.bs = 0
call this.stopPeriodic() // never follow with a .startPeriodic() call
call this.destroy() // of any sort (when in the .periodic method).
endif
endmethod
implement T32x
static method create takes real duration, BSMove s returns thistype
//static method create takes real duration returns thistype
local thistype this = thistype.allocate()
set this.bs = s
set this.endTick = T32_Tick + R2I(duration / T32_PERIOD)
return this
endmethod
endstruct
private function OnFinish takes projectile p returns nothing
local BSMove s = BSM_Array[GetUnitId(p.sourceUnit)]
call SetUnitTimeScale(s.Unit, .5)
call RangedAttack_Timer2.create(TIMER_DUR2, s).startPeriodic()
call p.terminate()
set s = 0
endfunction
private function OnLoop takes projectile p returns nothing
endfunction
private function StartProjectile takes BSMove s returns nothing
local unit u = s.Unit
local real ux = GetUnitX(u)
local real uy = GetUnitY(u)
local real tarx = s.TargetX
local real tary = s.TargetY
local real ang = Atan2((tary - uy),(tarx - ux))
local real dist = DistanceBetweenPoints(Location(tarx,tary),Location(ux,uy))
local projectile proj = 0
call MoveLocation(loc,ux,uy)
//---------------------------------------------------------
//set proj = projectile.create(ux,uy,GetUnitFlyHeight(u) + 150.00 + GetLocationZ(loc),ang)
set proj = projectile.create(ux,uy,GetUnitFlyHeight(u) + GetProjHeight(s.Unit),ang)
set proj.sourceUnit = s.Unit
set proj.owningPlayer = GetOwningPlayer(u)
set proj.effectPath = GetProjEffect(s.Unit) // Caster Projectile
//set proj.damageDealt = 0.
set proj.scaleSize = 1.
set proj.zOffset = 50.00 // Unit Projectile Offset?
set proj.timedLife = dist / SPEED // Unit Projectile Speed?
set proj.allowExpiration = true
set proj.allowDeathSfx = true
set proj.allowArcAnimReset = true
set proj.allowUnitCollisions = false
set proj.allowDestCollisions = false
set proj.onExpire = OnFinish
//set proj.onFinish = OnFinish
set proj.onLoop = OnLoop
call MoveLocation(loc,tarx,tary)
call proj.projectNormal(tarx,tary,50.00 + GetLocationZ(loc),SPEED)
//---------------------------------------------------------
set u = null
endfunction
private struct RangedAttack_Timer1
private integer endTick
private BSMove bs
private method periodic takes nothing returns nothing
if this.endTick == T32_Tick then // no more this.ticksLeft stuff and incrementing.
call StartProjectile(bs)
set this.bs = 0
call this.stopPeriodic() // never follow with a .startPeriodic() call
call this.destroy() // of any sort (when in the .periodic method).
endif
endmethod
implement T32x
static method create takes real duration, BSMove s returns thistype
//static method create takes real duration returns thistype
local thistype this = thistype.allocate()
set this.bs = s
set this.endTick = T32_Tick + R2I(duration / T32_PERIOD)
return this
endmethod
endstruct
private function DoAttack takes BSMove s returns nothing
local unit u = s.Unit
call IssueImmediateOrder(u, "stop")
call SetUnitAnimation(u, "stand")
call SetUnitTimeScale(u, 2.)
call SetUnitAnimation(u, "attack")
call QueueUnitAnimation(u, "ready")
call RangedAttack_Timer1.create(TIMER_DUR1, s).startPeriodic()
//-------------------------------------------
set u = null
endfunction
private struct RangedAttack_Timer0
private integer endTick
private BSMove bs
private method periodic takes nothing returns nothing
if this.endTick == T32_Tick then // no more this.ticksLeft stuff and incrementing.
call DoAttack(bs)
set this.bs = 0
call this.stopPeriodic() // never follow with a .startPeriodic() call
call this.destroy() // of any sort (when in the .periodic method).
endif
endmethod
implement T32x
static method create takes BSMove s returns thistype
//static method create takes real duration returns thistype
local real duration = s.Duration + 0.1
local thistype this = thistype.allocate()
set this.bs = s
set this.endTick = T32_Tick + R2I(duration / T32_PERIOD)
return this
endmethod
endstruct
function abilRangeAttack takes BSMove s returns nothing
call SimpleSoundOnUnit(SOUND_CHARGE, s.Unit)
call MoveForward(s)
call RangedAttack_Timer0.create(s).startPeriodic()
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
endfunction
endlibrary
Last edited by a moderator: