Spell Contest #4 | Submission Thread

Status
Not open for further replies.

Romek

Super Moderator
Reaction score
963
SpellContest4.png

Submissions


  • One post per member here
  • Only post if you're submitting
  • Feel free to edit your submission any amount of times before the deadline.
  • Also feel free to make your posts look nice and detailed. No big screenshots though...
  • Make sure to use the edit button when editing submissions

Main Contest Thread
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
Here you go guys, first submission by me this time!

Split-Image Slice
This skill is a tribute to the awesome SNES game Seiken Densetsu 3.

Its my own mix between an assassin-like heroes final skill and the old cheezy blademaster of wc3.

what is special about this skill?

The damage dealt depends on the casting heroes attack power.
the skill is made with GUI 97% and is completely MUI as well.

and now a personal note to all of you wise-asses who keep saying "GUI SPELL NEED HASHTABLES TO BE MUI !!!!11!!1oneoneone"
This spell does not need a hashtable at all and i have intended it to be this way.
maybe some simple-minded people can realize now that there was GUI map making before hashtables have been implemented.

the skill is highly configurable, i've added some comments and a big block of global variables to alter the skills effects.
however, i havent concentrated too much on this aspect, there are still many individual bonus effects you might want to integrate if you are gonna implement this skill in your game. the possibilities are endless (or at least almost).

there is also a little flaw of this skill i cannot remove which i personally dislike alot, if you wanna know more about it download the map and read the comments.

Good luck to all participants! i want to see some awesome skills in this contest!

Update:
Added another configuration whether shadow images will disappear when the cast is finished, the caster is interupted or killed.
added some test triggers like a preload and visibility over the whole map as well as some more enemys.

Another Update:
I got alot of comments on feedback, especially about that little flaw i mentioned.
i have altered the demo map again, the shadow images will NOT use any supply anymore, fixed that one after i figured out there is a trigger action for this available (i really couldnt remember anymore).
however, the shadow images still show up as a hero icon on the left for the duration of the spell if the caster does so as well.

if romek permits i will upload an alternate version of this (which will not be graded by the jury) which uses dummy units for the shadow images in order to get rid of the last flaw as well (though the damage output will differ then)
 

Attachments

  • SplitImageSlice by Accname [Original].w3x
    44.4 KB · Views: 250

Dinowc

don't expect anything, prepare for everything
Reaction score
223
here's my submission (edited)

icons_11054_btn.jpg
Web Strike
Spits two sticky silks in a cone in front of the broodmother and snatches enemies who get hit with it. The enemies are immobilized and the broodmother can carry them with her for some duration. She can pull the units towards her at any time and biting them, infecting the victims with parasites for 8 seconds while healing the broodmother.

Level 1 - 600 cast range, units are immobilized for up to 5 seconds, infection deals 15 dps, heals by 5% of target's max hp.
Level 2 - 675 cast range, units are immobilized for up to 6 seconds, infection deals 25 dps, heals by 6% of target's max hp.
Level 3 - 750 cast range, units are immobilized for up to 7 seconds, infection deals 35 dps, heals by 7% of target's max hp.
Level 4 - 825 cast range, units are immobilized for up to 8 seconds, infection deals 45 dps, heals by 8% of target's max hp.
it's pretty much done, just hoping if someone could point me if they encounter any bugs

ss1se.jpg


ss2uz.jpg
 

HydraRancher

Truth begins in lies
Reaction score
197
Spider Mines

Lacks originality, but nonetheless, a good homage to Starcraft.

Equipped with siege tanks and vultures, overthrow the enemy Zerg Sunken Colony and Hydralisks using a combination of wit and skill.​


icons_12416_btn.jpg
Spider Mines

Description: The Vultures posses three mines in their arsenal, deadly cloaked spider mines to be exact. These sinister creepers jump out from the ground and attack nearby enemies. Though you can disarm one with heavy fire power, get too close, and you may find your head blown off.

Engineers also have this ability. Their stocks are unlimited, however they have a fifteen second cooldown.


I kinda went overboard with imports. Although this may not fit the rules, I had fun making it. :)

Screenshots.

faq5o4.jpg







-Side note, my Forum ID originates from the HydraRanchers, a popular Starcraft Broodwar game similar to footy involving Hydralisks.

Credits to all icons and models used.


Updates

Update v1.1 : Ironed out a few bugs, added a phoenix fire particle (not on screenshots).

Update v1.2 : Revamped the terrain, added customizability.

Update v2.0 : Added new unit - Engineer. Activates mines manually. Fixed a few bugs.

 

Attachments

  • Spider Mines v2.0.w3x
    988.9 KB · Views: 276

emjlr3

Change can be a good thing
Reaction score
395
Final Fantasy 7 - Omnislash
An attempt at a direct port of Cloud Strife's final limit break, from FF7 to WC3.
Acquired as a reward on the Battle Square, Omnislash provides the ultimate in Limit Break weaponry. Random enemies in the area are assailed through an onslaught of viscious blows, concluding with one final mighty strike that knocks the unit back, dazed and confused.

Level 1 - 25 damage per slash, 10 slashes total.
Level 2 - 50 damage per slash, 12 slashes total.
Level 3 - 75 damage per slash, 15 slashes total.

Cooldown - 15s
Target Range - 750/850/950
Mana Cost - 55/65/75

Spell Code
JASS:
scope FF7Omnislash initializer Init
//*********************************************************************
//* FF7 Omnislash v1.00
//* by: emjlr3
//* ----------
//*
//* Requirements:
//*     *An instant cast ability
//*     *The Omnislash(Cast SFX) dummy unit
//*     *UnitAlive native, found in the custom script section of this map
//*     *SoulTornado model, set as the Omnislash(Cast SFX) unit's model
//*         This imported model requires the texture "Textures\Tornado2b.blp"
//*     *TimerUtils library
//*         <a href="http://www.wc3c.net/showthread.php?t=101322" target="_blank" class="link link--external" rel="nofollow ugc noopener">http://www.wc3c.net/showthread.php?t=101322</a>
//*     *A copy of this trigger
//*     *If using the PREVENT option, the SimError library is required
//*         <a href="http://www.wc3c.net/showthread.php?t=101260" target="_blank" class="link link--external" rel="nofollow ugc noopener">http://www.wc3c.net/showthread.php?t=101260</a>
//*     *Although not required, the BoundSentinel library is recommended
//*         <a href="http://www.wc3c.net/showthread.php?t=102576" target="_blank" class="link link--external" rel="nofollow ugc noopener">http://www.wc3c.net/showthread.php?t=102576</a>
//*
//* (requires vJass)   More abilities at <a href="http://www.thehelper.net/forums" class="link link--internal">http://www.thehelper.net/forums</a>
//*
//*     Credits:
//*     *Vexorian for his TimerUils and SimError libraries
//*     *JetFangInferno for the SoulTornado model
//*
//* Important:
//*     *There is an instance limit of 1638.  If this limitation becomes
//*      a problem, let me know.
//*     *SFX strings can be set to &quot;&quot; for no effect.
//*     *If you decide to use the PREVENT option, you must have the SimError
//*      library, otherwise you may receive syntax errors when saving.
//*     *Incase you hadn&#039;t guessed it, the same unit cannot cast this
//*      ability twice at the same time.  For one, it&#039;s physically impossible,
//*      and for two, it would bug terribly, so best not to even try.
//*
//********************************************************************

globals
    // Configurable constants
    private constant integer    ABIL        = &#039;A000&#039; // Omnislash ability rawcode
    private constant attacktype ATTACKTYPE  = ATTACK_TYPE_HERO // Slash damage attacktype
    private constant integer    CASTUNIT1   = &#039;n001&#039; // Omnislash(Cast SFX) unit rawcode
    private constant real       CASTUNIT1D  = 1.5 // Omnislash(Cast SFX) unit timed life
    private constant real       CASTUNIT1S  = 3. // Omnislash(Cast SFX) unit real scale
    private constant real       CAST2L      = 1. // Duration of CASTSFX2
    private constant string     CASTSFX1    = &quot;Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl&quot; // First effect during cast
    private constant string     CASTSFX1A   = &quot;origin&quot; // CASTSFX1 attachment point
    private constant string     CASTSFX2    = &quot;war3mapImported\\SoulTornado.mdx&quot; // Second effect during cast
    private constant string     CASTSFX2A   = &quot;origin&quot; // CASTSFX2 attachment point
    private constant string     CASTSFX3    = &quot;Abilities\\Spells\\Other\\Incinerate\\IncinerateBuff.mdl&quot; // Effect on weapon during cast
    private constant string     CASTSFX3A   = &quot;weapon&quot; // CASTSFX2 attachment point
    private constant integer    CHAID       = 4 // Initial spell cast channel animation id
    private constant real       CHAS        = .7 // Caster time scale during channel animation (CHAID)
    private constant damagetype DAMAGETYPE  = DAMAGE_TYPE_NORMAL // Slash damage damagetype
    private constant boolean    DESELECT    = true // Deselect caster for owning player throughout spell
    private constant real       EFSFHR      = 900. // Fly height decrease rate during final slash hit 
    private constant real       EFSTO       = .5 // Time after final slash pause until the hit actually takes place
    private constant real       EFSTS       = 1. // Caster time scale during final slash hit
    private constant string     ENDA        = &quot;stand ready&quot; // End of spell queue animation
    private constant real       ENDCTS      = 1. // Caster time scale after spell is over
    private constant string     ENDSFX1     = &quot;Abilities\\Spells\\Other\\Volcano\\VolcanoDeath.mdl&quot; // Effect on target after last slash
    private constant string     ENDSFX2     = &quot;Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl&quot; // Effect on target after last slash
    private constant string     ENDSFXAP    = &quot;origin&quot; // Attachment point for ENDSFX1/2
    private constant boolean    FORCEATT    = false // Force attack target after final slash
    private constant real       FSFH        = 400. // Fly height to reach during final slash
    private constant real       FSFHR       = 800. // Fly height increase rate during final slash
    private constant integer    FSAID       = 3 // Final slash animation id
    private constant real       FSATS       = .7 // Caster time scale during final slash animation (FSAID)
    private constant real       FSMHSTO     = .5 // Time to pause at max height during final slash
    private constant real       FSMHTO      = .6 // Time before reaching final slash max fly height
    private constant boolean    GM          = true // Make caster invulnerable while slashing
    private constant string     HANDSFX     = &quot;Abilities\\Spells\\NightElf\\SpiritOfVengeance\\SpiritOfVengeanceBirthMissile.mdl&quot; // Effect on hands during slashes
    private constant string     HITSFX      = &quot;Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl&quot; // Effect on target after a slash  
    private constant string     HITSFXA     = &quot;chest&quot; // HITSFX attachment point
    private constant boolean    PRELOAD     = true // Preload Storm Grow Form ability
    private constant boolean    PREVENT     = true // Prevent casts when no available targets
    private constant string     PREVENTMSG  = &quot;No available targets.&quot; // Message to display when preventing a cast
    private constant integer    RUNAID      = 6 // Run phase animation id
    private constant real       RUNDBP      = 125. // Distance between caster and target required for run phase to end
    private constant real       RUNTS       = 2. // Run phase caster time scale
    private constant integer    SLASHFAID   = 3 // First slash animation id    
    private constant real       SLASHTI     = .40 // Periodic timer interval during slashes
    private constant real       SLASHTS     = 3. // Caster time scale during slashes
    private constant string     SLIDESFX1   = &quot;Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl&quot; // Effect on target during slide
    private constant string     SLIDESFX2   = &quot;Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl&quot; // Effect on target during slide
    private constant string     SLIDESFXAP  = &quot;origin&quot; // Attachment point for SLIDESFX1/2
    private constant integer    STCRID      = &#039;Arav&#039; // Storm Crow Form ability rawcode
    private constant real       TIMEOUT     = .04 // Periodic timer interval during run, final slash movement, and slide
    private constant string     WPNSFX1     = &quot;Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl&quot; // Effect on weapon during slashes
    private constant string     WPNSFX2     = &quot;Abilities\\Spells\\Items\\OrbVenom\\OrbVenomMissile.mdl&quot; // Effect on weapon during slashes
    private constant string     WPNSFXAP    = &quot;weapon&quot; // Attachment point for WPNSFX1/2
    
    // Don&#039;t touch these
    private boolexpr            BOOL
    private group               GROUP     
    private constant integer    FRAMERATE   = R2I(1./TIMEOUT)
    private integer             I
    private constant real       REALRUNDBP  = RUNDBP*RUNDBP     
    private integer array       SLASHIDS   
    private integer             SLASHIDT        
    private unit                T
    private group               TGROUP      = CreateGroup()
    private trigger             TRIGGER   
endglobals

// Omnislash configurable functions                          
private function Damage takes integer level returns real
    return level*25. // Damage per slash
endfunction
private function Radius takes integer level returns real
    return 650.+level*100. // Radius to check for targets
endfunction
private function RunSpeed takes integer level returns real
    return 875. // Movement rate during run phase
endfunction
private function SetupSlashId takes nothing returns nothing
    set SLASHIDT    = 3 // Total possible random slash animation ids
    
    set SLASHIDS[1] = 2 // Setup possible random slash animation ids
    set SLASHIDS[2] = 3
    set SLASHIDS[3] = 8
endfunction  
private function Slashes takes integer level returns integer
    if level==1 then // Total slashes
        return 10
    elseif level==2 then
        return 12
    else
        return 15
    endif
