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

Lightning Speed Laceration 1.09

Lightning Speed Laceration v1.09 by Maker.

LSL_4.jpg


The basic idea is simple yet somewhat unique. The spell was very fun and somewhat challenging to create. I'm very happy with the result, it looks great to me in action.

I appreciate all comments and improvement suggestions.


LSL_1.jpg


LSL_2.jpg


LSL_3.jpg







  • Init LSL
    • Events
      • Map Initialization
    • Conditions
    • Actions
      • -------- -------------------------------------------------- --------
      • -------- Create hashtable to store all data --------
      • -------- -------------------------------------------------- --------
      • Hashtable - Create a hashtable
      • Set MH_Hash = (Last created hashtable)
      • -------- -------------------------------------------------- --------
      • -------- Abilities --------
      • -------- -------------------------------------------------- --------
      • -------- Lightning Speed Laceration --------
      • Set MH_Ability[0] = Lightning Speed Laceration
      • -------- LSL Dummy --------
      • Set MH_Ability[1] = LSL Dummy
      • -------- Disable Attack --------
      • Set MH_Ability[2] = Disable Attack
      • -------- -------------------------------------------------- --------
      • -------- Effects --------
      • -------- -------------------------------------------------- --------
      • -------- The effect to be attached on attacking units --------
      • Set MH_Effect[0] = Abilities\Weapons\FaerieDragonMissile\FaerieDragonMissile.mdl
      • -------- The effect to be attached on target on hit --------
      • Set MH_Effect[1] = Abilities\Weapons\GyroCopter\GyroCopterImpact.mdl
      • -------- -------------------------------------------------- --------
      • -------- The attachment point for the effect on the attacker --------
      • -------- -------------------------------------------------- --------
      • Set MH_Attach_Point = weapon
      • -------- -------------------------------------------------- --------
      • -------- Unit type of the dummy --------
      • -------- -------------------------------------------------- --------
      • Set MH_Dummy_Type = Paladin Dummy
      • -------- -------------------------------------------------- --------
      • -------- How many attack animations are you using --------
      • -------- -------------------------------------------------- --------
      • Set MH_Animation_Indexes[0] = 2
      • -------- -------------------------------------------------- --------
      • -------- The animation indexes of your attack animations --------
      • -------- -------------------------------------------------- --------
      • Set MH_Animation_Indexes[1] = 4
      • Set MH_Animation_Indexes[2] = 5
      • -------- -------------------------------------------------- --------
      • -------- Attack duration --------
      • -------- -------------------------------------------------- --------
      • Set MH_Reals[0] = 1.50
      • -------- -------------------------------------------------- --------
      • -------- First Dummy Creation Delay --------
      • -------- -------------------------------------------------- --------
      • Set MH_Reals[1] = 0.21
      • -------- -------------------------------------------------- --------
      • -------- Dummy Creation Interval --------
      • -------- -------------------------------------------------- --------
      • Set MH_Reals[2] = 0.12
      • -------- -------------------------------------------------- --------
      • -------- Dummy Visibility Time --------
      • -------- -------------------------------------------------- --------
      • Set MH_Reals[3] = 1.00
      • -------- -------------------------------------------------- --------
      • -------- Base damage --------
      • -------- -------------------------------------------------- --------
      • Set MH_Reals[4] = 40.00
      • -------- -------------------------------------------------- --------
      • -------- Bonus damage per level --------
      • -------- -------------------------------------------------- --------
      • Set MH_Reals[5] = 10.00
      • -------- -------------------------------------------------- --------
      • -------- Dummy transparency --------
      • -------- -------------------------------------------------- --------
      • Set MH_Reals[6] = 50.00
      • -------- -------------------------------------------------- --------
      • -------- Damage delay --------
      • -------- -------------------------------------------------- --------
      • Set MH_Reals[7] = 0.30
      • -------- -------------------------------------------------- --------
      • -------- Cast delay --------
      • -------- -------------------------------------------------- --------
      • Set MH_Reals[8] = 0.48
      • -------- -------------------------------------------------- --------
      • -------- Does the spell stun --------
      • -------- -------------------------------------------------- --------
      • Set MH_Booleans[0] = True
      • -------- -------------------------------------------------- --------
  • MH Begin Attack
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to MH_Ability[0]
    • Actions
      • Set u1 = (Triggering unit)
      • Set u2 = (Target unit of ability being cast)
      • -------- -------------------------------------------------- --------
      • -------- The unit handle for hashtable key --------
      • -------- -------------------------------------------------- --------
      • Custom script: set udg_i1 = GetHandleId(udg_u1)
      • -------- -------------------------------------------------- --------
      • -------- Removes the attack ability from the caster, so he does not attack on his own --------
      • -------- -------------------------------------------------- --------
      • Unit - Add MH_Ability[2] to u1
      • -------- -------------------------------------------------- --------
      • -------- Randomizes an attack animation --------
      • -------- -------------------------------------------------- --------
      • Set i2 = MH_Animation_Indexes[(Random integer number between 1 and MH_Animation_Indexes[0])]
      • -------- -------------------------------------------------- --------
      • Custom script: call SaveInteger( udg_MH_Hash, udg_i1 , StringHash( "index") , udg_i2)
      • Custom script: call SaveInteger( udg_MH_Hash, udg_i1 , StringHash( "level") , GetUnitAbilityLevel( udg_u1 , udg_MH_Ability[0] - 1 ) )
      • Custom script: call SaveReal( udg_MH_Hash, udg_i1 , StringHash("x") , GetUnitX(udg_u1) )
      • Custom script: call SaveReal( udg_MH_Hash, udg_i1 , StringHash("y") , GetUnitY(udg_u1) )
      • Custom script: call SaveUnitHandle( udg_MH_Hash , udg_i1, StringHash("target") , udg_u2 )
      • -------- -------------------------------------------------- --------
      • -------- Attach a special effect on the unit and save it --------
      • -------- -------------------------------------------------- --------
      • Custom script: call SaveEffectHandle( udg_MH_Hash, udg_i1 , StringHash("effect1") , AddSpecialEffectTarget( udg_MH_Effect[0] , udg_u1 , udg_MH_Attach_Point ) )
      • -------- -------------------------------------------------- --------
      • Unit Group - Add u1 to MH_Caster_Execute
      • Unit Group - Add u1 to MH_Caster_Stop
      • Unit Group - Add u2 to MH_Images
      • -------- -------------------------------------------------- --------
      • Trigger - Turn on MH Clear Images <gen>
      • Trigger - Turn on MH Start Effect <gen>
      • Trigger - Turn on MH Create <gen>
  • MH Start Effect
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to MH_Ability[0]
    • Actions
      • Trigger - Turn on MH Delay Order <gen>
  • MH Delay Order
    • Events
      • Time - Every 0.00 seconds of game time
    • Conditions
    • Actions
      • -------- -------------------------------------------------- --------
      • -------- This trigger is needed because I need that small delay, otherwise the orders --------
      • -------- are issued in wrong order and animations get messed up. --------
      • -------- -------------------------------------------------- --------
      • Unit Group - Pick every unit in MH_Caster_Stop and do (Actions)
        • Loop - Actions
          • Set u1 = (Picked unit)
          • -------- -------------------------------------------------- --------
          • Unit - Order u1 to Hold Position
          • -------- -------------------------------------------------- --------
          • Custom script: call SetUnitAnimationByIndex(udg_u1, LoadInteger( udg_MH_Hash, GetHandleId(udg_u1), StringHash("index")) )
          • -------- -------------------------------------------------- --------
          • Unit Group - Remove u1 from MH_Caster_Stop
          • -------- -------------------------------------------------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (MH_Caster_Stop is empty) Equal to True
            • Then - Actions
              • Trigger - Turn off (This trigger)
              • Trigger - Turn off MH Start Effect <gen>
            • Else - Actions
  • MH Create
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in MH_Caster_Execute and do (Actions)
        • Loop - Actions
          • Set u1 = (Picked unit)
          • -------- -------------------------------------------------- --------
          • Custom script: set udg_i1 = GetHandleId(udg_u1)
          • Custom script: set udg_r1 = LoadReal( udg_MH_Hash , udg_i1 , StringHash("time") )
          • Custom script: set udg_u2 = LoadUnitHandle( udg_MH_Hash, udg_i1, StringHash("target"))
          • -------- -------------------------------------------------- --------
          • Custom script: set udg_r2 = GetUnitX(udg_u1)
          • Custom script: set udg_r3 = GetUnitY(udg_u1)
          • -------- -------------------------------------------------- --------
          • Custom script: set udg_r4 = LoadReal( udg_MH_Hash , udg_i1 , StringHash("x") )
          • Custom script: set udg_r5 = LoadReal( udg_MH_Hash , udg_i1 , StringHash("y") )
          • -------- -------------------------------------------------- --------
          • -------- Check that the spell timer isn't over and that the caster and target are still alive --------
          • -------- Also check that the unit hasn't moved, thus is still casting --------
          • -------- -------------------------------------------------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (u1 is alive) Equal to True
              • (u2 is alive) Equal to True
              • r1 Less than MH_Reals[0]
              • r4 Equal to r2
              • r5 Equal to r3
            • Then - Actions
              • -------- -------------------------------------------------- --------
              • -------- The following values are the delays for creating a dummy --------
              • -------- -------------------------------------------------- --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Or - Any (Conditions) are true
                    • Conditions
                      • r1 Equal to (MH_Reals[8] - MH_Reals[2])
                      • r1 Equal to (MH_Reals[8] + MH_Reals[2])
                      • r1 Equal to (MH_Reals[8] - (2.00 x MH_Reals[2]))
                      • r1 Equal to (MH_Reals[8] + (2.00 x MH_Reals[2]))
                • Then - Actions
                  • -------- -------------------------------------------------- --------
                  • -------- Tracks how many dummies there are --------
                  • -------- -------------------------------------------------- --------
                  • Custom script: set udg_i2 = 1 + LoadInteger( udg_MH_Hash , udg_i1 , StringHash("dummies") )
                  • -------- -------------------------------------------------- --------
                  • -------- Create a dummy attacker --------
                  • -------- -------------------------------------------------- --------
                  • Custom script: set udg_u3 = CreateUnit(Player(15) , udg_MH_Dummy_Type, udg_r2 , udg_r3 , GetUnitFacing(udg_u1) )
                  • -------- -------------------------------------------------- --------
                  • Custom script: call SaveInteger( udg_MH_Hash , udg_i1 , StringHash("dummies") , udg_i2)
                  • -------- -------------------------------------------------- --------
                  • -------- Link the dummy to caster --------
                  • -------- -------------------------------------------------- --------
                  • Custom script: call SaveUnitHandle( udg_MH_Hash , udg_i1 , udg_i2 , udg_u3 )
                  • -------- -------------------------------------------------- --------
                  • -------- Create and attach a special effect on the dummy --------
                  • -------- -------------------------------------------------- --------
                  • Custom script: set bj_lastCreatedEffect = AddSpecialEffectTarget( udg_MH_Effect[0] , udg_u3 , udg_MH_Attach_Point )
                  • Custom script: call SaveEffectHandle( udg_MH_Hash, GetHandleId(udg_u3) , StringHash("effect1") , bj_lastCreatedEffect)
                  • -------- -------------------------------------------------- --------
                  • -------- Make the dummy partially transparent --------
                  • -------- -------------------------------------------------- --------
                  • Animation - Change u3's vertex coloring to (100.00%, 100.00%, 100.00%) with MH_Reals[6]% transparency
                  • Unit - Change color of u3 to (Color of (Owner of u1))
                  • -------- -------------------------------------------------- --------
                  • -------- Limit the life time of the dummy --------
                  • -------- -------------------------------------------------- --------
                  • Unit - Add a MH_Reals[3] second Generic expiration timer to u3
                  • -------- -------------------------------------------------- --------
                  • -------- Adjust stats of the dummy to affect attack speed --------
                  • -------- -------------------------------------------------- --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (u1 is A Hero) Equal to True
                    • Then - Actions
                      • Hero - Set u3 Hero-level to (Hero level of u1), Hide level-up graphics
                    • Else - Actions
                  • -------- -------------------------------------------------- --------
                  • -------- Retrieve the attack anmation for the caster and play it --------
                  • -------- -------------------------------------------------- --------
                  • Custom script: call SetUnitAnimationByIndex(udg_u3, LoadInteger( udg_MH_Hash, udg_i1, StringHash("index") ) )
                • Else - Actions
              • -------- -------------------------------------------------- --------
              • -------- Reduce the spell timer --------
              • -------- -------------------------------------------------- --------
              • Custom script: call SaveReal( udg_MH_Hash, udg_i1 , StringHash("time") , udg_r1 + 0.03)
              • -------- -------------------------------------------------- --------
              • -------- Check whether damage should be applied or not --------
              • -------- -------------------------------------------------- --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Or - Any (Conditions) are true
                    • Conditions
                      • r1 Equal to (MH_Reals[8] + MH_Reals[7])
                      • r1 Equal to (MH_Reals[8] + (MH_Reals[7] + MH_Reals[2]))
                      • r1 Equal to (MH_Reals[8] + (MH_Reals[7] + (2.00 x MH_Reals[2])))
                      • r1 Equal to (MH_Reals[8] + (MH_Reals[7] - MH_Reals[2]))
                      • r1 Equal to (MH_Reals[8] + (MH_Reals[7] - (2.00 x MH_Reals[2])))
                • Then - Actions
                  • -------- -------------------------------------------------- --------
                  • -------- Apply damage --------
                  • -------- -------------------------------------------------- --------
                  • Custom script: call UnitDamageTarget( udg_u1 , udg_u2 , ( udg_MH_Reals[4] + ( udg_MH_Reals[5] * LoadInteger( udg_MH_Hash , udg_i1 , StringHash("level") ) ) ) , true , false , ATTACK_TYPE_NORMAL , DAMAGE_TYPE_NORMAL , WEAPON_TYPE_METAL_HEAVY_BASH )
                  • -------- -------------------------------------------------- --------
                  • -------- Create effect on the target --------
                  • -------- -------------------------------------------------- --------
                  • Custom script: call DestroyEffect( AddSpecialEffectTarget( udg_MH_Effect[1] , udg_u2 , "chest" ) )
                  • -------- -------------------------------------------------- --------
                  • -------- If the original caster applies damage, create a dummy and make it cast stunning spell on the target --------
                  • -------- -------------------------------------------------- --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • MH_Booleans[0] Equal to True
                      • r1 Equal to (MH_Reals[7] + MH_Reals[8])
                    • Then - Actions
                      • Custom script: set udg_u1 = CreateUnit(Player(15) , udg_MH_Dummy_Type, GetUnitX(udg_u2) , GetUnitY(udg_u2) , GetUnitFacing(udg_u2) )
                      • -------- -------------------------------------------------- --------
                      • Animation - Change u1's vertex coloring to (100.00%, 100.00%, 100.00%) with 100.00% transparency
                      • -------- -------------------------------------------------- --------
                      • Unit - Add MH_Ability[1] to u1
                      • Unit - Order u1 to Human Mountain King - Storm Bolt u2
                      • Unit - Add a MH_Reals[3] second Generic expiration timer to u1
                      • -------- -------------------------------------------------- --------
                    • Else - Actions
                • Else - Actions
            • Else - Actions
              • -------- -------------------------------------------------- --------
              • -------- Spell over, destroy the effect on the caster --------
              • -------- -------------------------------------------------- --------
              • Custom script: call DestroyEffect(LoadEffectHandle( udg_MH_Hash, udg_i1,StringHash("effect1") ) )
              • -------- -------------------------------------------------- --------
              • Unit Group - Remove u1 from MH_Caster_Execute
              • -------- -------------------------------------------------- --------
              • Unit - Remove MH_Ability[2] from u1
              • -------- -------------------------------------------------- --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • r4 Equal to r2
                  • r5 Equal to r3
                • Then - Actions
                  • Unit - Order u1 to Stop
                • Else - Actions
                  • -------- -------------------------------------------------- --------
                  • -------- Kill dummies --------
                  • -------- -------------------------------------------------- --------
                  • For each (Integer loopA) from 1 to (Load (Key dummies) of (Key (Picked unit)) from MH_Hash), do (Actions)
                    • Loop - Actions
                      • Unit - Kill (Load loopA of i1 in MH_Hash)
              • -------- -------------------------------------------------- --------
              • Custom script: call FlushChildHashtable( udg_MH_Hash, udg_i1 )
              • -------- -------------------------------------------------- --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (MH_Caster_Execute is empty) Equal to True
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                • Else - Actions
  • MH Clear Images
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to MH_Dummy_Type
    • Actions
      • -------- -------------------------------------------------- --------
      • -------- This trigger handles the dummy units --------
      • -------- -------------------------------------------------- --------
      • Set u1 = (Triggering unit)
      • -------- -------------------------------------------------- --------
      • Custom script: set udg_i1 = GetHandleId(udg_u1)
      • -------- -------------------------------------------------- --------
      • Custom script: call DestroyEffect(LoadEffectHandle( udg_MH_Hash, udg_i1,StringHash("effect1") ) )
      • -------- -------------------------------------------------- --------
      • Custom script: call FlushChildHashtable( udg_MH_Hash, udg_i1 )
      • -------- -------------------------------------------------- --------
      • Unit Group - Remove u1 from MH_Images
      • -------- -------------------------------------------------- --------
      • Unit - Remove u1 from the game
      • -------- -------------------------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (MH_Images is empty) Equal to True
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions


