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 poll for Hive's 12th Concept Art Contest is up! Go cast your vote for your favourite genie!
    Dismiss Notice
  4. Travel to distant realms and encounter scenes unknown to the common folk. The Greatest of Adventures is upon us with the 8th Cinematic Contest. Join in on a fun ride.
    Dismiss Notice
  5. The 18th Icon Contest is ON! Choose any ingame unit and give him/her Hero abilities. Good luck to all.
    Dismiss Notice
  6. Contestants are to create a scene set in the Stone Age. Come and see what you can come up with. We wish you the best of luck!
    Dismiss Notice
  7. Colour outside the lines! Techtree Contest #13 is a go. The contest is optionally paired.
    Dismiss Notice
  8. Greetings cerebrates, our Swarm needs new spawners that will have numerous children. Join the HIVE's 31st Modeling Contest - Spawners and Spawned! The contest is optionally paired.
    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 #19

Discussion in 'Triggers & Scripts' started by Bribe, Mar 19, 2011.

Thread Status:
Not open for further replies.
  1. NBalfa

    NBalfa

    Joined:
    Aug 20, 2010
    Messages:
    70
    Resources:
    0
    Resources:
    0
    My funny spell is going to be submitted soon I just need to fix some minor stuff.
     
  2. Mage_Goo

    Mage_Goo

    Joined:
    Jun 1, 2008
    Messages:
    366
    Resources:
    2
    Spells:
    2
    Resources:
    2
    well, I've tested most spell submitted and made my review here just to fill my free time. note that I hardly look at the code of your spell, just testing it
    review
    Loljuvination
    well... simple effect but fit the theme nicely... i like the backfire thing. u can cast it to enemy and then see them recover many hp, but took the rain of chaos and turned to hex all the time... the critter is also nice. all the more reason to cast it on enemy unit. too bad most of critter will die when the infernal come down and more will die because of it's permanent immolation. and.. if u cast the loljuvination on unit that already have that buff, nothing eally happened at all... the loljuvination still there and doing the same stuff as before. the regeneration rate doesn't seem to increase (oe is it just because it's too fast?), the number random thing spawned aren't doubled... never check the duration though. maybe u should make it stack-able?

    Daaaaaaamn
    oh well, a bit overpowered spell. I never see an ogre stand alive after affected with this spell. but that can be adjusted easily though. the stun is just... OP. u stun the target for 0.1 s every 0.2 s? wow... it's almost the same as stunned 'till the spell end. btw, u can set the 'Corpse' skill max dmg to 0 to completely remove the max total dmg. and.. if u cast it to ogre u put there, and the ogre survive the spell, the ogre will get smaller than before. That's because the ogre default size is not 100% i think? and.. imported model other than dummy model is prohibited. U must remove that blood cloud model and change it to other not-imported-model...

    Suicide Squad
    wow... that's a lot of library u use here... nice spell though. But the Sapper a bit stupid when chasing their target, sometimes, they just go to a place where the target was there few second before... and did the sapper pick random unit for the target? i think it's better for sapper to target the nearest enemy than just random. And.. if the sapper is idle, why don't u make it to wander randomly? better than just standing around

    Happiness Overload
    nice spell. I like the flower explosion u make here. Nice selection of projectile.
    there's something 'bout this spell that bug me though.
    1. the effect to target unit is permanent... maybe either remove it when caster stop channeling or add a duration to it or make the effect faded over time
    2. if u have 2 or more unit that channel this spell to one unit but not started at the same time, the unit size will change in a weird way. maybe just make it stack? so if 2 or more unit are channeling to same unit, the swelling speed will increase
    3. the explosion affect ally too. also, i think the radius and the damage of explosion should be swapped. The radius of explosion is too far and the damage done is too small.
    4. about the getflowerid library... why don't u just use array for it? so u can get rid all that if block.

    Super Frost Joke
    well, simple effect... btw, if the frost affect a magic immune unit, the frost won't show up, and the unit won't frosted at all, but the damage will done to that unit, which is weird...and sometimes, even when the frost shown, the joke isn't shown.

    Miracle Shot
    is the name a joke too? maybe Ball of Failure more fit as the name. I really can't see what make this spell called Miracle Shot, while it's more like bad shot... and well... simple spell, huh? but i somehow like how u put that anim for failing.

    Up You Go!
    oh well, relatively simple spell... i like how u apply the joke though but The effect are so-so IMO.

    Chicken burst
    good spell. well, i think the parabola formula is doing most of the job, but it still good. i like the projectile movement. 'bout the chicken, maybe u should make it instant decay, or just make the decay time faster, because the corpse stayed for too long and it's a bit strange to see the corpse still in one piece after it has been exploded though.

    Lame Joke
    nice and simple spell. I like how u put that sound. It fit the spell perfectly. Never know there's sound like that in editor. well, i can't find any flaw on this spell. i think it fit the standard.

    Contagious Cold
    Nice spell. My favorite so far. but, after many sneeze, somehow the spell won't work to some unit. And the sneeze area of effect a bit buggy too. Sometimes a unit right in front of the sneezing unit is affected, and sometimes not. The Blood mage on left part of map can't seem to use contagious cold. If used, nothing will happen. that also happen to many unit after a 'sneeze frenzy' (when there's many unit infected with cold sneezing to each other...)

    Bedlam and/or moonwalk spell
    Bedlam is... nice. even though it's not too useful vs creep, it can really mess up with the player. it is really useless though if the target don't have any allies near it and the effect are too... simple.
    Moonwalk is.. interesting. i really like the effect u do here. the most eye-catchy spell so far IMO. but... if ur enemy coincidentally have a very slow projectile... it will rendered useless... this one activated when the unit is attacked, right? what will happen if the enemy's projectile reach the 'moonwalk-er' after the 'moonwalking' effect is done? it's still get damaged right?
    btw, if u want to check if unit is alive or not... i think use IsUnitType(<unit>,UNIT_TYPE_DEAD) is better than check the life. because.. in some case, corpse can have more than 0 hp...


    and... for the sake of testing... can't u all use a proper spell test map? if u just don't have the time, u can always choose one of this
    now, I'm hope that InfinateAnswers's Flaming Burrito, NFWar's Curse of evil bunny and NBalfa's funny spell will be a really good one.
     
  3. Garfield1337

    Garfield1337

    Joined:
    Jul 6, 2009
    Messages:
    1,806
    Resources:
    4
    Maps:
    1
    Spells:
    3
    Resources:
    4
    Mage Goo,
    Your spell gives me a compile error while trying to save before testing o_O
    And yes,i opened with JNGP.

    EDIT: Updated the spell again - it will no longer fly weird when there's tall terrain on egg's path.
    I'm yet to add a decent test map =[

    [Attachment removed]
     
    Last edited: Apr 1, 2011
  4. NFWar

    NFWar

    Joined:
    Jul 27, 2008
    Messages:
    1,314
    Resources:
    227
    Models:
    1
    Icons:
    215
    Packs:
    1
    Skins:
    2
    Spells:
    6
    Tutorials:
    2
    Resources:
    227
    I changed the spell idea, since it had too much functions... I go with simple idea: Bunny Run!
     
  5. Mage_Goo

    Mage_Goo

    Joined:
    Jun 1, 2008
    Messages:
    366
    Resources:
    2
    Spells:
    2
    Resources:
    2
    huh? Dunno what caused this, but it works fine for me.
    Can you show me the screen shot of that compile error? maybe i can do something with it


    anyway... spell updated....

    Contestant Name: Mage_Goo
    Entry Name: Honey Shower v1.15

    Tooltip
    Honey Shower
    [​IMG]
    Hero shower an area with honey. Honey will reduce the enemy's movement and attract bees to attack that unit, dealing minor damage. There's a chance that the honey will attract a bear, which deal high damage.

    Level 1 - Slow unit by 10%, attract 3 bees for each enemy unit, each dealing 2 damage. There's 20% chance to summon bear, which deal 100 damage. Last 5 second.
    Level 2 - Slow unit by 15%, attract 4 bees for each enemy unit, each dealing 3 damage. There's 30% chance to summon bear, which deal 150 damage. Last 7.5 second.
    Level 3 - Slow unit by 20%, attract 5 bees for each enemy unit, each dealing 4 damage. There's 40% chance to summon bear, which deal 200 damage. Last 10 second.
    Level 4 - Slow unit by 25%, attract 6 bees for each enemy unit, each dealing 5 damage. There's 50% chance to summon bear, which deal 250 damage. Last 12.5 second.
    Affect Area of 300.

    and the 800 lines of code... wow
    code
    Code (vJASS):
    scope HoneyShower initializer InitTrig_Initialize
        ///////////////////////////////////////////////////////////////////////////////////////
        //Welcome to the Header                                                              //
        //u can customize most part of the spell from here                                   //
        ///////////////////////////////////////////////////////////////////////////////////////
        globals
            //Insert the raw-code of your Honey Shower 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                        = 'n000'
            //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 enemy unit that get affected by this spell.
            //in this spell, the only effect attached to enemy is slow effect when enemy is in the area of spell.
            private constant string BuffAttach                      = "origin"
           
            //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: Bear's damage default value is 100 dmg and it's modifier value is 50 dmg.
            // so, on lvl 1, bear's 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 honey duration default value here.
            private constant real Duration                          = 5.
            //insert modifier of honey duration here.
            private constant real DurationIncr                      = 2.5
           
            //insert the number of bee summoned for each affected unit here. this will be the default value.
            private constant integer BeeSum                         = 3
            //insert modifier of number of bee summoned here.
            private constant integer BeeSumIncr                     = 1
            //insert the attack interval for a group of bee here. this will be the default value.
            private constant real BeeAtkInterval                    = 1.
            //insert modifier of a bee's roup attack interval here.
            private constant real BeeAtkIntervalIncr                = 0.
            //insert the attack speed of a single bee here. this will be the default value.
            private constant real BeeAtkSpeed                       = 2.
            //insert modifier of bee's attack speed here.
            private constant real BeeAtkSpeedIncr                   = -0.5
            //insert the distance between bee and it's target here. this will be the default value.
            private constant real BeeDist                           = 200.
            //insert modifier of distance between bee and it's target here.
            private constant real BeeDistIncr                       = 0.
            //insert the damage dealt by a single bee's attack here. this will be the default value.
            private constant real BeeDmg                            = 2.
            //insert modifier of bee's damage here.
            private constant real BeeDmgIncr                        = 1.
            //insert the chance for each bee's attack to summon a bear here.
            //this processed as percentage. this will be the default value.
            private constant real BearChance                        = 20.
            //insert modifier of chance to summon bear here.
            private constant real BearChanceIncr                    = 10.
            //insert the damage dealt by a single bear's attack here. this will be the default value.
            private constant real BearDmg                           = 100.
            //insert modifier of bear's damage here.
            private constant real BearDmgIncr                       = 50.
            //insert the distance between bear and it's target here.
            private constant real BearDist                          = 150.
           
            //insert the bee's movement speed here.
            private constant real BeeMoveSpeed                      = 300.
            //insert the bee's collision here. it's the distance the bee's needed to successfully attack a unit.
            private constant real BeeCollision                      = 150.
            //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                           = 0.
            //insert the amount of movement the honey will reduce from the affected unit here.
            //this value should be between 0 and 1, while 0 means no slow and 1 means fully slow.
            //multiply this by 100 and u get the percentage of slow.
            private constant real SlowAmount                        = 0.10
            //insert modifier of honey's slow amount here.
            private constant real SlowIncr                          = 0.05
           
            //insert the model's path of the model u want to use for the bee.
            private constant string BeeModel                        = "units\\undead\\Locust\\Locust.mdl"
            //insert the unit u want to be the bear here. any unit that use the model that u want to be bear works here.
            //remember to use un-needed unit here for safety or just create a custom unit here.
            private constant integer BearUnit                       = 'ngz4'
            //insert the animation u want the bear to play when dealing damage to it's target.
            private constant string BearAnim                        = "attack"
            //insert the time it's needed to finish that animation.
            private constant real BearAnimTime                      = 1.
            //insert the attachment point u want the effect attached to.
            private constant string BearAttach                      = "chest"
            //insert the effect u want to be created once when the spell is started.
            //the effect is created on center of the honey's area.
            private constant string HoneyStartEffect                = "Abilities\\Spells\\Other\\HealingSpray\\HealBottleMissile.mdl"
            //insert the area effect that shown in the central of honey's area.
            //this one last until the duration end.
            private constant string HoneyAreaEffect                 = ""
            //set the scale of the area effect. 1 is the normal size of the effect. this will be default value.
            private constant real HoneyAreaEffectScale              = 1.
            //insert the area effect's scale modifier.
            private constant real HoneyAreaEffectScaleIncr          = 0.
            //set the effect that will be created on random location in honey's area on each interval.
            private constant string HoneyAreaSecondaryEffect        = "Abilities\\Spells\\Undead\\ReplenishHealth\\ReplenishHealthCasterOverhead.mdl"
            //set the number of secondary effect u want to be created on each interval.
            private constant integer HoneyAreaSecondaryEffectSum    = 10
            //set the interval for the secondary efect to shown.
            private constant real HoneyAreaSecondaryEffectInterval  = 1.
            //set the effect attached to unit's affected by honey's slow.
            private constant string HoneyBuffEffect                 = "Abilities\\Spells\\Human\\slow\\slowtarget.mdl"
            //set the effect that appear once when the spell's duration end.
            private constant string HoneyEndEffect                  = "Abilities\\Spells\\Other\\Andt\\Andt.mdl"
            //set the effect created when the bee is summoned.
            private constant string BeeAppearEffect                 = "Abilities\\Weapons\\snapMissile\\snapMissile.mdl"
            //set the effect attached to bee. this one is optional.
            private constant string BeeAttachEffect                 = ""
            //set the effect that created on enemy unit when they area damaged by the bee.
            private constant string BeeDmgEffect                    = "Abilities\\Weapons\\PoisonArrow\\PoisonArrowMissile.mdl"
            //set the effect that created when the bee disappear.
            private constant string BeeDisappearEffect              = "units\\undead\\Locust\\Locust.mdl"
            //set the effect when the bear is successfully summoned.
            private constant string BearAppearEffect                = "Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl"
            //set the effect when the bear successfully damage the enemy.
            private constant string BearDmgEffect                   = "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
            //set the effect that will be attached to the bear. this one is optional.
            private constant string BearAttachEffect                = ""
            //set the effect that created when the bear dsappear
            private constant string BearDisappearEffect             = "Abilities\\Spells\\Orc\\FeralSpirit\\feralspiritdone.mdl"
           
            //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 bee's attack type
            private constant attacktype BeeATT                      = ATTACK_TYPE_NORMAL
            //this one will decide the bee's damage type
            private constant damagetype BeeDGT                      = DAMAGE_TYPE_NORMAL
            //this one will decide the bee's weapon type
            private constant weapontype BeeWPT                      = WEAPON_TYPE_WHOKNOWS
            //this one will decide the bear's attack type
            private constant attacktype BearATT                     = ATTACK_TYPE_NORMAL
            //this one will decide the bear's damage type
            private constant damagetype BearDGT                     = DAMAGE_TYPE_NORMAL
            //this one will decide the bear's weapon type
            private constant weapontype BearWPT                     = WEAPON_TYPE_WHOKNOWS
           
            //////////////////////////////////////////////////////////////////////
            private boolexpr filter
            private unit temp
            private group g = CreateGroup()
            //this line is variable for the spell's mechanism. don't change it.
            //it's for the sake of efficiency of the spell..
            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 IsUnitVisible(target, GetOwningPlayer(caster))
        endfunction
        ///////////////////////////////////////////////////////////////////////////////////////
        //This is the end of the header                                                      //
        //don't edit anything below if u don't know it.                                      //
        //I'll try to explain it as best as i can though                                     //
        ///////////////////////////////////////////////////////////////////////////////////////
       
        //the bear's struct
        private struct Bear
            //well, initialize the struct
            private unit Caster
            private unit Target
            private unit bear
            private real Dmg
            private real Time
            private effect sfx
           
            private static Bear array Index
            private static integer Total = 0
            private static timer Timer = CreateTimer()
           
            static method Loop takes nothing returns nothing
                local Bear dat
                local integer i = 0
                //the usual looping every TimeOut set above.
                loop
                    exitwhen i >= Bear.Total
                    set dat = Bear.Index[i]
                    set dat.Time = dat.Time - TimeOut
                    //move the bear so it maintains the distance set above. note that this will move it's instantly
                    set R[0] = GetUnitFacing(dat.bear)-180.
                    if R[0] < 0 then
                        set R[0] = R[0] + 360.
                    endif
                    set R[1] = GetUnitX(dat.Target)+(BearDist*Cos(R[0]*bj_DEGTORAD))
                    set R[2] = GetUnitY(dat.Target)+(BearDist*Sin(R[0]*bj_DEGTORAD))
                    call SetUnitX(dat.bear,R[1])
                    call SetUnitY(dat.bear,R[2])
                    //check wether the bear animation has ended
                    if dat.Time <= 0 then
                        //if it's anim is end, do the stuff
                        //damage the target
                        call UnitDamageTarget(dat.Caster,dat.Target,dat.Dmg,true,false,BearATT,BearDGT,BearWPT)
                        //create bear's damage effect on target's location
                        call DestroyEffect(AddSpecialEffect(BearDmgEffect,GetUnitX(dat.Target),GetUnitY(dat.Target)))
                        //destroy bear's attached effect
                        call DestroyEffect(dat.sfx)
                        //create bear's disappear effect
                        call DestroyEffect(AddSpecialEffect(BearDisappearEffect,GetUnitX(dat.bear),GetUnitY(dat.bear)))
                        //remove the bear from game. why not just kill it? for safety.
                        //this because the bear can also be a normal unit, which leave corpse, or have ability that triggered when dies, or other annoying thing
                        call RemoveUnit(dat.bear)
                        //nulling the handle variable
                        set dat.Caster = null
                        set dat.Target = null
                        set dat.bear = null
                        set dat.sfx = null
                        //destroy the struct instance and rellocate it so it's ready for the next instance
                        call dat.destroy()
                        set Bear.Total = Bear.Total - 1
                        set Bear.Index[i] = Bear.Index[Bear.Total]
                        //decrease the loop counter, so the instance that fill this place will get in loop too
                        set i = i - 1
                    endif
                    //increase the loop counter
                    set i = i+1
                endloop
                if Bear.Total == 0 then
                //if there's no struct instance active anymore, it stop the timer
                    call PauseTimer(Bear.Timer)
                endif
            endmethod
           
            static method Create takes unit u, unit t, real dmg returns nothing
                //allocate the instance
                local Bear dat = Bear.allocate()
                //set the necessary variables
                set dat.Caster = u
                set dat.Target = t
                set dat.Dmg = dmg
                set dat.Time = BearAnimTime
                //create bear on random angle and have distance to target unit as set on the header
                set R[0] = GetRandomReal(0.,360.)
                set R[1] = GetUnitX(dat.Target)+(BearDist*Cos(R[0]*bj_DEGTORAD))
                set R[2] = GetUnitY(dat.Target)+(BearDist*Sin(R[0]*bj_DEGTORAD))
                set R[3] = R[0] - 180.
                if R[3] < 0. then
                    set R[3] = R[3]+360.
                endif
                set dat.bear = CreateUnit(GetOwningPlayer(u),BearUnit,R[1],R[2],R[3])
                //add the invulnerable and locust ability to prevent killing and selecting the bear.
                //that's t make the bear really an effect
                call UnitAddAbility(dat.bear,'Avul')
                call UnitAddAbility(dat.bear,'Aloc')
                //this one remove the bear ability to attack normally
                call UnitAddAbility(dat.bear,'Abun')
                //play the bear's desired animation
                call SetUnitAnimation(dat.bear,BearAnim)
                //create the bear's appear effect
                call DestroyEffect(AddSpecialEffect(BearAppearEffect,R[1],R[2]))
                //create the attach effect to bear
                set dat.sfx = AddSpecialEffectTarget(BearAttachEffect,dat.bear,BearAttach)
                if Bear.Total == 0 then
                //if there's no instance active before, active the timer
                    call TimerStart(Bear.Timer,TimeOut,true,function Bear.Loop)
                endif
                //allocate the instance to the right place
                set Bear.Index[Bear.Total] = dat
                set Bear.Total = Bear.Total + 1
            endmethod
        endstruct
       
        //Bee's Struct
        private struct Bee
        //struct's list of variable
            private unit bee
            private unit Caster
            private unit Target
            private real Dist
            private real angle
            private real Time
            private real time2
            private real Dmg
            private real Chance
            private integer level
            private integer Code
            private integer ActID
            private effect sfx
            private effect sfx2
           
            //array that save and share the interval of a group of bee attack
            static real array Interval
           
            private static Bee array Index
            private static integer Total = 0
            private static timer Timer = CreateTimer()
           
            static method Finish takes unit t, integer c returns nothing
                //method to destroy a group of bee by giving the code of which the bee attacking at.
                local integer i = 0
                local Bee dat
                //search the right bee
                loop
                    exitwhen i >= Bee.Total
                    set dat = Bee.Index[i]
                    //check if it's the right bee to end by check it's target and target's code
                    if (dat.Target == t) and (dat.Code == c) then
                        //destroy bee's model and bee's attached effect
                        call DestroyEffect(dat.sfx)
                        call DestroyEffect(dat.sfx2)
                        //create bee's disappear effect
                        call DestroyEffect(AddSpecialEffect(BeeDisappearEffect,GetUnitX(dat.bee),GetUnitY(dat.bee)))
                        //add timed life. it's more safer than instant kill
                        call UnitApplyTimedLife(dat.bee,'BTLF',TimeOut)
                        //nulling the handle
                        set dat.bee = null
                        set dat.Caster = null
                        set dat.Target = null
                        set dat.sfx = null
                        set dat.sfx2 = null
                        //destroy and relocate the instance
                        call dat.destroy()
                        set Bee.Total = Bee.Total - 1
                        set Bee.Index[i] = Bee.Index[Bee.Total]
                        set i = i - 1
                    endif
                    set i = i+1
                endloop
                if Bee.Total == 0 then
                    call PauseTimer(Bee.Timer)
                endif
            endmethod
           
            static method Change takes unit t, integer from, integer to returns nothing
                //method to change the unit code of a group of bee is attacking at.
                local integer i = 0
                local Bee dat
                //search the right group of bee
                loop
                    exitwhen i >= Bee.Total
                    set dat = Bee.Index[i]
                    //check if it's te right bee by check it's target and target's code
                    if (dat.Target == t) and (dat.Code == from) then
                        //change the target's code
                        set dat.Code = to
                        //move the shared interval of a group of bee
                        set Bee.Interval[to] = Bee.Interval[from]
                    endif
                    set i = i+1
                endloop
            endmethod
           
            static method Loop takes nothing returns nothing
                local integer i = 0
                local Bee dat
                //the usual looping
                loop
                    exitwhen i >= Bee.Total
                    set dat = Bee.Index[i]
                    //always move the angle bee is currently circling
                    set dat.angle = dat.angle+((BeeMoveSpeed*TimeOut/dat.Dist)*bj_RADTODEG)
                    if dat.angle <= 0 then
                        set dat.angle = dat.angle+360.
                    endif
                    if dat.ActID == 0 then
                        //bee's 'circling' part
                        if dat.time2 > 0 then
                        //reducing the tk speed counter if bee is not yet ready to attack
                            set dat.time2 = dat.time2-TimeOut
                        endif
                        //move te bee in the right position of circle
                        call SetUnitX(dat.bee,GetUnitX(dat.Target)+(dat.Dist*Cos(dat.angle*bj_DEGTORAD)))
                        call SetUnitY(dat.bee,GetUnitY(dat.Target)+(dat.Dist*Sin(dat.angle*bj_DEGTORAD)))
                        call SetUnitFacing(dat.bee,dat.angle+90.)
                        if (dat.time2 <= 0) and (Bee.Interval[dat.Code] <= 0) then
                        //if bee is ready to attack the interval of group is free, the bee will switch to attack
                            //switch the action ID to 'moving to attack'
                            set dat.ActID = 1
                            //reset the bee cooldown time
                            set dat.time2 = dat.Time
                            //reset the shared interval time
                            set Bee.Interval[dat.Code] = BeeAtkInterval+(BeeAtkIntervalIncr*I2R(dat.level))
                        endif
                    elseif dat.ActID == 1 then
                        //bee's 'moving to attack part'
                        //move bee to target according to it's speed.
                        set R[0] = Atan2(GetUnitY(dat.Target)-GetUnitY(dat.bee),GetUnitX(dat.Target)-GetUnitX(dat.bee))
                        set R[1] = GetUnitX(dat.bee)+(BeeMoveSpeed*TimeOut*Cos(R[0]))
                        set R[2] = GetUnitY(dat.bee)+(BeeMoveSpeed*TimeOut*Sin(R[0]))
                        call SetUnitX(dat.bee,R[1])    
                        call SetUnitY(dat.bee,R[2])
                        //check the distance between bee and the target
                        set R[3] = R[1] - GetUnitX(dat.Target)
                        set R[4] = R[2] - GetUnitY(dat.Target)
                        set R[5] = SquareRoot((R[3]*R[3])+(R[4]*R[4]))
                        if R[5] <= BeeCollision then
                            //if the distance is lower or equal to bee's collision,
                            //switch bee action ID to 'moving back to circling' part
                            set dat.ActID = 2
                            //damage the unit
                            call UnitDamageTarget(dat.Caster,dat.Target,dat.Dmg,true,false,BeeATT,BeeDGT,BeeWPT)
                            //create the bee damage effect
                            call DestroyEffect(AddSpecialEffect(BeeDmgEffect,GetUnitX(dat.Target),GetUnitY(dat.Target)))
                            if GetRandomReal(0.,100.) <= dat.Chance then
                            //check the chance to summon bear.
                            //if right, summon it with Bear.Create method
                                call Bear.Create(dat.Caster,dat.Target,BearDmg+(BearDmgIncr*I2R(dat.level)))
                            endif
                        endif
                    elseif dat.ActID == 2 then
                        //bee's 'moving back to circling'
                        //move bee to it's position in the circling according to it's speed
                        set R[6] = GetUnitX(dat.Target)+(dat.Dist*Cos(dat.angle*bj_DEGTORAD))
                        set R[7] = GetUnitY(dat.Target)+(dat.Dist*Sin(dat.angle*bj_DEGTORAD))
                        set R[0] = Atan2(R[7]-GetUnitY(dat.bee),R[6]-GetUnitX(dat.bee))
                        set R[1] = GetUnitX(dat.bee)+(BeeMoveSpeed*TimeOut*Cos(R[0]))
                        set R[2] = GetUnitY(dat.bee)+(BeeMoveSpeed*TimeOut*Sin(R[0]))
                        call SetUnitX(dat.bee,R[1])    
                        call SetUnitY(dat.bee,R[2])
                        //check the distance between bee and it's circling position
                        set R[3] = R[1] - R[6]
                        set R[4] = R[2] - R[7]
                        set R[5] = SquareRoot((R[3]*R[3])+(R[4]*R[4]))
                        if R[5] <= BeeCollision then
                        //if it's lower or equal to it's collision, make it circling again
                            //change action ID to 'circling' part
                            set dat.ActID = 0
                            //instantly move the bee to it's exact position in circling's circle
                            call SetUnitX(dat.bee,R[6])
                            call SetUnitY(dat.bee,R[7])
                            call SetUnitFacing(dat.bee,dat.angle+90.)
                        endif
                    endif
                    set i = i+1
                endloop
            endmethod
           
            static method Create takes unit c, unit u, integer i, integer lvl returns nothing
            //method to allocate the instance and set the necessary variable
                local Bee dat = Bee.allocate()
                //set the necessary variable
                set dat.Caster = c
                set dat.Target = u
                set dat.Code = i
                set dat.ActID = 0
                set dat.level = lvl
                set dat.Dist = BeeDist+(BeeDistIncr*I2R(dat.level))
                set dat.angle = GetRandomReal(0.,360.)
                set dat.Time = BeeAtkSpeed+(BeeAtkSpeedIncr*I2R(dat.level))
                set dat.time2 = dat.Time
                set dat.Dmg = BeeDmg+(BeeDmgIncr*I2R(dat.level))
                set dat.Chance = BearChance+(BearChanceIncr*I2R(dat.level))
                //create the bee
                set dat.bee = CreateUnit(GetOwningPlayer(dat.Caster),DummyID,GetUnitX(dat.Target)+(dat.Dist*Cos(dat.angle*bj_DEGTORAD)),GetUnitY(dat.Target)+(dat.Dist*Sin(dat.angle*bj_DEGTORAD)),dat.angle+90)
                //attach the bee model to it
                set dat.sfx = AddSpecialEffectTarget(BeeModel,dat.bee,DummyAttach)
                //attach the attach effect to it
                set dat.sfx2 = AddSpecialEffectTarget(BeeAttachEffect,dat.bee,DummyAttach)
                //create the appear effect
                call DestroyEffect(AddSpecialEffect(BeeAppearEffect,GetUnitX(dat.bee),GetUnitY(dat.bee)))
                if Bee.Total == 0 then
                //start the timer if there's no instance active before
                    call TimerStart(Bee.Timer,TimeOut,true,function Bee.Loop)
                endif
                //allocate the struct instance
                set Bee.Index[Bee.Total] = dat
                set Bee.Total = Bee.Total + 1
            endmethod
        endstruct
       
        //slow struct. struct for the affected unit
        private struct Slow
        //the variable needed
            private unit Caster
            private unit Affected
            private real Amount
            private real time
            private effect sfx
            private integer Code
           
            private static Slow array Index
            private static integer Total = 0
            private static timer Timer = CreateTimer()
           
            static method Finish takes unit u, integer a returns nothing
                //method to remove the effect on affected unit.
                local integer i = 0
                local Slow dat
                loop
                    exitwhen i >= Slow.Total
                    set dat = Slow.Index[i]
                    //check if it's the right unit by checking the unit and the code
                    if (dat.Affected == u) and (dat.Code == a) then
                        //destroy the buff effect
                        call DestroyEffect(dat.sfx)
                        //reset the unit move speed
                        call SetUnitMoveSpeed(dat.Affected,GetUnitMoveSpeed(dat.Affected)+dat.Amount)
                        //remove the group of bee attacking the unit by calling Bee.Finish and giving the unit's code
                        call Bee.Finish(dat.Affected,i)
                        //nulling the handle
                        set dat.Caster = null
                        set dat.Affected = null
                        set dat.sfx = null
                        //destroy and rellocate the instance
                        call dat.destroy()
                        set Slow.Total = Slow.Total-1
                        set Slow.Index[i] = Slow.Index[Slow.Total]
                        call Bee.Change(Slow.Index[Slow.Total].Affected,Slow.Total,i)
                        set i = i-1
                    endif
                    set i = i+1
                endloop
                if Slow.Total == 0 then
                //if there's no instance left, pause the timer
                    call PauseTimer(Slow.Timer)
                endif
            endmethod
           
            static method Change takes unit u, integer from, integer to returns nothing
                //method to change the code of affecte unit
                local integer i = 0
                local Slow dat
                //search the right affected unit
                loop
                    exitwhen i >= Slow.Total
                    set dat = Slow.Index[i]
                    //check if it's the right unit by check the unit and the code
                    if (dat.Affected == u) and (dat.Code == from) then
                        //change the code
                        set dat.Code = to
                    endif
                    set i = i+1
                endloop
            endmethod
           
            static method Loop takes nothing returns nothing
                local integer i = 0
                //the usual looping
                loop
                    exitwhen i >= Slow.Total
                    //reduce the group of bee shared interval
                    set Bee.Interval[i] = Bee.Interval[i]-TimeOut
                    set i = i+1
                endloop
            endmethod
           
            static method Create takes unit c, unit u, real r, effect fx, integer i, integer lvl returns nothing
                //allocate and create the effect for the unit
                local Slow dat = Slow.allocate()
                local integer s
                //set the necessary variable
                set dat.Caster = c
                set dat.Affected = u
                set dat.Amount = r
                //reduce the unit move speed
                call SetUnitMoveSpeed(u,GetUnitMoveSpeed(u)-dat.Amount)
                //set the necessary variable again
                set dat.sfx = fx
                set dat.Code = i
                //set the shared group of bee interval
                set Bee.Interval[Slow.Total]=BeeAtkInterval+(BeeAtkIntervalIncr*I2R(lvl))
                //create the desired bee amount
                set s = BeeSum+(BeeSumIncr*lvl)
                loop
                    exitwhen s <= 0
                    //create a bee via Bee.Create and pass the unit's code too
                    call Bee.Create(dat.Caster,dat.Affected,Slow.Total,lvl)
                    set s = s-1
                endloop
                if Slow.Total == 0 then
                //if there's no instance active before, active the timer
                    call TimerStart(Slow.Timer,TimeOut,true,function Slow.Loop)
                endif
                //allocate the instance
                set Slow.Index[Slow.Total] = dat
                set Slow.Total = Slow.Total+1
            endmethod
        endstruct
       
        //Honey struct.
        private struct Honey
        //list of needed variable
            private unit Caster
            private real CentralX
            private real CentralY
            private real Area
            private real Time
            private real Time2
            private integer level
            private unit sfxu
            private effect sfx
            private group Affected
           
            private static Honey array Index
            private static integer Total = 0
            private static timer Timer = CreateTimer()
           
            //function for the group filter
            static method CanTargeted takes nothing returns boolean
                return CanTarget(temp,GetFilterUnit())
            endmethod
           
            static method Loop takes nothing returns nothing
                local Honey dat
                local unit u
                local integer i = 0
                local integer j = 0
                //the usual looping
                loop
                    exitwhen i >= Honey.Total
                    set dat = Honey.Index[i]
                    //reduce the time counter for duration and secondary effect interval
                    set dat.Time = dat.Time-TimeOut
                    set dat.Time2 = dat.Time2-TimeOut
                    //pick all group in affected group
                    call GroupAddGroup(dat.Affected,g)
                    loop
                        set u = FirstOfGroup(g)
                        exitwhen u == null
                        call GroupRemoveUnit(g,u)
                        //check the distance to central location
                        set R[0] = dat.CentralX - GetUnitX(u)
                        set R[1] = dat.CentralY - GetUnitY(u)
                        set R[2] = SquareRoot((R[0]*R[0])+(R[1]*R[1]))
                        if (R[2] > dat.Area) or not(CanTarget(dat.Caster,u)) then
                        //if the unit either out of the area or doesn't fulfill the 'can be targeted' condition,
                            //it'll removed from affected group and finish the effect on that unit
                            call GroupRemoveUnit(dat.Affected,u)
                            call Slow.Finish(u,i)
                        endif    
                    endloop
                    //pick every unit in the area that fulfill the 'can be targeted' condition
                    set filter = Filter(function Honey.CanTargeted)
                    set temp = dat.Caster
                    call GroupEnumUnitsInRange(g,dat.CentralX,dat.CentralY,dat.Area,filter)
                    loop
                        set u = FirstOfGroup(g)
                        exitwhen u == null
                        call GroupRemoveUnit(g,u)
                        //check if it's already affected by the spell
                        if not IsUnitInGroup(u,dat.Affected) then
                            //if yes, add it to affected group and create the effect on it
                            call GroupAddUnit(dat.Affected,u)
                            call Slow.Create(dat.Caster,u,GetUnitMoveSpeed(u)*(SlowAmount+(SlowIncr*I2R(dat.level))),AddSpecialEffectTarget(HoneyBuffEffect,u,BuffAttach),i,dat.level)
                        endif
                    endloop
                    set temp = null
                    call DestroyBoolExpr(filter)
                    //check wether the secondary effect interval has reached
                    if dat.Time2 <= 0 then
                        //reset the interval
                        set dat.Time2 = HoneyAreaSecondaryEffectInterval
                        //create the effect
                        set j = HoneyAreaSecondaryEffectSum
                        loop
                            exitwhen j == 0
                            //pick random location
                            set R[0] = GetRandomReal(0.,dat.Area)
                            set R[1] = GetRandomReal(0.,360.)
                            set R[2] = dat.CentralX+(R[0]*Cos(R[1]*bj_DEGTORAD))
                            set R[3] = dat.CentralY+(R[0]*Sin(R[1]*bj_DEGTORAD))
                            //create the effect
                            call DestroyEffect(AddSpecialEffect(HoneyAreaSecondaryEffect,R[2],R[3]))
                            set j = j-1
                        endloop
                    endif
                    //check wether the duration has ended
                    if dat.Time <= 0 then
                        //remove all unit from affected group and end the spell's effect via Slow.Finish
                        loop
                            set u = FirstOfGroup(dat.Affected)
                            exitwhen u == null
                            call GroupRemoveUnit(dat.Affected,u)
                            call Slow.Finish(u,i)
                        endloop
                        //create the spell's finished effect
                        call DestroyEffect(AddSpecialEffect(HoneyEndEffect,dat.CentralX,dat.CentralY))
                        //destroy the affected group
                        call DestroyGroup(dat.Affected)
                        //destroy the area effect
                        call DestroyEffect(dat.sfx)
                        //kill the dummy unit
                        call UnitApplyTimedLife(dat.sfxu,'BTLF',0.5)
                        //nulling handle variable
                        set dat.Affected = null
                        set dat.sfxu = null
                        set dat.Caster = null
                        set dat.sfx = null
                        //destroy and relocate struct instance
                        call dat.destroy()
                        set Honey.Total = Honey.Total - 1
                        set Honey.Index[i] = Honey.Index[Honey.Total]
                        //pick all moved struct's affected unt and change it's code
                        call GroupAddGroup(Honey.Index[Honey.Total].Affected,g)
                        loop
                            set u = FirstOfGroup(g)
                            exitwhen u == null
                            call GroupRemoveUnit(g,u)
                            call Slow.Change(u,Honey.Total,i)
                        endloop
                        set i = i-1
                    endif
                    set i = i+1
                endloop
                if Honey.Total == 0 then
                //if there's no instance active, pause the timer
                    call PauseTimer(Honey.Timer)
                endif
                set u = null
            endmethod
           
            static method Create takes nothing returns nothing
                //the create method...
                local Honey dat = Honey.allocate()
                local unit u = GetTriggerUnit()
                local unit u2
                local integer i = HoneyAreaSecondaryEffectSum
                //set the necessary variable
                set dat.Caster = u
                set dat.level = GetUnitAbilityLevel(u,SpellID) - 1
                set dat.CentralX = GetSpellTargetX()
                set dat.CentralY = GetSpellTargetY()
                set dat.Time = Duration+(DurationIncr*I2R(dat.level))
                set dat.Time2 = HoneyAreaSecondaryEffectInterval
                set dat.Area = AoE+(AoEIncr*I2R(dat.level))
                //create the area effect
                //create dummy unit
                set dat.sfxu = CreateUnit(GetOwningPlayer(u),DummyID,dat.CentralX,dat.CentralY,0.)
                //create effect and attach to that dummy
                set dat.sfx = AddSpecialEffectTarget(HoneyAreaEffect,dat.sfxu,DummyAttach)
                //change the created area effect scale
                call SetUnitScale(dat.sfxu,HoneyAreaEffectScale+(HoneyAreaEffectScaleIncr*I2R(dat.level)),0.,0.)            
                //create the secondary area effect
                call DestroyEffect(AddSpecialEffect(HoneyStartEffect,dat.CentralX,dat.CentralY))
                loop
                    exitwhen i == 0
                    set R[0] = GetRandomReal(0.,dat.Area)
                    set R[1] = GetRandomReal(0.,360.)
                    set R[2] = dat.CentralX+(R[0]*Cos(R[1]*bj_DEGTORAD))
                    set R[3] = dat.CentralY+(R[0]*Sin(R[1]*bj_DEGTORAD))
                    call DestroyEffect(AddSpecialEffect(HoneyAreaSecondaryEffect,R[2],R[3]))
                    set i = i-1
                endloop
                //pick all unit in spell's area that fulfill the 'can be targeted' condition
                set dat.Affected = CreateGroup()
                set filter = Filter(function Honey.CanTargeted)
                set temp = u
                call GroupEnumUnitsInRange(g,dat.CentralX,dat.CentralY,dat.Area,filter)
                loop
                    set u2 = FirstOfGroup(g)
                    exitwhen u2 == null
                    call GroupRemoveUnit(g,u2)
                    //add it to affected group
                    call GroupAddUnit(dat.Affected,u2)
                    //create spell's effect on that unit
                    call Slow.Create(u,u2,GetUnitMoveSpeed(u2)*(SlowAmount+(SlowIncr*I2R(dat.level))),AddSpecialEffectTarget(HoneyBuffEffect,u2,BuffAttach),Honey.Total,dat.level)
                endloop
                set temp = null
                call DestroyBoolExpr(filter)
                if Honey.Total == 0 then
                //if there's no instance before, start the timer
                    call TimerStart(Honey.Timer,TimeOut,true,function Honey.Loop)
                endif
                //allocate the struct instance
                set Honey.Index[Honey.Total] = dat
                set Honey.Total = Honey.Total+1
                set u = null
                set u2 = null
            endmethod
        endstruct
         
        private function Conditions takes nothing returns boolean
            if GetSpellAbilityId() == SpellID then
                call Honey.Create()
            endif
            return false
        endfunction
       
        private function InitTrig_Initialize takes nothing returns nothing
            //create the spell trigger
            local trigger t = CreateTrigger()
            //add the event to it
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            //add the 'condition' to that trigger
            call TriggerAddCondition(t, Condition(function Conditions))
            //preload the unit
            call RemoveUnit(CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),BearUnit,0,0,0))
            call RemoveUnit(CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),DummyID,0,0,0))
            //preload all effect
            call Preload(BeeModel)
            call Preload(HoneyStartEffect)
            call Preload(HoneyAreaEffect)
            call Preload(HoneyAreaSecondaryEffect)
            call Preload(HoneyBuffEffect)
            call Preload(HoneyEndEffect)
            call Preload(BeeAppearEffect)
            call Preload(BeeAttachEffect)
            call Preload(BeeDmgEffect)
            call Preload(BeeDisappearEffect)
            call Preload(BearAppearEffect)
            call Preload(BearDmgEffect)
            call Preload(BearAttachEffect)
            call Preload(BearDisappearEffect)
        endfunction
    endscope

    the screeny
    Screeny
    [​IMG]


    changelog
    v1.0
    Submit the spell

    v1.1
    Add comment
    Make the 'CanTargeted' function easier to change
    Change Spell AoE to 300
    and few other small thing

    v1.5
    Fix the Error when opened by recent jasshelper
    Fix bug when the Bear appear, it's appear effect isn't it the right place


    To-do List
    1. Use proper effect that really honey-like


    and... I'm already frustrated on choosing the right effect for the honey area...
    Anyone know any nice effect that really resemble 'honey'?

    EDIT: UPDATED to v1.15.
     

    Attached Files:

    Last edited: Mar 31, 2011
  6. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,015
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Have you tried attaching effects to a dummy model and giving the dummy-unit yellow vertex colouring? Some coloured blood effects would fit none too badly.
     
  7. Garfield1337

    Garfield1337

    Joined:
    Jul 6, 2009
    Messages:
    1,806
    Resources:
    4
    Maps:
    1
    Spells:
    3
    Resources:
    4
    Mage Goo,here's a screenshot of error
    Error
    [​IMG]
     

    Attached Files:

    • SS.jpg
      SS.jpg
      File size:
      324.1 KB
      Views:
      174
  8. Mage_Goo

    Mage_Goo

    Joined:
    Jun 1, 2008
    Messages:
    366
    Resources:
    2
    Spells:
    2
    Resources:
    2
    well, after 3 hours of trying almost all of the blood effect, I found out that it won't change the color even when the unit vertex coloring is changed...
    I try to use the MoonWellTarget though, but the effect are floating far above in the air if i make it larger...


    ok, I'll fix it in a minute. After I update my outdated jasshelper, I found out that this occur because recent update that allow u to use struct member without '.<member name>' or 'this.<member name>' anymore. it thinks that Bear i use there is a Bear member of that Bear struct, thus thinks that as an error. I'm gonna fix it by change the name of that member.

    EDIT: Update the spell above... decided to keep the effect just like that...
     
  9. NFWar

    NFWar

    Joined:
    Jul 27, 2008
    Messages:
    1,314
    Resources:
    227
    Models:
    1
    Icons:
    215
    Packs:
    1
    Skins:
    2
    Spells:
    6
    Tutorials:
    2
    Resources:
    227
    Oh no I dont have much time! I will spend 5 hours in school (starting from now). Damn it, I have so prepare test map. Spell will do no damage. It is utility spell. I cant reveal it or explain description, because lulz factor will be lower when you will see spell with your own eyes.

    I looked at gmt time and it is like 3 of night there. Here it is 3 of evening, so I still have like 12-5=7 hours? I am not sure. Correct meh if I am wrong.
     
  10. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,015
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Roughly 19 more hours
     
  11. -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
    Here you go, finished one!
    There is chance that I forget something so I won't upload pictures and such things, if I find time and improve it even more I will upload last version once again, if not I will edit this post :)
     

    Attached Files:

  12. Maker

    Maker

    Joined:
    Mar 6, 2006
    Messages:
    9,193
    Resources:
    17
    Maps:
    2
    Spells:
    14
    Tutorials:
    1
    Resources:
    17
    @-Kobas-

    Maybe the setup trigger should be in the spell folder, since it's integral for the spell to work. The looping trigger should be turned on/off and you're loading data you don't necessarily need. Just a few tips to make the competition tougher.

    @Mage_Goo
    Thanks for the comments and taking time to test!
     
  13. NBalfa

    NBalfa

    Joined:
    Aug 20, 2010
    Messages:
    70
    Resources:
    0
    Resources:
    0
    Edit: I just fixed it!^^
    sorry for bothering
     
  14. Mage_Goo

    Mage_Goo

    Joined:
    Jun 1, 2008
    Messages:
    366
    Resources:
    2
    Spells:
    2
    Resources:
    2
    u can set the 'Corpse' ability Maximum Total damage to 0 rather than 99,999 to make it really don't have maximum total damage.
    it's nice that u have updated the tooltip, but u didn't put the spell duration there.

    I believe it's has something to do with the unit's
    Art - Animation - Cast Backswing
    Art - Animation - Cast Point
    Movement - Turn Rate
    or that's because your web's cast range that make the dummy must walk first to cast it to the target.
    or maybe it's because there's something wrong in your trigger
     
  15. -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
    [​IMG]

    Rupture



    [​IMG] [​IMG]
    More pictures below :)

    Have fun!
     

    Attached Files:

    • Rupture.w3x
      File size:
      120.5 KB
      Views:
      44
    • 1.JPG
      1.JPG
      File size:
      50 KB
      Views:
      80
    • 2.JPG
      2.JPG
      File size:
      30.6 KB
      Views:
      78
    • 3.JPG
      3.JPG
      File size:
      44.8 KB
      Views:
      166
    • 4.JPG
      4.JPG
      File size:
      36.5 KB
      Views:
      159
    • 5.JPG
      5.JPG
      File size:
      40.6 KB
      Views:
      73
    • 6.JPG
      6.JPG
      File size:
      34.6 KB
      Views:
      110
  16. Astaroth Zion

    Astaroth Zion

    Joined:
    Feb 13, 2011
    Messages:
    360
    Resources:
    26
    Models:
    25
    Packs:
    1
    Resources:
    26
    Ahh I'm almost done,
    I will use this post to summite my final work

    Edit: about Mage Goo feedback, the area of effect isn't buggy there is a probability that the unit in that area get Contagious Cold (the probability increases with level). Thanks for pointing that out, seem that I forget to put that explanation at the tooltip.

    Edit: my submission, can tell me how to post triggers here???

    Contagious Cold




    Tooltip

    Infect yourself with a extremely agresive cold, you will began to sneeze suffering some damage and speed reduction, but also there is chance to pass the cold to nearby units and increasing the cold duration of units already infected. The possibility to infect increases with level.
    • Level 1 takes 12 damage per sneeze, 7% attack speed reduction and 15% movement speed reduction. Each unit has a 45% chance to be infected by CCold when sneezed.
    • Level 2 takes 25 damage per sneeze, 14% attack speed reduction and 25% movement speed reduction. Each unit has a 55% chance to be infected by CCold when sneezed.
    • Level 3 takes 37 damage per sneeze, 21% attack speed reduction and 35% movement speed reduction. Each unit has a 65% chance to be infected by CCold when sneezed.
    • Level 4 takes 50 damage per sneeze, 28% attack speed reduction and 45% movement speed reduction. Each unit has a 75% chance to be infected by CCold when sneezed.

    Triggers
    Not know how to put them here XD
     

    Attached Files:

    Last edited: Mar 31, 2011
  17. NBalfa

    NBalfa

    Joined:
    Aug 20, 2010
    Messages:
    70
    Resources:
    0
    Resources:
    0
    here Is my spell :
     

    Attached Files:

  18. NFWar

    NFWar

    Joined:
    Jul 27, 2008
    Messages:
    1,314
    Resources:
    227
    Models:
    1
    Icons:
    215
    Packs:
    1
    Skins:
    2
    Spells:
    6
    Tutorials:
    2
    Resources:
    227
    Bunny Setings
    • Bunny Run Setings
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to Bunny Run
      • Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • BR_Integer[1] Equal to 0
          • Then - Actions
            • Trigger - Turn on Bunny Run Loop <gen>
          • Else - Actions
        • -------- Checking for units that already have the buff. If caster already have the buff, it will be replaced. --------
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Triggering unit) is in BR_Group) Equal to True
          • Then - Actions
            • For each (Integer BR_Integer[3]) from 1 to (Number of units in BR_Group), do (Actions)
              • Loop - Actions
                • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • (Triggering unit) Equal to BR_Caster[BR_Integer[3]]
                  • Then - Actions
                    • Set BR_Level[BR_Integer[3]] = (Level of Bunny Run for (Triggering unit))
                    • Set BR_Duration[BR_Integer[3]] = (4.00 + (1.00 x (Real(BR_Level[BR_Integer[3]]))))
                  • Else - Actions
          • Else - Actions
            • Unit Group - Add (Triggering unit) to BR_Group
            • Set BR_Integer[1] = (BR_Integer[1] + 1)
            • Set BR_Integer[2] = (BR_Integer[2] + 1)
            • Set BR_On[BR_Integer[2]] = True
            • Set BR_Caster[BR_Integer[2]] = (Triggering unit)
            • Set BR_Level[BR_Integer[2]] = (Level of Bunny Run for (Triggering unit))
            • Set BR_Duration[BR_Integer[2]] = (3.00 + (1.00 x (Real(BR_Level[BR_Integer[2]]))))
            • -------- Jump is not random. It is fake parabola. It will not move unit at point, but just change the height. Chose some values for variables to make nice looking jump, not too frequent, and not too high. --------
            • Set BR_MaxDistance[BR_Integer[2]] = 312.00
            • Set BR_Distance[BR_Integer[2]] = BR_MaxDistance[BR_Integer[2]]
            • Set BR_Height[BR_Integer[2]] = 100.00
            • -------- This changes landing time with level, so jumps will be more frequent. --------
            • Set BR_Speed[BR_Integer[2]] = (6.00 + (2.00 x (Real(BR_Level[BR_Integer[2]]))))
            • -------- Yes, lots of effects --------
            • Special Effect - Create a special effect attached to the foot left of (Triggering unit) using units\critters\EasterRabbit\EasterRabbit.mdl
            • Set BR_Effect[BR_Integer[2]] = (Last created special effect)
            • Special Effect - Create a special effect attached to the foot right of (Triggering unit) using units\critters\EasterRabbit\EasterRabbit.mdl
            • Set BR_Effect2[BR_Integer[2]] = (Last created special effect)
            • Special Effect - Create a special effect attached to the foot right of (Triggering unit) using Abilities\Weapons\FaerieDragonMissile\FaerieDragonMissile.mdl
            • Set BR_Effect3[BR_Integer[2]] = (Last created special effect)
            • Special Effect - Create a special effect attached to the foot left of (Triggering unit) using Abilities\Weapons\FaerieDragonMissile\FaerieDragonMissile.mdl
            • Set BR_Effect4[BR_Integer[2]] = (Last created special effect)
            • -------- Making ground unit to be able to change height --------
            • Unit - Add Storm Crow Form to (Triggering unit)
            • Unit - Remove Storm Crow Form from (Triggering unit)

    Bunny Run Loop
    • Bunny Run Loop
      • Events
        • Time - Every 0.02 seconds of game time
      • Conditions
      • Actions
        • For each (Integer BR_Integer[0]) from 1 to BR_Integer[2], do (Actions)
          • Loop - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • BR_On[BR_Integer[0]] Equal to True
              • Then - Actions
                • -------- Even if duration is 0, we have to finish the last jump to make it looks smooth. So we wait for distance variable to become 0 and it becomes 0 when unit lands on ground. --------
                • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • BR_Distance[BR_Integer[0]] Less than or equal to 0.00
                    • BR_Duration[BR_Integer[0]] Less than or equal to 0.00
                  • Then - Actions
                    • -------- The group below is for units that are under effect of this spell. --------
                    • Unit Group - Remove BR_Caster[BR_Integer[0]] from BR_Group
                    • Special Effect - Destroy BR_Effect[BR_Integer[0]]
                    • Special Effect - Destroy BR_Effect2[BR_Integer[0]]
                    • Special Effect - Destroy BR_Effect3[BR_Integer[0]]
                    • Special Effect - Destroy BR_Effect4[BR_Integer[0]]
                    • Set BR_On[BR_Integer[0]] = False
                    • -------- Standard recycling --------
                    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      • If - Conditions
                        • BR_Integer[0] Less than BR_Integer[2]
                      • Then - Actions
                        • Set BR_On[BR_Integer[0]] = BR_On[BR_Integer[2]]
                        • Set BR_Caster[BR_Integer[0]] = BR_Caster[BR_Integer[2]]
                        • Set BR_Distance[BR_Integer[0]] = BR_Distance[BR_Integer[2]]
                        • Set BR_Speed[BR_Integer[0]] = BR_Speed[BR_Integer[2]]
                        • Set BR_MaxDistance[BR_Integer[0]] = BR_MaxDistance[BR_Integer[2]]
                        • Set BR_Duration[BR_Integer[0]] = BR_Duration[BR_Integer[2]]
                        • Set BR_Height[BR_Integer[0]] = BR_Height[BR_Integer[2]]
                        • Set BR_Level[BR_Integer[0]] = BR_Level[BR_Integer[2]]
                        • Set BR_Parabola[BR_Integer[0]] = BR_Parabola[BR_Integer[2]]
                        • Set BR_Effect[BR_Level[0]] = BR_Effect[BR_Integer[0]]
                        • Set BR_Effect2[BR_Integer[0]] = BR_Effect2[BR_Integer[2]]
                        • Set BR_Effect3[BR_Integer[0]] = BR_Effect3[BR_Integer[2]]
                        • Set BR_Effect4[BR_Integer[0]] = BR_Effect4[BR_Integer[2]]
                      • Else - Actions
                    • Set BR_Integer[2] = (BR_Integer[2] - 1)
                    • Set BR_Integer[1] = (BR_Integer[1] - 1)
                    • Set BR_Integer[0] = (BR_Integer[0] - 1)
                    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      • If - Conditions
                        • BR_Integer[2] Equal to 0
                      • Then - Actions
                        • Trigger - Turn off (This trigger)
                      • Else - Actions
                  • Else - Actions
                    • -------- dead unit have to stop jumping, at least land on ground. Seting duration to 0. Else dead unit will jump til effect ends. --------
                    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      • If - Conditions
                        • (BR_Caster[BR_Integer[0]] is dead) Equal to True
                      • Then - Actions
                        • Set BR_Duration[BR_Integer[0]] = 0.00
                      • Else - Actions
                        • -------- Unit is alive? Yes. Reduce duration by repiod of looping. --------
                        • Set BR_Duration[BR_Integer[0]] = (BR_Duration[BR_Integer[0]] - 0.02)
                    • -------- Calculating parabola and changing unit height. --------
                    • Set BR_Distance[BR_Integer[0]] = (BR_Distance[BR_Integer[0]] - BR_Speed[BR_Integer[0]])
                    • Set BR_Parabola[BR_Integer[0]] = (((4.00 x BR_Height[BR_Integer[0]]) / BR_MaxDistance[BR_Integer[0]]) x ((BR_MaxDistance[BR_Integer[0]] - BR_Distance[BR_Integer[0]]) x (BR_Distance[BR_Integer[0]] / BR_MaxDistance[BR_Integer[0]])))
                    • Animation - Change BR_Caster[BR_Integer[0]] flying height to BR_Parabola[BR_Integer[0]] at 0.00
                    • -------- If duration is not 0 or less (spell still have effect) and distance > 0 (unit land on ground) than repeat jump --------
                    • -------- Those actions run when unit land on ground (but not the last landing) --------
                    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      • If - Conditions
                        • BR_Distance[BR_Integer[0]] Less than or equal to 0.00
                        • BR_Duration[BR_Integer[0]] Greater than 0.00
                      • Then - Actions
                        • Sound - Play RatWhat1 <gen> at 100.00% volume, attached to BR_Caster[BR_Integer[0]]
                        • -------- refreshing distance to make unit to jump again --------
                        • Set BR_Distance[BR_Integer[0]] = BR_MaxDistance[BR_Integer[0]]
                        • Set BR_Point[0] = (Position of BR_Caster[BR_Integer[0]])
                        • -------- dummy uses spell that cause enemys to miss. Here it is spawning and casting spell at position of special effect. Duration is always the same, because special effect animation cant be extended. --------
                        • Unit - Create 1 Dummy for (Owner of BR_Caster[BR_Integer[0]]) at BR_Point[0] facing Default building facing degrees
                        • Unit - Add Cloud (Custom) to (Last created unit)
                        • Unit - Order (Last created unit) to Human Dragonhawk Rider - Cloud BR_Point[0]
                        • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
                        • Special Effect - Create a special effect at BR_Point[0] using Objects\Spawnmodels\Undead\ImpaleTargetDust\ImpaleTargetDust.mdl
                        • Special Effect - Destroy (Last created special effect)
                        • -------- Only one leak? nice.... kill ET! --------
                        • Custom script: call RemoveLocation (udg_BR_Point[0])
                      • Else - Actions
              • Else - Actions


    Tooltip
    Summon two cute bunny slippers, that increase movemet speed. They are so exiding to be summoned, what they jump all the time and makes hero to jump too. Every leap will leave dust cloud. It makes enemys to miss with 25% of chance. |n|n|cffffcc00Level 1|r - 40% movement speed for 4 seconds. |n|cffffcc00Level 2|r - 60% movement speed for 5 seconds. |n|cffffcc00Level 3|r - 80% movement speed for 6 seconds.


    This is the latest wip!
     

    Attached Files:

    Last edited: Mar 31, 2011
  19. Maker

    Maker

    Joined:
    Mar 6, 2006
    Messages:
    9,193
    Resources:
    17
    Maps:
    2
    Spells:
    14
    Tutorials:
    1
    Resources:
    17
    My entry:

    [​IMG]

    With correct timing, you're able to evade attacks. I fail here many times :D
    http://www.youtube.com/watch?v=l2MosWbA_Pk

    Code (vJASS):

    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Moonwalk v1.0 by Maker
       
        The caster is gain 100% Evade for short duration
        and deals AOE at the end.
       
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/



    scope Moonwalk initializer InitTrig_Moonwalk

        globals
       
            // Main ability ~ Moonwalk
            private constant integer ABILID = 'A003'
            // Spell book ~ Spell Book - Moonwalk
            private constant integer BOOKID = 'A004'
            // Dummy's raw code ~ Moonwalk Dummy
            private constant integer DUMMYID = 'h000'
           
            // The animation ondex of walk animation
            // This is different for many units
            private constant integer INDEX = 12
           
            // How far the unit moonwalks
            private constant real OFFSET = 250.
            // How much the unit moves per loop
            // Speedloop begins from 0 and goes to bj_PI
            // When it is >= bj_PI, the unit has returned to the original pos
            private constant real SPEEDLOOP = bj_PI/20.
           
            // AoE of damage
            private constant real AOE = 200.
            // Base damage
            private constant real DMGBASE = 40.
            // Bonus damage per level, doesn't apply at lvl 1
            private constant real DMGBONUS = 20.
           
            // How often the loop than changes unit's position runs
            private constant real TIMERLOOP = 0.03125
           
            // How fast the animation speed plays
            private constant real ANIMSPEED = 2.
           
            // Is floating text shown
            private constant boolean SHOWFLOAT = TRUE
            private constant string array FLOATS
            // How many different floating texts are defined
            private constant integer FLOATAMOUNT = 2
            // The size of the floating text
            private constant real FLOATSIZE = 0.021
           
            // Self explanatory
            private constant attacktype ATK_TYPE = ATTACK_TYPE_NORMAL
            private constant damagetype DMG_TYPE = DAMAGE_TYPE_NORMAL
           
            // Order string of the buff applying ability
            private constant string DUMMYBUFFORDER = "innerfire"
           
            // Effect upon hit by AoE
            private constant string EFFECTTARGET = "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl"
            // Effect to apply on caster for the duration of the dodging move
            private constant string EFFECTCASTER = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"
            // Effect to apply at caster's position when spell is cast
            private constant string PREEFFECTCASTER = "Abilities\\Spells\\Items\\AIil\\AIilTarget.mdl"
            // Attachment point for EFFECTTARGET
            private constant string ETARGATT = "chest"
            // Attachment point for EFFECTCASTER
            private constant string ECASTATT = "origin"
           
            /*~~~~~~~~~~~~~~~~~~~~~ Don't change these ~~~~~~~~~~~~~~~~~~~~~~*/
            private real dmg
            private unit caster
            private player plr
            private integer moonwalks = 0
            private integer prewalks = 0
            private integer actives = 0
            private unit dummy
           
            private hashtable hash = InitHashtable()
            private group grp = CreateGroup()
            private group Moonwalkers = CreateGroup()
            private timer MoonwalkTimer = CreateTimer()
            private group Prewalkers = CreateGroup()
            private timer PreTimer = CreateTimer()
            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
       
        endglobals
       
        // Here you can define the floating texts
        private function SetFloats takes nothing returns nothing
            set FLOATS[1] = "Can't touch this!"
            set FLOATS[2] = "You can't see me!"
        endfunction
       
        /*~~~~~~~~~ DThese return child keys for hashtable actions ~~~~~~~*/
        private function HashX takes nothing returns integer
            return 1
        endfunction
       
        private function HashY takes nothing returns integer
            return 2
        endfunction
       
        private function HashLoop takes nothing returns integer
            return 3
        endfunction
       
        private function HashAngle takes nothing returns integer
            return 4
        endfunction
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
       
        // Damages units, filters out unwanted units
        private function DamageFilter takes nothing returns boolean
            local unit u = GetFilterUnit()
            if GetWidgetLife(u) > 0.405 and /*
            */
    IsUnitEnemy(u , plr) /*
         */
    then
                call DestroyEffect(AddSpecialEffectTarget(EFFECTTARGET , u , ETARGATT))
                call UnitDamageTarget(caster , u , dmg , true , false , ATK_TYPE , DMG_TYPE , WEAPON_TYPE_WHOKNOWS)
            endif
            set u = null
            return false
        endfunction
       
       
        private function LoopWalkers takes nothing returns nothing
            local unit u = GetEnumUnit()
            local integer id = GetHandleId(u)
            local real r = LoadReal(hash , id , HashLoop())
            local real angle = LoadReal(hash , id , HashAngle())
            local real x = LoadReal(hash , id , HashX())
            local real y = LoadReal(hash , id , HashY())
            set r = r + SPEEDLOOP
            if r < bj_PI and GetWidgetLife(u) > 0.405 then
                call SetUnitX(u , x + OFFSET * Cos(angle) * Sin(r))
                call SetUnitY(u , y + OFFSET * Sin(angle) * Sin(r))
                call SaveReal(hash , id , HashLoop() , r)
                call SetUnitVertexColor(u , 255 , 255 , 255 , R2I(255*r/bj_PI) )
            else
                call SetUnitX(u,x)
                call SetUnitY(u,y)
               
                call UnitRemoveAbility(u , BOOKID)
                call SetUnitTimeScale(u , 1)
                call SetUnitAnimation(u , "stand")
                call SetUnitVertexColor(u , 255 , 255 , 255 , 255 )
                call DestroyEffect(LoadEffectHandle(hash , id , StringHash("effect")))
               
                set caster = u
                set plr = GetOwningPlayer(u)
                set dmg = LoadReal(hash , id , StringHash("damage"))
                call GroupEnumUnitsInRange(grp , x , y , AOE , function DamageFilter)
                call GroupClear(grp)
               
                set moonwalks = moonwalks - 1
                if moonwalks == 0 then
                    call PauseTimer(MoonwalkTimer)
                endif
                call GroupRemoveUnit(Moonwalkers , u)
            endif
           
            set u = null
        endfunction
       
       
        private function TimerExpire takes nothing returns nothing
            call ForGroup(Moonwalkers , function LoopWalkers)
        endfunction

       
        private function CastActions takes nothing returns nothing
            local unit u = GetTriggerUnit()
            local integer id = GetHandleId(u)
           
            if SHOWFLOAT == TRUE then
                set bj_lastCreatedTextTag = CreateTextTag()
                call SetTextTagText(bj_lastCreatedTextTag , FLOATS[GetRandomInt(1,FLOATAMOUNT)] , FLOATSIZE)
                call SetTextTagPosUnit(bj_lastCreatedTextTag , u , 0. )
                // With this line one can modifu the floating text colour
                //call SetTextTagColor(bj_lastCreatedTextTag , 255 , 255 , 255 , 255)
                call SetTextTagVelocity( bj_lastCreatedTextTag , 0, 0.05 )
                call SetTextTagPermanent( bj_lastCreatedTextTag , false )
                call SetTextTagLifespan( bj_lastCreatedTextTag , 2.00 )
                call SetTextTagFadepoint( bj_lastCreatedTextTag , 1.70 )
            endif
               
            call SaveReal(hash , id , HashAngle() , GetRandomReal(0,360))
            call SaveReal(hash , id , HashLoop() , 0)
            call SaveReal(hash , id , HashX() , GetUnitX(u))
            call SaveReal(hash , id , HashY() , GetUnitY(u))
            call SaveEffectHandle(hash , id , StringHash("effect") , AddSpecialEffectTarget(EFFECTCASTER , u , ECASTATT))
           
            // Adds the evasion ability    
            call UnitAddAbility(u , BOOKID)
            // Increases the animation speed
            call SetUnitTimeScale(u , ANIMSPEED)
           
            call SaveReal(hash , id , StringHash("damage") , DMGBASE + (GetUnitAbilityLevel(u , ABILID) - 1) * DMGBONUS)
           
            call SetUnitX(dummy , GetUnitX(u))
            call SetUnitY(dummy , GetUnitY(u))
            call IssueTargetOrder(dummy , DUMMYBUFFORDER , u)
           
            if moonwalks == 0 then
                call TimerStart(MoonwalkTimer , TIMERLOOP , true , function TimerExpire)
            endif
            set moonwalks = moonwalks + 1
            call GroupAddUnit(Moonwalkers , u)
           
            set u = null
        endfunction
       
        /*~ The pre actions override the animation of the ability ~~*/
        /*~ This allows me to play the walk animation already when ~*/
        /*~ the spell is begun to cast. The actual actions take ~~~~*/
        /*~ place when staring the effect of the ability ~~~~~~~~~~~*/
        private function PreWalkerLoop takes nothing returns nothing
            local unit u = GetEnumUnit()
            set prewalks = prewalks - 1
            call GroupRemoveUnit(Prewalkers , u)
            call DestroyEffect(AddSpecialEffect(PREEFFECTCASTER, GetUnitX(u), GetUnitY(u)))
            call SetUnitAnimationByIndex(u , INDEX)
            set u = null
        endfunction
       
       
        private function PreTimerExpire takes nothing returns nothing
            call ForGroup(Prewalkers , function PreWalkerLoop)
        endfunction
       
       
        private function BeginActions takes nothing returns nothing
            if prewalks == 0 then
                call TimerStart(PreTimer , 0. , false , function PreTimerExpire)
            endif
            set prewalks = prewalks + 1
            call GroupAddUnit(Prewalkers , GetTriggerUnit())
        endfunction
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
       
       
        private function CastConditions takes nothing returns boolean
            return GetSpellAbilityId() == ABILID and not(IsUnitInGroup(GetTriggerUnit() , Moonwalkers))
        endfunction
       

        private function InitTrig_Moonwalk takes nothing returns nothing
            local trigger t1 = CreateTrigger()
            local trigger t2 = CreateTrigger()
            local integer i = 0
            call TriggerAddCondition( t1 , Condition( function CastConditions ) )
            call TriggerAddAction( t1 , function CastActions )
            call TriggerAddCondition( t2 , Condition( function CastConditions ) )
            call TriggerAddAction( t2 , function BeginActions )
            loop
                call TriggerRegisterPlayerUnitEvent(t1, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
                call TriggerRegisterPlayerUnitEvent(t2, Player(i), EVENT_PLAYER_UNIT_SPELL_CAST, null)
                call SetPlayerAbilityAvailable(Player(i) , BOOKID , false)
                exitwhen i == 15
                set i = i + 1
            endloop
            set dummy = CreateUnit( Player(15) , DUMMYID , 0 , 0 , 0 )
            call ShowUnit(dummy , false)
            call SetFloats()
        endfunction
       
    endscope
     
     

    Attached Files:

    Last edited: Apr 1, 2011
  20. Garfield1337

    Garfield1337

    Joined:
    Jul 6, 2009
    Messages:
    1,806
    Resources:
    4
    Maps:
    1
    Spells:
    3
    Resources:
    4
    Well, here's my final submission.
    [​IMG]
    Code
    Code (vJASS):
    //===========================================================================
    //                        Chicken Burst spell
    //                          by Garfield1337
    //===========================================================================
    scope ChickenBurst initializer Init

        globals
            private constant integer CHICKEN_ID               =   'h001'  //Raw code of chicken
            private constant integer DUMMY_ID                 =   'h002'  //Raw code of dummy
            private constant integer EGG_ID                   =   'h000'  //Raw code of egg
            private constant integer ABILITY_ID               =   'A000'  //Raw code of ability
            private constant real EGG_SPEED                   =   24.00   //Egg's flying speed
            private constant real CHICKEN_SPEED               =   4.00    //Chickens' flying speed
            private constant real CHICKEN_HEIGHT              =   600.0   //Chickens' max height when flying
            private constant real CHICKEN_EXPLOSION_AOE       =   160.0   //Radius of area which chickens damage
            private constant real CHICKEN_RANGE_MIN           =   150.0   //Minimum range chickens fly from egg
            private constant real CHICKEN_RANGE_MAX           =   350.0   //Maximum range chickens fly from egg
            private constant string CHICKEN_EXPLOSION_SFX     =   "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl"   //Effect created upon chicken explosion
            private constant boolean DAMAGE_ALLIED            =   false   //Should the spell damage allied units?
            private constant boolean DAMAGE_ENEMY             =   true    //Should the spell damage enemy units?
            private constant attacktype ATTACK_TYPE           =   ATTACK_TYPE_NORMAL   //Explosion attack type
            private constant damagetype DAMAGE_TYPE           =   DAMAGE_TYPE_NORMAL   //Explosion damage type
            private constant weapontype WEAPON_TYPE           =   WEAPON_TYPE_WHOKNOWS //Explosion weapon type
            private constant boolean DESTROY_DESTRUCTABLES    =   false   //Should the explosion destroy destructables?
            private constant boolean TREES_ONLY               =   false   //Should the explosion only affect trees as destructables?
            //If DESTROY_DESTRUCTABLES is false,DESTRUCTABLE_DAMAGE can be set to a number greater than 0.00
            //to damage destructables instead of instantly killing them
            //If DESTROY_DESTRUCTABLES is false and DESTRUCTABLE_DAMAGE is 0.00 the spell will not affect any destructables
            private constant real DESTRUCTABLE_DAMAGE         =   40.0
        endglobals
       
        private keyword INVALID_TARGETS //Don't change this line
       
        private function InvalidTargets takes nothing returns nothing
            //Which unit types shouldn't be affected by spell
            set INVALID_TARGETS[0]                            =   UNIT_TYPE_FLYING
            set INVALID_TARGETS[1]                            =   UNIT_TYPE_STRUCTURE
            set INVALID_TARGETS[2]                            =   UNIT_TYPE_MAGIC_IMMUNE
        endfunction
       
        private function Damage takes integer lvl returns real
            //Damage per explosion per level
            return 50.0 + 20.0 * lvl
        endfunction
       
        private function ChickenAmount takes integer lvl returns integer
            //Number of chickens per level
            return 5 + 5 * lvl
        endfunction
       
        private function ChickenDuration takes nothing returns real
            //Time before each chicken explodes
            return GetRandomReal(1.00,2.00)
        endfunction
       
        //End of configuration part
        //===========================================================================
       
        globals
            private hashtable Hash = InitHashtable()
            private group g = CreateGroup()
            private location l = Location(0.00,0.00)
            private unittype array INVALID_TARGETS
            private group EGGS = CreateGroup()
            private group CHICKENS = CreateGroup()
            private rect r
            private unit t
            private real r1
            private real r2
            private real r3
            private real r4
            private integer i1
            private integer i2
            private integer i3
            private unit u1
            private unit u2
            private real x1
            private real y1
            private real x2
            private real y2
        endglobals

        private function Parabola takes real y0, real y1, real h, real d, real x returns real
            local real A = (2*(y0+y1)-4*h)/(d*d)
            local real B = (y1-y0-A*d*d)/d        //Credits to moyack for the parabola function
            return A*x*x + B*x + y0
        endfunction

        private function Cast takes nothing returns boolean
            if GetSpellAbilityId() == ABILITY_ID then
                set x1 = GetUnitX(GetTriggerUnit())
                set y1 = GetUnitY(GetTriggerUnit())
                //Creating egg
                set u1 = CreateUnit(GetOwningPlayer(GetTriggerUnit()),EGG_ID,x1,y1,GetRandomReal(0.00,360.0))
                set x2 = GetSpellTargetX()
                set y2 = GetSpellTargetY()
                set i1 = GetHandleId(u1)
                //Moving the egg on caster's position since it is created beside
                call SetUnitX(u1,x1)
                call SetUnitY(u1,y1)
                //Enabling the egg to fly by adding and removing crow form
                call UnitAddAbility(u1,'Amrf')
                call UnitRemoveAbility(u1,'Amrf')
                //Adding a slight height to egg so it doesn't fly off the ground
                call SetUnitFlyHeight(u1,30.0,0.00)
                //Saving angle between caster and target
                set r1 = Atan2(y2 - y1,x2 - x1)
                call SaveReal(Hash,i1,0,r1)
                //To prevent the egg from hitting cliff while in air before reaching it's target
                //i check height of terrain on egg's way and find the peak (if any)
                //then later i add the peak's height to max height of parabola in loop
                set r2 = 0
                set r3 = SquareRoot(Pow(x2 - x1,2) + Pow(y2 - y1,2))
                set r4 = 0
                loop
                    call MoveLocation(l,x1 + r2 * Cos(r1),y1 + r2 * Sin(r1))
                    if r2 == 0 then
                        //Saving caster's height for parabola
                        call SaveReal(Hash,i1,1,GetLocationZ(l) + 30.0)
                    elseif r2 >= r3 then
                        //Saving target's height for parabola
                        call SaveReal(Hash,i1,2,GetLocationZ(l))
                        exitwhen true
                    endif
                    if GetLocationZ(l) > r4 then
                        set r4 = GetLocationZ(l)
                    endif
                    set r2 = r2 + 32.0
                endloop
                //Saving peak's height
                call SaveReal(Hash,i1,3,r4)
                //Saving total distance
                call SaveReal(Hash,i1,4,r3)
                //Saving passed distance which is 0
                call SaveReal(Hash,i1,5,0.00)
                //Saving spell level
                call SaveInteger(Hash,i1,6,GetUnitAbilityLevel(GetTriggerUnit(),ABILITY_ID))
                //Saving a custom integer which will be used in loop
                call SaveInteger(Hash,i1,7,0)
                call GroupAddUnit(EGGS,u1)
            endif
            return false
        endfunction

        private function Loop1 takes nothing returns nothing
            //Egg loop
            set u1 = GetEnumUnit()
            set i1 = GetHandleId(u1)
            set i2 = LoadInteger(Hash,i1,7)
            set i3 = 0
            if i2 == 0 then //At first, the egg is just flying
                //Egg movement
                set x1 = GetUnitX(u1) + EGG_SPEED * Cos(LoadReal(Hash,i1,0))
                set y1 = GetUnitY(u1) + EGG_SPEED * Sin(LoadReal(Hash,i1,0))
                call SetUnitX(u1,x1)
                call SetUnitY(u1,y1)
                call SaveReal(Hash,i1,5,LoadReal(Hash,i1,5) + EGG_SPEED)
                call MoveLocation(l,x1,y1)
                //Setting egg's flying height with parabola
                call SetUnitFlyHeight(u1,Parabola(LoadReal(Hash,i1,1),LoadReal(Hash,i1,2),LoadReal(Hash,i1,4) / 3 + LoadReal(Hash,i1,3),LoadReal(Hash,i1,4),LoadReal(Hash,i1,5)) - GetLocationZ(l),0.00)
                if LoadReal(Hash,i1,5) >= LoadReal(Hash,i1,4) then
                    //Playing egg's birth animation to make it look as if it jumped off the ground
                    call SetUnitAnimation(u1,"birth")
                    //If the egg hits ground,the custom integer is set to 1 to prevent egg from moving anymore
                    call SaveInteger(Hash,i1,7,1)
                endif
            else
                set x1 = GetUnitX(u1)
                set y1 = GetUnitY(u1)
                //The custom integer is now used as a counter to simulate wait function
                call SaveInteger(Hash,i1,7,i2 + 1)
                if i2 == 20 then //Upon reaching 20 the egg explodes...
                    set u2 = CreateUnit(GetOwningPlayer(u1),DUMMY_ID,x1,y1,GetRandomReal(0.00,360.0))
                    call SetUnitX(u2,x1)
                    call SetUnitY(u2,y1)
                    //Mine's death spell animation is used as a small explosion for egg
                    call SetUnitAnimation(u2,"death spell")
                    call UnitApplyTimedLife(u2,'BTLF',2.00)
                elseif i2 == 25 then //...and after a short delay,chickens burst
                    loop
                        set i3 = i3 + 1
                        //Creating chickens until it hits wanted amount
                        exitwhen i3 > ChickenAmount(LoadInteger(Hash,i1,6))
                        //Defining the facing angle of each chicken to make them form a circle
                        set r1 = 6.28318 / ChickenAmount(LoadInteger(Hash,i1,6)) *  (i3 - 1) + GetRandomReal(0.00,6.28318 / ChickenAmount(LoadInteger(Hash,i1,6)))
                        set u2 = CreateUnit(GetOwningPlayer(u1),CHICKEN_ID,x1,y1,r1 * bj_RADTODEG)
                        call SetUnitX(u2,x1)
                        call SetUnitY(u2,y1)
                        set i2 = GetHandleId(u2)
                        //Enabling the chickens to fly
                        call UnitAddAbility(u2,'Amrf')
                        call UnitRemoveAbility(u2,'Amrf')
                        //Defining the coordinates for each chicken to fall on
                        set x2 = x1 + GetRandomReal(CHICKEN_RANGE_MIN,CHICKEN_RANGE_MAX) * Cos(r1)
                        set y2 = y1 + GetRandomReal(CHICKEN_RANGE_MIN,CHICKEN_RANGE_MAX) * Sin(r1)
                        //Saving the egg's height for parabola
                        call MoveLocation(l,x1,y1)
                        call SaveReal(Hash,i2,0,GetLocationZ(l))
                        //Saving target coordinates' height
                        call MoveLocation(l,x2,y2)
                        call SaveReal(Hash,i2,1,GetLocationZ(l))
                        //Saving total distance
                        call SaveReal(Hash,i2,2,SquareRoot(Pow(x2 - x1,2) + Pow(y2 - y1,2)))
                        //Saving passed distance
                        call SaveReal(Hash,i2,3,0.00)
                        //Saving spell level, inherited from the egg
                        call SaveInteger(Hash,i2,4,LoadInteger(Hash,i1,6))
                        call GroupAddUnit(CHICKENS,u2)
                    endloop
                    //After chickens are created, the egg is destroyed
                    call KillUnit(u1)
                    call GroupRemoveUnit(EGGS,u1)
                    call FlushChildHashtable(Hash,i1)
                endif
            endif
        endfunction

        private function Loop2 takes nothing returns nothing
            //Chicken loop
            set u1 = GetEnumUnit()
            set i1 = GetHandleId(u1)
            //Chicken movement
            set x1 = GetUnitX(u1) + CHICKEN_SPEED * Cos(GetUnitFacing(u1) * bj_DEGTORAD)
            set y1 = GetUnitY(u1) + CHICKEN_SPEED * Sin(GetUnitFacing(u1) * bj_DEGTORAD)
            call SetUnitX(u1,x1)
            call SetUnitY(u1,y1)
            call MoveLocation(l,x1,y1)
            call SaveReal(Hash,i1,3,LoadReal(Hash,i1,3) + CHICKEN_SPEED)
            //Setting chickens' flying height with parabola
            call SetUnitFlyHeight(u1,Parabola(LoadReal(Hash,i1,0),LoadReal(Hash,i1,1),CHICKEN_HEIGHT + RMaxBJ(LoadReal(Hash,i1,0),LoadReal(Hash,i1,1)),LoadReal(Hash,i1,2),LoadReal(Hash,i1,3)) - GetLocationZ(l),0.00)
            if LoadReal(Hash,i1,3) >= LoadReal(Hash,i1,2) then
                //Upon hitting ground,each chicken is ordered to move to a random point
                //The distance is defined by chickens' movement speed and time before they explode
                set r1 = ChickenDuration()
                set r2 = GetUnitMoveSpeed(u1) * r1 * 3
                set x1 = GetUnitX(u1) + r2 * Cos(GetRandomReal(0.00,6.28318))
                set y1 = GetUnitY(u1) + r2 * Sin(GetRandomReal(0.00,6.28318))
                call IssuePointOrder(u1,"smart",x1,y1)
                //Applying timed life to chickens to make them explode after the set time
                call UnitApplyTimedLife(u1,'BTLF',r1)
                call GroupRemoveUnit(CHICKENS,u1)
            endif
        endfunction

        private function LoopInit takes nothing returns nothing
            call ForGroup(EGGS,function Loop1)
            call ForGroup(CHICKENS,function Loop2)
        endfunction

        private function ExplosionFilter takes nothing returns boolean
            //Explosion's filter
            local boolean b = true
            set i1 = 0
            set u1 = GetTriggerUnit()
            set u2 = GetFilterUnit()
            //Checking whether filter unit is enemy or ally
            //whether the corresponding  booleans are true or false
            //and whether the filter unit is alive
            if ((DAMAGE_ENEMY == true and IsUnitEnemy(u2,GetOwningPlayer(u1))) or (DAMAGE_ALLIED == true and IsUnitAlly(u2,GetOwningPlayer(u1)))) and IsUnitType(u2, UNIT_TYPE_DEAD) == false then
                loop
                    //Looping through all invalid target types
                    //If the filter unit belongs to any,it's invalid
                    exitwhen INVALID_TARGETS[i1] == null
                    if IsUnitType(u2,INVALID_TARGETS[i1]) then
                        set b = false
                    endif
                    set i1 = i1 + 1
                endloop
                if b then
                    //If the filter unit passes all checks, it's damaged
                    call UnitDamageTarget(u1,u2,Damage(LoadInteger(Hash,GetHandleId(u1),4)),true,false,ATTACK_TYPE,DAMAGE_TYPE,WEAPON_TYPE)
                endif
            endif
            return false
        endfunction
       
        private function DestructableEnum takes nothing returns nothing
            local destructable d = GetFilterDestructable()
            //Checking destructable life and filtering out dead ones
            if GetDestructableLife(d) > 0 then
                set x1 = GetDestructableX(d)
                set y1 = GetDestructableY(d)
                //If only trees should be damaged or destroyed, a tree-check is applied
                if TREES_ONLY then
                    call IssueTargetOrder(t,"harvest",d)
                    if not(GetUnitCurrentOrder(t) == OrderId("harvest")) then
                        //In case destructable is not a tree, the function ends
                        call IssueImmediateOrder(t,"stop")
                        return
                    endif
                    call IssueImmediateOrder(t,"stop")
                endif
                if DESTROY_DESTRUCTABLES then
                    //Destroying destructable if the configurable boolean is true...
                    call KillDestructable(d)
                else
                    //...if not, it's damaged instead
                    if DESTRUCTABLE_DAMAGE < GetDestructableLife(d) then
                        call SetDestructableAnimation(d,"stand hit")
                    endif
                    call SetDestructableLife(d,GetDestructableLife(d) - DESTRUCTABLE_DAMAGE)
                endif
            endif
            set d = null
        endfunction

        private function Death takes nothing returns boolean
            set u1 = GetTriggerUnit()
            set x1 = GetUnitX(u1)
            set y1 = GetUnitY(u1)
            if GetUnitTypeId(u1) == CHICKEN_ID then
                //When a chicken dies, it creates the SFX and enumerates
                //the surrounding units and destructables for damage
                call DestroyEffect(AddSpecialEffect(CHICKEN_EXPLOSION_SFX,GetUnitX(u1),GetUnitY(u1)))
                call GroupEnumUnitsInRange(g,x1,y1,CHICKEN_EXPLOSION_AOE,Filter(function ExplosionFilter))
                //Checking if destructable annihilation or damage is ON
                if DESTROY_DESTRUCTABLES or DESTRUCTABLE_DAMAGE != 0.00 then
                    call MoveRectTo(r,x1,y1)
                    call EnumDestructablesInRect(r,null,function DestructableEnum)
                endif
                call FlushChildHashtable(Hash,GetHandleId(u1))
            elseif GetUnitTypeId(u1) == DUMMY_ID then
                //When a dummy dies,it's instantly removed to hide the dying animation
                call RemoveUnit(u1)
            endif
            return false
        endfunction

        private function Init takes nothing returns nothing
            local trigger t1 = CreateTrigger()
            local trigger t2 = CreateTrigger()
            call InvalidTargets()
            set t = CreateUnit(Player(15),DUMMY_ID,0.00,0.00,0.00)
            call ShowUnit(t,false)
            set r = Rect(-CHICKEN_EXPLOSION_AOE,-CHICKEN_EXPLOSION_AOE,CHICKEN_EXPLOSION_AOE,CHICKEN_EXPLOSION_AOE)
            set i1 = 0
            loop
                call TriggerRegisterPlayerUnitEvent(t1,Player(i1),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
                call TriggerRegisterPlayerUnitEvent(t2,Player(i1),EVENT_PLAYER_UNIT_DEATH,null)
                set i1 = i1 + 1
                exitwhen i1 == 16
            endloop
            call TriggerAddCondition(t1,Condition(function Cast))
            call TriggerAddCondition(t2,Condition(function Death))
            call TimerStart(CreateTimer(),0.03,true,function LoopInit)
            set t1 = null
            set t2 = null
        endfunction

    endscope
     
     

    Attached Files:

    Last edited: Apr 1, 2011
Thread Status:
Not open for further replies.