• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Water Image v.101d

Water Image

Creates number of illusions of the Hero from the water splash to confuse the enemy.

Level 1 - Creates 8 illusions, they deal 15% damage and take 500% damage.
Level 2 - Creates 9 illusions, they deal 18% damage and take 400% damage.
Level 3 - Creates 10 illusions, they deal 21% damage and take 300% damage.


JASS:
library WaterImage requires xefx, xecast, SpellEffectEvent, T32, SimError optional BoundSentinel
//*------------------------------------------------------------------------------------------
//* _________________________________________________________________________________________
//*                             water image - v1.01d
//*                                 by scorpion182
//* _________________________________________________________________________________________
//* Requirements:
//* 
//* . JassHelper http://www.wc3c.net/
//* . T32 http://www.thehelper.net/
//* . bound sentinel (optional), xe, SimError by Vexorian http://www.wc3c.net/
//* . SpellEffectEvent by Bribe 
//* . RegisterPlayerUnitEvent by Magtheridon96
//*------------------------------------------------------------------------------------------
//*-------------CALIBRATION SECTION----------------------------------------------------------
    globals
        // spell rawcode
        private constant integer SPELL_ID               =   'A000' 
        
        //dummy spell id
        private constant integer DUMMY_SPELL_ID         =   'A001' 
        
        //dummy order id
        private constant integer DUMMY_ORDER_ID         =   852274
        
        //missile fx path
        private constant string  MISSILE_FX             =   "Abilities\\Weapons\\WaterElementalMissile\\WaterElementalMissile.mdl" 
        
        //splash fx path
        private constant string  SPLASH_FX              =   "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl"
        
        //max bounce
        private constant integer MAX_BOUNCE             =   5
        
        private constant integer MAX_INSTANCE_MISSILE   =   30
        
        //missile speed
        private constant real    SPEED                  =   300. 
        
        //maximum bounce height
        private constant real    MAX_HEIGHT             =   100. 
        
        //missile scale
        private constant real    MISSILE_SCALE          =   1.0 
        
        //distance increment
        private constant real    DISTANCE_INC           =   SPEED * T32_PERIOD 
        
        //error message
        private constant string  ERROR_MSG              =   "Another instance is running for this caster." 
        
        private constant boolean PRELOAD_FX             = true
    endglobals
    
    //image count
    private constant function GetImageCount takes integer lvl returns integer
        return (lvl * 1) + 7
    endfunction
    
    //spell area of effect
    private constant function GetAoE takes integer lvl returns real
        return (lvl * 0) + 500.
    endfunction