endfunction
private function Targets takes unit target, unit caster returns boolean
    return true // Custom target check
endfunction

// Slide configurable functions
private function BrakeFactor takes integer level returns real
    return .95 // Deceleration rate during slide
endfunction
private function BreakPoint takes integer level returns real
    return 12.5 // Speed at which the slide stops
endfunction
private function SDamage takes integer level returns real
    return level*25. // Damage during slide
endfunction
private function SlideSpeed takes integer level returns real
    return 500. // Initial slide speed
endfunction

//===========================================================\\
private struct slide
    timer t
    unit caster
    unit target
    real cos
    real sin
    real speed
    real break
    real brakes
    real damage
endstruct
private function Slide takes nothing returns nothing
    local slide d=GetTimerData(GetExpiredTimer())    
    
    // Slide has been completed
    if d.speed&lt;=d.break then
        call ReleaseTimer(d.t)
        call d.destroy()
    else
        // Update position with effects and such
        call SetUnitPosition(d.target,GetUnitX(d.target)+d.speed*d.cos,GetUnitY(d.target)+d.speed*d.sin)
        call DestroyEffect(AddSpecialEffectTarget(SLIDESFX1,d.target,SLIDESFXAP))
        call DestroyEffect(AddSpecialEffectTarget(SLIDESFX2,d.target,SLIDESFXAP))
        call UnitDamageTarget(d.caster,d.target,d.damage,false,false,ATTACKTYPE,DAMAGETYPE,null)
    endif
    // Apply the brakes
    set d.speed=d.speed*d.brakes
endfunction
private struct omni
    timer t
    unit caster
    unit target=null
    unit dum
    player play
    integer level
    integer mode=0
    integer count=0
    integer slashes
    real realrunspeed
    real damage
    real dist
    real cos
    real sin
    real time=0.
    real radius
    effect array sfx[5]
      
    method onDestroy takes nothing returns nothing
        local slide d
        local real ang
        local integer i=0
        local real speed
        
        // Make everything normal again
        static if DESELECT then
            call GroupRemoveUnit(GROUP,.caster)
            if GetLocalPlayer()==.play then
                call SelectUnit(.caster,true)
            endif
        endif
        call PauseUnit(.caster,false)
        call SetUnitPathing(.caster,true)
        static if GM then
            call SetUnitInvulnerable(.caster,false)
        endif
        call SetUnitTimeScale(.caster,ENDCTS)
        call ReleaseTimer(.t)        
        call QueueUnitAnimation(.caster,ENDA)
        call DestroyEffect(.sfx[0])
        call DestroyEffect(.sfx[1])
        call DestroyEffect(.sfx[2])
        call DestroyEffect(.sfx[3])
        call DestroyEffect(.sfx[4])
        // Double check for required unit states, makes sure spell wasn&#039;t ended prematurely
        if UnitAlive(.target) and UnitAlive(.caster) then  
            static if FORCEATT then
                call IssueTargetOrder(.caster,&quot;attack&quot;,.target)
            endif
            call DestroyEffect(AddSpecialEffectTarget(ENDSFX1,.target,ENDSFXAP))
            call DestroyEffect(AddSpecialEffectTarget(ENDSFX2,.target,ENDSFXAP))
            call UnitDamageTarget(.caster,.target,.damage,false,false,ATTACKTYPE,DAMAGETYPE,null)
            // Create and load slide data
            set d=slide.create()
            set d.caster=.caster
            set d.target=.target
            set ang=Atan2(GetUnitY(.target)-GetUnitY(.caster),GetUnitX(.target)-GetUnitX(.caster))
            set d.cos=Cos(ang)
            set d.sin=Sin(ang)
            // Again, more silly arithmetic to make things &quot;easier&quot;
            set d.speed=SlideSpeed(.level)/FRAMERATE
            set d.break=BreakPoint(.level)/FRAMERATE
            set d.brakes=BrakeFactor(.level)
            set d.damage=SDamage(.level)
            set d.t=NewTimer()
            call SetTimerData(d.t,d)
            call TimerStart(d.t,TIMEOUT,true,function Slide)
            
            // Blunt force alternative to a finite sum calculation
            set speed=d.speed
            loop
                set i=i+1
                exitwhen speed&lt;=d.break
                set speed=speed*d.brakes
            endloop
            set d.damage=d.damage/i
        endif    
        // Who knows if the user had their configs. right.  Spells over, so lets make sure &quot;everything&quot; is back to normal
        call SetUnitFlyHeight(.caster,GetUnitDefaultFlyHeight(.caster),0.)
    endmethod
endstruct

private function GetTargets takes nothing returns boolean
    local omni d=I
    local unit T=GetFilterUnit()
    
    return UnitAlive(T) and IsUnitEnemy(T,d.play) and IsUnitType(T,UNIT_TYPE_STRUCTURE)==false and Targets(T,d.caster)
endfunction
private function Effects takes nothing returns nothing
    local omni d=GetTimerData(GetExpiredTimer())
    local real angle
    local real xcast=GetUnitX(d.caster)
    local real xtarg=GetUnitX(d.target)
    local real ycast=GetUnitY(d.caster)
    local real ytarg=GetUnitY(d.target)
    local real dist
    local real r
    local integer i
    local integer j=1
    
    // Initial animation fix
    if d.mode==0 then      
        // Start channel animation
        if d.count==0 then
            call SetUnitTimeScale(d.caster,CHAS)
            call SetUnitAnimationByIndex(d.caster,CHAID)  
            // Silly user
            debug if CASTUNIT1D&lt;.01 then
                debug call BJDebugMsg(&quot;We have an error.  Set your CASTUNIT1D value to greater then .01.&quot;)
            debug endif
            // So our time remains as the user desires
            call PauseTimer(d.t)
            call TimerStart(d.t,CASTUNIT1D-.01,false,function Effects)
            set d.count=1
        // Remove initial effect, wait until end of channel
        elseif d.count==1 then
            call ShowUnit(d.dum,false)
            call RemoveUnit(d.dum) // Buggy, effect would not remove with a unit timed life function call
            call SetUnitTimeScale(d.caster,0.)
            call PauseTimer(d.t)
            call TimerStart(d.t,CAST2L,false,function Effects)
            set d.mode=1
        endif
    // Check distance for run up
    elseif d.mode==1 then
        // Make sure we are still kickin&#039;, otherwise gg nub
        if not UnitAlive(d.caster) then
            call d.destroy()
            return
        else
            // Godmode for the rest of the spell
            static if GM then
                call SetUnitInvulnerable(d.caster,true)
            endif
        endif
        // If &gt;XXX distance between caster and target, start run
        if (xtarg-xcast)*(xtarg-xcast)+(ytarg-ycast)*(ytarg-ycast)&gt;REALRUNDBP then        
            call SetUnitTimeScale(d.caster,RUNTS)
            call SetUnitAnimationByIndex(d.caster,RUNAID)            
            set d.mode=2
            // People bitch about wanting distance/sec rather then distance/interval, so I must add in extra arithmetic to sastify this need
            set d.realrunspeed=RunSpeed(d.level)/FRAMERATE
            // Start run timer
            call PauseTimer(d.t)
            call TimerStart(d.t,TIMEOUT,true,function Effects)
        else
            set d.mode=3
            // Start slashes immediately
            call PauseTimer(d.t)
            call TimerStart(d.t,0.0,false,function Effects)
        endif        
        call DestroyEffect(d.sfx[0])
        call DestroyEffect(d.sfx[1])
    // Run caster toward target quickly
    elseif d.mode==2 then 
        // If the target is dead, no need to keep running
        if not UnitAlive(d.target) then
            call d.destroy()
            return
        endif
        set angle=Atan2(ytarg-ycast, xtarg-xcast)        
        set xcast=xcast+d.realrunspeed*Cos(angle)
        set ycast=ycast+d.realrunspeed*Sin(angle)
        call SetUnitX(d.caster,xcast)
        call SetUnitY(d.caster,ycast)
        call SetUnitFacing(d.caster,angle*bj_RADTODEG)
        // If &lt;XXX distance between caster and target, end run
        if (xtarg-xcast)*(xtarg-xcast)+(ytarg-ycast)*(ytarg-ycast)&lt;=REALRUNDBP then
            set d.mode=3
            set d.count=0
            call PauseTimer(d.t)
            // Start slashes immediately
            call TimerStart(d.t,0.0,false,function Effects)
        endif
    // Do slashes
    elseif d.mode==3 then
        // First slash
        if d.count==0 then
            call PauseTimer(d.t)
            call TimerStart(d.t,SLASHTI,true,function Effects)
            call SetUnitTimeScale(d.caster,SLASHTS)
            call SetUnitAnimationByIndex(d.caster,SLASHFAID)
            set angle=Atan2(ycast-ytarg, xcast-xtarg)
            set d.dist=SquareRoot((xtarg-xcast)*(xtarg-xcast)+(ytarg-ycast)*(ytarg-ycast))
            set d.cos=d.dist*Cos(angle)
            set d.sin=d.dist*Sin(angle)
            // Pretty
            set d.sfx[0]=AddSpecialEffectTarget(HANDSFX,d.caster,&quot;hand, left&quot;)
            set d.sfx[1]=AddSpecialEffectTarget(HANDSFX,d.caster,&quot;hand, right&quot;)
            set d.sfx[2]=AddSpecialEffectTarget(WPNSFX1,d.caster,WPNSFXAP)
            set d.sfx[3]=AddSpecialEffectTarget(WPNSFX2,d.caster,WPNSFXAP)
        // Every slash there after
        else
            set I=d
            call GroupClear(TGROUP)
            call GroupEnumUnitsInRange(TGROUP,GetUnitX(d.caster),GetUnitY(d.caster),d.radius,BOOL)
            set d.target=GroupPickRandomUnit(TGROUP)
            // No available targets
            if d.target==null then
                call d.destroy()
                return
            endif
            set ytarg=GetUnitY(d.target)
            set xtarg=GetUnitX(d.target)
            call SetUnitX(d.caster,xtarg+d.cos)
            call SetUnitY(d.caster,ytarg+d.sin)
            call SetUnitFacing(d.caster,Atan2(ytarg-ycast,xtarg-xcast)*bj_RADTODEG)
            // So the user can specify various slash animations throughout the spell
            set i=GetRandomInt(1,SLASHIDT)
            loop                
                exitwhen j==i
                set j=j+1
                debug if j&gt;SLASHIDT
                    debug call BJDebugMsg(&quot;We have an error.  Somehow you mucked up the available slash animations.  Check your configurables.&quot;)
                    debug exitwhen true // Had this w/o a debug for a while, and was wondering why I saw the same damn animation so often....
                debug endif
            endloop
            call SetUnitAnimationByIndex(d.caster,SLASHIDS[j])
        endif
        // Damage to target and slash effect
        call UnitDamageTarget(d.caster,d.target,d.damage,false,false,ATTACKTYPE,DAMAGETYPE,null)
        call DestroyEffect(AddSpecialEffectTarget(HITSFX,d.target,HITSFXA))
        
        set d.count=d.count+1   
        // Slashes to date are total-1, now we can do the final cinematic slash
        if d.count&gt;d.slashes then
            set d.mode=4
            set d.count=0
            call PauseTimer(d.t)
            set I=d
            call GroupClear(TGROUP)
            call GroupEnumUnitsInRange(TGROUP,GetUnitX(d.caster),GetUnitY(d.caster),d.radius,BOOL)
            set d.target=GroupPickRandomUnit(TGROUP)
            // No available targets
            if d.target==null then
                call d.destroy()
                return
            endif
            // Start final slash
            call PauseTimer(d.t)
            call TimerStart(d.t,SLASHTI,false,function Effects)
        endif
    // Do final slash
    elseif d.mode==4 then
        // This is the &quot;up&quot; phase, travel up and animate accordingly
        if d.count==0 then
            call SetUnitFacing(d.caster,Atan2(ytarg-ycast,xtarg-xcast)*bj_RADTODEG)
            call SetUnitAnimationByIndex(d.caster,FSAID)
            call UnitAddAbility(d.caster,STCRID)
            call UnitRemoveAbility(d.caster,STCRID)
            call SetUnitFlyHeight(d.caster,FSFH,FSFHR)
            call SetUnitTimeScale(d.caster,FSATS)
            set d.sfx[4]=AddSpecialEffectTarget(CASTSFX3,d.caster,CASTSFX3A)
            call PauseTimer(d.t)
            call TimerStart(d.t,FSMHTO,false,function Effects)
            set d.count=1
        // This is the pause phase, now that we&#039;ve reached &quot;up&quot;, hang out for a bit
        elseif d.count==1 then
            call SetUnitTimeScale(d.caster,0.)
            call PauseTimer(d.t)
            call TimerStart(d.t,FSMHSTO,false,function Effects)
            set d.count=2
        // This is the &quot;down&quot; phase, since our anti-gravity boots have worn off, head back to ground level
        elseif d.count==2 then
            call SetUnitFlyHeight(d.caster,GetUnitDefaultFlyHeight(d.caster),EFSFHR)
            call SetUnitTimeScale(d.caster,EFSTS)
            set d.mode=5
            // Begin &quot;get moving to the target&quot; timer
            call PauseTimer(d.t)
            call TimerStart(d.t,TIMEOUT,true,function Effects)
        endif
    // Make the &quot;down&quot; phase look good
    elseif d.mode==5 then   
        // If the target moves during the final slash, the caster must then move back to the target, preferably making it look good
        // If the target is dead, our hero winds up bouncing to the map center, which we don&#039;t want
        // However, we still want to finish the animation, otherwise slashing a dead target may look even goofier
        if not UnitAlive(d.target) then
            set xtarg=GetUnitX(d.caster)
            set ytarg=GetUnitY(d.caster)
        endif
        set dist=(xtarg-xcast)*(xtarg-xcast)+(ytarg-ycast)*(ytarg-ycast)
        // Some fancy maths so the hero moves linearly to the target throughout the entire EFSTO time
        if dist&gt;REALRUNDBP then
            set r=(EFSTO-d.time)/TIMEOUT
            set dist=(SquareRoot(dist)-d.dist)/r
            set angle=Atan2(ytarg-ycast,xtarg-xcast)
            call SetUnitX(d.caster,xcast+dist*Cos(angle))
            call SetUnitY(d.caster,ycast+dist*Sin(angle))
            call SetUnitFacing(d.caster,angle*bj_RADTODEG)
        endif
        set d.time=d.time+TIMEOUT
        // End all be all
        if d.time&gt;=EFSTO then
            call d.destroy()
        endif
    endif
