HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

PROBLEM WITh scRIPT

08-10-2008, 01:11 PM#1
fX_
Script is SUPPOSED to fade-in units then play an animation then issue an order OR fade-in units while playing an animation then issue an order. It fades-in only the first unit to be "spawned". All subsequent units to be "spawned" don't fade-in. What's wrong?

edit: after some further testing, fade-in is disabled after the first instance of spawning completes. subsequent spawns spawned before the first spawning completes get faded-in; spawns that get spawned after the first spawning takes places do not fade-in.

Collapse JASS:
library SpawnUnit
globals
    private constant real gR_DurationTimer = 0.10
    private integer gINT_CountStructMin = 0
    private integer gINT_CountStructMax = 0
    private timer gTIMER = CreateTimer()
    private integer array gINT_StructSpawn
endglobals

private struct structSpawn
    boolean boolOnSpawn
    unit uSpawn
    boolean boolActive
    integer intIntervalSpawn
    integer intIntervalSpawnCount
    integer intRedIncrement
    integer intGreenIncrement
    integer intBlueIncrement
    integer intAlphaIncrement
    boolean boolOnAnim
    real rAnimSpeed
    string strAnim
    integer intAnim
    sound sndStart
    real rDurationAnim
    sound sndEnd
    string strOrder
    real rLocXTarget
    real rLocYTarget
    unit uTarget
    
    static method Create takes unit unitSpawn,boolean activeSpawn,real durationSpawn,integer redMax,integer greenMax,integer blueMax,integer alphaMax,real speedAnim,sound startSound,string stringAnim,integer integerAnim,real durationAnim,sound endSound,string order,real locXTarget,real locYTarget,unit unitTarget returns structSpawn
        local structSpawn Data = structSpawn.allocate()
        set Data.boolOnSpawn = TRUE
        set Data.uSpawn = unitSpawn
        set Data.boolActive = activeSpawn
        set Data.intIntervalSpawn = R2I(durationSpawn / gR_DurationTimer)
        set Data.intRedIncrement = redMax / Data.intIntervalSpawn
        set Data.intGreenIncrement = greenMax / Data.intIntervalSpawn
        set Data.intBlueIncrement = blueMax / Data.intIntervalSpawn
        set Data.intAlphaIncrement = alphaMax / Data.intIntervalSpawn
        set Data.rAnimSpeed = speedAnim
        set Data.strAnim = stringAnim
        set Data.intAnim = integerAnim
        set Data.sndStart = startSound
        set Data.rDurationAnim = durationAnim
        set Data.sndEnd = endSound
        set Data.strOrder = order
        set Data.rLocXTarget = locXTarget
        set Data.rLocYTarget = locYTarget
        set Data.uTarget = unitTarget
        return Data
    endmethod
    
    method onDestroy takes nothing returns nothing
        set this.uSpawn = null
        set this.strAnim = null
        set this.sndStart = null
        set this.sndEnd = null
        set this.strOrder = null
        set this.uTarget = null
    endmethod
endstruct

