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

ArcaneGlaive v1.2

  • Like
Reactions: deepstrasz
JASS:
    // by Dalvengyr @Hiveworkshop.com
    // *******************************************************
    //                                                       *
    //                  Arcane Glaive v1.2                   *
    //                                                       *
    // Description                                           *
    // Causes Spell Breaker's attacks to deal no physical    *
    // damage. Arcane Glaive will burn mana on hit and deals *
    // 4x of burned mana as magic damage to units within 175 *
    // AoE. The glaive will bounce 2 times before expired.   *
    //                                                       *
    // Requirement(s)                                        *
    // - None                                                *
    //                                                       *
    // How to import                                         *
    // - Copy this trigger folder into your map              *
    // - Copy dummy unit & spell into your map               *
    // - Configure the spell                                 *
    //                                                       *
    // Credits:                                              *
    // - ArcaneNova.mdx by dhguardianes                      *
    // - ArcaneGlaive.mdx by Infrisios                       *
    // - BloodElfSpellThief.blp by shockwave                 *
    // - BTNTranquilityStar by QuadraDowN                    *
    //                                                       *
    // *******************************************************
    
    //                    Configurations
    
    // Main spell's rawcode
    constant function AGL__SpellID takes nothing returns integer
        return 'A000'
    endfunction
    
    // Dummy unit's rawcode
    constant function AGL__DummyID takes nothing returns integer
        return 'h000'
    endfunction
    
    // Spell's periodic interval
    constant function AGL__Accuracy takes nothing returns real
        return 0.03125
    endfunction
    
    // Created sfx on hit
    constant function AGL__HitSfx  takes nothing returns string
        return "war3mapImported\\Arcane Nova.mdx"
    endfunction
    
    // Sfx attachment point
    constant function AGL__HitSfxPt  takes nothing returns string
        return "origin"
    endfunction
    
    // Missile's model filepath
    constant function AGL__MissileModel  takes nothing returns string
        return "war3mapImported\\ArcaneGlaive_2.mdx"
    endfunction
    
    // Missile's scale
    constant function AGL__MissileSize takes nothing returns real
        return 1.0
    endfunction
    
    // Missile's moverate
    constant function AGL__MissileSpeed takes nothing returns real
        return 25.0
    endfunction
    
    // Missile's turn rate (in radian)
    constant function AGL__MissileTurnRate takes nothing returns real
        return 10.75 * bj_DEGTORAD
    endfunction
    
    // Missile will be expired if does not hit anything after
    // this duration
    constant function AGL__MissileLifespan takes nothing returns real
        return 3.0
    endfunction
    
    // Launch z
    constant function AGL__NormalZ takes nothing returns real
        return 66.0
    endfunction
    
    // Hit range
    constant function AGL__HitRadius takes nothing returns real
        return 50.0
    endfunction
    
    // Missile decay time
    constant function AGL__SfxDecayTime takes nothing returns real
        return 3.0
    endfunction
    
    // Target search radius (minimun range)
    constant function AGL__SearchRadiusMin takes nothing returns real
        return 175.0
    endfunction
    
    // Target search radius (maximum range)
    constant function AGL__SearchRadiusMax takes nothing returns real
        return 600.0
    endfunction
    
    // Each unit can only be targeted once
    constant function AGL__TargetsOnce takes nothing returns boolean
        return false
    endfunction
    
    // If true, glaive will removed if caster is dead/removed
    constant function AGL__RemoveOnDead takes nothing returns boolean
        return false
    endfunction
    
    // Number of jumps for each level
    constant function AGL__bounceCount takes integer level returns integer
        return 2
    endfunction
    
    // Burned mana amount for each level
    constant function AGL__manaBurn takes integer level returns real
        return 5.0 * level
    endfunction
    
    // Dealt damage factor for each level
    constant function AGL__damageFactor takes integer level returns real
        return 4.0
    endfunction
    
    // AoE of damage for each level
    constant function AGL__damageAoE takes integer level returns real
        return 175.0
    endfunction
    
    // Attack type of dealt damage
    constant function AGL__AttackType takes nothing returns attacktype
        return ATTACK_TYPE_NORMAL
    endfunction
    
    // Damage type of dealt damage
    constant function AGL__DamageType takes nothing returns damagetype
        return DAMAGE_TYPE_NORMAL
    endfunction
    
    // Target classification
    constant function AGL__filterTarget takes unit u returns boolean
        return not(IsUnitType(u, UNIT_TYPE_FLYING) or IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) or IsUnitType(u, UNIT_TYPE_MECHANICAL) or IsUnitType(u, UNIT_TYPE_STRUCTURE))
    endfunction
    
    // ===========================================================================
    
    constant function AGL__isInBound takes real x, real y returns boolean
        return x < udg_AGL__MapBounds[0] and x > udg_AGL__MapBounds[1] and y < udg_AGL__MapBounds[2] and y > udg_AGL__MapBounds[3]
    endfunction
    
    function AGL__deindex takes integer i returns integer
        
        if AGL__TargetsOnce() then
            call DestroyGroup(udg_AGL__Group[i])
        endif
        call DestroyEffect(udg_AGL__MissileSfx[i])
        call UnitApplyTimedLife(udg_AGL__Missile[i], 'BTLF', AGL__SfxDecayTime())
        
        set udg_AGL__Caster[i]       = udg_AGL__Caster[udg_AGL__Counter]
        set udg_AGL__Target[i]       = udg_AGL__Target[udg_AGL__Counter]
        set udg_AGL__Player[i]       = udg_AGL__Player[udg_AGL__Counter]
        set udg_AGL__Damage[i]       = udg_AGL__Damage[udg_AGL__Counter]
        
        set udg_AGL__Bounce[i]       = udg_AGL__Bounce[udg_AGL__Counter]
        set udg_AGL__Mana[i]         = udg_AGL__Mana[udg_AGL__Counter]
        set udg_AGL__Lifespan[i]     = udg_AGL__Lifespan[udg_AGL__Counter]
        set udg_AGL__MissileX[i]     = udg_AGL__MissileX[udg_AGL__Counter]
        set udg_AGL__AoE[i]          = udg_AGL__AoE[udg_AGL__Counter]
        
        set udg_AGL__MissileY[i]     = udg_AGL__MissileY[udg_AGL__Counter]
        set udg_AGL__Missile[i]      = udg_AGL__Missile[udg_AGL__Counter]
        set udg_AGL__MissileFace[i]  = udg_AGL__MissileFace[udg_AGL__Counter]
        set udg_AGL__MissileSfx[i]   = udg_AGL__MissileSfx[udg_AGL__Counter]
        
        if AGL__TargetsOnce() then
            set udg_AGL__Group[i]        = udg_AGL__Group[udg_AGL__Counter]
            set udg_AGL__Group[udg_AGL__Counter]        = null
        endif
        
        set udg_AGL__MissileSfx[udg_AGL__Counter]   = null
        set udg_AGL__Missile[udg_AGL__Counter]      = null
        set udg_AGL__Caster[udg_AGL__Counter]       = null
        set udg_AGL__Target[udg_AGL__Counter]       = null
        
        set udg_AGL__Counter = udg_AGL__Counter - 1
        if udg_AGL__Counter < 1 then
            call PauseTimer(udg_AGL__Timer)
        else
            return i - 1
        endif
        
        return i
    endfunction
    
    // Get new target with lowest mana around previous target
    function AGL__getTarget takes integer i returns unit
        
        local real m = -1
        local unit u
        local real x
        local real y
        
        call GroupEnumUnitsInRange(udg_AGL__TempGroup, udg_AGL__MissileX[i], udg_AGL__MissileY[i], AGL__SearchRadiusMax(), null)
        loop
            set u = FirstOfGroup(udg_AGL__TempGroup)
            exitwhen u == null
            call GroupRemoveUnit(udg_AGL__TempGroup, u)
            
            if u != udg_AGL__Target[i] and not IsUnitInGroup(u, udg_AGL__Group[i]) and AGL__filterTarget(u) then
            
                if IsPlayerAlly(GetOwningPlayer(u), udg_AGL__Player[i]) and GetUnitState(u, UNIT_STATE_MANA) > m then
                
                    set x = GetUnitX(u)
                    set y = GetUnitY(u)
                    
                    if (udg_AGL__MissileX[i] - x)*(udg_AGL__MissileX[i] - x)+(udg_AGL__MissileY[i] - y)*(udg_AGL__MissileY[i] - y) > AGL__SearchRadiusMin() * AGL__SearchRadiusMin() then
                        if not IsUnitType(u, UNIT_TYPE_DEAD) and GetUnitTypeId(u) != 0 then
                            set udg_AGL__TempUnit = u
                            set m = GetUnitState(u, UNIT_STATE_MANA)
                        endif
                    endif
                endif
                
            endif
        endloop
        
        return udg_AGL__TempUnit
    endfunction
    
    function AGL__onTick takes nothing  returns nothing
        
        local integer i = 1
        local real a
        local real x
        local real y
        local real m
        
        loop
            exitwhen i > udg_AGL__Counter
            if udg_AGL__Lifespan[i] > AGL__Accuracy() and (not IsUnitType(udg_AGL__Caster[i], UNIT_TYPE_DEAD) and GetUnitTypeId(udg_AGL__Caster[i]) != 0 or not AGL__RemoveOnDead()) then
            
                set udg_AGL__Lifespan[i] = udg_AGL__Lifespan[i] - AGL__Accuracy()
                set x = GetUnitX(udg_AGL__Target[i])
                set y = GetUnitY(udg_AGL__Target[i])
                set a = Atan2(y - udg_AGL__MissileY[i], x - udg_AGL__MissileX[i])
                
                // Adjust missile's facing angle to the target
                if Cos(udg_AGL__MissileFace[i] - a) < Cos(AGL__MissileTurnRate()) then
                    if Sin(a - udg_AGL__MissileFace[i]) >= 0 then
                        set udg_AGL__MissileFace[i] = udg_AGL__MissileFace[i] + AGL__MissileTurnRate()
                    else
                        set udg_AGL__MissileFace[i] = udg_AGL__MissileFace[i] - AGL__MissileTurnRate()
                    endif
                else
                    set udg_AGL__MissileFace[i] = a
                endif
                
                // Set the target loc coordinate
                set udg_AGL__MissileX[i] = udg_AGL__MissileX[i] + AGL__MissileSpeed() * Cos(udg_AGL__MissileFace[i])
                set udg_AGL__MissileY[i] = udg_AGL__MissileY[i] + AGL__MissileSpeed() * Sin(udg_AGL__MissileFace[i])
                
                if AGL__isInBound(udg_AGL__MissileX[i], udg_AGL__MissileY[i]) then
                
                    if (udg_AGL__MissileX[i] - x)*(udg_AGL__MissileX[i] - x)+(udg_AGL__MissileY[i] - y)*(udg_AGL__MissileY[i] - y) < AGL__HitRadius() * AGL__HitRadius() then
                    
                        // Decrease mana
                        set m = GetUnitState(udg_AGL__Target[i], UNIT_STATE_MANA)
                        call SetUnitState(udg_AGL__Target[i], UNIT_STATE_MANA, m - udg_AGL__Mana[i])
                        set m = m - GetUnitState(udg_AGL__Target[i], UNIT_STATE_MANA)
                        call DestroyEffect(AddSpecialEffectTarget(AGL__HitSfx(), udg_AGL__Target[i], AGL__HitSfxPt()))
                        
                        // Deal damage to all units around the target
                        call GroupEnumUnitsInRange(udg_AGL__TempGroup, udg_AGL__MissileX[i], udg_AGL__MissileY[i], udg_AGL__AoE[i], null)
                        loop
                            set udg_AGL__TempUnit = FirstOfGroup(udg_AGL__TempGroup)
                            exitwhen udg_AGL__TempUnit == null
                            call GroupRemoveUnit(udg_AGL__TempGroup, udg_AGL__TempUnit)
                            
                            if IsPlayerAlly(GetOwningPlayer(udg_AGL__TempUnit), udg_AGL__Player[i]) and not IsUnitType(udg_AGL__TempUnit, UNIT_TYPE_DEAD) and GetUnitTypeId(udg_AGL__TempUnit) != 0 then
                                if AGL__filterTarget(udg_AGL__TempUnit) then
                                    call UnitDamageTarget(udg_AGL__Caster[i], udg_AGL__TempUnit, m, false, false, AGL__AttackType(), AGL__DamageType(), null)
                                endif
                            endif
                        endloop
                        
                        // Get next target if still can bounce
                        if udg_AGL__Bounce[i] > 0 then
                        
                            set udg_AGL__Bounce[i] = udg_AGL__Bounce[i] - 1
                            
                            if AGL__TargetsOnce() then
                                call GroupAddUnit(udg_AGL__Group[i], udg_AGL__Target[i])
                            endif
                            set udg_AGL__Target[i] = AGL__getTarget(i)
                            
                            if udg_AGL__Target[i] == null then
                                set i = AGL__deindex(i)
                            else
                                set udg_AGL__Lifespan[i] = AGL__MissileLifespan()
                            endif
                        else
                            set i = AGL__deindex(i)
                        endif
                    else
                        call SetUnitX(udg_AGL__Missile[i], udg_AGL__MissileX[i])
                        call SetUnitY(udg_AGL__Missile[i], udg_AGL__MissileY[i])
                    endif
                else
                    set i = AGL__deindex(i)
                endif
            else
                set i = AGL__deindex(i)
            endif
            set i = i + 1
        endloop
        
    endfunction
    
    function AGL__onCast takes nothing  returns boolean
        
        local integer l
    
        if GetSpellAbilityId() == AGL__SpellID() and AGL__filterTarget(GetSpellTargetUnit()) then
            set udg_AGL__Counter = udg_AGL__Counter + 1
            set udg_AGL__Caster[udg_AGL__Counter]       = GetTriggerUnit()
            set udg_AGL__Target[udg_AGL__Counter]       = GetSpellTargetUnit()
            set udg_AGL__Player[udg_AGL__Counter]       = GetOwningPlayer(udg_AGL__Target[udg_AGL__Counter])
            
            set l = GetUnitAbilityLevel(udg_AGL__Caster[udg_AGL__Counter], AGL__SpellID())
            
            set udg_AGL__Lifespan[udg_AGL__Counter]     = AGL__MissileLifespan()
            set udg_AGL__Damage[udg_AGL__Counter]       = AGL__damageFactor(l)
            set udg_AGL__Bounce[udg_AGL__Counter]       = AGL__bounceCount(l)
            set udg_AGL__Mana[udg_AGL__Counter]         = AGL__manaBurn(l)
            set udg_AGL__AoE[udg_AGL__Counter]          = AGL__damageAoE(l)
            
            set udg_AGL__MissileX[udg_AGL__Counter]     = GetUnitX(udg_AGL__Caster[udg_AGL__Counter])
            set udg_AGL__MissileY[udg_AGL__Counter]     = GetUnitY(udg_AGL__Caster[udg_AGL__Counter])
            set udg_AGL__MissileFace[udg_AGL__Counter]  = Atan2(GetUnitY(udg_AGL__Target[udg_AGL__Counter]) - udg_AGL__MissileY[udg_AGL__Counter], GetUnitX(udg_AGL__Target[udg_AGL__Counter]) - udg_AGL__MissileX[udg_AGL__Counter])
            set udg_AGL__Missile[udg_AGL__Counter]      = CreateUnit(GetTriggerPlayer(), AGL__DummyID(), udg_AGL__MissileX[udg_AGL__Counter], udg_AGL__MissileY[udg_AGL__Counter], udg_AGL__MissileFace[udg_AGL__Counter] * bj_RADTODEG)
            set udg_AGL__MissileSfx[udg_AGL__Counter]   = AddSpecialEffectTarget(AGL__MissileModel(), udg_AGL__Missile[udg_AGL__Counter], "origin")
            
            if AGL__TargetsOnce() then
                set udg_AGL__Group[udg_AGL__Counter]        = CreateGroup()
            endif
            
            if UnitAddAbility(udg_AGL__Missile[udg_AGL__Counter], 'Amrf') and UnitRemoveAbility(udg_AGL__Missile[udg_AGL__Counter], 'Amrf') then
            endif
            
            call SetUnitFlyHeight(udg_AGL__Missile[udg_AGL__Counter], AGL__NormalZ(), 0)
            call SetUnitScale(udg_AGL__Missile[udg_AGL__Counter], AGL__MissileSize(), 1, 1)
            
            if udg_AGL__Counter == 1 then
                call TimerStart(udg_AGL__Timer, AGL__Accuracy(), true, function AGL__onTick)
            endif
        endif
        
        return false
    endfunction

    function InitTrig_ArcaneGlaive takes nothing returns nothing
    
        // Initialize map bounds
        set udg_AGL__MapBounds[0] = GetRectMaxX(bj_mapInitialPlayableArea)
        set udg_AGL__MapBounds[1] = GetRectMinX(bj_mapInitialPlayableArea)
        set udg_AGL__MapBounds[2] = GetRectMaxY(bj_mapInitialPlayableArea)
        set udg_AGL__MapBounds[3] = GetRectMinY(bj_mapInitialPlayableArea)
    
        set gg_trg_ArcaneGlaive = CreateTrigger()
        set udg_AGL__TempGroup = CreateGroup()
        set udg_AGL__Timer = CreateTimer()
        
        call TriggerRegisterAnyUnitEventBJ(gg_trg_ArcaneGlaive, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(gg_trg_ArcaneGlaive, Condition(function AGL__onCast))
        
    endfunction

Keywords:
arcane, glaive, bounce, mana, burn, combust
Contents

ArcaneGlaive (Map)

Reviews
IcemanBo: -date: 3rd March 2015 -submission: ArcaneGlaive v1.2 It is a decent and solid coded glaive spell. Changes have been made, and all works fine. Approved IcemanBo...

Moderator

M

Moderator

IcemanBo:
-date: 3rd March 2015
-submission: ArcaneGlaive v1.2

It is a decent and solid coded glaive spell. Changes have been made, and all works fine.

Approved


IcemanBo: http://www.hiveworkshop.com/forums/spells-569/arcaneglaive-v1-1-a-257510/#post2643847

12:03, 21st Sep 2014
TriggerHappy:

  • You need to replace all configurable globals with constant functions.
  • The spell has no documentation. Make sure to include all required globals (if any) that need the spell requires.
  • Consider using a hashtable instead of all these global variables.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
You need to replace all configurable globals with constant functions.
Non-sense. They are slower, you want me to do repetitive function call? No way.

The spell has no documentation. Make sure to include all required globals (if any) that need the spell requires.
Why should we add bullshits into our code? ^)^ I will add variable creator by the way, forgot about that.