endfunction
private function Actions takes nothing returns nothing
    local omni d=omni.create()
    
    set d.caster=GetTriggerUnit()
    set d.play=GetOwningPlayer(d.caster)
    set d.level=GetUnitAbilityLevel(d.caster,ABIL)
    set d.radius=Radius(d.level)
    set I=d
    call GroupClear(TGROUP)
    call GroupEnumUnitsInRange(TGROUP,GetUnitX(d.caster),GetUnitY(d.caster),d.radius,BOOL)
    set d.target=GroupPickRandomUnit(TGROUP) // FirstOfGroup isn&#039;t exactly random...unfortunately
    // Had I used FirstOfGroup throughout the spell, the same target may have been selected the entire time
    // No available targets, just incase in the time between the cast event and the effect event, they all perish
    if d.target==null then
        call d.destroy()
        return
    endif
    // So as to know when to start the cinematic slash
    set d.slashes=Slashes(d.level)-1
    set d.damage=Damage(d.level)
    set d.t=NewTimer()
    call SetTimerData(d.t,d)
    call TimerStart(d.t,.01,false,function Effects) // Fix first animation bug
    // For some reason or another, I could not get my first animation to play w/o first waiting a brief moment
    // This accounts for that, and shouldn&#039;t be noticeable in game
    // The blink of an eye is ~.2s
    
    call PauseUnit(d.caster,true)
    call SetUnitPathing(d.caster,false)
    call DestroyEffect(AddSpecialEffectTarget(CASTSFX1,d.caster,CASTSFX1A))
    set d.sfx[0]=AddSpecialEffectTarget(CASTSFX2,d.caster,CASTSFX2A)
    set d.sfx[1]=AddSpecialEffectTarget(CASTSFX3,d.caster,CASTSFX3A)
    // This was the best effect I could find to mimic the original, just need to make it a bit larger
    set d.dum=CreateUnit(d.play,CASTUNIT1,0.,0.,0.)
    call SetUnitPathing(d.dum,false)
    // Sometimes they won&#039;t place exactly where you want until you give them no pathing
    call SetUnitX(d.dum,GetUnitX(d.caster))
    call SetUnitY(d.dum,GetUnitY(d.caster))
    call SetUnitScale(d.dum,CASTUNIT1S,CASTUNIT1S,CASTUNIT1S)
    
    // Deselect caster for player and add it to deselection trigger group
    static if DESELECT then
        call GroupAddUnit(GROUP,d.caster)
        if GetLocalPlayer()==d.play then
            call SelectUnit(d.caster,false)
        endif
    endif
endfunction
private function Conditions takes nothing returns boolean
    local omni d
    if GetSpellAbilityId()==ABIL then
        if PREVENT and GetTriggerEventId()==EVENT_PLAYER_UNIT_SPELL_CAST then
            set d=omni.create()
            set d.caster=GetTriggerUnit()
            set d.play=GetOwningPlayer(d.caster)
            set d.level=GetUnitAbilityLevel(d.caster,ABIL)
            set d.radius=Radius(d.level)
            set I=d
            call GroupClear(TGROUP)
            call GroupEnumUnitsInRange(TGROUP,GetUnitX(d.caster),GetUnitY(d.caster),d.radius,BOOL)
            set d.target=FirstOfGroup(TGROUP)
            // No available targets
            if d.target==null then
                call PauseUnit(d.caster,true)
                call IssueImmediateOrder(d.caster,&quot;stop&quot;)
                call PauseUnit(d.caster,false)
                // You never know....
                static if LIBRARY_SimError then
                    call SimError(d.play,PREVENTMSG)
                endif
            endif
            set d.target=null
            call d.destroy()
            return false
        elseif GetTriggerEventId()==EVENT_PLAYER_UNIT_SPELL_EFFECT then
            call Actions()
        endif
    endif
    return false
endfunction
private function Selected takes nothing returns boolean
    // I know its a little slow to fire, but who needs to select the hero when he can&#039;t even be controlled?
    if IsUnitInGroup(GetTriggerUnit(),GROUP) then
        if GetTriggerPlayer()==GetOwningPlayer(GetTriggerUnit()) then
            if GetLocalPlayer()==GetOwningPlayer(GetTriggerUnit()) then
                call SelectUnit(GetTriggerUnit(),false)
            endif
        endif
    endif
    return false
