Name | Type | is_array | initial_value |
u | unit | No |
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope ElectrifyingSmash initializer Init
// Electrifying Smash by The_Witcher
//The Mage lifts his enemy high into the sky to burn him with heavy lightnings.
//Then he smashes him to the ground, damaging all enemies in AOE.
// Setup Part
globals
// The Rawcode of the ability (Press Ctrl + D in object editor to show/hide rawcodes)
private constant integer ABILITY_ID = 'A000'
// The timer Interval (increase if laggs ingame)
private constant real INTERVAL = 0.01
// The amount the speed changes each interval (a amount nearer to 0 will make the unit raise higher before falling)
private constant real GRAVITY = -9.81 * INTERVAL
// The attacktype with which the units in the AOE are damaged
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL
// The damagetype with which the units in the AOE are damaged
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL
// The weapontype with which the units in the AOE are damaged
private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS
// The effect created when the target crushes down on the ground
private constant string CRUSH_EFFECT = "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"
// The effect created when the target reached the sky
private constant string LIGHTNING_EFFECT = "Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl"
// The Effect created when a lightning effect hits
private constant string DAMAGE_EFFECT = "Abilities\\Spells\\Human\\ManaFlare\\ManaFlareBoltImpact.mdl"
// The Effect created when the AOE damage is dealt
private constant string AOE_DAMAGE_EFFECT = "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
// The attachement point for all the effects
private constant string EFFECT_ATTACH = "chest"
endglobals
// Returns the damage each unit in AOE takes
private function GetDamage takes integer level returns real
return I2R(level) * 100
endfunction
// Returns the radius of the AOE
private function GetDamageRange takes integer level returns real
return I2R(level) * 50 + 150
endfunction
// Returns the maximal distance the unit gets shaked relative to the units original position
private function GetShakeRange takes integer level returns real
return I2R(level) * 7
endfunction
//-----------Don't modify anything below this line---------
private struct data
unit u
unit d
real z = 0
real x
real y
real Vz
integer t = 0
integer t2 = 0
integer phase = 1
timer tim = CreateTimer()
integer lvl
endstruct
globals
private hashtable h = InitHashtable()
private group g = CreateGroup()
private data temp
endglobals
private function FriendsOnly takes nothing returns boolean
return IsUnitAlly(GetFilterUnit(),GetOwningPlayer(temp.u)) and not (IsUnitType(GetFilterUnit(),UNIT_TYPE_DEAD) or GetUnitTypeId(GetFilterUnit()) == 0 )
endfunction
private function DamageGroup takes nothing returns nothing
call UnitDamageTarget(temp.d, GetEnumUnit(), GetDamage(temp.lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call DestroyEffect(AddSpecialEffectTarget(AOE_DAMAGE_EFFECT, GetEnumUnit(), EFFECT_ATTACH))
endfunction
private function execute takes nothing returns nothing
local data dat = LoadInteger(h,GetHandleId(GetExpiredTimer()),0)
local real zz = dat.Vz
if dat.phase == 1 then
set dat.Vz = dat.Vz + GRAVITY
if dat.Vz <= 0 and zz > 0 then
set dat.phase = 2
set dat.t = R2I(0.1/INTERVAL) - 1
endif
set dat.z = dat.z + dat.Vz
call SetUnitFlyHeight(dat.u,dat.z,0)
elseif dat.phase == 2 then
set dat.t = dat.t + 1
if ModuloInteger(dat.t,2) == 0 then
call SetUnitX(dat.u,GetRandomReal(dat.x-GetShakeRange(dat.lvl), dat.x+GetShakeRange(dat.lvl)))
call SetUnitY(dat.u,GetRandomReal(dat.y-GetShakeRange(dat.lvl), dat.y+GetShakeRange(dat.lvl)))
endif
if dat.t == R2I(0.2/INTERVAL) then
if dat.t2 == 6 then
set dat.phase = 3
call SetUnitPosition(dat.u,dat.x,dat.y)
set dat.Vz = -20
endif
call DestroyEffect(AddSpecialEffectTarget(LIGHTNING_EFFECT, dat.u, EFFECT_ATTACH))
call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, dat.u, EFFECT_ATTACH))
set dat.t = 0
set dat.t2 = dat.t2 + 1
endif
elseif dat.phase == 3 then
set dat.Vz = dat.Vz + GRAVITY
if dat.z <= 0 then
set dat.phase = 4
call DestroyEffect(AddSpecialEffect(CRUSH_EFFECT, dat.x, dat.y))
call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, dat.u, EFFECT_ATTACH))
set temp = dat
call GroupEnumUnitsInRange(g,dat.x,dat.y,GetDamageRange(dat.lvl),Condition(function FriendsOnly))
call UnitRemoveAbility(dat.u,'Avul')
call ForGroup(g,function DamageGroup)
call GroupClear(g)
endif
set dat.z = dat.z + dat.Vz
call SetUnitFlyHeight(dat.u,dat.z,0)
else
call PauseUnit(dat.u,false)
call PauseTimer(dat.tim)
call DestroyTimer(dat.tim)
call FlushChildHashtable(h,GetHandleId(dat.tim))
call dat.destroy()
endif
endfunction
private function cast takes nothing returns boolean
local data dat
if GetSpellAbilityId() == ABILITY_ID then
set dat = data.create()
set dat.u = GetSpellTargetUnit()
set dat.d = GetTriggerUnit()
call UnitAddAbility(dat.u,'Amrf')
call UnitRemoveAbility(dat.u,'Amrf')
call PauseUnit(dat.u, true)
call UnitAddAbility(dat.u,'Avul')
set dat.Vz = 8
set dat.x = GetUnitX(dat.u)
set dat.y = GetUnitY(dat.u)
set dat.lvl = GetUnitAbilityLevel(dat.d, ABILITY_ID)
call SaveInteger(h,GetHandleId(dat.tim),0,dat)
call TimerStart(dat.tim,INTERVAL,true,function execute)
endif
return false
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition(t,Condition(function cast))
call Preload(CRUSH_EFFECT)
call Preload(LIGHTNING_EFFECT)
call Preload(DAMAGE_EFFECT)
call Preload(AOE_DAMAGE_EFFECT)
endfunction
endscope