Name | Type | is_array | initial_value |
AbilityId | abilcode | Yes | |
Angle | real | No | |
Blast_Point | location | No | |
CurGrfDis | integer | No | |
DamageId | abilcode | No | |
Data | group | Yes | |
Death_Knight | unit | No | |
DummyId | unitcode | No | |
Enemies | group | No | |
exec | integer | Yes | |
FF_Caster | unit | No | |
FF_Caster_Pnt | location | No | |
FF_Exit | boolean | No | |
FF_Level | integer | No | |
FF_Point | location | No | |
FF_Power | integer | No | |
FF_Stop | boolean | No | |
FF_Trigger | trigger | No | |
GrfDis | integer | No | |
GrfId | unitcode | No | |
i | integer | No | |
IsGrfCreated | boolean | No | |
Jaina | unit | No | |
LocalHandleCache | gamecache | No | |
MaxGrfDis | integer | No | |
MUI | boolean | Yes | |
power | integer | Yes | |
Quit | button | No | |
SetPoints | trigger | No | |
SoundId | sound | No | |
Timer | timer | Yes | |
tn | integer | No | |
Trigger | trigger | Yes | |
u | unit | Yes | |
UsingMaxSpell | integer | No | |
Victory | dialog | No | |
X | real | No | |
Y | real | No |
//TESH.scrollpos=585
//TESH.alwaysfold=0
//============================
//Freezing Field by Dark Dragon maded in Jass Craft editor
//===================
//Creates multi explosions around caster damaging enemys and slowing them
//===================
//Jass Ver of spell - 1.00
//===================
//ReadMe
//===================
//Based Dota spell - note I dont prefer to play dota as it is to much
//unbalanced and because I used Scepter and all that it looks like
//so but I only like some custom spells in dota nothing more.
//I find people talking why did I have to make a clone of dota spell?
//Answer here is simpel "in jass I mean" I added some special grafics
//and damages is not as same in dota + I cant knowe which polarprojection
//exactly IceFrog use, but however this is dota based spell.
//Feel free to use this code as your own you have rights to do anything
//whit it, if you want you can edit it and post on other sites
//but please dont replace me whit yourself you can add your nick
//as one who edited this spell.
//So have fun!!!
//===================
//Global Vars
//End Globals
//******* - Code - ********
function SetTimerData takes timer t, group data returns nothing
set udg_Timer[udg_tn] = t
set udg_Data[udg_tn] = data
set udg_tn = udg_tn + 1
endfunction
function GetTimerData takes timer t returns group
local integer i = 0
loop
exitwhen i == udg_tn
if udg_Timer[i] == t then
return udg_Data[i]
endif
set i = i + 1
endloop
return null
endfunction
function ClearTimerData takes timer t, boolean destroy returns nothing
local integer i = 0
loop
exitwhen i == udg_tn
if udg_Timer[i] == t then
set udg_Data[i] = udg_Data[udg_tn-1]
set udg_Timer[i] = udg_Timer[udg_tn-1]
set udg_tn = udg_tn-1
exitwhen true
endif
set i = i + 1
endloop
if destroy then
call PauseTimer(t)
call DestroyTimer(t)
endif
endfunction
//--- PolarProjections ---
// ( X )
function PolarProjectionX takes real x, real dis, real angle returns real
return x + dis * Cos( angle * bj_DEGTORAD )
endfunction
// ( Y )
function PolarProjectionY takes real y, real dis, real angle returns real
return y + dis * Sin( angle * bj_DEGTORAD )
endfunction
//--- Raw-Codes ---
//Freezing Field
constant function FF_RawCode takes nothing returns integer
return 'A000'
endfunction
//Freezing Field Upgraded
constant function FFU_RawCode takes nothing returns integer
return 'A004'
endfunction
//Freezing Field Damage
constant function FFD_RawCode takes nothing returns integer
return 'A001'
endfunction
//Dummy
constant function D_RawCode takes nothing returns integer
return 'e000'
endfunction
//Grafics Unit
constant function Grf_RawCode takes nothing returns integer
return 'e001'
endfunction
//Locust
constant function L_RawCode takes nothing returns integer
return 'Aloc'
endfunction
//Expire Timer
constant function Exp_RawCode takes nothing returns integer
return 'BTLF'
endfunction
//======= Main Condition ========
function Freezing_Field_Cond takes nothing returns boolean
return GetSpellAbilityId() == FF_RawCode() or GetSpellAbilityId() == FFU_RawCode()
endfunction
function disableMe takes nothing returns nothing
call DisableTrigger(GetTriggeringTrigger())
endfunction
function moveenum takes nothing returns nothing
local unit u = GetEnumUnit()
set udg_Angle = udg_Angle + 10.
call SetUnitPosition(u, PolarProjectionX(GetUnitX(u), 3., udg_Angle), PolarProjectionY( GetUnitY(u), 3., udg_Angle))
endfunction
function killenum takes nothing returns nothing
call KillUnit(GetEnumUnit())
endfunction
function moveGrpEffects takes nothing returns nothing
local timer t = GetExpiredTimer()
local group g = GetTimerData(t)
local unit u = FirstOfGroup(g)
local integer exec = GetUnitUserData(u)+1
call SetUnitUserData(u, exec)
if exec == 200 then
call ForGroup(g, function killenum)
call ClearTimerData(t, true)
call DestroyGroup(g)
return
endif
set udg_Angle = 0.
call ForGroup(g, function moveenum)
endfunction
//********************************************
function Freezing_Field_Act takes nothing returns nothing
//Main setup loads globals and runs func
local unit c = GetTriggerUnit()
local real x = GetUnitX(c)
local real y = GetUnitY(c)
local integer power = 0
local integer i = 0
local integer j = 0
local unit u
local real dist
local real angle
local player p = GetOwningPlayer(c)
local trigger t = CreateTrigger()
local triggeraction ta
local group g = CreateGroup()
local timer tim = CreateTimer()
call TriggerRegisterUnitEvent(t, c, EVENT_UNIT_SPELL_ENDCAST)
call TriggerAddCondition(t, Condition(function Freezing_Field_Cond))
set ta = TriggerAddAction(t, function disableMe)
//Setup levele
if GetSpellAbilityId() == FF_RawCode() then
set power = GetUnitAbilityLevel(c, FF_RawCode())
else
set power = GetUnitAbilityLevel(c, FFU_RawCode())+1
endif
loop
exitwhen i >= 36
set u = CreateUnit(p, Grf_RawCode(), x, y, 0.)
call UnitAddAbility(u, L_RawCode())
call GroupAddUnit(g, u)
set i = i + 1
endloop
call SetTimerData(tim, g)
call TimerStart(tim, 0.01, true, function moveGrpEffects)
// Sets Points at wich the expl are created
//=========================
// Create Effects on caster
call DestroyEffect(AddSpecialEffectTarget( "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl", c, "origin" ))
//=========================
call SetSoundPosition( gg_snd_GlacierBlast, x, y, 0 )
call SetSoundVolume( gg_snd_GlacierBlast, 127 )
call StartSound( gg_snd_GlacierBlast )
// 1. Explosion
set dist = 256
set angle = 270
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
// 2. Explosion
set dist = 180
set angle = 180
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
// 3. Explosion
set dist = 189
set angle = 360
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
// 4. Explosion
set dist = 221
set angle = 90
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
// 5. Explosion
set dist = GetRandomReal( 200, 300 )
set angle = GetRandomReal( 0, 360 )
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
if not IsTriggerEnabled(t) then
call TriggerRemoveAction(t, ta)
call DestroyTrigger(t)
return
endif
// Now Multi Explosions
set i = 1
loop
exitwhen i > 2
set dist = 380
set angle = 152
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 273
set angle = 0
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 275
set angle = 162
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 311
set angle = 74
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
if not IsTriggerEnabled(t) then
call TriggerRemoveAction(t, ta)
call DestroyTrigger(t)
return
endif
set dist = 197
set angle = 96
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 243
set angle = 124
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 340
set angle = 325
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 458
set angle = 192
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = 181
set angle = 11
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 293
set angle = 142
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = 215
set angle = 187
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 343
set angle = 11
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 359
set angle = 357
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 186
set angle = 164
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 199
set angle = 182
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
if not IsTriggerEnabled(t) then
call TriggerRemoveAction(t, ta)
call DestroyTrigger(t)
return
endif
set dist = 212
set angle = 263
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 179
set angle = 283
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 227
set angle = 78
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 194
set angle = 87
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = 275
set angle = 162
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 367
set angle = 314
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 317
set angle = 47
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = 374
set angle = 138
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
if not IsTriggerEnabled(t) then
call TriggerRemoveAction(t, ta)
call DestroyTrigger(t)
return
endif
set dist = 300
set angle = 220
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set i = i + 1
endloop
set dist = GetRandomReal(200,370)
set angle = GetRandomReal(0,90)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
if not IsTriggerEnabled(t) then
call TriggerRemoveAction(t, ta)
call DestroyTrigger(t)
return
endif
set dist = GetRandomReal(175,470)
set angle = GetRandomReal(40,128)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = GetRandomReal(230,348)
set angle = GetRandomReal(90,190)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = GetRandomReal(200,420)
set angle = GetRandomReal(140,220)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = GetRandomReal(200,370)
set angle = GetRandomReal(0,90)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = GetRandomReal(200,440)
set angle = GetRandomReal(90,180)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = GetRandomReal(200,370)
set angle = GetRandomReal(180,270)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = GetRandomReal(250,470)
set angle = GetRandomReal(270,360)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = GetRandomReal(250,470)
set angle = GetRandomReal(270,360)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = GetRandomReal(180,480)
set angle = GetRandomReal(0,360)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerRemoveAction(t, ta)
call DestroyTrigger(t)
endfunction
function InitTrig_Freezing_Field_Jass takes nothing returns nothing
local integer i = 0
set gg_trg_Freezing_Field_Jass = CreateTrigger()
//natives are much faster
loop
exitwhen i >= bj_MAX_PLAYERS
call TriggerRegisterPlayerUnitEvent( gg_trg_Freezing_Field_Jass, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, Filter(null) )
set i = i + 1
endloop
call TriggerAddCondition( gg_trg_Freezing_Field_Jass, Condition( function Freezing_Field_Cond ) )
call TriggerAddAction( gg_trg_Freezing_Field_Jass, function Freezing_Field_Act )
//Preloader
call Preload("Abilities\\Weapons\\ZigguratFrostMissile\\ZigguratFrostMissile.mdl")
call Preload("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl")
call Preload("Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl")
call Preload("Abilities\\Spells\\Other\\FrostDamage\\FrostDamage.mdl")
call PreloadEnd(2.)
endfunction
//TESH.scrollpos=189
//TESH.alwaysfold=0
//============================
//Freezing Field by Dark Dragon maded in Jass Craft editor
//===================
//Creates multi explosions around caster damaging enemys and slowing them
//===================
//Jass Ver of spell - 1.00
//===================
//ReadMe
//===================
//Based Dota spell - note I dont prefer to play dota as it is to much
//unbalanced and because I used Scepter and all that it looks like
//so but I only like some custom spells in dota nothing more.
//I find people talking why did I have to make a clone of dota spell?
//Answer here is simpel "in jass I mean" I added some special grafics
//and damages is not as same in dota + I cant knowe which polarprojection
//exactly IceFrog use, but however this is dota based spell.
//Feel free to use this code as your own you have rights to do anything
//whit it, if you want you can edit it and post on other sites
//but please dont replace me whit yourself you can add your nick
//as one who edited this spell.
//So have fun!!!
//===================
//Global Vars
//End Globals
//******* - Code - ********
function SetTimerData takes timer t, group data returns nothing
set udg_Timer[udg_tn] = t
set udg_Data[udg_tn] = data
set udg_tn = udg_tn + 1
endfunction
function GetTimerData takes timer t returns group
local integer i = 0
loop
exitwhen i == udg_tn
if udg_Timer[i] == t then
return udg_Data[i]
endif
set i = i + 1
endloop
return null
endfunction
function ClearTimerData takes timer t, boolean destroy returns nothing
local integer i = 0
loop
exitwhen i == udg_tn
if udg_Timer[i] == t then
set udg_Data[i] = udg_Data[udg_tn-1]
set udg_Timer[i] = udg_Timer[udg_tn-1]
set udg_tn = udg_tn-1
exitwhen true
endif
set i = i + 1
endloop
if destroy then
call PauseTimer(t)
call DestroyTimer(t)
endif
endfunction
//--- PolarProjections ---
// ( X )
function PolarProjectionX takes real x, real dis, real angle returns real
return x + dis * Cos( angle * bj_DEGTORAD )
endfunction
// ( Y )
function PolarProjectionY takes real y, real dis, real angle returns real
return y + dis * Sin( angle * bj_DEGTORAD )
endfunction
//--- Raw-Codes ---
//Freezing Field
constant function FF_RawCode takes nothing returns integer
return udg_AbilityId[0]
endfunction
//Freezing Field Upgraded
constant function FFU_RawCode takes nothing returns integer
return udg_AbilityId[1]
endfunction
//Freezing Field Damage
constant function FFD_RawCode takes nothing returns integer
return udg_DamageId
endfunction
//Dummy
constant function D_RawCode takes nothing returns integer
return udg_DummyId
endfunction
//Grafics Unit
constant function Grf_RawCode takes nothing returns integer
return udg_GrfId
endfunction
//Locust
constant function L_RawCode takes nothing returns integer
return 'Aloc'
endfunction
//Expire Timer
constant function Exp_RawCode takes nothing returns integer
return 'BTLF'
endfunction
//======= Main Condition ========
function Freezing_Field_Cond takes nothing returns boolean
return GetSpellAbilityId() == FF_RawCode() or GetSpellAbilityId() == FFU_RawCode()
endfunction
function disableMe takes nothing returns nothing
call DisableTrigger(GetTriggeringTrigger())
endfunction
function moveenum takes nothing returns nothing
local unit u = GetEnumUnit()
set udg_Angle = udg_Angle + 10.
call SetUnitPosition(u, PolarProjectionX(GetUnitX(u), 3., udg_Angle), PolarProjectionY( GetUnitY(u), 3., udg_Angle))
endfunction
function killenum takes nothing returns nothing
call KillUnit(GetEnumUnit())
endfunction
function moveGrpEffects takes nothing returns nothing
local timer t = GetExpiredTimer()
local group g = GetTimerData(t)
local unit u = FirstOfGroup(g)
local integer exec = GetUnitUserData(u)+1
call SetUnitUserData(u, exec)
if exec == udg_MaxGrfDis/3 then
call ForGroup(g, function killenum)
call ClearTimerData(t, true)
call DestroyGroup(g)
return
endif
set udg_Angle = 0.
call ForGroup(g, function moveenum)
endfunction
//********************************************
function Freezing_Field_Act takes nothing returns nothing
//Main setup loads globals and runs func
local unit c = GetTriggerUnit()
local real x = GetUnitX(c)
local real y = GetUnitY(c)
local integer power = 0
local integer i = 0
local integer j = 0
local unit u
local real dist
local real angle
local player p = GetOwningPlayer(c)
local trigger t = CreateTrigger()
local triggeraction ta
local group g = CreateGroup()
local timer tim = CreateTimer()
call TriggerRegisterUnitEvent(t, c, EVENT_UNIT_SPELL_ENDCAST)
call TriggerAddCondition(t, Condition(function Freezing_Field_Cond))
set ta = TriggerAddAction(t, function disableMe)
//Setup levele
if GetSpellAbilityId() == FF_RawCode() then
set power = GetUnitAbilityLevel(c, FF_RawCode())
else
set power = GetUnitAbilityLevel(c, FFU_RawCode())+1
endif
loop
exitwhen i >= 36
set u = CreateUnit(p, Grf_RawCode(), x, y, 0.)
call UnitAddAbility(u, L_RawCode())
call GroupAddUnit(g, u)
set i = i + 1
endloop
call SetTimerData(tim, g)
call TimerStart(tim, 0.01, true, function moveGrpEffects)
// Sets Points at wich the expl are created
//=========================
// Create Effects on caster
call DestroyEffect(AddSpecialEffectTarget( "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl", c, "origin" ))
//=========================
call SetSoundPosition( udg_SoundId, x, y, 0 )
call SetSoundVolume( udg_SoundId, 127 )
call StartSound( udg_SoundId )
// 1. Explosion
set dist = 256
set angle = 270
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
// 2. Explosion
set dist = 180
set angle = 180
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
// 3. Explosion
set dist = 189
set angle = 360
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
// 4. Explosion
set dist = 221
set angle = 90
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
// 5. Explosion
set dist = GetRandomReal( 200, 300 )
set angle = GetRandomReal( 0, 360 )
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
if not IsTriggerEnabled(t) then
call TriggerRemoveAction(t, ta)
call DestroyTrigger(t)
return
endif
// Now Multi Explosions
set i = 1
loop
exitwhen i > 2
set dist = 380
set angle = 152
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 273
set angle = 0
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 275
set angle = 162
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 311
set angle = 74
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
if not IsTriggerEnabled(t) then
call TriggerRemoveAction(t, ta)
call DestroyTrigger(t)
return
endif
set dist = 197
set angle = 96
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 243
set angle = 124
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 340
set angle = 325
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 458
set angle = 192
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = 181
set angle = 11
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 293
set angle = 142
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = 215
set angle = 187
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 343
set angle = 11
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 359
set angle = 357
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 186
set angle = 164
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 199
set angle = 182
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
if not IsTriggerEnabled(t) then
call TriggerRemoveAction(t, ta)
call DestroyTrigger(t)
return
endif
set dist = 212
set angle = 263
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 179
set angle = 283
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 227
set angle = 78
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 194
set angle = 87
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = 275
set angle = 162
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 367
set angle = 314
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = 317
set angle = 47
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = 374
set angle = 138
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
if not IsTriggerEnabled(t) then
call TriggerRemoveAction(t, ta)
call DestroyTrigger(t)
return
endif
set dist = 300
set angle = 220
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set i = i + 1
endloop
set dist = GetRandomReal(200,370)
set angle = GetRandomReal(0,90)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
if not IsTriggerEnabled(t) then
call TriggerRemoveAction(t, ta)
call DestroyTrigger(t)
return
endif
set dist = GetRandomReal(175,470)
set angle = GetRandomReal(40,128)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = GetRandomReal(230,348)
set angle = GetRandomReal(90,190)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = GetRandomReal(200,420)
set angle = GetRandomReal(140,220)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = GetRandomReal(200,370)
set angle = GetRandomReal(0,90)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = GetRandomReal(200,440)
set angle = GetRandomReal(90,180)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = GetRandomReal(200,370)
set angle = GetRandomReal(180,270)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
set dist = GetRandomReal(250,470)
set angle = GetRandomReal(270,360)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = GetRandomReal(250,470)
set angle = GetRandomReal(270,360)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerSleepAction( 0.05 )
set dist = GetRandomReal(180,480)
set angle = GetRandomReal(0,360)
set u = CreateUnit( p, D_RawCode(), PolarProjectionX(x, dist, angle), PolarProjectionY(y, dist, angle), 0. )
call UnitAddAbility(u, FFD_RawCode())
call UnitApplyTimedLife( u, Exp_RawCode(), 1. )
call SetUnitAbilityLevel( u, FFD_RawCode(), power )
call IssueTargetOrder( u, "frostnova", u )
call TriggerRemoveAction(t, ta)
call DestroyTrigger(t)
endfunction
function InitTrig_Freezing_Field_Jass_Adv takes nothing returns nothing
local integer i = 0
set gg_trg_Freezing_Field_Jass_Adv = CreateTrigger()
//natives are much faster
loop
exitwhen i >= bj_MAX_PLAYERS
call TriggerRegisterPlayerUnitEvent( gg_trg_Freezing_Field_Jass_Adv, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, Filter(null) )
set i = i + 1
endloop
call TriggerAddCondition( gg_trg_Freezing_Field_Jass_Adv, Condition( function Freezing_Field_Cond ) )
call TriggerAddAction( gg_trg_Freezing_Field_Jass_Adv, function Freezing_Field_Act )
//Preloader
call Preload("Abilities\\Weapons\\ZigguratFrostMissile\\ZigguratFrostMissile.mdl")
call Preload("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl")
call Preload("Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl")
call Preload("Abilities\\Spells\\Other\\FrostDamage\\FrostDamage.mdl")
call PreloadEnd(2.)
endfunction
//TESH.scrollpos=589
//TESH.alwaysfold=0
// *****************************************************************************
// * Spell: Frezzing Field
// * -> By: Dark Dragon
// * -> Date: March 4 2009
// *
// *
// * --- Installation ---
// *
// * - 1. Get latest version of Jass NewGen and JassHelper from wc3c.net
// * - 2. If you don't have dummy.mdx model in your map extract it from here
// * - 3. Copy dummy unit from Object Editor (F6) and paste it in your map
// * - 4. Copy abilities: Freezing Field Damage, Freezing Field and/or Freezing Field Upgraded
// * - 5. Copy FF Upgrade ability if you want to use upgraded and add that ability to item you want
// * - 6. Copy this trigger and paste it in your map
// * - 7. Start reading below until it says "don't edit if you don't know jass"
// * (you must edit rawcodes to match your map) go to object editor and enable View -> Display Values As Raw Data
// * - 8. Edit rawcodes here and spell to style, as you wish and save your map
// * - 9. Enjoy!
// *****************************************************************************
// =====================================================================
// Frezzing Field library
//
library FrizzingField initializer Init_FreezingField
// **********************************************************
// --- Editable Spell Globals
// **********************************************************
globals
// This is the rawcode of the spell frezzing field
// Default: 'A000'
private constant integer FF_RAWCODE = 'A000'
// This is the rawcode of the spell frezzing field upgraded
// Default: 'A004'
private constant integer FFU_RAWCODE = 'A004'
// This is the rawcode of dummy unit
// Default: 'e000'
private constant integer DUM_RAWCODE = 'e000'
// This is the dummy ability frost nova
// Default: 'A001'
private constant integer DFN_RAWCODE = 'A001'
// This is the path to graphic effect
// Default: "Abilities\\Weapons\\ZigguratFrostMissile\\ZigguratFrostMissile.mdl"
private constant string GEFF_MODEL = "Abilities\\Weapons\\ZigguratFrostMissile\\ZigguratFrostMissile.mdl"
// This is the casters channel effect model
// Default: "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
private constant string CEFF_MODEL = "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
// This is the path to sound file which will be played when spell is cast
// Default: "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget1.wav"
private constant string GLACIER_SOUND = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget1.wav"
// This tells should graphic effects be created
// Default: true
private constant boolean ALLOW_GEFFECTS = true
// This is the graphic effect speed
// Default: 500.
private constant real GEFFECT_SPEED = 500.
// Shards min pass distance
// Default: 175.
private constant real SHARD_MIN_DISTANCE = 175.
// Shards max pass distance
// Default: 525.
private constant real SHARD_MAX_DISTANCE = 525.
// Shards min pass height
// Default: 200.
private constant real SHARD_MIN_HEIGHT = 200.
// Shards max pass height
// Default: 375.
private constant real SHARD_MAX_HEIGHT = 375.
// This is shards min count per cast
// Default: 8
private constant integer SHARD_MIN_COUNT = 10
// This is shards max count per cast
// Default: 10
private constant integer SHARD_MAX_COUNT = 16
// Shards min duration
// Default: 0.9
private constant real SHARD_MIN_TIMEOUT = 0.9
// Shards max duration
// Default: 1.8
private constant real SHARD_MAX_TIMEOUT = 1.8
// Do not touch this variables here
//{
private integer Levels = 0
private real array ExplosionDelay[8191]
private real array ExplosionArea[8191]
private real array ExplosionDur[8191]
//}
endglobals
// ===================================================
// *** Edit Frezzing Field Level Data ***
// ===================================================
private function Setup_FreezingField takes nothing returns nothing
// This is the max level of spell (add + one level if you use upgrader)
// So if Levels = 3, you must defined 4 levels like below
// Default: 3
set Levels = 3
// Max spell area of effect
// Default: 400, 435, 475, 500
set ExplosionArea[1] = 400.
set ExplosionArea[2] = 435.
set ExplosionArea[3] = 475.
set ExplosionArea[4] = 500.
// How offten explosions are created
// Default: 0.15, 0.13, 0.11, 0.10
set ExplosionDelay[1] = 0.15
set ExplosionDelay[2] = 0.13
set ExplosionDelay[3] = 0.11
set ExplosionDelay[4] = 0.10
// How long spell will last
// Default: 3, 3, 3, 3
set ExplosionDur[1] = 3.
set ExplosionDur[2] = 3.
set ExplosionDur[3] = 3.
set ExplosionDur[4] = 3.
endfunction
// ===== Do not edit below if you don't know jass =====
// --- Keywords ---
private keyword ArrayId
private keyword GetSpellLevel
private keyword GetAverageValue
// *******************************
// Spell uneditable globals
globals
private constant real TIMER_MOVE_DELAY = 0.025
private constant real PI_HALF = bj_PI / 2.
private constant real TWO_PI = 2. * bj_PI
private filterfunc this_filter = null
private boolean array IsCasting[8191]
endglobals
// ===================================================
// --- Freezing Field main struct ---
// ===================================================
private struct ffield
// **************************
// --- ffield members ---
private unit u
private real x
private real y
private integer lvl
private integer counter
private real dur
private player p
// ****************************
// --- Static variables ---
private static constant real MIN_DIST = 50.
// *** Constructor ***
public static method create takes nothing returns ffield
local ffield this = ffield.allocate()
set this.u = GetTriggerUnit()
set this.x = GetUnitX(this.u)
set this.y = GetUnitY(this.u)
set this.p = GetOwningPlayer(this.u)
set this.lvl = GetSpellLevel.evaluate(this.u)
set this.dur = ExplosionDur[this.lvl]
set this.counter = 1
set IsCasting[ArrayId.evaluate(this.u)] = true
return (this)
endmethod
// Will generate next counter
private method NextCounter takes nothing returns nothing
set this.counter = this.counter + GetRandomInt(1, 2)
set this.counter = (this.counter - (this.counter / 4) * 4) + 1
endmethod
// Will return angle for current explosion
private method Angle takes nothing returns real
local real min = (this.counter-1)*PI_HALF
local real max = min + PI_HALF
call this.NextCounter()
return GetRandomReal(min, max)
endmethod
// Returns distance for each explosion
private method Distance takes nothing returns real
return GetRandomReal(this.MIN_DIST, ExplosionArea[this.lvl])
endmethod
// Causes a single explosion
public method Explode takes nothing returns nothing
local unit u = null
local real ang = this.Angle()
local real dist = this.Distance()
set u = CreateUnit(this.p, DUM_RAWCODE, this.x + dist * Cos(ang), this.y + dist * Sin(ang), bj_UNIT_FACING)
call UnitAddAbility(u, DFN_RAWCODE)
call SetUnitAbilityLevel(u, DFN_RAWCODE, this.lvl)
call IssueTargetOrder(u, "frostnova", u)
call UnitAddAbility(u, 'Aloc')
call UnitApplyTimedLife(u, 'BTLF', 0.5)
set u = null
//call SetRandomSeed(GetRandomInt(0, 1000000))
endmethod
// Adds caster effect to caster
public method AddEffect takes string modelFile returns nothing
call DestroyEffect(AddSpecialEffectTarget(modelFile, this.u, "origin"))
endmethod
// Timeout for explosion
public method operator timeout takes nothing returns real
return ExplosionDelay[this.lvl]
endmethod
// Checks is this ffield valid
public method operator valid takes nothing returns boolean
debug call BJDebugMsg("in valid lvl = "+I2S(this.lvl))
return (this.lvl != -1)
endmethod
// Our end spell check
public method operator done takes nothing returns boolean
set this.dur = this.dur - this.timeout
return (this.dur <= 0. or not IsCasting[ArrayId.evaluate(this.u)])
endmethod
// How should this object be destroyed ~Destructor
public method onDestroy takes nothing returns nothing
debug set IsCasting[ArrayId.evaluate(this.u)] = false
set this.u = null
set this.p = null
endmethod
endstruct
// ===================================================
// --- Triggerx new non-leaking trigger type ---
// ===================================================
private struct triggerx
// Triggerx members
private trigger t
private triggeraction ta
private integer value
private timer tm
// Static vars
private static triggerx array ThisTriggx[8191]
// *** Constructor ***
public static method create takes code cond, code act, integer val returns triggerx
local triggerx this = triggerx.allocate()
set this.t = CreateTrigger()
set this.tm = null
set this.value = val
if (cond != null) then
call TriggerAddCondition(this.t, Condition(cond))
endif
if (act != null) then
set this.ta = TriggerAddAction(this.t, act)
endif
// Pointer at our triggerx
set this.ThisTriggx[ArrayId.evaluate(this.t)] = (this)
return (this)
endmethod
// Set custom value
public method SetValue takes integer val returns nothing
set this.value = val
endmethod
// Get custom value
public method GetValue takes nothing returns integer
return (this.value)
endmethod
// Will execute this triggerx
public method Execute takes nothing returns nothing
call TriggerExecute(this.t)
endmethod
// Returns triggering triggerx
public static method TriggeringTriggerx takes trigger trig returns triggerx
return (triggerx.ThisTriggx[ArrayId.evaluate(trig)])
endmethod
// Registers give timer to triggerx
public method RegisterTimerEvent takes real timeout returns nothing
set this.tm = CreateTimer()
call TimerStart(this.tm, timeout, true, null)
call TriggerRegisterTimerExpireEvent(this.t, this.tm)
endmethod
// This will add new event (when units stop spell cast)
public method RegisterEndSpellCast takes unit u returns nothing
call TriggerRegisterUnitEvent(this.t, u, EVENT_UNIT_SPELL_ENDCAST)
endmethod
// Returns current execution of triggerx
public method operator exec takes nothing returns integer
return GetTriggerExecCount(this.t)
endmethod
// *** ~Destructor ***
public method onDestroy takes nothing returns nothing
if (this.tm != null) then
call PauseTimer(this.tm)
call DestroyTimer(this.tm)
set this.tm = null
endif
set this.ThisTriggx[ArrayId.evaluate(this.t)] = 0
call TriggerRemoveAction(this.t, this.ta)
call DestroyTrigger(this.t)
set this.t = null
set this.ta = null
endmethod
endstruct
// ===================================================
// --- This is our ice shard struct ---
// ===================================================
// *** Functions for shard ***
// Calculates sign of number
private constant function Sign takes real x returns real
if (x >= 0.) then
return 1.
endif
return -1.
endfunction
// Will change unit's z axes
private function SetUnitZ takes unit whichUnit, real newz returns nothing
call SetUnitFlyHeight(whichUnit, newz, 0.)
endfunction
private struct shard
// * Shard struct members
private unit u
private effect e
private real x
private real y
private real z
private real dx
private real dy
private real xy_vel
private real z_vel
private real max_dist
private real dist
// Shard static members
private static constant player NEUTRAL = Player(0xF)
private static constant string ATTACH = "origin"
// * Constructor
public static method create takes real x, real y, real facing, real dist, real height, real time returns shard
local shard this = shard.allocate()
set this.u = CreateUnit(this.NEUTRAL, DUM_RAWCODE, x, y, facing)
set this.e = AddSpecialEffectTarget(GEFF_MODEL, this.u, this.ATTACH)
set this.x = x
set this.y = y
set this.z = 0.
set this.dx = Cos(facing * bj_DEGTORAD)
set this.dy = Sin(facing * bj_DEGTORAD)
set this.xy_vel = (2.*dist) / time
set this.z_vel = (2.*height) / time
set this.max_dist = dist
set this.dist = 0.
// Make dummy unselectable and flyable
call UnitAddAbility(this.u, 'Amrf')
call UnitAddAbility(this.u, 'Aloc')
return (this)
endmethod
// *** Our offset move method ***
private method OffsetMove takes nothing returns nothing
set this.x = this.x + this.xy_vel*TIMER_MOVE_DELAY * this.dx
set this.y = this.y + this.xy_vel*TIMER_MOVE_DELAY * this.dy
set this.z = this.z + this.z_vel*TIMER_MOVE_DELAY * Sign(-this.dist+this.max_dist/2.)
set this.dist = this.dist + this.xy_vel*TIMER_MOVE_DELAY
call SetUnitX(this.u, this.x)
call SetUnitY(this.u, this.y)
call SetUnitZ(this.u, this.z)
endmethod
// Checks for condition
public method OffsetMoveEx takes nothing returns nothing
if (this.dist < this.max_dist) then
call this.OffsetMove()
endif
endmethod
// Checks did shard complete its movement
public method operator done takes nothing returns boolean
return (this.dist >= this.max_dist)
endmethod
// ~Destructor
public method onDestroy takes nothing returns nothing
call DestroyEffect(this.e)
call RemoveUnit(this.u)
set this.e = null
set this.u = null
endmethod
endstruct
// ===================================================
// --- The cluster is the shards group ---
// ===================================================
private struct cluster
// *Cluster members
private shard array sh[SHARD_MAX_COUNT]
private boolean fin
private integer count
private real dur
private real cx
private real cy
// Cluster static constants
private static constant real a = 1./(125.*(SHARD_MIN_DISTANCE-SHARD_MAX_DISTANCE))
private static constant real b = -SHARD_MAX_DISTANCE/(125.*(SHARD_MIN_DISTANCE-SHARD_MAX_DISTANCE))
// *Constructor
public static method create takes integer count, real dur, real cx, real cy returns cluster
local cluster this = cluster.allocate()
local real passd
local real offsetd
local real x
local real y
local real rad
local real offsetrad
local real h
local real t
set this.count = count
set this.fin = false
set this.dur = dur
set this.cx = cx
set this.cy = cy
set offsetrad = (TWO_PI*0.5)/count
set count = 0
loop
exitwhen (count >= this.count)
set rad = count*(TWO_PI/this.count)
set rad = GetRandomReal(rad-offsetrad, rad+offsetrad)
set passd = GetRandomReal(SHARD_MIN_DISTANCE, SHARD_MAX_DISTANCE)
set offsetd = (passd * this.a) + this.b
set x = cx + offsetd * Cos(rad)
set y = cy + offsetd * Sin(rad)
set h = GetRandomReal(SHARD_MIN_HEIGHT, SHARD_MAX_HEIGHT)
set t = GetRandomReal(SHARD_MIN_TIMEOUT, SHARD_MAX_TIMEOUT)
set this.sh[count] = shard.create(x, y, rad*bj_RADTODEG, passd, h, t)
call SetRandomSeed(GetRandomInt(0, 1000000))
set count = count + 1
endloop
return (this)
endmethod
// This moves all shards in cluster
public method OffsetMove takes nothing returns nothing
local integer i = 0
local boolean b = true
loop
exitwhen (i >= this.count)
call this.sh[i].OffsetMoveEx()
set b = b and this.sh[i].done
set i = i + 1
endloop
set this.dur = this.dur - TIMER_MOVE_DELAY
set this.fin = b
endmethod
// Reloads (recreates the) cluster -> returns did he failed to load new cluster
public method Reload takes nothing returns boolean
local triggerx tx
local cluster cl
if (this.dur >= GetAverageValue.evaluate(SHARD_MIN_TIMEOUT, SHARD_MAX_TIMEOUT)) then
set tx = triggerx.TriggeringTriggerx(GetTriggeringTrigger())
set cl = cluster.create(GetRandomInt(SHARD_MIN_COUNT, SHARD_MAX_COUNT), this.dur, this.cx, this.cy)
call tx.SetValue(integer(cl))
call this.destroy()
return false
endif
call this.destroy()
return true
endmethod
// Did all shards reach ground?
public method operator complete takes nothing returns boolean
return (this.fin)
endmethod
// ~Destructor
public method onDestroy takes nothing returns nothing
local integer i = 0
loop
exitwhen (i >= this.count)
call this.sh[i].destroy()
set this.sh[i] = 0
set i = i + 1
endloop
set this.count = 0
endmethod
endstruct
// ======================================================
// *** Frezzing Field Custom Defined Functions ***
// ======================================================
// Returns Frezzing Field spell level
private function GetSpellLevel takes unit whichUnit returns integer
local integer id = GetSpellAbilityId()
local integer lvl = GetUnitAbilityLevel(whichUnit, id)
debug call BJDebugMsg(I2S(lvl))
if (lvl > Levels) then
return (-1)
endif
if (id == FF_RAWCODE) then
return (lvl)
elseif (id == FFU_RAWCODE) then
return (lvl + 1)
endif
return (0)
endfunction
// Average value of min, max
private constant function GetAverageValue takes real min, real max returns real
return min + (max-min) / 2.
endfunction
// Calculates modulo integer of a mod b
private constant function Mod takes integer a, integer b returns integer
return a - (a/b) * b
endfunction
// Gets local object id
private function ArrayId takes handle h returns integer
local integer id = GetHandleId(h)
return (id - (id / 8191) * 8191)
endfunction
// Creates triggerx
private function CreateTriggerx takes code cond, code act, integer val returns triggerx
return triggerx.create(cond, act, val)
endfunction
// Destroys triggerx
private function DestroyTriggerx takes triggerx whichTrigger returns nothing
call triggerx.destroy(whichTrigger)
endfunction
// Returns triggering triggerx
private function GetTriggeringTriggerx takes nothing returns triggerx
return triggerx.TriggeringTriggerx(GetTriggeringTrigger())
endfunction
// Will register timer event
private function TriggerxRegisterTimerEvent takes triggerx tx, real timeout returns nothing
call tx.RegisterTimerEvent(timeout)
endfunction
// Triggers when unit stops casting a spell
private function TriggerxRegisterEndSpellCast takes triggerx tx, unit whichUnit returns nothing
call tx.RegisterEndSpellCast(whichUnit)
endfunction
// Executes any triggerx
private function TriggerxExecute takes triggerx tx returns nothing
call tx.Execute()
endfunction
// Will play custom sound file
private function PlayGlacierExplode takes integer volume, real x, real y returns nothing
local sound s = CreateSound(GLACIER_SOUND, false, true, true, 10, 10, "DefaultEAXON")
call SetSoundParamsFromLabel( s, "FrostNova" )
call SetSoundDuration( s, 2904 )
call SetSoundPitch( s, 0.5 )
call SetSoundVolume(s, volume)
call SetSoundPosition(s, x, y, 0.)
call StartSound(s)
call KillSoundWhenDone(s)
set s = null
endfunction
// ===========================================================================
// ------ ------
// *** Spell's Main Code ***
// ------ ------
// ===========================================================================
// ------- Frezzing Field Condition -------
private constant function Freezing_Field_Cond takes nothing returns boolean
return GetSpellAbilityId() == FF_RAWCODE or GetSpellAbilityId() == FFU_RAWCODE
endfunction
// *** This is our loop function (field explosion) ***
private function FieldExplode takes nothing returns nothing
local triggerx tx = GetTriggeringTriggerx()
local ffield f = ffield( tx.GetValue() )
// Is spell done?
if (f.done) then
debug call BJDebugMsg("|cffff0000spell done casting|r")
call DestroyTriggerx(tx)
call f.destroy()
return
endif
if (Mod(tx.exec-1, R2I(1./f.timeout)) == 0) then
call f.AddEffect(CEFF_MODEL)
endif
// Cause single blow
call f.Explode()
endfunction
// Moves all shards (timed)
private function EnumShards takes nothing returns nothing
local triggerx tx = GetTriggeringTriggerx()
local cluster cl = cluster( tx.GetValue() )
call cl.OffsetMove()
if (cl.complete) then
if (cl.Reload()) then
call DestroyTriggerx(tx)
endif
endif
endfunction
// This is executed when caster stops casting the spell
private function FreezingFieldStop takes nothing returns nothing
debug call BJDebugMsg("End freezing field spell cast")
set IsCasting[ArrayId(GetTriggerUnit())] = false
call DestroyTriggerx( GetTriggeringTriggerx() )
endfunction
// *** Frezzing Field Action ***
private function Freezing_Field_Act takes nothing returns nothing
// ** Locals **
local real x = GetUnitX(GetTriggerUnit())
local real y = GetUnitY(GetTriggerUnit())
local ffield f = ffield.create()
local triggerx tx
local cluster cl
// Vaildate our ffield
if (not f.valid) then
call BJDebugMsg("|cffff0000Unable to cast Frezzing Field: Level of spell greather then defined|r")
call f.destroy()
call DestroyTrigger( GetTriggeringTrigger() )
return
endif
// Load our cluster here
if (ALLOW_GEFFECTS) then
set cl = cluster.create( GetRandomInt(SHARD_MIN_COUNT, SHARD_MAX_COUNT), ExplosionDur[GetSpellLevel(GetTriggerUnit())], x, y )
endif
// Its valid, now create our trigger
set tx = CreateTriggerx(null, function FieldExplode, integer(f))
call TriggerxRegisterTimerEvent(tx, f.timeout)
// Now load end cast triggerx
set tx = CreateTriggerx(function Freezing_Field_Cond, function FreezingFieldStop, 0)
call TriggerxRegisterEndSpellCast(tx, GetTriggerUnit())
if (ALLOW_GEFFECTS) then
// Now load shard loop trigger
set tx = CreateTriggerx(null, function EnumShards, integer(cl))
call TriggerxRegisterTimerEvent(tx, TIMER_MOVE_DELAY)
endif
// Sound file play
call PlayGlacierExplode(127, x, y)
endfunction
// ===================================================================================================
private constant function DummyBool takes nothing returns boolean
return (true)
endfunction
private function PreloadSounds takes nothing returns nothing
call TriggerSleepAction(3.)
call PlayGlacierExplode(1, 0., 0.)
call DestroyTriggerx(GetTriggeringTriggerx())
endfunction
private function Init_FreezingField takes nothing returns nothing
// --- Load locals ---
local trigger t = CreateTrigger()
local integer i = 0
// *** Dummy Filter ***
set this_filter = Filter(function DummyBool)
// --- Setup spell user style ---
call Setup_FreezingField()
// Load trigger event, condition and action
loop
exitwhen (i >= bj_MAX_PLAYERS)
call TriggerRegisterPlayerUnitEvent( t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, this_filter )
set i = i + 1
endloop
call TriggerAddCondition( t, Condition( function Freezing_Field_Cond ) )
call TriggerAddAction( t, function Freezing_Field_Act )
// --- Preloader ---
call Preload(GEFF_MODEL)
call Preload(CEFF_MODEL)
call Preload("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl")
call Preload("Abilities\\Spells\\Other\\FrostDamage\\FrostDamage.mdl")
call TriggerxExecute(CreateTriggerx(null, function PreloadSounds, 0))
set t = null
endfunction
endlibrary
//==========================================================================
// Dark Dragon Library Code v1.3
//
// * Made on Warcraft III v1.30.4
//
// Installation:
//
// 1) Export instantdummy.mdx from this map and import it to your map, leave path at "war3mapImported/instantdummy.mdx"
// 2) Copy this trigger to your map, save your map and then change below line "// external ... " or copy "DD Dummy" and paste it in your map
// 3) Copy and paste "Unit Chill" ability from this map to your map
// 4) Match the rawcodes below to your map or use same ones as below
//
// Credits:
// ('Vexorian' - dummy.mdx)
//============================================================================
// *** Change "// external" to "//! external", save your map, close map, change back from "//!" to "//" and save map again.
// *** This will create dummy in your map
//
// ==================================
// external ObjectMerger w3u ushd dumy uabi "Aloc,Amrf" uble 0 ucbs 0 ucpt 0 umxp 0 umxr 0 umdl "war3mapImported\instantdummy.mdx" ushu "None" umvh 0 umvs 1 umas 1 umis 1 ucol 0 ufoo 0 uhom 1 umpi 10000 umpm 10000 usid 1 usin 1 unam "DD Dummy"
// ==================================
//! zinc
library DDLib requires optional TimerUtils, optional GroupUtils
{
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// *** Lib constants ***
public {
// ----------------------------------------------------------------------
// * Start modify/match rawcodes to your map
constant integer DD_DUMMYCODE = 'dumy';
constant integer DD_ABILITY_CROWN_FORM = 'Amrf';
constant integer DD_CHILL = 'Achl';
constant integer DD_CHILL_BUFF = 'Bfro';
// * End modify
// ----------------------------------------------------------------------
constant integer p_null = (0x0);
constant real DD_INTERVAL = .017;
// map min and max coords
real DDMinX = 0.;
real DDMinY = 0.;
real DDMaxX = 0.;
real DDMaxY = 0.;
}
private {
constant integer HARVEST_ID = 'Ahrl';
constant real TRIGGER_REFRESH_RATE = (60.)*3.; /// damage detection trigger
unit TreeChecker = null;
trigger TempTrig = null;
integer NTrig = 0;
trigger DmgTrig[];
p_real EnumVec = p_null;
boolexpr EnumFilter = null;
sound ErrorSound = null;
timer GameElapsedTimer = null;
constant integer RND_INT_MAX_ARRAY_N = 100;
integer RndInt[], RndIntWriteN = 00, RndIntReadN = 00;
trigger TrigMouseEvent = null;
force RndGenForce = null;
real RndElapsedTime = 0.;
}
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// * types
public {
// *** pointer to list of data ***
type p_integer extends integer[8];
type p_real extends real[8];
type p_unit extends unit[8];
function H2ID(handle h) -> integer {
return GetHandleId(h) - 0x100000;
}
function New_pInteger(integer i) -> p_integer
{ p_integer p = p_integer.create(); p[0] = i; return p; }
function New_pReal(real r) -> p_real
{ p_real p = p_real.create(); p[0] = r; return p; }
function New_pUnit(unit u) -> p_unit
{ p_unit p = p_unit.create(); p[0] = u; return p; }
function pVector(real x, real y, real z) -> p_real {
p_real v = p_real.create();
v[0] = x; v[1] = y; v[2] = z;
return v;
}
// --------------------------------------------------------------------------------------
function DDMsg(string str) {
DisplayTimedTextFromPlayer(GetLocalPlayer(), 0., 0., 30., str);
}
// --------------------------------------------------------------------------------------
function DisplayErrorMsgPlayer(player p, real dur, string msg) {
if (GetLocalPlayer() == p) {
StartSound(ErrorSound);
DisplayTimedTextFromPlayer(p, 0., 0., dur, "|cffffcc00"+ msg +"|r");
}
}
}
// -----------------------------------------------------------------------
// -> ***** private globals *****
// -----------------------------------------------------------------------
private {
location TempLoc = Location(0., 0.);
timer TimerStack[];
integer TimN = 0;
group GroupStack[];
integer GrpN = 0;
unit DummyStack[];
integer DumN = 0;
integer TimTicks[];
integer TimData[];
timer TimTim1[];
timer TimTim2[];
integer UnitStackData = 0;
unit UnitStack[];
integer US_N = 0;
public hashtable DDHT = InitHashtable();
}
// -----------------------------------------------------------------------
public {
// *** Global funcs
function Pw_2(real x) -> real {
return x*x;
}
function DDHypot(real x, real y) -> real {
return (x*x) + (y*y);
}
function DDTerrZ(real x, real y) -> real {
MoveLocation(TempLoc, x, y);
return GetLocationZ(TempLoc);
}
function DDWidgetTerrZ(widget w) -> real {
MoveLocation(TempLoc, GetWidgetX(w), GetWidgetY(w));
return GetLocationZ(TempLoc);
}
function DDEffectTerrZ(effect e) -> real {
MoveLocation(TempLoc, BlzGetLocalSpecialEffectX(e), BlzGetLocalSpecialEffectY(e));
return GetLocationZ(TempLoc);
}
function DDGetUnitZ(unit u) -> real {
return BlzGetUnitZ(u) + GetUnitFlyHeight(u);
}
// =================================================================
// *** Save Handle data ****
// =================================================================
function DDSet(handle h, integer id, integer val) {
SaveInteger(DDHT, id+1, GetHandleId(h), val);
}
function DDGet(handle h, integer id) -> integer {
return LoadInteger(DDHT, id+1, GetHandleId(h));
}
function DDHas(handle h, integer id) -> boolean {
return HaveSavedInteger(DDHT, id+1, GetHandleId(h));
}
function DDFlush(integer id) {
FlushChildHashtable(DDHT, id+1);
}
// =================================================================
// *** Timer Handling ****
// =================================================================
// -> check if timer is recycled
function DDIsTimRecycled(timer t) -> boolean {
integer i;
for(i=TimN-01; i >= 00; i-=01)
if (TimerStack[i] == t)
return true;
return false;
}
// -> Load timer for recycling
function DDLoadTim() -> timer {
static if (LIBRARY_TimerUtils) { return NewTimer(); }
else {
if (TimN > 0) {
TimN -= 1;
return TimerStack[TimN];
}
return CreateTimer();
}
}
// -> recycle loaded timer
function DDRecycleTim(timer t) {
static if (LIBRARY_TimerUtils) { ReleaseTimer(t); }
else {
static if (DEBUG_MODE)
if (DDIsTimRecycled(t)) {
DDMsg("Multiple recycle of timer!");
return;
}
TimerStack[TimN] = t;
TimN += 1;
}
}
// ** Get data stored on expired timer
function DDTimData() -> integer {
return TimData[H2ID(GetExpiredTimer())];
}
// *** Custom timer tick
function DDCTimTick(timer t) -> integer {
return TimTicks[H2ID(t)];
}
// *** Gets current tick and adds next one ***
function DDTimTick() -> integer {
integer id = H2ID(GetExpiredTimer());
TimTicks[id] += 01;
return TimTicks[id];
}
// ** start timer with data storage
function DDStartTim(real secs, boolean looping, integer pdata, code func) -> timer {
timer t = DDLoadTim();
TimData[H2ID(t)] = pdata;
TimerStart(t, secs, looping, func);
return t;
}
// ** start timer with data storage, and launches it instantly
function DDStartTimInst(real secs, boolean looping, integer pdata, code func) -> timer {
timer t1 = DDLoadTim(), t2 = DDLoadTim(), t3 = DDLoadTim();
TimData[H2ID(t2)] = pdata;
TimerStart(t2, 0., false, func);
TimTim1[H2ID(t3)] = t1;
TimTim2[H2ID(t3)] = t2;
TimerStart(t3, .005, false, function() {
timer t = GetExpiredTimer();
integer id = H2ID(t);
PauseTimer(t);
static if (LIBRARY_TimerUtils)
ReleaseTimer(t);
else {
TimerStack[TimN] = t;
TimN += 1;
}
t = TimTim2[id];
if (DDIsTimRecycled(t))
t = TimTim1[id];
TimTicks[H2ID(t)] = 00;
PauseTimer(t);
static if (LIBRARY_TimerUtils)
ReleaseTimer(t);
else {
TimerStack[TimN] = t;
TimN += 1;
}
});
TimData[H2ID(t1)] = pdata;
TimerStart(t1, secs, looping, func);
return t1;
}
// *** Quit expired timer ***
function DDQuitTim() {
timer t = GetExpiredTimer();
TimTicks[H2ID(t)] = 00;
PauseTimer(t);
static if (LIBRARY_TimerUtils)
ReleaseTimer(t);
else {
TimerStack[TimN] = t;
TimN += 1;
}
}
function DDQuitTimEx(timer t) {
TimTicks[H2ID(t)] = 00;
PauseTimer(t);
static if (LIBRARY_TimerUtils)
ReleaseTimer(t);
else {
TimerStack[TimN] = t;
TimN += 1;
}
}
// =================================================================
// *** Group Handling ****
// =================================================================
// -> Load timer for recycling
function DDLoadGroup() -> group {
static if (LIBRARY_GroupUtils) { return NewGroup(); }
else {
if (GrpN > 0) {
GrpN -= 1;
return GroupStack[GrpN];
}
return CreateGroup();
}
}
// -> Recycle group
function DDRecycleGroup(group g) {
static if (LIBRARY_GroupUtils) { ReleaseGroup(g); }
else {
GroupClear(g);
GroupStack[GrpN] = g;
GrpN += 1;
}
}
// --------------------------------------------------------
// -- Quick filter area
private integer GroupFilterData = 00;
function DDGroupFilterArea(real x, real y, real radius, integer data, code func) {
group g = DDLoadGroup();
GroupFilterData = data;
GroupEnumUnitsInRange(g, x, y, radius, Filter(func));
DDRecycleGroup(g);
}
// --------------------------------------------------------
// -- Quick filter rect
function DDGroupFilterRect(rect r, integer data, code func) {
group g = DDLoadGroup();
GroupFilterData = data;
GroupEnumUnitsInRect(g, r, Filter(func));
DDRecycleGroup(g);
}
function DDGFilterData() -> integer {
return GroupFilterData;
}
function DDGFilterDataSet(integer data) {
GroupFilterData = data;
}
// --------------------------------------------------------
// *** Filtrates and fills units in to memory
function DDGroupFillMemArea(real x, real y, real radius, integer data, code filter) {
group g = DDLoadGroup();
boolexpr exp = And(Filter(filter), Filter(function() -> boolean {
UnitStack[US_N] = GetFilterUnit();
US_N += 1;
return false;
}));
US_N = 0;
UnitStack[0] = null;
UnitStackData = data;
GroupEnumUnitsInRange(g, x, y, radius, exp);
DDRecycleGroup(g);
DestroyBoolExpr(exp);
exp = null;
}
function DDGroupFillMemRect(rect r, integer data, code filter) {
group g = DDLoadGroup();
boolexpr exp = And(Filter(filter), Filter(function() -> boolean {
UnitStack[US_N] = GetFilterUnit();
US_N += 1;
return false;
}));
US_N = 0;
UnitStack[0] = null;
UnitStackData = data;
GroupEnumUnitsInRect(g, r, exp);
DDRecycleGroup(g);
DestroyBoolExpr(exp);
exp = null;
}
function DDMemUnitN() -> integer { return US_N; }
function DDMemUnitData() -> integer { return UnitStackData; }
function DDMemUnit(integer index) -> unit {
if (US_N == 0) return null;
debug {
if (index < 0) {
BJDebugMsg("DDMemUnit: index less than 0");
index = 0;
} else if (index >= US_N) {
BJDebugMsg("DDMemUnit: index greater than units alloc size");
index = 0;
}
}
return UnitStack[index];
}
// --------------------------------------------------------
// --------------------------------------------------------
// ***
// =================================================================
// *** Dummy Handling ****
// =================================================================
// -> Load dummy for recycling
function DDLoadDummy() -> unit {
if (DumN > 0) {
DumN -= 1;
PauseUnit(DummyStack[DumN], false);
return DummyStack[DumN];
}
return CreateUnit(Player(0xF), DD_DUMMYCODE, DDMaxX, DDMaxY, 0.);
}
// *** prepares/setups dummy for spell casting
function DDLoadSpellDummy(player owner, real x, real y, integer abil, integer abilLevel) -> unit {
unit dummy = DDLoadDummy();
SetUnitOwner(dummy, owner, false);
SetUnitX(dummy, x);
SetUnitY(dummy, y);
if (abil != p_null) {
UnitAddAbility(dummy, abil);
SetUnitAbilityLevel(dummy, abil, abilLevel);
}
return dummy;
}
// -> Recycle dummy
function DDRecycleDummy(unit u) {
PauseUnit(u, true);
DummyStack[DumN] = u;
DumN += 1;
}
// -> Recycle dummy timed
function DDRecycleDummyTimed(unit u, real secs) {
DDStartTim(secs, false, New_pUnit(u), function() {
DDRecycleDummy(p_unit(DDTimData())[0]);
p_unit(DDTimData()).destroy();
DDQuitTim();
});
}
// *** shares vision for timed amount, usually for dummy casting
function DDUnitShareVisionTimed(unit u, player toP, real secs) {
p_integer pi = p_integer.create();
pi[0] = New_pUnit(u);
pi[1] = GetPlayerId(toP);
UnitShareVision(u, toP, true);
DDStartTim(secs, false, pi, function() {
p_integer pi = DDTimData();
UnitShareVision(p_unit(pi[0])[0], Player(pi[1]), false);
p_unit(pi[0])[0] = null;
p_unit(pi[0]).destroy();
pi.destroy();
DDQuitTim();
});
}
// *** Remove ability timed ***
private struct uratimed {
private {
unit u;
integer abil;
}
static method create(unit whichUnit, integer id, real time) -> uratimed {
thistype this = allocate();
u = whichUnit;
abil = id;
DDStartTim(time, false, this, function() {
thistype this = DDTimData();
UnitRemoveAbility(u, abil);
DDQuitTim();
deallocate();
});
return 0;
}
}
function DDRemoveAbilityTimed(unit u, integer abil, real secs) { uratimed.create(u, abil, secs); }
function DDSpellDamage(unit u, unit v, real dmg) {
real life = GetWidgetLife(v);
real dmgfactor = 1.;
if (IsUnitType(v, UNIT_TYPE_HERO)) {
if (UnitHasItemOfTypeBJ(v, 'brac'))
dmgfactor = .5;
else
dmgfactor = .75;
}
if (life > dmg*dmgfactor) {
SetWidgetLife(v, life-(dmg*dmgfactor));
} else
UnitDamageTarget(u, v, 99999., false, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS);
}
// -------------------------------------------------------------------------------------
// *** Chills target unit
private struct chill {
unit u, dmy;
real dur;
static chill Data[];
//static key CHILL_KEY;
}
function DDUnitChill(player p, unit u, real dur) -> boolean {
//chill c = DDGet(u, chill.CHILL_KEY);
chill c = chill.Data[H2ID(u)];
unit d;
real rad;
if (c == p_null) {
c = chill.create();
c.u = u; c.dur = dur;
chill.Data[H2ID(u)] = c;
//DDSet(u, chill.CHILL_KEY, c);
d = DDLoadDummy();
c.dmy = d;
rad = GetUnitFacing(d) * bj_DEGTORAD;
SetUnitOwner(d, p, false);
UnitAddAbility(d, DD_CHILL);
SetUnitX(d, GetUnitX(u) - 20.*Cos(rad));
SetUnitY(d, GetUnitY(u) - 20.*Sin(rad));
if (IssueTargetOrder(d, "frostnova", u)) {
DDStartTim(.1, true, c, function() {
chill c = DDTimData();
c.dur -= .1;
if (c.dur <= 0. || GetUnitAbilityLevel(c.u, DD_CHILL_BUFF) == 00) {
UnitRemoveAbility(c.u, DD_CHILL_BUFF);
UnitRemoveAbility(c.dmy, DD_CHILL);
DDRecycleDummy(c.dmy);
chill.Data[H2ID(c.u)] = p_null;
//DDSet(c.u, chill.CHILL_KEY, p_null);
c.u = null;
c.destroy();
DDQuitTim();
}
});
return true;
}
return false;
}
c.dur = dur;
return true;
}
// ------------------------------------------------------------------------------------------------
struct fade {
unit u;
real trans;
real rate, e_trans, dur;
static constant real INTERVAL = .1;
static method create(unit u, real dur, real s_trans, real e_trans) -> fade {
fade this = allocate();
this.u = u;
this.trans = s_trans;
this.rate = ((e_trans-s_trans)/dur)*fade.INTERVAL;
this.e_trans = e_trans;
this.dur = dur;
return this;
}
}
// *** Fades unit over time ***
public function DDFadeUnit(unit u, integer from_alpha, integer to_alpha, real duration) {
fade f = fade.create(u,
duration,
from_alpha/2.55,
to_alpha/2.55);
SetUnitVertexColor(u, 255, 255, 255, from_alpha);
// --- Start thread ---
DDStartTim(fade.INTERVAL, true, f, function() {
fade f = DDTimData();
f.trans += f.rate;
f.dur -= fade.INTERVAL;
SetUnitVertexColor(f.u, 255, 255, 255, R2I(f.trans*2.55));
if (f.dur < 0.) {
SetUnitVertexColor(f.u, 255, 255, 255, R2I(f.e_trans*2.55));
f.u = null;
f.destroy();
DDQuitTim();
}
});
}
// ------------------------------------------------------------------------------------------------
// Check if unit is invulnerable
function DDIsUnitInvulnerable(unit u) -> boolean {
unit d = DDLoadDummy();
real hp = GetWidgetLife(u);
boolean flag;
UnitDamageTarget(d, u, 1., true, false, null, null, null);
flag = GetWidgetLife(u) == hp;
SetWidgetLife(u, hp);
DDRecycleDummy(d);
return flag;
}
// *** check if unit is ward
function DDIsUnitWard(unit whichUnit) -> boolean {
return GetUnitDefaultMoveSpeed(whichUnit) == 0.;
}
// =================================================================
// *** Effect Handling ****
// =================================================================
// -----------------------------------------------
// *** Define movable effect
struct ddeffect {
private {
effect e;
real fac; // facing angle in radians
real effZ; // pitch in radians
real decay;
real stepTrans, cTrans, eTrans;
static constant real EFFECT_DECAY = 5.;
}
// =========================================================================================
// =========================================================================================
static method create(string mdl, real x, real y, real facRad, real size) -> ddeffect {
ddeffect this = allocate();
this.e = AddSpecialEffect(mdl, x, y);
this.fac = facRad;
this.effZ = 0.;
BlzSetSpecialEffectRoll(this.e, facRad);
BlzSetSpecialEffectScale(this.e, size);
return this;
}
static method createZ(string mdl, real x, real y, real z, real facRad, real size) -> ddeffect {
ddeffect this = allocate();
this.e = AddSpecialEffect(mdl, x, y);
this.fac = facRad;
this.effZ = z-DDTerrZ(x, y);
BlzSetSpecialEffectRoll(this.e, facRad);
BlzSetSpecialEffectScale(this.e, size);
BlzSetSpecialEffectZ(this.e, z);
return this;
}
// -----------------
method destroy() {
DestroyEffect(this.e);
this.e = null;
deallocate();
}
// *** destroys effect timed
method destroyx(real decayTime) {
DDStartTim(decayTime, false, this, function() {
ddeffect se = DDTimData();
BlzSetSpecialEffectPosition(se.e, DDMaxX, DDMaxY, 0.);
DestroyEffect(se.e);
se.e = null;
se.deallocate();
DDQuitTim();
});
}
// =========================================================================================
// =========================================================================================
method operator Z=(real z) { BlzSetSpecialEffectZ(this.e, z); }
method operator X() -> real { return BlzGetLocalSpecialEffectX(this.e); }
method operator Y() -> real { return BlzGetLocalSpecialEffectY(this.e); }
method operator Z() -> real { return BlzGetLocalSpecialEffectZ(this.e); }
method operator WZ() -> real { return DDEffectTerrZ(this.e); }
method operator Height() -> real { return this.Z-this.WZ; }
method operator Facing=(real facRad) { BlzSetSpecialEffectRoll(this.e, facRad); this.fac = facRad; }
method operator Facing() -> real { return this.fac; }
method Position(real x, real y) { BlzSetSpecialEffectPosition(this.e, x, y, this.effZ+this.WZ); }
method PositionZ(real x, real y, real z) { BlzSetSpecialEffectPosition(this.e, x, y, z); }
method Animation(animtype at) { BlzPlaySpecialEffect(this.e, at); }
method AnimationSpeed(real animSpeed) { BlzSetSpecialEffectTimeScale(this.e, animSpeed/100.); }
//method operator Pitch=(integer pitch) { SetUnitAnimationByIndex(u, pitch); }
//method Face(widget w) { Facing = Atan2(GetWidgetY(w)-Y, GetWidgetX(w)-X)*bj_RADTODEG; }
method Fade(real startTransparency, real endTransparency, real duration) {
this.cTrans = startTransparency;
this.eTrans = endTransparency;
this.stepTrans = .1*(endTransparency-startTransparency) / duration;
BlzSetSpecialEffectAlpha(this.e, R2I(startTransparency*2.55));
DDStartTim(.1, true, this, function() {
ddeffect dde = DDTimData();
dde.cTrans += dde.stepTrans;
if (dde.stepTrans > 0.)
if (dde.cTrans >= dde.eTrans) {
BlzSetSpecialEffectAlpha(dde.e, R2I(dde.eTrans*2.55));
DDQuitTim();
return;
}
else
if (dde.cTrans <= dde.eTrans) {
BlzSetSpecialEffectAlpha(dde.e, R2I(dde.eTrans*2.55));
DDQuitTim();
return;
}
BlzSetSpecialEffectAlpha(dde.e, R2I(dde.cTrans*2.55));
});
}
}
private type timedeffect extends effect[01];
function DDDestroyEffectTimed(effect e, real secs) {
timedeffect te = timedeffect.create();
te[00] = e;
DDStartTim(secs, true, te, function() {
timedeffect te = DDTimData();
DestroyEffect(te[00]);
te.destroy();
DDQuitTim();
});
}
}
// ----------------------------------------------------------------------------
// *** Main damage detection function, registers any damage dealt to units ***
public function DDTriggerRegisterAnyUnitDamaged(trigger t) {
DmgTrig[NTrig] = t;
NTrig += 1;
}
function InitDamageDetection() {
code c = function() {
if (TempTrig != null)
DestroyTrigger(TempTrig);
TempTrig = CreateTrigger();
TriggerRegisterEnterRectSimple(TempTrig, bj_mapInitialPlayableArea);
TriggerAddCondition(TempTrig, function() -> boolean {
integer i;
// *** Check if we need to exec triggers or register an unit ***
if (GetTriggerEventId() == EVENT_UNIT_DAMAGED) {
for(i=0; i < NTrig; i+=1)
if (IsTriggerEnabled(DmgTrig[i]))
if (TriggerEvaluate(DmgTrig[i]))
TriggerExecute(DmgTrig[i]);
}
else
// *** Register new unit ***
TriggerRegisterUnitEvent(GetTriggeringTrigger(),
GetTriggerUnit(),
EVENT_UNIT_DAMAGED);
return false;
});
DDGroupFilterRect(bj_mapInitialPlayableArea, 00, function() -> boolean {
TriggerRegisterUnitEvent(TempTrig, GetFilterUnit(), EVENT_UNIT_DAMAGED);
return false;
});
};
trigger t = CreateTrigger();
TriggerAddAction(t, c);
TriggerExecute(t);
DestroyTrigger(t);
TimerStart(CreateTimer(), TRIGGER_REFRESH_RATE, true, c);
t = null;
}
// ---------------------------------------------------------------------------------
// *** Main enum dests in range function ***
public function DDEnumDestsInRange(p_real vec, real radius, boolexpr filter, code pfunc) {
rect r = Rect(vec[0]-radius, vec[1]-radius, vec[0]+radius, vec[1]+radius);
EnumVec[0] = vec[0];
EnumVec[1] = vec[1];
EnumVec[2] = radius;
if (filter != null) filter = And(EnumFilter, filter);
else filter = EnumFilter;
EnumDestructablesInRect(r, filter, pfunc);
if (filter != EnumFilter) { DestroyBoolExpr(filter); filter = null; }
RemoveRect(r);
r = null;
}
function InitEnumDests() {
EnumVec = p_real.create();
EnumFilter = Filter(function() -> boolean {
return Pw_2(EnumVec[0]-GetDestructableX(GetFilterDestructable())) + Pw_2(EnumVec[1]-GetDestructableY(GetFilterDestructable())) < Pw_2(EnumVec[2]);
});
}
// --------------------------------------------------------------------------------------
// *** checks is destruct tree ***
public function DDIsDestructableTree(destructable d) -> boolean {
if (d != null) {
PauseUnit(TreeChecker, false);
if (IssueTargetOrder(TreeChecker, "harvest", d)) {
PauseUnit(TreeChecker, true);
return true;
}
PauseUnit(TreeChecker, true);
}
return false;
}
function InitDestTreeCheck() {
TreeChecker = CreateUnit(Player(bj_PLAYER_NEUTRAL_EXTRA), DD_DUMMYCODE, DDMaxX, DDMaxY, 0.);
UnitAddAbility(TreeChecker, HARVEST_ID);
PauseUnit(TreeChecker, true);
}
// --------------------------------------------------------------------------------------
public function DDNewTextTagUnit(unit whichUnit, string text, real dur, real red, real green, real blue, real transparency) {
CreateTextTagUnitBJ( text, whichUnit, 0., 11.00, red, green, blue, transparency );
SetTextTagPermanentBJ( bj_lastCreatedTextTag, false );
SetTextTagVelocityBJ( bj_lastCreatedTextTag, 48.00, 90 );
SetTextTagFadepointBJ( bj_lastCreatedTextTag, dur-1.25 );
SetTextTagLifespanBJ( bj_lastCreatedTextTag, dur );
}
// --------------------------------------------------------------------------------------
struct cameranoisedata {
player p[12];
integer n=00;
}
public function DDCameraSetSourceNoiseForPlayers(real x, real y, real mag, real vel, real maxDist, real duration) {
integer i;
real d;
cameranoisedata cnd = cameranoisedata.create();
for (i=00; i < bj_MAX_PLAYERS; i+=01) {
if (GetLocalPlayer() == Player(i)) {
d = SquareRoot( Pw_2(GetCameraTargetPositionX()-x) + Pw_2(GetCameraTargetPositionY()-y) );
if (d < maxDist) {
cnd.p[cnd.n] = Player(i);
CameraSetSourceNoise(mag-(d*(mag/maxDist)), vel-(d*(vel/maxDist)));
CameraSetTargetNoise(mag-(d*(mag/maxDist)), vel-(d*(vel/maxDist)));
cnd.n += 01;
}
}
}
DDStartTim(duration, false, cnd, function() {
cameranoisedata cnd = DDTimData();
while(cnd.n != 00) {
cnd.n -= 01;
if (GetLocalPlayer() == cnd.p[cnd.n])
CameraSetSourceNoise(0., 0.);
CameraSetTargetNoise(0., 0.);
}
cnd.destroy();
DDQuitTim();
});
}
// --------------------------------------------------------------------------------------
hashtable GenSndTable = null;
public function DDGenericSound(string file, real vol, real x, real y, real mxDist, real pitch) {
integer sh = StringHash(file),
snd_n = LoadInteger(GenSndTable, sh, 04);
sound s = LoadSoundHandle(GenSndTable, sh, snd_n);
real d;
integer i;
if (s == null) {
s = CreateSound(file, false, false, false, 10, 10, "");
SaveSoundHandle(GenSndTable, sh, snd_n, s);
} else if (GetSoundIsPlaying(s)) {
StopSound(s, false, false);
}
SetSoundPitch(s, pitch);
snd_n += 01;
if (snd_n == 04)
snd_n = 00;
SaveInteger(GenSndTable, sh, 04, snd_n);
// Play sound and shake camera for players within spell cast range
for (i=00; i < bj_MAX_PLAYERS; i+=01) {
if (GetLocalPlayer() == Player(i)) {
d = SquareRoot( DDHypot(GetCameraTargetPositionX()-x, GetCameraTargetPositionY()-y) );
if (d < mxDist) {
SetSoundVolume(s, R2I((vol-d*(vol/mxDist))*1.27));
StartSound(s);
}
}
}
}
public function DDGetGameElapsedTime() -> real {
return TimerGetElapsed(GameElapsedTimer);
}
public function DDGetRndReal(real min, real max) -> real {
real rnd = ((max-min)/1000000.)*I2R(RndInt[RndIntReadN]);
debug if (max > 1000000.)
DDMsg("ERROR: \"DDGetRndNumber\" - 'max' variable is greater than 1000000!");
RndIntReadN += 01; if (RndIntReadN == RND_INT_MAX_ARRAY_N) RndIntReadN = 00;
return min + rnd;
}
public function DDGetRndInt(integer min, integer max) -> integer {
return R2I( DDGetRndReal(I2R(min), I2R(max)) );
}
// ====================================================================
function onInit() {
InitDamageDetection();
InitDestTreeCheck();
InitEnumDests();
DDMinX = GetRectMinX(bj_mapInitialPlayableArea);
DDMinY = GetRectMinY(bj_mapInitialPlayableArea);
DDMaxX = GetRectMaxX(bj_mapInitialPlayableArea);
DDMaxY = GetRectMaxY(bj_mapInitialPlayableArea);
GenSndTable = InitHashtable();
ErrorSound = CreateSound( "Sound\\Interface\\Error.wav", false, false, false, 10, 10, "" );
SetSoundParamsFromLabel( ErrorSound, "InterfaceError" );
SetSoundDuration( ErrorSound, 614 );
SetSoundVolume(ErrorSound, 127);
GameElapsedTimer = CreateTimer();
TimerStart(GameElapsedTimer, 10800., false, null);
for(RndIntWriteN=00; RndIntWriteN < RND_INT_MAX_ARRAY_N; RndIntWriteN+=01)
RndInt[RndIntWriteN] = GetRandomInt(00, 1000000);
RndIntWriteN = 00;
RndGenForce = CreateForce();
TrigMouseEvent = CreateTrigger();
ForForce(bj_FORCE_ALL_PLAYERS, function() {
if (GetPlayerController(GetEnumPlayer()) == MAP_CONTROL_USER)
TriggerRegisterPlayerEvent(TrigMouseEvent, GetEnumPlayer(), EVENT_PLAYER_MOUSE_MOVE);
});
TriggerAddCondition(TrigMouseEvent, Condition(function() -> boolean {
real mouseN;
boolean xFirst = GetRandomInt(00, 01) == 01;
if (!IsPlayerInForce(GetTriggerPlayer(), RndGenForce)) {
// example: input x = 578.4571496
// output rnd n = 4571498
if (xFirst)
mouseN = RAbsBJ(BlzGetTriggerPlayerMouseX()) * 100.;
else
mouseN = RAbsBJ(BlzGetTriggerPlayerMouseY()) * 100.;
if (mouseN == 0.)
return false;
//mouseN *= 100.;
RndInt[RndIntWriteN] = R2I((mouseN - I2R(R2I(mouseN))) * 1000.);
//DDMsg(I2S(RndInt[RndIntWriteN]));
//RndIntWriteN += 01; if (RndIntWriteN == RND_INT_MAX_ARRAY_N) RndIntWriteN = 00;
if (xFirst)
mouseN = RAbsBJ(BlzGetTriggerPlayerMouseY()) * 100.;
else
mouseN = RAbsBJ(BlzGetTriggerPlayerMouseX()) * 100.;
RndInt[RndIntWriteN] += R2I((mouseN - I2R(R2I(mouseN))) * 1000.)*1000;
//DDMsg(I2S(RndInt[RndIntWriteN]));
RndIntWriteN += 01; if (RndIntWriteN == RND_INT_MAX_ARRAY_N) RndIntWriteN = 00;
ForceAddPlayer(RndGenForce, GetTriggerPlayer());
}
if (DDGetGameElapsedTime()-RndElapsedTime > .125) {
ForceClear(RndGenForce);
RndElapsedTime = DDGetGameElapsedTime();
}
return false;
}));
}
}
//! endzinc
//TESH.scrollpos=102
//TESH.alwaysfold=0
// *****************************************************************************
// * Spell: Freezing Field
// * -> By: Dark Dragon
// *
// *
// *
// * --- Installation ---
// *
// * - 1. Copy this trigger and DD Library if not already
// * - 2. Export and import Aghanims Scepter icon if you want
// * - 3. Copy and paste abilities Freezing Field Damage (Dummy), Freezing Field and its Updated (if you want) version to your map
// * - 4. Start editing below until it says "Custom spell code"
// * - 5. Enjoy!
// *****************************************************************************
// =====================================================================
// Freezing Field library
//
//! zinc
library FreezingField requires DDLib
{
// **********************************************************
// --- Editable Spell Globals
// **********************************************************
// This is the rawcode of the spell frezzing field
// Default: 'FFld'
constant integer FF_RAWCODE = 'FFld';
// This is the rawcode of the spell frezzing field upgraded
// Default: 'FFdu'
constant integer FFU_RAWCODE = 'FFdu';
// This is the dummy ability frost nova
// Default: 'FFDg'
constant integer DFN_RAWCODE = 'FFDg';
// This is the casters channel effect model
// Default: "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
constant string CEFF_MODEL = "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl";
// This is the path to sound file which will be played when spell is cast
// Default: "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget1.wav"
constant string GLACIER_SOUND_FILE_PATH = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget1.wav";
// Sound volume in percentage
// Default: 100%
constant real GLACIER_SOUND_VOLUME = 100.;
// Default 0.5
constant real GLACIER_SOUND_PITCH = 0.5;
// Default 3500.
constant real GLACIER_SOUND_MAX_DISTANCE = 3500.;
// This is offset from caster to cause nova damage, meaning to not create explosions on position of caster
// Default: 50.
constant real NOVA_OFFSET = 50.;
// Area of effect of nova, radius
// Default: 70.
constant real NOVA_AREA = 70.;
// Area of effect of the spell, radius, AoE can only be certain numbers that follow the formula:
// NOVA_OFFSET + NOVA_AREA * n, where n is integer number
// Default: 470. AoE / n is 6
constant real FREEZING_FIELD_AREA = NOVA_OFFSET + NOVA_AREA * 6.;
// Explosions per second
// Default: 12
constant integer EXPLOSIONS_PER_SECOND = 12;
// Use ice fall graphics, eye candy, but uses more system resources
// Default: true
constant boolean ICE_FALL_USE = true;
// Model file used for graphic display
// Default: "Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathMissile.mdl"
constant string ICE_FALL_MODEL = "Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathMissile.mdl";
// Size of ice fall block (model)
// Default: 0.66
constant real ICE_FALL_SCALE = 0.66;
// Ice fall offset from blast point
// Default: 340., 400.
constant real ICE_FALL_MIN_OFFSET = 340.;
constant real ICE_FALL_MAX_OFFSET = 400.;
// Ice fall initial height and gravity acceleration
// Default: 1200., 3600.
constant real ICE_FALL_HEIGHT = 1200.;
constant real ICE_FALL_ACCELERATION = 3600.;
// Ice fall angle in degrees
// Default: -20., 50.
constant real ICE_FALL_MIN_ANGLE = -20.;
constant real ICE_FALL_MAX_ANGLE = 50.;
// Use custom terrain type
// Default: true
constant boolean DO_PAINT_FIELD = true;
// Terrain type id
// Default: 'Iice'
constant integer FIELD_TYPE = 'Iice';
// Terrain offset duration after spell end cast
// Default: 3.
constant real PAINT_FIELD_OFFSET_DUR = 3.;
// =========================================================================
// ---- ----
// *** Custom spell code ***
// ---- ----
// =========================================================================
// Default: auto
boolean FreezingFieldChanneling[];
// ---------------------------------------------
// * Main data for storing terrain type, and altering it
// ---------------------------------------------
struct altfield {
private {
integer typ[64], var[64];
boolean blighted[64];
real X[64], Y[64];
integer n=0;
unit bc[64];
integer bca[64];
integer bcn;
static constant integer BLIGHT_ABIL_LARGE = 'Abgl';
static constant integer BLIGHT_ABIL_SMALL = 'Abgs';
static constant real BLIGHT_ABIL_RADIUS = 960.;
}
private method RemoveBlightAbilArea(real x, real y, boolean remove) {
if (remove) {
bcn = 0;
DDGroupFillMemArea(x, y, BLIGHT_ABIL_RADIUS+FREEZING_FIELD_AREA, this, function() -> boolean {
thistype this = DDMemUnitData();
if (GetUnitAbilityLevel(GetFilterUnit(), BLIGHT_ABIL_LARGE) > 0) {
bc[bcn] = GetFilterUnit();
bca[bcn] = BLIGHT_ABIL_LARGE;
UnitRemoveAbility(bc[bcn], BLIGHT_ABIL_LARGE);
bcn += 1;
} else if (GetUnitAbilityLevel(GetFilterUnit(), BLIGHT_ABIL_SMALL) > 0) {
bc[bcn] = GetFilterUnit();
bca[bcn] = BLIGHT_ABIL_SMALL;
UnitRemoveAbility(bc[bcn], BLIGHT_ABIL_SMALL);
bcn += 1;
}
return false;
});
}
else {
while(bcn > 0) {
bcn -= 1;
if (GetUnitAbilityLevel(bc[bcn], bca[bcn]) == 0)
UnitAddAbility(bc[bcn], bca[bcn]);
}
}
}
method FreezeField(real x, real y) {
real w = -FREEZING_FIELD_AREA, h, maxh;
//n = 0;
RemoveBlightAbilArea(x, y, true);
while(w <= FREEZING_FIELD_AREA) {
maxh = SquareRoot(Pw_2(FREEZING_FIELD_AREA) - Pw_2(w));
h = -maxh;
do {
if (GetTerrainType(x+w, y+h) != FIELD_TYPE) {
X[n] = x+w; Y[n] = y+h;
typ[n] = GetTerrainType(X[n], Y[n]);
var[n] = GetTerrainVariance(X[n], Y[n]);
blighted[n] = IsPointBlighted(X[n], Y[n]);
if (blighted[n])
SetBlightPoint(Player(0xF), X[n], Y[n], false);
SetTerrainType(X[n], Y[n], FIELD_TYPE, -1, 1, 0);
n += 1;
}
h += bj_CELLWIDTH;
} while(h <= maxh);
w += bj_CELLWIDTH;
}
}
method UnfreezeField() {
if (n > 0) {
while(n >= 0) {
n -= 1;
SetTerrainType(X[n], Y[n], typ[n], var[n], 1, 0);
if (blighted[n])
SetBlightPoint(Player(0), X[n], Y[n], true);
}
}
RemoveBlightAbilArea(0., 0., false);
}
}
// -----------------------------------------------------
// *** primary spell data ***
// -----------------------------------------------------
struct ffdata {
unit caster;
player owner;
integer rnd[EXPLOSIONS_PER_SECOND], rnd_n;
integer lvl;
altfield af;
private {
static real OX[], OY[];
static integer ON = 0;
static location BlastLoc = null;
}
static method create(unit c, integer l) -> ffdata {
ffdata this = allocate();
caster = c;
owner = GetOwningPlayer(c);
rnd_n = 0;
lvl = l;
static if (DO_PAINT_FIELD) {
af = altfield.create();
af.FreezeField(GetUnitX(caster), GetUnitY(caster));
}
return this;
}
method destroy() {
static if (DO_PAINT_FIELD) {
DDStartTim(PAINT_FIELD_OFFSET_DUR, false, af, function() {
altfield af = DDTimData();
af.UnfreezeField();
af.destroy();
DDQuitTim();
});
}
deallocate();
}
// *** This is called every second ***
method TryResetRndN(integer tick) {
if (ModuloInteger(tick, EXPLOSIONS_PER_SECOND) == EXPLOSIONS_PER_SECOND-01)
rnd_n = 0;
}
// *** returns random n, that is not used ***
// *** every second this is reseted to 0 ***
private method GetRndN() -> integer {
integer n, i;
boolean flag;
do {
n = DDGetRndInt(0, ON-1);
flag = false;
for(i=0; i < rnd_n; i+=1)
if (rnd[i] == n) {
flag = true;
break;
}
} while(flag);
rnd[rnd_n] = n;
rnd_n += 1;
return n;
}
// *** Gets us the blast location X, Y ***
method GetRndLoc() -> location {
integer n = GetRndN();
MoveLocation(BlastLoc, GetUnitX(caster) + OX[n], GetUnitY(caster) + OY[n]);
return BlastLoc;
}
// --------------------------------------------
// *** Init static globals ***
static method onInit() {
real SAFE_SHIFT = 5.;
real INIT_RADIUS = NOVA_AREA+NOVA_OFFSET;
integer MAX_I = R2I( ((FREEZING_FIELD_AREA-INIT_RADIUS-NOVA_AREA+SAFE_SHIFT) / (2.*NOVA_AREA)) ), MAX_J;
integer i, j;
real r;
BlastLoc = Location(0., 0.);
// *** Loop through radius ***
for(i=0; i <= MAX_I; i+=1) {
// Get current radius and fill circumference with nova circles
r = INIT_RADIUS + (i*2.*NOVA_AREA);
MAX_J = R2I(bj_PI / Atan(NOVA_AREA/r));
for(j=0; j < MAX_J; j+=1) {
// *** Loop through angle, and store points ***
OX[ON] = r * Cos(j*(2.*bj_PI/MAX_J));
OY[ON] = r * Sin(j*(2.*bj_PI/MAX_J));
ON += 1;
}
}
//BJDebugMsg(I2S(ON));
}
}
// -------------------------------------------------------
// *** Ice fall graphic struct
// -------------------------------------------------------
public struct icefall {
private {
ddeffect dde;
//real x, y, z;
real ox, oy, wz;
player p;
integer l;
}
// -----------------------------------
// *** Constructor
static method create(player owner, real x, real y, integer lvl) -> icefall {
icefall this = allocate();
real xy_shift = DDGetRndReal(ICE_FALL_MIN_OFFSET, ICE_FALL_MAX_OFFSET);
real alpha = GetRandomReal(ICE_FALL_MIN_ANGLE, ICE_FALL_MAX_ANGLE)*bj_DEGTORAD;
real t = SquareRoot(2.*ICE_FALL_HEIGHT/ICE_FALL_ACCELERATION);
real dx = Cos(alpha),
dy = Sin(alpha);
wz = DDTerrZ(x, y);
dde = ddeffect.createZ(ICE_FALL_MODEL, x + xy_shift * dx, y + xy_shift * dy, wz + ICE_FALL_HEIGHT, 1.5*bj_PI, ICE_FALL_SCALE);
ox = DD_INTERVAL*-dx*xy_shift/t;
oy = DD_INTERVAL*-dy*xy_shift/t;
p = owner;
l = lvl;
return this;
}
static method FrostNovaExplosion(player owner, real x, real y, integer lvl) {
unit dummy = DDLoadSpellDummy(owner, x, y, DFN_RAWCODE, lvl);
UnitRemoveAbility(dummy, 'Aloc');
IssueTargetOrder(dummy, "frostnova", dummy);
DDStartTim(1., false, New_pUnit(dummy), function() {
p_unit pd = DDTimData();
SetWidgetLife(pd[0], GetUnitState(pd[0], UNIT_STATE_MAX_LIFE));
UnitAddAbility(pd[0], 'Aloc');
UnitRemoveAbility(pd[0], DFN_RAWCODE);
DDRecycleDummy(pd[0]);
pd.destroy();
DDQuitTim();
});
}
// -----------------------------------
// *** Run motion, auto destroy
method InitMotion() {
DDStartTim(DD_INTERVAL, true, this, function() {
icefall this = DDTimData();
integer tick = DDTimTick();
// *** Motion of ice blocks ***
dde.PositionZ(dde.X + ox, dde.Y + oy, wz + ICE_FALL_HEIGHT - (.5*ICE_FALL_ACCELERATION*Pw_2(tick*DD_INTERVAL)));
/*xe.Y += oy;
xe.Z = ICE_FALL_HEIGHT - (.5*ICE_FALL_ACCELERATION*Pw_2(tick*DD_INTERVAL));*/
// *** Impact?
if (dde.Z < 10.) {
FrostNovaExplosion(p, dde.X, dde.Y, l);
dde.destroy();
destroy();
DDQuitTim();
}
});
}
}
// =========================================================================
//
// *** Init spell Freezing Field ***
//
// =========================================================================
function onInit() {
trigger t = CreateTrigger();
TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT);
TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_ENDCAST);
TriggerAddCondition(t, Condition(function() -> boolean {
ffdata d;
integer lvl;
unit u;
// ------------------------------------------------
// Primary condition
// ------------------------------------------------
if (GetSpellAbilityId() != FF_RAWCODE && GetSpellAbilityId() != FFU_RAWCODE)
return false;
u = GetTriggerUnit();
// ------------------------------------------------
// Check if spell is done
// ------------------------------------------------
if (GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_ENDCAST) {
// *** End spell ***
FreezingFieldChanneling[H2ID(u)] = false;
return false;
}
// ------------------------------------------------
// New instance initialize
// ------------------------------------------------
if (GetSpellAbilityId() == FF_RAWCODE)
lvl = GetUnitAbilityLevel(u, FF_RAWCODE);
else
lvl = GetUnitAbilityLevel(u, FFU_RAWCODE) + 01;
d = ffdata.create(u, lvl);
// *** Play sound ***
DDGenericSound(GLACIER_SOUND_FILE_PATH, GLACIER_SOUND_VOLUME, GetWidgetX(u), GetWidgetY(u), GLACIER_SOUND_MAX_DISTANCE, GLACIER_SOUND_PITCH);
// *** Is casting = true
FreezingFieldChanneling[H2ID(u)] = true;
DDStartTimInst(1./EXPLOSIONS_PER_SECOND, true, d, function() {
ffdata d = DDTimData();
integer tick = DDTimTick();
location l;
// *** Quit spell ***
if (!FreezingFieldChanneling[H2ID(d.caster)]) {
d.destroy();
DDQuitTim();
return;
}
// *** Load caster effect ***
if (ModuloInteger(tick, 02*EXPLOSIONS_PER_SECOND) == 01)
DestroyEffect( AddSpecialEffectTarget(CEFF_MODEL, d.caster, "origin") );
l = d.GetRndLoc();
// *** Create explosion ***
static if (ICE_FALL_USE)
// static location
icefall.create(d.owner, GetLocationX(l), GetLocationY(l), d.lvl).InitMotion();
else
icefall.FrostNovaExplosion(d.owner, GetLocationX(l), GetLocationY(l), d.lvl);
// *** Every second all possible locs are reseted
d.TryResetRndN(tick);
});
// ------------------------------------------------
//
// *** End trigger condition ***
//
u = null;
return false;
// ------------------------------------------------
}));
// ----------------------------
// *** Load sound ***
/*
GlacierExplode = CreateSound(GLACIER_SOUND, false, true, true, 10, 10, "DefaultEAXON");
SetSoundParamsFromLabel(GlacierExplode, "FrostNova");
SetSoundPitch(GlacierExplode, 0.5);
SetSoundVolume(GlacierExplode, 127);
*/
}
}
//! endzinc
// ============================================================================================
// Change me from /* to // and then back to /* after saving and reopening the map
// |
// ˇ
/*
// Credits: PurgeandFire for lua tutorial
//! externalblock extension=lua ObjectMerger $FILENAME$
//! i -- ===================================================
//! i FREEZING_FIELD_DAMAGE_ID = "FFDg"
//! i FREEZING_FIELD_ABIL_ID = "FFld"
//! i FREEZING_FIELD_IMPROVED_ABIL_ID = "FFdu" -- Set this value to "nil" if not using upgrader
//! i CHAIN_FROST_ABIL_ID = "CFro"
//! i CHAIN_FROST_IMPROVED_ABIL_ID = "CFru" -- Set this value to "nil" if not using upgrader or if not using chain frost spell
//! i AGHANIM_SCEPTER_ABIL_ID = "Aghs"
//! i -- ===================================================
//! i setobjecttype("abilities")
//! i createobject("AUfn", FREEZING_FIELD_DAMAGE_ID)
//! i makechange(current,"anam", "Freezing Field Damage")
//! i makechange(current,"alev", "4")
//! i makechange(current,"aher", false)
//! i makechange(current,"arac", "nightelf")
//! i local i = 0
//! i for i=1, 4 do
//! i local si = tostring(i)
//! i makechange(current,"atar",si,"Enemy,Ground,Organic,Self")
//! i makechange(current,"Ufn2",si,"0.")
//! i makechange(current,"aare",si,"160.")
//! i makechange(current,"ahdu",si,"4.")
//! i makechange(current,"adur",si,"6.")
//! i makechange(current,"amcs",si,"0")
//! i end
//! i makechange(current,"Ufn1","1","105.")
//! i makechange(current,"Ufn1","2","150.")
//! i makechange(current,"Ufn1","3","200.")
//! i makechange(current,"Ufn1","4","260.")
//! i createobject("AEsf", FREEZING_FIELD_ABIL_ID)
//! i makechange(current,"anam", "Freezing Field")
//! i makechange(current,"alev", "3")
//! i makechange(current,"aart", "ReplaceableTextures\\CommandButtons\\BTNFreezingBreath.blp")
//! i makechange(current,"arar", "ReplaceableTextures\\CommandButtons\\BTNFreezingBreath.blp")
//! i makechange(current,"aret", "Learn |cffffcc00F|rreezing Field - [|CFF0960B8Level ".. string.char(37) .."d|r]")
//! i makechange(current,"arut", "Summons multi explosions around the Jaina damaging enemys and slowing them for <"..FREEZING_FIELD_DAMAGE_ID..",Dur1> seconds. |n|n|cFF0960B8Level 1|r - Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA1> damage.|n|cFF0960B8Level 2|r - Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA2> damage.|n|cFF0960B8Level 3|r - Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA3> damage.|nLast <"..FREEZING_FIELD_ABIL_ID..",HeroDur1> seconds.|n|n|cffff0000Channeling|r")
//! i local i = 0
//! i for i=1, 3 do
//! i local si = tostring(i)
//! i makechange(current,"atar",si,"Self")
//! i makechange(current,"Esf1",si,"0.")
//! i makechange(current,"Esf2",si,"4.")
//! i makechange(current,"Esf3",si,"0.")
//! i makechange(current,"aare",si,"0.")
//! i makechange(current,"ahdu",si,"4.1")
//! i makechange(current,"adur",si,"4.1")
//! i makechange(current,"acdn",si,"10")
//! i makechange(current,"abuf",si,nil)
//! i makechange(current,"aeff",si,nil)
//! i makechange(current,"atp1",si,"|cffffcc00F|rreezing Field - [|CFF0960B8Level "..si.."|r]")
//! i makechange(current,"aub1",si,"Summons multi explosions around the Jaina damaging enemys and slowing them for <"..FREEZING_FIELD_DAMAGE_ID..",Dur"..si.."> seconds. Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA"..si.."> damage. |n|nLast <"..FREEZING_FIELD_ABIL_ID..",HeroDur"..si.."> seconds.|n|cffff0000Channeling|r")
//! i end
//! i makechange(current,"amcs","1","200")
//! i makechange(current,"amcs","2","250")
//! i makechange(current,"amcs","3","300")
//! i if (FREEZING_FIELD_IMPROVED_ABIL_ID ~= nil) then
//! i createobject("AEsf", FREEZING_FIELD_IMPROVED_ABIL_ID)
//! i makechange(current,"anam", "Freezing Field")
//! i makechange(current,"ansf", " ( Upgraded )")
//! i makechange(current,"alev", "3")
//! i makechange(current,"aart", "ReplaceableTextures\\CommandButtons\\BTNFreezingBreath.blp")
//! i makechange(current,"arar", "ReplaceableTextures\\CommandButtons\\BTNFreezingBreath.blp")
//! i makechange(current,"aret", "Learn |cffffcc00F|rreezing Field - [|CFF0960B8Level ".. string.char(37) .."d|r]")
//! i makechange(current,"arut", "Summons multi explosions around the Jaina damaging enemys and slowing them for <"..FREEZING_FIELD_DAMAGE_ID..",Dur1> seconds. |n|n|cFF0960B8Level 1|r - Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA2> damage.|n|cFF0960B8Level 2|r - Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA3> damage.|n|cFF0960B8Level 3|r - Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA4> damage.|nLast <"..FREEZING_FIELD_IMPROVED_ABIL_ID..",HeroDur1> seconds.|n|n|cffff0000Channeling|r")
//! i local i = 0
//! i for i=1, 3 do
//! i local si = tostring(i)
//! i makechange(current,"atar",si,"Self")
//! i makechange(current,"Esf1",si,"0.")
//! i makechange(current,"Esf2",si,"4.")
//! i makechange(current,"Esf3",si,"0.")
//! i makechange(current,"aare",si,"0.")
//! i makechange(current,"ahdu",si,"4.1")
//! i makechange(current,"adur",si,"4.1")
//! i makechange(current,"acdn",si,"10")
//! i makechange(current,"abuf",si,nil)
//! i makechange(current,"aeff",si,nil)
//! i makechange(current,"atp1",si,"|cffffcc00F|rreezing Field - [|CFF0960B8Level "..si.."|r]")
//! i makechange(current,"aub1",si,"Summons multi explosions around the Jaina damaging enemys and slowing them for <"..FREEZING_FIELD_DAMAGE_ID..",Dur"..tostring(i+1).."> seconds. Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA"..tostring(i+1).."> damage. |n|nLast <"..FREEZING_FIELD_IMPROVED_ABIL_ID..",HeroDur"..si.."> seconds.|n|cffff0000Channeling|r")
//! i makechange(current,"amcs",si,tostring(150+50*i))
//! i end
//! i end
//! i if (FREEZING_FIELD_IMPROVED_ABIL_ID ~= nil or CHAIN_FROST_IMPROVED_ABIL_ID ~= nil) then
//! i createobject("ANeg", AGHANIM_SCEPTER_ABIL_ID)
//! i makechange(current,"aart", "ReplaceableTextures\\CommandButtons\\BTNINV_Wand_05.blp")
//! i makechange(current,"Neg3","1", FREEZING_FIELD_ABIL_ID..","..FREEZING_FIELD_IMPROVED_ABIL_ID)
//! i if (CHAIN_FROST_IMPROVED_ABIL_ID ~= nil) then
//! i makechange(current,"Neg4","1", CHAIN_FROST_ABIL_ID..","..CHAIN_FROST_IMPROVED_ABIL_ID)
//! i else
//! i makechange(current,"Neg4","1", nil)
//! i end
//! i makechange(current,"Neg5","1", nil)
//! i makechange(current,"Neg6","1", nil)
//! i makechange(current,"Neg1","1", "0.")
//! i makechange(current,"Neg2","1", "0.")
//! i makechange(current,"aher", false)
//! i makechange(current,"abuf","1", nil)
//! i makechange(current,"alev", "1")
//! i makechange(current,"arac", "nightelf")
//! i makechange(current,"anam", "CF & FF Upgrader")
//! i end
//! endexternalblock
*/
// ^
// |
// Change me from */ to // and then back to */ after saving and reopening the map
// ============================================================================================