//==================================================================================//
// //
// 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