JASS:
//==================================================================================//
//                                                                                  //
//  LIGHTNING SPEED LACERATION by Maker v1.00                                       //                      
//                                                                                  //
//          The caster strikes the target several times at lightning-like speed     //
//          causing severe blunt force trauma and stun.                             //
//                                                                                  //
//          Requires  JNGP and TimerUtils                                           //
//                                                                                  //
//      How to import:                                                              //
//          1.  Copy the ability                                                    //
//          2.  Copy the dummy ability                                              //
//          3.  Create a copy of your unit and make it a dummy unit.                //
//              You can take a look at the paladin dummy in this map to see         //
//              which data field you need to edit.                                  //
//          4.  Set ABILID, DUMABILID and DUMMYID to correct raw codes.             //
//              You can view raw codes in object editor by clicking Ctrl + D.       //
//          5.  Edit animation indexes in SetAnim function.                         //
//              You can use the Animation Test trigger in Test folder to            //
//              check animation indexes.                                            //
//                                                                                  //
//==================================================================================//


scope LSL

    globals
        // Ability raw code
        private constant integer        ABILID      = 'A003'
        // Dummy stun ability raw code
        private constant integer        DUMABILID   = 'A002'
        // Dummy unit raw code
        private constant integer        DUMMYID     = 'H000'
        
        private constant attacktype     ATT         = ATTACK_TYPE_NORMAL
        private constant damagetype     DAM         = DAMAGE_TYPE_NORMAL
        // Affects the sound when damage is applied
        private constant weapontype     WEA         = WEAPON_TYPE_METAL_HEAVY_BASH
        
        // Delay between starting the hit animation and applying damage
        private constant real           DMGDELAY    = 0.25
        // Delay between applying damage and removing dummies
        private constant real           DEATHDELAY  = 0.50
        // Delay of dummy creation between creating copies
        private constant real           CREATEDELAY = 0.15
        // How fast the animation plays
        private constant real           TIMESCALE   = 1.50
        // Dummy unit transparency. 0 = invisible, 255 = fully visible
        private constant integer        ALPHA       = 127
        
        // Attached to the the attackers
        private constant string         WPNEFF      = "Abilities\\Weapons\\FaerieDragonMissile\\FaerieDragonMissile.mdl"
        // Attached on the target
        private constant string         HITEFF      = "Abilities\\Weapons\\GyroCopter\\GyroCopterImpact.mdl"
        // Attach point of WPNEFF
        private constant string         HITATT      = "weapon"
        // Attach point of HITEFF
        private constant string         DMGATT      = "chest"
        
        
        private         integer         ANIMCOUNT
        private         integer array   ANIMS
    endglobals
    
    // Configure the attack animation indexes an how many of the exist
    private function SetAnims takes nothing returns nothing
        set ANIMS[1] = 4
        set ANIMS[2] = 5
        set ANIMCOUNT = 2
    endfunction
    
    // How many times the ability hits
    private constant function GetHits takes integer lvl returns integer
        return 2 + lvl
    endfunction
    
    // Damage per hit
    private constant function GetDamage takes integer lvl returns real
        return 15. + lvl * 15.
    endfunction
    
    // Handles hit instances
    private struct Hit
        unit hit
        unit caster
        unit target
        real dmg
        real dmgdelay
        real dur
        timer tim
        effect eff
        boolean b
        
        static method remove takes nothing returns nothing
            local timer t = GetExpiredTimer()
            local thistype this = GetTimerData(t)
            if .b then
                call RemoveUnit(.hit)
            else
                call SetUnitTimeScale(.hit, TIMESCALE)
            endif
            call DestroyEffect(.eff)
            call ReleaseTimer(t)
            call .destroy()
            set t = null
        endmethod
        
        static method damage takes nothing returns nothing
            local timer t = GetExpiredTimer()
            local thistype this = GetTimerData(t)
            call UnitDamageTarget(.caster, .target, .dmg, true, false, ATT, DAM, WEA)
            call DestroyEffect(AddSpecialEffectTarget(HITEFF, .target, DMGATT))
            call TimerStart(.tim, DEATHDELAY, false, function thistype.remove)
            set t = null
        endmethod
        
        static method onHit takes boolean b, integer ind, unit caster, unit tar, real dmg, real x, real y returns nothing
            local thistype this = thistype.allocate()
            
            if b then
                set .hit = CreateUnit(Player(15), DUMMYID, x, y, GetUnitFacing(caster))
                call UnitApplyTimedLife(.hit, 1, 2)
                call SetUnitColor(.hit, GetPlayerColor(GetOwningPlayer(caster)))
                call SetUnitVertexColor(.hit, 255, 255, 255, ALPHA)
                call SetUnitAnimationByIndex(.hit, ind)
            else
                set .hit = caster
            endif
            
            set .b = b
            set .caster = caster
            set .target = tar
            set .dmg = dmg
            set .tim = NewTimer()
            
            call SetUnitTimeScale(.hit, TIMESCALE)
            set .eff = AddSpecialEffectTarget(WPNEFF, .hit, HITATT)
            call SetTimerData(.tim, this)
            call TimerStart(.tim, DMGDELAY, false, function thistype.damage)
        endmethod
    endstruct
    
    private struct LSL
        real x
        real y
        real dmg
        integer lvl
        integer loops
        integer maxLoops
        unit caster
        unit target
        integer anim
        timer tim
        
        static method periodic takes nothing returns nothing
            local timer t = GetExpiredTimer()
            local thistype this = GetTimerData(t)
            
            if not(IsUnitType(.caster, UNIT_TYPE_DEAD) or GetUnitTypeId(.caster) == 0)      /*
            */ and not(IsUnitType(.target, UNIT_TYPE_DEAD) or GetUnitTypeId(.target) == 0)  /*
            */ and .loops != maxLoops                                                       /*
            */ and .x == GetUnitX(.caster)                                                  /*
            */ and .y == GetUnitY(.caster)                                                  then
                if .loops == 0 then
                    set bj_lastCreatedUnit = CreateUnit(Player(15), DUMMYID, .x, .y, GetUnitFacing(.caster))
                    call UnitApplyTimedLife(bj_lastCreatedUnit, 1, 1)
                    call SetUnitAbilityLevel(bj_lastCreatedUnit, DUMABILID, .lvl)
                    call IssueTargetOrder(bj_lastCreatedUnit, "thunderbolt", .target)
                    call ShowUnit(bj_lastCreatedUnit, false)
                    call Hit.onHit(false, .anim, .caster, .target, .dmg, .x, .y)
                else
                    call Hit.onHit(true, .anim, .caster, .target, .dmg, .x, .y)
                endif
                set .loops = .loops + 1
            else
                call ReleaseTimer(t)
                call .destroy()
            endif
            
            set t = null
        endmethod
        
        static method onCast takes nothing returns nothing
            local thistype this = thistype.allocate()
            
            set .lvl = GetUnitAbilityLevel(GetTriggerUnit(), ABILID)
            set .tim = NewTimer()
            set .loops = 0
            set .maxLoops = GetHits(.lvl)
            set .dmg = GetDamage(.lvl)
            set .caster = GetTriggerUnit()
            set .target = GetSpellTargetUnit()
            set .x = GetUnitX(.caster)
            set .y = GetUnitY(.caster)
            set .anim = ANIMS[GetRandomInt(1, ANIMCOUNT)]
            
            call SetTimerData(.tim, this)
            call SetUnitAnimationByIndex(.caster, .anim)
            call TimerStart(.tim, CREATEDELAY, true, function thistype.periodic)
        endmethod
        
        static method condition takes nothing returns boolean
            if GetSpellAbilityId() == ABILID then
                call thistype.onCast()
            endif
            return false
        endmethod
        
        private static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            call SetAnims()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(t, Condition(function thistype.condition))
            set t = null
        endmethod
    endstruct
    