function Spawn takes nothing returns nothing
    local structSpawn StructSpawn = 0
    local integer INT_CountStructMin = gINT_CountStructMin
    call BJDebugMsg(I2S(gINT_CountStructMin))
    call BJDebugMsg(I2S(gINT_CountStructMax))
    loop
        exitwhen INT_CountStructMin > gINT_CountStructMax
        set StructSpawn = gINT_StructSpawn[INT_CountStructMin]
        //SPAWN ACTIONS//
        if StructSpawn.boolOnSpawn == TRUE then
            if StructSpawn.intIntervalSpawnCount <= StructSpawn.intIntervalSpawn then
                call SetUnitVertexColor(StructSpawn.uSpawn,(StructSpawn.intRedIncrement * StructSpawn.intIntervalSpawnCount),(StructSpawn.intGreenIncrement * StructSpawn.intIntervalSpawnCount),(StructSpawn.intBlueIncrement * StructSpawn.intIntervalSpawnCount),(StructSpawn.intAlphaIncrement * StructSpawn.intIntervalSpawnCount))
                set StructSpawn.intIntervalSpawnCount = StructSpawn.intIntervalSpawnCount + 1
            else
                //DEACTIVATE SPAWN ACTIONS//
                //ACTIVATE ANIMATION ACTIONS IF boolActive == FALSE//
                set StructSpawn.boolOnSpawn = FALSE
                if StructSpawn.boolActive == FALSE then
                    set StructSpawn.boolOnAnim = TRUE
                    if StructSpawn.strAnim != null then
                        call SetUnitAnimation(StructSpawn.uSpawn,StructSpawn.strAnim)
                    else
                        call SetUnitAnimationByIndex(StructSpawn.uSpawn,StructSpawn.intAnim)
                    endif
                    if StructSpawn.sndStart != null then
                        call AttachSoundToUnit(StructSpawn.sndStart,StructSpawn.uSpawn)
                        call SetSoundVolume(StructSpawn.sndStart,127)
                        call StartSound(StructSpawn.sndStart)
                    endif
                endif
            endif
        endif
        //ANIMATION ACTIONS//
        if StructSpawn.boolOnAnim == TRUE then
            if StructSpawn.rDurationAnim > 0 then
                set StructSpawn.rDurationAnim = StructSpawn.rDurationAnim - gR_DurationTimer
            else
                //DEACTIVATE ANIMATION ACTIONS//
                //EXECUTE ORDER ACTIONS//
                set StructSpawn.boolOnAnim = FALSE
                call SetUnitTimeScale(StructSpawn.uSpawn,1.00)
                call SetUnitAnimation(StructSpawn.uSpawn,"stand")
                if StructSpawn.sndEnd != null then
                    call AttachSoundToUnit(StructSpawn.sndEnd,StructSpawn.uSpawn)
                    call SetSoundVolume(StructSpawn.sndEnd,127)
                    call StartSound(StructSpawn.sndEnd)
                endif
                call PauseUnit(StructSpawn.uSpawn,FALSE)
                if StructSpawn.uTarget != null then
                    call IssueTargetOrder(StructSpawn.uSpawn,StructSpawn.strOrder,StructSpawn.uTarget)
                elseif StructSpawn.rLocXTarget != 0.00 then
                    call IssuePointOrder(StructSpawn.uSpawn,StructSpawn.strOrder,StructSpawn.rLocXTarget,StructSpawn.rLocYTarget)
                elseif StructSpawn.strOrder != null then
                    call IssueImmediateOrder(StructSpawn.uSpawn,StructSpawn.strOrder)
                endif
                call StructSpawn.destroy()
            endif
        endif
        set INT_CountStructMin = INT_CountStructMin + 1
    endloop
endfunction

function SpawnUnit takes unit unitSpawn,boolean activeSpawn,real durationSpawn,integer redMax,integer greenMax,integer blueMax,integer alphaMax,real speedAnim,sound startSound,string stringAnim,integer integerAnim,real durationAnim,sound endSound,string order,real locXTarget,real locYTarget,unit unitTarget returns nothing
    local structSpawn Data = structSpawn.Create(unitSpawn,activeSpawn,durationSpawn,redMax,greenMax,blueMax,alphaMax,speedAnim,startSound,stringAnim,integerAnim,durationAnim,endSound,order,locXTarget,locYTarget,unitTarget)
    call SetUnitVertexColor(unitSpawn,0,0,0,0)
    if activeSpawn == TRUE then
        set Data.boolOnAnim = TRUE
        if Data.sndStart != null then
            call AttachSoundToUnit(Data.sndStart,Data.uSpawn)
            call SetSoundVolume(Data.sndStart,127)
            call StartSound(Data.sndStart)
        endif
    else
        set Data.boolOnAnim = FALSE
        call PauseUnit(unitSpawn,TRUE)
    endif
    if gINT_CountStructMax == 0 then
        call TimerStart(gTIMER,gR_DurationTimer,TRUE,function Spawn)
    endif
    set gINT_StructSpawn[gINT_CountStructMax] = Data
    set gINT_CountStructMax = gINT_CountStructMax + 1