Consider using a hashtable instead of all these global variables.
Seriously TH, hashtable is much slower than variables. I'll prefer to spend some bytes for speed.
 
Non-sense. They are slower, you want me to do repetitive function call? No way.

Aren't you the one always complaining about how these speed differences aren't noticeable? This is one of those cases and Vex's map optimizer will inline them AFAIK which would result in even faster code. I see no logical reason to require that many globals specifically for configuration in a JASS spell. The way people did it before vJass was with constant functions and I still think it's a good idea.

I can run some benchmarks for you if you'd like.

Why should we add bullshits into our code? ^)^ I will add variable creator by the way, forgot about that.

Documentation is required.

Seriously TH, hashtable is much slower than variables. I'll prefer to spend some bytes for speed

Just a suggestion for some cleaner code.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
This is one of those cases and Vex's map optimizer will inline them AFAIK which would result in even faster code.
Not everyone here uses JNGP. That's why I prefer to submit Jass and GUI spell/system here. So that people who is using normal WE can compile it optimizedly. And again, I would prefer to spend some bytes for that un-noticeable difference. Though 4 bytes x 17 = 68 bytes wont kill anybody ^)^

Documentation is required.
Okay
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
I'm talking about the map optimizer, not JassHelper. Almost everyone uses it before uploading their map.

In it's current setup there's also no level support. For example:

set udg_AGL__HIT_RADIUS = 50.0

Dunno about optimizier.

I will use constant function with level as parameter if only I think it's needed. General missile attributes (speed, size, hit radius, etc.) should not be configured differently for each level.
 
Cool spell, also if people were smart they would learn about the U9 optimizer that makes editing anybody's map impossible. You only can extract files. TriggerHappy =)

4/5 - I really think this is one of the coolest spells I have seen lately.

I'd rather speed over hashtables in a spell like this, it matters. Though what does inlining exactly mean?
 
Here's your spell with constant functions instead of mass amounts of globals.

