//***************************************************************************
//* *
//* Brutal Blizzard v1.5 [Bblz_] *
//* by Ofel *
//* *
//* www.hiveworkshop.com *
//* *
//***************************************************************************
//***************************************************************************
//* *
//* Configuration below requires JASS knowledge *
//* *
//***************************************************************************
// ---------------------------
// Unit alive filter function
// ---------------------------
function Bblz_IsUnitAlive takes unit u returns boolean
return not IsUnitType(u,UNIT_TYPE_DEAD)
endfunction
// ---------------------------
// Damage filter function
// ---------------------------
function Bblz_DamageTargetFilter takes unit u,player owner returns boolean
return IsUnitEnemy(u,owner) and not IsUnitType(u,UNIT_TYPE_FLYING) and not IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)
endfunction
// ---------------------------
// Freeze filter function
// ---------------------------
function Bblz_FreezeTargetFilter takes unit u returns boolean
return not IsUnitType(u,UNIT_TYPE_STRUCTURE)
endfunction
// ---------------------------
// End of configuration
//===========================================================================
// ---------------------------
// Preloader function
// ---------------------------
function Bblz_Preload takes nothing returns nothing
local integer i=1
local real time
local real r=udg_Bblz_ShardSpawnHeight*udg_Bblz_ShardInterval
loop
exitwhen i>3
set time=r/udg_Bblz_ShardFallSpeed[i]
set udg_Bblz_HSpeed[i]=udg_Bblz_ShardSpawnOffset/(time/udg_Bblz_ShardInterval)
set udg_Bblz_FreezeDamage[i]=udg_Bblz_FreezeDamage[i]*udg_Bblz_ShardInterval
set i=i+1
endloop
set udg_Bblz_SpawnFacing=udg_Bblz_ShardSpawnAngle+180
set udg_Bblz_OffsetAngle=udg_Bblz_ShardSpawnAngle*bj_DEGTORAD
if udg_Bblz_ShardTDeformDepth<=0 then
set udg_Bblz_ShardTDeformDepth=0.01
endif
set udg_Bblz_Harvester=CreateUnit(udg_Bblz_DummiesOwner,udg_Bblz_HarvesterType,0,0,0)
call UnitAddAbility(udg_Bblz_Harvester,'Ahar')
call SetUnitInvulnerable(udg_Bblz_Harvester,true) // In case hidden unit get damaged by another trigger
call ShowUnit(udg_Bblz_Harvester,false)
call UnitAddAbility(udg_Bblz_Harvester,udg_Bblz_Ability)
call UnitRemoveAbility(udg_Bblz_Harvester,udg_Bblz_Ability)
set udg_Bblz_MapX[1]=GetRectMinX(bj_mapInitialPlayableArea)
set udg_Bblz_MapY[1]=GetRectMinY(bj_mapInitialPlayableArea)
set udg_Bblz_MapX[2]=GetRectMaxX(bj_mapInitialPlayableArea)
set udg_Bblz_MapY[2]=GetRectMaxY(bj_mapInitialPlayableArea)
call Preload(udg_Bblz_ShardModel)
call Preload(udg_Bblz_HitSFX)
set i=1
loop
exitwhen udg_Bblz_ExplosionSFX[i]==null
call Preload(udg_Bblz_ExplosionSFX[i])
set i=i+1
endloop
call Preload(udg_Bblz_FreezeSFX)
endfunction
// ---------------------------
// X point checker function
// ---------------------------
function Bblz_IsXInMap takes real x returns boolean
return x>=udg_Bblz_MapX[1] and x<=udg_Bblz_MapX[2]
endfunction
// ---------------------------
// Y point checker function
// ---------------------------
function Bblz_IsYInMap takes real y returns boolean
return y>=udg_Bblz_MapY[1] and y<=udg_Bblz_MapY[2]
endfunction
// ---------------------------
// Unit disabler function
// ---------------------------
function Bblz_DisableUnit takes unit u,integer level returns nothing
local unit u2=CreateUnit(udg_Bblz_DummiesOwner,udg_Bblz_DummyType,GetUnitX(u),GetUnitY(u),0)
call UnitAddAbility(u2,udg_Bblz_FreezeAbility)
call SetUnitAbilityLevel(u2,udg_Bblz_FreezeAbility,level)
call IssueTargetOrderById(u2,852095,u)
call UnitApplyTimedLife(u2,'BTLF',0.1)
set u2=null
endfunction
// ---------------------------
// Tree destroyer function
// ---------------------------
function Bblz_DestroyTrees takes nothing returns nothing
local destructable tree=GetEnumDestructable()
if IssueTargetOrderById(udg_Bblz_Harvester,852018,tree) then
call KillDestructable(tree)
endif
set tree=null
endfunction
// ---------------------------
// Tree scanner function
// ---------------------------
function Bblz_ScanTrees takes real x,real y,real radius returns nothing
call SetRect(udg_Bblz_tempRect,x-radius,y-radius,x+radius,y+radius)
set bj_enumDestructableCenter=Location(x,y)
set bj_enumDestructableRadius=radius
call EnumDestructablesInRect(udg_Bblz_tempRect,filterEnumDestructablesInCircleBJ,function Bblz_DestroyTrees)
call RemoveLocation(bj_enumDestructableCenter)
endfunction
// ---------------------------
// Terrain deformation function
// ---------------------------
function Bblz_TerrainDeform takes real radius,real depth,real x,real y returns nothing
call TerrainDeformCrater(x,y,radius,depth,100,false)
endfunction
// ---------------------------
// Periodic/core function
// ---------------------------
function Bblz_Periodic takes nothing returns boolean
local integer index=0
local real x
local real y
local real x2
local real y2
local real offset
local real angle
local real facing
local integer i
local unit u
loop
exitwhen index>udg_Bblz_MaxIndex
// ---------------------------
// Method 1: Falling shards
// ---------------------------
if udg_Bblz_Method[index]==1 then
set x=GetUnitX(udg_Bblz_Dummy[index])
set y=GetUnitY(udg_Bblz_Dummy[index])
if udg_Bblz_Height[index]>0 then
set udg_Bblz_Height[index]=udg_Bblz_Height[index]-udg_Bblz_ShardFallSpeed[udg_Bblz_Level[index]]
call SetUnitFlyHeight(udg_Bblz_Dummy[index],udg_Bblz_Height[index],0)
set x=x+udg_Bblz_HSpeed[udg_Bblz_Level[index]]*Cos(udg_Bblz_HAngle[index])
set y=y+udg_Bblz_HSpeed[udg_Bblz_Level[index]]*Sin(udg_Bblz_HAngle[index])
call SetUnitX(udg_Bblz_Dummy[index],x)
call SetUnitY(udg_Bblz_Dummy[index],y)
else
set i=1
loop
exitwhen udg_Bblz_ExplosionSFX[i]==null
call DestroyEffect(AddSpecialEffect(udg_Bblz_ExplosionSFX[i],x,y))
set i=i+1
endloop
call GroupEnumUnitsInRange(udg_Bblz_tempGroup,x,y,udg_Bblz_DamageRadius[udg_Bblz_Level[index]],null)
loop
set u=FirstOfGroup(udg_Bblz_tempGroup)
exitwhen u==null
if Bblz_IsUnitAlive(u) and Bblz_DamageTargetFilter(u,udg_Bblz_Owner[index]) then
call UnitDamageTarget(udg_Bblz_Caster[index],u,udg_Bblz_DamagePerShard[udg_Bblz_Level[index]],true,false,udg_Bblz_AttackType,udg_Bblz_DamageType,null)
call DestroyEffect(AddSpecialEffectTarget(udg_Bblz_HitSFX,u,udg_Bblz_HitSFXPoint))
if Bblz_IsUnitAlive(u) and Bblz_FreezeTargetFilter(u) then
if IsUnitInGroup(u,udg_Bblz_FreezedUnits) then
set i=1
loop
exitwhen i>udg_Bblz_MaxIndex
if udg_Bblz_Target[i]==u then
set udg_Bblz_realTimer[i]=udg_Bblz_FreezeDuration[udg_Bblz_Level[index]]
call Bblz_DisableUnit(u,udg_Bblz_Level[index])
endif
set i=i+1
endloop
else
set udg_Bblz_MaxIndex=udg_Bblz_MaxIndex+1
set udg_Bblz_Target[udg_Bblz_MaxIndex]=u
set udg_Bblz_Caster[udg_Bblz_MaxIndex]=udg_Bblz_Caster[index]
set udg_Bblz_Level[udg_Bblz_MaxIndex]=udg_Bblz_Level[index]
set udg_Bblz_AttachedFX[udg_Bblz_MaxIndex]=AddSpecialEffectTarget(udg_Bblz_FreezeSFX,u,udg_Bblz_FreezeSFXPoint)
set udg_Bblz_realTimer[udg_Bblz_MaxIndex]=udg_Bblz_FreezeDuration[udg_Bblz_Level[index]]
call SetUnitTimeScale(u,0)
call Bblz_DisableUnit(u,udg_Bblz_Level[index])
set udg_Bblz_Method[udg_Bblz_MaxIndex]=2
call GroupAddUnit(udg_Bblz_FreezedUnits,u)
endif
endif
endif
call GroupRemoveUnit(udg_Bblz_tempGroup,u)
endloop
if udg_Bblz_DestroyTrees then
call Bblz_ScanTrees(x,y,udg_Bblz_DamageRadius[udg_Bblz_Level[index]]) // Custom destructable enumeration function :D
endif
call Bblz_TerrainDeform(udg_Bblz_ShardTDeformRadius,udg_Bblz_ShardTDeformDepth,x,y)
call DestroyEffect(udg_Bblz_AttachedFX[index])
call KillUnit(udg_Bblz_Dummy[index])
set udg_Bblz_Method[index]=4
endif
// ---------------------------
// Method 2: Freezing units
// ---------------------------
elseif udg_Bblz_Method[index]==2 then
if not Bblz_IsUnitAlive(udg_Bblz_Target[index]) then
set udg_Bblz_realTimer[index]=0
endif
if udg_Bblz_realTimer[index]>0 then
set udg_Bblz_realTimer[index]=udg_Bblz_realTimer[index]-udg_Bblz_PeriodicInterval
call UnitDamageTarget(udg_Bblz_Caster[index],udg_Bblz_Target[index],udg_Bblz_FreezeDamage[udg_Bblz_Level[index]],true,false,udg_Bblz_AttackType,udg_Bblz_DamageType,null)
else
call DestroyEffect(udg_Bblz_AttachedFX[index])
call SetUnitTimeScale(udg_Bblz_Target[index],1)
call GroupRemoveUnit(udg_Bblz_FreezedUnits,udg_Bblz_Target[index])
set udg_Bblz_Method[index]=4
endif
// ---------------------------
// Method 3: Creating shards and spell timer
// ---------------------------
elseif udg_Bblz_Method[index]==3 then
if GetUnitCurrentOrder(udg_Bblz_Caster[index])==udg_Bblz_OrderId and udg_Bblz_realTimer[index]>0 then
set udg_Bblz_realTimer[index]=udg_Bblz_realTimer[index]-udg_Bblz_PeriodicInterval
set udg_Bblz_realTimer2[index]=udg_Bblz_realTimer2[index]-udg_Bblz_PeriodicInterval
if udg_Bblz_realTimer2[index]<=0 then
set udg_Bblz_realTimer2[index]=udg_Bblz_ShardInterval
set angle=GetRandomReal(0,2*bj_PI)
set offset=GetRandomReal(0,udg_Bblz_AoE[udg_Bblz_Level[index]])
set x=udg_Bblz_TargetX[index]+offset*Cos(angle)
set y=udg_Bblz_TargetY[index]+offset*Sin(angle)
set x2=x+udg_Bblz_ShardSpawnOffset*Cos(udg_Bblz_OffsetAngle)
set y2=y+udg_Bblz_ShardSpawnOffset*Sin(udg_Bblz_OffsetAngle)
if not Bblz_IsXInMap(x2) or not Bblz_IsYInMap(y2) then
set x2=x-udg_Bblz_ShardSpawnOffset*Cos(udg_Bblz_OffsetAngle)
set y2=y-udg_Bblz_ShardSpawnOffset*Sin(udg_Bblz_OffsetAngle)
set facing=udg_Bblz_SpawnFacing+180
else
set facing=udg_Bblz_SpawnFacing
endif
set udg_Bblz_MaxIndex=udg_Bblz_MaxIndex+1
set udg_Bblz_Dummy[udg_Bblz_MaxIndex]=CreateUnit(udg_Bblz_DummiesOwner,udg_Bblz_DummyType,x2,y2,facing)
set udg_Bblz_AttachedFX[udg_Bblz_MaxIndex]=AddSpecialEffectTarget(udg_Bblz_ShardModel,udg_Bblz_Dummy[udg_Bblz_MaxIndex],"origin")
call SetUnitScale(udg_Bblz_Dummy[udg_Bblz_MaxIndex],udg_Bblz_ShardSize[udg_Bblz_Level[index]],0,0)
call SetUnitFlyHeight(udg_Bblz_Dummy[udg_Bblz_MaxIndex],udg_Bblz_ShardSpawnHeight,0)
set udg_Bblz_Height[udg_Bblz_MaxIndex]=udg_Bblz_ShardSpawnHeight
set udg_Bblz_Caster[udg_Bblz_MaxIndex]=udg_Bblz_Caster[index]
set udg_Bblz_Owner[udg_Bblz_MaxIndex]=udg_Bblz_Owner[index]
set udg_Bblz_Level[udg_Bblz_MaxIndex]=udg_Bblz_Level[index]
set udg_Bblz_HAngle[udg_Bblz_MaxIndex]=facing*bj_DEGTORAD
set udg_Bblz_Method[udg_Bblz_MaxIndex]=1
endif
else
set udg_Bblz_Method[index]=4
endif
// ---------------------------
// Method 4: Recycling indexes
// ---------------------------
elseif udg_Bblz_Method[index]==4 then
set udg_Bblz_AttachedFX[index]=udg_Bblz_AttachedFX[udg_Bblz_MaxIndex]
set udg_Bblz_Caster[index]=udg_Bblz_Caster[udg_Bblz_MaxIndex]
set udg_Bblz_Dummy[index]=udg_Bblz_Dummy[udg_Bblz_MaxIndex]
set udg_Bblz_HAngle[index]=udg_Bblz_HAngle[udg_Bblz_MaxIndex]
set udg_Bblz_Height[index]=udg_Bblz_Height[udg_Bblz_MaxIndex]
set udg_Bblz_Level[index]=udg_Bblz_Level[udg_Bblz_MaxIndex]
set udg_Bblz_Method[index]=udg_Bblz_Method[udg_Bblz_MaxIndex]
set udg_Bblz_Owner[index]=udg_Bblz_Owner[udg_Bblz_MaxIndex]
set udg_Bblz_realTimer[index]=udg_Bblz_realTimer[udg_Bblz_MaxIndex]
set udg_Bblz_realTimer2[index]=udg_Bblz_realTimer2[udg_Bblz_MaxIndex]
set udg_Bblz_Target[index]=udg_Bblz_Target[udg_Bblz_MaxIndex]
set udg_Bblz_TargetX[index]=udg_Bblz_TargetX[udg_Bblz_MaxIndex]
set udg_Bblz_TargetY[index]=udg_Bblz_TargetY[udg_Bblz_MaxIndex]
set udg_Bblz_Caster[udg_Bblz_MaxIndex]=null
set udg_Bblz_Dummy[udg_Bblz_MaxIndex]=null
set udg_Bblz_Owner[udg_Bblz_MaxIndex]=null
set udg_Bblz_Target[udg_Bblz_MaxIndex]=null
set index=index-1
set udg_Bblz_MaxIndex=udg_Bblz_MaxIndex-1
if udg_Bblz_MaxIndex==0 then
call PauseTimer(udg_Bblz_PeriodicTimer)
endif
endif
set index=index+1
endloop
return false
endfunction
// ---------------------------
// Activation function
// ---------------------------
function Bblz_Cast takes nothing returns boolean
local integer i
if GetSpellAbilityId()==udg_Bblz_Ability then
set udg_Bblz_Caster[0]=GetTriggerUnit()
if udg_Bblz_MaxIndex==0 then
call TimerStart(udg_Bblz_PeriodicTimer,udg_Bblz_PeriodicInterval,true,function Bblz_Periodic)
else
set i=1
loop
exitwhen i>udg_Bblz_MaxIndex
if udg_Bblz_Caster[i]==udg_Bblz_Caster[0] and udg_Bblz_Method[i]==3 then
set udg_Bblz_Method[i]=4
endif
set i=i+1
endloop
endif
set udg_Bblz_MaxIndex=udg_Bblz_MaxIndex+1
set udg_Bblz_Caster[udg_Bblz_MaxIndex]=udg_Bblz_Caster[0]
set udg_Bblz_Owner[udg_Bblz_MaxIndex]=GetTriggerPlayer()
set udg_Bblz_Level[udg_Bblz_MaxIndex]=GetUnitAbilityLevel(udg_Bblz_Caster[udg_Bblz_MaxIndex],udg_Bblz_Ability)
set udg_Bblz_TargetX[udg_Bblz_MaxIndex]=GetSpellTargetX()
set udg_Bblz_TargetY[udg_Bblz_MaxIndex]=GetSpellTargetY()
set udg_Bblz_realTimer[udg_Bblz_MaxIndex]=udg_Bblz_Duration[udg_Bblz_Level[udg_Bblz_MaxIndex]]
set udg_Bblz_realTimer2[udg_Bblz_MaxIndex]=0
set udg_Bblz_Method[udg_Bblz_MaxIndex]=3
endif
return false
endfunction
// ---------------------------
// Initializer function
// ---------------------------
function InitTrig_Brutal_Blizzard takes nothing returns nothing
set gg_trg_Brutal_Blizzard=CreateTrigger()
set udg_Bblz_tempRect=Rect(0,0,0,0)
call TriggerRegisterAnyUnitEventBJ(gg_trg_Brutal_Blizzard,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(gg_trg_Brutal_Blizzard,Filter(function Bblz_Cast))
endfunction