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

[JASS] Crit Error

Status
Not open for further replies.
Level 9
Joined
Nov 25, 2008
Messages
194
Well I always get a critical error when testing my map.

Here is the code of the spell:
JASS:
scope FieryRage initializer init

    globals
        private constant integer SpellID        = 'A000'
        private constant integer DummyID        = 'h000'
        private constant integer CrowFormID     = 'Amrf'
        private constant string  Dummy1attach1  = "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl"
        private constant string  Dummy1attach2  = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl"
        private constant string  Dummy2attach1  = ""
        private constant string  Dummy2attach2  = ""
        private constant string  Dummy3attach   = ""
        private constant string  SFX1           = "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl"
        private constant string  SFX2           = ""
        private constant string  SFX3           = ""
        private constant real    SFX1size       = 1.5
        private constant real    TimerInt       = .03
        private constant boolean Attack         = false
        private constant boolean Ranged         = false
        private constant attacktype AttackType  = ATTACK_TYPE_NORMAL
        private constant damagetype DamageType  = DAMAGE_TYPE_NORMAL
        private constant weapontype WeaponType  = WEAPON_TYPE_WHOKNOWS
    endglobals
    
    private function Dummys1 takes integer lev returns integer
        return 5
    endfunction
    
    private function Dummys2 takes integer lev returns integer
        return 10
    endfunction
    
    private function Dummys3 takes integer lev returns integer
        return Dummys2(0)*3
    endfunction
    
    private function Damage1 takes real dist, integer lev returns real
        return lev*100.
    endfunction
    
    private function Damage2 takes real dist, integer lev returns real
        return lev*25.
    endfunction
    
    private function DamagePerSec takes real dist, integer lev returns real
        return lev*10.*TimerInt
    endfunction
    
    private function AoE1 takes real dist, integer lev returns real
        return dist/2.
    endfunction
    
    private function AoE2 takes real dist, integer lev returns real
        return dist/4.
    endfunction
    
    private function Dummy2maxHeight takes real dist, integer lev returns real
        return AoE2(dist, 0)
    endfunction
    
    private function Dummy3maxHeight takes real dist, integer lev returns real
        return GetRandomReal(.0, 300.)
    endfunction
    
    private function DamagePerSecAoe takes real dist, integer lev returns real
        return 220.
    endfunction
    
    //Ignore the following 3 lines.
    globals
        private player p
    endglobals
    //Setup continues
    
    private function UnitFilter takes nothing returns boolean
        local unit u = GetFilterUnit()
        return IsUnitEnemy(u, p) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and not IsUnitType(u, UNIT_TYPE_MECHANICAL) and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) and GetWidgetLife(u)>.405
    endfunction
    
    //End of Setup
    
    
    private struct data
        unit cast
        unit array dum [8190]
        real dist
        real angle
        real aoe1
        real aoe2
        real aoe3
        real dmg1
        real dmg2
        real dmg3
        real cx
        real cy
        real tx
        real ty
        real ang
        real  array dumang [8191]
        real formula
        real maxheight2
        real array maxheight3 [8191]
        real array anglemod [8191]
        integer step
        integer dummys1
        integer dummys2
        integer dummys3
        effect e0
        effect array e1 [8191]
        effect array e2 [8191]
    endstruct
    
    globals
        private data array ar
        private timer tim = CreateTimer()
        private integer total
        private boolexpr b
        private group g = CreateGroup()
    endglobals
        
    private function condition takes nothing returns boolean
        return GetSpellAbilityId()==SpellID
    endfunction

    private function periodic takes nothing returns nothing
        local data d
        local integer i = 0
        local integer ii = 0
        local real x = .0
        local real y = .0
        local real dist = .0
        local unit u
        loop
            exitwhen i >= total
            set d = ar[i]
            if d.step == 0 then
                loop
                    exitwhen ii >= d.dummys1
                    set ii = ii + 1
                    set d.dum[ii] = CreateUnit(Player(16), DummyID, d.cx, d.cy, d.ang)
                    set d.anglemod[ii] = d.dummys1/2-ii
                    call PauseUnit(d.dum[ii], true)
                    set d.e1[ii] = AddSpecialEffectTarget(Dummy1attach1 , d.dum[ii], "chest")
                    set d.e2[ii] = AddSpecialEffectTarget(Dummy1attach2 , d.dum[ii], "origin")
                    call UnitAddAbility(d.dum[ii], CrowFormID)
                endloop
                set d.formula = bj_PI/2.
                set ii = 0
                set d.step = 1
            endif
                
            if d.step == 1 then
                set d.formula = d.formula + bj_PI/80.
                loop
                    exitwhen ii >= d.dummys1
                    set ii = ii + 1
                    set x = GetUnitX(d.dum[ii])
                    set y = GetUnitY(d.dum[ii])
                    set dist = SquareRoot(Pow((d.tx-x), 2.)+Pow((d.ty-y), 2.))
                    call SetUnitX(d.dum[ii], x+d.aoe1/40.*Cos(d.angle+(3.-d.anglemod[ii]*Sin(d.formula)*bj_PI/2.)))
                    call SetUnitY(d.dum[ii], y+d.aoe1/40.*Sin(d.angle+(3.-d.anglemod[ii]*Sin(d.formula)*bj_PI/2.)))
                    set x = GetUnitX(d.dum[ii])
                    set y = GetUnitY(d.dum[ii])
                    call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                    set u = FirstOfGroup(g)
                    loop
                        exitwhen u == null
                        call UnitDamageTarget(d.cast, u, d.dmg3, Attack, Ranged, AttackType, DamageType, WeaponType)
                        if GetRandomInt(1, 10) == 10 then
                            call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(u), GetUnitY(u)))
                        endif
                        call GroupRemoveUnit(g, u)
                        set u = FirstOfGroup(g)
                    endloop
                    set ii = 0
                    if d.formula == bj_PI then
                        set d.step = 2
                    endif
                endloop
            endif
                
            if d.step == 2 then
                call GroupEnumUnitsInRange(g, d.tx, d.ty, d.aoe1, b)
                loop
                    exitwhen u == null
                    call UnitDamageTarget(d.cast, u, d.dmg1, Attack, Ranged, AttackType, DamageType, WeaponType)
                    call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(u), GetUnitY(u)))
                    call GroupRemoveUnit(g, u)
                    set u = FirstOfGroup(g)
                endloop
                set u = CreateUnit(Player(16), DummyID, d.tx, d.ty, .0)
                call SetUnitScale(u, SFX1size, SFX1size, SFX1size)
                set d.e0 = AddSpecialEffectTarget(SFX1, u, "chest")
                call UnitApplyTimedLife(u, 'BTLF', 1.)
                call PauseUnit(u, true)
                loop
                    exitwhen ii >= d.dummys1
                    call DestroyEffect(d.e1[ii])
                    call DestroyEffect(d.e2[ii])
                    call RemoveUnit(d.dum[ii])
                endloop
                set ii = 0
                loop
                    exitwhen ii >= d.dummys2
                    set ii = ii + 1
                    set d.dum[ii] = CreateUnit(Player(16), DummyID, d.cx, d.cy, d.ang)
                    set d.anglemod[ii] = d.dummys1/2-ii
                    call PauseUnit(d.dum[ii], true)
                    set d.e1[ii] = AddSpecialEffectTarget(Dummy2attach1 , d.dum[ii], "chest")
                    set d.e2[ii] = AddSpecialEffectTarget(Dummy2attach2 , d.dum[ii], "origin")
                    call UnitAddAbility(d.dum[ii], CrowFormID)
                    set d.dumang[ii] = bj_PI*2./d.dummys2*ii
                endloop
                set ii = 0
                set d.step = 3
                set d.formula = 0.
            endif
                
            if d.step == 3 then
                set d.formula = d.formula + bj_PI/20.
                loop
                    exitwhen ii >= d.dummys2
                    set ii = ii + 1
                    set x = GetUnitX(d.dum[ii])
                    set y = GetUnitY(d.dum[ii])
                    call SetUnitX(d.dum[ii], x+d.aoe2/20.*Cos(ii*bj_PI*2./d.dummys2))
                    call SetUnitY(d.dum[ii], y+d.aoe2/20.*Sin(ii*bj_PI*2./d.dummys2))
                    call SetUnitFlyHeight(d.dum[ii], d.maxheight2*Sin(d.formula), 0.)
                    set x = GetUnitX(d.dum[ii])
                    set y = GetUnitY(d.dum[ii])
                    call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                    set u = FirstOfGroup(g)
                    loop
                        exitwhen u == null
                        call UnitDamageTarget(d.cast, u, d.dmg3, Attack, Ranged, AttackType, DamageType, WeaponType)
                        if GetRandomInt(1, 10) == 10 then
                            call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(u), GetUnitY(u)))
                        endif
                        call GroupRemoveUnit(g, u)
                        set u = FirstOfGroup(g)
                    endloop
                    set ii = 0
                endloop
                if d.formula == bj_PI then
                    set d.step = 4
                endif
            endif
                
            if d.step == 4 then
                call DestroyEffect(d.e0)
                loop
                    exitwhen ii == d.dummys2
                    set ii = ii + 1
                    set x = GetUnitX(d.dum[ii])
                    set y = GetUnitY(d.dum[ii])
                    call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                    set u = FirstOfGroup(g)
                    loop
                        exitwhen u == null
                        call UnitDamageTarget(d.cast, u, d.dmg2, Attack, Ranged, AttackType, DamageType, WeaponType)
                        call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(u), GetUnitY(u)))
                        call GroupRemoveUnit(g, u)
                        set u = FirstOfGroup(g)
                    endloop
                    call DestroyEffect(AddSpecialEffect(SFX2, x, y))
                    call DestroyEffect(AddSpecialEffect(SFX2, x, y))
                    call DestroyEffect(d.e1[ii])
                    call DestroyEffect(d.e2[ii])
                    call RemoveUnit(d.dum[ii])
                endloop
                set ii = 0
                set d.step = 5
            endif
            
            if d.step == 5 then
                loop
                    exitwhen ii == d.dummys3
                    set ii = ii + 1
                    set d.dum[ii] = CreateUnit(Player(16), DummyID, x, y, (ii*(bj_PI*2.)/3.))
                    call PauseUnit(d.dum[ii], true)
                    set d.e1[ii] = AddSpecialEffectTarget(Dummy3attach , d.dum[ii], "chest")
                    call UnitAddAbility(d.dum[ii], CrowFormID)
                    set d.maxheight3[ii] = Dummy3maxHeight(d.dist, GetUnitAbilityLevel(d.cast, SpellID))
                endloop
                set d.formula = 0.
                set ii = 0
                set d.step = 6
            endif
            
            if d.step == 6 then
                set d.formula = d.formula+0.0625
                loop
                    exitwhen ii == d.dummys3
                    set ii = ii + 1
                    set x = GetUnitX(d.dum[ii])
                    set y = GetUnitY(d.dum[ii])
                    call SetUnitX(d.dum[ii], x+d.aoe3/20.*Cos((ii*(bj_PI*2.)/3.)))
                    call SetUnitY(d.dum[ii], y+d.aoe3/20.*Sin((ii*(bj_PI*2.)/3.)))
                    call SetUnitFlyHeight(d.dum[ii], d.maxheight3*d.formula, 0.)
                    set x = GetUnitX(d.dum[ii])
                    set y = GetUnitY(d.dum[ii])
                    call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                    set u = FirstOfGroup(g)
                    loop
                        exitwhen u == null
                        call UnitDamageTarget(d.cast, u, d.dmg3, Attack, Ranged, AttackType, DamageType, WeaponType)
                        if GetRandomInt(1, 10) == 10 then
                            call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(u), GetUnitY(u)))
                        endif
                        call GroupRemoveUnit(g, u)
                        set u = FirstOfGroup(g)
                    endloop
                endloop
                set ii = 0
                if d.formula >= 1. then
                    loop
                        exitwhen ii == d.dummys3
                        set ii = ii + 1
                        call DestroyEffect(d.e1[ii])
                        call RemoveUnit(d.dum[ii])
                        set ar[i] = ar[total-1]
                        set total = total - 1
                        call d.destroy()
                    endloop
                    
                endif
            endif
            set i = i + 1
        endloop
        if total == 0 then
            call PauseTimer(tim)
        endif
    endfunction
    
    private function actions takes nothing returns nothing
        local data d = data.create()
        local integer lev = GetUnitAbilityLevel(GetTriggerUnit(), SpellID)
        call BJDebugMsg("init")
        set d.tx = GetSpellTargetX()
        set d.ty = GetSpellTargetY()
        set d.cast = GetTriggerUnit()
        set d.cx = GetUnitX(d.cast)
        set d.cy = GetUnitY(d.cast)
        set d.ang = Atan2(d.ty-d.cy, d.tx-d.cx)
        set d.dist = SquareRoot(Pow(d.tx-d.cx, 2.)+Pow(d.ty-d.cy,2.))
        set d.aoe1 = AoE1(d.dist, lev)
        set d.aoe2 = AoE2(d.dist, lev)
        set d.aoe3 = DamagePerSecAoe(d.dist, lev)
        set d.dmg1 = Damage1(d.dist, lev)
        set d.dmg2 = Damage2(d.dist, lev)
        set d.dmg3 = DamagePerSec(d.dist, lev)
        set d.maxheight2 = Dummy2maxHeight(d.dist, lev)
        set d.step = 0
        set d.dummys1 = Dummys1(lev)
        set d.dummys2 = Dummys2(lev)
        set d.dummys3 = Dummys3(lev)
        if total == 0 then
            call TimerStart(tim, TimerInt, true, function periodic)
        endif
        set ar[total] = d
        set total = total + 1
    endfunction
    
    private function noleakfilter takes nothing returns boolean
        return true
    endfunction

    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        local filterfunc ff = Filter(function noleakfilter)
        loop
            exitwhen i >= 16
            set i = i + 1
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, ff)
        endloop
        set i = 0
        call TriggerAddAction(t, function actions)
        call TriggerAddCondition(t, Condition(function condition))
        set b = Condition(function UnitFilter)
        call DestroyFilter(ff)
        set ff = null
    endfunction
