#include "YourName.j"
scope Winterstar initializer init
{
#define
{
ABILITY = 'A001'
INTERVAL = 0.02
RADIUS = 50
MAX_DISTANCE = 500
EFFECT_COUNT = 18
DAMAGE = GetUnitAbilityLevel(.caster, ABILITY)*300*INTERVAL
MAX_EXECUTIONS = 20
EFFECT = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"
}
private keyword Frozen
private struct Winterstar
{
unit caster
float cur
float dist
static timer t = new timer
static int total = 0
static new data
static group enum = new group
static boolexpr bool = null
static thistype create(unit caster)
{
thistype this = new thistype
.caster = caster
.dist = MAX_DISTANCE/MAX_EXECUTIONS
.cur = .dist
if .total == 0
{
TimerStart(.t, INTERVAL, true, function thistype.work)
}
.data[.total++] = this
return this
}
private static void work()
{
int i = -1
do
{
break (++i >= .total)
thistype this; this = .data[i]
float x
float y
float a = 0
int q = -1
do
{
break (++q >= EFFECT_COUNT-1)
x = GetUnitX(.caster)+(.cur+GetRandomReal(0,50))*Cos(a)
y = GetUnitY(.caster)+(.cur+GetRandomReal(0,50))*Sin(a)
DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\ManaFlare\\ManaFlareMissile.mdl", x, y))
GroupEnumUnitsInRange(.enum, x, y, RADIUS, .bool)
unit u
do
{
u = FirstOfGroup(.enum)
break (u == null)
if IsUnitEnemy(u, GetOwningPlayer(.caster)) && !IsUnitType(u, UNIT_TYPE_DEAD)
{
UnitDamageTarget(.caster, u, DAMAGE, true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL, null)
Frozen.create(u, FROZEN_TIME)
DestroyEffect(AddSpecialEffect(EFFECT, GetUnitX(u), GetUnitY(u)))
}
GroupRemoveUnit(.enum, u)
}
a += 2*bj_PI/(EFFECT_COUNT-1)
}
.cur += .dist
if .cur >= MAX_DISTANCE
{
.total--
.data[i] = .data[.total]
.destroy()
}
}
if .total == 0 {PauseTimer(.t)}
}
}
#define
{
FROZEN_INTERVAL = 0.01
FROZEN_TIME = GetUnitAbilityLevel(.caster, ABILITY)
FROZEN_ANIM_SPEED = 0
FROZEN_RED = 255
FROZEN_GREEN = 255
FROZEN_BLUE = 255
FROZEN_EFFECT = "Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathTargetArt.mdl"
FROZEN_ATTACHMENT = "origin"
}
private struct Frozen
{
unit target
float time
float max
effect fx
timer t = new timer
static hashtable hash
static group frozen = new group
private static void onInit()
{
.hash = InitHashtable()
}
static thistype create(unit target, float time)
{
thistype this
if HaveSavedInteger(.hash, GetHandleId(target), 0)
{
this = LoadInteger(.hash, GetHandleId(target), 0)
}
else
{
this = new thistype
.target = target
.fx = AddSpecialEffectTarget(FROZEN_EFFECT, target, FROZEN_ATTACHMENT)
SetUnitTimeScale(target, FROZEN_ANIM_SPEED)
SetUnitVertexColor(target, FROZEN_RED, FROZEN_GREEN, FROZEN_BLUE, 255)
GroupAddUnit(.frozen, target)
SaveInteger(.hash, GetHandleId(target), 0, this)
SaveInteger(.hash, GetHandleId(.t), 0, this)
TimerStart(.t, FROZEN_INTERVAL, true, function thistype.work)
}
.time = 0
.max = time
return this
}
private static void work()
{
thistype this = LoadInteger(.hash, GetHandleId(GetExpiredTimer()), 0)
SetUnitPosition(.target, GetUnitX(.target), GetUnitY(.target))
.time = .time+FROZEN_INTERVAL
if .time >= .max || IsUnitType(.target, UNIT_TYPE_DEAD)
{
.destroy()
}
}
private void onDestroy()
{
PauseTimer(.t)
DestroyTimer(.t)
FlushChildHashtable(.hash, GetHandleId(.target))
FlushChildHashtable(.hash, GetHandleId(.t))
SetUnitTimeScale(.target, 1)
SetUnitVertexColor(.target, 255, 255, 255, 255)
DestroyEffect(.fx)
GroupRemoveUnit(.frozen, .target)
}
}
private void work()
{
if GetSpellAbilityId() == ABILITY
{
Winterstar.create(GetTriggerUnit())
}
}
private void init()
{
trigger trg = new trigger
TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
TriggerAddAction(trg, function work)
}
}