endfunction
endlibrary
08-10-2008, 02:52 PM#2
DioD
First of all check for OPlimit.

You cannot run heavy code in "loop for every active struct" manner.

Also you do not clean your array
gINT_StructSpawn after StructSpawn.destroy()

soo it stored handles to null structs and loop will go to this structs.
08-10-2008, 03:19 PM#3
fX_
I don't understand a thing you said. Could you elaborate?
08-10-2008, 03:26 PM#4
Anitarf
Translation: Your code is a mess, you should rethink your organisation.
08-11-2008, 03:25 AM#5
fX_
How is it messy?

edit: should i make methods out of some parts of it?

edit2: i made methods out of some parts. is it better now? is it still lacking in "order"?

Collapse JASS:
library SpawnUnit
globals
    private constant gR_DurationTimer = 0.10
    private integer gINT_CountStructMin = 0
    private integer gINT_CountStructMax = 0
    private Data array gData
endglobals

private struct Data
    timer T
    boolean boolActiveSpawn
    boolean boolSpawnOn
    boolean boolAnimationOn
    unit uSpawn
    integer intCountSpawnInterval
    integer intCounterSpawnInterval
    integer intRedIncrement
    integer intGreenIncrement
    integer intBlueIncrement
    integer intAlphaIncrement
    string strAnimation
    integer intAnimation
    real rAnimationSpeed
    integer intCountAnimationInterval
    integer intCounterAnimationInterval
    sound sndStart
    sound sndEnd
    string strOrder
    real rLocXTarget
    real rLocYTarget
    unit uTarget

    static method Create takes boolean boolActive, unit unitSpawn, real durationSpawn, integer redMax, integer greenMax, integer blueMax, integer alphaMax, string stringAnimation, integer integerAnimation, real animationSpeed, real durationAnimation, sound startSound, sound endSound, string order, real locXTarget, real locYTarget, unit unitTarget returns Data
        local Data Data = Data.allocate()
        set Data.boolActiveSpawn = boolActive
        set Data.boolSpawnOn = TRUE
        if Data.boolActiveSpawn = TRUE then
            set Data.boolAnimationOn = TRUE
        else
            set Data.boolAnimationOn = FALSE
        endif
        set Data.uSpawn = unitSpawn
        set Data.intCountSpawnInterval = R2I(durationSpawn / gR_DurationTimer)
        set Data.intCounterSpawnInterval = 0
        set Data.intRedIncrement = redMax / intCountSpawnInterval
        set Data.intGreenIncrement = greenMax / intCountSpawnInterval
        set Data.intBlueIncrement = blueMax / intCountSpawnInterval
        set Data.intAlphaIncrement = alphaMax / intCountSpawnInterval
        set Data.strAnimation = stringAnimation
        set Data.intAnimation = integerAnimation
        set Data.rAnimationSpeed = animationSpeed
        set Data.intCountAnimationInterval = I2R(durationAnimation / gR_DurationTimer)
        set Data.intCounterAnimationInterval = 0
        set Data.sndStart = startSound
        set Data.sndEnd = endSound
        set Data.strOrder = order
        set Data.rLocXTarget = locXTarget
        set Data.rLocYTarget = locYTarget
        set Data.uTarget = unitTarget
        return Data
    endmethod
    
    static method Spawn takes nothing returns nothing
        local integer INT_Red = this.intRedIncrement * this.intCounterSpawnInterval
        local integer INT_Green = this.intGreenIncrement * this.intCounterSpawnInterval
        local integer INT_Blue = this.intBlueIncrement * this.intCounterSpawnInterval
        local integer INT_Alpha = this.intAlphaIncrement * this.intCounterSpawnInterval
        call SetUnitVertexColor(this.uSpawn, INT_Red, INT_Green, INT_Blue, INT_Alpha)
        set this.intCounterSpawnInterval = this.intCounterSpawnInterval + 1
        if this.intCounterSpawnInterval == this.intCountSpawnInterval then
            if this.boolActiveSpawn == FALSE then
                set this.boolAnimationOn = TRUE
            set this.boolSpawnOn == FALSE
        endif
    endmethod
    
    static method Animation takes nothing returns nothing
        local sound SND_FX
        if this.intCounterAnimationInterval == 0 then
            call SetUnitTimeScale(this.uSpawn, this.rAnimationSpeed)
            if this.strAnimation != null then
                call SetUnitAnimation(this.uSpawn, this.strAnimation)
            else
                call SetUnitAnimationByIndex(this.uSpawn, this.intAnimation)
            endif
            set SND_FX = this.sndStart
            call AttachSoundToUnit(SND_FX, this.uSpawn)
            call SetSoundVolume(SND_FX, 127)
            call StartSound(SND_FX)
        endif
        set this.intCounterAnimationInterval = this.intCounterAnimationInterval + 1
        if this.intCounterAnimationInterval == this.intCountAnimationInterval then
            call SetUnitTimeScale(this.uSpawn, 1.00)
            call SetUnitAnimation(this.uSpawn, "stand")
            set SND_FX = this.sndStart
            call AttachSoundToUnit(SND_FX, this.uSpawn)
            call SetSoundVolume(SND_FX, 127)
            call StartSound(SND_FX)
            call PauseUnit(this.uSpawn, FALSE)
            set this.boolAnimationOn == FALSE
        endif
        set SND_FX = null
    endmethod
    
    static method Destroy takes nothing returns nothing
        local integer INT_CountInstance = gINT_CountStructMin
        local integer INT_CountInstance = gINT_CountStructMin
        loop
            exitwhen INT_CountInstance == gINT_CountStructMax
            if gData[INT_CountInstance] == this. then
                set this.uSpawn = null
                        set Data.uSpawn = unitSpawn
                        set Data.strAnimation = null
                        set Data.sndStart = null
                        set Data.sndEnd = null
                        set Data.strOrder = null
                        set Data.uTarget = null
                if gINT_CountStructMax == 1 then
                    set gINT_CountStructMin = 1
                else
                    set gINT_CountStructMin = gINT_CountStructMin + 1
                endif
            endif
        endloop
    endmethod