endscope

Thanks in advance.
Here is the map to test.
 

Attachments

  • Fiery Rage v2.5.w3x
    111.6 KB · Views: 73
Level 4
Joined
Apr 16, 2009
Messages
85
the limit has always been 15 (there are 16 players "GUI Player 1" is actually Player(0) ... and "GUI Player 16" is Player(15))
 
Level 9
Joined
Nov 25, 2008
Messages
194
Hm well pretty simple solution thanks ;)

EDIT: Meh something different bugs now....

Again critical error, I must be king of them.

JASS:
scope FieryRage initializer init

    globals
        private constant integer SpellID        = 'A000'
        private constant integer DummyID        = 'h000'
        private constant integer CrowFormID     = 'Amrf'
        private constant string  Dummy1attach1  = "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl"
        private constant string  Dummy1attach2  = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl"
        private constant string  Dummy2attach1  = "Abilities\\Spells\\Other\\Volcano\\VolcanoMissile.mdl"
        private constant string  Dummy2attach2  = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
        private constant string  Dummy3attach   = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"
        private constant string  SFX1           = "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl"
        private constant string  SFX2           = "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl"
        private constant string  SFX3           = "Abilities\\Spells\\Other\\Volcano\\VolcanoDeath.mdl"
        private constant real    SFX1size       = 1.5
        private constant real    TimerInt       = .03
        private constant boolean Attack         = false
        private constant boolean Ranged         = false
        private constant attacktype AttackType  = ATTACK_TYPE_NORMAL
        private constant damagetype DamageType  = DAMAGE_TYPE_NORMAL
        private constant weapontype WeaponType  = WEAPON_TYPE_WHOKNOWS
    endglobals
    
    private function Dummys1 takes integer lev returns integer
        return 5
    endfunction
    
    private function Dummys2 takes integer lev returns integer
        return 10
    endfunction
    
    private function Dummys3 takes integer lev returns integer
        return Dummys2(0)*3
    endfunction
    
    private function Damage1 takes real dist, integer lev returns real
        return lev*100.
    endfunction
    
    private function Damage2 takes real dist, integer lev returns real
        return lev*25.
    endfunction
    
    private function DamagePerSec takes real dist, integer lev returns real
        return lev*10.*TimerInt
    endfunction
    
    private function AoE1 takes real dist, integer lev returns real
        return dist/2.
    endfunction
    
    private function AoE2 takes real dist, integer lev returns real
        return dist/4.
    endfunction
    
    private function Dummy2maxHeight takes real dist, integer lev returns real
        return AoE2(dist, 0)
    endfunction
    
    private function Dummy3maxHeight takes real dist, integer lev returns real
        return GetRandomReal(.0, 300.)
    endfunction
    
    private function DamagePerSecAoe takes real dist, integer lev returns real
        return 220.
    endfunction
    
    //Ignore the following 3 lines.
    globals
        private player p
    endglobals
    //Setup continues
    
    private function UnitFilter takes nothing returns boolean
        local unit u = GetFilterUnit()
        return IsUnitEnemy(u, p) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and not IsUnitType(u, UNIT_TYPE_MECHANICAL) and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) and GetWidgetLife(u)>.405
    endfunction
    
    //End of Setup
    
    
    private struct data
        unit cast
        unit array dum [8190]
        real dist
        real angle
        real aoe1
        real aoe2
        real aoe3
        real dmg1
        real dmg2
        real dmg3
        real cx
        real cy
        real tx
        real ty
        real ang
        real  array dumang [8190]
        real formula
        real maxheight2
        real array maxheight3 [8190]
        real array anglemod [8190]
        integer step
        integer dummys1
        integer dummys2
        integer dummys3
        effect e0
        effect array e1 [8190]
        effect array e2 [8190]
    endstruct
    
    globals
        private data array ar
        private timer tim = CreateTimer()
        private integer total = 0
        private boolexpr b
        private group g = CreateGroup()
    endglobals
        
    private function condition takes nothing returns boolean
        return GetSpellAbilityId()==SpellID
    endfunction

    private function periodic takes nothing returns nothing
        local data d
        local integer i = 0
        local integer ii = 0
        local real x = .0
        local real y = .0
        local unit u
        loop
            exitwhen i >= total
            set d = ar[i]
            if d.step == 0 then
                loop
                    exitwhen ii >= d.dummys1
                    set ii = ii + 1
                    set d.dum[ii] = CreateUnit(Player(15), DummyID, d.cx, d.cy, d.ang)
                    set d.anglemod[ii] = ii
                    call PauseUnit(d.dum[ii], true)
                    set d.e1[ii] = AddSpecialEffectTarget(Dummy1attach1 , d.dum[ii], "chest")
                    set d.e2[ii] = AddSpecialEffectTarget(Dummy1attach2 , d.dum[ii], "origin")
                    call UnitAddAbility(d.dum[ii], CrowFormID)
                endloop
                set d.formula = bj_PI/2.
                set ii = 0
                set d.step = 1
            endif
                
            if d.step == 1 then
                set d.formula = d.formula + bj_PI/80.
                loop
                    exitwhen ii >= d.dummys1
                    set ii = ii + 1
                    set x = GetUnitX(d.dum[ii])
                    set y = GetUnitY(d.dum[ii])
                    call SetUnitX(d.dum[ii], x+d.aoe1/40.*Cos(d.angle+(3.-d.anglemod[ii]*Sin(d.formula)*bj_PI/2.)))
                    call SetUnitY(d.dum[ii], y+d.aoe1/40.*Sin(d.angle+(3.-d.anglemod[ii]*Sin(d.formula)*bj_PI/2.)))
                    set x = GetUnitX(d.dum[ii])
                    set y = GetUnitY(d.dum[ii])
                    call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                    set u = FirstOfGroup(g)
                    loop
                        exitwhen u == null
                        call UnitDamageTarget(d.cast, u, d.dmg3, Attack, Ranged, AttackType, DamageType, WeaponType)
                        if GetRandomInt(1, 10) == 10 then
                            call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(u), GetUnitY(u)))
                        endif
                        call GroupRemoveUnit(g, u)
                        set u = FirstOfGroup(g)
                    endloop
                    set ii = 0
                    if d.formula == bj_PI then
                        set d.step = 2
                    endif
                endloop
            endif
                
            if d.step == 2 then
                call GroupEnumUnitsInRange(g, d.tx, d.ty, d.aoe1, b)
                loop
                    exitwhen u == null
                    call UnitDamageTarget(d.cast, u, d.dmg1, Attack, Ranged, AttackType, DamageType, WeaponType)
                    call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(u), GetUnitY(u)))
                    call GroupRemoveUnit(g, u)
                    set u = FirstOfGroup(g)
                endloop
                set u = CreateUnit(Player(15), DummyID, d.tx, d.ty, .0)
                call SetUnitScale(u, SFX1size, SFX1size, SFX1size)
                set d.e0 = AddSpecialEffectTarget(SFX1, u, "chest")
                call UnitApplyTimedLife(u, 'BTLF', 1.)
                call PauseUnit(u, true)
                loop
                    exitwhen ii >= d.dummys1
                    call DestroyEffect(d.e1[ii])
                    call DestroyEffect(d.e2[ii])
                    call RemoveUnit(d.dum[ii])
                endloop
                set ii = 0
                loop
                    exitwhen ii >= d.dummys2
                    set ii = ii + 1
                    set d.dum[ii] = CreateUnit(Player(15), DummyID, d.cx, d.cy, d.ang)
                    call PauseUnit(d.dum[ii], true)
                    set d.e1[ii] = AddSpecialEffectTarget(Dummy2attach1 , d.dum[ii], "chest")
                    set d.e2[ii] = AddSpecialEffectTarget(Dummy2attach2 , d.dum[ii], "origin")
                    call UnitAddAbility(d.dum[ii], CrowFormID)
                    set d.dumang[ii] = bj_PI*2./d.dummys2*ii
                endloop
                set ii = 0
                set d.step = 3
                set d.formula = 0.
            endif
                
            if d.step == 3 then
                set d.formula = d.formula + bj_PI/20.
                loop
                    exitwhen ii >= d.dummys2
                    set ii = ii + 1
                    set x = GetUnitX(d.dum[ii])
                    set y = GetUnitY(d.dum[ii])
                    call SetUnitX(d.dum[ii], x+d.aoe2/20.*Cos(ii*bj_PI*2./d.dummys2))
                    call SetUnitY(d.dum[ii], y+d.aoe2/20.*Sin(ii*bj_PI*2./d.dummys2))
                    call SetUnitFlyHeight(d.dum[ii], d.maxheight2*Sin(d.formula), 0.)
                    set x = GetUnitX(d.dum[ii])
                    set y = GetUnitY(d.dum[ii])
                    call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                    set u = FirstOfGroup(g)
                    loop
                        exitwhen u == null
                        call UnitDamageTarget(d.cast, u, d.dmg3, Attack, Ranged, AttackType, DamageType, WeaponType)
                        if GetRandomInt(1, 10) == 10 then
                            call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(u), GetUnitY(u)))
                        endif
                        call GroupRemoveUnit(g, u)
                        set u = FirstOfGroup(g)
                    endloop
                    set ii = 0
                endloop
                if d.formula == bj_PI then
                    set d.step = 4
                endif
            endif
                
            if d.step == 4 then
                call DestroyEffect(d.e0)
                loop
                    exitwhen ii == d.dummys2
                    set ii = ii + 1
                    set x = GetUnitX(d.dum[ii])
                    set y = GetUnitY(d.dum[ii])
                    call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                    set u = FirstOfGroup(g)
                    loop
                        exitwhen u == null
                        call UnitDamageTarget(d.cast, u, d.dmg2, Attack, Ranged, AttackType, DamageType, WeaponType)
                        call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(u), GetUnitY(u)))
                        call GroupRemoveUnit(g, u)
                        set u = FirstOfGroup(g)
                    endloop
                    call DestroyEffect(AddSpecialEffect(SFX2, x, y))
                    call DestroyEffect(AddSpecialEffect(SFX2, x, y))
                    call DestroyEffect(d.e1[ii])
                    call DestroyEffect(d.e2[ii])
                    call RemoveUnit(d.dum[ii])
                endloop
                set ii = 0
                set d.step = 5
            endif
            
            if d.step == 5 then
                loop
                    exitwhen ii == d.dummys3
                    set ii = ii + 1
                    set d.dum[ii] = CreateUnit(Player(15), DummyID, x, y, (ii*(bj_PI*2.)/3.))
                    call PauseUnit(d.dum[ii], true)
                    set d.e1[ii] = AddSpecialEffectTarget(Dummy3attach , d.dum[ii], "chest")
                    call UnitAddAbility(d.dum[ii], CrowFormID)
                    set d.maxheight3[ii] = Dummy3maxHeight(d.dist, GetUnitAbilityLevel(d.cast, SpellID))
                endloop
                set d.formula = 0.
                set ii = 0
                set d.step = 6
            endif
            
            if d.step == 6 then
                set d.formula = d.formula+0.0625
                loop
                    exitwhen ii == d.dummys3
                    set ii = ii + 1
                    set x = GetUnitX(d.dum[ii])
                    set y = GetUnitY(d.dum[ii])
                    call SetUnitX(d.dum[ii], x+d.aoe3/20.*Cos((ii*(bj_PI*2.)/3.)))
                    call SetUnitY(d.dum[ii], y+d.aoe3/20.*Sin((ii*(bj_PI*2.)/3.)))
                    call SetUnitFlyHeight(d.dum[ii], d.maxheight3*d.formula, 0.)
                    set x = GetUnitX(d.dum[ii])
                    set y = GetUnitY(d.dum[ii])
                    call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                    set u = FirstOfGroup(g)
                    loop
                        exitwhen u == null
                        call UnitDamageTarget(d.cast, u, d.dmg3, Attack, Ranged, AttackType, DamageType, WeaponType)
                        if GetRandomInt(1, 10) == 10 then
                            call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(u), GetUnitY(u)))
                        endif
                        call GroupRemoveUnit(g, u)
                        set u = FirstOfGroup(g)
                    endloop
                endloop
                set ii = 0
                if d.formula >= 1. then
                    loop
                        exitwhen ii == d.dummys3
                        set ii = ii + 1
                        call DestroyEffect(d.e1[ii])
                        call RemoveUnit(d.dum[ii])
                        set ar[i] = ar[total-1]
                        set total = total - 1
                        call d.destroy()
                    endloop
                    
                endif
            endif
            set i = i + 1
        endloop
        if total == 0 then
            call PauseTimer(tim)
        endif
    endfunction
    
    private function actions takes nothing returns nothing
        local data d = data.create()
        local integer lev = GetUnitAbilityLevel(GetTriggerUnit(), SpellID)
        set d.tx = GetSpellTargetX()
        set d.ty = GetSpellTargetY()
        set d.cast = GetTriggerUnit()
        set d.cx = GetUnitX(d.cast)
        set d.cy = GetUnitY(d.cast)
        set d.ang = Atan2(d.ty-d.cy, d.tx-d.cx)
        set d.dist = SquareRoot(Pow(d.tx-d.cx, 2.)+Pow(d.ty-d.cy,2.))
        set d.aoe1 = AoE1(d.dist, lev)
        set d.aoe2 = AoE2(d.dist, lev)
        set d.aoe3 = DamagePerSecAoe(d.dist, lev)
        set d.dmg1 = Damage1(d.dist, lev)
        set d.dmg2 = Damage2(d.dist, lev)
        set d.dmg3 = DamagePerSec(d.dist, lev)
        set d.maxheight2 = Dummy2maxHeight(d.dist, lev)
        set d.step = 0
        set d.dummys1 = Dummys1(lev)
        set d.dummys2 = Dummys2(lev)
        set d.dummys3 = Dummys3(lev)
        if total == 0 then
            call TimerStart(tim, TimerInt, true, function periodic)
        endif
        set ar[total] = d
        set total = total + 1
    endfunction
    
    private function noleakfilter takes nothing returns boolean
        return true
    endfunction

    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        local filterfunc ff = Filter(function noleakfilter)
        loop
            exitwhen i >= bj_MAX_PLAYER_SLOTS
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, ff)
            set i = i + 1
        endloop
        set i = 0
        call TriggerAddAction(t, function actions)
        call TriggerAddCondition(t, Condition(function condition))
        set b = Condition(function UnitFilter)
        call DestroyFilter(ff)
        set ff = null
    endfunction
