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

Spells & Systems Mini-Contest #20

Discussion in 'Triggers & Scripts' started by Bribe, May 18, 2011.

  1. The Reborn Devil

    The Reborn Devil

    Joined:
    Dec 31, 2006
    Messages:
    1,325
    Resources:
    0
    Resources:
    0
    Derp derp, finishing the spell now. Had to play some FFX :D

    Just to be sure, the spell must've been submitted before 08:00 GMT on Saturday (18th of June), right?

    Edit: Btw, Bribe, be prepared for spaghetti code from my side :D
     
  2. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,047
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Yeap, or Midnight between Friday/Saturday for those in West Coast USA (PST)
     
  3. The Reborn Devil

    The Reborn Devil

    Joined:
    Dec 31, 2006
    Messages:
    1,325
    Resources:
    0
    Resources:
    0
    Okeh.

    Btw, my spell got an unintentional feature :D
    When it's burning in one place (the ground begins to burn after a meteor has hit it) and another meteor strikes very close, then the fire (burning soil) is tossed away just like the units. This way the fire is spreading. I'm too lazy to make the fire damage units though, and it would kinda be overkill if it did, imo. Suddenly the fire is tossed into a forest and it begins to burn, lol. I might add it as an option when I release this in the spells section though.

    Edit: Btw, Deo, I chose another sound. U mad?
     
    Last edited: Jun 16, 2011
  4. Freyleyes

    Freyleyes

    Joined:
    Jun 28, 2008
    Messages:
    766
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Here is my final submission, so far :

    Worms Sheep Strike
    Show
    http://www.youtube.com/watch?v=Kmo1X7ST2cM


    Code
    Show
    Code (vJASS):
    //----------------------------------------------------------------------------------
    //Sheep Strike
    //Spells and systems contest #20
    //Created by : Xiliger
    //Uses :
    //  TimerUtils by Vexorian
    //  Parabolic movement by Mayoc/Spec
    //  GroupUtils by Rising_Dusk
    //----------------------------------------------------------------------------------

    scope SheepStrike initializer Init

    globals

        private constant integer SPELLID                        = 'A000'
            //This is the abilities id
        private constant integer UNITID                         = 'n000'
            //This is the sheep dummy units id
        private constant integer MAXCOUNT                       = 5
            //This is the maximum units that gets created
        private constant real MAXDISTANCE                       = 800.00
            //This is the distance from the cast point the units will summon
        private constant real UNITDISTANCE                      = 75.00
            //This is the distance between units as they are summoned
        private constant real MAXHEIGHT                         = 300.00
            //This is the flying height that the units gets spawned
        private constant real MAXHEIGHTPARABOLA                 = 500.00
            //This is the maximum height for the parabolic movement
        private constant real MOVEDISTANCE                      = 20.00
            //This is the distance a unit is moved by the timer
        private constant real DAMAGEAREA                        = 100.00
            //This is the detection area in wich damage will be done
        private constant real DAMAGEDONE                        = 100.00
            //This is the damage that is done to units
        private constant real RELAPSHIGHT                       = 400.00
            //This is the maximun height for the second bounce
        private constant real RELAPSDISTANCE                    = 7.50
            //This is the distance moved in the 3rd phase
        private constant string SPELLEFFECT1                    = "Abilities\\Spells\\Other\\BreathOfFire\\BreathOfFireDamage.mdl"
            //This is the "Fire Effect" added to the sheep
        private constant string SPELLEFFECT2                    = "Abilities\\Weapons\\SteamTank\\SteamTankImpact.mdl"

    endglobals

    private function GetDistance takes nothing returns real //Returns a random distance

        local real rMin = 0   //This is the min value for the random distance
        local real rMax = 300 //This is the max value for the random distance

        return GetRandomReal(rMin, rMax)

    endfunction

    struct Data

        unit dUnit      = null
        unit dCaster    = null
        real dDistance  = 0.00
        real dCDistance = 0.00
        real dAngle     = 0.00
        real x          = 0.00
        real y          = 0.00
        effect dEffect1 = null
        effect dEffect2 = null
        boolean dBool1  = false
        boolean dBool2  = false
        boolean dBool3  = false
        boolean dBool4  = false
        boolean dBool5  = false
        integer dVertex = 0
        player dOwner   = null
       
        static method create takes unit caster, real x, real y, real a, real d returns Data
       
            local Data dat = Data.allocate()
            local timer t  = NewTimer()
           
            set dat.dUnit     = CreateUnit(GetOwningPlayer(caster), UNITID, x, y, a)
            set dat.dCaster   = caster
            set dat.dDistance = d
            set dat.dAngle    = a
            set dat.dOwner    = GetOwningPlayer(caster)
           
            call SetUnitVertexColor(dat.dUnit, 225, 225, 225, 0)
            call SetUnitFlyHeight(dat.dUnit, MAXHEIGHT, 0)
            call SetTimerData(t, dat)
            call TimerStart(t, 0.04, true, function Data.onLoop)
           
            return dat
       
        endmethod
       
        private static method onLoop takes nothing returns nothing
       
            local timer t  = GetExpiredTimer()
            local Data dat = GetTimerData(t)
            local real x   = GetUnitX(dat.dUnit) + MOVEDISTANCE * Cos(dat.dAngle * bj_DEGTORAD)
            local real y   = GetUnitY(dat.dUnit) + MOVEDISTANCE * Sin(dat.dAngle * bj_DEGTORAD)
            local real d   = 0
            local unit n   = null
            local rect r   = bj_mapInitialPlayableArea
            local real rX  = 0
            local real rY  = 0
           
            set dat.x = GetUnitX(dat.dUnit)
            set dat.y = GetUnitY(dat.dUnit)
           
            if dat.dVertex < 255 then
           
                set dat.dVertex = dat.dVertex + 25
                call SetUnitVertexColor(dat.dUnit, 255, 255, 255, dat.dVertex)
               
            endif
           
    //-------------------------------------------------------------------------------------------
    //------------------This is the first phase of the spell-------------------------------------
    //-------------------------------------------------------------------------------------------
           
            if (dat.dDistance > dat.dCDistance) and (dat.dBool2 == false) then
           
                call SetUnitX(dat.dUnit, x)
                call SetUnitY(dat.dUnit, y)
               
                set dat.dCDistance = dat.dCDistance + MOVEDISTANCE
               
                if (dat.dCDistance > (dat.dDistance / 2)) and (dat.dBool1 == false) then
               
                    set dat.dEffect1 = AddSpecialEffectTarget(SPELLEFFECT1, dat.dUnit, "origin")
                    set dat.dBool1   = true
               
                endif
           
            else //The following code switches to the second phase
               
                if dat.dBool2 == false then
               
                    set d              = GetDistance()
                    set dat.dBool2     = true
                    set dat.dBool3     = true
                    set dat.dAngle     = GetRandomReal(0, 359)
                    set x              = GetUnitX(dat.dUnit) + d * Cos(dat.dAngle * bj_DEGTORAD)
                    set y              = GetUnitY(dat.dUnit) + d * Sin(dat.dAngle * bj_DEGTORAD)
                    set dat.dDistance  = SquareRoot((x - GetUnitX(dat.dUnit)) * (x - GetUnitX(dat.dUnit)) + (y - GetUnitY(dat.dUnit)) * (y - GetUnitY(dat.dUnit)))
                    set dat.dCDistance = 0
               
                endif
           
            endif
           
    //-------------------------------------------------------------------------------------------
    //------------------This is the second phase of the spell------------------------------------
    //-------------------------------------------------------------------------------------------
           
            if (dat.dDistance > dat.dCDistance) and (dat.dBool2 == true) then
           
                set dat.dCDistance = dat.dCDistance + RELAPSDISTANCE
               
                set x = dat.x + RELAPSDISTANCE * Cos(dat.dAngle * bj_DEGTORAD)
                set y = dat.y + RELAPSDISTANCE* Sin(dat.dAngle * bj_DEGTORAD)
               
                call SetUnitX(dat.dUnit, x)
                call SetUnitY(dat.dUnit, y)
                call SetUnitFacing(dat.dUnit, dat.dAngle)
               
                call SetUnitFlyHeight(dat.dUnit, ParabolaZ2( MAXHEIGHT, 0, MAXHEIGHTPARABOLA, dat.dDistance, dat.dCDistance), 0)
           
            else
           
                if dat.dBool3 == true then
           
                    set dat.dBool3 = false
                   
                    call GroupUnitsInArea(ENUM_GROUP, dat.x, dat.y, DAMAGEAREA)
           
                    loop
           
                        set n = FirstOfGroup(ENUM_GROUP)
               
                        exitwhen n == null
               
                        if (IsUnitAlly(n, dat.dOwner) == false) and (GetWidgetLife(n) > 0) then
               
                            call UnitDamageTarget(dat.dCaster, n, DAMAGEDONE, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
               
                        endif
               
                        call GroupRemoveUnit(ENUM_GROUP, n)
                        call ReleaseGroup(ENUM_GROUP)
           
                    endloop
           
                    call DestroyEffect(AddSpecialEffectTarget(SPELLEFFECT2, dat.dUnit, "origin"))
                   
                    set d              = GetRandomReal(400, 500)
                    set dat.dAngle     = GetRandomReal(0, 359)
                    set x              = GetUnitX(dat.dUnit) + d * Cos(dat.dAngle * bj_DEGTORAD)
                    set y              = GetUnitY(dat.dUnit) + d * Sin(dat.dAngle * bj_DEGTORAD)
                    set dat.dDistance  = SquareRoot((x - GetUnitX(dat.dUnit)) * (x - GetUnitX(dat.dUnit)) + (y - GetUnitY(dat.dUnit)) * (y - GetUnitY(dat.dUnit)))
                    set dat.dCDistance = 0
                    set dat.dBool4     = true
               
                endif
           
            endif
           
    //-------------------------------------------------------------------------------------------
    //------------------This is the third phase of the spell-------------------------------------
    //-------------------------------------------------------------------------------------------
       
            if (dat.dDistance > dat.dCDistance) and (dat.dBool4 == true) then
           
                set dat.dCDistance = dat.dCDistance + RELAPSDISTANCE
               
                set x = dat.x + RELAPSDISTANCE * Cos(dat.dAngle * bj_DEGTORAD)
                set y = dat.y + RELAPSDISTANCE * Sin(dat.dAngle * bj_DEGTORAD)
               
                call SetUnitX(dat.dUnit, x)
                call SetUnitY(dat.dUnit, y)
                call SetUnitFacing(dat.dUnit, dat.dAngle)
               
                call SetUnitFlyHeight(dat.dUnit, ParabolaZ( RELAPSHIGHT, dat.dDistance, dat.dCDistance), 0)
           
            else
               
                if dat.dBool4 == true then
               
                    call ReleaseTimer(t)
                    call DestroyEffect(AddSpecialEffectTarget(SPELLEFFECT2, dat.dUnit, "origin"))
                    call dat.destroy()
               
                endif
           
            endif
           
        //This is used as an escape method if the unit is not inside the map bounds
       
        set rX = GetUnitX(dat.dUnit)
        set rY = GetUnitY(dat.dUnit)
       
        if (GetRectMinX(r) <= rX) and (rX <= GetRectMaxX(r)) and (GetRectMinY(r) <= rY) and (rY <= GetRectMaxY(r)) == false then
       
            call ReleaseTimer(t)
            call dat.destroy()
           
        endif
       
        endmethod

        private method destroy takes nothing returns nothing
       
            local unit  n = null
       
            call DestroyEffect(.dEffect1)
            call KillUnit(.dUnit)
            call GroupUnitsInArea(ENUM_GROUP, .x, .y, DAMAGEAREA)
           
            loop
           
                set n = FirstOfGroup(ENUM_GROUP)
               
                exitwhen n == null
               
                if (IsUnitAlly(n, .dOwner) == false) and (GetWidgetLife(n) > 0) then
               
                    call UnitDamageTarget(.dCaster, n, DAMAGEDONE, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
               
                endif
               
                call GroupRemoveUnit(ENUM_GROUP, n)
           
            endloop
           
            call ReleaseGroup(ENUM_GROUP)
           
            set n = null
       
        endmethod
       
    endstruct

    private function Conditions takes nothing returns boolean
       
        return GetSpellAbilityId() == SPELLID
       
    endfunction

    private function Actions takes nothing returns nothing

        local unit u    = GetTriggerUnit()
        local real x    = GetSpellTargetX()
        local real y    = GetSpellTargetY()
        local real a    = bj_RADTODEG * Atan2(y - GetUnitY(u), x - GetUnitX(u))
        local integer i = 0
       
        set x = x + MAXDISTANCE * Cos((a - 180) * bj_DEGTORAD)
        set y = y + MAXDISTANCE * Sin((a - 180) * bj_DEGTORAD)
       
        loop
       
            call Data.create(u, x, y, a, (MAXDISTANCE + ( i * UNITDISTANCE)))
       
            set i = i + 1
       
            set x = x + UNITDISTANCE * Cos((a - 180) * bj_DEGTORAD)
            set y = y + UNITDISTANCE * Sin((a - 180) * bj_DEGTORAD)
       
            exitwhen i == MAXCOUNT
       
        endloop

    endfunction

    private function Init takes nothing returns nothing

        local trigger tr = CreateTrigger()
       
        call TriggerRegisterAnyUnitEventBJ( tr, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( tr, Condition( function Conditions ) )
        call TriggerAddAction( tr, function Actions )
       
    endfunction

    endscope
     
     

    Attached Files:

  5. -Kobas-

    -Kobas-

    Joined:
    Jan 17, 2010
    Messages:
    5,894
    Resources:
    28
    Icons:
    1
    Tools:
    2
    Maps:
    10
    Spells:
    4
    Template:
    5
    Tutorials:
    6
    Resources:
    28
    Ahahahah this one look cool :)
    Still you miss burning effect, damage over time, after explosion :D
     
  6. Freyleyes

    Freyleyes

    Joined:
    Jun 28, 2008
    Messages:
    766
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Made a small update.
    *Added a DoT effect

    Worms Sheep Strike
    Show
    http://www.youtube.com/watch?v=Kmo1X7ST2cM
     

    Attached Files:

  7. Klingo

    Klingo

    Joined:
    Dec 19, 2009
    Messages:
    246
    Resources:
    5
    Spells:
    5
    Resources:
    5
    It's the last day of this contest, if you guys havn't finish, speed up a litlle bit and post your final submission
     
  8. Mage_Goo

    Mage_Goo

    Joined:
    Jun 1, 2008
    Messages:
    366
    Resources:
    2
    Spells:
    2
    Resources:
    2
    fuh... it's still 7 hour before the deadline, right?

    Finally, the first and final submission:
    Final Submission here

    Legend of Mana's Aerial Reaver

    here's the video, it start from 2.26 to 2.32. Can't find any other video, so i hope this will do
    video
    http://www.youtube.com/watch?v=5tqI4Rv-ftI


    code
    Code (vJASS):
    scope AerialReaver initializer InitTrig_Initialize
        ///////////////////////////////////////////////////////////////////////////////////////
        //Welcome to the Header                                                              //
        //u can customize most part of the spell from here                                   //
        ///////////////////////////////////////////////////////////////////////////////////////
        globals
            //Insert the raw-code of your Aerial Reaver ability. U can see the raw-code of the spell by pressing Ctrl+D.
            private constant integer SpellID                = 'A000'
            //Insert your dummy unit raw-code. Dummy unit must be able to be attached by an effect.
            private constant integer DummyID                = 'h000'
            //this one for the attachment point of the dummy. most of it use either "chest" or "origin".
            private constant string DummyAttach             = "chest"
            //insert where u want the effect attached to your unit that cast this spell.
            private constant string CasterAttach            = "chest"
            //insert where u want the effect attached to enemy unit that get affected by this spell.
            private constant string TargetAttach            = "chest"
           
            //to produce a value in this spell that get increased/decreased on different level,
            //i use the default and modifier value. for lvl 1 spell, the default value will be applied.
            //on each increased lvl, the modifier value will be added to default value, thus effectively
            //increase/decrease that value.
            //ex: First Explosion's damage default value is 150 dmg and it's modifier value is 50 dmg.
            // so, on lvl 1, the damage will be 100. on lvl 2 it's (100+50)=150 dmg,
            //on lvl 3 it's (150+50)=200 dmg, and so on
           
            //insert the spell's area of effect here. this will be the default value.
            private constant real AoE                       = 300.
            //insert modifier of spell's area of effect here.
            private constant real AoEIncr                   = 50.
           
            //Fitst Explosion Set-up
            //insert the damage dealt by the first explosion here. this will be the default value.
            private constant real FEDamage                  = 50.
            //insert modifier of first explosion damage here.
            private constant real FEDamageIncr              = 25.
            //insert the animation u want the caster to play when first explosion occur here
            private constant string FECasterAnim            = "slam"
            //insert the max height of the caster's jump here
            private constant real FECasterJumpHeight        = 200.
            //insert how long the first explosion will last. this will be the default value
            private constant real FETime                    = 2.5
            //insert modifier of first explosion time here.
            private constant real FETimeIncr                = 0.5
            //insert the max height the tossed unit will reach here
            private constant real FETossHeight              = 400.
            private constant real FETossHeightRatio         = 0.5
            //First Eplosion Effect
            //insert how many line of explosion will be created. this will be the default value
            private constant integer FEELineSum             = 3
            //insert the modifier of line sum here.
            private constant integer FEELineSumIncr         = 1
            //insert how many 'pillar' will be created on each line here. this will be the default value
            private constant integer FEECircleSum           = 2
            //insert the modifier of 'pillar' sum per line here
            private constant integer FEECircleSumIncr       = 1
            //insert how may effect will created for each 'pillar' here
            private constant integer FEESum                 = 10
            //insert the height of the pillar here
            private constant real FEEHeight                 = 400.
            //insert the interval of each new circle of pillar will be created here
            private constant real FEEInterval               = 0.5
            //insert the time needed for each 'pillar' to fully appear here
            private constant real FEEAppearTime             = 0.5
            //insert the time each pillar will stand still, doing nothing here
            private constant real FEEStandTime              = 0.5
            //insert the time needed for each pillar to fully disappear here
            private constant real FEEDisappearTime          = 0.5
           
            //Second Explosion Set-up
            //insert the damage dealt by the second explosion here. this will be the default value.
            private constant real SEDamage                  = 100.
            //insert modifier of second explosion damage here.
            private constant real SEDamageIncr              = 25.
            //insert the animation u want the caster to play when first explosion occur here
            private constant string SECasterAnim            = "attack"
            //insert the max height of the caster's jump here
            private constant real SECasterJumpHeight        = 200.
            //insert the rotation speed of the caster here
            private constant real SECasterAngSpeed          = 3600.
            //insert how long the second explosion will last.
            private constant real SETime                    = 3.
            //insert the max height the tossed unit will reach here
            private constant real SETossHeight              = 400.
            //Second Explosion Effect
            //insert how many rotating effect that will be created here
            private constant integer SEESum                 = 10
            //insert the height of the rotating effect here
            private constant real SEEHeight                 = 200.
            //insert the rotating effect distance to caster here
            private constant real SEEDistance               = 200.
            //insert the rotating effect rotating speed here
            private constant real SEEAngSpeed               = 360.
            //insert the interval between the appearance of each rotating effect here
            private constant real SEEAppearInterval         = 0.1
            //insert the interval between the disappearance of each rotating effect here
            private constant real SEEDisappearInterval      = 0.1
           
            //Effect Set-up
            //insert the 'pillar' from first explosion effect model here
            private constant string FEEModel                = "Abilities\\Spells\\Undead\\Darksummoning\\DarkSummonTarget.mdl"
            //set the red tinting color of 'pillar' here. It's between 0 to 255.
            private constant integer FEEModelRed            = 255
            //set the green tinting color of 'pillar' here. It's between 0 to 255.
            private constant integer FEEModelGreen          = 75
            //set the blue tinting color of 'pillar' here. It's between 0 to 255.
            private constant integer FEEModelBlue           = 200
            //insert the effect that will be created on caster when the first explosion occur.
            //this one destroyed instantly
            private constant string FECasterEffect          = ""
            //insert the effect that will be attached on caster when the first explosion occur.
            //this one stay until first explosion end
            private constant string FECasterAttachEffect    = "Abilities\\Spells\\Items\\HealingSalve\\HealingSalveTarget.mdl"
            //insert the effect that will be created on unit when it tossed by the first explosion.
            //this one destroyed instantly
            private constant string FETargetEffect          = ""
            //insert the effect that will be attached on unit when it tossed by the first explosion.
            //this one stay until the toss end
            private constant string FETargetAttachEffect    = ""
            //insert the rotating effect model here
            private constant string SEEModel                = "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl"
            //set the red tinting color of rotating effect here. It's between 0 to 255.
            private constant integer SEEModelRed            = 0
            //set the green tinting color of rotating effect here. It's between 0 to 255.
            private constant integer SEEModelGreen          = 0
            //set the blue tinting color of rotating effect here. It's between 0 to 255.
            private constant integer SEEModelBlue           = 0
            //set the rotating effect scale
            private constant real SEEModelScale             = 2.
            //insert the effect that will be created on caster when the second explosion occur.
            //this one destroyed instantly
            private constant string SECasterEffect          = "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"
            //insert the effect that will be attached on caster when the second explosion occur.
            //this one stay until second explosion end
            private constant string SECasterAttachEffect    = "Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl"
            //insert the effect that will be created on unit when it tossed by the second explosion.
            //this one destroyed instantly
            private constant string SETargetEffect          = ""
            //insert the effect that will be attached on unit when it tossed by the second explosion.
            //this one stay until the toss end
            private constant string SETargetAttachEffect    = ""
           
            //set the timer's time out. the lower it is, the more precise the spell will get.
            //but, warcraft has it's limit for time out though. don't use value lower than 0.03
            //because it will lower the warcraft performance.
            //this one usually between 0.05 to 0.03. 0.03 is more common(and efficient too!)
            private constant real TimeOut                   = 0.03
           
            //this one will decide the first explosion attack type
            private constant attacktype FEATT               = ATTACK_TYPE_NORMAL
            //this one will decide the first explosion damage type
            private constant damagetype FEDGT               = DAMAGE_TYPE_NORMAL
            //this one will decide the first explosion weapon type
            private constant weapontype FEWPT               = WEAPON_TYPE_WHOKNOWS
            //this one will decide the second explosion attack type
            private constant attacktype SEATT               = ATTACK_TYPE_NORMAL
            //this one will decide the second explosion damage type
            private constant damagetype SEDGT               = DAMAGE_TYPE_NORMAL
            //this one will decide the second explosion weapon type
            private constant weapontype SEWPT               = WEAPON_TYPE_WHOKNOWS
           
            //////////////////////////////////////////////////////////////////////
            private boolexpr filter
            private unit temp
            //this line is variable for the spell's mechanism. don't change it.
            //it's for the sake of efficiency of the spell..
            private unit u2
            private group g = CreateGroup()
            private real array R
            //////////////////////////////////////////////////////////////////////
        endglobals
       
        //u can edit the condition the unit neded to be affected by the spell here
        private function CanTarget takes unit caster, unit target returns boolean
            return IsUnitEnemy(target, GetOwningPlayer(caster))/*
             */
    and not (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE))/*
             */
    and not (IsUnitType(target, UNIT_TYPE_DEAD))/*
             */
    and IsUnitType(target, UNIT_TYPE_GROUND)/*
             */
    and IsUnitVisible(target, GetOwningPlayer(caster))
        endfunction
        ///////////////////////////////////////////////////////////////////////////////////////
        //This is the end of the header                                                      //
        //don't edit anything below if u don't know it.                                      //
        ///////////////////////////////////////////////////////////////////////////////////////
       
        //tossed struct.
        private struct Tossed
            private unit u
            private real vx
            private real angle
            private real vy
            private real acc
            private effect sfx
           
            static group Affected = CreateGroup()
           
            private static Tossed array Index
            private static integer Total = 0
            private static timer Timer = CreateTimer()
           
            static method Change takes unit u1, real x, real y, real a, real ang, string sfxs, string sfxs2 returns nothing
                //change the velocity and the deccelerate of the unit. only called if the unit is tossed when it's already being tossed
                local Tossed dat
                local integer i = 0
                loop
                    exitwhen i >= Tossed.Total
                    set dat = Tossed.Index[i]
                    if dat.u == u1 then
                        set dat.u = u1
                        set dat.vx = x
                        set dat.vy = y
                        set dat.acc = a
                        set dat.angle = ang
                        call DestroyEffect(dat.sfx)
                        set dat.sfx = AddSpecialEffectTarget(sfxs,u1,TargetAttach)
                        call DestroyEffect(AddSpecialEffectTarget(sfxs2,u1,TargetAttach))
                    endif
                    set i = i + 1
                endloop
            endmethod
           
            static method Loop takes nothing returns nothing
                //the loop. long story short, this one just move the unit according to it's velocity.
                //also reduce the velocity by the decceleration.
                local Tossed dat
                local integer i = 0
                loop
                    exitwhen i >= Tossed.Total
                    set dat = Tossed.Index[i]
                    set dat.vy = dat.vy - (dat.acc*TimeOut)
                    set R[1] = GetUnitX(dat.u) + dat.vx*TimeOut*Cos(dat.angle*bj_DEGTORAD)
                    set R[2] = GetUnitY(dat.u) + dat.vx*TimeOut*Sin(dat.angle*bj_DEGTORAD)
                    set R[3] = GetUnitFlyHeight(dat.u) + (dat.vy*TimeOut)
                    call SetUnitX(dat.u,R[1])
                    call SetUnitY(dat.u,R[2])
                    call SetUnitFlyHeight(dat.u,R[3],0.)
                    if R[3] <= 0 then
                        call PauseUnit(dat.u,false)
                        call DestroyEffect(dat.sfx)
                        call SetUnitFlyHeight(dat.u,GetUnitDefaultFlyHeight(dat.u),0.)
                        call GroupRemoveUnit(Tossed.Affected,dat.u)
                        set dat.u = null
                        set dat.sfx = null
                        call dat.destroy()
                        set Tossed.Total = Tossed.Total - 1
                        set Tossed.Index[i] = Tossed.Index[Tossed.Total]
                        set i = i - 1
                    endif
                    set i = i + 1
                endloop
                if Tossed.Total == 0 then
                    call PauseTimer(Tossed.Timer)
                endif
            endmethod
           
            static method Create takes unit u1, real x, real y, real a, real ang, string sfxs, string sfxs2 returns nothing
                //index the unit and save the velocity and decceleration
                local Tossed dat = Tossed.allocate()
                set dat.u = u1
                call UnitAddAbility(u1,'Arav')
                call UnitRemoveAbility(u1,'Arav')
                set dat.vx = x
                set dat.vy = y
                set dat.acc = a
                set dat.angle = ang
                set dat.sfx = AddSpecialEffectTarget(sfxs,u1,TargetAttach)
                call PauseUnit(dat.u,true)
                call DestroyEffect(AddSpecialEffectTarget(sfxs2,u1,TargetAttach))
                call GroupAddUnit(Tossed.Affected,u1)
                if Tossed.Total == 0 then
                    call TimerStart(Tossed.Timer,TimeOut,true,function Tossed.Loop)
                endif
                set Tossed.Index[Tossed.Total] = dat
                set Tossed.Total = Tossed.Total + 1
            endmethod
        endstruct
       
        //the 'pillar' struct
        private struct FEEffect
            private group sfxg
            private real Time
            private integer ActId
           
            private static FEEffect array Index
            private static integer Total = 0
            private static timer Timer = CreateTimer()
           
            static method Loop takes nothing returns nothing
                //basically doing 1 of 3 stuff.
                //1. moving the effect to it's place in 'pillar'
                //2. stand still, doing nothing
                //3. make pillar dsappear by scale the effect down, then kill it
                local FEEffect dat
                local integer i = 0
                loop
                    exitwhen i >= FEEffect.Total
                    set dat = FEEffect.Index[i]
                    set dat.Time = dat.Time-TimeOut
                    if dat.ActId == 1 then
                        call GroupAddGroup(dat.sfxg,g)
                        loop
                            set u2 = FirstOfGroup(g)
                            exitwhen u2 == null
                            set R[1] = (FEEHeight/FEESum)*GetUnitUserData(u2)
                            set R[2] = R[1]*((FEEAppearTime-dat.Time)/FEEAppearTime)
                            call SetUnitFlyHeight(u2,R[2],0)
                            call GroupRemoveUnit(g,u2)
                        endloop
                        if dat.Time <= 0 then
                            set dat.Time = FEEStandTime
                            set dat.ActId = 2
                        endif
                    elseif dat.ActId == 2 then
                        if dat.Time <= 0 then
                            set dat.Time = FEEDisappearTime
                            set dat.ActId = 3
                        endif
                    elseif dat.ActId == 3 then
                        if dat.Time <= 0 then
                            loop
                                set u2 = FirstOfGroup(dat.sfxg)
                                exitwhen u2 == null
                                call UnitApplyTimedLife(u2,'BTLF',TimeOut)
                                call GroupRemoveUnit(dat.sfxg,u2)
                            endloop
                            call DestroyGroup(dat.sfxg)
                            set dat.sfxg = null
                            call dat.destroy()
                            set FEEffect.Total = FEEffect.Total - 1
                            set FEEffect.Index[i] = FEEffect.Index[FEEffect.Total]
                            set i = i -1
                        else
                            set R[1] = (dat.Time/FEEDisappearTime)
                            call GroupAddGroup(dat.sfxg,g)
                            loop
                                set u2 = FirstOfGroup(g)
                                exitwhen u2 == null
                                call SetUnitScale(u2,R[1],R[1],R[1])
                                call GroupRemoveUnit(g,u2)
                            endloop
                        endif
                    endif
                    set i = i + 1
                endloop
                if FEEffect.Total == 0 then
                    call PauseTimer(FEEffect.Timer)
                endif  
            endmethod
                   
            static method Create takes real x, real y, player p returns nothing
                //initiate and create the effect
                local FEEffect dat = FEEffect.allocate()
                local integer i = 0
                local unit u
                set dat.sfxg = CreateGroup()
                set dat.Time = FEEAppearTime
                set dat.ActId = 1
                loop
                    exitwhen i > FEESum
                    set u = CreateUnit(p,DummyID,x,y,0.)
                    call AddSpecialEffectTarget(FEEModel,u,DummyAttach)
                    call GroupAddUnit(dat.sfxg,u)
                    call SetUnitUserData(u,i)
                    call SetUnitVertexColor(u,FEEModelRed,FEEModelGreen,FEEModelBlue,255)
                    set i = i + 1    
                endloop
                if FEEffect.Total == 0 then
                    call TimerStart(FEEffect.Timer,TimeOut,true,function FEEffect.Loop)
                endif
                set FEEffect.Index[FEEffect.Total] = dat
                set FEEffect.Total = FEEffect.Total + 1
            endmethod
        endstruct
       
        //the main struct
        private struct Main
            private unit Caster
            private real x
            private real y
            private real angle
            private integer ActId
            private real Area
            private real Time
            private real Time2
            private real v
            private real acc
            private integer num
            private integer num2
            private integer level
            private group sfxg
            private effect sfx
            private group affected
           
            private static Main array Index
            private static integer Total = 0
            private static timer Timer = CreateTimer()
           
            static method CanTargeted takes nothing returns boolean
                //for filter purpose
                return CanTarget(temp,GetFilterUnit())
            endmethod
           
            static method Loop takes nothing returns nothing
                //this basically doing 2 stuff.
                //1. doing the first explosion. explained below
                //2. doing the second explosion. explained below
                //also check if the caster dies. if yes, end the spell immediately
                local Main dat
                local integer i = 0
                local integer l
                loop
                    exitwhen i >= Main.Total
                    set dat = Main.Index[i]
                    set dat.Time = dat.Time-TimeOut
                    set dat.Time2 = dat.Time2-TimeOut
                    call SetUnitFlyHeight(dat.Caster,GetUnitFlyHeight(dat.Caster)+(dat.v*TimeOut),0.)
                    set dat.v = dat.v-(dat.acc*TimeOut)
                    if  IsUnitType(dat.Caster,UNIT_TYPE_DEAD) then
                        call PauseUnit(dat.Caster,false)
                        call SetUnitFlyHeight(dat.Caster,GetUnitDefaultFlyHeight(dat.Caster),0)
                        call DestroyEffect(dat.sfx)
                        loop
                            set u2 = FirstOfGroup(dat.sfxg)
                            exitwhen u2 == null
                            call UnitApplyTimedLife(u2,'BTLF',TimeOut)
                            call GroupRemoveUnit(dat.sfxg,u2)
                        endloop
                        call DestroyGroup(dat.sfxg)
                        call DestroyGroup(dat.affected)
                        set dat.Caster = null
                        set dat.sfx = null
                        set dat.sfxg = null
                        set dat.affected = null
                        call dat.destroy()
                        set Main.Total = Main.Total - 1
                        set Main.Index[i] = Main.Index[Main.Total]
                        set i = i - 1
                    elseif dat.ActId == 1 then
                        //first explosion.
                        //basically just create each 'pillar' circle by circle on each interval.
                        //it also toss unit and add it to group so it didn't tossed again
                        if (dat.Time2 <= 0) and (dat.num<=dat.num2) then
                            set dat.Time2 = FEEInterval
                            set l = FEELineSum+(FEELineSumIncr*dat.level)
                            set R[1] = 360/I2R(l)
                            set R[2] = (dat.Area/I2R(dat.num2))*I2R(dat.num)
                            loop
                                exitwhen l <= 0
                                set R[3] = dat.angle+(R[1]*I2R(l))
                                if R[3] > 360 then
                                    set R[3] = R[3] - 360
                                endif
                                call FEEffect.Create(dat.x+(R[2]*Cos(R[3]*bj_DEGTORAD)),dat.y+(R[2]*Sin(R[3]*bj_DEGTORAD)),GetOwningPlayer(dat.Caster))
                                set l = l - 1
                            endloop
                            set dat.num = dat.num+1
                        endif
                        call GroupAddGroup(dat.affected,g)
                        loop
                            set u2 = FirstOfGroup(g)
                            exitwhen u2 == null
                            if not (CanTarget(dat.Caster,u2)) then
                                call GroupRemoveUnit(dat.affected,u2)
                            endif
                            call GroupRemoveUnit(g,u2)
                        endloop
                        set temp = dat.Caster
                        set filter = Filter(function Main.CanTargeted)
                        call GroupEnumUnitsInRange(g,dat.x,dat.y,dat.Area,filter)
                        loop
                            set u2 = FirstOfGroup(g)
                            exitwhen u2 == null
                            if not IsUnitInGroup(u2,dat.affected) then
                                set R[4] = (2*FETossHeight*dat.Time)/(FETossHeight+SquareRoot(FETossHeight*FETossHeight*(1-FETossHeightRatio)))
                                set R[1] = (4*FETossHeight)/(R[4])
                                set R[3] = (8*FETossHeight)/(R[4]*R[4])
                                call GroupAddUnit(dat.affected,u2)    
                                set R[0] = FEDamage+(FEDamageIncr*I2R(dat.level))
                                call UnitDamageTarget(dat.Caster,u2,R[0],true,false,FEATT,FEDGT,FEWPT)
                                if IsUnitInGroup(u2,Tossed.Affected) then
                                    call Tossed.Change(u2,0,R[1],R[3],0.,FETargetAttachEffect,FETargetEffect)
                                else                                  
                                    call Tossed.Create(u2,0,R[1],R[3],0.,FETargetAttachEffect,FETargetEffect)
                                endif
                            endif  
                            call GroupRemoveUnit(g,u2)
                        endloop
                        if dat.Time <= 0 then
                            //change of phase.
                            //re-initiate the variable, effect, and the group
                            set dat.angle = GetRandomReal(0.,360.)
                            set dat.ActId = 2
                            set dat.Time = SETime
                            set dat.Time2 = SEEAppearInterval
                            set dat.v = (4*SECasterJumpHeight)/dat.Time
                            set dat.acc = (8*SECasterJumpHeight)/(dat.Time*dat.Time)
                            set dat.num = 1
                            set dat.num2 = SEESum
                            call DestroyEffect(dat.sfx)
                            set dat.sfx = AddSpecialEffectTarget(SECasterAttachEffect,dat.Caster,CasterAttach)
                            call DestroyEffect(AddSpecialEffectTarget(SECasterEffect,dat.Caster,CasterAttach))
                            call SetUnitAnimation(dat.Caster,SECasterAnim)
                            call GroupClear(dat.affected)
                            set temp = dat.Caster
                            set filter = Filter(function Main.CanTargeted)
                            call GroupEnumUnitsInRange(g,dat.x,dat.y,dat.Area,filter)
                            loop
                                set u2 = FirstOfGroup(g)
                                exitwhen u2 == null
                                set R[5] = (2*SETossHeight*dat.Time)/(SETossHeight+SquareRoot(SETossHeight*(SETossHeight-GetUnitFlyHeight(u2))))
                                set R[1] = (4*SETossHeight)/(R[5])
                                set R[6] = GetUnitX(u2)-dat.x
                                set R[7] = GetUnitY(u2)-dat.y
                                set R[2] = (dat.Area-SquareRoot(R[6]*R[6]+R[7]*R[7]))/dat.Time
                                set R[3] = (8*FETossHeight)/(R[5]*R[5])
                                set R[4] = bj_RADTODEG*Atan2(GetUnitY(u2)-dat.y,GetUnitX(u2)-dat.x)
                                call GroupAddUnit(dat.affected,u2)
                                set R[0] = SEDamage+(SEDamageIncr*I2R(dat.level))
                                call UnitDamageTarget(dat.Caster,u2,R[0],true,false,SEATT,SEDGT,SEWPT)
                                if IsUnitInGroup(u2,Tossed.Affected) then
                                    call Tossed.Change(u2,R[2],R[1],R[3],R[4],SETargetAttachEffect,SETargetEffect)
                                else
                                    call Tossed.Create(u2,R[2],R[1],R[3],R[4],SETargetAttachEffect,SETargetEffect)
                                endif
                                call GroupRemoveUnit(g,u2)
                            endloop
                            set temp = null
                            call DestroyBoolExpr(filter)
                        endif
                    elseif dat.ActId == 2 then
                        //the second explosion
                        //basically just create each rotating effect one by one, then rotating it individually
                        //also rotate the caster
                        set dat.angle = dat.angle+(SEEAngSpeed*TimeOut)
                        call SetUnitFacing(dat.Caster,GetUnitFacing(dat.Caster)+(SECasterAngSpeed*TimeOut))
                        call GroupAddGroup(dat.sfxg,g)
                        loop
                            set u2 = FirstOfGroup(g)
                            exitwhen u2 == null
                            set R[1] = GetUnitFacing(u2)+(SEEAngSpeed*TimeOut)
                            call SetUnitX(u2,dat.x+(SEEDistance*Cos(R[1]*bj_DEGTORAD)))
                            call SetUnitY(u2,dat.y+(SEEDistance*Sin(R[1]*bj_DEGTORAD)))
                            call SetUnitFacing(u2,R[1])
                            call GroupRemoveUnit(g,u2)
                        endloop
                        if (dat.Time2 <= 0) and (dat.num<=dat.num2) then
                            set dat.Time2 = SEEAppearInterval
                            set u2 = CreateUnit(GetOwningPlayer(dat.Caster),DummyID,dat.x+(SEEDistance*Cos(dat.angle*bj_DEGTORAD)),dat.y+(SEEDistance*Sin(dat.angle*bj_DEGTORAD)),dat.angle)
                            call AddSpecialEffectTarget(SEEModel,u2,DummyAttach)
                            call SetUnitScale(u2,SEEModelScale,SEEModelScale,SEEModelScale)
                            call SetUnitFlyHeight(u2,(SEEHeight/I2R(dat.num2))*dat.num,0.)
                            call SetUnitFacing(u2,dat.angle)
                            call SetUnitVertexColor(u2,SEEModelRed,SEEModelGreen,SEEModelBlue,255)
                            set R[1] = ((dat.Time+(dat.Time2*dat.num))/2)+(SEEDisappearInterval*(dat.num-1))
                            call UnitApplyTimedLife(u2,'BTLF',R[1])    
                            call GroupAddUnit(dat.sfxg,u2)
                            set dat.angle = dat.angle - (360/I2R(dat.num2))
                            set dat.num = dat.num+1
                        endif
                        call GroupAddGroup(dat.affected,g)
                        loop
                            set u2 = FirstOfGroup(g)
                            exitwhen u2 == null
                            if not (CanTarget(dat.Caster,u2)) then
                                call GroupRemoveUnit(dat.affected,u2)
                            endif
                            call GroupRemoveUnit(g,u2)
                        endloop
                        set temp = dat.Caster
                        set filter = Filter(function Main.CanTargeted)
                        call GroupEnumUnitsInRange(g,dat.x,dat.y,dat.Area,filter)
                        loop
                            set u2 = FirstOfGroup(g)
                            exitwhen u2 == null
                            if not IsUnitInGroup(u2,dat.affected) then
                                set R[5] = (2*SETossHeight*dat.Time)/(SETossHeight+SquareRoot(SETossHeight*(SETossHeight-GetUnitFlyHeight(u2))))
                                set R[1] = (4*SETossHeight)/(R[5])
                                set R[6] = GetUnitX(u2)-dat.x
                                set R[7] = GetUnitY(u2)-dat.y
                                set R[2] = (dat.Area-SquareRoot(R[6]*R[6]+R[7]*R[7]))/dat.Time
                                set R[3] = (8*FETossHeight)/(R[5]*R[5])
                                set R[4] = bj_RADTODEG*Atan2(GetUnitY(u2)-dat.y,GetUnitX(u2)-dat.x)
                                call GroupAddUnit(dat.affected,u2)    
                                set R[0] = SEDamage+(SEDamageIncr*I2R(dat.level))
                                call UnitDamageTarget(dat.Caster,u2,R[0],true,false,SEATT,SEDGT,SEWPT)
                                if IsUnitInGroup(u2,Tossed.Affected) then
                                    call Tossed.Change(u2,R[2],R[1],R[3],R[4],SETargetAttachEffect,SETargetEffect)
                                else
                                    call Tossed.Create(u2,R[2],R[1],R[3],R[4],SETargetAttachEffect,SETargetEffect)
                                endif
                            endif  
                            call GroupRemoveUnit(g,u2)
                        endloop
                        if dat.Time <= 0 then
                            //finish the spell. clearing te index
                            call PauseUnit(dat.Caster,false)
                            call SetUnitFlyHeight(dat.Caster,GetUnitDefaultFlyHeight(dat.Caster),0)
                            call DestroyEffect(dat.sfx)
                            loop
                                set u2 = FirstOfGroup(dat.sfxg)
                                exitwhen u2 == null
                                call UnitApplyTimedLife(u2,'BTLF',TimeOut)
                                call GroupRemoveUnit(dat.sfxg,u2)
                            endloop
                            call DestroyGroup(dat.sfxg)
                            call DestroyGroup(dat.affected)
                            set dat.Caster = null
                            set dat.sfx = null
                            set dat.sfxg = null
                            set dat.affected = null
                            call dat.destroy()
                            set Main.Total = Main.Total - 1
                            set Main.Index[i] = Main.Index[Main.Total]
                            set i = i - 1
                        endif
                    endif
                    set i = i +1
                endloop
                if Main.Total == 0 then
                    call PauseTimer(Main.Timer)
                endif  
            endmethod
           
            static method Create takes nothing returns nothing
                //the creating of the spell.
                //create one pillar in the place of caster.
                //initiate all variable, create the efect, etc.
                local Main dat = Main.allocate()
                local unit u = GetTriggerUnit()
                call PauseUnit(u,true)
                set dat.Caster = u
                call PauseUnit(dat.Caster,true)
                call UnitAddAbility(u,'Arav')
                call UnitRemoveAbility(u,'Arav')
                set dat.x = GetUnitX(u)
                set dat.y = GetUnitY(u)
                set dat.angle = GetRandomReal(0.,360.)
                call FEEffect.Create(dat.x,dat.y,GetOwningPlayer(u))
                set dat.ActId = 1
                set dat.level = GetUnitAbilityLevel(u,SpellID) - 1
                set dat.Area = AoE+(AoEIncr*I2R(dat.level))
                set dat.Time = FETime+(FETimeIncr*I2R(dat.level))
                set dat.Time2 = FEEInterval
                set dat.v = (4*FECasterJumpHeight)/dat.Time
                set dat.acc = (8*FECasterJumpHeight)/(dat.Time*dat.Time)
                set dat.num = 1
                set dat.num2 = FEECircleSum+(FEECircleSumIncr*dat.level)
                set dat.sfxg = CreateGroup()
                set dat.sfx = AddSpecialEffectTarget(FECasterAttachEffect,u,CasterAttach)
                call DestroyEffect(AddSpecialEffectTarget(FECasterEffect,u,CasterAttach))
                call SetUnitAnimation(u,FECasterAnim)
                set dat.affected = CreateGroup()
                set temp = u
                set filter = Filter(function Main.CanTargeted)
                call GroupEnumUnitsInRange(g,dat.x,dat.y,dat.Area,filter)
                loop
                    set u2 = FirstOfGroup(g)
                    exitwhen u2 == null
                    set R[4] = (2*FETossHeight*dat.Time)/(FETossHeight+SquareRoot(FETossHeight*FETossHeight*(1-FETossHeightRatio)))
                    set R[1] = (4*FETossHeight)/(R[4])
                    set R[3] = (8*FETossHeight)/(R[4]*R[4])
                    call GroupAddUnit(dat.affected,u2)
                    set R[0] = FEDamage+(FEDamageIncr*I2R(dat.level))
                    call UnitDamageTarget(dat.Caster,u2,R[0],true,false,FEATT,FEDGT,FEWPT)
                    if IsUnitInGroup(u2,Tossed.Affected) then
                        call Tossed.Change(u2,0,R[1],R[3],0.,FETargetAttachEffect,FETargetEffect)
                    else
                        call Tossed.Create(u2,0,R[1],R[3],0.,FETargetAttachEffect,FETargetEffect)
                    endif
                    call GroupRemoveUnit(g,u2)
                endloop
                set temp = null
                call DestroyBoolExpr(filter)
                if Main.Total == 0 then
                    call TimerStart(Main.Timer,TimeOut,true,function Main.Loop)
                endif
                set Main.Index[Main.Total] = dat
                set Main.Total = Main.Total+1
                set u = null
            endmethod  
        endstruct
       
        private function Conditions takes nothing returns boolean
            if GetSpellAbilityId() == SpellID then
                call Main.Create()
            endif
            return false
        endfunction
       
        private function InitTrig_Initialize takes nothing returns nothing
            //create the trigger
            local trigger t = CreateTrigger()
            //add event
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            //add 'condition'
            call TriggerAddCondition(t, Condition(function Conditions))
            //preload dummy unit
            call RemoveUnit(CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),DummyID,0,0,0))
            //preload the spell's effect
            call Preload(FEEModel)
            call Preload(FECasterEffect)
            call Preload(FECasterAttachEffect)
            call Preload(FETargetEffect)  
            call Preload(FETargetAttachEffect)
            call Preload(SEEModel)
            call Preload(SECasterEffect)  
            call Preload(SECasterAttachEffect)
            call Preload(SETargetEffect)  
            call Preload(SETargetAttachEffect)
        endfunction
    endscope


    honestly, this is the most un-polished and rushed spell I've ever done. If only I still have time... darn exam, killing 90% of my time.

    changelog
    v1.0
    Uploaded
     

    Attached Files:

    Last edited: Jun 18, 2011
  9. Vengeancekael

    Vengeancekael

    Joined:
    Aug 11, 2009
    Messages:
    5,746
    Resources:
    16
    Tools:
    1
    Maps:
    13
    Spells:
    1
    StarCraft II Resources:
    1
    Resources:
    16
    You still have some time to work on it. But I guess you're busy.
     
  10. Mage_Goo

    Mage_Goo

    Joined:
    Jun 1, 2008
    Messages:
    366
    Resources:
    2
    Spells:
    2
    Resources:
    2
    yeah, i know. The caster animation is ugly, there's some additional effect i want to add, etc. but darn real life. when i submit this, it's already 1 am here, so i can't use the remaining 7 hour to polish it a bit.

    So, now it's already finished, right?
    anyone have the list of all submission?
    EDIT:
    DARN!
    still have four hours left! gonna update it

    EDIT2:
    since I'm not allowed to double post, I'll just make the proper submission here


    Contestant Name: Mage_Goo
    Entry Name: Aerial Reaver v1.1

    Tooltip
    Aerial Reaver
    icon.jpg
    A secret technique of throwin enemies up into the air and carving into them as they fall.

    Level 1 - Deal a total of 150 damage in an area of 300.
    Level 2 - Deal a total of 200 damage in an area of 350.
    Level 3 - Deal a total of 250 damage in an area of 400.
    Target ground unit only.

    Some screeny
    Screeny
    [​IMG]

    The real Aerial Reaver. It start from 2.26 to 2.32. Can't find other video, so I hope this will do.
    video
    http://www.youtube.com/watch?v=5tqI4Rv-ftI

    another long code...
    code
    Code (vJASS):
    scope AerialReaver initializer InitTrig_Initialize
        ///////////////////////////////////////////////////////////////////////////////////////
        //Welcome to the Header                                                              //
        //u can customize most part of the spell from here                                   //
        ///////////////////////////////////////////////////////////////////////////////////////
        globals
            //Insert the raw-code of your Aerial Reaver ability. U can see the raw-code of the spell by pressing Ctrl+D.
            private constant integer SpellID                = 'A000'
            //Insert your dummy unit raw-code. Dummy unit must be able to be attached by an effect.
            private constant integer DummyID                = 'h000'
            //this one for the attachment point of the dummy. most of it use either "chest" or "origin".
            private constant string DummyAttach             = "chest"
            //insert where u want the effect attached to your unit that cast this spell.
            private constant string CasterAttach            = "chest"
            //insert where u want the effect attached to enemy unit that get affected by this spell.
            private constant string TargetAttach            = "chest"
           
            //to produce a value in this spell that get increased/decreased on different level,
            //i use the default and modifier value. for lvl 1 spell, the default value will be applied.
            //on each increased lvl, the modifier value will be added to default value, thus effectively
            //increase/decrease that value.
            //ex: First Explosion's damage default value is 150 dmg and it's modifier value is 50 dmg.
            // so, on lvl 1, the damage will be 100. on lvl 2 it's (100+50)=150 dmg,
            //on lvl 3 it's (150+50)=200 dmg, and so on
           
            //insert the spell's area of effect here. this will be the default value.
            private constant real AoE                       = 300.
            //insert modifier of spell's area of effect here.
            private constant real AoEIncr                   = 50.
           
            //Fitst Explosion Set-up
            //insert the damage dealt by the first explosion here. this will be the default value.
            private constant real FEDamage                  = 50.
            //insert modifier of first explosion damage here.
            private constant real FEDamageIncr              = 25.
            //insert the animation u want the caster to play when first explosion occur here
            private constant string FECasterAnim            = "slam"
            //insert the animation's time here
            private constant real FECasterAnimTime          = 5.
            //insert the max height of the caster's jump here
            private constant real FECasterJumpHeight        = 200.
            //insert how long the first explosion will last. this will be the default value
            private constant real FETime                    = 2.5
            //insert modifier of first explosion time here.
            private constant real FETimeIncr                = 0.5
            //insert the max height the tossed unit will reach here
            private constant real FETossHeight              = 400.
            private constant real FETossHeightRatio         = 0.5
            //First Eplosion Effect
            //insert how many line of explosion will be created. this will be the default value
            private constant integer FEELineSum             = 3
            //insert the modifier of line sum here.
            private constant integer FEELineSumIncr         = 1
            //insert how many 'pillar' will be created on each line here. this will be the default value
            private constant integer FEECircleSum           = 2
            //insert the modifier of 'pillar' sum per line here
            private constant integer FEECircleSumIncr       = 1
            //insert how may effect will created for each 'pillar' here
            private constant integer FEESum                 = 5
            //insert the height of the pillar here
            private constant real FEEHeight                 = 400.
            //insert the interval of each new circle of pillar will be created here
            private constant real FEEInterval               = 0.5
            //insert the time needed for each 'pillar' to fully appear here
            private constant real FEEAppearTime             = 0.5
            //insert the time each pillar will stand still, doing nothing here
            private constant real FEEStandTime              = 0.5
            //insert the time needed for each pillar to fully disappear here
            private constant real FEEDisappearTime          = 0.5
           
            //Second Explosion Set-up
            //insert the damage dealt by the second explosion here. this will be the default value.
            private constant real SEDamage                  = 100.
            //insert modifier of second explosion damage here.
            private constant real SEDamageIncr              = 25.
            //insert the animation u want the caster to play when first explosion occur here
            private constant string SECasterAnim            = "attack"
            //insert the animation's time here
            private constant real SECasterAnimTime          = 0.5
            //insert the max height of the caster's jump here
            private constant real SECasterJumpHeight        = 400.
            //insert the rotation speed of the caster here
            private constant real SECasterAngSpeed          = 3600.
            //insert how long the second explosion will last.
            private constant real SETime                    = 3.
            //insert the max height the tossed unit will reach here
            private constant real SETossHeight              = 400.
            //Second Explosion Effect
            //insert how many rotating effect that will be created here
            private constant integer SEESum                 = 10
            //insert the height of the rotating effect here
            private constant real SEEHeight                 = 200.
            //insert the rotating effect distance to caster here
            private constant real SEEDistance               = 200.
            //insert the rotating effect rotating speed here
            private constant real SEEAngSpeed               = 360.
            //insert the interval between the appearance of each rotating effect here
            private constant real SEEAppearInterval         = 0.1
            //insert the interval between the disappearance of each rotating effect here
            private constant real SEEDisappearInterval      = 0.03
           
            //Sound Setup
            //sound that played on caster when second explosion occur
            private constant string SECasterSound           = "Abilities\\Weapons\\PhoenixMissile\\PhoenixAttack.wav"
            //the volume percentage of caster's second explosion sound
            private constant real SECasterSoundVolume       = 200.
            //the interval between the play of each sound
            private constant real SECasterSoundInterval     = 0.2
           
            //Effect Set-up
            //insert the 'pillar' from first explosion effect model here
            private constant string FEEModel                = "Abilities\\Spells\\Undead\\Darksummoning\\DarkSummonTarget.mdl"
            //set the red tinting color of 'pillar' here. It's between 0 to 255.
            private constant integer FEEModelRed            = 255
            //set the green tinting color of 'pillar' here. It's between 0 to 255.
            private constant integer FEEModelGreen          = 75
            //set the blue tinting color of 'pillar' here. It's between 0 to 255.
            private constant integer FEEModelBlue           = 200
            //insert the effect that will be created on caster when the first explosion occur.
            //this one destroyed instantly
            private constant string FECasterEffect          = ""
            //insert the effect that will be attached on caster when the first explosion occur.
            //this one stay until first explosion end
            private constant string FECasterAttachEffect    = ""
            //insert the effect that will be created on unit when it tossed by the first explosion.
            //this one destroyed instantly
            private constant string FETargetEffect          = ""
            //insert the effect that will be attached on unit when it tossed by the first explosion.
            //this one stay until the toss end
            private constant string FETargetAttachEffect    = ""
            //insert the rotating effect model here
            private constant string SEEModel                = "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl"
            //set the red tinting color of rotating effect here. It's between 0 to 255.
            private constant integer SEEModelRed            = 0
            //set the green tinting color of rotating effect here. It's between 0 to 255.
            private constant integer SEEModelGreen          = 255
            //set the blue tinting color of rotating effect here. It's between 0 to 255.
            private constant integer SEEModelBlue           = 0
            //set the rotating effect scale
            private constant real SEEModelScale             = 3.
            //insert the effect that will be created on caster when the second explosion occur.
            //this one destroyed instantly
            private constant string SECasterEffect          = "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl"
            //insert the effect that will be attached on caster when the second explosion occur.
            //this one stay until second explosion end
            private constant string SECasterAttachEffect    = "Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl"
            //insert the effect that will be created on unit when it tossed by the second explosion.
            //this one destroyed instantly
            private constant string SETargetEffect          = ""
            //insert the effect that will be attached on unit when it tossed by the second explosion.
            //this one stay until the toss end
            private constant string SETargetAttachEffect    = ""
           
            //set the timer's time out. the lower it is, the more precise the spell will get.
            //but, warcraft has it's limit for time out though. don't use value lower than 0.03
            //because it will lower the warcraft performance.
            //this one usually between 0.05 to 0.03. 0.03 is more common(and efficient too!)
            private constant real TimeOut                   = 0.03
           
            //this one will decide the first explosion attack type
            private constant attacktype FEATT               = ATTACK_TYPE_NORMAL
            //this one will decide the first explosion damage type
            private constant damagetype FEDGT               = DAMAGE_TYPE_NORMAL
            //this one will decide the first explosion weapon type
            private constant weapontype FEWPT               = WEAPON_TYPE_WHOKNOWS
            //this one will decide the second explosion attack type
            private constant attacktype SEATT               = ATTACK_TYPE_NORMAL
            //this one will decide the second explosion damage type
            private constant damagetype SEDGT               = DAMAGE_TYPE_NORMAL
            //this one will decide the second explosion weapon type
            private constant weapontype SEWPT               = WEAPON_TYPE_WHOKNOWS
           
            //////////////////////////////////////////////////////////////////////
            private boolexpr filter
            private unit temp
            //this line is variable for the spell's mechanism. don't change it.
            //it's for the sake of efficiency of the spell..
            private unit u2
            private group g = CreateGroup()
            private real array R
            //////////////////////////////////////////////////////////////////////
        endglobals
       
        //u can edit the condition the unit neded to be affected by the spell here
        private function CanTarget takes unit caster, unit target returns boolean
            return IsUnitEnemy(target, GetOwningPlayer(caster))/*
             */
    and not (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE))/*
             */
    and not (IsUnitType(target, UNIT_TYPE_DEAD))/*
             */
    and IsUnitType(target, UNIT_TYPE_GROUND)/*
             */
    and IsUnitVisible(target, GetOwningPlayer(caster))
        endfunction
        ///////////////////////////////////////////////////////////////////////////////////////
        //This is the end of the header                                                      //
        //don't edit anything below if u don't know it.                                      //
        ///////////////////////////////////////////////////////////////////////////////////////
       
        //tossed struct.
        private struct Tossed
            private unit u
            private real vx
            private real angle
            private real vy
            private real acc
            private effect sfx
           
            static group Affected = CreateGroup()
           
            private static Tossed array Index
            private static integer Total = 0
            private static timer Timer = CreateTimer()
           
            static method Change takes unit u1, real x, real y, real a, real ang, string sfxs, string sfxs2 returns nothing
                //change the velocity and the deccelerate of the unit. only called if the unit is tossed when it's already being tossed
                local Tossed dat
                local integer i = 0
                loop
                    exitwhen i >= Tossed.Total
                    set dat = Tossed.Index[i]
                    if dat.u == u1 then
                        set dat.u = u1
                        set dat.vx = x
                        set dat.vy = y
                        set dat.acc = a
                        set dat.angle = ang
                        call DestroyEffect(dat.sfx)
                        set dat.sfx = AddSpecialEffectTarget(sfxs,u1,TargetAttach)
                        call DestroyEffect(AddSpecialEffectTarget(sfxs2,u1,TargetAttach))
                    endif
                    set i = i + 1
                endloop
            endmethod
           
            static method Loop takes nothing returns nothing
                //the loop. long story short, this one just move the unit according to it's velocity.
                //also reduce the velocity by the decceleration.
                local Tossed dat
                local integer i = 0
                loop
                    exitwhen i >= Tossed.Total
                    set dat = Tossed.Index[i]
                    set dat.vy = dat.vy - (dat.acc*TimeOut)
                    set R[1] = GetUnitX(dat.u) + dat.vx*TimeOut*Cos(dat.angle*bj_DEGTORAD)
                    set R[2] = GetUnitY(dat.u) + dat.vx*TimeOut*Sin(dat.angle*bj_DEGTORAD)
                    set R[3] = GetUnitFlyHeight(dat.u) + (dat.vy*TimeOut)
                    call SetUnitX(dat.u,R[1])
                    call SetUnitY(dat.u,R[2])
                    call SetUnitFlyHeight(dat.u,R[3],0.)
                    if R[3] <= 0 then
                        call PauseUnit(dat.u,false)
                        call DestroyEffect(dat.sfx)
                        call SetUnitFlyHeight(dat.u,GetUnitDefaultFlyHeight(dat.u),0.)
                        call GroupRemoveUnit(Tossed.Affected,dat.u)
                        set dat.u = null
                        set dat.sfx = null
                        call dat.destroy()
                        set Tossed.Total = Tossed.Total - 1
                        set Tossed.Index[i] = Tossed.Index[Tossed.Total]
                        set i = i - 1
                    endif
                    set i = i + 1
                endloop
                if Tossed.Total == 0 then
                    call PauseTimer(Tossed.Timer)
                endif
            endmethod
           
            static method Create takes unit u1, real x, real y, real a, real ang, string sfxs, string sfxs2 returns nothing
                //index the unit and save the velocity and decceleration
                local Tossed dat = Tossed.allocate()
                set dat.u = u1
                call UnitAddAbility(u1,'Arav')
                call UnitRemoveAbility(u1,'Arav')
                set dat.vx = x
                set dat.vy = y
                set dat.acc = a
                set dat.angle = ang
                set dat.sfx = AddSpecialEffectTarget(sfxs,u1,TargetAttach)
                call PauseUnit(dat.u,true)
                call DestroyEffect(AddSpecialEffectTarget(sfxs2,u1,TargetAttach))
                call GroupAddUnit(Tossed.Affected,u1)
                if Tossed.Total == 0 then
                    call TimerStart(Tossed.Timer,TimeOut,true,function Tossed.Loop)
                endif
                set Tossed.Index[Tossed.Total] = dat
                set Tossed.Total = Tossed.Total + 1
            endmethod
        endstruct
       
        //the 'pillar' struct
        private struct FEEffect
            private group sfxg
            private real Time
            private integer ActId
           
            private static FEEffect array Index
            private static integer Total = 0
            private static timer Timer = CreateTimer()
           
            static method Loop takes nothing returns nothing
                //basically doing 1 of 3 stuff.
                //1. moving the effect to it's place in 'pillar'
                //2. stand still, doing nothing
                //3. make pillar dsappear by scale the effect down, then kill it
                local FEEffect dat
                local integer i = 0
                loop
                    exitwhen i >= FEEffect.Total
                    set dat = FEEffect.Index[i]
                    set dat.Time = dat.Time-TimeOut
                    if dat.ActId == 1 then
                        call GroupAddGroup(dat.sfxg,g)
                        loop
                            set u2 = FirstOfGroup(g)
                            exitwhen u2 == null
                            set R[1] = (FEEHeight/FEESum)*GetUnitUserData(u2)
                            set R[2] = R[1]*((FEEAppearTime-dat.Time)/FEEAppearTime)
                            call SetUnitFlyHeight(u2,R[2],0)
                            call GroupRemoveUnit(g,u2)
                        endloop
                        if dat.Time <= 0 then
                            set dat.Time = FEEStandTime
                            set dat.ActId = 2
                        endif
                    elseif dat.ActId == 2 then
                        if dat.Time <= 0 then
                            set dat.Time = FEEDisappearTime
                            set dat.ActId = 3
                        endif
                    elseif dat.ActId == 3 then
                        if dat.Time <= 0 then
                            loop
                                set u2 = FirstOfGroup(dat.sfxg)
                                exitwhen u2 == null
                                call UnitApplyTimedLife(u2,'BTLF',TimeOut)
                                call GroupRemoveUnit(dat.sfxg,u2)
                            endloop
                            call DestroyGroup(dat.sfxg)
                            set dat.sfxg = null
                            call dat.destroy()
                            set FEEffect.Total = FEEffect.Total - 1
                            set FEEffect.Index[i] = FEEffect.Index[FEEffect.Total]
                            set i = i -1
                        else
                            set R[1] = (dat.Time/FEEDisappearTime)
                            call GroupAddGroup(dat.sfxg,g)
                            loop
                                set u2 = FirstOfGroup(g)
                                exitwhen u2 == null
                                call SetUnitScale(u2,R[1],R[1],R[1])
                                call GroupRemoveUnit(g,u2)
                            endloop
                        endif
                    endif
                    set i = i + 1
                endloop
                if FEEffect.Total == 0 then
                    call PauseTimer(FEEffect.Timer)
                endif  
            endmethod
                   
            static method Create takes real x, real y, player p returns nothing
                //initiate and create the effect
                local FEEffect dat = FEEffect.allocate()
                local integer i = 0
                local unit u
                set dat.sfxg = CreateGroup()
                set dat.Time = FEEAppearTime
                set dat.ActId = 1
                loop
                    exitwhen i > FEESum
                    set u = CreateUnit(p,DummyID,x,y,0.)
                    call AddSpecialEffectTarget(FEEModel,u,DummyAttach)
                    call GroupAddUnit(dat.sfxg,u)
                    call SetUnitUserData(u,i)
                    call SetUnitVertexColor(u,FEEModelRed,FEEModelGreen,FEEModelBlue,255)
                    set i = i + 1    
                endloop
                if FEEffect.Total == 0 then
                    call TimerStart(FEEffect.Timer,TimeOut,true,function FEEffect.Loop)
                endif
                set FEEffect.Index[FEEffect.Total] = dat
                set FEEffect.Total = FEEffect.Total + 1
            endmethod
        endstruct
       
        //the main struct
        private struct Main
            private unit Caster
            private real x
            private real y
            private real angle
            private integer ActId
            private real Area
            private real Time
            private real Time2
            private real Time3
            private real Time4
            private real v
            private real acc
            private integer num
            private integer num2
            private integer level
            private group sfxg
            private effect sfx
            private group affected
           
            private static Main array Index
            private static integer Total = 0
            private static timer Timer = CreateTimer()
           
            static method CanTargeted takes nothing returns boolean
                //for filter purpose
                return CanTarget(temp,GetFilterUnit())
            endmethod
           
            static method Loop takes nothing returns nothing
                //this basically doing 2 stuff.
                //1. doing the first explosion. explained below
                //2. doing the second explosion. explained below
                //also check if the caster dies. if yes, end the spell immediately
                local Main dat
                local integer i = 0
                local integer l
                local sound snd
                loop
                    exitwhen i >= Main.Total
                    set dat = Main.Index[i]
                    set dat.Time = dat.Time-TimeOut
                    set dat.Time2 = dat.Time2-TimeOut
                    set dat.Time3 = dat.Time3-TimeOut
                    call SetUnitFlyHeight(dat.Caster,GetUnitFlyHeight(dat.Caster)+(dat.v*TimeOut),0.)
                    set dat.v = dat.v-(dat.acc*TimeOut)
                    if  IsUnitType(dat.Caster,UNIT_TYPE_DEAD) then
                        call PauseUnit(dat.Caster,false)
                        call SetUnitFlyHeight(dat.Caster,GetUnitDefaultFlyHeight(dat.Caster),0)
                        call DestroyEffect(dat.sfx)
                        loop
                            set u2 = FirstOfGroup(dat.sfxg)
                            exitwhen u2 == null
                            call UnitApplyTimedLife(u2,'BTLF',TimeOut)
                            call GroupRemoveUnit(dat.sfxg,u2)
                        endloop
                        call DestroyGroup(dat.sfxg)
                        call DestroyGroup(dat.affected)
                        set dat.Caster = null
                        set dat.sfx = null
                        set dat.sfxg = null
                        set dat.affected = null
                        call dat.destroy()
                        set Main.Total = Main.Total - 1
                        set Main.Index[i] = Main.Index[Main.Total]
                        set i = i - 1
                    elseif dat.ActId == 1 then
                        //first explosion.
                        //basically just create each 'pillar' circle by circle on each interval.
                        //it also toss unit and add it to group so it didn't tossed again
                        if (dat.Time2 <= 0) and (dat.num<=dat.num2) then
                            set dat.Time2 = FEEInterval
                            set l = FEELineSum+(FEELineSumIncr*dat.level)
                            set R[1] = 360/I2R(l)
                            set R[2] = (dat.Area/I2R(dat.num2))*I2R(dat.num)
                            loop
                                exitwhen l <= 0
                                set R[3] = dat.angle+(R[1]*I2R(l))
                                if R[3] > 360 then
                                    set R[3] = R[3] - 360
                                endif
                                call FEEffect.Create(dat.x+(R[2]*Cos(R[3]*bj_DEGTORAD)),dat.y+(R[2]*Sin(R[3]*bj_DEGTORAD)),GetOwningPlayer(dat.Caster))
                                set l = l - 1
                            endloop
                            set dat.num = dat.num+1
                        endif
                        if dat.Time3 <= 0 then
                            call SetUnitAnimation(dat.Caster,FECasterAnim)
                            set dat.Time3 = FECasterAnimTime
                        endif
                        call GroupAddGroup(dat.affected,g)
                        loop
                            set u2 = FirstOfGroup(g)
                            exitwhen u2 == null
                            if not (CanTarget(dat.Caster,u2)) then
                                call GroupRemoveUnit(dat.affected,u2)
                            endif
                            call GroupRemoveUnit(g,u2)
                        endloop
                        set temp = dat.Caster
                        set filter = Filter(function Main.CanTargeted)
                        call GroupEnumUnitsInRange(g,dat.x,dat.y,dat.Area,filter)
                        loop
                            set u2 = FirstOfGroup(g)
                            exitwhen u2 == null
                            if not IsUnitInGroup(u2,dat.affected) then
                                set R[4] = (2*FETossHeight*dat.Time)/(FETossHeight+SquareRoot(FETossHeight*FETossHeight*(1-FETossHeightRatio)))
                                set R[1] = (4*FETossHeight)/(R[4])
                                set R[3] = (8*FETossHeight)/(R[4]*R[4])
                                call GroupAddUnit(dat.affected,u2)    
                                set R[0] = FEDamage+(FEDamageIncr*I2R(dat.level))
                                call UnitDamageTarget(dat.Caster,u2,R[0],true,false,FEATT,FEDGT,FEWPT)
                                if IsUnitInGroup(u2,Tossed.Affected) then
                                    call Tossed.Change(u2,0,R[1],R[3],0.,FETargetAttachEffect,FETargetEffect)
                                else                                  
                                    call Tossed.Create(u2,0,R[1],R[3],0.,FETargetAttachEffect,FETargetEffect)
                                endif
                            endif  
                            call GroupRemoveUnit(g,u2)
                        endloop
                        if dat.Time <= 0 then
                            //change of phase.
                            //re-initiate the variable, effect, and the group
                            set dat.angle = GetRandomReal(0.,360.)
                            set dat.ActId = 2
                            set dat.Time = SETime
                            set dat.Time2 = SEEAppearInterval
                            set dat.Time3 = SECasterAnimTime
                            set dat.Time4 = SECasterSoundInterval
                            set snd = CreateSound(SECasterSound, false, true, true, 10, 10, "SpellsEAX")
                            call SetSoundDuration(snd, GetSoundFileDuration(SECasterSound))
                            call AttachSoundToUnit(snd, dat.Caster)
                            call SetSoundVolume(snd, R2I(SECasterSoundVolume*127.*0.01))
                            call StartSound(snd)
                            call KillSoundWhenDone(snd)
                            set dat.v = (4*SECasterJumpHeight)/dat.Time
                            set dat.acc = (8*SECasterJumpHeight)/(dat.Time*dat.Time)
                            set dat.num = 1
                            set dat.num2 = SEESum
                            call DestroyEffect(dat.sfx)
                            set dat.sfx = AddSpecialEffectTarget(SECasterAttachEffect,dat.Caster,CasterAttach)
                            call DestroyEffect(AddSpecialEffectTarget(SECasterEffect,dat.Caster,CasterAttach))
                            call SetUnitAnimation(dat.Caster,SECasterAnim)
                            call GroupClear(dat.affected)
                            set temp = dat.Caster
                            set filter = Filter(function Main.CanTargeted)
                            call GroupEnumUnitsInRange(g,dat.x,dat.y,dat.Area,filter)
                            loop
                                set u2 = FirstOfGroup(g)
                                exitwhen u2 == null
                                set R[5] = (2*SETossHeight*dat.Time)/(SETossHeight+SquareRoot(SETossHeight*(SETossHeight-GetUnitFlyHeight(u2))))
                                set R[1] = (4*SETossHeight)/(R[5])
                                set R[6] = GetUnitX(u2)-dat.x
                                set R[7] = GetUnitY(u2)-dat.y
                                set R[2] = (dat.Area-SquareRoot(R[6]*R[6]+R[7]*R[7]))/dat.Time
                                set R[3] = (8*FETossHeight)/(R[5]*R[5])
                                set R[4] = bj_RADTODEG*Atan2(GetUnitY(u2)-dat.y,GetUnitX(u2)-dat.x)
                                call GroupAddUnit(dat.affected,u2)
                                set R[0] = SEDamage+(SEDamageIncr*I2R(dat.level))
                                call UnitDamageTarget(dat.Caster,u2,R[0],true,false,SEATT,SEDGT,SEWPT)
                                if IsUnitInGroup(u2,Tossed.Affected) then
                                    call Tossed.Change(u2,R[2],R[1],R[3],R[4],SETargetAttachEffect,SETargetEffect)
                                else
                                    call Tossed.Create(u2,R[2],R[1],R[3],R[4],SETargetAttachEffect,SETargetEffect)
                                endif
                                call GroupRemoveUnit(g,u2)
                            endloop
                            set temp = null
                            call DestroyBoolExpr(filter)
                        endif
                    elseif dat.ActId == 2 then
                        //the second explosion
                        //basically just create each rotating effect one by one, then rotating it individually
                        //also rotate the caster
                        set dat.Time4 = dat.Time4-TimeOut
                        set dat.angle = dat.angle+(SEEAngSpeed*TimeOut)
                        call SetUnitFacing(dat.Caster,GetUnitFacing(dat.Caster)+(SECasterAngSpeed*TimeOut))
                        call GroupAddGroup(dat.sfxg,g)
                        loop
                            set u2 = FirstOfGroup(g)
                            exitwhen u2 == null
                            set R[1] = GetUnitFacing(u2)+(SEEAngSpeed*TimeOut)
                            call SetUnitX(u2,dat.x+(SEEDistance*Cos(R[1]*bj_DEGTORAD)))
                            call SetUnitY(u2,dat.y+(SEEDistance*Sin(R[1]*bj_DEGTORAD)))
                            call SetUnitFacing(u2,R[1])
                            call GroupRemoveUnit(g,u2)
                        endloop
                        if (dat.Time2 <= 0) and (dat.num<=dat.num2) then
                            set dat.Time2 = SEEAppearInterval
                            set u2 = CreateUnit(GetOwningPlayer(dat.Caster),DummyID,dat.x+(SEEDistance*Cos(dat.angle*bj_DEGTORAD)),dat.y+(SEEDistance*Sin(dat.angle*bj_DEGTORAD)),dat.angle)
                            call AddSpecialEffectTarget(SEEModel,u2,DummyAttach)
                            call SetUnitScale(u2,SEEModelScale,SEEModelScale,SEEModelScale)
                            call SetUnitFlyHeight(u2,(SEEHeight/I2R(dat.num2))*dat.num,0.)
                            call SetUnitFacing(u2,dat.angle)
                            call SetUnitVertexColor(u2,SEEModelRed,SEEModelGreen,SEEModelBlue,255)
                            set R[1] = ((dat.Time+(dat.Time2*dat.num))*0.5)+(dat.Time2*(dat.num-1))
                            call UnitApplyTimedLife(u2,'BTLF',R[1])    
                            call GroupAddUnit(dat.sfxg,u2)
                            set dat.angle = dat.angle - (360/I2R(dat.num2))
                            set dat.num = dat.num+1
                        endif
                        if dat.Time3 <= 0 then
                            call SetUnitAnimation(dat.Caster,SECasterAnim)
                            set dat.Time3 = SECasterAnimTime
                        endif
                        if dat.Time4 <= 0 then
                            set snd = CreateSound(SECasterSound, false, true, true, 10, 10, "SpellsEAX")
                            call SetSoundDuration(snd, GetSoundFileDuration(SECasterSound))
                            call AttachSoundToUnit(snd, dat.Caster)
                            call SetSoundVolume(snd, R2I(SECasterSoundVolume*127.*0.01))
                            call StartSound(snd)
                            call KillSoundWhenDone(snd)
                            set dat.Time4 = SECasterSoundInterval
                        endif
                        call GroupAddGroup(dat.affected,g)
                        loop
                            set u2 = FirstOfGroup(g)
                            exitwhen u2 == null
                            if not (CanTarget(dat.Caster,u2)) then
                                call GroupRemoveUnit(dat.affected,u2)
                            endif
                            call GroupRemoveUnit(g,u2)
                        endloop
                        set temp = dat.Caster
                        set filter = Filter(function Main.CanTargeted)
                        call GroupEnumUnitsInRange(g,dat.x,dat.y,dat.Area,filter)
                        loop
                            set u2 = FirstOfGroup(g)
                            exitwhen u2 == null
                            if not IsUnitInGroup(u2,dat.affected) then
                                set R[5] = (2*SETossHeight*dat.Time)/(SETossHeight+SquareRoot(SETossHeight*(SETossHeight-GetUnitFlyHeight(u2))))
                                set R[1] = (4*SETossHeight)/(R[5])
                                set R[6] = GetUnitX(u2)-dat.x
                                set R[7] = GetUnitY(u2)-dat.y
                                set R[2] = (dat.Area-SquareRoot(R[6]*R[6]+R[7]*R[7]))/dat.Time
                                set R[3] = (8*FETossHeight)/(R[5]*R[5])
                                set R[4] = bj_RADTODEG*Atan2(GetUnitY(u2)-dat.y,GetUnitX(u2)-dat.x)
                                call GroupAddUnit(dat.affected,u2)    
                                set R[0] = SEDamage+(SEDamageIncr*I2R(dat.level))
                                call UnitDamageTarget(dat.Caster,u2,R[0],true,false,SEATT,SEDGT,SEWPT)
                                if IsUnitInGroup(u2,Tossed.Affected) then
                                    call Tossed.Change(u2,R[2],R[1],R[3],R[4],SETargetAttachEffect,SETargetEffect)
                                else
                                    call Tossed.Create(u2,R[2],R[1],R[3],R[4],SETargetAttachEffect,SETargetEffect)
                                endif
                            endif  
                            call GroupRemoveUnit(g,u2)
                        endloop
                        if dat.Time <= 0 then
                            //finish the spell. clearing te index
                            call PauseUnit(dat.Caster,false)
                            call SetUnitFlyHeight(dat.Caster,GetUnitDefaultFlyHeight(dat.Caster),0)
                            call DestroyEffect(dat.sfx)
                            loop
                                set u2 = FirstOfGroup(dat.sfxg)
                                exitwhen u2 == null
                                call UnitApplyTimedLife(u2,'BTLF',TimeOut)
                                call GroupRemoveUnit(dat.sfxg,u2)
                            endloop
                            call DestroyGroup(dat.sfxg)
                            call DestroyGroup(dat.affected)
                            set dat.Caster = null
                            set dat.sfx = null
                            set dat.sfxg = null
                            set dat.affected = null
                            call dat.destroy()
                            set Main.Total = Main.Total - 1
                            set Main.Index[i] = Main.Index[Main.Total]
                            set i = i - 1
                        endif
                    endif
                    set i = i +1
                endloop
                if Main.Total == 0 then
                    call PauseTimer(Main.Timer)
                endif
                set snd = null
            endmethod
           
            static method Create takes nothing returns nothing
                //the creating of the spell.
                //create one pillar in the place of caster.
                //initiate all variable, create the efect, etc.
                local Main dat = Main.allocate()
                local unit u = GetTriggerUnit()
                call PauseUnit(u,true)
                set dat.Caster = u
                call PauseUnit(dat.Caster,true)
                call UnitAddAbility(u,'Arav')
                call UnitRemoveAbility(u,'Arav')
                set dat.x = GetUnitX(u)
                set dat.y = GetUnitY(u)
                set dat.angle = GetRandomReal(0.,360.)
                call FEEffect.Create(dat.x,dat.y,GetOwningPlayer(u))
                set dat.ActId = 1
                set dat.level = GetUnitAbilityLevel(u,SpellID) - 1
                set dat.Area = AoE+(AoEIncr*I2R(dat.level))
                set dat.Time = FETime+(FETimeIncr*I2R(dat.level))
                set dat.Time2 = FEEInterval
                set dat.Time3 = FECasterAnimTime
                set dat.v = (4*FECasterJumpHeight)/dat.Time
                set dat.acc = (8*FECasterJumpHeight)/(dat.Time*dat.Time)
                set dat.num = 1
                set dat.num2 = FEECircleSum+(FEECircleSumIncr*dat.level)
                set dat.sfxg = CreateGroup()
                set dat.sfx = AddSpecialEffectTarget(FECasterAttachEffect,u,CasterAttach)
                call DestroyEffect(AddSpecialEffectTarget(FECasterEffect,u,CasterAttach))
                call SetUnitAnimation(u,FECasterAnim)
                set dat.affected = CreateGroup()
                set temp = u
                set filter = Filter(function Main.CanTargeted)
                call GroupEnumUnitsInRange(g,dat.x,dat.y,dat.Area,filter)
                loop
                    set u2 = FirstOfGroup(g)
                    exitwhen u2 == null
                    set R[4] = (2*FETossHeight*dat.Time)/(FETossHeight+SquareRoot(FETossHeight*FETossHeight*(1-FETossHeightRatio)))
                    set R[1] = (4*FETossHeight)/(R[4])
                    set R[3] = (8*FETossHeight)/(R[4]*R[4])
                    call GroupAddUnit(dat.affected,u2)
                    set R[0] = FEDamage+(FEDamageIncr*I2R(dat.level))
                    call UnitDamageTarget(dat.Caster,u2,R[0],true,false,FEATT,FEDGT,FEWPT)
                    if IsUnitInGroup(u2,Tossed.Affected) then
                        call Tossed.Change(u2,0,R[1],R[3],0.,FETargetAttachEffect,FETargetEffect)
                    else
                        call Tossed.Create(u2,0,R[1],R[3],0.,FETargetAttachEffect,FETargetEffect)
                    endif
                    call GroupRemoveUnit(g,u2)
                endloop
                set temp = null
                call DestroyBoolExpr(filter)
                if Main.Total == 0 then
                    call TimerStart(Main.Timer,TimeOut,true,function Main.Loop)
                endif
                set Main.Index[Main.Total] = dat
                set Main.Total = Main.Total+1
                set u = null
            endmethod  
        endstruct
       
        private function Conditions takes nothing returns boolean
            if GetSpellAbilityId() == SpellID then
                call Main.Create()
            endif
            return false
        endfunction
       
        private function InitTrig_Initialize takes nothing returns nothing
            //create the trigger
            local trigger t = CreateTrigger()
            //add event
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            //add 'condition'
            call TriggerAddCondition(t, Condition(function Conditions))
            //preload dummy unit
            call RemoveUnit(CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),DummyID,0,0,0))
            //preload the spell's effect
            call Preload(SECasterSound)
            call Preload(FEEModel)
            call Preload(FECasterEffect)
            call Preload(FECasterAttachEffect)
            call Preload(FETargetEffect)  
            call Preload(FETargetAttachEffect)
            call Preload(SEEModel)
            call Preload(SECasterEffect)  
            call Preload(SECasterAttachEffect)
            call Preload(SETargetEffect)  
            call Preload(SETargetAttachEffect)
        endfunction
    endscope

    changelog
    v1.0
    Submit the spell

    v1.1
    Improve Caster Animation
    Add Additional Sound
    Other small stuff that I forgot
     

    Attached Files:

    Last edited: Jun 18, 2011
  11. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,047
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Contest is over, I will be reviewing submissions now.
     
  12. indomitable1319

    indomitable1319

    Joined:
    Jan 22, 2010
    Messages:
    2,278
    Resources:
    0
    Resources:
    0
    Alright! Time to lose!
     
  13. Deolrin

    Deolrin

    Joined:
    Apr 18, 2008
    Messages:
    7,219
    Resources:
    57
    Models:
    48
    Icons:
    6
    Packs:
    2
    Tutorials:
    1
    Resources:
    57
    I know I'm not participating, but may I please ask... Can someone still submit an entry, even if it's a few hours late?
    Because last time I saw TRD in chat, he said that all the spell lacks is a tooltip, and then disconnected. That was yesterday. I haven't seen him since then. I assume that he's done with the spell, and he simply didn't have the chance to submit it.
     
  14. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,047
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    I was going to PM TRD about that because I haven't been able to find his map. As long as the "last-saved" timestamp on the file is no later than 0800GMT it should be fine for him.
     
  15. Deolrin

    Deolrin

    Joined:
    Apr 18, 2008
    Messages:
    7,219
    Resources:
    57
    Models:
    48
    Icons:
    6
    Packs:
    2
    Tutorials:
    1
    Resources:
    57
    Pretty strict, eh... D:
    In the modeling contests they allow entries like 3 days after the deadline if all the contestants are fine with that. xP
     
  16. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,047
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    What is strict about it? There's a deadline to have the entry in by. I'm also not a robot, despite popular opinion. I do have a sense of flexibility. 3 days is a bit long for me though. I've already reviewed 16/19 of the submissions and that's not counting TRD's meteor spell. Why delay the results?
     
  17. Vengeancekael

    Vengeancekael

    Joined:
    Aug 11, 2009
    Messages:
    5,746
    Resources:
    16
    Tools:
    1
    Maps:
    13
    Spells:
    1
    StarCraft II Resources:
    1
    Resources:
    16
    Woho that was fast lol, 16 already.
     
  18. Adiktuz

    Adiktuz

    Joined:
    Oct 16, 2008
    Messages:
    9,674
    Resources:
    23
    Models:
    2
    Packs:
    1
    Maps:
    1
    Spells:
    16
    Tutorials:
    1
    JASS:
    2
    Resources:
    23
    wow, super fast...
     
  19. Mage_Goo

    Mage_Goo

    Joined:
    Jun 1, 2008
    Messages:
    366
    Resources:
    2
    Spells:
    2
    Resources:
    2
    wow, that's really fast. if TRD give the spell, the result will announced immediately? Awesome.

    grr... just realized that one of my parabolic formula is a bit wrong. hope it won't reduce my point too much...
     
  20. Deolrin

    Deolrin

    Joined:
    Apr 18, 2008
    Messages:
    7,219
    Resources:
    57
    Models:
    48
    Icons:
    6
    Packs:
    2
    Tutorials:
    1
    Resources:
    57
    Wait a sec. No poll? :S