• 🏆 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!

Chidori v1.2


A spell based from the Naruto anime.
  • Description
    Kakashi concentrates a great amount of Lightning Element's chakra in the hand. Once finish, Kakashi starts to move forward very fast, gaining high speed and makes a sharp attack using his hand, impaling the target's body. This serious damage makes the target dying because it strikes the internals.
  • Levels
    Level 1 - 200 strike damage, 200 dying damage.
    Level 2 - 300 strike damage, 250 dying damage.
    Level 3 - 400 strike damage, 300 dying damage.
  • Code
    JASS:
    //===========================================================================
    //=**************************************************************************
    //=*
    //=*  Chidori by Ofel
    //=*  v1.2
    //=*
    //=*  Credits:
    //=*   + PurgeandFire
    //=*   + Gwapogi
    //=*   + Jad
    //=*   + bowser499
    //=*
    //=*  Requirement:
    //=*   + Check Walkability system
    //=*
    //=**************************************************************************
    //===========================================================================
    
    //***************************************************************************
    //***************************************************************************
    //**
    //**  CONFIGURATION
    //**
    //***************************************************************************
    //***************************************************************************
    
    //***************************************************************************
    //*
    //*  Determines the ability raw code. Press Ctrl + D to show the raw code in
    //*  Object Editor
    //*
    //***************************************************************************
    constant function C_AbilityId takes nothing returns integer
        return 'A000'
    endfunction
    //***************************************************************************
    //*
    //*  Determines the base order id of the ability mentioned above. This is
    //*  used to check if the caster is still channeling the ability
    //*
    //***************************************************************************
    constant function C_OrderId takes nothing returns integer
        return OrderId("absorb")
    endfunction
    //***************************************************************************
    //*
    //*  Determines the animation by index when the caster is 'concentrating'.
    //*  If you change the caster model, you may need to test the animation
    //*  again until you found the correct one
    //*
    //***************************************************************************
    constant function C_ConcentrateAnimationIndex takes nothing returns integer
        return 11
    endfunction
    //***************************************************************************
    //*
    //*  Determines the animation by index when the caster is 'moving'
    //*
    //***************************************************************************
    constant function C_RunAnimationIndex takes nothing returns integer
        return 2
    endfunction
    //***************************************************************************
    //*
    //*  Determines the animation by index when the caster is going to swing his
    //*  hand when about to strike the target
    //*
    //***************************************************************************
    constant function C_SwingAnimationIndex takes nothing returns integer
        return 13
    endfunction
    //***************************************************************************
    //*
    //*  Determines the minimum distance where the caster will start swinging
    //*  his hand to strike the target
    //*
    //***************************************************************************
    constant function C_SwingDistance takes nothing returns real
        return 400.00
    endfunction
    //***************************************************************************
    //*
    //*  Determines the percent of animation speed when the caster is swinging
    //*
    //***************************************************************************
    constant function C_SwingAnimationSpeed takes nothing returns real
        return 200.00
    endfunction
    //***************************************************************************
    //*
    //*  Determines the period time of the spell to 'update' things related to
    //*  the spell. Include moving the caster, spawning effects, counting timer,
    //*  damaging target, etc
    //*
    //***************************************************************************
    constant function C_Interval takes nothing returns real
        return 0.03125
    endfunction
    //***************************************************************************
    //*
    //*  Determines the initial move speed of the caster after finish
    //*  'concentrating'
    //*
    //***************************************************************************
    constant function C_InitialSpeed takes nothing returns real
        return 1.00
    endfunction
    //***************************************************************************
    //*
    //*  Determines the move speed acceleration of the caster when moving toward
    //*  the target
    //*
    //***************************************************************************
    constant function C_SpeedAcceleration takes nothing returns real
        return 2.00
    endfunction
    //***************************************************************************
    //*
    //*  Determines the maximum speed of the caster when moving toward target
    //*
    //***************************************************************************
    constant function C_MaxSpeed takes nothing returns real
        return 40.00
    endfunction
    //***************************************************************************
    //*
    //*  Determines the minimum distance where the caster is considered as
    //*  'has strike' the target
    //*
    //***************************************************************************
    constant function C_MinDistance takes nothing returns real
        return 150.00
    endfunction
    //***************************************************************************
    //*
    //*  Determines the how long the target will dying after the strike
    //*
    //***************************************************************************
    constant function C_DyingDuration takes nothing returns real
        return 10.00
    endfunction
    //***************************************************************************
    //*
    //*  Determines the effect attached on the caster
    //*
    //***************************************************************************
    constant function C_HandSFXModel takes nothing returns string
        return "war3mapImported\\ZapMissile.mdx"
    endfunction
    //***************************************************************************
    //*
    //*  Determines the attachment point for the effect above
    //*
    //***************************************************************************
    constant function C_HandSFXAttachment takes nothing returns string
        return "hand right"
    endfunction
    //***************************************************************************
    //*
    //*  Determines the effect attached on the caster. Different than the first
    //*  one, this effect spawns periodicly
    //*
    //***************************************************************************
    constant function C_LoopingSFXModel takes nothing returns string
        return "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
    endfunction
    //***************************************************************************
    //*
    //*  Determines the attachment point for the effect above
    //*
    //***************************************************************************
    constant function C_LoopingSFXAttachment takes nothing returns string
        return "hand right"
    endfunction
    //***************************************************************************
    //*
    //*  Determines the spawn interval of the effect above
    //*
    //***************************************************************************
    constant function C_LoopingSFXInterval takes nothing returns real
        return 0.09
    endfunction
    //***************************************************************************
    //*
    //*  Determines the strike effect
    //*
    //***************************************************************************
    constant function C_StrikeSFXModel takes nothing returns string
        return "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"
    endfunction
    //***************************************************************************
    //*
    //*  Determines the attachment point for the effect above
    //*
    //***************************************************************************
    constant function C_StrikeSFXAttachment takes nothing returns string
        return "origin"
    endfunction
    //***************************************************************************
    //*
    //*  Determines the dying effect attached on the target that spawns
    //*  periodicly
    //*
    //***************************************************************************
    constant function C_DyingSFXModel takes nothing returns string
        return "Objects\\Spawnmodels\\Other\\HumanBloodCinematicEffect\\HumanBloodCinematicEffect.mdl"
    endfunction
    //***************************************************************************
    //*
    //*  Determines the attachment point for the effect above
    //*
    //***************************************************************************
    constant function C_DyingSFXAttachment takes nothing returns string
        return "chest"
    endfunction
    //***************************************************************************
    //*
    //*  Determines the attack-type
    //*
    //***************************************************************************
    constant function C_AttackType takes nothing returns attacktype
        return ATTACK_TYPE_PIERCE
    endfunction
    //***************************************************************************
    //*
    //*  Determines the damage-type
    //*
    //***************************************************************************
    constant function C_DamageType takes nothing returns damagetype
        return DAMAGE_TYPE_LIGHTNING
    endfunction
    //***************************************************************************
    //*
    //*  Determines how long the caster will need to 'concentrate'
    //*
    //***************************************************************************
    function C_ConcentrateDuration takes real level returns real
        return 2.50 - (level * 0.50)
    endfunction
    //***************************************************************************
    //*
    //*  Determines the strike damage
    //*
    //***************************************************************************
    function C_StrikeDamage takes real level returns real
        return level * 100.00 + 100.00
    endfunction
    //***************************************************************************
    //*
    //*  Determines the total damage dealt to the target
    //*
    //***************************************************************************
    function C_DyingTotalDamage takes real level returns real
        return level * 50.00 + 150.00
    endfunction
    //***************************************************************************
    //***************************************************************************
    //**
    //**  END OF CONFIGURATION
    //**
    //***************************************************************************
    //***************************************************************************
    
    function C_Periodic takes nothing returns nothing
        local real x
        local real y
        local real x2
        local real y2
        local real angle
        local real dist
        local integer index = 1
        loop
            exitwhen index > udg_C_MaxIndex
            if (udg_C_Stage[index] == 1) then
                if (not IsUnitType(udg_C_Target[index], UNIT_TYPE_DEAD) and udg_C_RealTimer[index] > 0) then
                    set udg_C_RealTimer2[index] = udg_C_RealTimer2[index] - C_Interval()
                    if (udg_C_RealTimer2[index] <= 0) then
                        call DestroyEffect(AddSpecialEffectTarget(C_DyingSFXModel(), udg_C_Target[index], C_DyingSFXAttachment()))
                        set udg_C_RealTimer2[index] = 1
                    endif
                    call UnitDamageTarget(udg_C_Caster[index], udg_C_Target[index], udg_C_DamagePerSecond[udg_C_Level[index]], true, false, C_AttackType(), C_DamageType(), null)
                    set udg_C_RealTimer[index] = udg_C_RealTimer[index] - C_Interval()
                else
                    set udg_C_Stage[index] = 4
                endif
            elseif (udg_C_Stage[index] == 2) then
                if (not IsUnitType(udg_C_Caster[index], UNIT_TYPE_DEAD) and not IsUnitType(udg_C_Target[index], UNIT_TYPE_DEAD)) then
                    if (GetUnitCurrentOrder(udg_C_Caster[index]) == C_OrderId()) then
                        set x = GetUnitX(udg_C_Caster[index])
                        set y = GetUnitY(udg_C_Caster[index])
                        set x2 = GetUnitX(udg_C_Target[index]) - x
                        set y2 = GetUnitY(udg_C_Target[index]) - y
                        set dist = x2 * x2 + y2 * y2
                        if (dist > udg_C_Saver[1]) then
                            if (udg_C_Swinged[index] == false) then
                                if (dist <= udg_C_Saver[2]) then
                                    call SetUnitAnimationByIndex(udg_C_Caster[index], C_SwingAnimationIndex())
                                    call SetUnitTimeScalePercent(udg_C_Caster[index], C_SwingAnimationSpeed())
                                    set udg_C_Swinged[index] = true
                                else
                                    call SetUnitAnimationByIndex(udg_C_Caster[index], C_RunAnimationIndex())
                                endif
                            endif
                            set angle = Atan2(y2, x2)
                            set x = x + udg_C_Speed[index] * Cos(angle)
                            set y = y + udg_C_Speed[index] * Sin(angle)
                            set udg_CP_Point = Location(x, y)
                            call TriggerExecute(gg_trg_Check_Walkability)
                            if (udg_CP_PointIsWalkable == true) then
                                call SetUnitX(udg_C_Caster[index], x)
                                call SetUnitY(udg_C_Caster[index], y)
                                call SetUnitFacing(udg_C_Caster[index], angle * bj_RADTODEG)
                                if (udg_C_Speed[index] < C_MaxSpeed()) then
                                    set udg_C_Speed[index] = udg_C_Speed[index] + C_SpeedAcceleration()
                                else
                                    set udg_C_Speed[index] = C_MaxSpeed()
                                endif
                            else
                                call DestroyEffect(udg_C_Model[index])
                                call IssueImmediateOrder(udg_C_Caster[index], "stop")
                                set udg_C_Stage[index] = 4
                            endif
                        else
                            call DestroyEffect(AddSpecialEffectTarget(C_StrikeSFXModel(), udg_C_Target[index], C_StrikeSFXAttachment()))
                            call UnitDamageTarget(udg_C_Caster[index], udg_C_Target[index], C_StrikeDamage(udg_C_Level[index]), true, false, C_AttackType(), C_DamageType(), null)
                            call DestroyEffect(udg_C_Model[index])
                            call SetUnitTimeScalePercent(udg_C_Caster[index], 100)
                            call IssueImmediateOrder(udg_C_Caster[index], "stop")
                            if (not IsUnitType(udg_C_Target[index], UNIT_TYPE_DEAD)) then
                                set udg_C_RealTimer[index] = C_DyingDuration()
                                set udg_C_RealTimer2[index] = 0
                                set udg_C_Stage[index] = 1
                            else
                                set udg_C_Stage[index] = 4
                            endif
                        endif
                    else
                        call DestroyEffect(udg_C_Model[index])
                        set udg_C_Stage[index] = 4
                    endif
                else
                    call DestroyEffect(udg_C_Model[index])
                    call IssueImmediateOrder(udg_C_Caster[index], "stop")
                    set udg_C_Stage[index] = 4
                endif
            elseif (udg_C_Stage[index] == 3) then
                if (not IsUnitType(udg_C_Caster[index], UNIT_TYPE_DEAD) and not IsUnitType(udg_C_Target[index], UNIT_TYPE_DEAD)) then
                    set x = GetUnitX(udg_C_Caster[index])
                    set y = GetUnitY(udg_C_Caster[index])
                    if (GetUnitCurrentOrder(udg_C_Caster[index]) == C_OrderId() and x == udg_C_CasterX[index] and y == udg_C_CasterY[index]) then
                        if (udg_C_RealTimer[index] > 0) then
                            set udg_C_RealTimer2[index] = udg_C_RealTimer2[index] - C_Interval()
                            if (udg_C_RealTimer2[index] <= 0) then
                                call DestroyEffect(AddSpecialEffectTarget(C_LoopingSFXModel(), udg_C_Caster[index], C_LoopingSFXAttachment()))
                                set udg_C_RealTimer2[index] = C_LoopingSFXInterval()
                            endif
                            set udg_C_RealTimer[index] = udg_C_RealTimer[index] - C_Interval()
                        else
                            set udg_C_Speed[index] = C_InitialSpeed()
                            set udg_C_Swinged[index] = false
                            set udg_C_Stage[index] = 2
                        endif
                    else
                        call DestroyEffect(udg_C_Model[index])
                        set udg_C_Stage[index] = 4
                    endif
                else
                    call DestroyEffect(udg_C_Model[index])
                    call IssueImmediateOrder(udg_C_Caster[index], "stop")
                    set udg_C_Stage[index] = 4
                endif
            elseif (udg_C_Stage[index] == 4) then
                set udg_C_Caster[index] = udg_C_Caster[udg_C_MaxIndex]
                set udg_C_CasterX[index] = udg_C_CasterX[udg_C_MaxIndex]
                set udg_C_CasterY[index] = udg_C_CasterY[udg_C_MaxIndex]
                set udg_C_Level[index] = udg_C_Level[udg_C_MaxIndex]
                set udg_C_Model[index] = udg_C_Model[udg_C_MaxIndex]
                set udg_C_RealTimer[index] = udg_C_RealTimer[udg_C_MaxIndex]
                set udg_C_RealTimer2[index] = udg_C_RealTimer2[udg_C_MaxIndex]
                set udg_C_Speed[index] = udg_C_Speed[udg_C_MaxIndex]
                set udg_C_Stage[index] = udg_C_Stage[udg_C_MaxIndex]
                set udg_C_Swinged[index] = udg_C_Swinged[udg_C_MaxIndex]
                set udg_C_Target[index] = udg_C_Target[udg_C_MaxIndex]
                set index = index - 1
                set udg_C_MaxIndex = udg_C_MaxIndex - 1
                if (udg_C_MaxIndex == 0) then
                    call PauseTimer(udg_C_Timer)
                endif
            endif
            set index = index + 1
        endloop
    endfunction
    
    function C_Cast takes nothing returns boolean
        local integer index
        if (GetSpellAbilityId() == C_AbilityId()) then
            set udg_C_Caster[0] = GetTriggerUnit()
            if (udg_C_MaxIndex == 0) then
                call TimerStart(udg_C_Timer, C_Interval(), true, function C_Periodic)
            else
                set index = 1
                loop
                    exitwhen index > udg_C_MaxIndex
                    if (udg_C_Caster[index] == udg_C_Caster[0] and udg_C_Stage[index] != 1) then
                        call DestroyEffect(udg_C_Model[index])
                        set udg_C_Stage[index] = 4
                    endif
                    set index = index + 1
                endloop
            endif
            set udg_C_MaxIndex = udg_C_MaxIndex + 1
            set udg_C_Caster[udg_C_MaxIndex] = udg_C_Caster[0]
            set udg_C_Target[udg_C_MaxIndex] = GetSpellTargetUnit()
            set udg_C_Level[udg_C_MaxIndex] = GetUnitAbilityLevel(udg_C_Caster[udg_C_MaxIndex], C_AbilityId())
            set udg_C_CasterX[udg_C_MaxIndex] = GetUnitX(udg_C_Caster[udg_C_MaxIndex])
            set udg_C_CasterY[udg_C_MaxIndex] = GetUnitY(udg_C_Caster[udg_C_MaxIndex])
            set udg_C_Model[udg_C_MaxIndex] = AddSpecialEffectTarget(C_HandSFXModel(), udg_C_Caster[udg_C_MaxIndex], C_HandSFXAttachment())
            set udg_C_RealTimer[udg_C_MaxIndex] = C_ConcentrateDuration(udg_C_Level[udg_C_MaxIndex])
            set udg_C_RealTimer2[udg_C_MaxIndex] = 0
            call SetUnitAnimationByIndex(udg_C_Caster[udg_C_MaxIndex], C_ConcentrateAnimationIndex())
            set udg_C_Stage[udg_C_MaxIndex] = 3
        endif
        return false
    endfunction
    
    //===========================================================================
    function InitTrig_Chidori takes nothing returns nothing
        set gg_trg_Chidori = CreateTrigger()
        if (udg_C_Timer == null) then
            set udg_C_Timer = CreateTimer()
        endif
        call TriggerRegisterAnyUnitEventBJ(gg_trg_Chidori, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(gg_trg_Chidori, Filter(function C_Cast))
        set udg_C_Saver[1] = C_MinDistance() * C_MinDistance()
        set udg_C_Saver[2] = C_SwingDistance() * C_SwingDistance()
        set udg_C_DamagePerSecond[1] = C_DyingTotalDamage(1) * C_Interval()
        set udg_C_DamagePerSecond[2] = C_DyingTotalDamage(2) * C_Interval()
        set udg_C_DamagePerSecond[3] = C_DyingTotalDamage(3) * C_Interval()
    endfunction
  • Requirement
    - Check Walkability system by PurgeandFire
  • Credits
    - Gwapogi for Kakashi model
    - PurgeandFire for Check Walkability system
    - Jad for suggestion
    - bowser499 for suggestion
  • Changelog
    - v1.0: Initial version
    - v1.1: Added Check Walkability system suggested by Jad
    - v1.2: Converted into a pure JASS, removed some configuration, fixed many things, added new type of configuration
  • Other
    There's ZapMissile.mdl used in this test map but i don't know who's the author


Keywords:
Anime, Naruto, Lightning, Move, Strike, Dragging, MUI, GUI
Contents

Test Map (Map)

Reviews
Chidori v1.1 | Reviewed by Maker | 27th Sep 2013 APPROVED A Leakless, MUI spell with good effects and nice functionality [tr] The looping trigger should be turned off initially and you could shorten that trigger by...

Moderator

M

Moderator


Chidori v1.1 | Reviewed by Maker | 27th Sep 2013
APPROVED


126248-albums6177-picture66521.png


A Leakless, MUI spell with good effects and nice functionality
126248-albums6177-picture66523.png


The looping trigger should be turned off initially and you could shorten
that trigger by reorganizing the actions
[tr]
 
Hmmm.....
  • Loop - Actions
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
  • If - Conditions
  • C_Caster[C_Index] Equal to C_Caster[0]
  • Then - Actions
  • Special Effect - Destroy C_HandFX[C_Index]
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
  • If - Conditions
  • C_Stage[C_Index] Equal to 2
  • Then - Actions
  • Animation - Change C_Caster[C_Index]'s animation speed to 100.00% of its original speed
  • Else - Actions
  • Set C_Stage[C_Index] = 4
  • Else - Actions
What did you destroy, Ofel? There's no effect made before this line
 
Level 16
Joined
Jul 31, 2012
Messages
2,217

Review

Suggestions

Rating

Judgement

My Words

  • Custom script: if (not IsTerrainPathable(udg_C_X[1], udg_C_Y[1], udg_C_PathingType)) then
Do not use this kind of condition to track pathability, it won't detect pathing blockers, use the item path-ability system

Make the caster always face the target, it can change facing if it was ordered something
225233-albums6523-picture74070.jpg
225233-albums6523-picture74103.jpg
If You want me to review an Update of This Spell, Please Notifiy me this by VM or PM
 
Last edited:
Level 16
Joined
Jul 31, 2012
Messages
2,217
1.1 Review

Review

Suggestions

Rating

Judgement

My Words

You Should Add Credits to Thrikodius for his ZapMissile Model
Nice New Effect
Problems fixed!
Add an AoE Damage at impact or something like that :)
225233-albums6523-picture74071.jpg
225233-albums6523-picture74103.jpg
If You want me to review an Update of This Spell, Please Notifiy me this by VM or PM
 