endstruct

function Callback_gTIMER takes nothing returns nothing
    local timer TIMER = GetExpiredTimer()
    local Data Data = 0
    local integer INT_CountInstance = gINT_CountStructMin
    loop
        exitwhen INT_CountInstance == gINT_CountStructMax
        //IDENTITY CHECK//
        set Data = gData[INT_CountInstance]
        if Data.timerT = TIMER then
            //ACTIONS//
            call Data.Spawn()
            call Data.Animation
            if Data.boolSpawnOn == FALSE And Data.boolAnimationOn == FALSE then
                call Data.Destroy
                call PauseTimer(TIMER)
                call DestroyTimer(TIMER)
            endif
        endif
    endloop
endfunction

function SpawnUnit takes boolean boolActive, unit unitSpawn, real durationSpawn, integer redMax, integer greenMax, integer blueMax, integer alphaMax, string stringAnimation, integer integerAnimation, real animationSpeed, real durationAnimation, sound startSound, sound endSound, string order, real locXTarget, real locYTarget, unit unitTarget returns nothing
    local Data Data = Data.Create(boolActive, unitSpawn, durationSpawn, redMax, greenMax, blueMax, alphaMax, stringAnimation, integerAnimation, animationSpeed, durationAnimation, startSound, endSound, order, locXTarget, locYTarget, unitTarget)
    if gINT_CountStructMax < 8190 then
        set gINT_CountStructMax = gINT_CountStructMax + 1
    else
        set gINT_CountStructMax = 1
    endif
    set gData[gINT_CountStructMax] = Data
    if Data.boolActiveSpawn == FALSE then
        call PauseUnit(Data.uSpawn,TRUE)
        set Data.boolAnimationOn == TRUE
    endif
    set Data.timerT = CreateTimer()
    call TimerStart(Data.timerT, gR_DurationTimer, TRUE, function Callback_gTIMER)
endfunction
endlibrary
08-11-2008, 03:52 AM#6
TheDefiled
Meaning that you should consider recreating the code, as it's currently very unorganized, and makes it difficult to understand what's happening.