JASS:
    // by Dalvengyr @Hiveworkshop.com
    // ******************************************************
    //
    //                      Arcane Glaive v1.1
    //
    // Description
    // Causes Spell Breaker's attacks to deal no physical damage.
    // Arcane Glaive will burn mana on hit and deals 4x of
    // burned mana as magic damage to units within 175 AoE.
    // The glaive will bounce 2 times before expired.
    //
    // How to import
    // - Copy this trigger folder into your map
    // - Copy dummy unit into your map
    // - Configure the spell
    //
    // Credits:
    // - ArcaneNova.mdx by dhguardianes
    // - ArcaneGlaive.mdx by Infrisios
    // - BloodElfSpellThief.blp by shockwave
    // - BTNTranquilityStar by QuadraDowN
    //
    // ******************************************************
    
    // Configurations
    
    constant function AGL__SPELL_ID takes nothing returns integer
        return 'A000'
    endfunction
    
    constant function AGL__DUMMY_ID takes nothing returns integer
        return 'h000'
    endfunction
    
    constant function AGL__HIT_SFX  takes nothing returns string
        return "war3mapImported\\Arcane Nova.mdx"
    endfunction
    
    constant function AGL__HIT_SFX_PT  takes nothing returns string
        return "origin"
    endfunction
    
    // Missile datas
    constant function AGL__MISSILE_SFX  takes nothing returns string
        return "war3mapImported\\ArcaneGlaive_2.mdx"
    endfunction
    
    constant function AGL__MISSILE_SIZE takes nothing returns real
        return 1.0
    endfunction
    
    constant function AGL__MISSILE_SPEED takes nothing returns real
        return 25.0
    endfunction
    
    constant function AGL__MISSILE_TURN_RATE takes nothing returns real
        return 10.75 * bj_DEGTORAD
    endfunction
    
    constant function AGL__MISSILE_LIFESPAN takes nothing returns real
        return 3.0
    endfunction
    
    constant function AGL__MISSILE_Z takes nothing returns real
        return 66.0
    endfunction
    
    // Hit range
    constant function AGL__HIT_RADIUS takes nothing returns real
        return 50.
    endfunction
    
    // Missile decay time
    constant function AGL__SFX_DECAY_TIME takes nothing returns real
        return 3.0
    endfunction
    
    // Target search radius
    constant function AGL__SEARCH_RADIUS_MIN takes nothing returns real
        return 175.
    endfunction
    
    constant function AGL__SEARCH_RADIUS_MAX takes nothing returns real
        return 600.0
    endfunction
    
    // Each unit can only be targeted once
    constant function AGL__TARGETS_ONCE takes nothing returns boolean
        return false
    endfunction
    
    constant function AGL__ACCURACY takes nothing returns real
        return 0.03125
    endfunction
    
    // Type of dealt damage
    constant function AGL__ATTACK_TYPE takes nothing returns attacktype
        return ATTACK_TYPE_NORMAL
    endfunction
    
    constant function AGL__DAMAGE_TYPE takes nothing returns damagetype
        return DAMAGE_TYPE_NORMAL
    endfunction
    
    // Burned mana amount
    constant function AGL__manaBurn takes integer level returns real
        return 5.0 * level
    endfunction
    
    // Dealt damage factor
    constant function AGL__damageFactor takes integer level returns real
        return 4.0
    endfunction
    
    // AoE of damage
    constant function AGL__damageAoE takes integer level returns real
        return 175.0
    endfunction
    
    // Number of jumps
    constant function AGL__bounceCount takes integer level returns integer
        return 2
    endfunction
    
    // Target classification
    constant function AGL__filterTarget takes unit u returns boolean
        return not(IsUnitType(u, UNIT_TYPE_FLYING) or IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) or IsUnitType(u, UNIT_TYPE_MECHANICAL) or IsUnitType(u, UNIT_TYPE_STRUCTURE))
    endfunction
    
    // ===========================================================================
    
    constant function AGL__isInBound takes real x, real y returns boolean
        return x < udg_AGL__MapBounds[0] and x > udg_AGL__MapBounds[1] and y < udg_AGL__MapBounds[2] and y > udg_AGL__MapBounds[3]
    endfunction
    
    function AGL__deindex takes integer i returns integer
        
        call DestroyGroup(udg_AGL__Group[i])
        call DestroyEffect(udg_AGL__MissileSfx[i])
        call UnitApplyTimedLife(udg_AGL__Missile[i], 'BTLF', AGL__SFX_DECAY_TIME())
        
        set udg_AGL__Caster[i]       = udg_AGL__Caster[udg_AGL__Counter]
        set udg_AGL__Target[i]       = udg_AGL__Target[udg_AGL__Counter]
        set udg_AGL__Player[i]       = udg_AGL__Player[udg_AGL__Counter]
        set udg_AGL__Damage[i]       = udg_AGL__Damage[udg_AGL__Counter]
        
        set udg_AGL__Bounce[i]       = udg_AGL__Bounce[udg_AGL__Counter]
        set udg_AGL__Mana[i]         = udg_AGL__Mana[udg_AGL__Counter]
        set udg_AGL__Lifespan[i]     = udg_AGL__Lifespan[udg_AGL__Counter]
        set udg_AGL__MissileX[i]     = udg_AGL__MissileX[udg_AGL__Counter]
        set udg_AGL__AoE[i]          = udg_AGL__AoE[udg_AGL__Counter]
        
        set udg_AGL__MissileY[i]     = udg_AGL__MissileY[udg_AGL__Counter]
        set udg_AGL__Missile[i]      = udg_AGL__Missile[udg_AGL__Counter]
        set udg_AGL__MissileFace[i]  = udg_AGL__MissileFace[udg_AGL__Counter]
        set udg_AGL__MissileSfx[i]   = udg_AGL__MissileSfx[udg_AGL__Counter]
        set udg_AGL__Group[i]        = udg_AGL__Group[udg_AGL__Counter]
        
        set udg_AGL__Group[udg_AGL__Counter]        = null
        set udg_AGL__MissileSfx[udg_AGL__Counter]   = null
        set udg_AGL__Missile[udg_AGL__Counter]      = null
        set udg_AGL__Caster[udg_AGL__Counter]       = null
        set udg_AGL__Target[udg_AGL__Counter]       = null
        
        set udg_AGL__Counter = udg_AGL__Counter - 1
        if udg_AGL__Counter < 1 then
            call PauseTimer(udg_AGL__Timer)
        else
            return i - 1
        endif
        
        return i
    endfunction
    
    function AGL__getTarget takes integer i returns unit
        
        local real m = -1
        local unit u
        local real x
        local real y
        
        call GroupEnumUnitsInRange(udg_AGL__TempGroup, udg_AGL__MissileX[i], udg_AGL__MissileY[i], AGL__SEARCH_RADIUS_MAX(), null)
        loop
            set u = FirstOfGroup(udg_AGL__TempGroup)
            exitwhen u == null
            if u != udg_AGL__Target[i] and not IsUnitInGroup(u, udg_AGL__Group[i]) and AGL__filterTarget(u) then
                if IsPlayerAlly(GetOwningPlayer(u), udg_AGL__Player[i]) and GetUnitState(u, UNIT_STATE_MANA) > m then
                    set x = GetUnitX(u)
                    set y = GetUnitY(u)
                    if (udg_AGL__MissileX[i] - x)*(udg_AGL__MissileX[i] - x)+(udg_AGL__MissileY[i] - y)*(udg_AGL__MissileY[i] - y) > AGL__SEARCH_RADIUS_MIN() * AGL__SEARCH_RADIUS_MIN() then
                        if GetWidgetLife(u) > 0.405 then
                            set udg_AGL__TempUnit = u
                            set m = GetUnitState(u, UNIT_STATE_MANA)
                        endif
                    endif
                endif
            endif
            call GroupRemoveUnit(udg_AGL__TempGroup, u)
        endloop
        
        return udg_AGL__TempUnit
    endfunction
    
    function AGL__onTick takes nothing  returns nothing
        
        local integer i = 1
        local real a
        local real x
        local real y
        local real m
        
        loop
            exitwhen i > udg_AGL__Counter
            if udg_AGL__Lifespan[i] > AGL__ACCURACY() then
            
                set udg_AGL__Lifespan[i] = udg_AGL__Lifespan[i] - AGL__ACCURACY()
                set x = GetUnitX(udg_AGL__Target[i])
                set y = GetUnitY(udg_AGL__Target[i])
                set a = Atan2(y - udg_AGL__MissileY[i], x - udg_AGL__MissileX[i])
                
                if Cos(udg_AGL__MissileFace[i] - a) < Cos(AGL__MISSILE_TURN_RATE()) then
                    if Sin(a - udg_AGL__MissileFace[i]) >= 0 then
                        set udg_AGL__MissileFace[i] = udg_AGL__MissileFace[i] + AGL__MISSILE_TURN_RATE()
                    else
                        set udg_AGL__MissileFace[i] = udg_AGL__MissileFace[i] - AGL__MISSILE_TURN_RATE()
                    endif
                else
                    set udg_AGL__MissileFace[i] = a
                endif
                
                set udg_AGL__MissileX[i] = udg_AGL__MissileX[i] + AGL__MISSILE_SPEED() * Cos(udg_AGL__MissileFace[i])
                set udg_AGL__MissileY[i] = udg_AGL__MissileY[i] + AGL__MISSILE_SPEED() * Sin(udg_AGL__MissileFace[i])
                
                if AGL__isInBound(udg_AGL__MissileX[i], udg_AGL__MissileY[i]) then
                    if (udg_AGL__MissileX[i] - x)*(udg_AGL__MissileX[i] - x)+(udg_AGL__MissileY[i] - y)*(udg_AGL__MissileY[i] - y) < AGL__HIT_RADIUS() * AGL__HIT_RADIUS() then
                        set m = GetUnitState(udg_AGL__Target[i], UNIT_STATE_MANA)
                        call SetUnitState(udg_AGL__Target[i], UNIT_STATE_MANA, m - udg_AGL__Mana[i])
                        set m = m - GetUnitState(udg_AGL__Target[i], UNIT_STATE_MANA)
                        call DestroyEffect(AddSpecialEffectTarget(AGL__HIT_SFX(), udg_AGL__Target[i], AGL__HIT_SFX_PT()))
                        
                        call GroupEnumUnitsInRange(udg_AGL__TempGroup, udg_AGL__MissileX[i], udg_AGL__MissileY[i], udg_AGL__AoE[i], null)
                        loop
                            set udg_AGL__TempUnit = FirstOfGroup(udg_AGL__TempGroup)
                            exitwhen udg_AGL__TempUnit == null
                            if IsPlayerAlly(GetOwningPlayer(udg_AGL__TempUnit), udg_AGL__Player[i]) and GetWidgetLife(udg_AGL__TempUnit) > 0.405 then
                                if AGL__filterTarget(udg_AGL__TempUnit) then
                                    call UnitDamageTarget(udg_AGL__Caster[i], udg_AGL__TempUnit, m, false, false, AGL__ATTACK_TYPE(), AGL__DAMAGE_TYPE(), null)
                                endif
                            endif
                            call GroupRemoveUnit(udg_AGL__TempGroup, udg_AGL__TempUnit)
                        endloop
                        
                        if udg_AGL__Bounce[i] > 0 then
                            set udg_AGL__Bounce[i] = udg_AGL__Bounce[i] - 1
                            if AGL__TARGETS_ONCE() then
                                call GroupAddUnit(udg_AGL__Group[i], udg_AGL__Target[i])
                            endif
                            set udg_AGL__Target[i] = AGL__getTarget(i)
                            if udg_AGL__Target[i] == null then
                                set i = AGL__deindex(i)
                            else
                                set udg_AGL__Lifespan[i] = AGL__MISSILE_LIFESPAN()
                            endif
                        else
                            set i = AGL__deindex(i)
                        endif
                    else
                        call SetUnitX(udg_AGL__Missile[i], udg_AGL__MissileX[i])
                        call SetUnitY(udg_AGL__Missile[i], udg_AGL__MissileY[i])
                    endif
                else
                    set i = AGL__deindex(i)
                endif
            else
                set i = AGL__deindex(i)
            endif
            set i = i + 1
        endloop
        
    endfunction
    
    function AGL__onCast takes nothing  returns boolean
        
        local integer l
    
        if GetSpellAbilityId() == AGL__SPELL_ID() then
            if AGL__filterTarget(GetSpellTargetUnit()) then
                set udg_AGL__Counter = udg_AGL__Counter + 1
                set udg_AGL__Caster[udg_AGL__Counter]       = GetTriggerUnit()
                set udg_AGL__Target[udg_AGL__Counter]       = GetSpellTargetUnit()
                set udg_AGL__Player[udg_AGL__Counter]       = GetOwningPlayer(udg_AGL__Target[udg_AGL__Counter])
                
                set l = GetUnitAbilityLevel(udg_AGL__Caster[udg_AGL__Counter], AGL__SPELL_ID())
                set udg_AGL__Lifespan[udg_AGL__Counter]     = AGL__MISSILE_LIFESPAN()
                set udg_AGL__Damage[udg_AGL__Counter]       = AGL__damageFactor(l)
                set udg_AGL__Bounce[udg_AGL__Counter]       = AGL__bounceCount(l)
                set udg_AGL__Mana[udg_AGL__Counter]         = AGL__manaBurn(l)
                set udg_AGL__AoE[udg_AGL__Counter]          = AGL__damageAoE(l)
                
                set udg_AGL__Group[udg_AGL__Counter]        = CreateGroup()
                set udg_AGL__MissileX[udg_AGL__Counter]     = GetUnitX(udg_AGL__Caster[udg_AGL__Counter])
                set udg_AGL__MissileY[udg_AGL__Counter]     = GetUnitY(udg_AGL__Caster[udg_AGL__Counter])
                set udg_AGL__MissileFace[udg_AGL__Counter]  = Atan2(GetUnitY(udg_AGL__Target[udg_AGL__Counter]) - udg_AGL__MissileY[udg_AGL__Counter], GetUnitX(udg_AGL__Target[udg_AGL__Counter]) - udg_AGL__MissileX[udg_AGL__Counter])
                set udg_AGL__Missile[udg_AGL__Counter]      = CreateUnit(GetTriggerPlayer(), AGL__DUMMY_ID(), udg_AGL__MissileX[udg_AGL__Counter], udg_AGL__MissileY[udg_AGL__Counter], udg_AGL__MissileFace[udg_AGL__Counter] * bj_RADTODEG)
                set udg_AGL__MissileSfx[udg_AGL__Counter]   = AddSpecialEffectTarget(AGL__MISSILE_SFX(), udg_AGL__Missile[udg_AGL__Counter], "origin")
                
                if UnitAddAbility(udg_AGL__Missile[udg_AGL__Counter], 'Amrf') and UnitRemoveAbility(udg_AGL__Missile[udg_AGL__Counter], 'Amrf') then
                endif
                call SetUnitFlyHeight(udg_AGL__Missile[udg_AGL__Counter], AGL__MISSILE_Z(), 0)
                call SetUnitScale(udg_AGL__Missile[udg_AGL__Counter], AGL__MISSILE_SIZE(), 1, 1)
                
                if udg_AGL__Counter == 1 then
                    call TimerStart(udg_AGL__Timer, AGL__ACCURACY(), true, function AGL__onTick)
                endif
            endif
        endif
        
        return false
    endfunction

    function InitTrig_ArcaneGlaive takes nothing returns nothing
    
        set udg_AGL__MapBounds[0] = GetRectMaxX(bj_mapInitialPlayableArea)
        set udg_AGL__MapBounds[1] = GetRectMinX(bj_mapInitialPlayableArea)
        set udg_AGL__MapBounds[2] = GetRectMaxY(bj_mapInitialPlayableArea)
        set udg_AGL__MapBounds[3] = GetRectMinY(bj_mapInitialPlayableArea)
    
        set gg_trg_ArcaneGlaive = CreateTrigger()
        set udg_AGL__TempGroup = CreateGroup()
        set udg_AGL__Timer = CreateTimer()
        
        call TriggerRegisterAnyUnitEventBJ(gg_trg_ArcaneGlaive, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(gg_trg_ArcaneGlaive, Condition(function AGL__onCast))
        
    endfunction

Now here it is when saved in JNGP. Notice how everything inlines (// INLINED!!). This obviously results in faster code and less memory usage.

JASS:
    constant function AGL__SPELL_ID takes nothing returns integer
        return 'A000'
    endfunction
    
    constant function AGL__DUMMY_ID takes nothing returns integer
        return 'h000'
    endfunction
    
    constant function AGL__HIT_SFX takes nothing returns string
        return "war3mapImported\\Arcane Nova.mdx"
    endfunction
    
    constant function AGL__HIT_SFX_PT takes nothing returns string
        return "origin"
    endfunction
    
    // Missile datas
    constant function AGL__MISSILE_SFX takes nothing returns string
        return "war3mapImported\\ArcaneGlaive_2.mdx"
    endfunction
    
    constant function AGL__MISSILE_SIZE takes nothing returns real
        return 1.0
    endfunction
    
    constant function AGL__MISSILE_SPEED takes nothing returns real
        return 25.0
    endfunction
    
    constant function AGL__MISSILE_TURN_RATE takes nothing returns real
        return 10.75 * bj_DEGTORAD
    endfunction
    
    constant function AGL__MISSILE_LIFESPAN takes nothing returns real
        return 3.0
    endfunction
    
    constant function AGL__MISSILE_Z takes nothing returns real
        return 66.0
    endfunction
    
    // Hit range
    constant function AGL__HIT_RADIUS takes nothing returns real
        return 50.
    endfunction
    
    // Missile decay time
    constant function AGL__SFX_DECAY_TIME takes nothing returns real
        return 3.0
    endfunction
    
    // Target search radius
    constant function AGL__SEARCH_RADIUS_MIN takes nothing returns real
        return 175.
    endfunction
    
    constant function AGL__SEARCH_RADIUS_MAX takes nothing returns real
        return 600.0
    endfunction
    
    // Each unit can only be targeted once
    constant function AGL__TARGETS_ONCE takes nothing returns boolean
        return false
    endfunction
    
    constant function AGL__ACCURACY takes nothing returns real
        return 0.03125
    endfunction
    
    // Type of dealt damage
    constant function AGL__ATTACK_TYPE takes nothing returns attacktype
        return ATTACK_TYPE_NORMAL
    endfunction
    
    constant function AGL__DAMAGE_TYPE takes nothing returns damagetype
        return DAMAGE_TYPE_NORMAL
    endfunction
    
    // Burned mana amount
    constant function AGL__manaBurn takes integer level returns real
        return 5.0 * level
    endfunction
    
    // Dealt damage factor
    constant function AGL__damageFactor takes integer level returns real
        return 4.0
    endfunction
    
    // AoE of damage
    constant function AGL__damageAoE takes integer level returns real
        return 175.0
    endfunction
    
    // Number of jumps
    constant function AGL__bounceCount takes integer level returns integer
        return 2
    endfunction
    
    // Target classification
    constant function AGL__filterTarget takes unit u returns boolean
        return not ( IsUnitType(u, UNIT_TYPE_FLYING) or IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) or IsUnitType(u, UNIT_TYPE_MECHANICAL) or IsUnitType(u, UNIT_TYPE_STRUCTURE) )
    endfunction
    
    // ===========================================================================
    
    constant function AGL__isInBound takes real x,real y returns boolean
        return x < udg_AGL__MapBounds[0] and x > udg_AGL__MapBounds[1] and y < udg_AGL__MapBounds[2] and y > udg_AGL__MapBounds[3]
    endfunction
    
    function AGL__deindex takes integer i returns integer
        
        call DestroyGroup(udg_AGL__Group[i])
        call DestroyEffect(udg_AGL__MissileSfx[i])
        call UnitApplyTimedLife(udg_AGL__Missile[i], 'BTLF', (3.0)) // INLINED!!
        
        set udg_AGL__Caster[i]=udg_AGL__Caster[udg_AGL__Counter]
        set udg_AGL__Target[i]=udg_AGL__Target[udg_AGL__Counter]
        set udg_AGL__Player[i]=udg_AGL__Player[udg_AGL__Counter]
        set udg_AGL__Damage[i]=udg_AGL__Damage[udg_AGL__Counter]
        
        set udg_AGL__Bounce[i]=udg_AGL__Bounce[udg_AGL__Counter]
        set udg_AGL__Mana[i]=udg_AGL__Mana[udg_AGL__Counter]
        set udg_AGL__Lifespan[i]=udg_AGL__Lifespan[udg_AGL__Counter]
        set udg_AGL__MissileX[i]=udg_AGL__MissileX[udg_AGL__Counter]
        set udg_AGL__AoE[i]=udg_AGL__AoE[udg_AGL__Counter]
        
        set udg_AGL__MissileY[i]=udg_AGL__MissileY[udg_AGL__Counter]
        set udg_AGL__Missile[i]=udg_AGL__Missile[udg_AGL__Counter]
        set udg_AGL__MissileFace[i]=udg_AGL__MissileFace[udg_AGL__Counter]
        set udg_AGL__MissileSfx[i]=udg_AGL__MissileSfx[udg_AGL__Counter]
        set udg_AGL__Group[i]=udg_AGL__Group[udg_AGL__Counter]
        
        set udg_AGL__Group[udg_AGL__Counter]=null
        set udg_AGL__MissileSfx[udg_AGL__Counter]=null
        set udg_AGL__Missile[udg_AGL__Counter]=null
        set udg_AGL__Caster[udg_AGL__Counter]=null
        set udg_AGL__Target[udg_AGL__Counter]=null
        
        set udg_AGL__Counter=udg_AGL__Counter - 1
        if udg_AGL__Counter < 1 then
            call PauseTimer(udg_AGL__Timer)
        else
            return i - 1
        endif
        
        return i
    endfunction
    
    function AGL__getTarget takes integer i returns unit
        
        local real m= - 1
        local unit u
        local real x
        local real y
        
        call GroupEnumUnitsInRange(udg_AGL__TempGroup, udg_AGL__MissileX[i], udg_AGL__MissileY[i], (600.0), null) // INLINED!!
        loop
            set u=FirstOfGroup(udg_AGL__TempGroup)
            exitwhen u == null
            if u != udg_AGL__Target[i] and not IsUnitInGroup(u, udg_AGL__Group[i]) and AGL__filterTarget(u) then
                if IsPlayerAlly(GetOwningPlayer(u), udg_AGL__Player[i]) and GetUnitState(u, UNIT_STATE_MANA) > m then
                    set x=GetUnitX(u)
                    set y=GetUnitY(u)
                    if ( udg_AGL__MissileX[i] - x ) * ( udg_AGL__MissileX[i] - x ) + ( udg_AGL__MissileY[i] - y ) * ( udg_AGL__MissileY[i] - y ) > (175.) * (175.) then // INLINED!!
                        if GetWidgetLife(u) > 0.405 then
                            set udg_AGL__TempUnit=u
                            set m=GetUnitState(u, UNIT_STATE_MANA)
                        endif
                    endif
                endif
            endif
            call GroupRemoveUnit(udg_AGL__TempGroup, u)
        endloop
        
        return udg_AGL__TempUnit
    endfunction
    
    function AGL__onTick takes nothing returns nothing
        
        local integer i= 1
        local real a
        local real x
        local real y
        local real m
        
        loop
            exitwhen i > udg_AGL__Counter
            if udg_AGL__Lifespan[i] > (0.03125) then // INLINED!!
            
                set udg_AGL__Lifespan[i]=udg_AGL__Lifespan[i] - (0.03125) // INLINED!!
                set x=GetUnitX(udg_AGL__Target[i])
                set y=GetUnitY(udg_AGL__Target[i])
                set a=Atan2(y - udg_AGL__MissileY[i], x - udg_AGL__MissileX[i])
                
                if Cos(udg_AGL__MissileFace[i] - a) < Cos((10.75 * bj_DEGTORAD)) then // INLINED!!
                    if Sin(a - udg_AGL__MissileFace[i]) >= 0 then
                        set udg_AGL__MissileFace[i]=udg_AGL__MissileFace[i] + (10.75 * bj_DEGTORAD) // INLINED!!
                    else
                        set udg_AGL__MissileFace[i]=udg_AGL__MissileFace[i] - (10.75 * bj_DEGTORAD) // INLINED!!
                    endif
                else
                    set udg_AGL__MissileFace[i]=a
                endif
                
                set udg_AGL__MissileX[i]=udg_AGL__MissileX[i] + (25.0) * Cos(udg_AGL__MissileFace[i]) // INLINED!!
                set udg_AGL__MissileY[i]=udg_AGL__MissileY[i] + (25.0) * Sin(udg_AGL__MissileFace[i]) // INLINED!!
                
                if AGL__isInBound(udg_AGL__MissileX[i] , udg_AGL__MissileY[i]) then
                    if ( udg_AGL__MissileX[i] - x ) * ( udg_AGL__MissileX[i] - x ) + ( udg_AGL__MissileY[i] - y ) * ( udg_AGL__MissileY[i] - y ) < (50.) * (50.) then // INLINED!!
                        set m=GetUnitState(udg_AGL__Target[i], UNIT_STATE_MANA)
                        call SetUnitState(udg_AGL__Target[i], UNIT_STATE_MANA, m - udg_AGL__Mana[i])
                        set m=m - GetUnitState(udg_AGL__Target[i], UNIT_STATE_MANA)
                        call DestroyEffect(AddSpecialEffectTarget(("war3mapImported\\Arcane Nova.mdx"), udg_AGL__Target[i], ("origin"))) // INLINED!!
                        
                        call GroupEnumUnitsInRange(udg_AGL__TempGroup, udg_AGL__MissileX[i], udg_AGL__MissileY[i], udg_AGL__AoE[i], null)
                        loop
                            set udg_AGL__TempUnit=FirstOfGroup(udg_AGL__TempGroup)
                            exitwhen udg_AGL__TempUnit == null
                            if IsPlayerAlly(GetOwningPlayer(udg_AGL__TempUnit), udg_AGL__Player[i]) and GetWidgetLife(udg_AGL__TempUnit) > 0.405 then
                                if AGL__filterTarget(udg_AGL__TempUnit) then
                                    call UnitDamageTarget(udg_AGL__Caster[i], udg_AGL__TempUnit, m, false, false, (ATTACK_TYPE_NORMAL), (DAMAGE_TYPE_NORMAL), null) // INLINED!!
                                endif
                            endif
                            call GroupRemoveUnit(udg_AGL__TempGroup, udg_AGL__TempUnit)
                        endloop
                        
                        if udg_AGL__Bounce[i] > 0 then
                            set udg_AGL__Bounce[i]=udg_AGL__Bounce[i] - 1
                            if (false) then // INLINED!!
                                call GroupAddUnit(udg_AGL__Group[i], udg_AGL__Target[i])
                            endif
                            set udg_AGL__Target[i]=AGL__getTarget(i)
                            if udg_AGL__Target[i] == null then
                                set i=AGL__deindex(i)
                            else
                                set udg_AGL__Lifespan[i]=(3.0) // INLINED!!
                            endif
                        else
                            set i=AGL__deindex(i)
                        endif
                    else
                        call SetUnitX(udg_AGL__Missile[i], udg_AGL__MissileX[i])
                        call SetUnitY(udg_AGL__Missile[i], udg_AGL__MissileY[i])
                    endif
                else
                    set i=AGL__deindex(i)
                endif
            else
                set i=AGL__deindex(i)
            endif
            set i=i + 1
        endloop
        
    endfunction
    
    function AGL__onCast takes nothing returns boolean
        
        local integer l
    
        if GetSpellAbilityId() == ('A000') then // INLINED!!
            if AGL__filterTarget(GetSpellTargetUnit()) then
                set udg_AGL__Counter=udg_AGL__Counter + 1
                set udg_AGL__Caster[udg_AGL__Counter]=GetTriggerUnit()
                set udg_AGL__Target[udg_AGL__Counter]=GetSpellTargetUnit()
                set udg_AGL__Player[udg_AGL__Counter]=GetOwningPlayer(udg_AGL__Target[udg_AGL__Counter])
                
                set l=GetUnitAbilityLevel(udg_AGL__Caster[udg_AGL__Counter], ('A000')) // INLINED!!
                set udg_AGL__Lifespan[udg_AGL__Counter]=(3.0) // INLINED!!
                set udg_AGL__Damage[udg_AGL__Counter]=AGL__damageFactor(l)
                set udg_AGL__Bounce[udg_AGL__Counter]=AGL__bounceCount(l)
                set udg_AGL__Mana[udg_AGL__Counter]=(5.0 * (l)) // INLINED!!
                set udg_AGL__AoE[udg_AGL__Counter]=AGL__damageAoE(l)
                
                set udg_AGL__Group[udg_AGL__Counter]=CreateGroup()
                set udg_AGL__MissileX[udg_AGL__Counter]=GetUnitX(udg_AGL__Caster[udg_AGL__Counter])
                set udg_AGL__MissileY[udg_AGL__Counter]=GetUnitY(udg_AGL__Caster[udg_AGL__Counter])
                set udg_AGL__MissileFace[udg_AGL__Counter]=Atan2(GetUnitY(udg_AGL__Target[udg_AGL__Counter]) - udg_AGL__MissileY[udg_AGL__Counter], GetUnitX(udg_AGL__Target[udg_AGL__Counter]) - udg_AGL__MissileX[udg_AGL__Counter])
                set udg_AGL__Missile[udg_AGL__Counter]=CreateUnit(GetTriggerPlayer(), ('h000'), udg_AGL__MissileX[udg_AGL__Counter], udg_AGL__MissileY[udg_AGL__Counter], udg_AGL__MissileFace[udg_AGL__Counter] * bj_RADTODEG) // INLINED!!
                set udg_AGL__MissileSfx[udg_AGL__Counter]=AddSpecialEffectTarget(("war3mapImported\\ArcaneGlaive_2.mdx"), udg_AGL__Missile[udg_AGL__Counter], "origin") // INLINED!!
                
                if UnitAddAbility(udg_AGL__Missile[udg_AGL__Counter], 'Amrf') and UnitRemoveAbility(udg_AGL__Missile[udg_AGL__Counter], 'Amrf') then
                endif
                call SetUnitFlyHeight(udg_AGL__Missile[udg_AGL__Counter], (66.0), 0) // INLINED!!
                call SetUnitScale(udg_AGL__Missile[udg_AGL__Counter], (1.0), 1, 1) // INLINED!!
                
                if udg_AGL__Counter == 1 then
                    call TimerStart(udg_AGL__Timer, (0.03125), true, function AGL__onTick) // INLINED!!
                endif
            endif
        endif
        
        return false
    endfunction

    function InitTrig_ArcaneGlaive takes nothing returns nothing
    
        set udg_AGL__MapBounds[0]=GetRectMaxX(bj_mapInitialPlayableArea)
        set udg_AGL__MapBounds[1]=GetRectMinX(bj_mapInitialPlayableArea)
        set udg_AGL__MapBounds[2]=GetRectMaxY(bj_mapInitialPlayableArea)
        set udg_AGL__MapBounds[3]=GetRectMinY(bj_mapInitialPlayableArea)
    
        set gg_trg_ArcaneGlaive=CreateTrigger()
        set udg_AGL__TempGroup=CreateGroup()
        set udg_AGL__Timer=CreateTimer()
        
        call TriggerRegisterAnyUnitEventBJ(gg_trg_ArcaneGlaive, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(gg_trg_ArcaneGlaive, Condition(function AGL__onCast))
        
    endfunction

Now here's the final script when ran through vex's map optimizer. 99% of people use this tool before publishing their map (real statistic).

JASS:
constant function AGL__manaBurn takes integer level returns real
	return 5.*level
endfunction

constant function AGL__damageFactor takes integer level returns real
	return 4.
endfunction

constant function AGL__damageAoE takes integer level returns real
	return 175.
endfunction

constant function AGL__bounceCount takes integer level returns integer
	return 2
endfunction

constant function AGL__filterTarget takes unit u returns boolean
	return not(IsUnitType(u,UNIT_TYPE_FLYING)or IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)or IsUnitType(u,UNIT_TYPE_MECHANICAL)or IsUnitType(u,UNIT_TYPE_STRUCTURE))
endfunction

constant function AGL__isInBound takes real x,real y returns boolean
	return x<udg_AGL__MapBounds[0]and x>udg_AGL__MapBounds[1]and y<udg_AGL__MapBounds[2]and y>udg_AGL__MapBounds[3]
endfunction

function AGL__deindex takes integer i returns integer
	call DestroyGroup(udg_AGL__Group[i])
	call DestroyEffect(udg_AGL__MissileSfx[i])
	call UnitApplyTimedLife(udg_AGL__Missile[i],'BTLF',(3.))
	set udg_AGL__Caster[i]=udg_AGL__Caster[udg_AGL__Counter]
	set udg_AGL__Target[i]=udg_AGL__Target[udg_AGL__Counter]
	set udg_AGL__Player[i]=udg_AGL__Player[udg_AGL__Counter]
	set udg_AGL__Damage[i]=udg_AGL__Damage[udg_AGL__Counter]
	set udg_AGL__Bounce[i]=udg_AGL__Bounce[udg_AGL__Counter]
	set udg_AGL__Mana[i]=udg_AGL__Mana[udg_AGL__Counter]
	set udg_AGL__Lifespan[i]=udg_AGL__Lifespan[udg_AGL__Counter]
	set udg_AGL__MissileX[i]=udg_AGL__MissileX[udg_AGL__Counter]
	set udg_AGL__AoE[i]=udg_AGL__AoE[udg_AGL__Counter]
	set udg_AGL__MissileY[i]=udg_AGL__MissileY[udg_AGL__Counter]
	set udg_AGL__Missile[i]=udg_AGL__Missile[udg_AGL__Counter]
	set udg_AGL__MissileFace[i]=udg_AGL__MissileFace[udg_AGL__Counter]
	set udg_AGL__MissileSfx[i]=udg_AGL__MissileSfx[udg_AGL__Counter]
	set udg_AGL__Group[i]=udg_AGL__Group[udg_AGL__Counter]
	set udg_AGL__Group[udg_AGL__Counter]=null
	set udg_AGL__MissileSfx[udg_AGL__Counter]=null
	set udg_AGL__Missile[udg_AGL__Counter]=null
	set udg_AGL__Caster[udg_AGL__Counter]=null
	set udg_AGL__Target[udg_AGL__Counter]=null
	set udg_AGL__Counter=udg_AGL__Counter-1
	if udg_AGL__Counter<1 then
	call PauseTimer(udg_AGL__Timer)
	else
	return i-1
	endif
	return i
endfunction
function AGL__getTarget takes integer i returns unit
	local real m=-1
	local unit u
	local real x
	local real y
	call GroupEnumUnitsInRange(udg_AGL__TempGroup,udg_AGL__MissileX[i],udg_AGL__MissileY[i],(600.),null)
	loop
	set u=FirstOfGroup(udg_AGL__TempGroup)
	exitwhen u==null
	if u!=udg_AGL__Target[i]and not IsUnitInGroup(u,udg_AGL__Group[i])and AGL__filterTarget(u)then
	if IsPlayerAlly(GetOwningPlayer(u),udg_AGL__Player[i])and GetUnitState(u,UNIT_STATE_MANA)>m then
	set x=GetUnitX(u)
	set y=GetUnitY(u)
	if(udg_AGL__MissileX[i]-x)*(udg_AGL__MissileX[i]-x)+(udg_AGL__MissileY[i]-y)*(udg_AGL__MissileY[i]-y)>(175.)*(175.)then
	if GetWidgetLife(u)>.405 then
	set udg_AGL__TempUnit=u
	set m=GetUnitState(u,UNIT_STATE_MANA)
	endif
	endif
	endif
	endif
	call GroupRemoveUnit(udg_AGL__TempGroup,u)
	endloop
	return udg_AGL__TempUnit
endfunction
function AGL__onTick takes nothing returns nothing
	local integer i=1
	local real a
	local real x
	local real y
	local real m
	loop
	exitwhen i>udg_AGL__Counter
	if udg_AGL__Lifespan[i]>(.03125)then
	set udg_AGL__Lifespan[i]=udg_AGL__Lifespan[i]-(.03125)
	set x=GetUnitX(udg_AGL__Target[i])
	set y=GetUnitY(udg_AGL__Target[i])
	set a=Atan2(y-udg_AGL__MissileY[i],x-udg_AGL__MissileX[i])
	if Cos(udg_AGL__MissileFace[i]-a)<Cos((10.75*bj_DEGTORAD))then
	if Sin(a-udg_AGL__MissileFace[i])>=0 then
	set udg_AGL__MissileFace[i]=udg_AGL__MissileFace[i]+(10.75*bj_DEGTORAD)
	else
	set udg_AGL__MissileFace[i]=udg_AGL__MissileFace[i]-(10.75*bj_DEGTORAD)
	endif
	else
	set udg_AGL__MissileFace[i]=a
	endif
	set udg_AGL__MissileX[i]=udg_AGL__MissileX[i]+(25.)*Cos(udg_AGL__MissileFace[i])
	set udg_AGL__MissileY[i]=udg_AGL__MissileY[i]+(25.)*Sin(udg_AGL__MissileFace[i])
	if AGL__isInBound(udg_AGL__MissileX[i],udg_AGL__MissileY[i])then
	if(udg_AGL__MissileX[i]-x)*(udg_AGL__MissileX[i]-x)+(udg_AGL__MissileY[i]-y)*(udg_AGL__MissileY[i]-y)<(50.)*(50.)then
	set m=GetUnitState(udg_AGL__Target[i],UNIT_STATE_MANA)
	call SetUnitState(udg_AGL__Target[i],UNIT_STATE_MANA,m-udg_AGL__Mana[i])
	set m=m-GetUnitState(udg_AGL__Target[i],UNIT_STATE_MANA)
	call DestroyEffect(AddSpecialEffectTarget(("war3mapImported\\Arcane Nova.mdx"),udg_AGL__Target[i],("origin")))
	call GroupEnumUnitsInRange(udg_AGL__TempGroup,udg_AGL__MissileX[i],udg_AGL__MissileY[i],udg_AGL__AoE[i],null)
	loop
	set udg_AGL__TempUnit=FirstOfGroup(udg_AGL__TempGroup)
	exitwhen udg_AGL__TempUnit==null
	if IsPlayerAlly(GetOwningPlayer(udg_AGL__TempUnit),udg_AGL__Player[i])and GetWidgetLife(udg_AGL__TempUnit)>.405 then
	if AGL__filterTarget(udg_AGL__TempUnit)then
	call UnitDamageTarget(udg_AGL__Caster[i],udg_AGL__TempUnit,m,false,false,(ATTACK_TYPE_NORMAL),(DAMAGE_TYPE_NORMAL),null)
	endif
	endif
	call GroupRemoveUnit(udg_AGL__TempGroup,udg_AGL__TempUnit)
	endloop
	if udg_AGL__Bounce[i]>0 then
	set udg_AGL__Bounce[i]=udg_AGL__Bounce[i]-1
	if(false)then
	call GroupAddUnit(udg_AGL__Group[i],udg_AGL__Target[i])
	endif
	set udg_AGL__Target[i]=AGL__getTarget(i)
	if udg_AGL__Target[i]==null then
	set i=AGL__deindex(i)
	else
	set udg_AGL__Lifespan[i]=(3.)
	endif
	else
	set i=AGL__deindex(i)
	endif
	else
	call SetUnitX(udg_AGL__Missile[i],udg_AGL__MissileX[i])
	call SetUnitY(udg_AGL__Missile[i],udg_AGL__MissileY[i])
	endif
	else
	set i=AGL__deindex(i)
	endif
	else
	set i=AGL__deindex(i)
	endif
	set i=i+1
	endloop
endfunction
function AGL__onCast takes nothing returns boolean
	local integer l
	if GetSpellAbilityId()==('A000')then
	if AGL__filterTarget(GetSpellTargetUnit())then
	set udg_AGL__Counter=udg_AGL__Counter+1
	set udg_AGL__Caster[udg_AGL__Counter]=GetTriggerUnit()
	set udg_AGL__Target[udg_AGL__Counter]=GetSpellTargetUnit()
	set udg_AGL__Player[udg_AGL__Counter]=GetOwningPlayer(udg_AGL__Target[udg_AGL__Counter])
	set l=GetUnitAbilityLevel(udg_AGL__Caster[udg_AGL__Counter],('A000'))
	set udg_AGL__Lifespan[udg_AGL__Counter]=(3.)
	set udg_AGL__Damage[udg_AGL__Counter]=AGL__damageFactor(l)
	set udg_AGL__Bounce[udg_AGL__Counter]=AGL__bounceCount(l)
	set udg_AGL__Mana[udg_AGL__Counter]=(5.*(l))
	set udg_AGL__AoE[udg_AGL__Counter]=AGL__damageAoE(l)
	set udg_AGL__Group[udg_AGL__Counter]=CreateGroup()
	set udg_AGL__MissileX[udg_AGL__Counter]=GetUnitX(udg_AGL__Caster[udg_AGL__Counter])
	set udg_AGL__MissileY[udg_AGL__Counter]=GetUnitY(udg_AGL__Caster[udg_AGL__Counter])
	set udg_AGL__MissileFace[udg_AGL__Counter]=Atan2(GetUnitY(udg_AGL__Target[udg_AGL__Counter])-udg_AGL__MissileY[udg_AGL__Counter],GetUnitX(udg_AGL__Target[udg_AGL__Counter])-udg_AGL__MissileX[udg_AGL__Counter])
	set udg_AGL__Missile[udg_AGL__Counter]=CreateUnit(GetTriggerPlayer(),('h000'),udg_AGL__MissileX[udg_AGL__Counter],udg_AGL__MissileY[udg_AGL__Counter],udg_AGL__MissileFace[udg_AGL__Counter]*bj_RADTODEG)
	set udg_AGL__MissileSfx[udg_AGL__Counter]=AddSpecialEffectTarget(("war3mapImported\\ArcaneGlaive_2.mdx"),udg_AGL__Missile[udg_AGL__Counter],"origin")
	if UnitAddAbility(udg_AGL__Missile[udg_AGL__Counter],'Amrf')and UnitRemoveAbility(udg_AGL__Missile[udg_AGL__Counter],'Amrf')then
	endif
	call SetUnitFlyHeight(udg_AGL__Missile[udg_AGL__Counter],(66.),0)
	call SetUnitScale(udg_AGL__Missile[udg_AGL__Counter],(1.),1,1)
	if udg_AGL__Counter==1 then
	call TimerStart(udg_AGL__Timer,(.03125),true,function AGL__onTick)
	endif
	endif
	endif
	return false
endfunction
function InitTrig_ArcaneGlaive takes nothing returns nothing
	set udg_AGL__MapBounds[0]=GetRectMaxX(bj_mapInitialPlayableArea)
	set udg_AGL__MapBounds[1]=GetRectMinX(bj_mapInitialPlayableArea)
	set udg_AGL__MapBounds[2]=GetRectMaxY(bj_mapInitialPlayableArea)
	set udg_AGL__MapBounds[3]=GetRectMinY(bj_mapInitialPlayableArea)
	set gg_trg_ArcaneGlaive=CreateTrigger()
	set udg_AGL__TempGroup=CreateGroup()
	set udg_AGL__Timer=CreateTimer()
	call TriggerRegisterAnyUnitEventBJ(gg_trg_ArcaneGlaive,EVENT_PLAYER_UNIT_SPELL_EFFECT)
	call TriggerAddCondition(gg_trg_ArcaneGlaive,Condition(function AGL__onCast))
endfunction

In your case constant functions are the best solution, please use them :thumbs_up:
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Here's your spell with constant functions instead of mass amounts of globals.

JASS:
    // by Dalvengyr @Hiveworkshop.com
    // ******************************************************
    //
    //                      Arcane Glaive v1.1
    //
    // Description
    // Causes Spell Breaker's attacks to deal no physical damage.
    // Arcane Glaive will burn mana on hit and deals 4x of
    // burned mana as magic damage to units within 175 AoE.
    // The glaive will bounce 2 times before expired.
    //
    // How to import
    // - Copy this trigger folder into your map
    // - Copy dummy unit into your map
    // - Configure the spell
    //
    // Credits:
    // - ArcaneNova.mdx by dhguardianes
    // - ArcaneGlaive.mdx by Infrisios
    // - BloodElfSpellThief.blp by shockwave
    // - BTNTranquilityStar by QuadraDowN
    //
    // ******************************************************
    
    // Configurations
    
    constant function AGL__SPELL_ID takes nothing returns integer
        return 'A000'
    endfunction
    
    constant function AGL__DUMMY_ID takes nothing returns integer
        return 'h000'
    endfunction
    
    constant function AGL__HIT_SFX  takes nothing returns string
        return "war3mapImported\\Arcane Nova.mdx"
    endfunction
    
    constant function AGL__HIT_SFX_PT  takes nothing returns string
        return "origin"
    endfunction
    
    // Missile datas
    constant function AGL__MISSILE_SFX  takes nothing returns string
        return "war3mapImported\\ArcaneGlaive_2.mdx"
    endfunction
    
    constant function AGL__MISSILE_SIZE takes nothing returns real
        return 1.0
    endfunction
    
    constant function AGL__MISSILE_SPEED takes nothing returns real
        return 25.0
    endfunction
    
    constant function AGL__MISSILE_TURN_RATE takes nothing returns real
        return 10.75 * bj_DEGTORAD
    endfunction
    
    constant function AGL__MISSILE_LIFESPAN takes nothing returns real
        return 3.0
    endfunction
    
    constant function AGL__MISSILE_Z takes nothing returns real
        return 66.0
    endfunction
    
    // Hit range
    constant function AGL__HIT_RADIUS takes nothing returns real
        return 50.
    endfunction
    
    // Missile decay time
    constant function AGL__SFX_DECAY_TIME takes nothing returns real
        return 3.0
    endfunction
    
    // Target search radius
    constant function AGL__SEARCH_RADIUS_MIN takes nothing returns real
        return 175.
    endfunction
    
    constant function AGL__SEARCH_RADIUS_MAX takes nothing returns real
        return 600.0
    endfunction
    
    // Each unit can only be targeted once
    constant function AGL__TARGETS_ONCE takes nothing returns boolean
        return false
    endfunction
    
    constant function AGL__ACCURACY takes nothing returns real
        return 0.03125
    endfunction
    
    // Type of dealt damage
    constant function AGL__ATTACK_TYPE takes nothing returns attacktype
        return ATTACK_TYPE_NORMAL
    endfunction
    
    constant function AGL__DAMAGE_TYPE takes nothing returns damagetype
        return DAMAGE_TYPE_NORMAL
    endfunction
    
    // Burned mana amount
    constant function AGL__manaBurn takes integer level returns real
        return 5.0 * level
    endfunction
    
    // Dealt damage factor
    constant function AGL__damageFactor takes integer level returns real
        return 4.0
    endfunction
    
    // AoE of damage
    constant function AGL__damageAoE takes integer level returns real
        return 175.0
    endfunction
    
    // Number of jumps
    constant function AGL__bounceCount takes integer level returns integer
        return 2
    endfunction
    
    // Target classification
    constant function AGL__filterTarget takes unit u returns boolean
        return not(IsUnitType(u, UNIT_TYPE_FLYING) or IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) or IsUnitType(u, UNIT_TYPE_MECHANICAL) or IsUnitType(u, UNIT_TYPE_STRUCTURE))
    endfunction
    
    // ===========================================================================
    
    constant function AGL__isInBound takes real x, real y returns boolean
        return x < udg_AGL__MapBounds[0] and x > udg_AGL__MapBounds[1] and y < udg_AGL__MapBounds[2] and y > udg_AGL__MapBounds[3]
    endfunction
    
    function AGL__deindex takes integer i returns integer
        
        call DestroyGroup(udg_AGL__Group[i])
        call DestroyEffect(udg_AGL__MissileSfx[i])
        call UnitApplyTimedLife(udg_AGL__Missile[i], 'BTLF', AGL__SFX_DECAY_TIME())
        
        set udg_AGL__Caster[i]       = udg_AGL__Caster[udg_AGL__Counter]
        set udg_AGL__Target[i]       = udg_AGL__Target[udg_AGL__Counter]
        set udg_AGL__Player[i]       = udg_AGL__Player[udg_AGL__Counter]
        set udg_AGL__Damage[i]       = udg_AGL__Damage[udg_AGL__Counter]
        
        set udg_AGL__Bounce[i]       = udg_AGL__Bounce[udg_AGL__Counter]
        set udg_AGL__Mana[i]         = udg_AGL__Mana[udg_AGL__Counter]
        set udg_AGL__Lifespan[i]     = udg_AGL__Lifespan[udg_AGL__Counter]
        set udg_AGL__MissileX[i]     = udg_AGL__MissileX[udg_AGL__Counter]
        set udg_AGL__AoE[i]          = udg_AGL__AoE[udg_AGL__Counter]
        
        set udg_AGL__MissileY[i]     = udg_AGL__MissileY[udg_AGL__Counter]
        set udg_AGL__Missile[i]      = udg_AGL__Missile[udg_AGL__Counter]
        set udg_AGL__MissileFace[i]  = udg_AGL__MissileFace[udg_AGL__Counter]
        set udg_AGL__MissileSfx[i]   = udg_AGL__MissileSfx[udg_AGL__Counter]
        set udg_AGL__Group[i]        = udg_AGL__Group[udg_AGL__Counter]
        
        set udg_AGL__Group[udg_AGL__Counter]        = null
        set udg_AGL__MissileSfx[udg_AGL__Counter]   = null
        set udg_AGL__Missile[udg_AGL__Counter]      = null
        set udg_AGL__Caster[udg_AGL__Counter]       = null
        set udg_AGL__Target[udg_AGL__Counter]       = null
        
        set udg_AGL__Counter = udg_AGL__Counter - 1
        if udg_AGL__Counter < 1 then
            call PauseTimer(udg_AGL__Timer)
        else
            return i - 1
        endif
        
        return i
    endfunction
    
    function AGL__getTarget takes integer i returns unit
        
        local real m = -1
        local unit u
        local real x
        local real y
        
        call GroupEnumUnitsInRange(udg_AGL__TempGroup, udg_AGL__MissileX[i], udg_AGL__MissileY[i], AGL__SEARCH_RADIUS_MAX(), null)
        loop
            set u = FirstOfGroup(udg_AGL__TempGroup)
            exitwhen u == null
            if u != udg_AGL__Target[i] and not IsUnitInGroup(u, udg_AGL__Group[i]) and AGL__filterTarget(u) then
                if IsPlayerAlly(GetOwningPlayer(u), udg_AGL__Player[i]) and GetUnitState(u, UNIT_STATE_MANA) > m then
                    set x = GetUnitX(u)
                    set y = GetUnitY(u)
                    if (udg_AGL__MissileX[i] - x)*(udg_AGL__MissileX[i] - x)+(udg_AGL__MissileY[i] - y)*(udg_AGL__MissileY[i] - y) > AGL__SEARCH_RADIUS_MIN() * AGL__SEARCH_RADIUS_MIN() then
                        if GetWidgetLife(u) > 0.405 then
                            set udg_AGL__TempUnit = u
                            set m = GetUnitState(u, UNIT_STATE_MANA)
                        endif
                    endif
                endif
            endif
            call GroupRemoveUnit(udg_AGL__TempGroup, u)
        endloop
        
        return udg_AGL__TempUnit
    endfunction
    
    function AGL__onTick takes nothing  returns nothing
        
        local integer i = 1
        local real a
        local real x
        local real y
        local real m
        
        loop
            exitwhen i > udg_AGL__Counter
            if udg_AGL__Lifespan[i] > AGL__ACCURACY() then
            
                set udg_AGL__Lifespan[i] = udg_AGL__Lifespan[i] - AGL__ACCURACY()
                set x = GetUnitX(udg_AGL__Target[i])
                set y = GetUnitY(udg_AGL__Target[i])
                set a = Atan2(y - udg_AGL__MissileY[i], x - udg_AGL__MissileX[i])
                
                if Cos(udg_AGL__MissileFace[i] - a) < Cos(AGL__MISSILE_TURN_RATE()) then
                    if Sin(a - udg_AGL__MissileFace[i]) >= 0 then
                        set udg_AGL__MissileFace[i] = udg_AGL__MissileFace[i] + AGL__MISSILE_TURN_RATE()
                    else
                        set udg_AGL__MissileFace[i] = udg_AGL__MissileFace[i] - AGL__MISSILE_TURN_RATE()
                    endif
                else
                    set udg_AGL__MissileFace[i] = a
                endif
                
                set udg_AGL__MissileX[i] = udg_AGL__MissileX[i] + AGL__MISSILE_SPEED() * Cos(udg_AGL__MissileFace[i])
                set udg_AGL__MissileY[i] = udg_AGL__MissileY[i] + AGL__MISSILE_SPEED() * Sin(udg_AGL__MissileFace[i])
                
                if AGL__isInBound(udg_AGL__MissileX[i], udg_AGL__MissileY[i]) then
                    if (udg_AGL__MissileX[i] - x)*(udg_AGL__MissileX[i] - x)+(udg_AGL__MissileY[i] - y)*(udg_AGL__MissileY[i] - y) < AGL__HIT_RADIUS() * AGL__HIT_RADIUS() then
                        set m = GetUnitState(udg_AGL__Target[i], UNIT_STATE_MANA)
                        call SetUnitState(udg_AGL__Target[i], UNIT_STATE_MANA, m - udg_AGL__Mana[i])
                        set m = m - GetUnitState(udg_AGL__Target[i], UNIT_STATE_MANA)
                        call DestroyEffect(AddSpecialEffectTarget(AGL__HIT_SFX(), udg_AGL__Target[i], AGL__HIT_SFX_PT()))
                        
                        call GroupEnumUnitsInRange(udg_AGL__TempGroup, udg_AGL__MissileX[i], udg_AGL__MissileY[i], udg_AGL__AoE[i], null)
                        loop
                            set udg_AGL__TempUnit = FirstOfGroup(udg_AGL__TempGroup)
                            exitwhen udg_AGL__TempUnit == null
                            if IsPlayerAlly(GetOwningPlayer(udg_AGL__TempUnit), udg_AGL__Player[i]) and GetWidgetLife(udg_AGL__TempUnit) > 0.405 then
                                if AGL__filterTarget(udg_AGL__TempUnit) then
                                    call UnitDamageTarget(udg_AGL__Caster[i], udg_AGL__TempUnit, m, false, false, AGL__ATTACK_TYPE(), AGL__DAMAGE_TYPE(), null)
                                endif
                            endif
                            call GroupRemoveUnit(udg_AGL__TempGroup, udg_AGL__TempUnit)
                        endloop
                        
                        if udg_AGL__Bounce[i] > 0 then
                            set udg_AGL__Bounce[i] = udg_AGL__Bounce[i] - 1
                            if AGL__TARGETS_ONCE() then
                                call GroupAddUnit(udg_AGL__Group[i], udg_AGL__Target[i])
                            endif
                            set udg_AGL__Target[i] = AGL__getTarget(i)
                            if udg_AGL__Target[i] == null then
                                set i = AGL__deindex(i)
                            else
                                set udg_AGL__Lifespan[i] = AGL__MISSILE_LIFESPAN()
                            endif
                        else
                            set i = AGL__deindex(i)
                        endif
                    else
                        call SetUnitX(udg_AGL__Missile[i], udg_AGL__MissileX[i])
                        call SetUnitY(udg_AGL__Missile[i], udg_AGL__MissileY[i])
                    endif
                else
                    set i = AGL__deindex(i)
                endif
            else
                set i = AGL__deindex(i)
            endif
            set i = i + 1
        endloop
        
    endfunction
    
    function AGL__onCast takes nothing  returns boolean
        
        local integer l
    
        if GetSpellAbilityId() == AGL__SPELL_ID() then
            if AGL__filterTarget(GetSpellTargetUnit()) then
                set udg_AGL__Counter = udg_AGL__Counter + 1
                set udg_AGL__Caster[udg_AGL__Counter]       = GetTriggerUnit()
                set udg_AGL__Target[udg_AGL__Counter]       = GetSpellTargetUnit()
                set udg_AGL__Player[udg_AGL__Counter]       = GetOwningPlayer(udg_AGL__Target[udg_AGL__Counter])
                
                set l = GetUnitAbilityLevel(udg_AGL__Caster[udg_AGL__Counter], AGL__SPELL_ID())
                set udg_AGL__Lifespan[udg_AGL__Counter]     = AGL__MISSILE_LIFESPAN()
                set udg_AGL__Damage[udg_AGL__Counter]       = AGL__damageFactor(l)
                set udg_AGL__Bounce[udg_AGL__Counter]       = AGL__bounceCount(l)
                set udg_AGL__Mana[udg_AGL__Counter]         = AGL__manaBurn(l)
                set udg_AGL__AoE[udg_AGL__Counter]          = AGL__damageAoE(l)
                
                set udg_AGL__Group[udg_AGL__Counter]        = CreateGroup()
                set udg_AGL__MissileX[udg_AGL__Counter]     = GetUnitX(udg_AGL__Caster[udg_AGL__Counter])
                set udg_AGL__MissileY[udg_AGL__Counter]     = GetUnitY(udg_AGL__Caster[udg_AGL__Counter])
                set udg_AGL__MissileFace[udg_AGL__Counter]  = Atan2(GetUnitY(udg_AGL__Target[udg_AGL__Counter]) - udg_AGL__MissileY[udg_AGL__Counter], GetUnitX(udg_AGL__Target[udg_AGL__Counter]) - udg_AGL__MissileX[udg_AGL__Counter])
                set udg_AGL__Missile[udg_AGL__Counter]      = CreateUnit(GetTriggerPlayer(), AGL__DUMMY_ID(), udg_AGL__MissileX[udg_AGL__Counter], udg_AGL__MissileY[udg_AGL__Counter], udg_AGL__MissileFace[udg_AGL__Counter] * bj_RADTODEG)
                set udg_AGL__MissileSfx[udg_AGL__Counter]   = AddSpecialEffectTarget(AGL__MISSILE_SFX(), udg_AGL__Missile[udg_AGL__Counter], "origin")
                
                if UnitAddAbility(udg_AGL__Missile[udg_AGL__Counter], 'Amrf') and UnitRemoveAbility(udg_AGL__Missile[udg_AGL__Counter], 'Amrf') then
                endif
                call SetUnitFlyHeight(udg_AGL__Missile[udg_AGL__Counter], AGL__MISSILE_Z(), 0)
                call SetUnitScale(udg_AGL__Missile[udg_AGL__Counter], AGL__MISSILE_SIZE(), 1, 1)
                
                if udg_AGL__Counter == 1 then
                    call TimerStart(udg_AGL__Timer, AGL__ACCURACY(), true, function AGL__onTick)
                endif
            endif
        endif
        
        return false
    endfunction

    function InitTrig_ArcaneGlaive takes nothing returns nothing
    
        set udg_AGL__MapBounds[0] = GetRectMaxX(bj_mapInitialPlayableArea)
        set udg_AGL__MapBounds[1] = GetRectMinX(bj_mapInitialPlayableArea)
        set udg_AGL__MapBounds[2] = GetRectMaxY(bj_mapInitialPlayableArea)
        set udg_AGL__MapBounds[3] = GetRectMinY(bj_mapInitialPlayableArea)
    
        set gg_trg_ArcaneGlaive = CreateTrigger()
        set udg_AGL__TempGroup = CreateGroup()
        set udg_AGL__Timer = CreateTimer()
        
        call TriggerRegisterAnyUnitEventBJ(gg_trg_ArcaneGlaive, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(gg_trg_ArcaneGlaive, Condition(function AGL__onCast))
        
    endfunction

Now here it is when saved in JNGP. Notice how everything inlines (// INLINED!!). This obviously results in faster code and less memory usage.

JASS:
    constant function AGL__SPELL_ID takes nothing returns integer
        return 'A000'
    endfunction
    
    constant function AGL__DUMMY_ID takes nothing returns integer
        return 'h000'
    endfunction
    
    constant function AGL__HIT_SFX takes nothing returns string
        return "war3mapImported\\Arcane Nova.mdx"
    endfunction
    
    constant function AGL__HIT_SFX_PT takes nothing returns string
        return "origin"
    endfunction
    
    // Missile datas
    constant function AGL__MISSILE_SFX takes nothing returns string
        return "war3mapImported\\ArcaneGlaive_2.mdx"
    endfunction
    
    constant function AGL__MISSILE_SIZE takes nothing returns real
        return 1.0
    endfunction
    
    constant function AGL__MISSILE_SPEED takes nothing returns real
        return 25.0
    endfunction
    
    constant function AGL__MISSILE_TURN_RATE takes nothing returns real
        return 10.75 * bj_DEGTORAD
    endfunction
    
    constant function AGL__MISSILE_LIFESPAN takes nothing returns real
        return 3.0
    endfunction
    
    constant function AGL__MISSILE_Z takes nothing returns real
        return 66.0
    endfunction
    
    // Hit range
    constant function AGL__HIT_RADIUS takes nothing returns real
        return 50.
    endfunction
    
    // Missile decay time
    constant function AGL__SFX_DECAY_TIME takes nothing returns real
        return 3.0
    endfunction
    
    // Target search radius
    constant function AGL__SEARCH_RADIUS_MIN takes nothing returns real
        return 175.
    endfunction
    
    constant function AGL__SEARCH_RADIUS_MAX takes nothing returns real
        return 600.0
    endfunction
    
    // Each unit can only be targeted once
    constant function AGL__TARGETS_ONCE takes nothing returns boolean
        return false
    endfunction
    
    constant function AGL__ACCURACY takes nothing returns real
        return 0.03125
    endfunction
    
    // Type of dealt damage
    constant function AGL__ATTACK_TYPE takes nothing returns attacktype
        return ATTACK_TYPE_NORMAL
    endfunction
    
    constant function AGL__DAMAGE_TYPE takes nothing returns damagetype
        return DAMAGE_TYPE_NORMAL
    endfunction
    
    // Burned mana amount
    constant function AGL__manaBurn takes integer level returns real
        return 5.0 * level
    endfunction
    
    // Dealt damage factor
    constant function AGL__damageFactor takes integer level returns real
        return 4.0
    endfunction
    
    // AoE of damage
    constant function AGL__damageAoE takes integer level returns real
        return 175.0
    endfunction
    
    // Number of jumps
    constant function AGL__bounceCount takes integer level returns integer
        return 2
    endfunction
    
    // Target classification
    constant function AGL__filterTarget takes unit u returns boolean
        return not ( IsUnitType(u, UNIT_TYPE_FLYING) or IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) or IsUnitType(u, UNIT_TYPE_MECHANICAL) or IsUnitType(u, UNIT_TYPE_STRUCTURE) )
    endfunction
    
    // ===========================================================================
    
    constant function AGL__isInBound takes real x,real y returns boolean
        return x < udg_AGL__MapBounds[0] and x > udg_AGL__MapBounds[1] and y < udg_AGL__MapBounds[2] and y > udg_AGL__MapBounds[3]
    endfunction
    
    function AGL__deindex takes integer i returns integer
        
        call DestroyGroup(udg_AGL__Group[i])
        call DestroyEffect(udg_AGL__MissileSfx[i])
        call UnitApplyTimedLife(udg_AGL__Missile[i], 'BTLF', (3.0)) // INLINED!!
        
        set udg_AGL__Caster[i]=udg_AGL__Caster[udg_AGL__Counter]
        set udg_AGL__Target[i]=udg_AGL__Target[udg_AGL__Counter]
        set udg_AGL__Player[i]=udg_AGL__Player[udg_AGL__Counter]
        set udg_AGL__Damage[i]=udg_AGL__Damage[udg_AGL__Counter]
        
        set udg_AGL__Bounce[i]=udg_AGL__Bounce[udg_AGL__Counter]
        set udg_AGL__Mana[i]=udg_AGL__Mana[udg_AGL__Counter]
        set udg_AGL__Lifespan[i]=udg_AGL__Lifespan[udg_AGL__Counter]
        set udg_AGL__MissileX[i]=udg_AGL__MissileX[udg_AGL__Counter]
        set udg_AGL__AoE[i]=udg_AGL__AoE[udg_AGL__Counter]
        
        set udg_AGL__MissileY[i]=udg_AGL__MissileY[udg_AGL__Counter]
        set udg_AGL__Missile[i]=udg_AGL__Missile[udg_AGL__Counter]
        set udg_AGL__MissileFace[i]=udg_AGL__MissileFace[udg_AGL__Counter]
        set udg_AGL__MissileSfx[i]=udg_AGL__MissileSfx[udg_AGL__Counter]
        set udg_AGL__Group[i]=udg_AGL__Group[udg_AGL__Counter]
        
        set udg_AGL__Group[udg_AGL__Counter]=null
        set udg_AGL__MissileSfx[udg_AGL__Counter]=null
        set udg_AGL__Missile[udg_AGL__Counter]=null
        set udg_AGL__Caster[udg_AGL__Counter]=null
        set udg_AGL__Target[udg_AGL__Counter]=null
        
        set udg_AGL__Counter=udg_AGL__Counter - 1
        if udg_AGL__Counter < 1 then
            call PauseTimer(udg_AGL__Timer)
        else
            return i - 1
        endif
        
        return i
    endfunction
    
    function AGL__getTarget takes integer i returns unit
        
        local real m= - 1
        local unit u
        local real x
        local real y
        
        call GroupEnumUnitsInRange(udg_AGL__TempGroup, udg_AGL__MissileX[i], udg_AGL__MissileY[i], (600.0), null) // INLINED!!
        loop
            set u=FirstOfGroup(udg_AGL__TempGroup)
            exitwhen u == null
            if u != udg_AGL__Target[i] and not IsUnitInGroup(u, udg_AGL__Group[i]) and AGL__filterTarget(u) then
                if IsPlayerAlly(GetOwningPlayer(u), udg_AGL__Player[i]) and GetUnitState(u, UNIT_STATE_MANA) > m then
                    set x=GetUnitX(u)
                    set y=GetUnitY(u)
                    if ( udg_AGL__MissileX[i] - x ) * ( udg_AGL__MissileX[i] - x ) + ( udg_AGL__MissileY[i] - y ) * ( udg_AGL__MissileY[i] - y ) > (175.) * (175.) then // INLINED!!
                        if GetWidgetLife(u) > 0.405 then
                            set udg_AGL__TempUnit=u
                            set m=GetUnitState(u, UNIT_STATE_MANA)
                        endif
                    endif
                endif
            endif
            call GroupRemoveUnit(udg_AGL__TempGroup, u)
        endloop
        
        return udg_AGL__TempUnit
    endfunction
    
    function AGL__onTick takes nothing returns nothing
        
        local integer i= 1
        local real a
        local real x
        local real y
        local real m
        
        loop
            exitwhen i > udg_AGL__Counter
            if udg_AGL__Lifespan[i] > (0.03125) then // INLINED!!
            
                set udg_AGL__Lifespan[i]=udg_AGL__Lifespan[i] - (0.03125) // INLINED!!
                set x=GetUnitX(udg_AGL__Target[i])
                set y=GetUnitY(udg_AGL__Target[i])
                set a=Atan2(y - udg_AGL__MissileY[i], x - udg_AGL__MissileX[i])
                
                if Cos(udg_AGL__MissileFace[i] - a) < Cos((10.75 * bj_DEGTORAD)) then // INLINED!!
                    if Sin(a - udg_AGL__MissileFace[i]) >= 0 then
                        set udg_AGL__MissileFace[i]=udg_AGL__MissileFace[i] + (10.75 * bj_DEGTORAD) // INLINED!!
                    else
                        set udg_AGL__MissileFace[i]=udg_AGL__MissileFace[i] - (10.75 * bj_DEGTORAD) // INLINED!!
                    endif
                else
                    set udg_AGL__MissileFace[i]=a
                endif
                
                set udg_AGL__MissileX[i]=udg_AGL__MissileX[i] + (25.0) * Cos(udg_AGL__MissileFace[i]) // INLINED!!
                set udg_AGL__MissileY[i]=udg_AGL__MissileY[i] + (25.0) * Sin(udg_AGL__MissileFace[i]) // INLINED!!
                
                if AGL__isInBound(udg_AGL__MissileX[i] , udg_AGL__MissileY[i]) then
                    if ( udg_AGL__MissileX[i] - x ) * ( udg_AGL__MissileX[i] - x ) + ( udg_AGL__MissileY[i] - y ) * ( udg_AGL__MissileY[i] - y ) < (50.) * (50.) then // INLINED!!
                        set m=GetUnitState(udg_AGL__Target[i], UNIT_STATE_MANA)
                        call SetUnitState(udg_AGL__Target[i], UNIT_STATE_MANA, m - udg_AGL__Mana[i])
                        set m=m - GetUnitState(udg_AGL__Target[i], UNIT_STATE_MANA)
                        call DestroyEffect(AddSpecialEffectTarget(("war3mapImported\\Arcane Nova.mdx"), udg_AGL__Target[i], ("origin"))) // INLINED!!
                        
                        call GroupEnumUnitsInRange(udg_AGL__TempGroup, udg_AGL__MissileX[i], udg_AGL__MissileY[i], udg_AGL__AoE[i], null)
                        loop
                            set udg_AGL__TempUnit=FirstOfGroup(udg_AGL__TempGroup)
                            exitwhen udg_AGL__TempUnit == null
                            if IsPlayerAlly(GetOwningPlayer(udg_AGL__TempUnit), udg_AGL__Player[i]) and GetWidgetLife(udg_AGL__TempUnit) > 0.405 then
                                if AGL__filterTarget(udg_AGL__TempUnit) then
                                    call UnitDamageTarget(udg_AGL__Caster[i], udg_AGL__TempUnit, m, false, false, (ATTACK_TYPE_NORMAL), (DAMAGE_TYPE_NORMAL), null) // INLINED!!
                                endif
                            endif
                            call GroupRemoveUnit(udg_AGL__TempGroup, udg_AGL__TempUnit)
                        endloop
                        
                        if udg_AGL__Bounce[i] > 0 then
                            set udg_AGL__Bounce[i]=udg_AGL__Bounce[i] - 1
                            if (false) then // INLINED!!
                                call GroupAddUnit(udg_AGL__Group[i], udg_AGL__Target[i])
                            endif
                            set udg_AGL__Target[i]=AGL__getTarget(i)
                            if udg_AGL__Target[i] == null then
                                set i=AGL__deindex(i)
                            else
                                set udg_AGL__Lifespan[i]=(3.0) // INLINED!!
                            endif
                        else
                            set i=AGL__deindex(i)
                        endif
                    else
                        call SetUnitX(udg_AGL__Missile[i], udg_AGL__MissileX[i])
                        call SetUnitY(udg_AGL__Missile[i], udg_AGL__MissileY[i])
                    endif
                else
                    set i=AGL__deindex(i)
                endif
            else
                set i=AGL__deindex(i)
            endif
            set i=i + 1
        endloop
        
    endfunction
    
    function AGL__onCast takes nothing returns boolean
        
        local integer l
    
        if GetSpellAbilityId() == ('A000') then // INLINED!!
            if AGL__filterTarget(GetSpellTargetUnit()) then
                set udg_AGL__Counter=udg_AGL__Counter + 1
                set udg_AGL__Caster[udg_AGL__Counter]=GetTriggerUnit()
                set udg_AGL__Target[udg_AGL__Counter]=GetSpellTargetUnit()
                set udg_AGL__Player[udg_AGL__Counter]=GetOwningPlayer(udg_AGL__Target[udg_AGL__Counter])
                
                set l=GetUnitAbilityLevel(udg_AGL__Caster[udg_AGL__Counter], ('A000')) // INLINED!!
                set udg_AGL__Lifespan[udg_AGL__Counter]=(3.0) // INLINED!!
                set udg_AGL__Damage[udg_AGL__Counter]=AGL__damageFactor(l)
                set udg_AGL__Bounce[udg_AGL__Counter]=AGL__bounceCount(l)
                set udg_AGL__Mana[udg_AGL__Counter]=(5.0 * (l)) // INLINED!!
                set udg_AGL__AoE[udg_AGL__Counter]=AGL__damageAoE(l)
                
                set udg_AGL__Group[udg_AGL__Counter]=CreateGroup()
                set udg_AGL__MissileX[udg_AGL__Counter]=GetUnitX(udg_AGL__Caster[udg_AGL__Counter])
                set udg_AGL__MissileY[udg_AGL__Counter]=GetUnitY(udg_AGL__Caster[udg_AGL__Counter])
                set udg_AGL__MissileFace[udg_AGL__Counter]=Atan2(GetUnitY(udg_AGL__Target[udg_AGL__Counter]) - udg_AGL__MissileY[udg_AGL__Counter], GetUnitX(udg_AGL__Target[udg_AGL__Counter]) - udg_AGL__MissileX[udg_AGL__Counter])
                set udg_AGL__Missile[udg_AGL__Counter]=CreateUnit(GetTriggerPlayer(), ('h000'), udg_AGL__MissileX[udg_AGL__Counter], udg_AGL__MissileY[udg_AGL__Counter], udg_AGL__MissileFace[udg_AGL__Counter] * bj_RADTODEG) // INLINED!!
                set udg_AGL__MissileSfx[udg_AGL__Counter]=AddSpecialEffectTarget(("war3mapImported\\ArcaneGlaive_2.mdx"), udg_AGL__Missile[udg_AGL__Counter], "origin") // INLINED!!
                
                if UnitAddAbility(udg_AGL__Missile[udg_AGL__Counter], 'Amrf') and UnitRemoveAbility(udg_AGL__Missile[udg_AGL__Counter], 'Amrf') then
                endif
                call SetUnitFlyHeight(udg_AGL__Missile[udg_AGL__Counter], (66.0), 0) // INLINED!!
                call SetUnitScale(udg_AGL__Missile[udg_AGL__Counter], (1.0), 1, 1) // INLINED!!
                
                if udg_AGL__Counter == 1 then
                    call TimerStart(udg_AGL__Timer, (0.03125), true, function AGL__onTick) // INLINED!!
                endif
            endif
        endif
        
        return false
    endfunction

    function InitTrig_ArcaneGlaive takes nothing returns nothing
    
        set udg_AGL__MapBounds[0]=GetRectMaxX(bj_mapInitialPlayableArea)
        set udg_AGL__MapBounds[1]=GetRectMinX(bj_mapInitialPlayableArea)
        set udg_AGL__MapBounds[2]=GetRectMaxY(bj_mapInitialPlayableArea)
        set udg_AGL__MapBounds[3]=GetRectMinY(bj_mapInitialPlayableArea)
    
        set gg_trg_ArcaneGlaive=CreateTrigger()
        set udg_AGL__TempGroup=CreateGroup()
        set udg_AGL__Timer=CreateTimer()
        
        call TriggerRegisterAnyUnitEventBJ(gg_trg_ArcaneGlaive, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(gg_trg_ArcaneGlaive, Condition(function AGL__onCast))
        
    endfunction

Now here's the final script when ran through vex's map optimizer. 99% of people use this tool before publishing their map (real statistic).

JASS:
constant function AGL__manaBurn takes integer level returns real
	return 5.*level
endfunction

constant function AGL__damageFactor takes integer level returns real
	return 4.
endfunction

constant function AGL__damageAoE takes integer level returns real
	return 175.
endfunction

constant function AGL__bounceCount takes integer level returns integer
	return 2
endfunction

constant function AGL__filterTarget takes unit u returns boolean
	return not(IsUnitType(u,UNIT_TYPE_FLYING)or IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)or IsUnitType(u,UNIT_TYPE_MECHANICAL)or IsUnitType(u,UNIT_TYPE_STRUCTURE))
endfunction

constant function AGL__isInBound takes real x,real y returns boolean
	return x<udg_AGL__MapBounds[0]and x>udg_AGL__MapBounds[1]and y<udg_AGL__MapBounds[2]and y>udg_AGL__MapBounds[3]
endfunction

function AGL__deindex takes integer i returns integer
	call DestroyGroup(udg_AGL__Group[i])
	call DestroyEffect(udg_AGL__MissileSfx[i])
	call UnitApplyTimedLife(udg_AGL__Missile[i],'BTLF',(3.))
	set udg_AGL__Caster[i]=udg_AGL__Caster[udg_AGL__Counter]
	set udg_AGL__Target[i]=udg_AGL__Target[udg_AGL__Counter]
	set udg_AGL__Player[i]=udg_AGL__Player[udg_AGL__Counter]
	set udg_AGL__Damage[i]=udg_AGL__Damage[udg_AGL__Counter]
	set udg_AGL__Bounce[i]=udg_AGL__Bounce[udg_AGL__Counter]
	set udg_AGL__Mana[i]=udg_AGL__Mana[udg_AGL__Counter]
	set udg_AGL__Lifespan[i]=udg_AGL__Lifespan[udg_AGL__Counter]
	set udg_AGL__MissileX[i]=udg_AGL__MissileX[udg_AGL__Counter]
	set udg_AGL__AoE[i]=udg_AGL__AoE[udg_AGL__Counter]
	set udg_AGL__MissileY[i]=udg_AGL__MissileY[udg_AGL__Counter]
	set udg_AGL__Missile[i]=udg_AGL__Missile[udg_AGL__Counter]
	set udg_AGL__MissileFace[i]=udg_AGL__MissileFace[udg_AGL__Counter]
	set udg_AGL__MissileSfx[i]=udg_AGL__MissileSfx[udg_AGL__Counter]
	set udg_AGL__Group[i]=udg_AGL__Group[udg_AGL__Counter]
	set udg_AGL__Group[udg_AGL__Counter]=null
	set udg_AGL__MissileSfx[udg_AGL__Counter]=null
	set udg_AGL__Missile[udg_AGL__Counter]=null
	set udg_AGL__Caster[udg_AGL__Counter]=null
	set udg_AGL__Target[udg_AGL__Counter]=null
	set udg_AGL__Counter=udg_AGL__Counter-1
	if udg_AGL__Counter<1 then
	call PauseTimer(udg_AGL__Timer)
	else
	return i-1
	endif
	return i
endfunction
function AGL__getTarget takes integer i returns unit
	local real m=-1
	local unit u
	local real x
	local real y
	call GroupEnumUnitsInRange(udg_AGL__TempGroup,udg_AGL__MissileX[i],udg_AGL__MissileY[i],(600.),null)
	loop
	set u=FirstOfGroup(udg_AGL__TempGroup)
	exitwhen u==null
	if u!=udg_AGL__Target[i]and not IsUnitInGroup(u,udg_AGL__Group[i])and AGL__filterTarget(u)then
	if IsPlayerAlly(GetOwningPlayer(u),udg_AGL__Player[i])and GetUnitState(u,UNIT_STATE_MANA)>m then
	set x=GetUnitX(u)
	set y=GetUnitY(u)
	if(udg_AGL__MissileX[i]-x)*(udg_AGL__MissileX[i]-x)+(udg_AGL__MissileY[i]-y)*(udg_AGL__MissileY[i]-y)>(175.)*(175.)then
	if GetWidgetLife(u)>.405 then
	set udg_AGL__TempUnit=u
	set m=GetUnitState(u,UNIT_STATE_MANA)
	endif
	endif
	endif
	endif
	call GroupRemoveUnit(udg_AGL__TempGroup,u)
	endloop
	return udg_AGL__TempUnit
endfunction
function AGL__onTick takes nothing returns nothing
	local integer i=1
	local real a
	local real x
	local real y
	local real m
	loop
	exitwhen i>udg_AGL__Counter
	if udg_AGL__Lifespan[i]>(.03125)then
	set udg_AGL__Lifespan[i]=udg_AGL__Lifespan[i]-(.03125)
	set x=GetUnitX(udg_AGL__Target[i])
	set y=GetUnitY(udg_AGL__Target[i])
	set a=Atan2(y-udg_AGL__MissileY[i],x-udg_AGL__MissileX[i])
	if Cos(udg_AGL__MissileFace[i]-a)<Cos((10.75*bj_DEGTORAD))then
	if Sin(a-udg_AGL__MissileFace[i])>=0 then
	set udg_AGL__MissileFace[i]=udg_AGL__MissileFace[i]+(10.75*bj_DEGTORAD)
	else
	set udg_AGL__MissileFace[i]=udg_AGL__MissileFace[i]-(10.75*bj_DEGTORAD)
	endif
	else
	set udg_AGL__MissileFace[i]=a
	endif
	set udg_AGL__MissileX[i]=udg_AGL__MissileX[i]+(25.)*Cos(udg_AGL__MissileFace[i])
	set udg_AGL__MissileY[i]=udg_AGL__MissileY[i]+(25.)*Sin(udg_AGL__MissileFace[i])
	if AGL__isInBound(udg_AGL__MissileX[i],udg_AGL__MissileY[i])then
	if(udg_AGL__MissileX[i]-x)*(udg_AGL__MissileX[i]-x)+(udg_AGL__MissileY[i]-y)*(udg_AGL__MissileY[i]-y)<(50.)*(50.)then
	set m=GetUnitState(udg_AGL__Target[i],UNIT_STATE_MANA)
	call SetUnitState(udg_AGL__Target[i],UNIT_STATE_MANA,m-udg_AGL__Mana[i])
	set m=m-GetUnitState(udg_AGL__Target[i],UNIT_STATE_MANA)
	call DestroyEffect(AddSpecialEffectTarget(("war3mapImported\\Arcane Nova.mdx"),udg_AGL__Target[i],("origin")))
	call GroupEnumUnitsInRange(udg_AGL__TempGroup,udg_AGL__MissileX[i],udg_AGL__MissileY[i],udg_AGL__AoE[i],null)
	loop
	set udg_AGL__TempUnit=FirstOfGroup(udg_AGL__TempGroup)
	exitwhen udg_AGL__TempUnit==null
	if IsPlayerAlly(GetOwningPlayer(udg_AGL__TempUnit),udg_AGL__Player[i])and GetWidgetLife(udg_AGL__TempUnit)>.405 then
	if AGL__filterTarget(udg_AGL__TempUnit)then
	call UnitDamageTarget(udg_AGL__Caster[i],udg_AGL__TempUnit,m,false,false,(ATTACK_TYPE_NORMAL),(DAMAGE_TYPE_NORMAL),null)
	endif
	endif
	call GroupRemoveUnit(udg_AGL__TempGroup,udg_AGL__TempUnit)
	endloop
	if udg_AGL__Bounce[i]>0 then
	set udg_AGL__Bounce[i]=udg_AGL__Bounce[i]-1
	if(false)then
	call GroupAddUnit(udg_AGL__Group[i],udg_AGL__Target[i])
	endif
	set udg_AGL__Target[i]=AGL__getTarget(i)
	if udg_AGL__Target[i]==null then
	set i=AGL__deindex(i)
	else
	set udg_AGL__Lifespan[i]=(3.)
	endif
	else
	set i=AGL__deindex(i)
	endif
	else
	call SetUnitX(udg_AGL__Missile[i],udg_AGL__MissileX[i])
	call SetUnitY(udg_AGL__Missile[i],udg_AGL__MissileY[i])
	endif
	else
	set i=AGL__deindex(i)
	endif
	else
	set i=AGL__deindex(i)
	endif
	set i=i+1
	endloop
endfunction
function AGL__onCast takes nothing returns boolean
	local integer l
	if GetSpellAbilityId()==('A000')then
	if AGL__filterTarget(GetSpellTargetUnit())then
	set udg_AGL__Counter=udg_AGL__Counter+1
	set udg_AGL__Caster[udg_AGL__Counter]=GetTriggerUnit()
	set udg_AGL__Target[udg_AGL__Counter]=GetSpellTargetUnit()
	set udg_AGL__Player[udg_AGL__Counter]=GetOwningPlayer(udg_AGL__Target[udg_AGL__Counter])
	set l=GetUnitAbilityLevel(udg_AGL__Caster[udg_AGL__Counter],('A000'))
	set udg_AGL__Lifespan[udg_AGL__Counter]=(3.)
	set udg_AGL__Damage[udg_AGL__Counter]=AGL__damageFactor(l)
	set udg_AGL__Bounce[udg_AGL__Counter]=AGL__bounceCount(l)
	set udg_AGL__Mana[udg_AGL__Counter]=(5.*(l))
	set udg_AGL__AoE[udg_AGL__Counter]=AGL__damageAoE(l)
	set udg_AGL__Group[udg_AGL__Counter]=CreateGroup()
	set udg_AGL__MissileX[udg_AGL__Counter]=GetUnitX(udg_AGL__Caster[udg_AGL__Counter])
	set udg_AGL__MissileY[udg_AGL__Counter]=GetUnitY(udg_AGL__Caster[udg_AGL__Counter])
	set udg_AGL__MissileFace[udg_AGL__Counter]=Atan2(GetUnitY(udg_AGL__Target[udg_AGL__Counter])-udg_AGL__MissileY[udg_AGL__Counter],GetUnitX(udg_AGL__Target[udg_AGL__Counter])-udg_AGL__MissileX[udg_AGL__Counter])
	set udg_AGL__Missile[udg_AGL__Counter]=CreateUnit(GetTriggerPlayer(),('h000'),udg_AGL__MissileX[udg_AGL__Counter],udg_AGL__MissileY[udg_AGL__Counter],udg_AGL__MissileFace[udg_AGL__Counter]*bj_RADTODEG)
	set udg_AGL__MissileSfx[udg_AGL__Counter]=AddSpecialEffectTarget(("war3mapImported\\ArcaneGlaive_2.mdx"),udg_AGL__Missile[udg_AGL__Counter],"origin")
	if UnitAddAbility(udg_AGL__Missile[udg_AGL__Counter],'Amrf')and UnitRemoveAbility(udg_AGL__Missile[udg_AGL__Counter],'Amrf')then
	endif
	call SetUnitFlyHeight(udg_AGL__Missile[udg_AGL__Counter],(66.),0)
	call SetUnitScale(udg_AGL__Missile[udg_AGL__Counter],(1.),1,1)
	if udg_AGL__Counter==1 then
	call TimerStart(udg_AGL__Timer,(.03125),true,function AGL__onTick)
	endif
	endif
	endif
	return false
endfunction
function InitTrig_ArcaneGlaive takes nothing returns nothing
	set udg_AGL__MapBounds[0]=GetRectMaxX(bj_mapInitialPlayableArea)
	set udg_AGL__MapBounds[1]=GetRectMinX(bj_mapInitialPlayableArea)
	set udg_AGL__MapBounds[2]=GetRectMaxY(bj_mapInitialPlayableArea)
	set udg_AGL__MapBounds[3]=GetRectMinY(bj_mapInitialPlayableArea)
	set gg_trg_ArcaneGlaive=CreateTrigger()
	set udg_AGL__TempGroup=CreateGroup()
	set udg_AGL__Timer=CreateTimer()
	call TriggerRegisterAnyUnitEventBJ(gg_trg_ArcaneGlaive,EVENT_PLAYER_UNIT_SPELL_EFFECT)
	call TriggerAddCondition(gg_trg_ArcaneGlaive,Condition(function AGL__onCast))
endfunction

In your case constant functions are the best solution, please use them :thumbs_up:

Man, you don't need to do that. You just need to say constant functions are required and eventually I will do it by myself. Anyway, thank you very much, TH. I will just copy-paste your code :grin: Thanks again...
 
GetWidgetLife(udg_AGL__TempUnit) > 0.405
^Change this in ... I'm sure you know what I mean. :D

JASS:
// Each unit can only be targeted once
constant function AGL__TargetsOnce takes nothing returns boolean
    return false
endfunction
If this function will return true, you could avoid dynamic group creation and destruction. So some operations/checks would not be needed anymore. :)
Correct me if I'm wrong.