//*------------------------------------------------------------------------------------------
//*-----------END OF CALIBRATION-------------------------------------------------------------
    globals
        private xecast cast
        private Table activeTable
    endglobals
    
    //Parabolic Function by Moyack and Spec
    private function ParabolaZ takes real h, real d, real x returns real
      return (4 * h / d) * (d - x) * (x / d)
    endfunction
    
    globals
        private constant real A = 2 * bj_PI
    endglobals
    
    private struct data
        integer total                                       //image count
        integer lvl                                         //level of ability when it cast
        real x                                              //x coord of spell target
        real y                                              //y coord of spell target
        unit caster                                         //caster
        unit array illusion[MAX_INSTANCE_MISSILE]
        xefx array fx[MAX_INSTANCE_MISSILE]
        real array pos[MAX_INSTANCE_MISSILE] 
        real array distance[MAX_INSTANCE_MISSILE] 
        integer array n_bounce[MAX_INSTANCE_MISSILE]
        real max_h = MAX_HEIGHT
        real max_dist = 0
        integer counter = 0
        static thistype temp = 0
        
        static method create takes unit c, real dis, integer count, integer lvl returns thistype
            local data this = thistype.allocate()
            local integer i = 0
            
            if (GetLocalPlayer() == GetOwningPlayer(c)) then
                call SelectUnit(c, true)
            endif
            
            call DestroyEffect(AddSpecialEffect(SPLASH_FX, .x, .y))
            set .total = count
            set .caster = c
            set .lvl = lvl
            set .x = GetUnitX(c)
            set .y = GetUnitY(c)
            set .max_dist = dis
            
            loop
            exitwhen i ==.total
                set .fx[i] = xefx.create(x, y, i*A/.total)
                set .fx[i].fxpath = MISSILE_FX
                set .fx[i].scale = MISSILE_SCALE
                set .distance[i] = dis
                set .pos[i] = dis
                set i = i + 1
            endloop
                        
            return this
        endmethod
        
        private method destroy takes nothing returns nothing 
            local integer i = 0
            local integer shuffle = GetRandomInt(0, .total - 1)
            
            set temp = this
            
            loop
            exitwhen i ==.total
            
                set cast.level = .lvl
                set cast.owningplayer = GetOwningPlayer(.caster) 
                call cast.castOnTarget(.caster)
                
                call DestroyEffect(AddSpecialEffect(SPLASH_FX, .fx[i].x, .fx[i].y))
                
                call SetUnitX(.illusion[i], .fx[i].x)
                call SetUnitY(.illusion[i], .fx[i].y)
                call SetUnitFacing(.illusion[i], (.fx[i].xyangle * bj_RADTODEG) - 180.)
                    
                if (GetLocalPlayer() == GetOwningPlayer(.illusion[i])) then
                    call SelectUnit(.illusion[i], true)
                endif
                
                //shuffle the caster with the image
                if i == shuffle then
                    call SetUnitX(.caster, GetUnitX(.illusion[i]))
                    call SetUnitY(.caster, GetUnitY(.illusion[i]))
                    call SetUnitFacing(.caster, (.fx[i].xyangle * bj_RADTODEG) - 180.)
                    call RemoveUnit(.illusion[i])
                endif
                
                call .fx[i].destroy()
            
                set i = i + 1
            endloop

            set activeTable[GetHandleId(.caster)] = 0
        endmethod
        
        method periodic takes nothing returns nothing
            local real x
            local real y
            local real dx
            local real dy
            local integer i = 0
            
            loop
            exitwhen i ==.total
            
                if (.pos[i] > 0) then
                    set .fx[i].x =.fx[i].x + DISTANCE_INC * Cos(.fx[i].xyangle)
                    set .fx[i].y =.fx[i].y + DISTANCE_INC * Sin(.fx[i].xyangle) 
                    set .pos[i] = .pos[i] - DISTANCE_INC
                    set .fx[i].z = ParabolaZ(.max_h, .distance[i], .pos[i])
                else
                    if .n_bounce[i] <= MAX_BOUNCE then
                        set .n_bounce[i] = .n_bounce[i] + 1
                        set x = .fx[i].x + .max_dist * Cos(.fx[i].xyangle)
                        set y = .fx[i].y + .max_dist * Sin(.fx[i].xyangle)
                        set dx = x - .fx[i].x
                        set dy = y - .fx[i].y
                        set .distance[i] = SquareRoot(dx * dx + dy * dy)
                        set .pos[i] = .distance[i]
                    else
                        call .stopPeriodic()
                        call .destroy()
                        exitwhen true
                    endif
                endif
                
                set i = i + 1
            endloop
        endmethod
        
        implement T32x
        
        static method spellEffect takes nothing returns nothing
            local thistype this
            local unit c = GetTriggerUnit()
            local integer lvl = GetUnitAbilityLevel(c, SPELL_ID)
            
            if activeTable[GetHandleId(c)] == 0 then

                set this = thistype.create(c, GetAoE(lvl) / MAX_BOUNCE, GetImageCount(lvl), lvl)
                set activeTable[GetHandleId(c)] = this
                call .startPeriodic()
            else
                call SimError(GetOwningPlayer(c), ERROR_MSG)
            endif
            
            set c = null
        endmethod
        
        static method illusionInit takes nothing returns nothing
            local unit s = GetSummonedUnit()
            
            if temp != 0 then
                set temp.illusion[temp.counter] = s
                set temp.counter = temp.counter + 1
            endif
            
            set s = null
        endmethod
        
        static method onInit takes nothing returns nothing
            call RegisterSpellEffectEvent(SPELL_ID, function thistype.spellEffect)
            
            call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SUMMON, function thistype.illusionInit)
            
            //xe cast init
            set cast = xecast.create()                         
            set cast.abilityid = DUMMY_SPELL_ID 
            set cast.orderid   = DUMMY_ORDER_ID
            
            //table
            set activeTable = Table.create() 
            
            //preload fx and ability
            
            static if PRELOAD_FX then
                set bj_lastCreatedUnit = CreateUnit(Player(15), XE_DUMMY_UNITID, 0, 0, 0)
                
                call UnitAddAbility(bj_lastCreatedUnit, DUMMY_SPELL_ID)
                call RemoveUnit(bj_lastCreatedUnit)
            
                call Preload(MISSILE_FX)
                call Preload(SPLASH_FX)
            endif
            
        endmethod
        
    endstruct
    