endscope


v1.00 Uploaded @ 14.09.2010
v1.01 Uploaded @ 14.09.2010
*Dummies removed from the game rather than just hiding them.
*Sound is now destroyed.
*Dummies are created for neutral, not P1.
*Tooltip fixed.
*Uses bj_lastCreatedEffect rather than GetLastCreatedEffectBJ().
v1.02 Uploaded @ 14.09.2010
*Changed the event for "Starts the effect..." to "Begins casting..." for reduced delay between casting and executing the spell for smoother effect.
*Adjusted timing values, tooltip, damage.
*Increased the number of hits from 4 to 5.
v1.03 Uploaded @ 14.09.2010
*Back to "Starts the effect..." event, since "Begins casting..." doesn't trigger cooldown or reduce mana.
*The spell effect vanishes if you move while it's on.
v1.04 Uploaded @ 15.09.2010
*Re-added Locust to the dummy.
*Added target filters
v1.05 Uploaded @ 15.09.2010
*Now uses a combination of "Begins casting... and Start the effect..." to reduce the delay of starting the effect, but it still triggers cooldown and mana cost.
*How to impot -instructions.
*Adjusted timings.
v1.06 Uploaded @ 16.09.2010
*Fixed a bug causing the spell not to stun.
*Replaced some pure GUI actions with custom script JASS actions.
v1.06a Uploaded @ 27.09.2010
*The special effect attached to the caster's weapon is now correctly removed.
*Removed debug messages.
v1.07 Uploaded @ 25.01.2011
*Now using UnitDamageTarget instead of UnitDamageTargetBJ. Now the hit sound can be controlled by weapon type, and the sound plays on all hits.
v1.08 Uploaded @ 28.01.2011
*Several trigger optimizations.
*Fixed a special effect leak.
v1.09 Uploaded @ 01.03.2011
*Changed initalization trigger event fro 0.00 game time to Map initialization
*Made adding the dummy ability to use a variable.
Update @ 26.09.2011
*Added vJASS version.