endscope

Hope the mistake isn't that dumb this time.
Thanks in advance for your help.

EDIT2: Oh and you can activate FW_Init3 and FW_Run3 in the other folder to see how the spell should work.
 

Attachments

  • Fiery Rage v2.5.w3x
    111.4 KB · Views: 52
Last edited:
Level 17
Joined
Mar 17, 2009
Messages
1,349
JASS:
exitwhen i >= bj_MAX_PLAYER_SLOTS
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, ff)
set i = i + 1

Make it:
JASS:
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, ff)
set i = i + 1
exitwhen i >= bj_MAX_PLAYER_SLOTS

I think it'll work then... the way you looped before still looped through the 16th player.
This way, integer i reaches 16, but never loops through it ;)
 
Level 4
Joined
Apr 16, 2009
Messages
85
i think what crashes now it this part
JASS:
if d.formula >= 1. then
    loop
        exitwhen ii == d.dummys3
            set ii = ii + 1
            call DestroyEffect(d.e1[ii])
            call RemoveUnit(d.dum[ii])
            set ar[i] = ar[total-1]
            set total = total - 1
            call d.destroy()
    endloop
endif

if i read that correctly d.dummys3 should be 30 in your case the instance limit from your spell is 1 (you should really fix that and your create and destroy methods) so total can't be larger then 1 but you are subtracting 30 from it so in the end you are trying to access ar[total - 1] for a negative value of total and that doesn't work

