1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  4. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  5. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  6. The results are out! Check them out.
    Dismiss Notice
  7. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  8. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  9. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Spell Crashes game

Discussion in 'Triggers & Scripts' started by WyrmSlayer, Aug 3, 2019.

  1. WyrmSlayer

    WyrmSlayer

    Joined:
    Apr 18, 2010
    Messages:
    67
    Resources:
    1
    Spells:
    1
    Resources:
    1
    I dont know the reason, but it appears that the game crashes when this spell is used.
    Code (Text):
    scope UnlimitedBladeWorks

        globals                    
            private constant integer ABILITY_ID = 'ubwe' //spell Id
            private constant real FPS = 0.0312500
         
            //Spell Constants
            private constant real RADIUS = 800 //radius of the reality marble
            private constant real CASTTIME = 0.5 //delay before the formation of RM
            private constant real FORMTIME = 1.0 //formation time of reality marble
            private constant real DURATION = 8 //duration of spell
         
            //Spell Visuals
            private constant string ANIMATION = "Spell Three" //caster animation when the spell is casted
            private constant real ANIMATIONSPEED = 150 //animation speed of caster
            private constant string CASTINGSOUND = "war3mapImported\\EMY_NP.mp3"
         
            private constant string FIREFX = "Doodads\\Cinematic\\TownBurningFireEmitter\\TownBurningFireEmitter.mdl" //sfx of the RM border
            private constant real FIREFXSIZE = 1.25 //size of Fireborder
            private constant real FIREFXSPIN = 6 //degrees of spin of fire (rate depends of FPS)
            private constant integer FIREFXCOUNT = 60 //number of firefx
         
            private constant string SWORDFX = "war3mapImported\\EmiyaSword.mdl" //sfx of swords
            private constant real SWORDFXSIZE = 1.25 //size of swords
            private constant integer SWORDFXPITCH = 60 //pitch of swords
            private constant real SWORDFXCOUNT = 1.75
            private constant real SWORDFXINC = .25
         
            private constant string GEAR1FX = "war3mapImported\\Gear2.mdl"
            private constant string GEAR2FX = "war3mapImported\\Gear3.mdl"
            private constant integer GEARCOUNT = 12
     
             
         
        endglobals
     
        //Function made by Blade.dk; Search for [url=http://www.wc3campaigns.com]wc3campaigns.com[/url] for more info
        private function CopyGroup takes group g returns group
            set bj_groupAddGroupDest = CreateGroup()
            call ForGroup(g, function GroupAddGroupEnum)
            return bj_groupAddGroupDest
        endfunction
     
        private struct MySpell
     
            private unit    caster
            private real     duration
            private real     formtime
            private real     casttime
            private real    firefxspeed
            private real     swordfxcount
            private real     radius
            private real     angle
            private group     realitymarblegroup
            private group    copygroup
            private group     firegroup
            private real    ubwX
            private real    ubwY
            private real     fireangleinc
            private real     gearangle
            private integer stage
         
             
            private static method onPeriodic takes nothing returns nothing
                local timer tmr = GetExpiredTimer()
                local integer g
                local unit u
                local real X1
                local real Y1
                local real X2
                local real Y2
                local real fireangle
                local real gearsize
                local real gearZ
                local integer gearvar
             
                local thistype this = GetTimerData(tmr)
             
                // Your spell code. For example.
                if this.stage == 1 then
                    if this.casttime > 0 then
                        if GetWidgetLife(this.caster) >= 0.405 then
                            set this.casttime = this.casttime - FPS
                        else
                        set this.stage = 0
                        endif
                    else
                    set this.stage = 2
                    set this.ubwX = GetUnitX(this.caster)
                    set this.ubwY = GetUnitY(this.caster)
                    set g = FIREFXCOUNT
                    loop
                        exitwhen g <= 0
                        set u = GetRecycledDummy(ubwX, ubwY, 0, this.angle)
                        call AddSpecialEffectTarget(FIREFX,u,"origin")
                        set this.angle = this.angle + fireangleinc
                        call GroupAddUnit(this.realitymarblegroup,u)
                        call GroupAddUnit(this.firegroup,u)
                        call SetUnitScale(u, FIREFXSIZE, 1, 1)
                        set g = g - 1
                    endloop
                    endif
                endif
                 
                if this.stage == 2 then
                    if this.formtime > 0 then
                        set this.copygroup = CopyGroup(this.firegroup)
                        set this.radius = this.radius + this.firefxspeed
                        loop
                            set u = FirstOfGroup(this.copygroup)
                            exitwhen u == null
                            set X1 = GetUnitX(u)
                            set Y1 = GetUnitY(u)
                            set fireangle = GetUnitFacing(u)
                            set X2 = X1 + this.firefxspeed * Cos( Deg2Rad (fireangle))
                            set Y2 = Y1 + this.firefxspeed * Sin( Deg2Rad (fireangle))
                            call SetUnitX(u, X2)
                            call SetUnitY(u, Y2)
                            call SetUnitFacing(u, fireangle + FIREFXSPIN)
                            call GroupRemoveUnit(this.copygroup, u)
                        endloop
                         
                        set g = R2I(this.swordfxcount)
                        loop
                            exitwhen g == 0
                            set X2 = this.ubwX + GetRandomReal( -1 * this.radius, this.radius ) * Cos(GetRandomReal(0,360))
                            set Y2 = this.ubwY + GetRandomReal( -1 * this.radius, this.radius ) * Sin(GetRandomReal(0,360))
                            set u = GetRecycledDummy(X2, Y2, 0, GetRandomReal(0,360))
                            call AddSpecialEffectTarget(SWORDFX,u,"origin")
                            call GroupAddUnit(this.realitymarblegroup,u)
                            call SetUnitScale(u, SWORDFXSIZE, 1, 1)
                            call SetUnitAnimationByIndex(u, SWORDFXPITCH)
                            set g = g - 1
                        endloop
                        set this.swordfxcount = this.swordfxcount + SWORDFXINC
                     
                        set this.formtime = this.formtime - FPS
                     
                    else
                        set this.stage = 3
                        set this.angle = GetRandomReal(0,360)
                        set g = GEARCOUNT
                        loop
                            exitwhen g == 0
                            set X2 = this.ubwX + (this.radius + 25)*Cos(this.angle)
                            set Y2 = this.ubwY + (this.radius + 25)*Sin(this.angle)
                            set this.angle = this.angle + this.gearangle
                            set gearsize = GetRandomReal(2.25,3.25)
                            set gearZ = GetRandomReal(125,225)
                            set u = GetRecycledDummy(X2, Y2, gearZ, this.angle)
                            set gearvar = GetRandomInt(1,2)
                            if gearvar == 1 then
                                call AddSpecialEffectTarget(GEAR1FX,u,"origin")
                            else
                                call AddSpecialEffectTarget(GEAR2FX,u,"origin")
                            endif
                            call GroupAddUnit(this.realitymarblegroup,u)
                            call SetUnitScale(u, gearsize, 1, 1)
                            set g = g - 1
                        endloop
                    endif
                endif
             
                if this.stage == 3    then  
                    if this.duration > 0 then
                        set this.duration = this.duration - FPS
                        //apply border control
                    else
                    set this.stage = 0  
                    endif
                endif
             
                //deallocation
                if this.stage == 0 then
                    call this.destroy()
                    call ReleaseTimer(tmr)
                    call PauseUnit(this.caster, false)
                    loop
                        set u = FirstOfGroup(this.realitymarblegroup)
                        exitwhen u == null
                        call DummyAddRecycleTimer(u,0.5)  
                    endloop
                endif
             
                set tmr = null
            endmethod
                       
            private static method onEffect takes nothing returns nothing
             
                local thistype this = thistype.create()// Creates a unique index "this".
             
                //initializing spell variables
                set this.caster = GetTriggerUnit()
                set this.duration = DURATION
                set this.casttime = CASTTIME
                set this.formtime = FORMTIME
                set this.firefxspeed = (RADIUS / (FORMTIME / (1/FPS)))
                set this.radius = 0
                set this.angle = GetRandomReal(0,360)
                set this.swordfxcount = SWORDFXCOUNT
                set this.fireangleinc = 360 / I2R(FIREFXCOUNT)
                set this.gearangle = 360 / I2R(GEARCOUNT)
             
                //start casting
                //creating groups
                set this.realitymarblegroup = CreateGroup()
                set this.copygroup = CreateGroup()
                set this.firegroup = CreateGroup()
             
                //spell core
                set this.stage = 1
                call PauseUnit(this.caster, true)
                call SetUnitAnimation(this.caster, ANIMATION)
                call SetUnitTimeScale(this.caster, ANIMATIONSPEED)
                call AttachSoundUnit(this.caster, CASTINGSOUND, 127, 9, 2000, false, true, 1500, 3000)
             
                //add caster to Casting group here
                //add caster to not moving group here
                //add caster to not walking group here
             
         
                call TimerStart(NewTimerEx(this), FPS, true, function thistype.onPeriodic)
            endmethod  
         
            private static method onInit takes nothing returns nothing
                call RegisterSpellEffectEvent(ABILITY_ID, function thistype.onEffect)
            endmethod
     
        endstruct

    endscope
     
    Last edited: Sep 19, 2019
  2. Pyrogasm

    Pyrogasm

    Joined:
    Feb 27, 2007
    Messages:
    2,901
    Resources:
    1
    Spells:
    1
    Resources:
    1
    You absolutely do not need to use I2R, that's just pointless. Any operation that involves an integer and a real outputs a real; the only case where you might need to 'convert' in some way is doing integer division where you want the output to be a real. 3/2 = 1 in integer division, not 1.5.
     
  3. WyrmSlayer

    WyrmSlayer

    Joined:
    Apr 18, 2010
    Messages:
    67
    Resources:
    1
    Spells:
    1
    Resources:
    1
    currently redoing the triggers hahaha.. Ill post an update.. thanks for the input.



    made things simpler, still crashes tho.. for some reason, unit creation doesnt happen as well??
     
    Last edited: Aug 3, 2019
  4. IcemanBo

    IcemanBo

    Joined:
    Sep 6, 2013
    Messages:
    6,178
    Resources:
    22
    Maps:
    3
    Spells:
    11
    Template:
    1
    Tutorials:
    4
    JASS:
    3
    Resources:
    22
    Please use [jass][/jass] tags to post JASS code, and update first post code instead of posting new ones. : )

    Code (vJASS):
    loop
        set u = FirstOfGroup(this.realitymarblegroup)
        exitwhen u == null
        call DummyAddRecycleTimer(u,0.5)
    endloop
    ^No units removed from group. => probably infinite loop

    Some notes:
    • set this.copygroup = CopyGroup(this.firegroup)
      here happens an object leak, because your group is already created, but CopyGroup() does again create a new group, too.
    • There should be an extra destroy() method, where all things are releases etc, and also member vars of this are nulled.
    When does it crash? What does not work? Does something even work? Which units are not being created, none at all? etc..
    Have not tested the map (can't now), but I believe you're on a level where you know such things could help others and yourself. :)
     
  5. WyrmSlayer

    WyrmSlayer

    Joined:
    Apr 18, 2010
    Messages:
    67
    Resources:
    1
    Spells:
    1
    Resources:
    1

    Edited, the game doesnt crash now, however no units are still being created....

    I did put some debugging message a while ago, it turns out that the spell fires up to Stage = 2 and beyond, its just that no creation of units take place.

    Code (Text):

    scope UnlimitedBladeWorks
        globals
            private constant integer ABILITY_ID = 'ubwe'
            private constant real FPS = 0.03125
            private group copy
            private constant real UBW_DURATION = 8.0 //seconds
            private constant real UBW_FORMTIME = 1.0 //seconds
            private constant real UBW_CASTTIME = 0.5 //seconds
            private constant real UBW_RADIUS = 800
            private constant string FIRE_SFX = "Doodads\\Cinematic\\TownBurningFireEmitter\\TownBurningFireEmitter"
            private constant real FIRE_SIZE = 1.25
            private constant integer FIRE_COUNT = 60
            private constant real FIRE_ANGLE = 6
           
           
        endglobals
       
        private struct UnlimitedBladeWorks
       
            private unit        caster
            private real        duration
            private real         casttime
            private integer        stage
            private location     UBWlocation
            private real         formtime
            private real         angle
            private group         firefxgroup
            private group        ubwgroup
            private effect        sfx
            private real         radius
            private real        firefxspeed
            private real         fireangle
           
               
            private static method onPeriodic takes nothing returns nothing
                local timer tmr = GetExpiredTimer()
                local thistype this = GetTimerData(tmr)
                local unit u
                local real x1
                local real y1
                local real z1
                local real x2
                local real y2
                local real facing
                local integer s
                // Your spell code. For example.
               
                if this.stage == 1 then
                    if this.casttime <= 0 then
                        set this.stage = 2
                        set this.UBWlocation = GetUnitLoc(this.caster)
                        set x1 = GetLocationX(this.UBWlocation)
                        set y1 = GetLocationY(this.UBWlocation)
                        set z1 = GetLocationZ(this.UBWlocation)
                        set s = FIRE_COUNT
                        loop
                            exitwhen s == 0
                            set s = s - 1
                            set this.angle = this.angle + fireangle
                            set u = GetRecycledDummy(x1,y1,z1,this.angle)
                            set this.sfx = AddSpecialEffectTarget(FIRE_SFX,u,"origin")
                            call SetUnitScalePercent(u, FIRE_SIZE, FIRE_SIZE, FIRE_SIZE)
                            call GroupAddUnit(this.firefxgroup,u)
                            call GroupAddUnit(this.ubwgroup, u)
                        endloop
                           
                    else
                        if GetWidgetLife(this.caster) >= 0.405 then
                            set this.casttime = this.casttime - FPS
                        else
                            set this.stage = 0
                        endif
                    endif
                endif
           
                if this.stage == 2 then
                    if this.formtime > 0 then
                        set this.formtime = this.formtime - FPS
                        set copy = this.firefxgroup
                        loop
                            set u = FirstOfGroup(copy)
                            exitwhen u == null
                            set x1 = GetUnitX(u)
                            set y1 = GetUnitY(u)
                            set facing = GetUnitFacing(u)
                            set x2 = x1 + this.firefxspeed*CosBJ(facing)
                            set y2 = y1 + this.firefxspeed*SinBJ(facing)
                            call SetUnitX(u,x2)
                            call SetUnitY(u,y2)
                            call GroupRemoveUnit(copy,u)
                            set u = null
                        endloop  
                        //create swords
                    else
                    set this.stage = 3
                    //create gears
                    endif
                endif
               
                if this.stage == 3 then
                    if this.duration > 0 then
                    set this.duration = this.duration - FPS
                    //apply border control
                    endif
                    set this.stage = 0
                endif
               
                if this.stage == 0 then  
                    //destroy trigger not yet complete
                    call this.destroy()
                    call ReleaseTimer(tmr)
                    loop
                        set u = FirstOfGroup(this.ubwgroup)
                        exitwhen u == null
                        call DummyAddRecycleTimer(u, 0.5)
                        call DestroyEffect(this.sfx)
                        call GroupRemoveUnit(this.ubwgroup,u)
                    endloop  
                endif
               
                set tmr = null
            endmethod
                         
            private static method onEffect takes nothing returns nothing
                local thistype this = thistype.create()
               
                set this.caster = GetTriggerUnit()
                set this.duration = UBW_DURATION
                set this.formtime = UBW_FORMTIME
                set this.casttime = UBW_CASTTIME
                set this.radius = 0
                set this.firefxspeed = UBW_RADIUS / (UBW_FORMTIME / (1 / FPS))
                set this.angle = GetRandomReal(0,360)
                set this.fireangle = 360 / FIRE_COUNT
               
                call IssueImmediateOrder(this.caster, "stop")
                call PauseUnit(this.caster, true)
               
                set this.stage = 1
               
               
                call TimerStart(NewTimerEx(this), FPS, true, function thistype.onPeriodic)
            endmethod  
            private static method onInit takes nothing returns nothing
                call RegisterSpellEffectEvent(ABILITY_ID, function thistype.onEffect)
            endmethod
        endstruct
    endscope
     
     

    Attached Files:

  6. IcemanBo

    IcemanBo

    Joined:
    Sep 6, 2013
    Messages:
    6,178
    Resources:
    22
    Maps:
    3
    Spells:
    11
    Template:
    1
    Tutorials:
    4
    JASS:
    3
    Resources:
    22
    Check if the dummy lib usage works correctly for you.
     
  7. WyrmSlayer

    WyrmSlayer

    Joined:
    Apr 18, 2010
    Messages:
    67
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Game crashes again when i put in these 2 functions

    set this.firefxgroup = CreateGroup()
    set this.ubwgroup = CreateGroup()
     
  8. IcemanBo

    IcemanBo

    Joined:
    Sep 6, 2013
    Messages:
    6,178
    Resources:
    22
    Maps:
    3
    Spells:
    11
    Template:
    1
    Tutorials:
    4
    JASS:
    3
    Resources:
    22
    Read my first post again. : )
     
  9. WyrmSlayer

    WyrmSlayer

    Joined:
    Apr 18, 2010
    Messages:
    67
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Rewrote the entire code, reread the tutorial for dynamic indexing in jass.. heres the result.


    received_393939987937277.gif

    Code (vJASS):


    scope UnlimitedBladeWorks initializer Init
        //===first Vjass spell xD =============================
        //================ USES DYNAMIC INDEXING =============//
        //https://www.hiveworkshop.com/threads/vjass-dynamic-indexing-tutorial.245956/
     
     
        globals
            private timer period = CreateTimer()
            private constant real fps = 1.0 / 32.0
            private integer dindex = -1
        endglobals
     
        /*==================================================
        =======================SETUP========================
        ==================================================*/

        globals
            private integer SPELLID = 'Eubw'
         
            //spell constants
            private real CASTTIME = 0.25
            private real FORMTIME = 1.25
            private real DURATION = 12.0
            private real RADIUS = 1200.0
         
            //spell visuals
         
            private integer FIRESFXCOUNT = 60
            private real SWORDSFXCOUNT = 1.25
            private real SWORDSFXINC = 0.15
            private integer GEARFXCOUNT = 24
            private real FIRESFXSIZE = 1.75
            private real SWORDFXSIZE = 2.00
            private real FIREFXSPIN = 11.0
            private real SWORDFXHEIGHT = -65.0
     
            private string SWORDSFX = "war3mapImported\\EmiyaUbwSword.mdx"
            private string FIRETRAILSFX = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl"
            private string FIRESFX = "war3mapImported\\UbwFire.mdx"
            private string SWORDSFXSPAWN = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
        endglobals
     
     
            //spell visuals continuation
            private function GEARSFX takes nothing returns string
                local integer random
                set random = GetRandomInt(1,2)
                if random == 1 then
                    return "war3mapImported\\Gear2.mdx"
                else
                    return "war3mapImported\\Gear3.mdx"
                endif
            endfunction
     
            private function ANGLEPERFIRE takes integer a returns real
                return 360.0 / a
            endfunction
         
            private function GEARSFXHEIGHT takes real size returns real
                return GetRandomReal(50.0, 150.) + 25.*size
            endfunction
         
            private function GEARSFXSIZE takes nothing returns real
                return GetRandomReal(1.5, 3.)
            endfunction
         
            private function ANGLEPERGEAR takes integer a returns real
                return 360.0 / a
            endfunction
         
            private function FIREFXSPEED  takes real aoe, real formtime returns real
                return aoe / (formtime / fps)
            endfunction
     
     
        /*==================================================
        =====================END SETUP========================
        ==================================================*/

     
            private struct tempDat
                unit caster
                integer stage
                real casttime
                real formtime
                real speed
                real ubwx
                real ubwy
                real duration
                location ubwpoint
                group ubwdummygroup
                real swordcount
                real swordspawnaoe
                group swordgroup
             
                method destroy takes nothing returns nothing
                    //wash leaks
                    if dindex == -1 then
                        call PauseTimer(period)
                    endif
                    call this.deallocate()
                endmethod
            endstruct
         
        globals
            private tempDat array data
        endglobals
     
     
        private function FireSpreadSpin takes group g, location l, real speed returns nothing
            local unit fire
            local location fireloc
            local real angle
            local real x2
            local real y2
            local group copy = CreateGroup()
            call GroupAddGroup(g, copy)
            loop
                set fire = FirstOfGroup(copy)
                exitwhen fire == null
                set fireloc = GetUnitLoc(fire)
                set angle = AngleBetweenPoints(l, fireloc)
                set x2 = GetLocationX(l) + speed*Cos( Deg2Rad(angle + FIREFXSPIN) )
                set y2 = GetLocationY(l) + speed*Sin( Deg2Rad(angle + FIREFXSPIN) )
                call SetUnitX(fire, x2)
                call SetUnitY(fire, y2)
             
                call RemoveLocation(fireloc)
                set fireloc = null
                call GroupRemoveUnit(copy, fire)
                set fire = null
            endloop
            call DestroyGroup(copy)
            set copy = null
        endfunction
     
        private function SFXDestroy takes nothing returns nothing
     
            local unit sfx = GetEnumUnit()
         
            call DestroySFX(sfx)
            call DummyAddRecycleTimer(sfx, 0.7) //recycles dummy
         
            set sfx = null //removing leaks
         
        endfunction
        private function ubwtargets takes nothing returns boolean
            local unit pick = GetFilterUnit()
            local boolean b = true
            if    GetWidgetLife(pick) < 0.405 then
                set b = false
            endif
            return b
        endfunction
     
        private function bordercontrol takes group g, location p, real r, real up, real down returns nothing
        local unit u
        local location t
        local real d
        local real a
        local real x
        local real y
        loop
            set u = FirstOfGroup(g)
            exitwhen u == null
            set t = GetUnitLoc(u)
            set d = DistanceBetweenPoints(p, t)
            set a = Deg2Rad( AngleBetweenPoints(p, t) )
            if d < r then  
                    if d > r - up then
                    set x = GetLocationX(p) + (r - up)* Cos(a)
                    set y = GetLocationY(p) + (r - up)* Sin(a)
                    call SetUnitX(u, x)
                    call SetUnitY(u, y)
                    endif
                 
            else
                    if d < r + down then
                    set x = GetLocationX(p) + (r + down)*Cos(a)
                    set y = GetLocationY(p) + (r + down)*Sin(a)
                    call SetUnitX(u, x)
                    call SetUnitY(u, y)
                    endif
            endif
            call GroupRemoveUnit(g, u)
            call RemoveLocation(t)
            set t = null
            set u = null
         
        endloop
     
        endfunction
     
        private function periodic takes nothing returns nothing
            local tempDat this
            local integer i = 0  //loops through instances
            local integer looper
            local real angle
            local unit dummy
            local real x
            local real y
            local real size
            local group g
         
            loop
                exitwhen i>dindex
                set this = data[i]
             
             
                //spell core
             
                if this.stage == 1 then
                    if this.casttime > 0 then
                        set this.casttime = this.casttime - fps
                        else
                        if GetWidgetLife(this.caster) >= 0.405 then
                         
                            //restoring player control
                            call PauseUnit(this.caster, false                      //
                            call GroupRemoveUnit(CannotMove, this.caster)            //
                            call GroupRemoveUnit(CannotWalk, this.caster)            // For keyboard movement system
                            call GroupRemoveUnit(CannotTurn, this.caster)            //
                            set this.stage = 2  //sets spells stage
                            set this.ubwx = GetUnitX(this.caster) //sets spell loc
                            set this.ubwy = GetUnitY(this.caster) //sets spell loc
                            set this.ubwpoint = GetUnitLoc(this.caster) //sets ubw loc
                         
                            //CREATING FIRE SFX
                            set looper = 0
                            set angle = GetRandomReal(0, 360)
                            loop
                                exitwhen looper >= FIRESFXCOUNT
                                set looper = looper + 1
                                set angle = angle + ANGLEPERFIRE(FIRESFXCOUNT) //sets angle of firesfx
                                set x = this.ubwx + 5 * Cos( Deg2Rad (angle) ) //adds offset, for spinning effect
                                set y = this.ubwy + 5 * Sin( Deg2Rad (angle) )
                             
                                set dummy = GetRecycledDummy(x,y,0.0, angle) //dummy recycler by flux
                                call CreateSFX( dummy, FIRESFX, FIRETRAILSFX) //self made system for sfx
                             
                                call GroupAddUnit(this.ubwdummygroup, dummy) //adds firesfx to group
                                call SetUnitScale(dummy, FIRESFXSIZE, 1, 1)
                         
                            endloop  
                        else
                            set this.stage = 0
                        endif
                    endif  
             
                else
             
                    if this.stage == 2 then
                        if this.formtime > 0 then
                            set this.formtime = this.formtime - fps      
                            set this.swordspawnaoe = this.swordspawnaoe + this.speed
                            call FireSpreadSpin(this.ubwdummygroup,this.ubwpoint,this.swordspawnaoe)   //moves fire and spins
                            set looper = 0
                            set this.swordcount = this.swordcount + SWORDSFXINC   //creating swords, forms as fire boundary expands
                            loop
                                exitwhen looper >= R2I(this.swordcount)
                                set looper = looper + 1
                                set angle = Deg2Rad(GetRandomReal(0, 360))
                                set x = this.ubwx + (this.swordspawnaoe + GetRandomReal(-125, 125) )*Cos(angle)
                                set y = this.ubwy + (this.swordspawnaoe + GetRandomReal(-125, 125) )*Sin(angle)
                             
                                set dummy = GetRecycledDummy(x,y, SWORDFXHEIGHT , Rad2Deg(angle))
                                call CreateSFX(dummy, SWORDSFX, "")
                             
                                call GroupAddUnit(this.swordgroup, dummy)
                                call SetUnitScale(dummy, SWORDFXSIZE, 1, 1)
                                //call SetUnitTimeScale(dummy, 99)
                         
                            endloop
                     
                        else
                            set this.stage = 3
                         
                            //creating Gears
                            set looper = 0
                            set angle = GetRandomReal(0, 360)
                            loop
                                exitwhen looper >= GEARFXCOUNT
                                set looper = looper + 1
                                set angle = angle + ANGLEPERGEAR(GEARFXCOUNT)
                                set x = this.ubwx + RADIUS * Cos ( Deg2Rad (angle) )
                                set y = this.ubwy + RADIUS * Sin ( Deg2Rad (angle) )
                             
                                set size = GEARSFXSIZE()
                             
                                set dummy = GetRecycledDummy(x,y, GEARSFXHEIGHT(size) , angle) //uses DummyRecycler by flux
                                call CreateSFX(dummy, GEARSFX() , "") //self made sfx system
                                call SetUnitScale(dummy, size, 1, 1 )
                                call SetUnitTimeScale(dummy, 0.5)
                                call GroupAddUnit(this.swordgroup, dummy)
                            endloop
                            //add sword rain ability here
                        endif
                    else
                        if this.stage == 3 then
                            if this.duration > 0 and GetWidgetLife(this.caster) >= 0.405 then
                                set this.duration = this.duration - fps
                                set g = CreateGroup()                                                                //creates border group
                                call GroupEnumUnitsInRange(g, this.ubwx, this.ubwy, RADIUS, function ubwtargets)  //traps units inside boundary field
                                call bordercontrol(g, this.ubwpoint, RADIUS, 115, 75)
                                call DestroyGroup(g)
                                set g = null
                            else
                                set this.stage = 0
                            endif
                        endif
                    endif
                    if this.stage == 0 then
                        //Ending Spell
                        call ForGroup(this.ubwdummygroup, function SFXDestroy)
                        call ForGroup(this.swordgroup, function SFXDestroy)
                        call RemoveLocation(this.ubwpoint)
                        set this.ubwpoint = null
                        set this.caster = null
                        call DestroyGroup(this.ubwdummygroup)
                        set this.ubwdummygroup = null
                        call DestroyGroup(this.swordgroup)
                        set this.swordgroup = null
                        //Destroying Instance
                        set data[i] = data[dindex]
                        set i = i - 1
                        set dindex = dindex - 1
                        call this.destroy()
                    endif
                endif
            set i = i + 1
            endloop
        endfunction
     
        private function Cond takes nothing returns boolean
            local tempDat this
            if GetSpellAbilityId() == SPELLID then
                //instantiating
                set this = tempDat.create()
                //setup variables
                set this.caster = GetTriggerUnit()
                set this.casttime = CASTTIME
                set this.formtime = FORMTIME
                set this.duration = DURATION
                set this.stage = 1
                set this.speed = FIREFXSPEED( RADIUS, FORMTIME )
                set this.swordcount = SWORDSFXCOUNT
                set this.swordspawnaoe = 0
                //spell start
                call AttachSoundUnit(this.caster, "war3mapImported\\EMY_NP.mp3", 127, 9, 2000, false, true, 1500, 3000)
                call StopSound( GetLastPlayedSound(), true, true)
                call PauseUnit(this.caster, true)
                call IssueImmediateOrder(this.caster, "stop")
                call SetUnitAnimation(this.caster, "Spell Three")
                //for movement trigger
                call GroupAddUnit(CannotMove, this.caster)          //
                call GroupAddUnit(CannotWalk, this.caster)         // For keyboard movement
                call GroupAddUnit(CannotTurn, this.caster)         //
                call GroupRemoveUnit(IsWalking, this.caster)       //
                //creating groups
                set this.ubwdummygroup = CreateGroup()
                set this.swordgroup = CreateGroup()
                //increasing Loop
                set dindex = dindex + 1
                set data[dindex] = this
                if dindex == 0 then
                    call TimerStart(period, fps, true, function periodic)
                endif
            endif
            return false
        endfunction
     
        private function Init takes nothing returns nothing
            local trigger t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(t, Condition( function Cond ))
            set t = null
         
        endfunction
         
         
    endscope

     
     
    Last edited: Sep 16, 2019
  10. Pyrogasm

    Pyrogasm

    Joined:
    Feb 27, 2007
    Messages:
    2,901
    Resources:
    1
    Spells:
    1
    Resources:
    1
    So does that mean it works? What? You can and should remove the dependency on locations in lieu of using coordinates directly; things like DistanceBetweenPoints (and other BJ functions (things that show up in red)) are crutches and you should learn not to use them (google "distance between two points" or read the function to figure out how to replace it, for example). IMO TriggerRegister... is fine because it's just an init thing and it saves you the hassle of typing it all out.
    Code (vJASS):
    call AttachSoundUnit(this.caster, "war3mapImported\\EMY_NP.mp3", 127, 9, 2000, false, true, 1500, 3000)
    call StopSound( GetLastPlayedSound(), true, true)

    Unless the AttachSoundUnit function sets the bj_lastPlayedSound variable, that StopSound call will not function. Where is that function declared?
     
  11. WyrmSlayer

    WyrmSlayer

    Joined:
    Apr 18, 2010
    Messages:
    67
    Resources:
    1
    Spells:
    1
    Resources:
    1

    Yes the spell works now.. okay ill read up on the angle and distance between points

    That attachsoundunit function was a snipet
    Heres the source:

    [Solved] - 3D Sound Attachment
     
  12. Pyrogasm

    Pyrogasm

    Joined:
    Feb 27, 2007
    Messages:
    2,901
    Resources:
    1
    Spells:
    1
    Resources:
    1
    You need to use udg_lastCreatedSound instead of GetLastPlayedSound(), as per the function.
     
  13. WyrmSlayer

    WyrmSlayer

    Joined:
    Apr 18, 2010
    Messages:
    67
    Resources:
    1
    Spells:
    1
    Resources:
    1


    UPDATE:
    -Used this to get the distance and the angle between 2 points:

    Code (vJASS):

    set x2 = GetUnitX(u)
            set y2 = GetUnitY(u)
            set dx = x2 - x
            set dy = y2 - y
            set d = SquareRoot( dx*dx + dy*dy )
            set a = Atan2(dy, dx)
     


    -Changed the 3D Sound attachment variable from udg_lastCreatedSound to AttachedSound... (just wanted to remove the udg_variable, so i used a global sound, inserted in the snippet's library)

    -Created 1 group for all, 1 group used for copying for all the instances of the spell
    Code (vJASS):

            private group all = CreateGroup()
            private group copy = CreateGroup()
     



    Is there a function that can be used as a substitute for this?
    Code (vJASS):

            call GroupAddGroup(g, copy)
     


    Code (vJASS):

    scope UnlimitedBladeWorks initializer Init
        //===first Vjass spell xD =============================
        //================ USES DYNAMIC INDEXING =============//
        //https://www.hiveworkshop.com/threads/vjass-dynamic-indexing-tutorial.245956/
       
       
        globals
            private timer period = CreateTimer()
            private constant real fps = 1.0 / 32.0
            private integer dindex = -1
            private group all = CreateGroup()
            private group copy = CreateGroup()
        endglobals
       
        /*==================================================
        =======================SETUP========================
        ==================================================*/

        globals
            private integer SPELLID = 'Eubw'
           
            //spell constants
            private real CASTTIME = 0.25
            private real FORMTIME = 1.25
            private real DURATION = 12.0
            private real RADIUS = 1200.0
           
            //spell visuals
           
            private integer FIRESFXCOUNT = 55
            private real SWORDSFXCOUNT = 1.25
            private real SWORDSFXINC = 0.12
            private integer GEARFXCOUNT = 24
            private real FIRESFXSIZE = 1.80
            private real SWORDFXSIZE = 2.00
            private real FIREFXSPIN = 7.5
            private real SWORDFXHEIGHT = -65.0
       
            private string SWORDSFX = "war3mapImported\\EmiyaUbwSword.mdx"
            private string FIRETRAILSFX = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl"
            private string FIRESFX = "war3mapImported\\UbwFire.mdx"
        endglobals
       
       
            //spell visuals continuation
            private function GEARSFX takes nothing returns string
                local integer random
                set random = GetRandomInt(1,2)
                if random == 1 then
                    return "war3mapImported\\Gear2.mdx"
                else
                    return "war3mapImported\\Gear3.mdx"
                endif
            endfunction
       
            private function ANGLEPERFIRE takes integer a returns real
                return 360.0 / a
            endfunction
           
            private function GEARSFXHEIGHT takes real size returns real
                return GetRandomReal(50.0, 150.) + 25.*size
            endfunction
           
            private function GEARSFXSIZE takes nothing returns real
                return GetRandomReal(1.5, 3.)
            endfunction
           
            private function ANGLEPERGEAR takes integer a returns real
                return 360.0 / a
            endfunction
           
            private function FIREFXSPEED  takes real aoe, real formtime returns real
                return aoe / (formtime / fps)
            endfunction
       
       
        /*==================================================
        =====================END SETUP========================
        ==================================================*/

       
            private struct tempDat
                unit caster
                integer stage
                real casttime
                real formtime
                real speed
                real ubwx
                real ubwy
                real duration
                group ubwdummygroup
                real swordcount
                real swordspawnaoe
                group swordgroup
               
                method destroy takes nothing returns nothing
                    //wash leaks
                    if dindex == -1 then
                        call PauseTimer(period)
                    endif
                    call this.deallocate()
                endmethod
            endstruct
           
        globals
            private tempDat array data
        endglobals
       
       
        private function FireSpreadSpin takes group g, real x, real y, real speed returns nothing
            local unit fire
            local real angle
            local real x2
            local real y2
            local real x3
            local real y3
           
            call GroupClear(copy)
            call GroupAddGroup(g, copy)
            loop
                set fire = FirstOfGroup(copy)
                exitwhen fire == null
                set x2 = GetUnitX(fire)
                set y2 = GetUnitY(fire)
                set angle = (Atan2(y2-y, x2-x)) + Deg2Rad (FIREFXSPIN)
                set x2 = x + speed*Cos(angle)
                set y2 = y + speed*Sin(angle)
                call SetUnitX(fire, x2)
                call SetUnitY(fire, y2)
               
                call GroupRemoveUnit(copy, fire)
                set fire = null
            endloop
        endfunction
       
        private function SFXDestroy takes nothing returns nothing
       
            local unit sfx = GetEnumUnit()
           
            call DestroySFX(sfx)
            call DummyAddRecycleTimer(sfx, 0.7) //recycles dummy
           
            set sfx = null //removing leaks
           
        endfunction
        private function ubwtargets takes nothing returns boolean
            local unit pick = GetFilterUnit()
            local boolean b = true
            if    GetWidgetLife(pick) < 0.405 then
                set b = false
            endif
            return b
        endfunction
       
        private function bordercontrol takes group g, real x, real y, real r, real up, real down returns nothing
        local unit u
        local real d
        local real a
        local real x2
        local real y2
        local real angle
        local real dx
        local real dy
        loop
            set u = FirstOfGroup(g)
            exitwhen u == null
            set x2 = GetUnitX(u)
            set y2 = GetUnitY(u)
            set dx = x2 - x
            set dy = y2 - y
            set d = SquareRoot( dx*dx + dy*dy )
            set a = Atan2(dy, dx)
            if d < r then  
                    if d > r - up then
                    set x2 = x + (r - up)* Cos(a)
                    set y2 = y + (r - up)* Sin(a)
                    call SetUnitX(u, x2)
                    call SetUnitY(u, y2)
                    endif
                   
            else
                    if d < r + down then
                    set x2 = x + (r + down)*Cos(a)
                    set y2 = y + (r + down)*Sin(a)
                    call SetUnitX(u, x2)
                    call SetUnitY(u, y2)
                    endif
            endif
            call GroupRemoveUnit(g, u)
            set u = null
           
        endloop
       
        endfunction
       
        private function periodic takes nothing returns nothing
            local tempDat this
            local integer i = 0  //loops through instances
            local integer looper
            local real angle
            local unit dummy
            local real x
            local real y
            local real size
           
            loop
                exitwhen i>dindex
                set this = data[i]
               
               
                //spell core
               
                if this.stage == 1 then
                    if this.casttime > 0 then
                        set this.casttime = this.casttime - fps
                        else
                        if GetWidgetLife(this.caster) >= 0.405 then
                            //restoring player control
                            call PauseUnit(this.caster, false)                     //
                            call GroupRemoveUnit(CannotMove, this.caster)            //
                            call GroupRemoveUnit(CannotWalk, this.caster)            // For keyboard movement system
                            call GroupRemoveUnit(CannotTurn, this.caster)            //
                            set this.stage = 2  //sets spells stage
                            set this.ubwx = GetUnitX(this.caster) //sets spell loc
                            set this.ubwy = GetUnitY(this.caster) //sets spell loc                  
                            //CREATING FIRE SFX
                            set looper = 0
                            set angle = GetRandomReal(0, 360)
                            loop
                                exitwhen looper >= FIRESFXCOUNT
                                set looper = looper + 1
                                set angle = angle + ANGLEPERFIRE(FIRESFXCOUNT) //sets angle of firesfx
                                set x = this.ubwx + 5 * Cos( Deg2Rad (angle) ) //adds offset, for spinning effect
                                set y = this.ubwy + 5 * Sin( Deg2Rad (angle) )
                                set dummy = GetRecycledDummy(x,y,0.0, angle) //dummy recycler by flux
                                call CreateSFX( dummy, FIRESFX, FIRETRAILSFX) //self made system for sfx
                                call GroupAddUnit(this.ubwdummygroup, dummy) //adds firesfx to group
                                call SetUnitScale(dummy, FIRESFXSIZE, 1, 1)
                           
                            endloop  
                        else
                            set this.stage = 0
                        endif
                    endif  
               
                else
               
                    if this.stage == 2 then
                        if this.formtime > 0 then
                            set this.formtime = this.formtime - fps      
                            set this.swordspawnaoe = this.swordspawnaoe + this.speed
                            call FireSpreadSpin(this.ubwdummygroup,this.ubwx, this.ubwy,this.swordspawnaoe)   //moves fire and spins
                            set looper = 0
                            set this.swordcount = this.swordcount + SWORDSFXINC   //creating swords, forms as fire boundary expands
                            loop
                                exitwhen looper >= R2I(this.swordcount)
                                set looper = looper + 1
                                set angle = Deg2Rad(GetRandomReal(0, 360))
                                set x = this.ubwx + (this.swordspawnaoe + GetRandomReal(-125, -25) )*Cos(angle)
                                set y = this.ubwy + (this.swordspawnaoe + GetRandomReal(-125, -25) )*Sin(angle)
                               
                                set dummy = GetRecycledDummy(x,y, SWORDFXHEIGHT , Rad2Deg(angle))
                                call CreateSFX(dummy, SWORDSFX, "")
                               
                                call GroupAddUnit(this.swordgroup, dummy)
                                call SetUnitScale(dummy, SWORDFXSIZE, 1, 1)
                                //call SetUnitTimeScale(dummy, 99)
                           
                            endloop
                       
                        else
                            set this.stage = 3
                            //Add UBW ABILITIES HERE
                            //creating Gears
                            set looper = 0
                            set angle = GetRandomReal(0, 360)
                            loop
                                exitwhen looper >= GEARFXCOUNT
                                set looper = looper + 1
                                set angle = angle + ANGLEPERGEAR(GEARFXCOUNT)
                                set x = this.ubwx + RADIUS * Cos ( Deg2Rad (angle) )
                                set y = this.ubwy + RADIUS * Sin ( Deg2Rad (angle) )
                               
                                set size = GEARSFXSIZE()
                               
                                set dummy = GetRecycledDummy(x,y, GEARSFXHEIGHT(size) , angle) //uses DummyRecycler by flux
                                call CreateSFX(dummy, GEARSFX() , "") //self made sfx system
                                call SetUnitScale(dummy, size, 1, 1 )
                                call SetUnitTimeScale(dummy, 0.5)
                                call GroupAddUnit(this.swordgroup, dummy)
                            endloop
                       
                        endif
                    else
                        if this.stage == 3 then
                            if this.duration > 0 and GetWidgetLife(this.caster) >= 0.405 then
                                set this.duration = this.duration - fps                                                                //creates border group
                                call GroupEnumUnitsInRange(all, this.ubwx, this.ubwy, RADIUS, function ubwtargets)  //traps units inside boundary field
                                call bordercontrol(all, this.ubwx, this.ubwy, RADIUS, 115, 75)
                            else
                                set this.stage = 0
                            endif
                        endif
                    endif
                    if this.stage == 0 then
                        //Ending Spell
                        call ForGroup(this.ubwdummygroup, function SFXDestroy)
                        call ForGroup(this.swordgroup, function SFXDestroy)
                        set this.caster = null
                        call DestroyGroup(this.ubwdummygroup)
                        set this.ubwdummygroup = null
                        call DestroyGroup(this.swordgroup)
                        set this.swordgroup = null
                        //Destroying Instance
                        set data[i] = data[dindex]
                        set i = i - 1
                        set dindex = dindex - 1
                        call this.destroy()
                    endif
                endif
            set i = i + 1
            endloop
        endfunction
       
        private function Cond takes nothing returns boolean
            local tempDat this
            if GetSpellAbilityId() == SPELLID then
                //instantiating
                set this = tempDat.create()
                //setup variables
                set this.caster = GetTriggerUnit()
                set this.casttime = CASTTIME
                set this.formtime = FORMTIME
                set this.duration = DURATION
                set this.stage = 1
                set this.speed = FIREFXSPEED( RADIUS, FORMTIME )
                set this.swordcount = SWORDSFXCOUNT
                set this.swordspawnaoe = 0
                //spell start
                call AttachSoundUnit(this.caster, "war3mapImported\\EMY_NP.mp3", 127, 9, 2000, false, true, 1500, 3000)
                call KillSoundWhenDone( AttachedSound)
                call PauseUnit(this.caster, true)
                call IssueImmediateOrder(this.caster, "stop")
                call SetUnitAnimation(this.caster, "Spell Three")
                //for movement trigger
                call GroupAddUnit(CannotMove, this.caster)          //
                call GroupAddUnit(CannotWalk, this.caster)         // For keyboard movement
                call GroupAddUnit(CannotTurn, this.caster)         //
                call GroupRemoveUnit(IsWalking, this.caster)       //
                //creating groups
                set this.ubwdummygroup = CreateGroup()
                set this.swordgroup = CreateGroup()
                //increasing Loop
                set dindex = dindex + 1
                set data[dindex] = this
                if dindex == 0 then
                    call TimerStart(period, fps, true, function periodic)
                endif
            endif
            return false
        endfunction
       
        private function Init takes nothing returns nothing
            local trigger t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(t, Condition( function Cond ))
            set t = null
           
        endfunction
           
           
    endscope
     
     
    Last edited: Sep 20, 2019