Keywords:
fast, speed, multihit, lightning, maker, stun
Contents

Lightning Speed Laceration v1.08 (Map)

Reviews
12:27, 1st Mar 2011 Bribe: The short variable names are still something I would like to see prefixed or given a disclaimer for ("don't use these variable names as arrays or use them for longer than 0 seconds") The initialization should just be...

Moderator

M

Moderator

12:27, 1st Mar 2011
Bribe:

The short variable names are still something I would like to see prefixed or given a disclaimer for ("don't use these variable names as arrays or use them for longer than 0 seconds")

The initialization should just be "Map Initialization". You'll don't waste an event registry by doing it that way and it won't cause errors.

But that's not going to stop this from getting approved because the rest just looks too good.

Approved - Highly Recommended.
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
Multihit Cancel Order and MH Create can be put in the same trigger.

They serve totally different purposes. A caster is looped through Multihit Cancel Order only once per cast. If I combined them, then I'd need to add a check in the loop and it would run 30+ times basically for nothing. It's more efficient this way.

I need the 0.01 delay between the cast and ordering the unit to hold position and play attack animation so that orders/animations won't get messed up.

The trigger should be called Multihit Delay Order really.

Don't use periodic under 0.01

I'm not (though it is possible even with GUI), it's exactly 0.01. I need the delay to be as short as possible.
 