Edit: btw the Player(16) seem to be fixed (deuterium's solution does the same as yours anyway)
 
Last edited:
Level 4
Joined
Apr 16, 2009
Messages
85
No, putting the exitwhen at the front or bottom of the loop makes no difference except when it might exit as soon as the loop starts.

yes its not really the exact same, but it only changes the loop from a "while" loop into a "do - while" loop - which in this case acts the same
 
Level 4
Joined
Apr 16, 2009
Messages
85
well its only partly working and looks only partly like your demo but it doesn't crash and you should be able to fix and finish it from here on

(btw i cleaned up your code a bit but its still realy bad - but well after all i guess i didn't do better with my first jass spell ^^)
JASS:
scope FieryRage initializer init

    globals
        private constant integer SpellID        = 'A000'
        private constant integer DummyID        = 'h000'
        private constant integer CrowFormID     = 'Amrf'
        private constant string  Dummy1attach1  = "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl"
        private constant string  Dummy1attach2  = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl"
        private constant string  Dummy2attach1  = "Abilities\\Spells\\Other\\Volcano\\VolcanoMissile.mdl"
        private constant string  Dummy2attach2  = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
        private constant string  Dummy3attach   = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"
        private constant string  SFX1           = "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl"
        private constant string  SFX2           = "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl"
        private constant string  SFX3           = "Abilities\\Spells\\Other\\Volcano\\VolcanoDeath.mdl"
        private constant real    SFX1size       = 1.5
        private constant real    TimerInt       = .03
        private constant boolean Attack         = false
        private constant boolean Ranged         = false
        private constant attacktype AttackType  = ATTACK_TYPE_NORMAL
        private constant damagetype DamageType  = DAMAGE_TYPE_NORMAL
        private constant weapontype WeaponType  = WEAPON_TYPE_WHOKNOWS
        private constant integer MaxDummys = 30
    endglobals
    
    private function Dummys1 takes integer lev returns integer
        return 5
    endfunction
    
    private function Dummys2 takes integer lev returns integer
        return 10
    endfunction
    
    private function Dummys3 takes integer lev returns integer
        return Dummys2(0)*3
    endfunction
    
    private function Damage1 takes real dist, integer lev returns real
        return lev*100.
    endfunction
    
    private function Damage2 takes real dist, integer lev returns real
        return lev*25.
    endfunction
    
    private function DamagePerSec takes real dist, integer lev returns real
        return lev*10.*TimerInt
    endfunction
    
    private function AoE1 takes real dist, integer lev returns real
        return dist/2.
    endfunction
    
    private function AoE2 takes real dist, integer lev returns real
        return dist/4.
    endfunction
    
    private function Dummy2maxHeight takes real dist, integer lev returns real
        return AoE2(dist, 0)
    endfunction
    
    private function Dummy3maxHeight takes real dist, integer lev returns real
        return GetRandomReal(.0, 300.)
    endfunction
    
    private function DamagePerSecAoe takes real dist, integer lev returns real
        return 220.
    endfunction
    
    //Ignore the following 3 lines.
    globals
        private player p
    endglobals
    //Setup continues
    
    private function UnitFilter takes nothing returns boolean
        local unit u = GetFilterUnit()
        return IsUnitEnemy(u, p) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and not IsUnitType(u, UNIT_TYPE_MECHANICAL) and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) and GetWidgetLife(u)>.405
    endfunction
    
    //End of Setup
    
    globals
        private data array ar
        private timer tim = CreateTimer()
        private integer total = 0
        private boolexpr b
        private group g = CreateGroup()
    endglobals
    
    private function periodic takes nothing returns nothing
        local data d
        local integer i = 0
        local integer ii = 0
        local real x = .0
        local real y = .0
        local unit u
        loop
            exitwhen i >= total
            set d = ar[i]
            if d.step == 0 then
                set ii = 0
                loop
                    exitwhen ii >= d.dummys1
                    set d.dum[ii] = CreateUnit(Player(15), DummyID, d.cx, d.cy, d.angle)
                    set d.anglemod[ii] = ii
                    call PauseUnit(d.dum[ii], true)
                    set d.e1[ii] = AddSpecialEffectTarget(Dummy1attach1 , d.dum[ii], "chest")
                    set d.e2[ii] = AddSpecialEffectTarget(Dummy1attach2 , d.dum[ii], "origin")
                    call UnitAddAbility(d.dum[ii], CrowFormID)
                    set ii = ii + 1
                endloop
                set d.formula = bj_PI/2.
                set d.step = 1
            elseif d.step == 1 then
                set d.formula = d.formula + bj_PI/80.
                set ii = 0
                loop
                    exitwhen ii >= d.dummys1
                    set x = GetUnitX(d.dum[ii])+d.aoe1/40.*Cos(d.angle+(0.0523-d.anglemod[ii]*Sin(d.formula)))
                    set y = GetUnitY(d.dum[ii])+d.aoe1/40.*Sin(d.angle+(0.0523-d.anglemod[ii]*Sin(d.formula)))
                    call SetUnitX(d.dum[ii], x)
                    call SetUnitY(d.dum[ii], y)
                    
                    call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                    set u = FirstOfGroup(g)
                    loop
                        exitwhen u == null
                        call UnitDamageTarget(d.cast, u, d.dmg3, Attack, Ranged, AttackType, DamageType, WeaponType)
                        if GetRandomInt(1, 10) == 10 then
                            call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(u), GetUnitY(u)))
                        endif
                        call GroupRemoveUnit(g, u)
                        set u = FirstOfGroup(g)
                    endloop
                    
                    set ii = ii + 1
                endloop
                
                if d.formula >= bj_PI then
                    set d.step = 2
                endif
            elseif d.step == 2 then
                call GroupEnumUnitsInRange(g, d.tx, d.ty, d.aoe1, b)
                loop
                    set u = FirstOfGroup(g)
                    exitwhen u == null
                    call UnitDamageTarget(d.cast, u, d.dmg1, Attack, Ranged, AttackType, DamageType, WeaponType)
                    call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(u), GetUnitY(u)))
                    call GroupRemoveUnit(g, u)
                endloop
                set u = CreateUnit(Player(15), DummyID, d.tx, d.ty, .0)
                call SetUnitScale(u, SFX1size, SFX1size, SFX1size)
                set d.e0 = AddSpecialEffectTarget(SFX1, u, "chest")
                call UnitApplyTimedLife(u, 'BTLF', 1.)
                call PauseUnit(u, true)
                set ii = 0
                loop
                    exitwhen ii >= d.dummys1
                    call DestroyEffect(d.e1[ii])
                    call DestroyEffect(d.e2[ii])
                    call RemoveUnit(d.dum[ii])
                    set ii = ii + 1
                endloop
                set ii = 0
                loop
                    exitwhen ii >= d.dummys2
                    set d.dum[ii] = CreateUnit(Player(15), DummyID, d.cx, d.cy, d.angle)
                    call PauseUnit(d.dum[ii], true)
                    set d.e1[ii] = AddSpecialEffectTarget(Dummy2attach1 , d.dum[ii], "chest")
                    set d.e2[ii] = AddSpecialEffectTarget(Dummy2attach2 , d.dum[ii], "origin")
                    call UnitAddAbility(d.dum[ii], CrowFormID)
                    set d.dumang[ii] = bj_PI*2./d.dummys2*ii
                    set ii = ii + 1
                endloop
                set d.step = 3
                set d.formula = 0.
            elseif d.step == 3 then
                set d.formula = d.formula + bj_PI/20.
                set ii = 0
                loop
                    exitwhen ii >= d.dummys2
                    set x = GetUnitX(d.dum[ii])+d.aoe2/20.*Cos(ii*bj_PI*2./d.dummys2)
                    set y = GetUnitY(d.dum[ii])+d.aoe2/20.*Sin(ii*bj_PI*2./d.dummys2)
                    call SetUnitX(d.dum[ii], x)
                    call SetUnitY(d.dum[ii], y)
                    call SetUnitFlyHeight(d.dum[ii], d.maxheight2*Sin(d.formula), 0.)
                    
                    call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                    set u = FirstOfGroup(g)
                    loop
                        exitwhen u == null
                        call UnitDamageTarget(d.cast, u, d.dmg3, Attack, Ranged, AttackType, DamageType, WeaponType)
                        if GetRandomInt(1, 10) == 10 then
                            call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(u), GetUnitY(u)))
                        endif
                        call GroupRemoveUnit(g, u)
                        set u = FirstOfGroup(g)
                    endloop
                    set ii = ii + 1
                endloop
                if d.formula == bj_PI then
                    set d.step = 4
                endif
            elseif d.step == 4 then
                call DestroyEffect(d.e0)
                set ii = 0
                loop
                    exitwhen ii == d.dummys2
                    set x = GetUnitX(d.dum[ii])
                    set y = GetUnitY(d.dum[ii])
                    call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                    set u = FirstOfGroup(g)
                    loop
                        exitwhen u == null
                        call UnitDamageTarget(d.cast, u, d.dmg2, Attack, Ranged, AttackType, DamageType, WeaponType)
                        call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(u), GetUnitY(u)))
                        call GroupRemoveUnit(g, u)
                        set u = FirstOfGroup(g)
                    endloop
                    call DestroyEffect(AddSpecialEffect(SFX2, x, y))
                    call DestroyEffect(AddSpecialEffect(SFX2, x, y))
                    call DestroyEffect(d.e1[ii])
                    call DestroyEffect(d.e2[ii])
                    call RemoveUnit(d.dum[ii])
                    set ii = ii + 1
                endloop
                set ii = 0
                set d.step = 5
            elseif d.step == 5 then
                set ii = 0
                loop
                    exitwhen ii >= d.dummys3
                    set d.dum[ii] = CreateUnit(Player(15), DummyID, x, y, (ii*(bj_PI*2.)/3.))
                    call PauseUnit(d.dum[ii], true)
                    set d.e1[ii] = AddSpecialEffectTarget(Dummy3attach , d.dum[ii], "chest")
                    call UnitAddAbility(d.dum[ii], CrowFormID)
                    set d.maxheight3[ii] = Dummy3maxHeight(d.dist, GetUnitAbilityLevel(d.cast, SpellID))
                    set ii = ii + 1
                endloop
                set d.formula = 0.
                set d.step = 6
            elseif d.step == 6 then
                set d.formula = d.formula+0.0625
                set ii = 0
                loop
                    exitwhen ii == d.dummys3
                    set x = GetUnitX(d.dum[ii])+d.aoe3/20.*Cos((ii*(bj_PI*2.)/3.))
                    set y = GetUnitY(d.dum[ii])+d.aoe3/20.*Sin((ii*(bj_PI*2.)/3.))
                    call SetUnitX(d.dum[ii], x)
                    call SetUnitY(d.dum[ii], y)
                    call SetUnitFlyHeight(d.dum[ii], d.maxheight3*d.formula, 0.)
                    call GroupEnumUnitsInRange(g, x, y, d.aoe3, b)
                    set u = FirstOfGroup(g)
                    loop
                        exitwhen u == null
                        call UnitDamageTarget(d.cast, u, d.dmg3, Attack, Ranged, AttackType, DamageType, WeaponType)
                        if GetRandomInt(1, 10) == 10 then
                            call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(u), GetUnitY(u)))
                        endif
                        call GroupRemoveUnit(g, u)
                        set u = FirstOfGroup(g)
                    endloop
                    set ii = ii + 1
                endloop
                
                if d.formula >= 1. then
                    set ii = 0
                    loop
                        exitwhen ii >= d.dummys3
                        call DestroyEffect(d.e1[ii])
                        call RemoveUnit(d.dum[ii])
                        set ii = ii + 1
                    endloop
                    call d.destroy()
                    set i = i - 1
                endif
            endif
            set i = i + 1
        endloop
    endfunction
    
    struct data
        unit cast
        unit array dum [MaxDummys]
        real dist
        real angle
        real aoe1
        real aoe2
        real aoe3
        real dmg1
        real dmg2
        real dmg3
        real cx
        real cy
        real tx
        real ty
        real  array dumang [MaxDummys]
        real formula
        real maxheight2
        real array maxheight3 [MaxDummys]
        real array anglemod [MaxDummys]
        integer step
        integer dummys1
        integer dummys2
        integer dummys3
        effect e0
        effect array e1 [MaxDummys]
        effect array e2 [MaxDummys]
        integer pos
        
        public static method create takes unit caster, real targetx, real targety returns thistype
            local thistype d = thistype.allocate()
            local integer lev = GetUnitAbilityLevel(GetTriggerUnit(), SpellID)
            set d.tx = targetx
            set d.ty = targety
            set d.cast = caster
            set d.cx = GetUnitX(d.cast)
            set d.cy = GetUnitY(d.cast)
            set d.angle = Atan2(d.ty-d.cy, d.tx-d.cx)
            set d.dist = SquareRoot(Pow(d.tx-d.cx, 2.)+Pow(d.ty-d.cy,2.))
            set d.aoe1 = AoE1(d.dist, lev)
            set d.aoe2 = AoE2(d.dist, lev)
            set d.aoe3 = DamagePerSecAoe(d.dist, lev)
            set d.dmg1 = Damage1(d.dist, lev)
            set d.dmg2 = Damage2(d.dist, lev)
            set d.dmg3 = DamagePerSec(d.dist, lev)
            set d.maxheight2 = Dummy2maxHeight(d.dist, lev)
            set d.step = 0
            set d.dummys1 = Dummys1(lev)
            set d.dummys2 = Dummys2(lev)
            set d.dummys3 = Dummys3(lev)
            set d.pos = total
            set ar[total] = d
            set total = total + 1
            if total == 1 then
                call TimerStart(tim, TimerInt, true, function periodic)
            endif
            return d
        endmethod
        
        private method onDestroy takes nothing returns nothing
            local integer i = 0
            set total = total - 1
            set ar[.pos] = ar[total]
            set ar[.pos].pos = .pos
            if total == 0 then
                call PauseTimer(tim)
            endif
        endmethod
    endstruct
    
    
        
    private function condition takes nothing returns boolean
        return GetSpellAbilityId()==SpellID
    endfunction

    
    
    private function actions takes nothing returns nothing
        call data.create(GetTriggerUnit(),GetSpellTargetX(), GetSpellTargetY())
    endfunction
    

    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        loop
            exitwhen i >= bj_MAX_PLAYER_SLOTS
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
            set i = i + 1
        endloop
        call TriggerAddAction(t, function actions)
        call TriggerAddCondition(t, Condition(function condition))
        set b = Condition(function UnitFilter)
    endfunction
endscope
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
@ Void:
Oh, then let's say you have exitwhen at the top of the loop:
JASS:
loop
    exitwhen i == 5
    // --- actions ---
endloop

This exits directly at the exitwhen line when the condition is met or does it run the actions inside the loop and then exits? Get my question? :)
 
Level 4
Joined
Apr 16, 2009
Messages
85
@ Void:
Oh, then let's say you have exitwhen at the top of the loop:
JASS:
loop
    exitwhen i == 5
    // --- actions ---
endloop

This exits directly at the exitwhen line when the condition is met or does it run the actions inside the loop and then exits? Get my question? :)

it exits directly - the exitwhen line just instantly stops the loop when the expression returns true. you can even use it as a "break" by just calling "exitwhen true" (after all you can have as many exitwhens as you want)
 
Status
Not open for further replies.
Top