//***************************************************************************************************************
//* *
//* Runes Spell (vJASSified). *
//* By Moyack. *
//* V.2.2. *
//* *
//***************************************************************************************************************
//*
library Runes initializer init
//***************************************************************************************************************
//* The constant data where you can modify the ability properties
//*
globals
private constant integer SpellID = 'A000' // Returns the spell ID. Spell based on Serpent Ward
private constant integer RuneID = 'o000' // Returns the dummy summoned unit ID.
private constant real dt = 0.2 // the rate which the runes will detect an unit
endglobals
private constant function Range takes integer lvl returns real
return 120. + 50. * (lvl - 1) // Returns the range where the runes will detect units
endfunction
private constant function Radius takes integer lvl returns real
return 2 * Range(lvl) // Returns the radius where the runes will be placed
endfunction
private constant function Amount takes integer lvl returns integer
return 4 + 1 * (lvl - 1) // Returns the number of runes in the at the perimeter
endfunction
private constant function Damage takes integer lvl returns real
return 350. + 50. * (lvl - 1) // Returns the damage dealt to units near to the runes
endfunction
private constant function Duration takes integer lvl returns real
return 40. + 5. * (lvl - 1) // Returns the runes timed life
endfunction
//***************************************************************************************************************
//* end constant data...
//*
globals
private group G = CreateGroup()
endglobals
private function GetFX takes integer id returns string
return GetAbilityEffectById(SpellID, EFFECT_TYPE_SPECIAL, id)
endfunction
private struct rune
unit c
player p
effect f
real x
real y
real d = 0.
integer l
integer i
private static integer counter = 0
private static rune array runes
private static integer do = 0
private static integer id = 0
static unit dummy = null
private static method GetUnits takes nothing returns boolean
local unit u = GetFilterUnit()
if GetWidgetLife( u ) > 0.405 and IsUnitType(u, UNIT_TYPE_FLYING) == false then
call SetUnitOwner(rune.dummy, rune.runes[rune.id].p, false)
if GetWidgetLife(rune.runes[rune.id].c) > 0.405 then
call UnitDamageTarget(rune.runes[rune.id].c, u, Damage(rune.runes[rune.id].l), false, false, ATTACK_TYPE_SIEGE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_ROCK_HEAVY_BASH)
else
call UnitDamageTarget(rune.dummy, u, Damage(rune.runes[rune.id].l), false, false, ATTACK_TYPE_SIEGE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_ROCK_HEAVY_BASH)
endif
set rune.do = rune.do + 1
endif
set u = null
return false
endmethod
private method onDestroy takes nothing returns nothing
call DestroyEffect(.f)
if .d < Duration(.l) then
call DestroyEffect(AddSpecialEffect(GetFX(1), .x, .y))
call DestroyEffect(AddSpecialEffect(GetFX(2), .x, .y))
endif
set rune.counter = rune.counter - 1
set rune.runes[rune.counter].i = .i
set rune.runes[.i] = rune.runes[rune.counter]
endmethod
static method Start takes unit c, real x, real y returns nothing
local rune R = rune.allocate()
if IsPlayerAlly(GetLocalPlayer(), GetOwningPlayer(c)) then
set R.f = AddSpecialEffect(GetFX(0), x, y)
else
set R.f = AddSpecialEffect("Abilities\\Spells\\NightElf\\TreeofLifeUpgrade\\TreeofLifeUpgradeTargetArt.mdl", x, y)
endif
set R.c = c
set R.p = GetOwningPlayer(c)
set R.x = x
set R.y = y
set R.l = GetUnitAbilityLevel(c, SpellID)
set R.i = rune.counter
set rune.runes[rune.counter] = integer(R)
set rune.counter = rune.counter + 1
endmethod
static method Update takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= rune.counter
set rune.id = i
set rune.do = 0
set rune.runes[i].d = rune.runes[i].d + dt
call GroupEnumUnitsInRange(G, rune.runes[i].x, rune.runes[i].y, Range(rune.runes[i].l), Condition(function rune.GetUnits))
if rune.do > 0 or rune.runes[i].d >= Duration(rune.runes[i].l) then
call rune.runes[i].destroy()
endif
set i = i + 1
endloop
endmethod
endstruct
//***************************************************************************************************************
//* *
//* Runes Casting Functions *
//* *
//***************************************************************************************************************
private function Actions takes nothing returns boolean
local unit c = GetSummoningUnit()
local unit r = GetSummonedUnit()
local real lx = GetUnitX(r)
local real ly = GetUnitY(r)
local real fc = GetUnitFacing(c) * bj_DEGTORAD
local real a = Amount(GetUnitAbilityLevel(c, SpellID))
local real R = Radius(GetUnitAbilityLevel(c, SpellID))
local real angle = 2 * bj_PI / a
local integer count = 0
local real x
local real y
call RemoveUnit(r)
call rune.Start(c, lx, ly)
if GetUnitTypeId(r)==RuneID then
loop
exitwhen count == a
set x = lx + R * Cos(fc + count * angle)
set y = ly + R * Sin(fc + count * angle)
call rune.Start(c, x, y)
set count = count + 1
endloop
endif
set c = null
set r = null
return false
endfunction
//===========================================================================
private function init takes nothing returns nothing
local trigger t= CreateTrigger( )
local integer i= 0
loop
exitwhen (i<=bj_MAX_PLAYER_SLOTS)
call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SUMMON,null)
set i=1+1
endloop
call TriggerAddCondition( t, Filter( function Actions ) )
call Preload(GetFX(0))
call Preload(GetFX(1))
call Preload(GetFX(2))
set rune.dummy = CreateUnit(Player(15), RuneID, 0,0,0)
call ShowUnit(rune.dummy, false)
call TimerStart(CreateTimer(), dt, true, function rune.Update)
set t = null
endfunction
endlibrary