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

[Solved] Second timer not running

Status
Not open for further replies.
I'm working on this system that shoots a series of lightning effects, and I'm using 2 timers to A) control the interval between each shot and B) fade out each individual lightning effect. I'm having some issues getting the fade timer to work, however. It just doesn't run. I've used DebugMsg in all functions and the ones in IndividualLaser_Timer don't print on screen when I test it.

JASS:
library BL initializer BurstLaser_Setup

  
    globals
        private trigger BurstLaserTrigger = CreateTrigger()
        public boolean array UsesBurstLaser     //Must always be true or the system won't work.
        public boolean array Uninterruptible    //If true, lasers will keep firing even if the target is stunned or dead.
        public boolean array IsLaserGrounded    //If true, then your Lasers will always strike the ground. Invalidates LaserSpreadZ. Can be useful for AoE ground attacks.
        public integer array NumberOfLasers     //CANNOT BE LESS THAN 1 or you will deal no damage. The number of lasers that will be shot per attack. CANNOT BE LESS THAN 1
        public integer array LaserDuration      //How long an individual laser will last before it starts to fade.
        public integer array LaserFadeTime      //How long it takes for each laser to fade. 32 == 1 second.
        public integer array LaserInterval      //The time between lasers. 32 == 1 second.
        public string array LaserLaunchFX       //The string of the special effect that plays on the launch dummy.
        public string array LaserImpactFX       //The string of the special effect that plays on the impact dummy.
        public string array LaserAreaFX         //The string of the special effect that plays on the impact dummy in addition to the ImpactFX. Works better with an AOE laser.
        public real array LaserLaunchScale      //Size of the Launch
        public real array LaserImpactScale      //Size of the Impact
        public real array LaserAreaScale        //Size of the Area effect
        public string array LaserString         //The string of lightning effect itself.
        public real array LaserAOE              //If greater that 0. will deal damage in an area around the impact.
        public real array LaserLaunchOffset     //How far forward with the Launch effect be. Use negative values to move backwards.
        public real array LaserLaunchHeight     //Adjusts the Launch effect along the Z axis. Positive value go up, negative values go down.
        public real array LaserLaunchAngle      //By how many degrees will the Launch effect be? Positive values adjust the angle counter-clockwise.
        public real array LaserSpreadXY         //How much your laser will spread out along the X and Y axis.
        public real array LaserSpreadZ          //How much your laser will spread out along the Z axis.
        public attacktype array LaserAttackType //Vanilla attack type like ATTACK_TYPE_HERO, ATTACK_TYPE_PIERCE, etc
        public integer array LaserDamageType    //The damage type from Damage Engine
        public boolean array LaserHitAll        //The laser will harm all units in the LaserAOE. If LaserAOE is <= 0. this does nothing.
        public boolean array LaserFriendlyFire  //AOE damage will damage allies
        public unit array LaserSentry           //This is optional. If something is set as the Sentry, the lasers will shoot from that unit instead.
        public integer array LaserDummyType     //This is the dummy used for launch and impact effects.
        public real array RED
        public real array BLUE
        public real array GREEN
        public real array ALPHA
      
        //Events
        public real EVENT = 0.
        public unit EVENT_Source = null
        public unit EVENT_Target = null
    endglobals
  
  
    function BurstLaser_onIndex takes nothing returns boolean
  
        local unit Source = udg_UDexUnits[udg_UDex]
        local integer ID  = udg_UDex
      
        if udg_UnitIndexEvent == 1. then
          
            //Raycaster
            if GetUnitTypeId(Source) == 'aray' then
                set UsesBurstLaser[ID]      = true
                set LaserString[ID]         = "YLLN"
                set RED[ID]                 = 1.
                set BLUE[ID]                = 1.
                set GREEN[ID]               = 1.
                set ALPHA[ID]               = 1.
                set LaserLaunchFX[ID]       = "Abilities\\Weapons\\ProcMissile\\ProcMissile.mdl"
                set LaserImpactFX[ID]       = "Abilities\\Weapons\\ProcMissile\\ProcMissile.mdl"
                set LaserAreaFX[ID]         = ""
                set LaserLaunchScale[ID]    = 1.
                set LaserImpactScale[ID]    = 1.
                set LaserAreaScale[ID]      = 1.
                set NumberOfLasers[ID]      = 3
                set LaserDuration[ID]       = 7
                set LaserFadeTime[ID]       = 11
                set LaserInterval[ID]       = 7
                set LaserAOE[ID]            = 0.
                set IsLaserGrounded[ID]     = false
                set LaserLaunchOffset[ID]   = 40.
                set LaserLaunchHeight[ID]   = 60.
                set LaserLaunchAngle[ID]    = 0.
                set LaserSpreadXY[ID]       = 20.
                set LaserSpreadZ[ID]        = 20.
                set LaserAttackType[ID]     = ATTACK_TYPE_PIERCE
                set LaserDamageType[ID]     = udg_DamageTypeCode
                set Uninterruptible[ID]     = false
                set LaserHitAll[ID]         = false
                set LaserFriendlyFire[ID]   = false
                set LaserSentry[ID]         = null
                set LaserDummyType[ID]      = 'dumi'
              
            //Fire Beam
            elseif GetUnitTypeId(Source) == '????' then
          
            endif
          
        else
            set UsesBurstLaser[ID]      = false
            set LaserString[ID]         = ""
            set RED[ID]                 = 1.
            set BLUE[ID]                = 1.
            set GREEN[ID]               = 1.
            set ALPHA[ID]               = 1.
            set LaserLaunchFX[ID]       = ""
            set LaserImpactFX[ID]       = ""
            set LaserAreaFX[ID]         = ""
            set LaserLaunchScale[ID]    = 1.
            set LaserImpactScale[ID]    = 1.
            set LaserAreaScale[ID]      = 1.
            set NumberOfLasers[ID]      = 1
            set LaserDuration[ID]       = 1
            set LaserFadeTime[ID]       = 1
            set LaserInterval[ID]       = 1
            set LaserAOE[ID]            = 0.
            set IsLaserGrounded[ID]     = false
            set LaserLaunchOffset[ID]   = 0.
            set LaserLaunchHeight[ID]   = 0.
            set LaserLaunchAngle[ID]    = 0.
            set LaserSpreadXY[ID]       = 0.
            set LaserSpreadZ[ID]        = 0.
            set LaserAttackType[ID]     = null
            set LaserDamageType[ID]     = 0
            set Uninterruptible[ID]     = false
            set LaserHitAll[ID]         = false
            set LaserFriendlyFire[ID]   = false
            set LaserSentry[ID]         = null
            set LaserDummyType[ID]      = 0
        endif
      
        set Source = null
        return false
    endfunction
  
    function BurstLaser_Setup takes nothing returns nothing
        call TriggerRegisterVariableEvent( BurstLaserTrigger, "udg_UnitIndexEvent", EQUAL, 1.00 )
        call TriggerRegisterVariableEvent( BurstLaserTrigger, "udg_UnitIndexEvent", EQUAL, 2.00 )
        call TriggerAddCondition( BurstLaserTrigger, function BurstLaser_onIndex)
    endfunction
  
  