endfunction
private function Init takes nothing returns nothing
    local trigger t=CreateTrigger()
    local unit u
    local integer index=0
    
    // Selection detection
    static if DESELECT then
        set TRIGGER=CreateTrigger()
        set GROUP=CreateGroup()
        call TriggerAddCondition(TRIGGER,Condition(function Selected))
    endif
    loop
        static if DESELECT then
            call TriggerRegisterPlayerUnitEvent(TRIGGER,Player(index),EVENT_PLAYER_UNIT_SELECTED,null)
        endif
        static if PREVENT then
            call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
        endif
        call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_CAST,null)
        set index=index+1
        exitwhen index==bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition(t,Condition(function Conditions))
    // Condition function for target selection
    set BOOL=Condition(function GetTargets)
    
    // Store users slash animations
    call SetupSlashId()
    
    // Preload storm crow form
    static if PRELOAD then
        set u=CreateUnit(Player(15),CASTUNIT1,0.,0.,0.)
        call UnitAddAbility(u,STCRID)
        call UnitApplyTimedLife(u,&#039;BTLF&#039;,.001)
        call ShowUnit(u,false)
        set u=null
    endif
endfunction

endscope

Configuration Instructions
JASS:
// The following is a detailed description of the configuration options provided in the FF7 Omnislash spell.
// I realize that for the most part, the global&#039;s names seem pretty random.  Contrary to popular believe, there actually is a naming scheme.  It&#039;s not always logical or consistent, but it exists nonetheless.

// GLOBALS:

//	Integers
//	ABIL		- Rawcode of the instant cast hero ability, which is Omnislash in this map.
//	CASTUNIT1	- Rawcode of the Omnislash(Cast SFX) unit, which is used to create the first of two &quot;channel&quot; effects on the caster prior to beginning to spell.  In this map it is the large red effect, which is sized up a bit and placed at the casters origin.
//	CHAID		- Animation id for your caster to use during this initial channel phase.
//	FSAID		- Animation id for your caster to use during the final slash, both as the unit ascends into the air, and which is finished as it descends to the target for the final slash.	
//	RUNAID	    - Animation id for your caster to use during the run up phase.  This occurs following channeling, if the target is a large distance away from the caster.  The caster will quickly move towards the target, while playing this animation id.
//	SLASHFAID	- Animation id for your caster to use as its first slash animation.  This is provide just for the hell of it.
//	STCRID		- This is the rawcode of the Storm Crow Form ability.  If you have not made changes to this ability in your map, this value doesn’t need to be updated, and should work fine.  The Storm Crow Form ability is used to allow us to manipulate the fly height of the caster during the final slash.
//	SLASHIDT	- This is the total possible random slash animation ids to use during the slashing phase.  In the case of this model (blademaster), I use all three attack animation ids, which are 2, 3 and 8.  This value is actually located in the Omnislash configurable functions section, in the function SetupSlashId.  These are chosen at random before each slash begins.
//	SLASHIDS	- These are the actual slash animation ids you will want to used.  For instance, say you had two total animations you wanted to play, at id 2 and 4.  Set SLASHIDS[1]=2 and set SLASHIDS[2]=4, and then you can entirely remove SLASHIDS[3], since you don’t need a third animation.

//	Reals
//	CASTUNIT1D	- The time you want the CASTUNIT1 present in the game, rather, how long you want its effect to last in seconds.  This also determines when the caster pauses during the channel time.  After this duration the caster will pause for a time, as discussed later.
//	CASTUNIT1S	- How big you want the scale of this effect.  The larger the number the bigger the effect.
//	CAST2L		- The duration of CASTSFX2.  CASTSFX2 is added at the beginning of the spell, and will last this long after the CASTUNIT1D is removed.  So if CASTUNIT1D is 1., and CAST2L is 1., the first effect will last one second, and this effect will last two.  This also determines when the “channel” phase will end, after which the caster begins slashing (or running to the target then slashing).
//	CHAS		- Time scale of the caster during the channel phase, up until the point when it pauses.
//	EFSFHR		- The rate at which the casters fly height increases during the final slash.  This final slash is broken up into three phases.  During the first, the caster rises upwards, playing its final attack animation.  After a duration, the caster pauses (preferably at is apex), and after a second duration, the caster returns to the ground, finishing its attack animation from where it left off when it was paused.
//	EFSTO		- This is the time from when the caster begins to descend during the final slash until you, as the user, think the final slash attack should actually register as hitting the target.
//	EFSTS		- This is the time scale for the caster during it’s descend phase of the final slash.
//	ENDCTS		- Time scale to return the caster to after the spell has completed.
//	FSFH		- Fly height to reach during the ascend phase of the final slash.  I simply set the casters fly height to this new height, using the rate set above (EFSFHR), this is not timed in anyway.  Therefore, as the user, you must use values that will have the caster reach this height in a time frame reasonable for your final slash desires.
//	FSFHR		- Rate at which the casters fly height should increase during the final slash.  This is units/second.
//	FSATS		- Caster time scale during the ascend phase of the final slash.  You will want to use a value that reaches the half way point in the final slash animation as the caster reaches the max height of this final slash cinematic.
//	FSMHSTO	    - Duration in seconds that you want the caster to pause at the apex of its final slash height.  At this time I set the casters time scale to zero, and then set it to EFSTS once the descend phase begins.
//	FSMHTO	    - Duration in seconds after the ascend phase of the final slash begins that you want the casters pause to begin.  Again, if you set the ascend fly height and rate of increase to values that don’t closely match this desired time, it will look strange.
//	RUNDBP	    - Distance required before slashes will begin on the first target.  If you cast the spell, and are further away then this distance from the randomly selected first target, you will run up to the target, to a distance at or just under this value.  This new distance from the target will be used for the rest of the spell as the desired distance from target for all slashes.
//	RUNTS		- Time scale for the caster during the run up to the target phase.
//	TIMEOUT	    - Periodic timer interval, to be used for all periodic events, which include running, sliding, and the final slash caster coordinates updating.

//	Strings
//	CASTSFX1	- Model for the first effect which is created and immediately destroyed right after casting.
//	CASTSFX1A	- Attachment point for this effect.
//	CASTSFX2	- Model for the effect that is created on the caster right after casting and remains for the duration of the channel phase.
//	CASTSFX2A	- Attachment point for this effect.
//	CASTSFX3	- Model for the effect created on the casters weapon during the channel phase.  This remains for the entire duration of the channel phase.  During this phase the caster is paused in WC3 and can no longer be issued commands.  The caster remains paused for the duration of the spell.  This same model is used again during the final slash cinematic.
//	CASTSFX3A	- Attachment point for this model.  It’s designed to be the weapon, but can be wherever you want.
//	ENDA        - Animation to queue at the end of the spell, if you don&#039;t want to force attack the target.
//  ENDSFX1	    - First model created and immediately destroyed on the final target after the final slash.
//	ENDSFX2	    - Second model created and immediately destroyed on the final target after the final slash.  There are two because I wanted two models to be displayed, for aesthetic purposes.
//	ENDSFXAP	- Attachment point for these two models
//	HANDSFX	    - Model attached to casters hands for the duration of the slashes.
//	HITSFX		- Model created and immediately destroyed on the current target after each slash.
//	HITSFXA	    - Attachment point for this model.
//	PREVENTMSG	- Message used to make the user aware that its attempt to cast the spell was interrupted, and why this was done.
//	SLIDESFX1	- First model created and immediately destroyed on the sliding last slash target.
//	SLIDESFX2	- Second model created and immediately destroyed on the sliding last slash target.  There are two because I thought the two together looked neat.
//	SLIDESFXAP	- Attachment point for these two models.  They are added and destroyed each TIMEOUT interval during the slide phase.
//	WPNSFX1	    - First model attached to the casters weapon during all slashes.
//	WPNSFX2	    - Second model attached to the casters weapon during all slashes.  There are two because I found one I liked, then found a second, and couldn’t decide between the two.
//	WPNSFXAP	- Attachment point for these two models.  It should be the weapon, but can be wherever you want.

//  Other
//	ATTACKTYPE	- Slash damage attacktype used when damaging the current target following a slash.
//	DAMAGETYPE	- Slash damage damagetype used when damaging the current target following a slash.
//	DESELECT	- Whether you want the caster deselected after the initial cast, and reselected at the end of it all.  This will also add the caster to a trigger which constantly deselects the hero during the entire spell if it is selected again by its owner.
//	FORCEATT	- Whether you want the caster to force attack the last target at the end of the spell.  If not, it will queue the ENDA animation.
//	GM		    - Whether you want the caster to be invulnerable for the duration of the slashes or not.  This does not change whether the caster is invulnerable during the channel phase, as it remains vulnerable during this time regardless.
//	PRELOAD	    - If you want to preload the Storm Crow Form ability, set this to true.  I simply create a copy of your CASTUNIT1, add the ability, and then apply a short timed life to the preload unit.
//	PREVENT	    - Will automatically detect if there are available targets in the selection radius.  If not, it will prevent the cast, and display an error message.

// FUNCTIONS: All configuration functions provide the level of the ability cast, unless otherwise stated.

//  Omnislash Related
//  Damage      - Damage dealt from each slash.
//  Radius      - Selection radius for new targets to slash.
//  RunSpeed    - Speed to move the caster toward the first target during the pre-slash run phase (per second).
//  SetupSlashId- This is where your slash animation ids are configured.  I did this so we could store multiple animations with minimal difficulty.  They are selected at random before each slash, aside from the first and last slash.  This function takes no arguments.
//  Slashes     - How many slashes you want to happen.  In this map, my values are not linear, so I had to use a simple if/else to set them manually.
//  Targets     - A custom function you can use to add additional filtering conditions to potential slash targets.  Currently, they must be alive, an enemy, and not a structure.  The rest is up to you.  This functions provides the current potential target, and the caster as unit arguments.
    
//  Slide Related: If you don&#039;t want a slide, set the SlideSpeed to 0.
//  BrakeFactor - This applys the brakes during the final targets slide.  Each TIMEOUT, its current move speed is multiplied by this value to get an updated, exponentially decaying move speed value, supplying our slide curve.
//  BreakPoint  - At this movement speed (per second), the slide will be considered over.
//  SDamage     - Incase you want periodic damage done during the slide.  This total damage will be dealt over the duration of the slide.
//  SlideSpeed  - The initial, starting slide speed (per second) for the final slash target.
 

Attachments

  • emjlr3 - Spell Contest 4 - FF7Omnislash.w3x
    164.9 KB · Views: 266

XeNiM666

I lurk for pizza
Reaction score
138
Hi and heres my submission out of boredom.. :D

Blade Dance

Code: vJASS
Mui: MUI
Requires: GT, KT2, AIDS

Description:
Performs a Blade Dance to a target, dealing a percentage of Agility damage per attack. Every phase of the dance increases the Agility factor by 15%. This "dance" is seperated into 5 Phases. Press the skill again to time the dance right.

Phase 1:
- Performs 3 attacks, If timed right between the 2nd and the 3rd attack, he perfoms the 2nd phase of the dance.

Phase 2:
- Performs 5 attacks while jumping and hurdling both units in the air. If timed right between any attack, performs the 3rd phase.

Phase 3:
- Attaches a chain to the target and performs 8 attacks while circling the target. If timed right between any attack, performs the 4th phase.

Phase 4:
- Pushes the target and the caster forward. If timed right, performs the last phase of the dance.

Phase 5:
- Kicks the target with great force, pushing him back.

Code:
JASS:
scope BladeDance initializer onInit

//============================================================================//
//============================================================================//
//                                                                            //
//                              BLADE DANCE v1.0                              //
//                                by XeNiM666                                 //
//                                                                            //
//============================================================================//
//============================================================================//
//                                                                            //
//  HOW TO IMPORT:                                                            //
//      1. Copy the &quot;dummy.mdx&quot; in the Import Manager                         //
//      2. Copy the ability itself together with the 4 phases                 //
//          - Blade Dance, Blade Dance Phase 2, Blade Dance Phase 3,          //
//            Blade Dance Phase 4, Blade Dance Phase 5                        //
//          - Every spell MUST have the same Base Order Id                    //
//      3. Copy the triggers under &quot;REQUIRED&quot; in the trigger folder           //
//      4. Copy this trigger by creating a trigger, converting it to custom   //
//         text and replacing everything in that trigger with all of this.    //
//      5. Configure everything below to your liking.                         //
//      6. Enjoy! <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />                                                          //
//                                                                            //
//============================================================================//
//============================================================================//

    globals
        // RAW CODE OF THE SPELL ITSELF
        private constant integer SPELL_ID = &#039;A000&#039;
        // RAW CODE OF THE SPELL ACTIVATED TO REACH PHASE 2
        private constant integer PHASE2_ID = &#039;A001&#039;
        // RAW CODE OF THE SPELL ACTIVATED TO REACH PHASE 3
        private constant integer PHASE3_ID = &#039;A002&#039;
        // RAW CODE OF THE SPELL ACTIVATED TO REACH PHASE 4
        private constant integer PHASE4_ID = &#039;A003&#039;
        // RAW CODE OF THE SPELL ACTIVATED TO REACH PHASE 5
        private constant integer PHASE5_ID = &#039;A004&#039;
        // THE BASE ORDER ID OF ALL THE ABILITIES LISTED ABOVE
        // THEY MUST HAVE THE SAME BASE ORDER ID&#039;S
        private constant string ABILITY_ORDER_ID = &quot;berserk&quot;
        
        // THE RATE AT WHICH THE TIMER RUNS. DEFAULT = 0.01000 = 100 TIMES A SECOND
        // MUST BE A MULTIPLE OF 0.00125
        private constant real TIMER_INTERVAL = 0.01000
        // I FELT THE NEED TO MAKE THIS 0.01 BECAUSE OF ACCURACY, PRECISION AND TIMING PURPOSES
        // I SUGGEST SETTING THIS IN LOWER INTERVALS FOR THE REASON ABOVE... <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
        
        // THE EFFECT PLAYED THAT INDICATES WHEN TO PRESS THE SKILL AGAIN TO GO
        // TO THE NEXT PHASE. NOTE THAT THIS EFFECT IS ATTACHED TO BOTH HANDS OF THE CASTER.
        private constant string INDICATOR = &quot;Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl&quot;
        // THE EFFECTS ATTACHED TO THE HANDS OF THE CASTER WHILE &quot;SLASHING&quot;
        private constant string HAND_EFFECTS = &quot;Abilities\\Spells\\Other\\Tornado\\Tornado_Target.mdl&quot;
        
        // INTERVAL OF ATTACKS AT PHASE 1
        private constant real PHASE1_SLASH_INTERVAL = 0.25
        // NUMBER OF ATTACKS MADE AT PHASE 1, INCLUDING THE LAST ATTACK
        private constant integer PHASE1_NUMBER_OF_ATTACKS =  3
        // THE MAXIMUM TIME OF THE LAST ATTACK IN PHASE 1
        private constant real PHASE1_INTERVAL = 1.00
        // THE MAXIMUM TIME FOR THE CASTER TO REACT TO GO TO PHASE 2.
        // MUST BE LESS THAN PHASE1_INTERVAL
        private constant real PHASE1_ACT_TIME = 0.50
        // THE ANIMATION PLAYED WHEN ATTACKING AT PHASE 1
        private constant string PHASE1_ANIMATION = &quot;attack&quot;
        
        // INTERVAL OF ATTACKS AT PHASE 2
        private constant real PHASE2_SLASH_INTERVAL = 0.15
        // NUMBER OF ATTACKS MADE AT PHASE 2
        private constant integer PHASE2_NUMBER_OF_ATTACKS = 5
        // HOW HIGH THE CASTER AND TARGET GOES PER HIT AT PHASE 2
        private constant real PHASE2_HEIGHT_INCREASE = 55.00
        // THE ANIMATION PLAYED WHEN ATTACKING AT PHASE 2
        private constant string PHASE2_ANIMATION = &quot;attack&quot;
        // HOW FAR THE HERO WILL GO WHEN HE DROPS AT PHASE 2 WHEN YOU FAIL
        private constant real PHASE2_DROP_DISTANCE = 500.00
        // HOW FAST THE DROP IS IN TERMS OF X/Y POSITION, NOT HEIGHT
        private constant real PHASE2_DROP_SPEED = 1250.00
        
        // INTERVAL OF ATTACKS AT PHASE 3
        private constant real PHASE3_SLASH_INTERVAL = 0.125
        // NUMBER OF ATTACKS MADE AT PHASE 3
        private constant integer PHASE3_NUMBER_OF_ATTACKS = 8
        // THE ANIMATION PLAYED WHEN ATTACKING AT PHASE 3
        private constant string PHASE3_ANIMATION = &quot;attack&quot;
        // HOW FAST THE CASTER AND TARGET DROPS TO THE GROUND AT THE END OF PHASE 3
        private constant real PHASE3_DROP_SPEED = 600.00
        // THE EFFECT PLAYED WHEN YOU FAIL TO REACH PHASE 4
        private constant string PHASE3_FAIL_DROP_EFFECT = &quot;Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl&quot;
        // WHERE THE EFFECT ABOVE WILL BE ATTACHED TO THE TARGET
        private constant string PHASE3_FAIL_DROP_EFFECT_ATTACH = &quot;origin&quot;
        // THE EFFECT PLAYED WHEN YOU SUCCEED IN REACHING PHASE 4
        private constant string PHASE3_GOOD_DROP_EFFECT = &quot;Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl&quot;
        // WHERE THE EFFECT ABOVE WILL BE ATTACHED TO THE TARGET
        private constant string PHASE3_GOOD_DROP_EFFECT_ATTACH = &quot;origin&quot;
        
        // HOW FAR THE HERO WILL GO WHEN HE DROPS AT PHASE 4
        private constant real PHASE4_DROP_DISTANCE = 500.00
        // HOW FAST THE DROP ABOVE IS IN TERMS OF X/Y POSITION, NOT HEIGHT
        private constant real PHASE4_DROP_SPEED = 850.00
        
        // HOW FAR THE TARGET GETS PUSHED BACK AT PHASE 5
        private constant real PHASE5_PUSHBACK_DISTANCE = 450.00
        // HOW FAST HE GETS PUSHED BACK
        private constant real PHASE5_PUSHBACK_SPEED = 550.00
        // THE EFFECT PLAYED WHILE THE TARGET IS BEING PUSHED BACK
        private constant string PHASE5_PUSHBACK_EFFECT = &quot;Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl&quot;
        // THE ANIMATION PLAYED WHEN THE TARGET GETS PUSHED BACK
        private constant string PHASE5_ANIMATION = &quot;attack&quot;
               
        // RAW CODE OF THE UNIT CREATED FOR THE ATTACK EFFECT
        // MUST HAVE THE &quot;dummy.mdx&quot; AS ITS MODEL
        private constant integer SLASH_DUMMY_ID = &#039;h000&#039;
        // THE EFFECT ATTACHED TO THE DUMMY ABOVE, WHICH WILL MAKE THE &quot;SLASH&quot; EFFECT
        private constant string SLASH_DUMMY_EFFECT = &quot;Abilities\\Spells\\Items\\WandOfNeutralization\\NeutralizationMissile.mdl&quot;
        // HOW BUG THE &quot;SLASH&quot; EFFECT IS
        private constant real SLASH_EFFECT_SCALE = 2.00
        // HOW FAST THE &quot;SLASH&quot; MOVES
        private constant real SLASH_DISTANCE_PER_SECOND = 1200.00
        // HOW FAR THE &quot;SLASH&quot; WILL MOVE
        private constant real SLASH_DISTANCE = 250.00
        // THE ANIMATION PLAYED WHENEVER AN ENEMY GETS HIT BY A &quot;SLASH&quot;
        private constant string DAMAGE_EFFECT_ANIMATION = &quot;death&quot;
        // THE EFFECT PLAYED WHEN THE TARGET TAKES DAMAGE FROM &quot;SLASHING&quot;
        private constant string SLASH_DAMAGE_EFFECT = &quot;Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl&quot;
        // WHERE THE EFFECT ABOVE WILL BE ATTACHED TO THE TARGET
        private constant string SLASH_DAMAGE_EFFECT_ATTACH = &quot;chest&quot;
        
        // THE ATTACK TYPE OF THE DAMAGE DEALT
        private constant attacktype DAMAGE_ATTACKTYPE = ATTACK_TYPE_HERO
        // THE DAMAGE TYPE OF THE DAMAGE DEALT
        private constant damagetype DAMAGE_DAMAGETYPE = DAMAGE_TYPE_NORMAL
        private constant real DAMAGE_BONUS_PER_PHASE = 0.15
    endglobals
    
    // FACTOR WHICH IS MULTIPLIED TO THE AGILITY OF THE HERO PER LEVEL
    // THIS DAMAGE IS DEALT EVERY &quot;SLASH&quot;
    private function Damage takes integer lvl returns real
        return 0.50 + ( 0.25 * lvl )
    endfunction
    
  //===============================================================================================================================================================
 //         DO NOT TOUCH UNLESS YOU KNOW WHAT YOU ARE DOING
//===============================================================================================================================================================
        
    globals
        private boolean array PHASE2_ACT[ 8190 ]
        private boolean array PHASE2_GOOD[ 8190 ]
        private boolean array PHASE3_ACT[ 8190 ]
        private boolean array PHASE4_ACT[ 8190 ]
        private boolean array PHASE5_ACT[ 8190 ]
        private boolean array PHASE5_GOOD[ 8190 ]
        private boolean array PHASE6_ACT[ 8190 ]
        private group Slashing = CreateGroup()
    endglobals
    
//=============================================================================================

    // THE STRUCT HANDLING THE &quot;SLASH&quot; EFFECTS
    private struct Slash
        unit slash
        effect ef
        real d = 0.00
        real cos
        real sin
        
        static method Move takes nothing returns boolean
            local Slash s = KT_GetData()
            
            local real r = SLASH_DISTANCE_PER_SECOND * TIMER_INTERVAL
            local real x
            local real y
            
            set s.d = s.d + r
            if s.d &lt;= SLASH_DISTANCE then
                set x = GetUnitX( s.slash ) + r * s.cos
                set y = GetUnitY( s.slash ) + r * s.sin
                call SetUnitX( s.slash, x )
                call SetUnitY( s.slash, y )
            else
                call s.destroy()
                return true
            endif
            
            return false
        endmethod
        
        method onDestroy takes nothing returns nothing
            call DestroyEffect( .ef )
            set .ef = null
            call KillUnit( .slash )
            set .slash = null
        endmethod
        
        static method create takes unit caster, real x, real y, real a returns Slash
            local Slash s = Slash.allocate()
            
            set s.slash = CreateUnit( GetOwningPlayer( caster ), SLASH_DUMMY_ID, x, y, a * bj_RADTODEG )
            set s.ef = AddSpecialEffectTarget( SLASH_DUMMY_EFFECT, s.slash, &quot;origin&quot; )
            set s.cos = Cos( a )
            set s.sin = Sin( a )
            call SetUnitFlyHeight( s.slash, GetUnitFlyHeight( caster ) + 100.00, 0.00 )
            call SetUnitScale( s.slash, SLASH_EFFECT_SCALE, SLASH_EFFECT_SCALE, SLASH_EFFECT_SCALE )
            call KT_Add( function Slash.Move, s, TIMER_INTERVAL )
            
            return s
        endmethod
        
    endstruct
    
//=============================================================================================
    
    // THE STRUCT HANDLING THE ENTIRE SPELL
    private struct Dance
        unit caster
        real cx
        real cy
        effect ef1
        effect ef2
        real dmg
        
        unit target
        real tx
        real ty
        
        real z
        real d = 0.00
        real a
        real cos
        real sin
        
        real int = PHASE1_SLASH_INTERVAL
        real r
        real t = 0.00
        real t2 = 0.00
        integer num = 0

        lightning l
        
        boolean eff = false
        
        static method Drop takes nothing returns boolean
            local Dance d = KT_GetData()
            
            local real r = PHASE2_DROP_SPEED * TIMER_INTERVAL
            local real x
            local real y
            local real z
            
            set d.d = d.d + r
            if d.d &lt;= PHASE2_DROP_DISTANCE then
                set z = ParabolaZ( d.z, ( PHASE2_DROP_DISTANCE * 2.00 ), PHASE2_DROP_DISTANCE + d.d )
                set x = GetUnitX( d.caster ) + r * d.cos
                set y = GetUnitY( d.caster ) + r * d.sin
                call SetUnitX( d.caster, x )
                call SetUnitY( d.caster, y )
                call UnitAddAbility( d.caster, &#039;Amrf&#039; )
                call SetUnitFlyHeight( d.caster, z, 0.00 )
                call UnitRemoveAbility( d.caster, &#039;Amrf&#039; )   
                
                set x = GetUnitX( d.target ) - r * d.cos
                set y = GetUnitY( d.target ) - r * d.sin
                set z = ParabolaZ( d.z, PHASE2_DROP_DISTANCE, ( PHASE2_DROP_DISTANCE / 2.00 ) + d.d )
                call SetUnitX( d.target, x )
                call SetUnitY( d.target, y )
                call UnitAddAbility( d.target, &#039;Amrf&#039; )
                call SetUnitFlyHeight( d.target, z, 0.00 )
                call UnitRemoveAbility( d.target, &#039;Amrf&#039; )
            else
                call d.destroy()
                
                return true
            endif
        
            return false
        endmethod

          //===============================//
         //            PHASE 5            //
        //===============================//
        static method Phase5 takes nothing returns boolean
            local Dance d = KT_GetData()
            
            local real r = PHASE5_PUSHBACK_SPEED * TIMER_INTERVAL
            local real x
            local real y
            
            set d.t2 = d.t2 + r
            if d.t2 &lt; PHASE5_PUSHBACK_DISTANCE then
                set x = GetUnitX( d.target ) + r * Cos( d.a )
                set y = GetUnitY( d.target ) + r * Sin( d.a )
                if IsTerrainPathable( x, y, PATHING_TYPE_WALKABILITY ) == false then
                    call SetUnitX( d.target, x )
                    call SetUnitY( d.target, y )
                    call DestroyEffect( AddSpecialEffect( PHASE5_PUSHBACK_EFFECT, x, y ) )
                endif
            else
                call d.destroy()
                
                return true
            endif
            
            return false
        endmethod
        
          //===============================//
         //            PHASE 4            //
        //===============================//
        static method Phase4 takes nothing returns boolean
            local Dance d = KT_GetData()
            
            local real r = PHASE4_DROP_SPEED * TIMER_INTERVAL
            local real x
            local real y
            local real z
            
            set d.d = d.d + r
            
            if PHASE5_ACT[ GetUnitId( d.caster ) ] == true and PHASE5_GOOD[ GetUnitId( d.caster ) ] == false then
                call SetPlayerAbilityAvailable( GetOwningPlayer( d.caster ), SPELL_ID, true )  
                call UnitRemoveAbility( d.caster, PHASE5_ID )  
                call SetUnitAnimation( d.caster, PHASE5_ANIMATION )
                
                set d.tx = GetUnitX( d.target )
                set d.ty = GetUnitY( d.target )
                set d.cx = GetUnitX( d.caster )
                set d.cy = GetUnitY( d.caster )
                set d.a = Atan2( d.ty - d.cy, d.tx - d.cx )
                set d.t2 = 0.00
                set PHASE5_GOOD[ GetUnitId( d.caster ) ] = true
                
                set d.dmg = GetHeroAgi( d.caster, true ) * ( Damage( GetUnitAbilityLevel( d.caster, SPELL_ID ) ) + ( 4.00 * DAMAGE_BONUS_PER_PHASE ) )
                call UnitDamageTarget( d.caster, d.target, d.dmg, true, false, DAMAGE_ATTACKTYPE, DAMAGE_DAMAGETYPE, WEAPON_TYPE_WHOKNOWS )
                call KT_Add( function Dance.Phase5, d, TIMER_INTERVAL )
            endif
            
            if d.d &lt;= PHASE4_DROP_DISTANCE then
                set z = ParabolaZ( d.z, ( PHASE4_DROP_DISTANCE * 2.00 ), PHASE4_DROP_DISTANCE + d.d )
                set x = GetUnitX( d.caster ) + r * d.cos
                set y = GetUnitY( d.caster ) + r * d.sin
                call SetUnitX( d.caster, x )
                call SetUnitY( d.caster, y )
                call UnitAddAbility( d.caster, &#039;Amrf&#039; )
                call SetUnitFlyHeight( d.caster, z, 0.00 )
                call UnitRemoveAbility( d.caster, &#039;Amrf&#039; )   
                
                set x = GetUnitX( d.target ) + r * d.cos
                set y = GetUnitY( d.target ) + r * d.sin
                set z = ParabolaZ( d.z, PHASE4_DROP_DISTANCE, ( PHASE4_DROP_DISTANCE / 2.00 ) + d.d )
                call SetUnitX( d.target, x )
                call SetUnitY( d.target, y )
                call UnitAddAbility( d.target, &#039;Amrf&#039; )
                call SetUnitFlyHeight( d.target, z, 0.00 )
                call UnitRemoveAbility( d.target, &#039;Amrf&#039; )                
            else
                if PHASE5_GOOD[ GetUnitId( d.caster ) ] == false then
                    call SetPlayerAbilityAvailable( GetOwningPlayer( d.caster ), SPELL_ID, true )  
                    call UnitRemoveAbility( d.caster, PHASE5_ID )    
                    call d.destroy()
                endif
                return true
            endif
            
            return false
        endmethod
        
          //===============================//
         //            PHASE 3            //
        //===============================//
        static method Phase3 takes nothing returns boolean
            local Dance d = KT_GetData()
            local Slash s
            local real x
            local real y
            local real a
            
            set d.t = d.t + TIMER_INTERVAL                    
            if d.t &gt;= d.int and d.num &lt; PHASE3_NUMBER_OF_ATTACKS then
                if PHASE4_ACT[ GetUnitId( d.caster ) ] == true then
                    call DestroyLightning( d.l )
                    set d.l = null

                    call UnitAddAbility( d.caster, PHASE5_ID )    
                    call UnitRemoveAbility( d.caster, PHASE4_ID )  
                    call DestroyEffect( AddSpecialEffectTarget( PHASE3_GOOD_DROP_EFFECT, d.target, PHASE3_GOOD_DROP_EFFECT_ATTACH ) )
                    call DestroyEffect( AddSpecialEffectTarget( PHASE3_FAIL_DROP_EFFECT, d.target, PHASE3_FAIL_DROP_EFFECT_ATTACH ) )
                    
                    set d.z = GetUnitZ( d.target )
                    
                    set d.dmg = GetHeroAgi( d.caster, true ) * ( Damage( GetUnitAbilityLevel( d.caster, SPELL_ID ) ) + ( 3.00 * DAMAGE_BONUS_PER_PHASE ) )
                    call UnitDamageTarget( d.caster, d.target, d.dmg, true, false, DAMAGE_ATTACKTYPE, DAMAGE_DAMAGETYPE, WEAPON_TYPE_WHOKNOWS )
                    call KT_Add( function Dance.Phase4, d, TIMER_INTERVAL )
                    
                    return true
                else
                    set d.tx = GetUnitX( d.target )
                    set d.ty = GetUnitY( d.target )
                    set d.cos = Cos( d.a )
                    set d.sin = Sin( d.a )
                    set x = d.tx - ( 150.00 * d.cos ) 
                    set y = d.ty - ( 150.00 * d.sin )
                    call SetUnitX( d.caster, x )
                    call SetUnitY( d.caster, y )
                    set d.cx = GetUnitX( d.caster )
                    set d.cy = GetUnitY( d.caster )
                    set d.z = GetUnitZ( d.target )
                    call MoveLightningEx( d.l, true, d.cx, d.cy, d.z, d.tx, d.ty, d.z )
                    set d.a = d.a + ( ( 2 * bj_PI ) / PHASE3_NUMBER_OF_ATTACKS )
                    set a = Atan2( d.ty - d.cy, d.tx - d.cx )
                    call SetUnitAnimation( d.caster, PHASE3_ANIMATION )
                    call SetUnitAnimation( d.target, DAMAGE_EFFECT_ANIMATION )
                    call SetUnitFacing( d.caster, a )
                    call UnitDamageTarget( d.caster, d.target, d.dmg, true, false, DAMAGE_ATTACKTYPE, DAMAGE_DAMAGETYPE, WEAPON_TYPE_WHOKNOWS )
                    set s = Slash.create( d.caster, d.cx, d.cy, a )
                    call DestroyEffect( AddSpecialEffectTarget( SLASH_DAMAGE_EFFECT, d.target, SLASH_DAMAGE_EFFECT_ATTACH ) )

                    set d.int = d.int + PHASE3_SLASH_INTERVAL
                    set d.num = d.num + 1
                    
                    if d.num == PHASE3_NUMBER_OF_ATTACKS - 1 then
                        call DestroyEffect( AddSpecialEffectTarget( INDICATOR, d.caster, &quot;hand,left&quot; ) )
                        call DestroyEffect( AddSpecialEffectTarget( INDICATOR, d.caster, &quot;hand,right&quot; ) )
                    endif
                endif
            elseif d.t &gt;= d.int and d.num &gt;= PHASE3_NUMBER_OF_ATTACKS then 
                call DestroyLightning( d.l )
                set d.l = null
                
                call DestroyEffect( AddSpecialEffectTarget( PHASE3_FAIL_DROP_EFFECT, d.target, PHASE3_FAIL_DROP_EFFECT_ATTACH ) )
                call UnitAddAbility( d.caster, &#039;Amrf&#039; )
                call UnitAddAbility( d.target, &#039;Amrf&#039; )
                call SetUnitFlyHeight( d.caster, GetUnitDefaultFlyHeight( d.caster ), PHASE3_DROP_SPEED )
                call SetUnitFlyHeight( d.target, GetUnitDefaultFlyHeight( d.target ), PHASE3_DROP_SPEED * 1.75 )
                call UnitRemoveAbility( d.caster, &#039;Amrf&#039; )   
                call UnitRemoveAbility( d.target, &#039;Amrf&#039; )
                
                call SetPlayerAbilityAvailable( GetOwningPlayer( d.caster ), SPELL_ID, true )  
                call UnitRemoveAbility( d.caster, PHASE4_ID )    
                call d.destroy()
                
                return true
            endif
            
            return false
        endmethod
        
          //===============================//
         //            PHASE 2            //
        //===============================//
        static method Phase2 takes nothing returns boolean
            local Dance d = KT_GetData()
            local Slash s
            set d.t = d.t + TIMER_INTERVAL
            
            if d.t &gt;= d.int and d.num &lt; PHASE2_NUMBER_OF_ATTACKS then
                if PHASE3_ACT[ GetUnitId( d.caster ) ] == true then
                    set d.l = AddLightningEx( &quot;LEAS&quot;, true, GetUnitX( d.caster ), GetUnitY( d.caster ), GetUnitZ( d.caster ), GetUnitX( d.target ), GetUnitY( d.target ), GetUnitZ( d.target ) )
                    call UnitRemoveAbility( d.caster, PHASE3_ID )
                    call UnitAddAbility( d.caster, PHASE4_ID )
                    
                    set d.t = 0.00
                    set d.num = 0
                    set d.int = PHASE3_SLASH_INTERVAL
                    set d.dmg = GetHeroAgi( d.caster, true ) * ( Damage( GetUnitAbilityLevel( d.caster, SPELL_ID ) ) + ( 2.00 * DAMAGE_BONUS_PER_PHASE ) )
                    
                    call KT_Add( function Dance.Phase3, d, TIMER_INTERVAL )
                    
                    return true
                else
                    call SetUnitAnimation( d.caster, PHASE2_ANIMATION )
                    call SetUnitAnimation( d.target, DAMAGE_EFFECT_ANIMATION )
                    call UnitDamageTarget( d.caster, d.target, d.dmg, true, false, DAMAGE_ATTACKTYPE, DAMAGE_DAMAGETYPE, WEAPON_TYPE_WHOKNOWS )
                    set s = Slash.create( d.caster, d.cx, d.cy, d.a )
                    call DestroyEffect( AddSpecialEffectTarget( SLASH_DAMAGE_EFFECT, d.target, SLASH_DAMAGE_EFFECT_ATTACH ) )
                    
                    set d.int = d.int + PHASE2_SLASH_INTERVAL      
                    set d.num = d.num + 1
                    if d.num == PHASE2_NUMBER_OF_ATTACKS - 1 then
                        call DestroyEffect( AddSpecialEffectTarget( INDICATOR, d.caster, &quot;hand,left&quot; ) )
                        call DestroyEffect( AddSpecialEffectTarget( INDICATOR, d.caster, &quot;hand,right&quot; ) )
                    endif
                    
                    call UnitAddAbility( d.caster, &#039;Amrf&#039; )
                    call UnitAddAbility( d.target, &#039;Amrf&#039; )
                    call SetUnitFlyHeight( d.caster, d.num * PHASE2_HEIGHT_INCREASE, d.num * PHASE2_HEIGHT_INCREASE / PHASE2_SLASH_INTERVAL )
                    call SetUnitFlyHeight( d.target, d.num * PHASE2_HEIGHT_INCREASE, d.num * PHASE2_HEIGHT_INCREASE / PHASE2_SLASH_INTERVAL )
                    call UnitRemoveAbility( d.caster, &#039;Amrf&#039; )   
                    call UnitRemoveAbility( d.target, &#039;Amrf&#039; )
                endif               
            elseif d.t &gt;= d.int and d.num &gt;= PHASE2_NUMBER_OF_ATTACKS then 
                call SetUnitTimeScale( d.caster, 1.00 )
                call SetPlayerAbilityAvailable( GetOwningPlayer( d.caster ), SPELL_ID, true )  
                call UnitRemoveAbility( d.caster, PHASE3_ID )
                
                set d.cos = Cos( d.a )
                set d.sin = Sin( d.a )
                set d.z = GetUnitZ( d.target )
                call KT_Add( function Dance.Drop, d, TIMER_INTERVAL )
                    
                return true
            endif
            
            return false
        endmethod
        
          //===============================//
         //            PHASE 1            //
        //===============================//
        static method Phase1 takes nothing returns boolean
            local Dance d = KT_GetData()
            local Slash s
            set d.t = d.t + TIMER_INTERVAL
            
            if d.t &gt;= d.int and d.num &lt; ( PHASE1_NUMBER_OF_ATTACKS - 1 ) then
                call SetUnitAnimation( d.caster, PHASE1_ANIMATION )
                call SetUnitAnimation( d.target, DAMAGE_EFFECT_ANIMATION )
                call UnitDamageTarget( d.caster, d.target, d.dmg, true, false, DAMAGE_ATTACKTYPE, DAMAGE_DAMAGETYPE, WEAPON_TYPE_WHOKNOWS )
                set s = Slash.create( d.caster, d.cx, d.cy, d.a )
                call DestroyEffect( AddSpecialEffectTarget( SLASH_DAMAGE_EFFECT, d.target, SLASH_DAMAGE_EFFECT_ATTACH ) )
               
                set d.num = d.num + 1
                if d.num &gt;= ( PHASE1_NUMBER_OF_ATTACKS - 1 ) then
                    set d.r = GetRandomReal( 0.00, PHASE1_INTERVAL - PHASE1_ACT_TIME )
                    set d.int = d.int + d.r
                    call SetUnitAnimation( d.caster, PHASE1_ANIMATION )
                    call SetUnitTimeScale( d.caster, PHASE1_INTERVAL * 0.50 )
                else
                    set d.int = d.int + PHASE1_SLASH_INTERVAL
                endif
            elseif d.t &gt;= d.int and d.num &gt;= ( PHASE1_NUMBER_OF_ATTACKS - 1 ) then 
                if d.eff == false then
                    call DestroyEffect( AddSpecialEffectTarget( INDICATOR, d.caster, &quot;hand,left&quot; ) )
                    call DestroyEffect( AddSpecialEffectTarget( INDICATOR, d.caster, &quot;hand,right&quot; ) )
                    set d.eff = true
                endif
                
                set d.t2 = d.t2 + TIMER_INTERVAL
                if d.t2 &lt;= PHASE1_ACT_TIME then
                    if PHASE2_ACT[ GetUnitId( d.caster ) ] == true and PHASE2_GOOD[ GetUnitId( d.caster ) ] == false then
                        call SetUnitAnimation( d.caster, PHASE1_ANIMATION )
                        call SetUnitAnimation( d.target, DAMAGE_EFFECT_ANIMATION )
                        call UnitDamageTarget( d.caster, d.target, d.dmg, true, false, DAMAGE_ATTACKTYPE, DAMAGE_DAMAGETYPE, WEAPON_TYPE_WHOKNOWS )
                        set s = Slash.create( d.caster, d.cx, d.cy, d.a )
                        call DestroyEffect( AddSpecialEffectTarget( SLASH_DAMAGE_EFFECT, d.target, SLASH_DAMAGE_EFFECT_ATTACH ) )
              
                        call SetUnitTimeScale( d.caster, 1.00 )
                        call SetPlayerAbilityAvailable( GetOwningPlayer( d.caster ), SPELL_ID, true )  
                        call UnitRemoveAbility( d.caster, PHASE2_ID )

                        call d.destroy()
                        return true
                    else
                        set PHASE2_GOOD[ GetUnitId( d.caster ) ] = true
                        if PHASE2_ACT[ GetUnitId( d.caster ) ] == true then
                            call UnitRemoveAbility( d.caster, PHASE2_ID )
                            call UnitAddAbility( d.caster, PHASE3_ID )
                            
                            set d.t = 0.00
                            set d.num = 0
                            set d.int = PHASE2_SLASH_INTERVAL
                            set d.dmg = GetHeroAgi( d.caster, true ) * ( Damage( GetUnitAbilityLevel( d.caster, SPELL_ID ) ) + DAMAGE_BONUS_PER_PHASE )
                            
                            call KT_Add( function Dance.Phase2, d, TIMER_INTERVAL )
                            return true
                        endif
                    endif
                else
                    if PHASE2_ACT[ GetUnitId( d.caster ) ] == false then
                        call SetUnitAnimation( d.caster, PHASE1_ANIMATION )
                        call SetUnitAnimation( d.target, DAMAGE_EFFECT_ANIMATION )
                        call UnitDamageTarget( d.caster, d.target, d.dmg, true, false, DAMAGE_ATTACKTYPE, DAMAGE_DAMAGETYPE, WEAPON_TYPE_WHOKNOWS )
                        set s = Slash.create( d.caster, d.cx, d.cy, d.a )
                        call DestroyEffect( AddSpecialEffectTarget( SLASH_DAMAGE_EFFECT, d.target, SLASH_DAMAGE_EFFECT_ATTACH ) )

                        call SetUnitTimeScale( d.caster, 1.00 )
                        call SetPlayerAbilityAvailable( GetOwningPlayer( d.caster ), SPELL_ID, true )  
                        call UnitRemoveAbility( d.caster, PHASE2_ID )
                        
                        call d.destroy()
                        return true
                    endif
                endif
            endif
            
            return false
        endmethod
        
        method onDestroy takes nothing returns nothing
            call DestroyEffect( .ef1 )
            set .ef1 = null
            call DestroyEffect( .ef2 ) 
            set .ef2 = null
            
            call PauseUnit( .target, false )
            set .target = null
            call GroupRemoveUnit( Slashing, .caster )
            set .caster = null
        endmethod
        
    endstruct
    
//=============================================================================================
 
    private function BD_Actions takes nothing returns boolean
        local Dance d = Dance.create()
        
        set d.caster = GetTriggerUnit()
        set d.cx = GetUnitX( d.caster )
        set d.cy = GetUnitY( d.caster )
        set d.ef1 = AddSpecialEffectTarget( HAND_EFFECTS, d.caster, &quot;hand,left&quot; )
        set d.ef2 = AddSpecialEffectTarget( HAND_EFFECTS, d.caster, &quot;hand,right&quot; )
        call GroupAddUnit( Slashing, d.caster )
        
        set d.target = GetSpellTargetUnit()
        set d.tx = GetUnitX( d.target )
        set d.ty = GetUnitY( d.target )
        set d.a = Atan2( d.ty - d.cy, d.tx - d.cx )
        
        call SetPlayerAbilityAvailable( GetOwningPlayer( d.caster ), SPELL_ID, false )  
        call UnitAddAbility( d.caster, PHASE2_ID )
        call PauseUnit( d.target, true )
        
        set d.dmg = GetHeroAgi( d.caster, true ) * Damage( GetUnitAbilityLevel( d.caster, SPELL_ID ) )
        
        set PHASE2_ACT[ GetUnitId( d.caster ) ] = false
        set PHASE2_GOOD[ GetUnitId( d.caster ) ] = false
        set PHASE3_ACT[ GetUnitId( d.caster ) ] = false
        set PHASE4_ACT[ GetUnitId( d.caster ) ] = false
        set PHASE5_ACT[ GetUnitId( d.caster ) ] = false
        set PHASE5_GOOD[ GetUnitId( d.caster ) ] = false
        set PHASE6_ACT[ GetUnitId( d.caster ) ] = false
        
        call KT_Add( function Dance.Phase1, d, TIMER_INTERVAL )
        return false
    endfunction
    
//=============================================================================================
    
    private function P2_Actions takes nothing returns boolean
        set PHASE2_ACT[ GetUnitId( GetTriggerUnit() ) ] = true
        return false
    endfunction
    
    private function P3_Actions takes nothing returns boolean
        set PHASE3_ACT[ GetUnitId( GetTriggerUnit() ) ] = true
        return false
    endfunction

    private function P4_Actions takes nothing returns boolean
        set PHASE4_ACT[ GetUnitId( GetTriggerUnit() ) ] = true
        return false
    endfunction
   
    private function P5_Actions takes nothing returns boolean
        set PHASE5_ACT[ GetUnitId( GetTriggerUnit() ) ] = true
        return false
    endfunction
    
    private function Stop takes nothing returns boolean
        local unit u = null
        call DisableTrigger( GetTriggeringTrigger() )
        if GetIssuedOrderId() != OrderId( ABILITY_ORDER_ID ) then
            set u = GetOrderedUnit()
            if IsUnitInGroup( u, Slashing ) == true then
                call IssuePointOrder( u, &quot;move&quot;, GetUnitX( u ), GetUnitY( u ) ) 
            endif
            set u = null
        endif
        call EnableTrigger( GetTriggeringTrigger() )
        return false
    endfunction

//=============================================================================================
    
    private function onInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        local unit u = CreateUnit( Player( 15 ), SLASH_DUMMY_ID, 0.00, 0.00, 0.00 )
        call UnitAddAbility( u, PHASE2_ID )
        call UnitRemoveAbility( u, PHASE2_ID )
        call UnitAddAbility( u, PHASE3_ID )
        call UnitRemoveAbility( u, PHASE3_ID )
        call UnitAddAbility( u, PHASE4_ID )
        call UnitRemoveAbility( u, PHASE4_ID )        
        call UnitAddAbility( u, PHASE5_ID )
        call UnitRemoveAbility( u, PHASE5_ID )
        call UnitAddAbility( u, &#039;Amrf&#039; )
        call UnitRemoveAbility( u, &#039;Amrf&#039; )
        call RemoveUnit( u )
        set u = null
        
        call GT_AddStartsEffectAction( function BD_Actions, SPELL_ID )
        call GT_AddBeginsCastingAction( function P2_Actions, PHASE2_ID )
        call GT_AddBeginsCastingAction( function P3_Actions, PHASE3_ID )
        call GT_AddBeginsCastingAction( function P4_Actions, PHASE4_ID )
        call GT_AddBeginsCastingAction( function P5_Actions, PHASE5_ID )
        
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_ORDER )
        call TriggerAddCondition( t, Condition( function Stop ) )
        set t = null
        
        call Preload( PHASE5_PUSHBACK_EFFECT )
        call Preload( PHASE3_GOOD_DROP_EFFECT )
        call Preload( PHASE3_FAIL_DROP_EFFECT )
        call Preload( SLASH_DAMAGE_EFFECT )
        call Preload( HAND_EFFECTS )
        call Preload( SLASH_DUMMY_EFFECT )
        call Preload( INDICATOR )
        call PreloadStart()
    endfunction

endscope


Map:
 

Attachments

  • Blade Dance - Spell Contest 4 - XeNiM666.w3x
    99.9 KB · Views: 228

Weep

Godspeed to the sound of the pounding
Reaction score
400
My submission (complete with halfway-lame excuse to make it count under the theme :p):

Deep Beast
by Weep
Version 1.0

anyd1x.jpg
2qaqp6p.jpg

It's hard to get a good screenshot of this, since it's fairly animated.

Credit to The_Overmind for inspiring me with the continues-until-it-misses idea.
 

Attachments

  • Weep - Spell Contest 4 - Deep Beast.w3x
    44.4 KB · Views: 229

Jedi

New Member
Reaction score
63
I know I should have not make this in last hours.This spell sucks :O

Shield Slam
Code: Jass,MUI (doesn't requires newgen)
Required Systems: No system required
Description
Dalek run towards to the targeted unit.When he reaches his target slams him/her with his shield, stuns targeted unit and deals damage to the targeted unit.Pushes target a short distance.

Level 1 - Dalek run towards to the targeted unit.When he reaches his target slams him/her with his shield, stuns him/her for 1.5 seconds and deals 100 damage to the targeted unit.Pushes target 500 units away.
Level 2 - Dalek run towards to the targeted unit.When he reaches his target slams him/her with his shield, stuns him/her for 3 seconds and deals 200 damage to the targeted unit.Pushes target 600 units away.
Level 3 - Dalek run towards to the targeted unit.When he reaches his target slams him/her with his shield, stuns him/her for 4.5 seconds and deals 300 damage to the targeted unit.Pushes target 700 units away.
Level 4 - Dalek run towards to the targeted unit.When he reaches his target slams him/her with his shield, stuns him/her for 6 seconds and deals 400 damage to the targeted unit.Pushes target 800 units away..
n4b3px.jpg
 

Attachments

  • Jedi - Spell Contest.w3x
    25.3 KB · Views: 220

Necrach

You can change this now in User CP.
Reaction score
62
Heavy Dance

Whoa, I really haven't had time for this. This spell should have been WAY more advanced, with another system (without Wait actions -.-'), the earthquake growing in size for each jump and a couple of costum effects, but I simply haven't had time for mapping :eek: so I had decided not to post here, but as there seems to be no spells similar to mine posted here yet I might as well submit, if you promise not to -rep me for such a simple spell :p

Heavy Dance
The hero does a wild dance, jumping up and down on the ground! :eek:

Channeling ability, spawning Earthquakes (yes, like the Far Seer ultimate) right on top of the caster. While channeling, the hero will evade some attacks from the enemy (yes, the Evasion % is way too high for a dancing giant, but otherwise this ability would have been useless compared to Thunder Clap and War Stomp :D)

It would fit any large hero, could be your Tauren Cheftain, Mountain Giant, Ogre, etc! Easy to implent in your map, you need to do nothing more than copying the abilities and triggers (only ONE variable is used) and all the effects can be changed in the object editor (5 abilities used). However, you will need a type of dummy unit used for this spell only!
 

Attachments

  • HeavyDance_spellcontestNecrach.w3x
    18.3 KB · Views: 218

NeuroToxin

New Member
Reaction score
46
Windslash - [Q] [Level %d]
The orc are powerful creatures, so powerful, that they can kick an enemy into the air, and then while he's up there, and hit him numerous times. After he finishes with the target, he stomps very hard dealing damage.

Level 1: Hits them 6 times. Does 6.25 Damage Per Slash, and 40 Landing Damage.
Level 2: Hits them 8 times. Does 13 Damage Per Slash, Does 80 Landing Damage.
Level 3: Hits them 10 times. Does 19.5 Damage Per Slash, Does 120 Landing Damage.
Level 4: Hits them 12 times. Does 25 Damage Per Slash, does 160 Landing Damage.


I didn't try to copy Emiljr's at all, I'm sorry if you think so, but I didn't, I just noticed no one ever made this kind of spell before. Only problem is I couldn't figure out how to make KT2 work with two functions at different intervals for one trigger. Nevertheless, it looks pretty good, here it is.

EDIT: Optimized it a bit.
 

Attachments

  • Windslash.w3x
    35.9 KB · Views: 218

Angel_Island

Much long, many time, wow
Reaction score
56
Mega Jump​

Code: GUI
MUI/MPI: MUI

The Mountain Giant jumps up in the air and lands at the target point up to 900 units away over 2 seconds. Upon landing, all units around the Mountain Giant will be launched up in the air 1,5 seconds. When they land, they will take damage and become slowed by 50% for 4 seconds.

Level 1 - 100 damage.
Level 2 - 150 damage.
Level 3 - 200 damage.
Level 4 - 250 damage.
 

Attachments

  • Mega Jump.w3x
    27.3 KB · Views: 225
Reaction score
86
Blade Masters Big Entry​
MUI
vJASS
Requires:
T32, AutoFly
Description:
Blademaster calls down pole for him to jump off of. He rushes up to it,jumps on, rides the momentum, and jumps off of it with such power it pushes the pole right into the ground and, vice versa, him straight into the sky. He strikes the ground with such fury that it shoots nearby enemy units into the sky.
Storyline behind the name?:
One day the blademaster was feeling so depressed. He wondered why his ultimate attack was so... wimpy. Why couldn't he transform into a super beast like all the other heroes??... So he decided to devise a plan with his minions. He schemed of one move... one move to rule them all. After finally creating it, they asked him, what should we call it? Hence, The Blade Masters Big Entry, was born.
Level 1:
AOE:1200
Damage~500(decreases distance away)
Enemy Unit Flight Time~ 1.8(decreases distance away)
Level 2:
AOE:1600
Damage~700(decreases distance away)
Enemy Unit Flight Time~ 2.1(decreases distance away)
Level 3:
AOE:2000
Damage~900(decreases distance away)
Enemy Unit Flight Time~ 2.4(decreases distance away)

Code:
Code:
//Blade Master's Big Entry
//Calls down assistance from his allies. They launch a pole for the blademaster to land on, which he uses to jump incredible distances.
scope BMBE initializer InitFunc 
    
    ///! external ObjectMerger w3a ANrf BMBE alev 3 anam "Blade Master's Big Entry" aare 1 1200 aare 2 1600 aare 3 2000 aran 1 5000 aran 2 5000 aran 3 5000 acdn 1 30 acdn 2 30 acdn 3 30 amcs 1 200 amcs 2 220 amcs 3 240 Hbz1 1 0 Hbz1 2 0 Hbz1 3 0 aeff 1 0 aeff 2 0 aeff 3 0
    globals
        private integer SpellID='BMBE'
        //Dummy ID of VEXORIAN MODELS UNIT. get dummy.mdx from import.
        private integer DummyID='pole'
        //Animation of your unit running/walking
        private integer walkingAnimationIndex=6
        //Animation of your unit taunting or preparing to attack
        private integer preparingToAttackIndex=4//If none, just use stand(0)
        //Animation if your unit has a jump attack
        private integer jumpAttackIndex=3
        //Speed of walking, to match running speed
        private real walkAnimScale=2
        //Speed of preparation animation, in case it's out of sync
        private real prepareScale=1
        //Scale of the pole your using
        private real poleScale=4.5
        //model length of pole. DONT CHANGE UNLESS YOU ALTER POLE MODEL
        private real standardPoleLen=100 // Length of pole at scale 1
        //Distance the BM rushes
        private integer initialRushDist=600
        //Speed at which the BM rushes
        private real initialRunSpeed = 30
        //Grav constant. Increase to make greater arcs
        private real gravConst=5
        //Damage your hero suffers if it hits some hill while jumping
        private real onFailDamage=100
        //Peak height of jump
        private real peakHeight=1400
        //Base flight time of units 
        private real BaseFT=1.5
        //Each level increase
        private real LevelFT=.3
        //Base damage 
        private real BaseDMG=300
        //Level increase
        private real LevelDMG=200
        //Base AOE
        private real BaseAOE=800
        //Level AOE
        private real LevelAOE=400
        //Model of pole
        private string modelPath="Doodads\\LordaeronSummer\\Props\\TorchHuman\\TorchHuman.mdl"
        //slam effect
        private string slamEffect="Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl"
        
        
        
        
        
        
        
        
        
        
        //leave alone
        private location tempLoc=null
    endglobals
    private function dealDamage takes unit src,unit u, real dmg returns nothing
        call UnitDamageTarget(src,u,dmg,true,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNIVERSAL,WEAPON_TYPE_WHOKNOWS)
    endfunction
    private function SimError takes player ForPlayer, string msg returns nothing
        if (GetLocalPlayer() == ForPlayer) then
            call DisplayTimedTextToPlayer( ForPlayer, 0.52, -1.00, 2.00, "|cffffcc00"+msg+"|r" )
        endif
    endfunction
    private function GetUnitZ takes unit u returns real // Generic GetZ that includes terrain height
        local real z=0
        set tempLoc = GetUnitLoc(u)
        set z = GetLocationZ(tempLoc)
        call RemoveLocation(tempLoc)
        return z+GetUnitFlyHeight(u)
    endfunction
    private function SetUnitZ takes unit u, real z returns nothing // Generic SetZ that includes terrain height
        local real terrainZ=0
        set tempLoc = GetUnitLoc(u)
        set terrainZ = GetLocationZ(tempLoc)
        call RemoveLocation(tempLoc)
        call SetUnitFlyHeight(u,z-terrainZ,0)
    endfunction
    private function GetTerrainZ takes real x, real y returns real
        local real terrainZ=0
        set tempLoc = Location(x,y)
        set terrainZ = GetLocationZ(tempLoc)
        call RemoveLocation(tempLoc)
        return terrainZ
    endfunction
    private function CheckZ takes real x, real y, real z returns boolean
        local unit u = CreateUnit(Player(14),'hfoo',x,y,0)
        local real dz
        local real locZ
        call SetUnitZ(u,z)
        set dz = z-GetUnitZ(u)
        call RemoveUnit(u)
        if(dz<100 and dz>-100)then
            return true
        endif
        return false
    endfunction
    private function CheckBaseXYZ takes real x, real y,real z returns boolean
        local unit u 
        local real dx 
        local real dy
        local real dz
        set tempLoc = Location(x,y)
        set u = CreateUnitAtLoc(Player(14),'hfoo',tempLoc,0)
        set dx=GetUnitX(u)-x 
        set dy=GetUnitY(u)-y
        set dz=GetUnitZ(u)-z 
        call RemoveUnit(u)
        call RemoveLocation(tempLoc)
        set u =null
        if(dx<100 and dx>-100 and dy<100 and dy>-100 and dz<100 and dz>-100) then
            return true
        endif
        return false
    endfunction
    private function CheckBaseXY takes real x, real y returns boolean
        local unit u 
        local real dx 
        local real dy
        set tempLoc = Location(x,y)
        set u = CreateUnitAtLoc(Player(14),'hfoo',tempLoc,0)
        set dx=GetUnitX(u)-x 
        set dy=GetUnitY(u)-y
        call RemoveUnit(u)
        call RemoveLocation(tempLoc)
        set u =null
        if(dx<100 and dx>-100 and dy<100 and dy>-100) then
            return true
        endif
        return false
    endfunction
    
    private struct arrow // Helper arrow struct. Destroys itself on contact with ground.
        unit u=null
        real x=0
        real y=0
        real z=0
        real vx=0
        real vy=0
        real vz=0
        real killTimer=10//Kill time After impact
        
        private stub method periodic takes nothing returns nothing
            set .x=.x+.vx//Changes coordinates
            set .y=.y+.vy
            set .z=.z+.vz
            set .vz=.vz-gravConst//Changes ZVelocity
            call SetUnitX(.u,.x)//Sets units coords
            call SetUnitY(.u,.y)
            call SetUnitZ(.u,.z)
            if(GetUnitFlyHeight(.u)<10)then //When the unit is very close to the ground, STOP.
                if(.killTimer!=-1)then
                    call UnitApplyTimedLife(.u,'BTLF',.killTimer) //TimedLife
                endif
                set .u=null
                call this.stopPeriodic()
                call this.destroy()
            endif 
        endmethod
        implement T32x
    endstruct
    private struct dummyArrow extends arrow
        private method setDummyAngle takes nothing returns nothing
            local real theta = Atan2(.vy,.vx) //Gets theta angle
            local real phi = Atan2(-1*.vz,SquareRoot(.vx*.vx+.vy*.vy))*bj_RADTODEG //Gets phi in degrees.
            call SetUnitFacing(.u,180+theta*bj_RADTODEG)
            call SetUnitAnimationByIndex(.u,R2I(phi)) //Sets Phi via Vexorian Dummy model.
        endmethod
        private method periodic takes nothing returns nothing
            call super.periodic()
            call .setDummyAngle()//Sets Theta and Phi angles for the unit
        endmethod
    endstruct
    private function impartForce takes unit u, real frce returns nothing
        local arrow a = arrow.create()
        set a.u=u
        set a.x=GetUnitX(u)
        set a.y=GetUnitY(u)
        set a.z=GetUnitZ(u)+15
        set a.vx=0
        set a.vy=0
        set a.killTimer=-1
        set a.vz=gravConst*frce/2/T32_PERIOD
        call a.startPeriodic()
    endfunction
    struct spellstruct //Handles a unique instance of the spell.
        unit caster
        unit dummy
        real x
        real y
        real z
        real vx
        real vy
        real vz
        real a
        real b
        real c
        real dist
        real toX
        real toY
        real toZ
        real initZ
        real height
        real time
        real dummyRotation
        effect fx
        integer endTick=0
        integer mode =0
        stub method modeFive takes nothing returns boolean
            return true
        endmethod
        stub method modeFour takes nothing returns boolean
            return true
        endmethod
        private method modeThree takes nothing returns boolean
            set .x = .x+.vx
            set .y = .y+.vy
            set .z = .vz*.time-gravConst*.time*.time+.initZ
            set .time = .time+1
            if(.time==2)then
                call SetUnitScale(.dummy,poleScale*.75,poleScale*.75,poleScale*.75)
            endif
            if(.time==3)then
                call SetUnitScale(.dummy,poleScale*.5,poleScale*.5,poleScale*.5)
            endif
            if(.time==4)then
                call SetUnitScale(.dummy,poleScale*.25,poleScale*.25,poleScale*.25)
            endif
            if(.time>5)then 
                call RemoveUnit(.dummy)
            endif
            if (not CheckZ(.x,.y,.z))then
                call dealDamage(.caster,.caster,onFailDamage)
                return true
            endif
            call SetUnitX(.caster,.x)
            call SetUnitY(.caster,.y)
            call SetUnitZ(.caster,.z)
            if(.endTick-T32_Tick==20)then
                call SetUnitAnimationByIndex(.caster,jumpAttackIndex)
            endif
            if (T32_Tick>=.endTick)then
                call PauseUnit(.caster,false)
                call SetUnitFlyHeight(.caster,0,0)
                call DestroyEffect(AddSpecialEffect(slamEffect,.x+.vx,.y+.vx))
                set .mode=4
            endif
            return false
        endmethod
        private method modeTwo takes nothing returns boolean
            local real angle
            local real time
            set .dummyRotation=.dummyRotation+4
            set angle = GetUnitFacing(.dummy)*bj_DEGTORAD
            set .x= GetUnitX(.dummy)+standardPoleLen*poleScale*Cos(angle)*Sin(bj_PI/2-.dummyRotation*bj_DEGTORAD)
            set .y= GetUnitY(.dummy)+standardPoleLen*poleScale*Sin(angle)*Sin(bj_PI/2-.dummyRotation*bj_DEGTORAD)
            set .z= GetUnitZ(.dummy)+standardPoleLen*poleScale*Cos(bj_PI/2-.dummyRotation*bj_DEGTORAD)
            call SetUnitX(.caster,.x)
            call SetUnitY(.caster,.y)
            call SetUnitZ(.caster,.z)
            call SetUnitAnimationByIndex(.dummy,R2I(.dummyRotation))
            if(.dummyRotation>=135)then
                call SetUnitTimeScale(.caster,1)
                call SetUnitAnimationByIndex(.caster,0)
                set .dummyRotation=angle+bj_PI
                set .mode =3
                set angle = SquareRoot((.x-.toX)*(.x-.toX)+(.y-.toY)*(.y-.toY))
                set .vz=SquareRoot(4*gravConst*(.height-.z))
                set time=(.vz/2/gravConst+SquareRoot((.height-.toZ)/gravConst))//(.vz+SquareRoot(.vz*.vz+4*gravConst*(.z-.toZ)))/(2*gravConst)
                set .time=0
                set .initZ=.z
                set .endTick= R2I(time)+T32_Tick+1
                set angle = angle/time
                set .vx=angle*Cos(.dummyRotation)
                set .vy=angle*Sin(.dummyRotation)
                call DestroyEffect(AddSpecialEffect(slamEffect,GetUnitX(.dummy),GetUnitY(.dummy)))
            endif
            return false
        endmethod
        private method modeOne takes nothing returns boolean
            set .x=.x+.vx
            set .y=.y+.vy
            set .z=.z+.vz
            call SetUnitX(.caster,.x)
            call SetUnitY(.caster,.y)
            call SetUnitZ(.caster,.z)
            set .dummyRotation=.dummyRotation-1
            call SetUnitAnimationByIndex(.caster,R2I(.dummyRotation))
            if(T32_Tick>=.endTick)then
                call SetUnitTimeScale(.caster,prepareScale)
                call SetUnitAnimationByIndex(.caster,preparingToAttackIndex)
                set .mode=2
                set .dummyRotation=45
            endif
            return false
        endmethod
        private method modeZero takes nothing returns boolean
            local real x
            local real y
            local real z
            local real angle
            local real phi
            set .x=.x+.vx
            set .y=.y+.vy
            call SetUnitX(.caster,.x)
            call SetUnitY(.caster,.y)
            if(T32_Tick>=.endTick)then
                call SetUnitAnimationByIndex(.dummy,55)
                set .dummyRotation=55
                set angle = GetUnitFacing(.dummy)*bj_DEGTORAD
                set x= GetUnitX(.dummy)+standardPoleLen*poleScale*Cos(angle)*Sin(bj_PI/4)
                set y= GetUnitY(.dummy)+standardPoleLen*poleScale*Sin(angle)*Sin(bj_PI/4)
                set z= GetUnitZ(.dummy)+standardPoleLen*poleScale*Cos(bj_PI/4)
                set .vx=(x-.x)/10
                set .vy=(y-.y)/10
                set .vz=(z-.z)/10
                set .endTick= T32_Tick+9
                set .mode=1
            endif
            return false
        endmethod
        private method periodic takes nothing returns nothing
            local boolean flag =false
            if(GetUnitState(.caster,UNIT_STATE_LIFE)<=0)then
                call this.destroy()
                return
            endif
            if(.mode==0)then
                if(.modeZero())then
                    call this.destroy()
                endif
                return
            endif
            if(.mode==1)then
                if(.modeOne())then
                    call this.destroy()
                endif
                return
            endif
            if(.mode==2)then
                if(.modeTwo())then
                    call this.destroy()
                endif
                return
            endif
            if(.mode==3)then
                if(.modeThree())then
                    call this.destroy()
                endif
                return
            endif
            if(.mode==4)then
                if(.modeFour())then
                    call this.destroy()
                endif
                return
            endif
            if(.mode==5)then
                if(.modeFive())then
                    call this.destroy()
                endif
                return
            endif
            call this.destroy()
        endmethod
        method onDestroy takes nothing returns nothing
            set .caster=null
            set .dummy=null
            call this.stopPeriodic()
            call DestroyEffect(.fx)
        endmethod
        implement T32x
    endstruct
    private function filter takes nothing returns boolean
    
        return true
    endfunction

    private struct impaleEffect extends spellstruct
        real repelForce=1.5
        real damage=400
        real AOE=1000
        method modeFour takes nothing returns boolean
            local group g= CreateGroup()
            local unit u =null
            local arrow a
            local real linear=.repelForce*(1/.AOE/.AOE)
            local real lineardmg =.damage*(1/.AOE/.AOE)
            local real dist=0
            local real ux
            local real uy
            call GroupEnumUnitsInRange(g,.x,.y,.AOE,Condition(function filter))
            loop
            set u=FirstOfGroup(g)
            exitwhen u==null
                if(not IsUnitAlly(u,GetOwningPlayer(.caster)))then
                    set ux=GetUnitX(u)
                    set uy=GetUnitY(u)
                    set dist = SquareRoot((ux-.x)*(ux-.x)+(uy-.y)*(uy-.y))
                    call dealDamage(.caster,u,.damage-dist*dist*lineardmg)
                    call impartForce(u,.repelForce-dist*dist*linear)
                endif
                call GroupRemoveUnit(g,u)
            endloop
            call DestroyGroup(g)
            set g= null
            return true
        endmethod
    endstruct
    private function Conditions takes nothing returns boolean
        return (GetSpellAbilityId()==SpellID)
    endfunction
    private function testPoint takes nothing returns nothing
        local unit caster = GetTriggerUnit()
        local real x = GetUnitX(caster)
        local real y = GetUnitY(caster)
        local real z = GetUnitZ(caster)
        local real toX
        local real toY
        local real angle=0
        local real d=50
        local real tstx=x
        local real tsty=y
        local real tstz
        local real dist
        set tempLoc=GetSpellTargetLoc()
        set toX=GetLocationX(tempLoc)
        set toY=GetLocationY(tempLoc)
        set angle = Atan2(toY-y, toX-x)
        set dist = SquareRoot((toX-x)*(toX-x)+(toY-y)*(toY-y))
        call RemoveLocation(tempLoc)
        if(dist<initialRushDist+200)then
            call SimError(GetOwningPlayer(caster),"Too close to target location. Move back "+R2S(initialRushDist+200-dist))
            call IssueImmediateOrder(caster,"stop")
            return
        endif
        if(not CheckBaseXYZ(x+initialRushDist*Cos(angle),y+initialRushDist*Sin(angle),z))then
            call SimError(GetOwningPlayer(caster),"Pole vault Zone is not clear.")
            call IssueImmediateOrder(caster,"stop")
            return
        endif
        loop
        exitwhen d>initialRushDist
            set tstz=GetTerrainZ(tstx,tsty)
            set tstx=x+d*Cos(angle)
            set tsty=y+d*Sin(angle)
            if(not CheckBaseXYZ(tstx,tsty,tstz))then
                call SimError(GetOwningPlayer(caster),"No clear path.")
                call IssueImmediateOrder(caster,"stop")
                return
            endif
            set d=d+50
        endloop
        if(not CheckBaseXY(toX,toY))then
            call SimError(GetOwningPlayer(caster),"Landing Zone is not clear.")
            call IssueImmediateOrder(caster,"stop")
            return
        endif
    endfunction
    private function actions takes nothing returns nothing
        local unit caster = GetTriggerUnit()
        local real x = GetUnitX(caster)
        local real y = GetUnitY(caster)
        local real z = GetUnitZ(caster)
        local real angle=0
        local real time=0
        local real temp=0
        local real level =GetUnitAbilityLevel(caster,SpellID)
        local impaleEffect instance = impaleEffect.create()
        local dummyArrow a = dummyArrow.create()
        set tempLoc=GetSpellTargetLoc()
        call IssueImmediateOrder(caster,"stop")
        set instance.toX=GetLocationX(tempLoc)
        set instance.toY=GetLocationY(tempLoc)
        set instance.toZ=GetLocationZ(tempLoc)
        set instance.height=peakHeight
        set angle = Atan2(instance.toY-y,instance.toX-x)
        set instance.caster=caster
        set instance.x=x
        set instance.y=y
        set instance.z=z
        set time=(initialRushDist-100)/(initialRunSpeed)
        set instance.endTick= T32_Tick+R2I(time)
        set instance.vx=initialRunSpeed*Cos(angle)
        set instance.vy=initialRunSpeed*Sin(angle)
        set instance.dummy = CreateUnit(GetOwningPlayer(caster),DummyID,x,y,180+angle*bj_RADTODEG)
        set instance.repelForce=BaseFT+LevelFT*level
        set instance.damage=BaseDMG+LevelDMG*level
        set instance.AOE=BaseAOE+LevelAOE*level
        set a.u=instance.dummy
        set a.x=x
        set a.y=y
        set time = time*.6
        set a.z=gravConst*time*time
        set temp=initialRushDist/time
        set a.vx=temp*Cos(angle)
        set a.vy=temp*Sin(angle)
        set a.killTimer=-1
        call a.startPeriodic()
        call instance.startPeriodic()
        call SetUnitTimeScale(instance.dummy,5)
        call PauseUnit(caster,true)
        call SetUnitTimeScale(caster,walkAnimScale)
        call SetUnitAnimationByIndex(caster,walkingAnimationIndex)
        set instance.fx=AddSpecialEffectTarget(modelPath,instance.dummy,"origin")
        call SetUnitScale(instance.dummy,poleScale,poleScale,poleScale)
        call RemoveLocation(tempLoc)
    endfunction
    private function InitFunc takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition(t,Condition(function Conditions))
        call TriggerAddAction(t,function actions)
        set t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CAST )
        call TriggerAddCondition(t,Condition(function Conditions))
        call TriggerAddAction(t,function testPoint)
    endfunction
    
endscope

Rambling and excuses:
:banghead::banghead: Sorry about the crappy submission. Finished it literally 10 minutes ago. I also just noticed it is very similar to the one right above mine... lol Oh well. I finished the mechanism for jumping which was what this really was all about. I originally was going to do more, but midterms in college. Had no time... anyway Romek I hope you enjoy, because I made this as per your request, awhile ago, about a pole vault lol. Although im sure you meant by a different mechanism.

Also sorry about the crappy test map... Just was trying to show off capabilties. Didnt get a chance to make it pretty or nice.
The ability also inflicts rain of fire buff which I couldn't get rid of in time...
I gave him scrolls of teleportation just in case you get stuck on a cliff or something.
The jumping mechanism checks the path the blademaster travels(initial rush) for obstacles as well as the landing zone.
 

Attachments

  • Infinitegde contest.w3x
    51 KB · Views: 224
Status
Not open for further replies.
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top