Level 6
Joined
Apr 24, 2008
Messages
174
Verry good (4/5) but:

Try to make the spell more smooth when it is casted, the hero stops for about 0.7 seconds before the effect start. Try to fix that.
Create a "ESC" option that increases the level of the hero so you can try all levels of the ability.

Thanks.
 
Level 2
Joined
Apr 18, 2008
Messages
16
I don't know if this is considered a preference or a bug ... but eh..

When you cast Lightning Speed Laceration on a target,
You can just cast it on a unit, then hit stop after you cast it and run off,
While the half invisible paladins sit there pummeling the enemy.

Other than that I love the spell,
Great Job! 4/5

Edit: OH! almost forgot, +rep!
 
Last edited:
Level 37
Joined
Mar 6, 2006
Messages
9,240
Updated to v1.02

I added a fifth hit, reduced the delay between casting, adjusted timings and tooltip.

Try to make the spell more smooth when it is casted, the hero stops for about 0.7 seconds before the effect start. Try to fix that.

Thanks a lot for the comment. I reduced the delay quite a bit. Now it's smoother. Could you test it again, see how you like it now?

When you cast Lightning Speed Laceration on a target,
You can just cast it on a unit, then hit stop after you cast it and run off,
While the half invisible paladins sit there pummeling the enemy.