endlibrary


History
v1.00
-----------------------
- Initial release for the contest

v.101
-----------------------
- remove autoindex, merge function ParabolaZ into spell trigger
- merge 2 struct into 1 struct only
- uses T32 instead timerutils

v.101b/c/d
-----------------------
fix more code and tooltip

Keywords:
water, image, spell, illusion, illusions, confuse, enemy, single, area, target, aoe, number, ninja
Contents

Water Image v1.01d (Map)

Reviews
1 Dec 2011 Bribe: Looks pretty solid. This was the winning entry for the Zephyr Illusion contest.

Moderator

M

Moderator

1 Dec 2011
Bribe: Looks pretty solid. This was the winning entry for the Zephyr Illusion contest.
 
Level 16
Joined
Jun 9, 2008
Messages
734
thanks for the comments and suggestions guys :ogre_haosis:

ok, here's the quick update, i will do the other things later :ogre_hurrhurr:

JASS:
library WaterImage requires xefx, xecast, SpellEffectEvent, T32, SimError optional BoundSentinel
//*------------------------------------------------------------------------------------------
//* _________________________________________________________________________________________
//*                             water image - v1.01b
//*                                 by scorpion182
//* _________________________________________________________________________________________
//* Requirements:
//* 
//* . JassHelper [url]http://www.wc3c.net/[/url]
//* . T32 [url]http://www.thehelper.net/[/url]
//* . bound sentinel (optional), xe, SimError by Vexorian [url]http://www.wc3c.net/[/url]
//* . SpellEffectEvent by Magtheridon96
//* . RegisterPlayerUnitEvent by Bribe
//*------------------------------------------------------------------------------------------
//*-------------CALIBRATION SECTION----------------------------------------------------------
    globals
        // spell rawcode
        private constant integer SPELL_ID               =   'A000' 
        
        //dummy spell id
        private constant integer DUMMY_SPELL_ID         =   'A001' 
        
        //dummy order id
        private constant integer DUMMY_ORDER_ID         =   852274
        
        //missile fx path
        private constant string  MISSILE_FX             =   "Abilities\\Weapons\\WaterElementalMissile\\WaterElementalMissile.mdl" 
        
        //splash fx path
        private constant string  SPLASH_FX              =   "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl"
        
        //max bounce
        private constant integer MAX_BOUNCE             =   5
        
        private constant integer MAX_INSTANCE_MISSILE   =   30
        
        //missile speed
        private constant real    SPEED                  =   300. 
        
        //maximum bounce height
        private constant real    MAX_HEIGHT             =   100. 
        
        //missile scale
        private constant real    MISSILE_SCALE          =   1.0 
        
        //distance increment
        private constant real    DISTANCE_INC           =   SPEED * T32_PERIOD 
        
        //error message
        private constant string  ERROR_MSG              =   "Another instance is running for this caster." 
        
        private constant boolean PRELOAD_FX             = true
    endglobals
    
    //image count
    private constant function GetImageCount takes integer lvl returns integer
        return (lvl * 1) + 7
    endfunction
    
    //spell area of effect
    private constant function GetAoE takes integer lvl returns real
        return (lvl * 0) + 500.
    endfunction

