Vortex Lightning v1.3

This bundle is marked as approved. It works and satisfies the submission rules.
  • Like
Reactions: Losam
-------------------------------------------
**
**V O R T E X**
**
**L I G H T N I N G**
**

I/ Spell Information:
untit216.jpg

II/ Spell Code:
JASS:
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//          V O R T E X   L I G H T N I N G
//                                  - Spell Create By:
//                                                      + Elphis
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
library VortexLightning /*                   
*/                                      requires /*
//                                              -*/ CTL /* http://www.wc3c.net/showthread.php?t=101322
//                                              -*/ SpellEffectEvent /* http://www.hiveworkshop.com/forums/jass-resources-412/snippet-spelleffectevent-187193/
//                                              -*/ Table /* http://www.wc3c.net/showthread.php?t=101246
//                                              -*/ IsDestructableTree /* http://www.wc3c.net/showthread.php?t=103927
//                                              -*/ RLPluginVL /* Spell Plugin
//                                              -*/ DOTPluginVL /* Spell Plugin
//                                              -*/ RLPluginVL /* Spell Plugin */
//                                      Optional:
//                                                NuclearExplosion.mdx - http://www.hiveworkshop.com/forums/models-530/nuclearexplosion-51829/?prev=search%3DNuclear%26d%3Dlist%26r%3D20
//                                                BoundSentinel - http://www.wc3c.net/showthread.php?t=102576 (You must adding it, this library help you prevent crash the game when lightning outside XY of map.
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//          - Spell Information:
//                              - Use power of the earth, calling a powerful vortex of lightning accumulation in the soil and launched on ground
//                                spending a little time to make power, when done, it release a powerful lightning discharge on ground
//                                when enemies within 100 range it will shock enemies
//                                and deals 50/100/150/200 damage, when electric release 50/60/70/80 lightning
//                                this vortex will causes an explotion deals 50 damage to enemies unit and destructable around
//                                500 range in 5 seconds.
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//          - Installation:
//                                - Import/copy the required libraries and Vortex Lightning code to your map
//                                - Import/copy the custom ability and unit to your map and change the SPELL_ID if needed
//                                - Export model NuclearExplosion.mdx, dummy.mdx and import it into your map
//                                - You may view the raw ID of the objects by pressing CTRL+D in the object editor
//                                - You may play with the configurables below
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
    //================================CONFIGURABLE================================
    globals
        //==============================SPELL SETTINGS========================================
        //Spell rawcode, change if needed
        private         constant            integer         SPELL_ID        =           'A000'
        //Dummy rawcode, change if needed
        private         constant            integer         LIGHTNING_DUMMY =           'e000'
        //Periodic of spell
        public          constant            real            PERIODIC        =           .031250000
        //========================================================================
        ////////////////////////////////////////////////////////////////////////////////////////////
        //Count of lightning release (Spell expire when reach this count)
        private         constant            integer         L_R_COUNT       =           5
        //Color of lightning increase per periodic
        private         constant            integer         COLOR_INC       =           5
        //Max distance when lightning release
        private         constant            real            MAX_DISTANCE    =           1000.
        //Min distance when lightning release
        private         constant            real            MIN_DISTANCE    =           500.
        //Max distance of vortex lightning
        private         constant            real            ORB_M_DISTANCE  =           500.
        //Distance increase per periodic
        private         constant            real            ORB_REACH       =           5.
        //Lightning powerful center size
        private         constant            real            CENTER_SIZE     =           3.
        //Size increase of center lightning per periodic
        private         constant            real            CENTER_SIZE_INC =           0.2
        //Lightning release speed outside
        private         constant            real            RELEASE_SPEED   =           10.
        //Range hit enemies, don't increase this value too much because it very powerful
        private         constant            real            WIHTHIN_RANGE   =           100.
        //Lightning release intevar
        private         constant            real            RELEASE_INTEVAR =           0.1
        //Damage when release lightning hit enemies unit
        private         constant            real            DAMAGE_BASE     =           50.
        //Damage fire deals to enemies unit within range of explotion
        private         constant            real            DAMAGE_FIRE     =           50.
        //Duration of fire damage to enemies unit and destructable
        private         constant            real            FIRE_DURATION   =           5.
        //Model of lightning vortex
        private         constant            string          MODEL           =           "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
        //Effect causes explore when lightning reach max distance
        private         constant            string          EXPLORE_MODEL   =           "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"
        //Explotion model when spell expire
        private         constant            string          M_EXPLOTION     =           "war3mapImported\\NuclearExplosion.mdx"
        //Fire effect to enemies unit and destructable
        private         constant            string          FIRE_EFFECT     =           "Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeDamageTarget.mdl"
        //Lightning attachment
        private         constant            string          ATTACH          =           "origin"
        //Enemies attachment
        private         constant            string          ENE_ATTACH      =           "chest"
        //Vortex lightning model
        private         constant            string          LIGHTNING_ALT   =           "DRAM"
        //Release lightning model
        private         constant            string          L_RELEASE       =           "CLPB"
        //                                  ======DAMAGE SETTINGS======
        private         constant            attacktype      ATTACKTYPE      =           ATTACK_TYPE_HERO
        private         constant            damagetype      DAMAGETYPE      =           DAMAGE_TYPE_COLD
        private         constant            weapontype      WEAPONTYPE      =           WEAPON_TYPE_METAL_HEAVY_BASH
        //                                  ======NON CONFIGURATION======
        private         constant            group           G               =           CreateGroup()
        private                             rect            RECT            =           Rect(0, 0, 0, 0)
        //
    endglobals
    //
    private struct VortexLightning extends array
        
        //
        player p    
        //
        unit caster
        unit dummy
        //
        real damage
        real xx
        real yy
        real an
        real reach
        real sinc
        real in
        //
        integer cl
        integer count
        //Table Installing
        Table tab
        //This function deals damage to destructable
        static method damageDestructable takes nothing returns boolean
            local destructable dummy = GetFilterDestructable()
            //
            if IsDestructableTree(dummy) then
                call DDPluginVL.add(dummy,FIRE_EFFECT,DAMAGE_FIRE,FIRE_DURATION,1.)
            endif
            //
            set dummy = null
            //
            return false
        endmethod
        //
        static method onCount takes unit caster returns integer
            return L_R_COUNT+GetUnitAbilityLevel(caster,SPELL_ID)*10 // Total count of vortex discharge lightning
        endmethod
        //
        static method onDamage takes unit caster returns real
            return DAMAGE_BASE*GetUnitAbilityLevel(caster,SPELL_ID) // Damage of lightning when hit enemies unit
        endmethod
        //
        
            implement CTL
                local integer i = 0
                local real x
                local real y
                local real dd
                local unit f
            implement CTLExpire
            //
            set an = an + 5.
            //
            loop
                exitwhen i > 10
                //
                set x = xx + reach * Cos((tab.real[10+i]+an)*0.01747)
                set y = yy + reach * Sin((tab.real[10+i]+an)*0.01747)
                //
                call SetUnitX(tab.unit[i],x)
                call SetUnitY(tab.unit[i],y)
                //
                call SetUnitVertexColor(tab.unit[i],cl,cl,cl,cl)
                //
                call MoveLightning(tab.lightning[20+i],true,x,y,xx,yy)
                //
                set i = i + 1
            endloop
            set i = 0
            //
            if count > 0 then
                if reach < ORB_M_DISTANCE then
                    set reach = reach + ORB_REACH
                else
                    //
                    if cl < 255 then
                        set cl = cl + COLOR_INC
                    elseif sinc < CENTER_SIZE then
                        set sinc = sinc + CENTER_SIZE_INC
                        call SetUnitScale(dummy,sinc,0.,0.)
                    else
                        if in < RELEASE_INTEVAR then
                            set in = in + PERIODIC
                        else
                            //
                            set in = 0.
                            //
                            set dd = GetRandomReal(MIN_DISTANCE,MAX_DISTANCE)
                            //
                            set count = count - 1
                            //This line release lightning
                            call RLPluginVL.add(caster,xx,yy,RELEASE_SPEED,damage,dd,WIHTHIN_RANGE,L_RELEASE,EXPLORE_MODEL,ATTACKTYPE,DAMAGETYPE,WEAPONTYPE)
                        endif
                    endif
                endif
                else
                    //
                    if reach > 0. then
                        //
                        set reach = reach - ORB_REACH
                        //
                        loop
                            exitwhen i > 10
                            //
                            set x = xx + reach * Cos((tab.real[10+i]+an)*0.01747)
                            set y = yy + reach * Sin((tab.real[10+i]+an)*0.01747)
                            //
                            call SetUnitX(tab.unit[i],x)
                            call SetUnitY(tab.unit[i],y)
                            //
                            call MoveLightning(tab.lightning[20+i],true,x,y,xx,yy)
                            //
                            set i = i + 1
                        endloop
                    elseif sinc > 0 then
                        set sinc = sinc - CENTER_SIZE_INC*2
                        //
                        call SetUnitScale(dummy,sinc,0.,0.)
                        //
                        set i = 0
                        //
                        loop
                            exitwhen i > 10
                            //
                            call SetUnitScale(tab.unit[i],sinc,0.,0.)
                            //
                            set i = i + 1
                        endloop
                    else
                        //Enum destructable
                        call SetRect(RECT, xx-ORB_M_DISTANCE, yy-ORB_M_DISTANCE, xx+ORB_M_DISTANCE, yy+ORB_M_DISTANCE)
                        //
                        call GroupEnumUnitsInRect(G,RECT,null)
                        loop
                            set f = FirstOfGroup(G)
                            exitwhen f == null
                            if IsUnitEnemy(f,p) or not IsUnitType(f,UNIT_TYPE_DEAD) then
                                //This line deals damage to enemies
                                call DOTPluginVL.add(caster,f,FIRE_EFFECT,ENE_ATTACH,DAMAGE_FIRE,FIRE_DURATION,1.,ATTACKTYPE,DAMAGETYPE,WEAPONTYPE)
                            endif
                            call GroupRemoveUnit(G,f)
                        endloop
                        //
                        call EnumDestructablesInRect(RECT,function thistype.damageDestructable,null)
                        //
                        set i = 0
                        //
                        loop
                            exitwhen i > 10
                            //
                            call DestroyLightning(tab.lightning[20+i])
                            call DestroyEffect(tab.effect[30+i])
                            call RemoveUnit(tab.unit[i])
                            //
                            set tab.unit[i] = null
                            set tab.lightning[20+i] = null
                            set tab.effect[30+i] = null
                            //
                            set i = i + 1
                        endloop
                        //
                        call DestroyEffect(AddSpecialEffect(M_EXPLOTION,xx,yy))
                        //
                        call RemoveUnit(dummy)
                        //
                        call tab.flush()
                        call tab.destroy()
                        //
                        set caster = null
                        set dummy = null
                        set p = null
                        //
                        call destroy()
                        //
                    endif
                    //
                endif
            //
            
        implement CTLEnd
        
        static method onCast takes nothing returns boolean
            local thistype this = create()
            local integer i = 0
            local real x
            local real y
            //
            set caster = GetTriggerUnit()
            set p = GetTriggerPlayer()
            //
            set xx = GetSpellTargetX()
            set yy = GetSpellTargetY()
            set damage = onDamage(caster)
            set count = onCount(caster)
            set an = 0.
            set reach = 0.
            set sinc = 0.
            set in = 0.
            set cl = 0
            //Table create
            set tab = Table.create()
            //
            loop
                exitwhen i > 10
                //
                set x = xx + 100. * Cos(0.01747*i*36)
                set y = yy + 100. * Sin(0.01747*i*36)
                //
                set tab.unit[i] = CreateUnit(p,LIGHTNING_DUMMY,x,y,0.)
                set tab.real[10+i] = 57.29582 * Atan2(y - yy, x - xx)
                set tab.lightning[20+i] = AddLightning(LIGHTNING_ALT,true,x,y,xx,yy)
                set tab.effect[30+i] = AddSpecialEffectTarget(MODEL,tab.unit[i],ATTACH)
                call SetUnitVertexColor(tab.unit[i],0,0,0,0)
                //
                set i = i + 1
            endloop
            //
            set dummy = CreateUnit(p,LIGHTNING_DUMMY,xx,yy,0.)
            call SetUnitScale(dummy,0.,0.,0.)
            //
            return false
        endmethod
        
        static method onInit takes nothing returns nothing
            call RegisterSpellEffectEvent(SPELL_ID,function thistype.onCast)
        endmethod
        //
    endstruct
    //