Thanks for taking time to comment. I will look into this issue. Should be easy to fix.
 
Level 19
Joined
Feb 4, 2009
Messages
1,313
casted it a few times and the special effect atached to weapon was not removed from the caster
also I am sure that creating items for dummy heros is likely to cause bugs in combination with many other triggers with "unit aquires item"-event
would be better to create an illusion of the hero somehow
(powerups maybe, but there might be other ways)
regarding your 0.01 sec delay:
timers are the best choice for pretty much 0 seconds delay (something like 0.00125, don't remember real value any more but it was damn small)

I think the spell is nice
+rep
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
Update to 1.03.

The spell effect disappears if you move (or get knocked back for example).

casted it a few times and the special effect atached to weapon was not removed from the caster

Hmm...not seen that myself. I'll look into it.

also I am sure that creating items for dummy heros is likely to cause bugs in combination with many other triggers with "unit aquires item"-event

True. No items create in this version.

regarding your 0.01 sec delay:

Well, I changed it to 0.00. It's low enough.

I think the spell is nice

Thanks :)
 
Level 6
Joined
Apr 24, 2008
Messages
174
Updated to v1.02

I added a fifth hit, reduced the delay between casting, adjusted timings and tooltip.

Originally Posted by MYHummeR.
"Try to make the spell more smooth when it is casted, the hero stops for about 0.7 seconds before the effect start. Try to fix that."