//*------------------------------------------------------------------------------------------
//*-----------END OF CALIBRATION-------------------------------------------------------------
    globals
        private xecast cast
        private Table activeTable
    endglobals
    
    //Parabolic Function by Moyack and Spec
    private function ParabolaZ takes real h, real d, real x returns real
      return (4 * h / d) * (d - x) * (x / d)
    endfunction
    
    globals
        private constant real A = 2 * bj_PI
    endglobals
    
    private struct data
        integer total                                       //image count
        integer lvl                                         //level of ability when it cast
        real x                                              //x coord of spell target
        real y                                              //y coord of spell target
        unit caster                                         //caster
        unit array illusion[MAX_INSTANCE_MISSILE]
        xefx array fx[MAX_INSTANCE_MISSILE]
        real array pos[MAX_INSTANCE_MISSILE] 
        real array distance[MAX_INSTANCE_MISSILE] 
        integer array n_bounce[MAX_INSTANCE_MISSILE]
        real max_h = MAX_HEIGHT
        real max_dist = 0
        integer counter = 0
        static thistype temp = 0
        
        static method create takes unit c, real dis, integer count, integer lvl returns thistype
            local data this = thistype.allocate()
            local integer i = 0
            
            if (GetLocalPlayer() == GetOwningPlayer(c)) then
                call ClearSelection()
                call SelectUnit(c, true)
            endif
            
            call DestroyEffect(AddSpecialEffect(SPLASH_FX, .x, .y))
            set .total = count
            set .caster = c
            set .lvl = lvl
            set .x = GetUnitX(c)
            set .y = GetUnitY(c)
            set .max_dist = dis
            
            loop
            exitwhen i ==.total
                set .fx[i] = xefx.create(x, y, i*A/.total)
                set .fx[i].fxpath = MISSILE_FX
                set .fx[i].scale = MISSILE_SCALE
                set .distance[i] = dis
                set .pos[i] = dis
                set i = i + 1
            endloop
                        
            return this
        endmethod
        
        private method destroy takes nothing returns nothing 
            local integer i = 0
            local integer shuffle = GetRandomInt(0, .total - 1)
            
            set temp = this
            
            loop
            exitwhen i ==.total
            
                set cast.level = .lvl
                set cast.owningplayer = GetOwningPlayer(.caster) 
                call cast.castOnTarget(.caster)
                
                call DestroyEffect(AddSpecialEffect(SPLASH_FX, .fx[i].x, .fx[i].y))
                
                call SetUnitX(.illusion[i], .fx[i].x)
                call SetUnitY(.illusion[i], .fx[i].y)
                call SetUnitFacing(.illusion[i], (.fx[i].xyangle * bj_RADTODEG) - 180.)
                    
                if (GetLocalPlayer() == GetOwningPlayer(.illusion[i])) then
                    call SelectUnit(.illusion[i], true)
                endif
                
                //shuffle the caster with the image
                if i == shuffle then
                    call SetUnitX(.caster, GetUnitX(.illusion[i]))
                    call SetUnitY(.caster, GetUnitY(.illusion[i]))
                    call SetUnitFacing(.caster, (.fx[i].xyangle * bj_RADTODEG) - 180.)
                    call RemoveUnit(.illusion[i])
                endif
                
                call .fx[i].destroy()
            
                set i = i + 1
            endloop

            set activeTable[GetHandleId(.caster)] = 0
        endmethod
        
        method periodic takes nothing returns nothing
            local real x
            local real y
            local real dx
            local real dy
            local integer i = 0
            local boolean finish = false
            
            loop
            exitwhen i ==.total
            
                if (.pos[i] > 0) then
                    set .fx[i].x =.fx[i].x + DISTANCE_INC * Cos(.fx[i].xyangle)
                    set .fx[i].y =.fx[i].y + DISTANCE_INC * Sin(.fx[i].xyangle) 
                    set .pos[i] = .pos[i] - DISTANCE_INC
                    set .fx[i].z = ParabolaZ(.max_h, .distance[i], .pos[i])
                else
                    if .n_bounce[i] <= MAX_BOUNCE then
                        set .n_bounce[i] = .n_bounce[i] + 1
                        set x = .fx[i].x + .max_dist * Cos(.fx[i].xyangle)
                        set y = .fx[i].y + .max_dist * Sin(.fx[i].xyangle)
                        set dx = x - .fx[i].x
                        set dy = y - .fx[i].y
                        set .distance[i] = SquareRoot(dx * dx + dy * dy)
                        set .pos[i] = .distance[i]
                    else
                        call .stopPeriodic()
                        call .destroy()
                        exitwhen true
                    endif
                endif
                
                set i = i + 1
            endloop
        endmethod
        
        implement T32x
        
        static method spellEffect takes nothing returns nothing
            local thistype this
            local unit c = GetTriggerUnit()
            local integer lvl = GetUnitAbilityLevel(c, SPELL_ID)
            
            if activeTable[GetHandleId(c)] == 0 then

                set this = thistype.create(c, GetAoE(lvl) / MAX_BOUNCE, GetImageCount(lvl), lvl)
                set activeTable[GetHandleId(c)] = this
                call .startPeriodic()
            else
                call SimError(GetOwningPlayer(c), ERROR_MSG)
            endif
            
            set c = null
        endmethod
        
        static method illusionInit takes nothing returns nothing
            local unit s = GetSummonedUnit()
            
            if temp != 0 then
                set temp.illusion[temp.counter] = s
                set temp.counter = temp.counter + 1
            endif
            
            set s = null
        endmethod
        
        static method onInit takes nothing returns nothing
            call RegisterSpellEffectEvent(SPELL_ID, function thistype.spellEffect)
            
            call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SUMMON, function thistype.illusionInit)
            
            //xe cast init
            set cast = xecast.create()                         
            set cast.abilityid = DUMMY_SPELL_ID 
            set cast.orderid   = DUMMY_ORDER_ID
            
            //table
            set activeTable = Table.create() 
            
            //preload fx and ability
            
            static if PRELOAD_FX then
                set bj_lastCreatedUnit = CreateUnit(Player(15), XE_DUMMY_UNITID, 0, 0, 0)
                
                call UnitAddAbility(bj_lastCreatedUnit, DUMMY_SPELL_ID)
                call RemoveUnit(bj_lastCreatedUnit)
            
                call Preload(MISSILE_FX)
                call Preload(SPLASH_FX)
            endif
            
        endmethod
        
    endstruct
    