It was better in my opinion if you would directly deindex if caster is dead/removed, as the caster is the one dealing damage.

Well made spell in my opinion. Though some short, explanatory documentation would not kill you I think. ( I think not much is needed here, but me for example still prefer some statements here and there)

I would appreciate it if not needed imports would be removed in demo map. And you should think twice if you need imports at all for a spell.
Most people (I think) might prefer less imports, still there is the possibility to suggest good fitting models/icons in spell description. Your choice.

Little note: GetTriggerPlayer() could be indexed as well.
 
Last edited:

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Updated

^Change this in ... I'm sure you know what I mean. :D
If this function will return true, you could avoid dynamic group creation and destruction. So some operations/checks would not be needed anymore. :)
Correct me if I'm wrong.
It was better in my opinion if you would directly index if caster is dead/removed, as the caster is the one dealing damage.
Done
Well made spell in my opinion. Though some short, explanatory documentation would not kill you I think. ( I think not much is needed here, but me for example still prefer some statements here and there)
Added some

Little note: GetTriggerPlayer() could be indexed as well.
TriggeringPlayer is not used.

Thnks for your review.
 
It was better in my opinion if you would directly index if caster is dead/removed, as the caster is the one dealing damage.
I meant deindex of course, sorry. Fixed my post. But you anyway have understood if correctly! :csmile:

Ah, yes TriggerPlayer() is not used more often, lol. I must have misread. :D

onTick you accicently forgot to change to correct IsUnitAlive check. (in damage part)

JASS:
set udg_AGL__Group[i] = udg_AGL__Group[udg_AGL__Counter]
set udg_AGL__Group[udg_AGL__Counter] = null
^These deindex operations don't need to be done, if AGL__TargetsOnce(). It's nothing critical, but with next update you just can move them to your destroy group operation.

That should be all.
 
Level 10
Joined
Aug 21, 2010
Messages
316
It is amazing the amount of contradictory things on this site.
For example, a moderator tells you to do something in a certain way("HIS WAY") and, of course, claims that it is literally the most correct way, while another moderator("or the same"), in another resource, the same way refutes.
So from the above mentioned, the logical question arises, what is actually happening here.
Coincidence, I think not.
Ignorance,presentation of all sorts of nonsense,imposing own style(opinions) definitely.

Of course there are good moderators but only a few of them...hmm...unfortunately.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
It is amazing the amount of contradictory things on this site.
For example, a moderator tells you to do something in a certain way("HIS WAY") and, of course, claims that it is literally the most correct way, while another moderator("or the same"), in another resource, the same way refutes.
So from the above mentioned, the logical question arises, what is actually happening here.
Coincidence, I think not.
Ignorance,presentation of all sorts of nonsense,imposing own style(opinions) definitely.

Of course there are good moderators but only a few of them...hmm...unfortunately.

The problem is not he's dictating his style. His fault is putting resources to needs fix based on super minor issues, which are not mandatory to be fixed.

Anyway,
Updated
 
Top