Thanks a lot for the comment. I reduced the delay quite a bit. Now it's smoother. Could you test it again, see how you like it now?

I'll test the map and check the changes now.
EDIT: Much better but can still be reduced more ^^
Thanks for taking the time to change it.
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
Values below 0.01 is possible, 0.01/2?

Yeah.

Two small issues, you can target yourself and the dummy that is used has fullhealth. thts not really a problem unless you are constantly watching your health. I think the dummies health bar shouldnt show up that way it doesnt block yours.

I forgot to add target filters. I also removed Locust from the dummies at some point for testing purposes and forgot to re-add it. These issues are now fixed in v1.04.

Thanks for reporting.

EDIT:
v1.05 Uploaded @ 15.09.2010
*Now uses a combination of "Begins casting... and Start the effect..." to reduce the delay of starting the effect, but it still triggers cooldown and mana cost.

EDIT2:
v1.06 uploaded.
 
Last edited:
Level 3
Joined
Aug 20, 2010
Messages
71
maybe you can make the spell having no target and add you a buff for some sec when you will attack while having the buff you will have this effect
 
Level 14
Joined
Nov 18, 2007
Messages
1,084
The spell looks pretty nice.

MH Delay Order

    • Custom script: set udg_i2 = LoadInteger( udg_MH_Hash, GetHandleId(udg_u1), StringHash("index"))
    • Custom script: call SetUnitAnimationByIndex(udg_u1, udg_i2)
    You could just use LoadInteger( udg_MH_Hash, GetHandleId(udg_u1), StringHash("index")) directly.