Chidori v1.1 by Ofel: Review by bowser499

Many Naruto fans who are familiar with WarCraft III are trying to make the best map about this series. Ones who don't know coding much and can't find a coder for themselves are searching for some pre-made spells to fit their maps' needs.
This spell is a kind of many Chidori spells around. If we follow the story of Naruto, Chidori (千鳥 or 'Thousand Birds') is the first technique created by Hatake Kakashi. Later he improved it and called the improved version as Raikiri.

Chidori in manga: Concentrates a great amount of Lightning Element's chakra in the hand of the user. This amount is so large that it becomes visible despite in its normal state it cannot be seen. The large concentration of electricity produces a sound that is similar to the chirps of the thousand birds (that's why this technique received its name). When the technique is ready, the caster starts to move forward very fast, gaining high speed and makes a sharp attack using his hand, impaling the enemy's body. This deals serious damage and results a death of this enemy, especially when it strikes the internals. This technique is classified as a technique for a silent kills because of the speed with which it's executed, despite the loud sound on its usage.

So, in general, Chidori is some powerful and fast ability.

What do we have here, in this version made by Ofel?

Originality: 1/5. Importing ideas from Naruto is similar to importing ideas from everywhere else. There is nothing that author did to make it look original. But still, this is good for everyone who is keen on making a Naruto map. I'll leave this to author to think up on how to make Naruto spell something original. To prove the objectivity of my point, here are some more Chidori spells I've found:So, no offence, but nothing original.

