Spell Annihilate

XeNiM666

I lurk for pizza
Reaction score
138
Annahilate
by XeNiM666

GUI/JASS/vJASS: vJASS
MUI/MPI: MUI
Leakless: Yes
Lagless: Very minor and small lag at first cast
Requirements: Cohadar's Timer Ticker System ( TT system )

Description:
Creates illusions of one's self around a targeted unit. Then after a short while, the illusions will start to dash to the targeted unit, dealing damage according to the caster's Agility. The illusions will also damage units in the way. After all the illusions finished their task, the caster will now dash to the target, dealing higher amount of damage, still according to the caster's Agility.

Screenshot:
Annahilate.jpg


Code:
Please critique my coding. I want to know how to make it better
JASS:
scope Annahilate

    globals
        // RAW CODE OF THE ANNAHILATE SPELL
        private constant integer ANNAHILATE_ID = 'A000'
        
        // RAW CODE OF THE ANNAHILATE DUMMY 
        private constant integer ANNAHILATE_DUMMY_ID = 'h000'
        // EFFECT CREATED UPON THE CREATION OF THE DUMMY
        private constant string ANNAHILATE_DUMMY_EFFECT_UPON_CREATION = "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl"
        // ANIMATION PLAYED WHILE THE DUMMY IS CHARGING
        private constant string ANNAHILATE_DUMMY_ANIMATION = "attack"
        
        // EFFECT ATTACHED TO THE DUMMY WHILE CHARGING
        private constant string ANNAHILATE_DUMMY_EFFECT = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl"
        // THE ATTACHMENT POINT OF THE EFFECT ABOVE
        private constant string ANNAHILATE_DUMMY_EFFECT_ATTACH = "hand,right"
        
        // EFFECT CREATED WHEN THE DUMMY REACHES THE TARGET
        private constant string ANNAHILATE_DAMAGE_EFFECT = "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
        // THE ATTACHMENT POINT OF THE EFFECT CREATED WHEN THE DUMMY REACHES THE TARGET
        private constant string ANNAHILATE_DAMAGE_EFFECT_ATTACH = "chest"
        
        // THE EFFECT CREATED WHEN THE CASTER TELEPORTS BEHIND THE TARGET
        private constant string ANNAHILATE_TELEPORT_EFFECT = "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl"
        
        // THE COLOR OF THE TEXTTAG CREATED TO SHOW HOW MUCH DAMAGE IS DEALT
        private constant string TEXTTAG_COLOR = "|CFFB8860B" // DARK GOLDEN ROD //
        
        // THE NUMBER OF ILLUSIONS PER CIRCLE
        // SO THE TOTAL NUMBER OF ILLUSIONS IS ( NUMBER_OF_ILLUSION_PER_CIRCLE * Number_of_Circles )
        private constant integer NUMBER_OF_ILLUSION_PER_CIRCLE = 10
        
        // THE STARTING DELAY OF THE SPELL
        private constant real DELAY_OF_SPELL = 0.80
        // HOW FAST THE DUMMIES MOVE
        private constant real DISTANCE_PER_SECOND = 1500.00
        // THE AREA OF EFFECT OF THE DUMMIES TO HIT ANYONE
        private constant real AREA_OF_EFFECT = 75.00
        // THE INTERVAL IN WHICH THE DUMMIES START TO CHARGE THE TARGET
        private constant real INTERVAL_PER_ILLUSION_TO_CHARGE = 0.075
        
        // MAXIMUM ILLUSIONS POSSIBLE
        private constant integer MAXIMUM_ILLUSIONS = 250
    endglobals

    private function Number_of_Circles takes integer lvl returns integer
        return lvl + 1 // NUMBER OF CIRCLE OF ILLUSIONS
    endfunction
    
    private function Multiplier takes integer lvl returns real
        return 0.40 + ( lvl * 0.20 ) // DAMAGE MULTIPLIER OF AGILITY
    endfunction
    
        //*************************************************************//
       //*************************************************************//
      //                      SPELL STARTS HERE                      //
     //*************************************************************//
    //*************************************************************//

    // A LITTLE FUNCTION TO REDUCE LEAKS
    private function True takes nothing returns boolean
        return true
    endfunction
    
    private struct Annahilate
        unit caster                                 // STORES THE CASTER
        real cx
        real cy
        unit target                                 // STORES THE TARGET
        real tx
        real ty
        integer lvl                                 // STORES THE LEVEL OF THE CASTED ABILITY
        real dmg                                    // STORES THE DAMAGE OF THE ABILITY                                                              
        integer num                             = 0 // STORES HOW MANY THE ILLUSIONS ARE
        unit array dummy [ MAXIMUM_ILLUSIONS ]      // STORES THE NEEDED DATA FOR THE DUMMIES
        effect array ef [ MAXIMUM_ILLUSIONS ]
        real array cos[ MAXIMUM_ILLUSIONS ]
        real array sin[ MAXIMUM_ILLUSIONS ]
        real array r [ MAXIMUM_ILLUSIONS ]
        integer array trans [ MAXIMUM_ILLUSIONS ]
        group array hit [ MAXIMUM_ILLUSIONS ]
        group dummies                           = CreateGroup() // STORES THE DUMMIES
        group moving                            = CreateGroup() // STORES THE MOVING DUMMIES
        group fading                            = CreateGroup() // STORES THE FADING DUMMIES
        real int                                = 0.00          // STORES THE INTERVAL OF THE DUMMIES
        
        // SELF EXPLAINABLE
        // THE CONDITIONS FOR DEALING DAMAGE TO THE UNITS
        static method Group_Conditions takes nothing returns boolean
            local unit u = GetFilterUnit()
            local boolean b1 = GetWidgetLife( u ) > 0.408
            local boolean b2 = IsUnitType( u, UNIT_TYPE_STRUCTURE ) != true
            local boolean b3 = IsUnitType( u, UNIT_TYPE_FLYING ) != true
            set u = null
            return b1 and b2 and b3
        endmethod
        
        // THE CASTER WILL DASH TO THE TARGET AT GREATER SPEED
        static method Attack takes nothing returns boolean
            local Annahilate a = TT_GetData()
            
            local boolean flag = false
            
            local real angle
            local real dis
            local real dx
            local real dy
            
            local texttag tt
            local real damage
            
            local group g = CreateGroup()
            local unit u = null
            local real x
            local real y
            
            local integer i = a.num + 1
            
            set a.cx = GetUnitX( a.caster )
            set a.cy = GetUnitY( a.caster )
            
            set angle = bj_RADTODEG * Atan2( a.ty - a.cy, a.tx - a.cx )
            set a.cos[ i ] = Cos( angle * bj_DEGTORAD )
            set a.sin[ i ] = Sin( angle * bj_DEGTORAD )
            
            set x = a.cx + a.r[ i ] * a.cos[ i ]
            set y = a.cy + a.r[ i ] * a.sin[ i ]
            
            set dx = a.tx - x
            set dy = a.ty - y
            set dis = SquareRoot( dx * dx + dy * dy )
            
            call SetUnitPosition( a.caster, x, y )
            
            // DAMAGE UNITS IN THE WAY
                        
            call GroupEnumUnitsInRange( g, x, y, AREA_OF_EFFECT, Condition( function Annahilate.Group_Conditions ) )
                    
            loop
                set u = FirstOfGroup( g )
                exitwhen u == null
                            
                if u != a.target and IsUnitEnemy( u, GetOwningPlayer( a.caster ) ) == true and IsUnitInGroup( u, a.hit[ i ] ) == false then
                    set x = GetUnitX( u )
                    set y = GetUnitY( u )
                    set damage = GetRandomReal( a.dmg * 0.75, a.dmg * 1.25 )
                        
                    call UnitDamageTarget( a.caster, u, damage, true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
                    call DestroyEffect( AddSpecialEffectTarget( ANNAHILATE_DAMAGE_EFFECT, u, ANNAHILATE_DAMAGE_EFFECT_ATTACH ) )
                            
                    set tt = CreateTextTag()
                    call SetTextTagText( tt, TEXTTAG_COLOR + I2S( R2I( damage ) ), 0.023 )
                    call SetTextTagVelocity( tt, 0.06102 * Cos( 90.00 * bj_DEGTORAD ), 0.06102 * Sin( 90.00 * bj_DEGTORAD ) )
                    call SetTextTagPos( tt, x, y, 0.00 )
                    call SetTextTagPermanent( tt, false )
                    call SetTextTagLifespan( tt, 2.50 )
                    call SetTextTagFadepoint( tt, 1.00 )
                    set tt = null
                            
                    call GroupAddUnit( a.hit[ i ], u )
                endif
                            
                call GroupRemoveUnit( g, u )
            
            endloop
            
            // IF CASTER REACHES TARGET, THEN DEAL DAMAGE
        
            if dis <= AREA_OF_EFFECT and IsUnitInGroup( a.target, a.hit[ i ] ) == false then
                set damage = GetRandomReal( a.dmg * 0.75, a.dmg * 1.25 ) * 2.00
                                    
                call UnitDamageTarget( a.caster, a.target, damage, true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
                call DestroyEffect( AddSpecialEffectTarget( ANNAHILATE_DAMAGE_EFFECT, a.target, ANNAHILATE_DAMAGE_EFFECT_ATTACH ) )
                                
                set tt = CreateTextTag()
                call SetTextTagText( tt, TEXTTAG_COLOR + I2S( R2I( damage ) ), 0.023 )
                call SetTextTagVelocity( tt, 0.06102 * Cos( 90.00 * bj_DEGTORAD ), 0.06102 * Sin( 90.00 * bj_DEGTORAD ) )
                call SetTextTagPos( tt, x, y, 0.00 )
                call SetTextTagPermanent( tt, false )
                call SetTextTagLifespan( tt, 2.50 )
                call SetTextTagFadepoint( tt, 1.00 )
                set tt = null
                                
                call GroupAddUnit( a.hit[ i ], a.target )
                call GroupAddUnit( a.fading, a.caster )
            endif
            
            // FADES THE UNIT
            
            if IsUnitInGroup( a.caster, a.fading ) == true then
                        
                if a.trans[ i ] > 0 then
                    set a.r[ i ] = a.r[ i ] / 2.00
                    set a.trans[ i ] = a.trans[ i ] - 20
                        
                    call SetUnitVertexColor( a.caster, 255, 255, 255, a.trans[ i ] )
                else
                    // THIS PART OF THE CODE IS LIKE THE onDestroy METHOD
                    call DestroyEffect( a.ef[ a.num + 1 ] )
                    set a.ef[ a.num + 1 ] = null
                    
                    set x = a.tx + 100.00 * Cos( ( GetUnitFacing( a.target ) - 180.00 ) * bj_DEGTORAD )
                    set y = a.ty + 100.00 * Sin( ( GetUnitFacing( a.target ) - 180.00 ) * bj_DEGTORAD )
                    
                    call SetUnitVertexColor( a.caster, 255, 255, 255, 255 )
                    call DestroyEffect( AddSpecialEffect( ANNAHILATE_TELEPORT_EFFECT, x, y ) )
                    call SetUnitPosition( a.caster, x, y )
                    
                    call PauseUnit( a.caster, false )
                    call PauseUnit( a.target, false )
                    
                    call SetUnitPathing( a.caster, true )
                    call SetUnitInvulnerable( a.caster, false )
                    
                    set a.caster = null
                    set a.target = null
                
                    set i = 0
                
                    loop
                        set i = i + 1
                    
                        call GroupClear( a.hit[ i ] )
                        call DestroyGroup( a.hit[ i ] )
                        set a.hit[ i ] = null
                    
                        exitwhen i >= a.num
                    endloop
                
                    call GroupClear( a.dummies )
                    call GroupClear( a.moving )
                    call GroupClear( a.fading )
                    call DestroyGroup( a.dummies )
                    call DestroyGroup( a.moving )
                    call DestroyGroup( a.fading )
                    set a.dummies = null
                    set a.moving = null
                    set a.fading = null
                
                    set flag = true
                
                    // END OF onDestroy METHOD
                endif
                        
            endif
            
            call DestroyGroup( g )
            set g = null
            set u = null
                        
            return flag
        endmethod
        
        static method Move takes nothing returns boolean
            local Annahilate a = TT_GetData()
            
            local boolean flag = false
            
            local group g = CreateGroup()
            local unit u = null
            local integer i = 0
            
            local texttag tt
            local real damage
            
            local real angle
            local real dis
            local real x
            local real y
            local real dx
            local real dy
            local real nx
            local real ny
            
            set a.tx = GetUnitX( a.target )
            set a.ty = GetUnitY( a.target )
            
            // PICKS ANOTHER DUMMY TO CHARGE
            if a.int >= INTERVAL_PER_ILLUSION_TO_CHARGE then
                set u = GroupPickRandomUnit( a.dummies )
                call SetUnitAnimation( u, ANNAHILATE_DUMMY_ANIMATION )
                call SetUnitTimeScale( u, 0.50 )
                
                call GroupAddUnit( a.moving, u )
                call GroupRemoveUnit( a.dummies, u )

                set a.int = 0.00
            else
                set a.int = a.int + TT_PERIOD
            endif
            
            // IF THE TARGET IS ALIVE            
            if GetUnitState( a.target, UNIT_STATE_LIFE ) > 0.408 then

                loop
                    set i = i + 1
                    
                    if a.dummy[ i ] != null then
                    
                        if IsUnitInGroup( a.dummy[ i ], a.moving ) == true then
                        
                            // MOVE THE UNIT
                            
                            set x = GetUnitX( a.dummy[ i ] )
                            set y = GetUnitY( a.dummy[ i ] )
                            
                            set nx = x + a.r[ i ] * a.cos[ i ]
                            set ny = y + a.r[ i ] * a.sin[ i ]
                            
                            set dx = a.tx - nx
                            set dy = a.ty - ny
                            set dis = SquareRoot( dx * dx + dy * dy )
                            
                            call SetUnitPosition( a.dummy[ i ], nx, ny )
                            
                            // DAMAGE UNITS IN THE WAY
                            
                            call GroupEnumUnitsInRange( g, nx, ny, AREA_OF_EFFECT, Condition( function Annahilate.Group_Conditions ) )
                        
                            loop
                                set u = FirstOfGroup( g )
                                exitwhen u == null
                                
                                if u != a.target and IsUnitEnemy( u, GetOwningPlayer( a.caster ) ) == true and IsUnitInGroup( u, a.hit[ i ] ) == false then
                                    set x = GetUnitX( u )
                                    set y = GetUnitY( u )
                                    set damage = GetRandomReal( a.dmg * 0.75, a.dmg * 1.25 ) * 0.70
                                        
                                    call UnitDamageTarget( a.caster, u, damage, true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
                                    call DestroyEffect( AddSpecialEffectTarget( ANNAHILATE_DAMAGE_EFFECT, u, ANNAHILATE_DAMAGE_EFFECT_ATTACH ) )
                                    
                                    set tt = CreateTextTag()
                                    call SetTextTagText( tt, TEXTTAG_COLOR + I2S( R2I( damage ) ), 0.023 )
                                    call SetTextTagVelocity( tt, 0.06102 * Cos( 90.00 * bj_DEGTORAD ), 0.06102 * Sin( 90.00 * bj_DEGTORAD ) )
                                    call SetTextTagPos( tt, x, y, 0.00 )
                                    call SetTextTagPermanent( tt, false )
                                    call SetTextTagLifespan( tt, 2.50 )
                                    call SetTextTagFadepoint( tt, 1.00 )
                                    set tt = null
                                    
                                    call GroupAddUnit( a.hit[ i ], u )
                                endif
                                
                                call GroupRemoveUnit( g, u )
                            endloop
                            
                            // IF UNIT IS WITHIN RANGE OF THE TARGET, DEAL DAMAGE
                                
                            if dis <= AREA_OF_EFFECT and IsUnitInGroup( a.target, a.hit[ i ] ) == false then
                                set damage = GetRandomReal( a.dmg * 0.75, a.dmg * 1.25 )
                                
                                call UnitDamageTarget( a.caster, a.target, damage, true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
                                call DestroyEffect( AddSpecialEffectTarget( ANNAHILATE_DAMAGE_EFFECT, a.target, ANNAHILATE_DAMAGE_EFFECT_ATTACH ) )
                                
                                set tt = CreateTextTag()
                                call SetTextTagText( tt, TEXTTAG_COLOR + I2S( R2I( damage ) ), 0.023 )
                                call SetTextTagVelocity( tt, 0.06102 * Cos( 90.00 * bj_DEGTORAD ), 0.06102 * Sin( 90.00 * bj_DEGTORAD ) )
                                call SetTextTagPos( tt, x, y, 0.00 )
                                call SetTextTagPermanent( tt, false )
                                call SetTextTagLifespan( tt, 2.50 )
                                call SetTextTagFadepoint( tt, 1.00 )
                                set tt = null
                                
                                call GroupAddUnit( a.hit[ i ], a.target )                    
                                call GroupAddUnit( a.fading, a.dummy[ i ] )
                                
                                call SetUnitTimeScale( a.dummy[ i ], 1.00 )
                                set a.r[ i ] = a.r[ i ] / 2.00
                            endif
                                                
                        endif
                        
                        // FADES THE UNIT WHEN IT REACHES THE TARGET
                        
                        if IsUnitInGroup( a.dummy[ i ], a.fading ) == true then
                            
                            if a.trans[ i ] > 0 then
                                set a.trans[ i ] = a.trans[ i ] - 3
                            
                                call SetUnitVertexColor( a.dummy[ i ], 255, 255, 255, a.trans[ i ] )
                            else
                                call DestroyEffect( a.ef[ i ] )
                                set a.ef[ i ] = null
                                call RemoveUnit( a.dummy[ i ] )
                                set a.dummy[ i ] = null
                            endif
                            
                        endif
                        
                    endif
                    
                    exitwhen i >= a.num
                    
                endloop
                
            // IF THE TARGET IS DEAD
            else
                
                loop
                    set i = i + 1
                    
                    call GroupRemoveUnit( a.moving, a.dummy[ i ] )
                    
                    if a.ef[ i ] != null then
                        call DestroyEffect( a.ef[ i ] )
                        set a.ef[ i ] = null
                    endif
                    
                    if a.trans[ i ] > 0 then
                        set a.trans[ i ] = a.trans[ i ] - 3
                            
                        call SetUnitVertexColor( a.dummy[ i ], 255, 255, 255, a.trans[ i ] )
                    else
                        call RemoveUnit( a.dummy[ i ] )
                        set a.dummy[ i ] = null
                    endif
                
                    exitwhen i >= a.num
                endloop
                
            endif
            
            // CHECKS WHETHER ALL THE DUMMIES HAS DONE ITS PURPOSE
            if CountUnitsInGroup( a.dummies ) <= 0 and CountUnitsInGroup( a.moving ) <= 0 and CountUnitsInGroup( a.fading ) <= 0 and GetUnitState( a.target, UNIT_STATE_LIFE ) > 0.408 then
                call SetUnitAnimation( a.caster, ANNAHILATE_DUMMY_ANIMATION )
                
                set a.ef[ a.num + 1 ] = AddSpecialEffectTarget( ANNAHILATE_DUMMY_EFFECT, a.caster, ANNAHILATE_DUMMY_EFFECT_ATTACH )
                call TT_Start( function Annahilate.Attack, a )
                
                set flag = true
            elseif CountUnitsInGroup( a.dummies ) <= 0 and CountUnitsInGroup( a.moving ) <= 0 and CountUnitsInGroup( a.fading ) <= 0 and GetUnitState( a.target, UNIT_STATE_LIFE ) <= 0.408 then
                // THIS PART OF THE CODE IS LIKE THE onDestroy METHOD
                    
                set x = a.tx + 100.00 * Cos( ( GetUnitFacing( a.target ) - 180.00 ) * bj_DEGTORAD )
                set y = a.ty + 100.00 * Sin( ( GetUnitFacing( a.target ) - 180.00 ) * bj_DEGTORAD )
                    
                call SetUnitVertexColor( a.caster, 255, 255, 255, 255 )
                call DestroyEffect( AddSpecialEffect( ANNAHILATE_TELEPORT_EFFECT, x, y ) )
                call SetUnitPosition( a.caster, x, y )
                    
                call PauseUnit( a.caster, false )
                call PauseUnit( a.target, false )
                    
                call SetUnitPathing( a.caster, true )
                call SetUnitInvulnerable( a.caster, false )
                
                set a.caster = null
                set a.target = null
            
                set i = 0
            
                loop
                    set i = i + 1
                
                    call GroupClear( a.hit[ i ] )
                    call DestroyGroup( a.hit[ i ] )
                    set a.hit[ i ] = null
                
                    exitwhen i >= a.num
                endloop
            
                call GroupClear( a.dummies )
                call GroupClear( a.moving )
                call GroupClear( a.fading )
                call DestroyGroup( a.dummies )
                call DestroyGroup( a.moving )
                call DestroyGroup( a.fading )
                set a.dummies = null
                set a.moving = null
                set a.fading = null
            
                set flag = true
        
                // END OF onDestroy METHOD
            endif
            
            call DestroyGroup( g )
            set g = null
            set u = null
            
            return flag
        endmethod
        
        static method Actions takes nothing returns nothing
            local Annahilate a = Annahilate.create()
            
            local integer i = 0
            local integer ii = 0
            
            local unit dummy
            local real x
            local real y
            local real angle
            
            local real r1
            local integer r2
            
            set a.caster = GetTriggerUnit()
            set a.cx = GetUnitX( a.caster )
            set a.cy = GetUnitY( a.caster )
            
            set a.lvl = GetUnitAbilityLevel( a.caster, ANNAHILATE_ID )
            set a.dmg = GetHeroAgi( a.caster, true ) * Multiplier( a.lvl )
            
            set a.target = GetSpellTargetUnit()
            set a.tx = GetUnitX( a.target )
            set a.ty = GetUnitY( a.target )
            
            call SetUnitPathing( a.caster, false )
            
            loop
                set ii = ii + 1
                
                loop
                    set i = i + 1
                    
                    // CREATES THE ILLUSIONS
                    
                    set r1 = ( ( ( 360.00 / NUMBER_OF_ILLUSION_PER_CIRCLE ) * i ) + ( ii * 12.00 ) )
                    set r2 = ( ( ii - 1 ) * NUMBER_OF_ILLUSION_PER_CIRCLE )
                     
                    set x = a.tx + ( 250.00 + ( ii * 150.00 ) ) * Cos( r1 * bj_DEGTORAD )
                    set y = a.ty + ( 250.00 + ( ii * 150.00 ) ) * Sin( r1 * bj_DEGTORAD )
                    
                    set angle = bj_RADTODEG * Atan2( a.ty - y, a.tx - x )
                    set a.cos[ r2 + i ] = Cos( angle * bj_DEGTORAD )
                    set a.sin[ r2 + i ] = Sin( angle * bj_DEGTORAD )
                    
                    set a.r[ r2 + i ] = DISTANCE_PER_SECOND * TT_PERIOD
                    
                    call DestroyEffect( AddSpecialEffect( ANNAHILATE_DUMMY_EFFECT_UPON_CREATION, x, y ) )
                    set a.dummy[ r2 + i ] = CreateUnit( GetOwningPlayer( a.caster ), ANNAHILATE_DUMMY_ID, x, y, angle )
                    set a.trans[ r2 + i ] = 100
                    call SetUnitVertexColor( a.dummy[ r2 + i ], 255, 255, 255, a.trans[ r2 + i ] )
                    call GroupAddUnit( a.dummies, a.dummy[ r2 + i ] )
                    set a.hit[ r2 + i ] = CreateGroup()
                    set a.ef[ r2 + i ] = AddSpecialEffectTarget( ANNAHILATE_DUMMY_EFFECT, a.dummy[ r2 + i ], ANNAHILATE_DUMMY_EFFECT_ATTACH )
                    
                    set a.num = a.num + 1
                                        
                    exitwhen i >= NUMBER_OF_ILLUSION_PER_CIRCLE
                endloop
                
                set i = 0
                exitwhen ii >= Number_of_Circles( a.lvl )
            endloop
            
            set r2 = GetRandomInt( 1, a.num )
            
            set x = GetUnitX( a.dummy[ r2 ] )
            set y = GetUnitY( a.dummy[ r2 ] )
            set angle = bj_RADTODEG * Atan2( a.ty - y, a.tx - x )
            
            set a.hit[ a.num + 1 ] = CreateGroup()
            set a.trans[ a.num + 1 ] = 255
            set a.r[ a.num + 1 ] = DISTANCE_PER_SECOND * TT_PERIOD * 1.75
            
            call SetUnitPosition( a.caster, x, y )
            call SetUnitFacing( a.caster, angle )
            
            call PauseUnit( a.caster, true )
            call PauseUnit( a.target, true )
            
            call SetUnitInvulnerable( a.caster, true )
            call SetUnitPathing( a.caster, false )
            
            set dummy = null
            
            call TriggerSleepAction( DELAY_OF_SPELL )
            
            call TT_Start( function Annahilate.Move, a )
        endmethod
        
        static method Check_ID takes nothing returns boolean
            return GetSpellAbilityId() == ANNAHILATE_ID
        endmethod

        //===========================================================================

        static method onInit takes nothing returns nothing
            local trigger A = CreateTrigger(  )
            local integer i = 0
                
            loop 
                exitwhen i >= 16
                call TriggerRegisterPlayerUnitEvent( A, Player( i ), EVENT_PLAYER_UNIT_SPELL_EFFECT, Condition( function True ) )
                    
                set i = i + 1
            endloop
            
            call TriggerAddCondition( A, Condition( function Annahilate.Check_ID ) )
            call TriggerAddAction( A, function Annahilate.Actions )
            
            set A = null
            
            // PRELOADING...
            
            call RemoveUnit( CreateUnit( Player( 15 ), ANNAHILATE_DUMMY_ID, 0.00, 0.00, 0.00 ) )

            call Preload( ANNAHILATE_DUMMY_EFFECT_UPON_CREATION )
            call Preload( ANNAHILATE_DUMMY_ANIMATION )
            call Preload( ANNAHILATE_DUMMY_EFFECT )
            call Preload( ANNAHILATE_DUMMY_EFFECT_ATTACH )
            call Preload( ANNAHILATE_DAMAGE_EFFECT )
            call Preload( ANNAHILATE_DAMAGE_EFFECT_ATTACH )
            call Preload( ANNAHILATE_TELEPORT_EFFECT )
            call Preload( TEXTTAG_COLOR )
        endmethod
    
    endstruct

endscope


Please rate and/or comment :D

Changelog:
April 8, 2009
- Added an option where you attach an effect to the dummy while charging.
- Fixed an annoying bug that when the target dies, they continue to charge.
- Added a screenshot.

Special Thanks:
Cohadar - TT System
General Frank - The Werewolf model ( It ROCKS!! )

Map:
 

Attachments

  • Annahilate.w3x
    209.4 KB · Views: 301
Reaction score
91
Shouldn't it be "Annihilate"?

Anyway, pretty awesome spell. I suggest giving an option to attach an effect on the illusions when they charge towards the unit - currently the white-ish effect they produce is just from the model, I assume it would look a little plain if another Hero model was used.
Your spell bugs when you cast it on a unit and it dies - the illusions charge to the bottom left corner of the map and the Hero gets paused forever (and stays invulnerable).
 

wraithseeker

Tired.
Reaction score
122
It bugs when I cast it on a unit the second time and I have some illusion standing there doing nothing and I got paused.

JASS:
unit array dummy [ MAXIMUM_ILLUSIONS ]      // STORES THE NEEDED DATA FOR THE DUMMIES
        real array cos[ MAXIMUM_ILLUSIONS ]
        real array sin[ MAXIMUM_ILLUSIONS ]
        real array r [ MAXIMUM_ILLUSIONS ]
        integer array trans [ MAXIMUM_ILLUSIONS ]
        group array hit [ MAXIMUM_ILLUSIONS ]


Isn't it possible to create a struct for every dummy unit so as to shorten your work.
 

XeNiM666

I lurk for pizza
Reaction score
138
I suggest giving an option to attach an effect on the illusions when they charge towards the unit
Good idea! :D
Your spell bugs when you cast it on a unit and it dies - the illusions charge to the bottom left corner of the map and the Hero gets paused forever (and stays invulnerable).
... didnt know that. Ill jst make it so that when the target dies, all the illusions will disappear.
It bugs when I cast it on a unit the second time and I have some illusion standing there doing nothing and I got paused.
I think thats a bug when you cast it in the map boundaries...

Well, thanks for the comments everyone! I'll try to fix those bugs tommorow. It's getting late :D:D
 

Doom-Angel

Jass User (Just started using NewGen)
Reaction score
167
seems kinda wierd to make an illusion make damage no?
it would be more reasonable to make it a clone then illusion.
 

Viikuna

No Marlo no game.
Reaction score
265
Few things:

Its better to use one global group for all groupings, instead of creating&destroying a local group g every TT_PERIOD.

JASS:
            
local unit u = GetFilterUnit()
local boolean b1 = GetWidgetLife( u ) > 0.408
local boolean b2 = IsUnitType( u, UNIT_TYPE_STRUCTURE ) != true
local boolean b3 = IsUnitType( u, UNIT_TYPE_FLYING ) != true
set u = null
return b1 and b2 and b3


could be:

JASS:
            
local unit u = GetFilterUnit()
local boolean b = GetWidgetLife( u ) > 0.408 and IsUnitType( u, UNIT_TYPE_STRUCTURE ) != true and IsUnitType( u, UNIT_TYPE_FLYING ) != true
set u = null
return b


Also nulling trigger A is useles, because you never destroy it.

Anyways, it looks pretty neat. I try to find some more things needing for fix.
 

Viikuna

No Marlo no game.
Reaction score
265
Ye, you hardly ever need to use DestroyGroup again

edit. Comments about the spell itself:

I font really like spells that pause caster like that. I think this could be a nice blink & damage AoE spell, if you make this point targetted.

The good thing is that this spell looks pretty cool.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top