1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Find your way through the deepest dungeon in the 18th Mini Mapping Contest Poll.
    Dismiss Notice
  3. A brave new world lies beyond the seven seas. Join the 34th Modeling Contest today!
    Dismiss Notice
  4. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
Hive 3 Remoosed BETA - NOW LIVE. Go check it out at BETA Hive Workshop! Post your feedback in this new forum BETA Feedback.
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Shadow Images Sword v1.1

Submitted by nhocklanhox6
This bundle is marked as substandard. It may contain bugs, not perform optimally or otherwise be in violation of the submission rules.
Spell Look Like
https://www.youtube.com/watch?v=3y7CGo7Asic&feature=youtu.be


Screen shot
Show
[​IMG]
[​IMG]


Spell code
Code (vJASS):
//***************************************************************************
//***************************************************************************
//***************************************************************************
//      S H A D O W S    I M A G E S     S W O R D
//                      -----------------------------------------
//                                          By: Nyuu
//      Version: 1.1
//
//      Sepll Description:
//  `                       - Use energy and power of the ground, Blade Master jump up from the ground to the target point,
//                          but because the power of the blade is too powerful, his sword cause the image of him has been splitted into two,
//                          this creates two illusions of him and has the same power plunges straight down to the ground,
//                          when the illusions hit the ground, it causing 100/150/200/250 damages to enemies simultaneously
//                          stunning them for 2/2.25/2.50/2.75 seconds around 250 range of the illusions, and then,
//                          the sword will pull them back, after mirage disappears, it creates a shock ground,
//                          making him invisible for 1.5 seconds.

//     Credits:
//              BoundSentinel - http://www.wc3c.net/showthread.php?t=102576

//          - Installation:
//                                - Import/copy Spell Code and Requires folder to your map
//                                - Import/copy the custom ability and unit to your map and change the SPELL_ID, DUMMY_ID, DUMMY_SPELL_ID,
//                               BUFF_ID if needed
//                                - You may view the raw ID of the objects by pressing CTRL+D in the object editor
//                                - You may play with the configurables below
//
//
//***************************************************************************
//***************************************************************************
//***************************************************************************