endlibrary

JASS:
scope BLonAttack initializer BL_onAttack

    globals
        private trigger BL_onAttack_Trigger = CreateTrigger()
        private group DamageGroup = CreateGroup()
     
        private constant real MAX_COLLISION_SIZE = 196.
     
        private real array Damage
        private real array FadeAmount
        private real array LaserRED
        private real array LaserBLUE
        private real array LaserGREEN
        private real array LaserALPHA
        private unit array LaserSource
        private unit array LaserTarget
        private unit array LaserDummyImpact
        private unit array LaserDummyLaunch
        private unit array LaserDummyArea
        private integer array LaserDummyType
        private integer array LaserInterval
        private integer array LaserIntervalSave
        private integer array LaserCount
        private lightning array Laser
        private boolean array IsLaserFading
        private boolean array IsLaserGrounded
        private boolean array LaserHitAll
        private boolean array LaserFriendlyFire
        private real array LaserLaunchOffset
        private real array LaserLaunchHeight
        private real array LaserLaunchAngle
        private real array LaserSpreadXY
        private real array LaserSpreadZ
        private string array LaserString
        private string array LaserLaunchFX
        private string array LaserImpactFX
        private string array LaserAreaFX
        private real array LaserLaunchScale
        private real array LaserImpactScale
        private real array LaserAreaScale
        private real array LaserDamage
        private real array LaserAOE
        private attacktype array LaserAttackType
        private integer array LaserDamageType
    endglobals
 
 
 
    function IndividualLaser_Timer takes nothing returns nothing
        local timer t               = GetExpiredTimer()
        local integer NewTimerID    = GetTimerData(t)
     
        if IsLaserFading[NewTimerID] then
            call BJDebugMsg("fade")
            set LaserALPHA[NewTimerID] = LaserALPHA[NewTimerID] - FadeAmount[NewTimerID]
            call SetLightningColor(Laser[NewTimerID], LaserRED[NewTimerID], LaserBLUE[NewTimerID], LaserGREEN[NewTimerID], LaserALPHA[NewTimerID])
            if LaserALPHA[NewTimerID] <= 0. then
                if LIBRARY_MissileRecycler then
                    call RecycleMissile(LaserDummyLaunch[NewTimerID])
                    call RecycleMissile(LaserDummyImpact[NewTimerID])
                    call RecycleMissile(LaserDummyArea[NewTimerID])
                else
                    call RemoveUnit(LaserDummyLaunch[NewTimerID])
                    call RemoveUnit(LaserDummyImpact[NewTimerID])
                    call RemoveUnit(LaserDummyArea[NewTimerID])
                endif
                set LaserDummyLaunch[NewTimerID] = null
                set LaserDummyImpact[NewTimerID] = null
                set LaserDummyArea[NewTimerID]   = null
                call DestroyLightning(Laser[NewTimerID])
                set Laser[NewTimerID] = null
                call IndexDeallocate(NewTimerID)
                call ReleaseTimer(t)
            endif
        else
            call BJDebugMsg("duration")
            set LaserInterval[NewTimerID] = LaserInterval[NewTimerID] - 1
            if LaserInterval[NewTimerID] <= 0 then
                set IsLaserFading[NewTimerID] = true
            endif
        endif
    endfunction
 
 
 
    function BurstLaser_Timer takes nothing returns nothing
        local timer t       = GetExpiredTimer()
        local integer tID   = GetTimerData(t)
        local timer New_t   = null
        local integer NewTimerID = 0
     
        local player SourcePlayer = GetOwningPlayer(LaserSource[tID])
        local boolean b = false
     
        local real SOURCE_X = GetUnitX(LaserSource[tID])
        local real SOURCE_Y = GetUnitY(LaserSource[tID])
        local real TARGET_X = GetUnitX(LaserTarget[tID])
        local real TARGET_Y = GetUnitY(LaserTarget[tID])
        local real Angle = Atan2(SOURCE_Y - TARGET_Y, SOURCE_X - TARGET_X) + LaserLaunchAngle[tID]
     
        local unit u = null
        local real TargetColl = GetUnitCollision(LaserTarget[tID])
     
        local real LAUNCH_X = SOURCE_X + Cos(Angle) * LaserLaunchOffset[tID]
        local real LAUNCH_Y = SOURCE_Y + Sin(Angle) * LaserLaunchOffset[tID]
        local real LAUNCH_Z = GetUnitZ(LaserSource[tID]) + LaserLaunchHeight[tID]
        local real IMPACT_X = (TARGET_X + Cos(Angle + 3.14159) * (TargetColl * .8)) + GetRandomReal(LaserSpreadXY[tID] * -1, LaserSpreadXY[tID])
        local real IMPACT_Y = (TARGET_Y + Sin(Angle + 3.14159) * (TargetColl * .8)) + GetRandomReal(LaserSpreadXY[tID] * -1, LaserSpreadXY[tID])
        local real IMPACT_Z = GetUnitZ(LaserTarget[tID]) + GetRandomReal(LaserSpreadZ[tID] * -1, LaserSpreadZ[tID])
     
        set LaserInterval[tID] = LaserInterval[tID] - 1
        if LaserInterval[tID] <= 0 then
            set LaserCount[tID] = LaserCount[tID] - 1
            set LaserInterval[tID] = LaserIntervalSave[tID]
            set NewTimerID = IndexAllocate()
         
            //Launch
            if LaserLaunchFX[tID] != null then
                set b = true
                if LIBRARY_MissileRecycler then
                    set LaserDummyLaunch[NewTimerID] = GetRecycledMissile(LAUNCH_X, LAUNCH_Y, LAUNCH_Z, Angle)
                else
                    set LaserDummyLaunch[NewTimerID] = CreateUnit(Player(14), LaserDummyType[tID], LAUNCH_X, LAUNCH_Y, Angle)
                    call SetUnitFlyHeight(LaserDummyLaunch[NewTimerID], IMPACT_Z, 0.)
                endif
                call SetUnitScale(LaserDummyLaunch[NewTimerID], LaserLaunchScale[NewTimerID], 0., 0.)
                call DestroyEffect(AddSpecialEffectTarget(LaserLaunchFX[tID], LaserDummyLaunch[NewTimerID], "origin"))
            endif
            //Impact
            if LaserImpactFX[tID] != null then
                set b = true
                /*if IsLaserGrounded[tID] then
                    set IMPACT_Z = 0.
                endif
                if LIBRARY_MissileRecycler then
                    set LaserDummyImpact[NewTimerID] = GetRecycledMissile(IMPACT_X, IMPACT_Y, IMPACT_Z, Angle)
                else*/
                    set LaserDummyImpact[NewTimerID] = CreateUnit(Player(14), LaserDummyType[tID], IMPACT_X, IMPACT_Y, Angle)
                    call SetUnitFlyHeight(LaserDummyImpact[NewTimerID], IMPACT_Z, 0.)
                //endif
                call SetUnitScale(LaserDummyImpact[NewTimerID], LaserImpactScale[NewTimerID], 0., 0.)
                call DestroyEffect(AddSpecialEffectTarget(LaserImpactFX[tID], LaserDummyImpact[NewTimerID], "origin"))
            endif
            //Area
            if LaserAreaFX[tID] != null then
                set b = true
                if LIBRARY_MissileRecycler then
                    set LaserDummyArea[NewTimerID] = GetRecycledMissile(IMPACT_X, IMPACT_Y, IMPACT_Z, Angle)
                else
                    set LaserDummyArea[NewTimerID] = CreateUnit(Player(14), LaserDummyType[tID], IMPACT_X, IMPACT_Y, Angle)
                    call SetUnitFlyHeight(LaserDummyArea[NewTimerID], IMPACT_Z, 0.)
                endif
                call SetUnitScale(LaserDummyArea[NewTimerID], LaserAreaScale[NewTimerID], 0., 0.)
                call DestroyEffect(AddSpecialEffectTarget(LaserAreaFX[tID], LaserDummyArea[NewTimerID], "origin"))
            endif
            //Laser
            if LaserString[tID] != null then
                set b = true
                set LaserRED[NewTimerID]    = LaserRED[tID]
                set LaserBLUE[NewTimerID]   = LaserBLUE[tID]
                set LaserGREEN[NewTimerID]  = LaserGREEN[tID]
                set LaserALPHA[NewTimerID]  = LaserALPHA[tID]
                set Laser[NewTimerID] = AddLightningEx(LaserString[tID], true, LAUNCH_X, LAUNCH_Y, LAUNCH_Z, IMPACT_X, IMPACT_Y, IMPACT_Z)
                call SetLightningColor(Laser[NewTimerID], LaserRED[NewTimerID], LaserBLUE[NewTimerID], LaserGREEN[NewTimerID], LaserALPHA[NewTimerID])
                set FadeAmount[NewTimerID] = LaserALPHA[NewTimerID] / FadeAmount[tID]
            endif
            //Damage
            if LaserAOE[tID] > 0. then
                call GroupEnumUnitsInRange(DamageGroup, IMPACT_X, IMPACT_Y, LaserAOE[tID] + MAX_COLLISION_SIZE, null)
                loop
                    set u = FirstOfGroup(DamageGroup)
                    call GroupRemoveUnit(DamageGroup, u)
                    exitwhen u == null
                    if IsUnitInRangeXY(u, IMPACT_X, IMPACT_Y, LaserAOE[tID]) and UnitAlive(u) and /*
                    [Friendly Fire] */( (LaserFriendlyFire[tID] and (IsUnitEnemy(u, SourcePlayer) or IsUnitAlly(u, SourcePlayer))) or /*
                    [Enemy]         */  (not LaserFriendlyFire[tID] and IsUnitEnemy(u, SourcePlayer)) ) and /*
                    [Invulnerable]  */   not IsUnitInvulnerable(u) and /*
                    [Magic Immune]  */( (LaserAttackType[tID] == ATTACK_TYPE_MAGIC and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)) or /*
                    [Ethereal]      */  (LaserAttackType[tID] != ATTACK_TYPE_MAGIC and not IsUnitType(u, UNIT_TYPE_ETHEREAL)) ) then
                        if not LaserHitAll[tID] and ( (not IsUnitType(u, UNIT_TYPE_FLYING) and not IsUnitType(LaserTarget[tID], UNIT_TYPE_FLYING)) or /*
                        */ (IsUnitType(u, UNIT_TYPE_FLYING) and IsUnitType(LaserTarget[tID], UNIT_TYPE_FLYING)) ) then
                            set udg_NextDamageType = LaserDamageType[tID]
                            call UnitDamageTarget(LaserSource[tID], u, LaserDamage[tID], true, true, LaserAttackType[tID], DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
                            call TriggerEvaluate(udg_ClearDamageEvent)
                        elseif LaserHitAll[tID] then
                            set udg_NextDamageType = LaserDamageType[tID]
                            call UnitDamageTarget(LaserSource[tID], u, LaserDamage[tID], true, true, LaserAttackType[tID], DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
                            call TriggerEvaluate(udg_ClearDamageEvent)
                        endif
                    endif
                endloop
            else
                set udg_NextDamageType = LaserDamageType[tID]
                call UnitDamageTarget(LaserSource[tID], LaserTarget[tID], LaserDamage[tID], true, true, LaserAttackType[tID], DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
                call TriggerEvaluate(udg_ClearDamageEvent)
            endif
            //Timer
            if b then
                set b = false
                set LaserInterval[NewTimerID] = LaserInterval[tID]
                set IsLaserFading[NewTimerID] = false
                set New_t = NewTimerEx(NewTimerID)
                call TimerStart(New_t, .03125, true, function IndividualLaser_Timer)
                set New_t = null
            else
                call IndexDeallocate(NewTimerID)
            endif
         
        endif
        if LaserCount[tID] <= 0 then
            call IndexDeallocate(tID)
            call ReleaseTimer(t)
        endif
    endfunction
 
 
 
    function BurstLaser takes nothing returns boolean
        local unit Source = udg_DamageEventSource
        local unit Target = udg_DamageEventTarget
        local integer Source_ID = GetUnitUserData(Source)
     
        local timer t = null
        local integer tID = 0
     
        local real SOURCE_X = 0.
        local real SOURCE_Y = 0.
        local real TARGET_X = 0.
        local real TARGET_Y = 0.
        local real LAUNCH_X = 0.
        local real LAUNCH_Y = 0.
        local real IMPACT_X = 0.
        local real IMPACT_Y = 0.
        local real Angle = 0.
     
        local real Damage = 0.
     
        if BL_UsesBurstLaser[Source_ID] and udg_DamageEventType == 0 and not udg_IsDamageSpell then
            set udg_DamageEventAmount = 0.
            set Damage = GetFullDamage(udg_DamageEventPrevAmt, GetUnitArmor(udg_DamageEventTarget)) / BL_NumberOfLasers[Source_ID]
         
            if BL_NumberOfLasers[Source_ID] > 0 then
                set tID = IndexAllocate()
                set t = NewTimerEx(tID)
             
                set LaserSource[tID]        = udg_DamageEventSource
                set LaserTarget[tID]        = udg_DamageEventTarget
                set LaserDamage[tID]        = Damage
                set LaserAOE[tID]           = BL_LaserAOE[Source_ID]
                set LaserAttackType[tID]    = BL_LaserAttackType[Source_ID]
                set LaserDamageType[tID]    = BL_LaserDamageType[Source_ID]
                set LaserHitAll[tID]        = BL_LaserHitAll[Source_ID]
                set LaserFriendlyFire[tID]  = BL_LaserFriendlyFire[Source_ID]
             
                set LaserInterval[tID]      = BL_LaserDuration[Source_ID]
                set LaserIntervalSave[tID]  = BL_LaserDuration[Source_ID]
                set LaserCount[tID]         = BL_NumberOfLasers[Source_ID]
             
                set LaserLaunchOffset[tID]  = BL_LaserLaunchOffset[Source_ID]
                set LaserLaunchHeight[tID]  = BL_LaserLaunchHeight[Source_ID]
                set LaserLaunchAngle[tID]   = BL_LaserLaunchAngle[Source_ID]
                set LaserSpreadXY[tID]      = BL_LaserSpreadXY[Source_ID]
                set LaserSpreadZ[tID]       = BL_LaserSpreadZ[Source_ID]
             
                set LaserLaunchFX[tID]      = BL_LaserLaunchFX[Source_ID]
                set LaserImpactFX[tID]      = BL_LaserImpactFX[Source_ID]
                set LaserAreaFX[tID]        = BL_LaserAreaFX[Source_ID]
                set LaserLaunchScale[tID]   = BL_LaserLaunchScale[Source_ID]
                set LaserImpactScale[tID]   = BL_LaserImpactScale[Source_ID]
                set LaserAreaScale[tID]     = BL_LaserAreaScale[Source_ID]
             
                set LaserString[tID]        = BL_LaserString[Source_ID]
                set LaserRED[tID]           = BL_RED[Source_ID]
                set LaserBLUE[tID]          = BL_BLUE[Source_ID]
                set LaserGREEN[tID]         = BL_GREEN[Source_ID]
                set LaserALPHA[tID]         = BL_ALPHA[Source_ID]
                set IsLaserFading[tID]      = false
             
                call TimerStart(t, .03125, true, function BurstLaser_Timer)
                set t = null
            endif
         
        endif
        set Source = null
        set Target = null
        return false
    endfunction
 
 
    function BL_onAttack takes nothing returns nothing
        call TriggerRegisterVariableEvent( BL_onAttack_Trigger, "udg_DamageModifierEvent", EQUAL, 1.00 )
        call TriggerAddCondition( BL_onAttack_Trigger, function BurstLaser )
    endfunction
 
endscope
 
Level 39
Joined
Feb 27, 2007
Messages
5,024
You're sure call TimerStart(New_t, .03125, true, function IndividualLaser_Timer) is happening properly (DebugMsg after it)? So the timer is getting paused before it can timeout once? Alternative idea: set the timeout to 0.00 and see if you get messages then (less time to interrupt the timer).
 
Okay, that's bizarre. I tried calling BJDebugMsg("TimerTest") at various points within the first timer and it looks like after this line: set FadeAmount[NewTimerID] = LaserALPHA[NewTimerID] / FadeAmount[tID] nothing else runs. It's in the if LaserString[tID] != null then part of BurstLaser_Timer.

EDIT: Oh, the FadeAmount[tID] is null, that's why... shouldn't that just return a 0 then?
 
Status
Not open for further replies.
Top