endlibrary
 
Level 16
Joined
Jun 9, 2008
Messages
734
EDIT:

//* . SpellEffectEvent by Magtheridon96
//* . RegisterPlayerUnitEvent by Bribe

- You got these two mixed up ;)



oops sorry, fixed now :ogre_hurrhurr:

Bribe said:
Bribe: Please implement the changes requested by Maker before we approve this (for example not clearing the entire selection when the spell is done).

fixed :D


JASS:
library WaterImage requires xefx, xecast, SpellEffectEvent, T32, SimError optional BoundSentinel
//*------------------------------------------------------------------------------------------
//* _________________________________________________________________________________________
//*                             water image - v1.01d
//*                                 by scorpion182
//* _________________________________________________________________________________________
//* Requirements:
//* 
//* . JassHelper [url]http://www.wc3c.net/[/url]
//* . T32 [url]http://www.thehelper.net/[/url]
//* . bound sentinel (optional), xe, SimError by Vexorian [url]http://www.wc3c.net/[/url]
//* . SpellEffectEvent by Bribe 
//* . RegisterPlayerUnitEvent by Magtheridon96
//*------------------------------------------------------------------------------------------
//*-------------CALIBRATION SECTION----------------------------------------------------------
    globals
        // spell rawcode
        private constant integer SPELL_ID               =   'A000' 
        
        //dummy spell id
        private constant integer DUMMY_SPELL_ID         =   'A001' 
        
        //dummy order id
        private constant integer DUMMY_ORDER_ID         =   852274
        
        //missile fx path
        private constant string  MISSILE_FX             =   "Abilities\\Weapons\\WaterElementalMissile\\WaterElementalMissile.mdl" 
        
        //splash fx path
        private constant string  SPLASH_FX              =   "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl"
        
        //max bounce
        private constant integer MAX_BOUNCE             =   5
        
        private constant integer MAX_INSTANCE_MISSILE   =   30
        
        //missile speed
        private constant real    SPEED                  =   300. 
        
        //maximum bounce height
        private constant real    MAX_HEIGHT             =   100. 
        
        //missile scale
        private constant real    MISSILE_SCALE          =   1.0 
        
        //distance increment
        private constant real    DISTANCE_INC           =   SPEED * T32_PERIOD 
        
        //error message
        private constant string  ERROR_MSG              =   "Another instance is running for this caster." 
        
        private constant boolean PRELOAD_FX             = true
    endglobals
    
    //image count
    private constant function GetImageCount takes integer lvl returns integer
        return (lvl * 1) + 7
    endfunction
    
    //spell area of effect
    private constant function GetAoE takes integer lvl returns real
        return (lvl * 0) + 500.
    endfunction