library ShadowImagesSword
   
    globals
   
        //-------------------------------------------------------------------------------------------------------------------------
        //-------------------------------------------------SPELL CONFIGURABLE------------------------------------------------------
        //-------------------------------------------------------------------------------------------------------------------------
       
        //Spell rawcode, change if needed
        private constant integer        SPELL_ID            ='A000'
        //Dummy stun spell rawcode, change if needed
        private constant integer        DUMMY_SPELL_ID      ='A001'
        //Rawcode of the dummy id, change if needed
        private constant integer        DUMMY_CASTER        ='e000'
        //Rawcode of the buff id, change if needed
        private constant integer        BUFF_ID             ='B000'
        //Rawcode of the fly ability, you can leave it alone :)
        private constant integer        FLY_ABILITY         ='Amrf'
        //Images alpha increase when it come back to the caster
        private constant integer        FADE_BACK_PERIOD    =3
        //Original dummy alpha
        private constant integer        DUMMY_ALPHA         =100
        //Spell periodic, you can leave it alone :)
        private constant real           PERIODIC            = .031250
        //Time to pause the caster animation
        private constant real           ANIMATION_PAUSE_TIME=0.5
        //Max height of the caster when he jumping
        private constant real           MAX_HEIGHT          =400.
        //The images will dehisce after reach this percent
        private constant real           DISTANCE_PERCENT    =50.
        //Caster jumping speed
        private constant real           SPEED               =10.
        //Enemies speed when they got hits from the caster
        private constant real           TARGET_SPEED        =20.
        //Enemies max height
        private constant real           TARGET_HEIGHT       =300.
        //Images separate speed
        private constant real           SEPARATE_SPEED      =10.
        //Images come back speed
        private constant real           DUMMY_FADE_BACK     =5.
        //Animation time after the images has separated
        private constant real           TIME_ANIMATION      =0.4
        //Sword distance of the images when they hit the ground
        private constant real           SWORD_DISTANCE      =100.
        //Slash area of effect
        private constant real           SLASH_AOE           =500.
        //Enemies knockback min distance
        private constant real           TARGET_MIN_DISTANCE =250.
        //Enemies knockback max distance
        private constant real           TARGET_MAX_DISTANCE =250.
        //Caster animation when he casting this spell
        private constant string         CASTER_ANIMATION    ="slam"
        //Spell dummy stun order id
        private constant string         DUMMY_ORDER         ="thunderbolt"
        //Spell dummy invisible order id
        private constant string         DUMMY_INVI_ORDER    ="invisibility"
        //The attachment of the images when they separate
        private constant string         ATTACHMENT          ="weapon"
        //Images sepatate effect
        private constant string         MIRROR_IMAGE_EFFECT ="Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl"
        //Caster jump effect
        private constant string         JUMP_EFFECT         ="Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl"
        //Effect attach on the images
        private constant string         SWORD_EFFECT        ="Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl"
        //Effect of the images when they hit the ground
        private constant string         SLASH_EFFECT        ="Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"
        //Knockback effect when the enemies got hits
        private constant string         KNOCK_EFFECT        ="Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl"
        //Effect of the caster when the images is back
        private constant string         EFFECT_BACK         ="Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl"
       
        //**************************************************************
        private constant attacktype     AT                  = ATTACK_TYPE_HERO
        private constant damagetype     DT                  = DAMAGE_TYPE_DEATH
        private constant weapontype     WT                  = WEAPON_TYPE_CLAW_HEAVY_SLICE
        //Damage base of this spell
        private constant real           DAMAGE_BASE         = 100.
        //**************************************************************
       
        //-------------------------------------------------------------------------------------------------------------------------
        //-------------------------------------------------------------------------------------------------------------------------
        //-------------------------------------------------------------------------------------------------------------------------
       
        //------------------------------------------------------------
        //----------------------NON CONFIGURABLE----------------------
        //------------------------------------------------------------
        /**/    private          integer M=-1
        /**/    private          integer M2=-1
        /**/    private          integer array MData
        /**/    private          integer array MData2
        /**/    
        /**/    private constant timer T=CreateTimer()
        /**/    private constant timer T2=CreateTimer()
        /**/    
        /**/    private constant group G=CreateGroup()
        /**/
        /**/    private          location L=Location(0.,0.)
        /**/    private          unit   DummyCaster
        /**/    private          unit   First
        //------------------------------------------------------------
        //------------------------------------------------------------
        //------------------------------------------------------------
       
    endglobals
   
    //Filter Function Settings******************************************
    private constant function filterFunc takes unit filterUnit, player casterOwner returns boolean
        return not IsUnitType(filterUnit,UNIT_TYPE_DEAD) and GetUnitTypeId(filterUnit) != 0 and IsUnitEnemy(filterUnit,casterOwner)
    endfunction
    //********************************************************************
   
    //Damage settings*****************************************************
    private constant function getDamage takes integer lvl returns real
        return DAMAGE_BASE+(lvl+50.)
    endfunction
    //******************************************************************
   
    function AddSpecialEffectZ takes string path, real x, real y, real z returns effect
        local destructable d = CreateDestructableZ( 'OTip', x, y, z, 0.00, 1, 0 )
        set bj_lastCreatedEffect = AddSpecialEffect( path, x, y )
        call RemoveDestructable( d )
        set d = null
        return bj_lastCreatedEffect
    endfunction
   
    struct KnockBackZ
   
        unit caster
       
        real distance
        real cos
        real sin
        real tick
        real reach=0.
   
        static method onPeriodic takes nothing returns nothing
            local thistype this
            local integer i=0
           
            local real x
            local real y
            local real f
           
            loop
                exitwhen i>M2
               
                set this=MData2[i]
               
                if reach<distance then
                    set reach=reach+tick
                   
                    set x=GetUnitX(caster)+cos
                    set y=GetUnitY(caster)+sin
                    call MoveLocation(L,x,y)
                   
                    set f=(4*TARGET_HEIGHT*reach)/distance*(1-(reach/distance))+GetLocationZ(L)
                   
                    call SetUnitPosition(caster,x,y)
                    call SetUnitFlyHeight(caster,f,0.)
                    call DestroyEffect(AddSpecialEffectZ(KNOCK_EFFECT,x,y,f))
                else
               
                    set caster=null
               
                    set MData2[this]=MData2[M2]
                    set MData2[M2]=-1
                    set M2=M2-1
                   
                    if M2==-1 then
                        call PauseTimer(T2)
                    endif
                   
                    call destroy()
                   
                    return
                   
                endif
               
                set i=i+1
            endloop
        endmethod
       
        static method knockAdd takes unit whichUnit,real whichAngle returns nothing
            local thistype this=allocate()
           
            set M2=M2+1
            set MData2[M2]=this
           
            set caster=whichUnit
           
            set distance=GetRandomReal(TARGET_MIN_DISTANCE,TARGET_MAX_DISTANCE)
            set tick=distance/TARGET_HEIGHT*TARGET_SPEED
           
            set cos=tick*Cos(whichAngle)
            set sin=tick*Sin(whichAngle)
           
            if UnitAddAbility(caster,FLY_ABILITY) then
                call UnitRemoveAbility(caster,FLY_ABILITY)
            endif
           
            if M2==0 then
                call TimerStart(T2,PERIODIC,true,function thistype.onPeriodic)
            endif
        endmethod
       
    endstruct
   
    struct ShadowImagesSword
       
        unit caster
        unit dummy
       
        effect e_caster
        effect e_dummy
       
        player casterOwner
       
        boolean stopFading=false
       
        real angle
        real angle2
        real max
        real time=0.
        real reach=0.
        real tick
        real dmg
        real distance_counter=0.
        real cos
        real sin
       
        integer fade_alpha
       
        method GroupEnumUnits takes unit cast,real x, real y returns nothing
            local real fx
           
            call GroupEnumUnitsInRange(G,x,y,SLASH_AOE,null)
           
            set x=GetUnitX(cast)
            set y=GetUnitY(cast)
           
            loop
                set First=FirstOfGroup(G)
                exitwhen First==null
               
                if filterFunc(First,casterOwner) then
               
                    set fx=GetUnitX(First)
                    set time=GetUnitY(First)
                   
                    call KnockBackZ.knockAdd(First,Atan2(time-y,fx-x))
                    call UnitDamageTarget(caster,First,dmg,true,false,AT,DT,WT)
                   
                    call SetUnitX(DummyCaster,fx)
                    call SetUnitY(DummyCaster,time)
                    call IssueTargetOrder(DummyCaster,DUMMY_ORDER,First)
                endif
               
                call GroupRemoveUnit(G,First)
            endloop
        endmethod
       
        static method onPeriodic takes nothing returns nothing
            local thistype this
            local integer i=0
           
            local real x
            local real y
            local real percent
            local real s
           
            loop
                exitwhen i>M
               
                set this=MData[i]
               
                if reach<max then
               
                    set x=GetUnitX(caster)+cos
                    set y=GetUnitY(caster)+sin
                   
                    call SetUnitX(caster,x)
                    call SetUnitY(caster,y)

                    set x=GetUnitX(dummy)+cos
                    set y=GetUnitY(dummy)+sin
                   
                    call SetUnitX(dummy,x)
                    call SetUnitY(dummy,y)
                   
                    set reach=reach+tick
                   
                    call MoveLocation(L,x,y)
                   
                    set s=(4*MAX_HEIGHT*reach)/max*(1-(reach/max))+GetLocationZ(L)
                   
                    call SetUnitFlyHeight(caster,s,0.)
                    call SetUnitFlyHeight(dummy,s,0.)
                   
                    if not stopFading then
                   
                        if time<ANIMATION_PAUSE_TIME then
                            set time=time+PERIODIC
                        else
                            call SetUnitTimeScale(dummy,0.)
                            call SetUnitTimeScale(caster,0.)
                        endif
                       
                        set percent=reach/max*100.
                       
                        if percent>= DISTANCE_PERCENT then
                            set stopFading=true
                           
                            set e_caster=AddSpecialEffectTarget(SWORD_EFFECT,caster,ATTACHMENT)
                            set e_dummy=AddSpecialEffectTarget(SWORD_EFFECT,dummy,ATTACHMENT)
                           
                            if GetLocalPlayer()==casterOwner then
                                call SelectUnit(caster,false)
                            endif
                           
                            call UnitAddAbility(caster,'Aloc')
                            call SetUnitVertexColor(caster,255,255,255,DUMMY_ALPHA)
                            call DestroyEffect(AddSpecialEffectZ(MIRROR_IMAGE_EFFECT,x,y,s))
                           
                            call SetUnitTimeScale(dummy,TIME_ANIMATION)
                            call SetUnitTimeScale(caster,TIME_ANIMATION)
                        endif
                       
                    else

                        set percent=SEPARATE_SPEED*Cos(angle2)
                        set s=SEPARATE_SPEED*Sin(angle2)
                       
                        set x=GetUnitX(dummy)+percent
                        set y=GetUnitY(dummy)+s
                       
                        call SetUnitX(dummy,x)
                        call SetUnitY(dummy,y)
                       
                        set x=GetUnitX(caster)-percent
                        set y=GetUnitY(caster)-s
                       
                        call SetUnitX(caster,x)
                        call SetUnitY(caster,y)
                       
                        set distance_counter=distance_counter+SEPARATE_SPEED
                       
                    endif
                   
                    if reach>=max then
                   
                        set cos=SWORD_DISTANCE*Cos(angle)
                        set sin=SWORD_DISTANCE*Sin(angle)
                       
                        set x=GetUnitX(caster)+cos
                        set y=GetUnitY(caster)+sin
                       
                        call DestroyEffect(AddSpecialEffect(SLASH_EFFECT,x,y))
                       
                        call SetUnitAbilityLevel(DummyCaster,DUMMY_SPELL_ID,fade_alpha)
                       
                        set fade_alpha=DUMMY_ALPHA
                       
                        call GroupEnumUnits(caster,x,y)
                       
                        set x=GetUnitX(dummy)+cos
                        set y=GetUnitY(dummy)+sin
                       
                        call DestroyEffect(AddSpecialEffect(SLASH_EFFECT,x,y))
                       
                        call GroupEnumUnits(dummy,x,y)
                       
                        set cos=DUMMY_FADE_BACK*Cos(angle2)
                        set sin=DUMMY_FADE_BACK*Sin(angle2)
                       
                        call DestroyEffect(e_caster)
                        call DestroyEffect(e_dummy)
                        set e_caster=null
                        set e_dummy=null
                    endif

                else
                   
                    set x=GetUnitX(dummy)-cos
                    set y=GetUnitY(dummy)-sin
                   
                    call SetUnitX(dummy,x)
                    call SetUnitY(dummy,y)
                   
                    set x=GetUnitX(caster)+cos
                    set y=GetUnitY(caster)+sin
                   
                    call SetUnitX(caster,x)
                    call SetUnitY(caster,y)
                   
                    if distance_counter>DUMMY_FADE_BACK then
                   
                        set distance_counter=distance_counter-DUMMY_FADE_BACK
                        set fade_alpha=fade_alpha+FADE_BACK_PERIOD
                       
                        call SetUnitVertexColor(dummy,255,255,255,fade_alpha)
                        call SetUnitVertexColor(caster,255,255,255,fade_alpha)
                       
                    else

                        call UnitRemoveAbility(caster,'Aloc')
                        call ShowUnit(caster,false)
                        call ShowUnit(caster,true)
                        call UnitRemoveAbility(caster,BUFF_ID)
                        call DestroyEffect(AddSpecialEffect(EFFECT_BACK,x,y))
                       
                        call SetUnitX(DummyCaster,x)
                        call SetUnitY(DummyCaster,y)
                        call IssueTargetOrder(DummyCaster,DUMMY_INVI_ORDER,caster)

                        call SetUnitTimeScale(caster,1.)
                       
                        call SetUnitAnimation(caster,"stand")
                        call SetUnitVertexColor(caster,255,255,255,255)
                       
                        if GetLocalPlayer()==casterOwner then
                            call SelectUnit(caster,true)
                        endif
                       
                        call RemoveUnit(dummy)
                       
                        set caster=null
                        set dummy=null
                        set casterOwner=null
                   
                        set MData[i]=MData[M]
                        set MData[M]=-1
                        set M=M-1
                       
                        if M==-1 then
                            call PauseTimer(T)
                        endif
                       
                        call destroy()
                        return
                    endif
                   
                endif
               
                set i=i+1
            endloop
           
        endmethod
       
        static method onCast takes nothing returns boolean
            local thistype this
           
            local real x
            local real y
            local real o
            local real z
           
            if GetSpellAbilityId()==SPELL_ID then
               
                set this=allocate()
               
                set M=M+1
                set MData[M]=this
               
                set caster=GetTriggerUnit()
                set casterOwner=GetTriggerPlayer()
               
                set x=GetUnitX(caster)
                set y=GetUnitY(caster)
                set o=GetSpellTargetX()
                set z=GetSpellTargetY()                
               
                set fade_alpha=GetUnitAbilityLevel(caster,SPELL_ID)
               
                set dmg=getDamage(fade_alpha)
               
                set max=SquareRoot((x-o)*(x-o)+(y-z)*(y-z))
               
                set angle2=(57.29583*Atan2(z-y,o-x)+90.)
                set angle=(angle2-90.)
                set angle2=angle2*.0174533
               
                set tick=max/MAX_HEIGHT*SPEED
               
                set dummy= CreateUnit(Player(15),GetUnitTypeId(caster),x,y,angle)
               
                set angle=angle*.0174533
               
                set cos=tick*Cos(angle)
                set sin=tick*Sin(angle)
               
                call SetUnitColor(dummy,GetPlayerColor(casterOwner))
               
                if UnitAddAbility(dummy,FLY_ABILITY) and UnitAddAbility(caster,FLY_ABILITY) then
                    call UnitRemoveAbility(dummy,FLY_ABILITY)
                    call UnitRemoveAbility(caster,FLY_ABILITY)
                    call UnitAddAbility(dummy,'Aloc')
                   
                    call SetUnitVertexColor(dummy,255,255,255,DUMMY_ALPHA)
                   
                    call SetUnitX(dummy,x)
                    call SetUnitY(dummy,y)
                endif
               
                call SetUnitAnimation(caster,CASTER_ANIMATION)
                call SetUnitAnimation(dummy,CASTER_ANIMATION)
               
                call SetUnitX(DummyCaster,x)
                call SetUnitY(DummyCaster,y)
                call SetUnitAbilityLevel(DummyCaster,DUMMY_SPELL_ID,5)
                call IssueTargetOrder(DummyCaster,DUMMY_ORDER,caster)
               
                call DestroyEffect(AddSpecialEffect(JUMP_EFFECT,x,y))
               
                if M==0 then
                    call TimerStart(T,PERIODIC,true,function thistype.onPeriodic)
                endif
               
            endif
           
            return false
        endmethod
       
        static method onInit takes nothing returns nothing
            local integer i=0
            local trigger t=CreateTrigger()
           
            loop
                exitwhen i>15
               
                call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
               
                set i=i+1
            endloop
           
            call TriggerAddCondition(t,function thistype.onCast)
           
            set DummyCaster=CreateUnit(Player(15),DUMMY_CASTER,0.,0.,0.)
       
            set t=null
        endmethod
       
    endstruct
   