MH Create

  • Checking if the unit's coordinates are the same isn't the best way to check if the unit is still casting the spell. For example, you could cast the spell and immediately stop the unit without moving, making the spell continue its effects.
    A better way would be to check if the unit's current order was still the same as the spell order. Something like this:
    Of course, for this to work, you'll want to make Lightning Speed Laceration an actual channeling spell.

    Actually, why didn't you make Lightning Speed Laceration ability a channeling spell?
    • Custom script: set udg_u3 = CreateUnit(Player(15) , udg_MH_Dummy_Type, GetUnitX(udg_u1) , GetUnitY(udg_u1) , GetUnitFacing(udg_u1) )
    Use udg_r2 and udg_r3 instead of getting the unit's coordinates again.
    • Custom script: call AddSpecialEffectTarget( udg_MH_Effect[0] , udg_u3 , udg_MH_Attach_Point )
    • Custom script: call SaveEffectHandle( udg_MH_Hash, GetHandleId(udg_u3) , StringHash("effect1") , bj_lastCreatedEffect)
    Does not work correctly since you're not using the BJ.
    • Custom script: call UnitDamageTarget( udg_u1 , udg_u2 , ( udg_MH_Reals[4] + ( udg_MH_Reals[5] * I2R(( GetUnitAbilityLevel( udg_u1 , udg_MH_Ability[0] ) - 1 ) ) ) ) , true , false , ATTACK_TYPE_NORMAL , DAMAGE_TYPE_NORMAL , WEAPON_TYPE_METAL_HEAVY_BASH )
    I2R is useless.
  • You should set the ability level of LSL Dummy for the dummy unit to the caster's ability level of Lightning Speed Laceration.
    • For each (Integer loopA) from 1 to (Load (Key dummies) of (Key (Picked unit)) from MH_Hash), do (Actions)
      • Loop - Actions
        • Unit - Kill (Load loopA of (Key (Picked unit)) in MH_Hash)
    If I'm not mistaken, I think you should use i1 instead of Key (Picked unit).
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
  • Custom script: set udg_i2 = LoadInteger( udg_MH_Hash, GetHandleId(udg_u1), StringHash("index"))
  • Custom script: call SetUnitAnimationByIndex(udg_u1, udg_i2)
You could just use LoadInteger( udg_MH_Hash, GetHandleId(udg_u1), StringHash("index")) directly.

Yeah, I originlly used the i2 for something else also, but got rid of that something else. That's why I loaded the value to i2. Fixed.

Actually, why didn't you make Lightning Speed Laceration ability a channeling spell?
The animations won't works as well. Now I also have full control over them, unlike with Channel.

  • Custom script: set udg_u3 = CreateUnit(Player(15) , udg_MH_Dummy_Type, GetUnitX(udg_u1) , GetUnitY(udg_u1) , GetUnitFacing(udg_u1) )
Use udg_r2 and udg_r3 instead of getting the unit's coordinates again.
Yes.

  • Custom script: call AddSpecialEffectTarget( udg_MH_Effect[0] , udg_u3 , udg_MH_Attach_Point )
  • Custom script: call SaveEffectHandle( udg_MH_Hash, GetHandleId(udg_u3) , StringHash("effect1") , bj_lastCreatedEffect)
Does not work correctly since you're not using the BJ.
Fixed.

  • Custom script: call UnitDamageTarget( udg_u1 , udg_u2 , ( udg_MH_Reals[4] + ( udg_MH_Reals[5] * I2R(( GetUnitAbilityLevel( udg_u1 , udg_MH_Ability[0] ) - 1 ) ) ) ) , true , false , ATTACK_TYPE_NORMAL , DAMAGE_TYPE_NORMAL , WEAPON_TYPE_METAL_HEAVY_BASH )
I2R is useless.
True.

You should set the ability level of LSL Dummy for the dummy unit to the caster's ability level of Lightning Speed Laceration.
Actully the dummies won't deal damage, only the caster does so the credit won't go to dummy units. But yeah, I should save the level when beginning to cast. Fixed.

[*]
  • For each (Integer loopA) from 1 to (Load (Key dummies) of (Key (Picked unit)) from MH_Hash), do (Actions)
    • Loop - Actions
      • Unit - Kill (Load loopA of (Key (Picked unit)) in MH_Hash)
If I'm not mistaken, I think you should use i1 instead of Key (Picked unit).
Yes.

Thank you for testing the spell.
 
Level 26
Joined
Jun 5, 2008
Messages
1,767
This is why I prefer jass spells, all you need to change is a few spots marked "Change".
I did as the instructions in the spell told me to, if they are lacking the information you just pointed out, then I have not done it, if it has pointed it out, then I have.

To be quite honest, I am not sure myself. But I always follow the instructions if I found a spell that I like.
 
Level 2
Joined
Nov 2, 2010
Messages
20
Hello, your spell is very useful and I would like to change the dummy's model.
But after I change it, the death animation will show when the dummy is die.
How can I fix it?
Thanks!
 
Level 1
Joined
Sep 30, 2011
Messages
1
Hi! Just an quite noobish question.

How whould i go forth to increase/decrease the amount of damage done, and the amount of strikes?

Im not using the JASS verson btw.

Looove the spells btw!

EDIT:
nvm, figured out.
Was looking in the wrong place. For anyone wondering its in the Init.
 
Top