//*------------------------------------------------------------------------------------------
//*-----------END OF CALIBRATION-------------------------------------------------------------
    globals
        private xecast cast
        private Table activeTable
    endglobals
    
    //Parabolic Function by Moyack and Spec
    private function ParabolaZ takes real h, real d, real x returns real
      return (4 * h / d) * (d - x) * (x / d)
    endfunction
    
    globals
        private constant real A = 2 * bj_PI
    endglobals
    
    private struct data
        integer total                                       //image count
        integer lvl                                         //level of ability when it cast
        real x                                              //x coord of spell target
        real y                                              //y coord of spell target
        unit caster                                         //caster
        unit array illusion[MAX_INSTANCE_MISSILE]
        xefx array fx[MAX_INSTANCE_MISSILE]
        real array pos[MAX_INSTANCE_MISSILE] 
        real array distance[MAX_INSTANCE_MISSILE] 
        integer array n_bounce[MAX_INSTANCE_MISSILE]
        real max_h = MAX_HEIGHT
        real max_dist = 0
        integer counter = 0
        static thistype temp = 0
        
        static method create takes unit c, real dis, integer count, integer lvl returns thistype
            local data this = thistype.allocate()
            local integer i = 0
            
            if (GetLocalPlayer() == GetOwningPlayer(c)) then
                call SelectUnit(c, true)
            endif
            
            call DestroyEffect(AddSpecialEffect(SPLASH_FX, .x, .y))
            set .total = count
            set .caster = c
            set .lvl = lvl
            set .x = GetUnitX(c)
            set .y = GetUnitY(c)
            set .max_dist = dis
            
            loop
            exitwhen i ==.total
                set .fx[i] = xefx.create(x, y, i*A/.total)
                set .fx[i].fxpath = MISSILE_FX
                set .fx[i].scale = MISSILE_SCALE
                set .distance[i] = dis
                set .pos[i] = dis
                set i = i + 1
            endloop
                        
            return this
        endmethod
        
        private method destroy takes nothing returns nothing 
            local integer i = 0
            local integer shuffle = GetRandomInt(0, .total - 1)
            
            set temp = this
            
            loop
            exitwhen i ==.total
            
                set cast.level = .lvl
                set cast.owningplayer = GetOwningPlayer(.caster) 
                call cast.castOnTarget(.caster)
                
                call DestroyEffect(AddSpecialEffect(SPLASH_FX, .fx[i].x, .fx[i].y))
                
                call SetUnitX(.illusion[i], .fx[i].x)
                call SetUnitY(.illusion[i], .fx[i].y)
                call SetUnitFacing(.illusion[i], (.fx[i].xyangle * bj_RADTODEG) - 180.)
                    
                if (GetLocalPlayer() == GetOwningPlayer(.illusion[i])) then
                    call SelectUnit(.illusion[i], true)
                endif
                
                //shuffle the caster with the image
                if i == shuffle then
                    call SetUnitX(.caster, GetUnitX(.illusion[i]))
                    call SetUnitY(.caster, GetUnitY(.illusion[i]))
                    call SetUnitFacing(.caster, (.fx[i].xyangle * bj_RADTODEG) - 180.)
                    call RemoveUnit(.illusion[i])
                endif
                
                call .fx[i].destroy()
            
                set i = i + 1
            endloop

            set activeTable[GetHandleId(.caster)] = 0
        endmethod
        
        method periodic takes nothing returns nothing
            local real x
            local real y
            local real dx
            local real dy
            local integer i = 0
            
            loop
            exitwhen i ==.total
            
                if (.pos[i] > 0) then
                    set .fx[i].x =.fx[i].x + DISTANCE_INC * Cos(.fx[i].xyangle)
                    set .fx[i].y =.fx[i].y + DISTANCE_INC * Sin(.fx[i].xyangle) 
                    set .pos[i] = .pos[i] - DISTANCE_INC
                    set .fx[i].z = ParabolaZ(.max_h, .distance[i], .pos[i])
                else
                    if .n_bounce[i] <= MAX_BOUNCE then
                        set .n_bounce[i] = .n_bounce[i] + 1
                        set x = .fx[i].x + .max_dist * Cos(.fx[i].xyangle)
                        set y = .fx[i].y + .max_dist * Sin(.fx[i].xyangle)
                        set dx = x - .fx[i].x
                        set dy = y - .fx[i].y
                        set .distance[i] = SquareRoot(dx * dx + dy * dy)
                        set .pos[i] = .distance[i]
                    else
                        call .stopPeriodic()
                        call .destroy()
                        exitwhen true
                    endif
                endif
                
                set i = i + 1
            endloop
        endmethod
        
        implement T32x
        
        static method spellEffect takes nothing returns nothing
            local thistype this
            local unit c = GetTriggerUnit()
            local integer lvl = GetUnitAbilityLevel(c, SPELL_ID)
            
            if activeTable[GetHandleId(c)] == 0 then

                set this = thistype.create(c, GetAoE(lvl) / MAX_BOUNCE, GetImageCount(lvl), lvl)
                set activeTable[GetHandleId(c)] = this
                call .startPeriodic()
            else
                call SimError(GetOwningPlayer(c), ERROR_MSG)
            endif
            
            set c = null
        endmethod
        
        static method illusionInit takes nothing returns nothing
            local unit s = GetSummonedUnit()
            
            if temp != 0 then
                set temp.illusion[temp.counter] = s
                set temp.counter = temp.counter + 1
            endif
            
            set s = null
        endmethod
        
        static method onInit takes nothing returns nothing
            call RegisterSpellEffectEvent(SPELL_ID, function thistype.spellEffect)
            
            call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SUMMON, function thistype.illusionInit)
            
            //xe cast init
            set cast = xecast.create()                         
            set cast.abilityid = DUMMY_SPELL_ID 
            set cast.orderid   = DUMMY_ORDER_ID
            
            //table
            set activeTable = Table.create() 
            
            //preload fx and ability
            
            static if PRELOAD_FX then
                set bj_lastCreatedUnit = CreateUnit(Player(15), XE_DUMMY_UNITID, 0, 0, 0)
                
                call UnitAddAbility(bj_lastCreatedUnit, DUMMY_SPELL_ID)
                call RemoveUnit(bj_lastCreatedUnit)
            
                call Preload(MISSILE_FX)
                call Preload(SPLASH_FX)
            endif
            
        endmethod
        
    endstruct
    
endlibrary
 
Last edited:
Level 7
Joined
Sep 2, 2011
Messages
350
Okay. I'm here again to rate the spell. I would like to let you know that I really like this spell. It's pretty simple yet it's useful. The effect will really able to confuse anyone including me. I will gladly use this spell maybe in the future.

Rating: 4/5
The spell works. MUI and Leakless.
Clean and simple spell
The effects are average and quite nice
It does confuses enemies
It's kinda awkward when the caster quickly disappears it might be a good idea to have a fade effect.
But that is only optional and other than that, the spell is great.
 
Top