endlibrary
JASS:
library RSEPluginVL requires CTL
    
    struct RSEPluginVL
        
        effect e
        unit c = null
        destructable d
        real time
        
        implement CTLExpire
        
        if c != null then
            if time < 0. or IsUnitType(c,UNIT_TYPE_DEAD) or GetUnitTypeId(c) == 0 then
                call DestroyEffect(e)
                set e = null
                set c = null
                call destroy()
            else
                set time = time - VortexLightning_PERIODIC
            endif
        else
            if time < 0. or GetWidgetLife(d) < 0.425 then
                call DestroyEffect(e)
                set e = null
                set d = null
                call destroy()
            else
                set time = time - VortexLightning_PERIODIC
            endif
        endif
        
        implement CTLEnd
        
        static method addTarget takes unit u,string eff,string attach,real dur returns nothing
            local thistype this = create()
            set c = u
            set e = AddSpecialEffectTarget(eff,c,attach)
            set time = dur
        endmethod
        
        static method addPoint takes string eff,destructable des,real x,real y,real dur returns nothing
            local thistype this
            set e = AddSpecialEffect(eff,x,y)
            set d = des
            set time = dur
        endmethod
        
    endstruct
endlibrary
JASS:
library RLPluginVL requires CTL
    //
    globals
        //
        private     constant    group       G          =   CreateGroup()
        //
    endglobals
    //
    struct RLPluginVL
        
        unit c
        //
        player p
        //
        real reach
        real maxdis
        real damage
        real within
        real speed
        real xx
        real yy
        real angle
        //
        string ef
        //
        attacktype attack
        damagetype dam
        weapontype weapon
        //
        lightning ll
        //
            implement CTL
            //
            local real x
            local real y
            local unit f
            //
            implement CTLExpire
            
            if reach < maxdis and speed > 0 then
                set reach = reach + speed
                //
                set x = xx + reach * Cos(angle*0.01747)
                set y = yy + reach * Sin(angle*0.01747)
                //
                call MoveLightning(ll,true,x,y,xx,yy)
                //
                call GroupEnumUnitsInRange(G,x,y,within,null)
                loop
                    set f = FirstOfGroup(G)
                    exitwhen f == null
                    
                    if IsUnitEnemy(f,p) and not IsUnitType(f,UNIT_TYPE_DEAD) or GetUnitTypeId(f) != 0 then
                        set speed = -1
                        call UnitDamageTarget(c,f,damage,true,false,attack,dam,weapon)
                    endif
                    call GroupRemoveUnit(G,f)
                endloop
            else
                set x = xx + reach * Cos(angle*0.01747)
                set y = yy + reach * Sin(angle*0.01747)
                call DestroyEffect(AddSpecialEffect(ef,x,y))
                call DestroyLightning(ll)
                set ll = null
                set c = null
                set p = null
                set attack = null
                set weapon = null
                set dam = null
                call destroy()
            endif
            
            implement CTLNull
            implement CTLEnd
        
        public static method add takes unit caster,real x,real y,real sp,real da,real dis,real hit,string l,string eff,attacktype a,damagetype d,weapontype w returns nothing
            //
            local thistype this = create()
            //
            set c = caster
            set p = GetOwningPlayer(c)
            set maxdis = dis
            set within = hit
            set damage = da
            set speed = sp
            set ef = eff
            set xx = x
            set yy = y
            set ll = AddLightning(l,true,xx,yy,xx,yy)
            set angle = GetRandomReal(0,360)
            set reach = 0.
            //
            set attack = a
            set dam = d
            set weapon = w
            //
        endmethod
        
    endstruct
    