Execution: 4/5. The execution that truly can get 5/5 is JASS or vJASS one. So minus one point because it is GUI (if you will convert the trigger to the text and see that mess that it produces you will probably agree on that one). There are also something that I want to point out to the author.
  • The ideal interval for the intensive timer is 0.04 or 0.035, but 0.03 is already too much;
  • If you know CustomScript actions and syntax, you'd better use pure JASS. It is a lot more readable and a lot less variables needed to implemented. GUI is what's lame in that point. It still takes the resources to execute all this code.
In general, it's ok. Documentation is present and is decent.

Effects: 4/5. The effect of lightning really fits here, but still, Chidori is something that requires more 'booms' or loud sounds (try war3's glowing rune sound effect that escalates in the volume? I think it will fit). Also, according to the lore, Chidori isn't something that knocks target back but it impales the target. So, most likely, caster must go through the target and trigger the chance for a lot more damage than it does. While studying the lore you can clearly understand that.

Overall: ((1+4+4)/3)=3/5. The objective rating of this spell is 3/5. It really lacks originality since it's taken from Naruto series. The documentation is good and decent but the spell uses GUI+CS and not very close to its description in manga. If I won't count originality factore here, the author did this spell good.
But unfortunately, it needs to be counted.

3/5: Useful
 
Last edited:
Level 2
Joined
May 27, 2013
Messages
17
I think this is a really cool looking spell nice job! i just have one suggestion that wouldn't be too hard to implement.

Since in the series the damage is based on the speed of the user (kakashi says this when sasuke uses is against gaara for the first time) maybe make it so that the further away the two ppl are the more damage it does. that would be really cool :)
 
Top