endlibrary


Changelogs
v1.0: First release version
v1.1: Minor mistake fixed


Keywords:
shadow, images, sword
Contents

Shadow Images Sword (Map)

Reviews
Moderator
12th Dec 2015 IcemanBo: Too long as NeedsFix. Rejected. 15:57, 1st Jan 2015 Maker: IcemanBo and edo did a pretty good review. Follow the advice given there.
  1. 12th Dec 2015
    IcemanBo: Too long as NeedsFix. Rejected.

    15:57, 1st Jan 2015
    Maker: IcemanBo and edo did a pretty good review.
    Follow the advice given there.
     
  2. xorkatoss

    xorkatoss

    Joined:
    Jul 12, 2010
    Messages:
    1,602
    Resources:
    7
    Models:
    5
    Maps:
    1
    Spells:
    1
    Resources:
    7
    the spell it's self is a pretty neat idea.

    the bug: this is what happens when 2 or more casts occur at the same time
     

    Attached Files:

  3. nhocklanhox6

    nhocklanhox6

    Joined:
    Feb 12, 2012
    Messages:
    335
    Resources:
    28
    Models:
    6
    Spells:
    21
    Tutorials:
    1
    Resources:
    28
    That's my minor mistake, thanks >.<..
     
  4. dhguardianes

    dhguardianes

    Joined:
    Jun 19, 2011
    Messages:
    82
    Resources:
    13
    Models:
    10
    Skins:
    1
    Maps:
    2
    Resources:
    13
    I feel that, should be hidden shadow units when they are flying :ogre_hurrhurr:
     
  5. Kazeon

    Kazeon

    Joined:
    Oct 12, 2011
    Messages:
    3,298
    Resources:
    38
    Icons:
    2
    Tools:
    1
    Maps:
    7
    Spells:
    21
    Tutorials:
    3
    JASS:
    4
    Resources:
    38
    • Code (vJASS):
      set dummy= CreateUnit(Player(15),GetUnitTypeId(caster),x,y,angle)

      Store
      Player(15)
      in a constant global variable
    • Code (vJASS):
                      if UnitAddAbility(dummy,FLY_ABILITY) and UnitAddAbility(caster,FLY_ABILITY) then
                          call UnitRemoveAbility(dummy,FLY_ABILITY)
                          call UnitRemoveAbility(caster,FLY_ABILITY)
                          call UnitAddAbility(dummy,'Aloc')
                         
                          call SetUnitVertexColor(dummy,255,255,255,DUMMY_ALPHA)
                         
                          call SetUnitX(dummy,x)
                          call SetUnitY(dummy,y)
                      endif

      Just follow the convention:
      Code (vJASS):
      if UnitAddAbility(dummy,FLY_ABILITY) and UnitRemoveAbility(dummy,FLY_ABILITY) then
      endif
      if UnitAddAbility(caster,FLY_ABILITY) and UnitRemoveAbility(caster,FLY_ABILITY) then
      endif

      Then put the rest actions outside the block. Currently, it may fails if user has a dummy unit with Crow Form ability defaultly from OE (some coders prefer this way). And
      call UnitAddAbility(dummy,'Aloc')
      , dummy unit should have locust ability by default in OE. Just remove that line.
    • For sake of elegance, I would prefer to add all of dummy abilities via trigger. Beside, you only need those abilities just for one dummy caster. And in case users want to use their own dummy unit. Users don't need to have multiple dummy units for every spell on their maps right?
    • Personally, I don't like spells which make the caster become invulnerable. It's often considered as overpowered spell.
    • Stun ability has 5 levels?
     
  6. edo494

    edo494

    Joined:
    Apr 16, 2012
    Messages:
    3,846
    Resources:
    5
    Spells:
    1
    JASS:
    4
    Resources:
    5
    Shadow Images Sword v1.1 - Review by IcemanBo & edo494

    Concept:

    Hero jump up to the sky, and while mid-air, he creates 2 illusions that jump to different directions, and upon reaching the ground they deal varying AoE damage and stun all enemies in certain range for certain time. After they land, the illusions disappear and the caster goes invisible for certain amount of time.

    Code:
    • instead of it being library, make it a scope. Library is used for systems that are meant to be seen by the whole code.

    • instead of using strings, you could use orderids(integers) in the configurable

    • Spell should not work in deep water, because if unit gets pushed there(or caster jumps there). You will have to somehow check if user doesnt try to jump into deep water

    • Inside
      AddSpecialEffectZ
      you dont use the destructable you create, if you meant to create special effect on the destructable, use
      AddSpecialEffectTarget(path, d, "some attachment")
      . If you dont, you can directly
      return AddSpecialEffect(path, x, y)


    • struct KnockBackZ
      =>
      private struct KnockBackZ
      ,
      struct ShadowImagesSword
      =>
      private struct ShadowImagesSword


    • Inside
      ShadowImagesSword.onPeriodic
      , inside the
      if not stopFading then
      and
      if percent>= DISTANCE_PERCENT then
      you create 2 effects, but you never remove them(if reach>=max evaluates to false). My(Edo) point of view on this is that if you create handle in certain scope, you should remove it in that scope, or before end of loop or end of function. You do neither in that if, you follow this on the rest tho.

    • Return statement inside
      KnockBackZ.onPeriodic
      inside the else block is useless. It may cause glitches, because you can potentially stop iterating mid-way The same return statement problem appears inside
      ShadowImagesSword.onPeriodic
      , you potentially return while iterating over the list.

    • 57.29583, *.0174533
      => what is this magical sorcery constant?

    • if UnitAddAbility(dummy,FLY_ABILITY) and UnitAddAbility(caster,FLY_ABILITY) then
      could be
      if UnitAddAbility(dummy,FLY_ABILITY) and UnitAddAbility(caster,FLY_ABILITY) and UnitRemoveAbility(dummy,FLY_ABILITY) and UnitRemoveAbility(caster,FLY_ABILITY) then
      , + it can fail if unit already has crow form ability on it when you call it(it will return false)

    • set dummy= CreateUnit(Player(15),GetUnitTypeId(caster),x,y,angle)
      You could store
      Player(15)
      inside constant variable, or use one provided by blizzard(Yes, I am looking at you
      PLAYER_NEUTRAL_PASSIVE


    • Quality of life: You dont need to actually loop inside the onInit, you could've just called the BJ, it does it for you anyways.
      You also dont need to null the trigger, as you never destroy it(I agree it is good practice, but technically just waste of 22 bytes :D)

    • Inside
      ShadowImagesSword.onPeriodic
      you periodically call
      SelectUnit(caster,false/true)
      , and this is not really mentioned, nor is it really required. You could make a
      constant boolean DE_SELECT_ON_PERIODIC
      and wrap the selection in
      static if


    • Also, you should follow JPAG with naming, for instance
      private          integer M=-1
      is not really descriptive. And yes, not only the configurable should be descriptive.

    Visuals:

    • When jumping over cliffs, the jump does not look very smooth
    • The skill icon does not fit well into the spell
    • tooltip could use some love(Improve the wordings, because it is kind of a mess as of now)
    • The ending effect is not really all that fitting, considering its origins(Mind control I believe)
    Conclusion:

    The code is pretty solid, with a few flaws in it, but no real logical errors. The concept of the spell is above average, because it "stands out of ordinary" with the spells of type "Jump, hit ground, knockback, damage", but this spell does a little bit unique stuff by spliting to two different units and Comboing the units.
    The visuals could've been improved, mainly the tooltip and icon of the spell.

    Rating: 3.5/5 Unique, will change to 4/5 when updated

     
  7. IcemanBo

    IcemanBo

    Joined:
    Sep 6, 2013
    Messages:
    6,549
    Resources:
    23
    Maps:
    3
    Spells:
    11
    Template:
    1
    Tutorials:
    5
    JASS:
    3
    Resources:
    23
    As stated by edo 3.5/5 for now, but definitly 4/5 when updated... for motivation. :D And a good spell. :csmile:
     
  8. nhocklanhox6

    nhocklanhox6

    Joined:
    Feb 12, 2012
    Messages:
    335
    Resources:
    28
    Models:
    6
    Spells:
    21
    Tutorials:
    1
    Resources:
    28
    Thank all of you. Will fix it soon^^.
     
    Last edited: Nov 17, 2014