endlibrary
JASS:
library DDPluginVL requires RSEPluginVL,CTL
    
    struct DDPluginVL
        //
        destructable d
        //
        real ti
        real dmg
        real intevar = 0.
        real time
        //
        implement CTLExpire
            //
            if ti > 0. or GetWidgetLife(d) > 0.425 then
                set ti = ti - VortexLightning_PERIODIC
                if intevar < time then
                    set intevar = intevar + VortexLightning_PERIODIC
                else
                    set intevar = 0.
                    call SetWidgetLife(d,GetWidgetLife(d)-dmg)
                endif
            else
                set d = null
                call destroy()
            endif
            //
        
        implement CTLEnd
        
        static method add takes destructable dest, string eff,real damage,real duration,real periodic returns nothing
            //
            local thistype this = create()
            //
            set d = dest
            set dmg = damage
            call RSEPluginVL.addPoint(eff,dest,GetDestructableX(d),GetDestructableY(d),duration)
            set ti = duration
            set time = periodic
            //
        endmethod
        
    endstruct
    //
endlibrary
JASS:
library DOTPluginVL requires RSEPluginVL,CTL
    
    struct DOTPluginVL
        //
        unit c
        unit d
        //
        real ti
        real dmg
        real intevar = 0.
        real time
        //
        attacktype att
        damagetype dam
        weapontype wea
        //
        implement CTLExpire
            //
            if ti < 0. or IsUnitType(d,UNIT_TYPE_DEAD) or GetUnitTypeId(d) == 0 then
                set d = null
                set c = null
                call destroy()
            else
                set ti = ti - VortexLightning_PERIODIC
            endif
            //
            if intevar < time then
                set intevar = intevar + VortexLightning_PERIODIC
            else
                set intevar = 0.
                call UnitDamageTarget(c,d,dmg,true,false,att,dam,wea)
            endif
            //
        
        implement CTLEnd
        
        static method add takes unit caster,unit target, string eff,string attach,real damage,real duration,real periodic,attacktype a,damagetype dd,weapontype w returns nothing
            //
            local thistype this = create()
            //
            set c = caster
            set d = target
            set dmg = damage
            set att = a
            set dam = dd
            set wea = w
            call RSEPluginVL.addTarget(d,eff,attach,duration)
            set ti = duration
            set time = periodic
            //
        endmethod
        
    endstruct
    //
endlibrary
III/ Spell Look Like:

untit217.jpg

untit218.jpg

untit219.jpg

untit220.jpg


IV/ Credits:
Click to view library DelFX
Click to view library SpellEffectEvent
Click to view library Bound Sentinel
Click to view library IsDestructableTree
Click to view model Nuclear Explotion
Click to view library CTL
-------------------------------------------

v1.0: First release version.
v1.1: Remove Table, add library Sentinel, Optimized
v1.1b: Optimized !
v1.2: Optimized.
v1.3: Leaks fixed, bugs fixed.


Keywords:
vortex,lightning,electric
Contents

Vortex Lightning (Map)

Reviews
Vortex Lightning v1.3 | Reviewed by Maker | 15th Oct 2013 APPROVED Approved. Leakless an MUI. The lightnings mixed with a fire explosion do not perfectly match Calculate 0.01747*36 before the loop in onCast Lots of...

Moderator

M

Moderator


Vortex Lightning v1.3 | Reviewed by Maker | 15th Oct 2013
APPROVED


126248-albums6177-picture66521.png


  • Approved. Leakless an MUI. The lightnings mixed with a fire explosion
    do not perfectly match
126248-albums6177-picture66523.png


  • Calculate 0.01747*36 before the loop in onCast
  • Lots of extra operations here
    set x = xx + reach * Cos((tab.real[10+i]+an)*0.01747) set y = yy + reach * Sin((tab.real[10+i]+an)*0.01747)
  • The ability has no follow through time, the casting animation looks bad
  • Make the height offset of the lightnings match the center of the dummy units
  • The final explosion effect disappears abruptly
  • The learn tooltip is missing the ability level
[tr]



Vortex Lightning v1.2 | Reviewed by Maker | 11th Oct 2013
NEEDS FIX



[TD]
126248-albums6177-picture66522.png

[TD]

  • Units keep losing health even when there is no buff or special effect on them.
    A player should be able to know what is causing the loss of hit points
  • You are leaking, use remove method of Table instead of setting
    things to null
126248-albums6177-picture66523.png


  • The final explosion effect disappears abruptly
  • I don't think lightnings look good on their own as they have triangle shaped ends
  • Make the height offset of the lightnings match the center of the dummy units
  • The ability has no follow through time, the casting animation looks bad
  • The dummies give too much vision
  • There could be only one timer since you're using 0.03125 period
  • onPeriod has many repeated calculations
  • GetUnitTypeId of instantly enumed units can't be 0

[/td]
[/TD]
 
Level 11
Joined
Oct 11, 2012
Messages
711
Nice eye-candy spell, my style! Does it cause lag? I have had time to test it.
BTW: why is the post about the mana bar system closed? Nice idea to use lightning effect as an indicator for the mana pool.

Edit: I am also using that nuclear bomb model in my map, so one less thing to import, which is great. LOL
 
Top