Name | Type | is_array | initial_value |
AfterDamageEvent | real | No | |
Bossinf | unit | No | |
CenterPoint | location | No | |
ClearDamageEvent | trigger | No | |
DamageBlockingAbility | abilcode | No | |
DamageEvent | real | No | |
DamageEventAmount | real | No | |
DamageEventOverride | boolean | No | |
DamageEventPrevAmt | real | No | |
DamageEventSource | unit | No | |
DamageEventsWasted | integer | No | |
DamageEventTarget | unit | No | |
DamageEventTrigger | trigger | No | |
DamageEventType | integer | No | |
DamageModifierEvent | real | No | |
DamageTypeBlocked | integer | No | |
DamageTypeCriticalStrike | integer | No | |
DamageTypeExplosive | integer | No | |
DamageTypeHeal | integer | No | |
DamageTypeReduced | integer | No | |
DmgEvLife | real | No | |
DmgEvPrevLife | real | No | |
DmgEvRecursionLevel | integer | No | |
DmgEvRecursionN | integer | No | |
DmgEvRunning | boolean | No | |
DmgEvStarted | boolean | No | |
DmgEvTimer | timer | No | |
DmgEvTrig | trigger | No | |
DmgEvUnit | unit | No | |
EyeChance | integer | No | |
Guardians | group | No | |
HeavyMarine | button | No | |
Humangroup | group | No | |
HumangroupCount | integer | No | |
Humans | force | No | |
HumanWins | integer | No | |
IsDamageSpell | boolean | No | |
IsUnitBeingKnockedBack | boolean | Yes | |
K2DAmphibious | boolean | Yes | |
K2DAngle | real | Yes | |
K2DBounce | boolean | Yes | |
K2DCollision | real | Yes | |
K2DCos | real | Yes | |
K2DCosD1 | real | Yes | |
K2DCosD2 | real | Yes | |
K2DCosH | real | Yes | |
K2DDebrisKiller | unit | No | |
K2DDestRadius | real | Yes | |
K2DDistanceLeft | real | Yes | |
K2DFlying | boolean | Yes | |
K2DFreeze | boolean | Yes | |
K2DFriction | real | Yes | |
K2DFXModel | string | Yes | |
K2DFXRate | real | Yes | |
K2DFXTimeLeft | real | Yes | |
K2DHeight | real | Yes | |
K2DHeightThreshold | real | Yes | |
K2DImpact | trigger | Yes | |
K2DItem | item | No | |
K2DItemOffset | boolean | No | |
K2DItemsFound | boolean | No | |
K2DKillTrees | boolean | Yes | |
K2DLastX | real | Yes | |
K2DLastY | real | Yes | |
K2DMaxDestRadius | real | No | |
K2DMaxX | real | No | |
K2DMaxY | real | No | |
K2DMinX | real | No | |
K2DMinY | real | No | |
K2DNext | integer | Yes | |
K2DOverride | boolean | Yes | |
K2DPause | boolean | Yes | |
K2DPrev | integer | Yes | |
K2DRadius | integer | Yes | |
K2DRegion | rect | No | |
K2DSimple | boolean | Yes | |
K2DSin | real | Yes | |
K2DSinD1 | real | Yes | |
K2DSinD2 | real | Yes | |
K2DSinH | real | Yes | |
K2DSource | unit | Yes | |
K2DTimeLeft | real | Yes | |
K2DTimeout | real | No | |
K2DTimer | timer | No | |
K2DUnbiasedCollision | boolean | Yes | |
K2DVelocity | real | Yes | |
K2DX | real | No | |
K2DY | real | No | |
Knockback2DAmphibious | boolean | No | |
Knockback2DAngle | real | No | |
Knockback2DBounces | boolean | No | |
Knockback2DCollision | real | No | |
Knockback2DDefaultBounce | boolean | No | |
Knockback2DDefaultDestRadius | real | No | |
Knockback2DDefaultFriction | real | No | |
Knockback2DDefaultFX | string | No | |
Knockback2DDefaultFXRate | real | No | |
Knockback2DDefaultGravity | real | No | |
Knockback2DDefaultKillTrees | boolean | No | |
Knockback2DDefaultPause | boolean | No | |
Knockback2DDestRadius | real | No | |
Knockback2DDistance | real | No | |
Knockback2DFriction | real | No | |
Knockback2DFXRate | real | No | |
Knockback2DGravity | real | No | |
Knockback2DHeight | real | No | |
Knockback2DKillTrees | boolean | No | |
Knockback2DLoopFX | string | No | |
Knockback2DOnImpact | trigger | No | |
Knockback2DOverride | boolean | No | |
Knockback2DPause | boolean | No | |
Knockback2DRobustPathing | integer | No | |
Knockback2DSimple | boolean | No | |
Knockback2DSource | unit | No | |
Knockback2DTime | real | No | |
Knockback2DTreeOrDebris | string | No | |
Knockback2DUnbiasedCollision | boolean | No | |
Knockback2DUnit | unit | No | |
LastDamageHP | real | No | |
LastDmgPrevAmount | real | Yes | |
LastDmgPrevType | integer | Yes | |
LastDmgSource | unit | Yes | |
LastDmgTarget | unit | Yes | |
LastDmgValue | real | Yes | |
LastDmgWasSpell | boolean | Yes | |
LeaklessGroup | group | No | |
LoopInt | integer | No | |
Mage | button | No | |
NextDamageOverride | boolean | No | |
NextDamageType | integer | No | |
Peasant | button | No | |
Radians_QuarterPi | real | No | |
Radians_QuarterTurn | real | No | |
Radians_Turn | real | No | |
RandomLevel | integer | No | |
RandomNumber | integer | No | |
SecretAgent | button | No | |
Song | sound | No | |
SpellDamageAbility | abilcode | No | |
StartTimer | timer | No | |
TargetPoint | location | No | |
Tauren_Shockwave | boolean | Yes | |
Tauren_WarStomp | boolean | Yes | |
TempReal | real | No | |
TimerWindow | timerdialog | No | |
turrets | group | No | |
UDex | integer | No | |
UDexGen | integer | No | |
UDexNext | integer | Yes | |
UDexPrev | integer | Yes | |
UDexRecycle | integer | No | |
UDexUnits | unit | Yes | |
UDexWasted | integer | No | |
UnitDamageRegistered | boolean | Yes | |
UnitIndexerEnabled | boolean | No | |
UnitIndexEvent | real | No | |
UnitPick | dialog | No | |
unloadchance | integer | No | |
Zombiegroup | group | No | |
Zombies | force | No |
//TESH.scrollpos=205
//TESH.alwaysfold=0
function K2DItemCheckXY takes real x, real y returns boolean
call SetItemPosition(udg_K2DItem, x, y)
return GetWidgetX(udg_K2DItem) == x and GetWidgetY(udg_K2DItem) == y
endfunction
function K2DItemCheckAxis takes real x, real y returns boolean
local real x2 = x*udg_K2DRadius[udg_UDex]
local real y2 = y*udg_K2DRadius[udg_UDex]
set x = udg_K2DX + x2
set y = udg_K2DY + y2
if K2DItemCheckXY(x, y) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) then
set x = udg_K2DX - x2
set y = udg_K2DY - y2
return K2DItemCheckXY(x, y) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endif
return false
endfunction
function K2DItemCheck takes nothing returns boolean
local boolean result = K2DItemCheckXY(udg_K2DX, udg_K2DY)
//Only perform additional pathing checks if the unit has a larger collision.
if result and udg_Knockback2DRobustPathing > 0 and udg_K2DRadius[udg_UDex] > 0 then
//Check horizontal axis of unit to make sure nothing is going to collide
set result = K2DItemCheckAxis(udg_K2DCosH[udg_UDex], udg_K2DSinH[udg_UDex])
//Check vertical axis of unit to ensure nothing will collide
set result = result and K2DItemCheckAxis(udg_K2DCos[udg_UDex], udg_K2DSin[udg_UDex])
if result and udg_Knockback2DRobustPathing == 2 and udg_K2DRadius[udg_UDex] > 16 then
//Check diagonal axis of unit if more thorough pathing is desired
set result = K2DItemCheckAxis(udg_K2DCosD1[udg_UDex], udg_K2DSinD1[udg_UDex])
set result = result and K2DItemCheckAxis(udg_K2DCosD2[udg_UDex], udg_K2DSinD2[udg_UDex])
endif
endif
//Reset item so it won't interfere with the map
call SetItemPosition(udg_K2DItem, udg_K2DMaxX, udg_K2DMaxY)
call SetItemVisible(udg_K2DItem, false)
return result
endfunction
function K2DItemFilter takes nothing returns boolean
//Check for visible items, temporarily hide them and add them to the filter.
if IsItemVisible(GetFilterItem()) then
call SetItemVisible(GetFilterItem(), false)
return true
endif
return false
endfunction
function K2DItemCode takes nothing returns nothing
//Perform the item-pathing check only once, then unhide those filtered items
if not udg_K2DItemsFound then
set udg_K2DItemsFound = true
set udg_K2DItemOffset = K2DItemCheck()
endif
call SetItemVisible(GetEnumItem(), true)
endfunction
function K2DKillDest takes nothing returns nothing
local real x
local real y
//Handle destruction of debris
set bj_destRandomCurrentPick = GetEnumDestructable()
if GetWidgetLife(bj_destRandomCurrentPick) > 0.405 and IssueTargetOrder(udg_K2DDebrisKiller, udg_Knockback2DTreeOrDebris, bj_destRandomCurrentPick) then
set x = GetWidgetX(bj_destRandomCurrentPick) - udg_K2DX
set y = GetWidgetY(bj_destRandomCurrentPick) - udg_K2DY
if x*x + y*y <= udg_K2DDestRadius[udg_UDex] then
call KillDestructable(bj_destRandomCurrentPick)
endif
endif
endfunction
function K2DEnumDests takes nothing returns nothing
call MoveRectTo(udg_K2DRegion, udg_K2DX, udg_K2DY)
if udg_K2DKillTrees[udg_UDex] then
call SetUnitX(udg_K2DDebrisKiller, udg_K2DX)
call SetUnitY(udg_K2DDebrisKiller, udg_K2DY)
call EnumDestructablesInRect(udg_K2DRegion, null, function K2DKillDest)
endif
endfunction
function Knockback2DCheckXY takes real x, real y returns boolean
set udg_K2DX = x + udg_K2DVelocity[udg_UDex]*udg_K2DCos[udg_UDex]
set udg_K2DY = y + udg_K2DVelocity[udg_UDex]*udg_K2DSin[udg_UDex]
if udg_K2DSimple[udg_UDex] then
//A "pull" effect or a missile system does not require complex pathing.
if udg_K2DX <= udg_K2DMaxX and udg_K2DX >= udg_K2DMinX and udg_K2DY <= udg_K2DMaxY and udg_K2DY >= udg_K2DMinY then
call K2DEnumDests()
return true
endif
return false
elseif udg_K2DFlying[udg_UDex] then
return not IsTerrainPathable(udg_K2DX, udg_K2DY, PATHING_TYPE_FLYABILITY)
elseif not IsTerrainPathable(udg_K2DX, udg_K2DY, PATHING_TYPE_WALKABILITY) then
call K2DEnumDests()
set udg_K2DItemOffset = false
call EnumItemsInRect(udg_K2DRegion, Filter(function K2DItemFilter), function K2DItemCode)
if udg_K2DItemsFound then
//If items were found, the check was already performed.
set udg_K2DItemsFound = false
else
//Otherwise, perform the check right now.
set udg_K2DItemOffset = K2DItemCheck()
endif
return udg_K2DItemOffset
endif
return udg_K2DAmphibious[udg_UDex] and not IsTerrainPathable(udg_K2DX, udg_K2DY, PATHING_TYPE_FLOATABILITY)
endfunction
function Knockback2DApplyAngle takes real angle returns nothing
set angle = ModuloReal(angle, udg_Radians_Turn)
set udg_K2DCos[udg_UDex] = Cos(angle)
set udg_K2DSin[udg_UDex] = Sin(angle)
set udg_K2DAngle[udg_UDex] = angle
if udg_Knockback2DRobustPathing > 0 then
set angle = ModuloReal(angle + udg_Radians_QuarterTurn, udg_Radians_Turn)
set udg_K2DCosH[udg_UDex] = Cos(angle)
set udg_K2DSinH[udg_UDex] = Sin(angle)
if udg_Knockback2DRobustPathing == 2 and udg_K2DRadius[udg_UDex] > 16 then
set angle = ModuloReal(angle + udg_Radians_QuarterPi, udg_Radians_Turn)
set udg_K2DCosD1[udg_UDex] = Cos(angle)
set udg_K2DSinD1[udg_UDex] = Sin(angle)
set angle = ModuloReal(angle + udg_Radians_QuarterTurn, udg_Radians_Turn)
set udg_K2DCosD2[udg_UDex] = Cos(angle)
set udg_K2DSinD2[udg_UDex] = Sin(angle)
endif
endif
endfunction
function Knockback2DLooper takes nothing returns nothing
local integer i = 0
local unit u
local real x
local real y
call PauseUnit(udg_K2DDebrisKiller, false)
loop
set i = udg_K2DNext[i]
exitwhen i == 0
set udg_UDex = i
set udg_K2DTimeLeft[i] = udg_K2DTimeLeft[i] - udg_K2DTimeout
set udg_K2DDistanceLeft[i] = udg_K2DDistanceLeft[i] - udg_K2DVelocity[i]
set u = udg_UDexUnits[i]
if udg_K2DTimeLeft[i] > 0.00 then
if udg_K2DTimeLeft[i] < udg_K2DHeightThreshold[i] and udg_K2DHeightThreshold[i] != 0.00 then
call SetUnitFlyHeight(u, GetUnitDefaultFlyHeight(u), GetUnitFlyHeight(u) - GetUnitDefaultFlyHeight(u)/udg_K2DHeightThreshold[i])
set udg_K2DHeightThreshold[i] = 0.00
endif
if udg_K2DPause[i] then
set x = udg_K2DLastX[i]
set y = udg_K2DLastY[i]
else
set x = GetUnitX(u)
set y = GetUnitY(u)
endif
if not Knockback2DCheckXY(x, y) then
if not udg_K2DFreeze[i] and IsTriggerEnabled(udg_K2DImpact[i]) and TriggerEvaluate(udg_K2DImpact[i]) then
call TriggerExecute(udg_K2DImpact[i])
endif
if udg_K2DBounce[i] then
call Knockback2DApplyAngle(udg_Radians_Turn - udg_K2DAngle[i])
if not Knockback2DCheckXY(x, y) then
call Knockback2DApplyAngle(udg_K2DAngle[i] + bj_PI)
if not Knockback2DCheckXY(x, y) then
call Knockback2DApplyAngle(udg_Radians_Turn - udg_K2DAngle[i])
set udg_K2DX = x
set udg_K2DY = y
endif
endif
else
set udg_K2DX = x
set udg_K2DY = y
set udg_K2DFreeze[i] = true
endif
endif
call SetUnitX(u, udg_K2DX)
call SetUnitY(u, udg_K2DY)
set udg_K2DLastX[i] = udg_K2DX
set udg_K2DLastY[i] = udg_K2DY
if udg_K2DFXModel[i] != "" then
set udg_K2DFXTimeLeft[i] = udg_K2DFXTimeLeft[i] - udg_K2DTimeout
if udg_K2DFXTimeLeft[i] <= 0.00 then
set udg_K2DFXTimeLeft[i] = udg_K2DFXRate[i]
if udg_K2DFlying[i] then
call DestroyEffect(AddSpecialEffectTarget(udg_K2DFXModel[i], u, "origin"))
else
call DestroyEffect(AddSpecialEffect(udg_K2DFXModel[i], udg_K2DX, udg_K2DY))
endif
endif
endif
if udg_K2DCollision[i] >= 0.00 then
set udg_Knockback2DSource = u
call GroupEnumUnitsInRange(bj_lastCreatedGroup, udg_K2DX, udg_K2DY, 200.00, null)
call GroupRemoveUnit(bj_lastCreatedGroup, u)
loop
set udg_Knockback2DUnit = FirstOfGroup(bj_lastCreatedGroup)
exitwhen udg_Knockback2DUnit == null
call GroupRemoveUnit(bj_lastCreatedGroup, udg_Knockback2DUnit)
if IsUnitInRange(udg_Knockback2DUnit, u, udg_K2DCollision[i]) and udg_K2DFlying[i] == IsUnitType(udg_Knockback2DUnit, UNIT_TYPE_FLYING) and (not IsUnitType(udg_Knockback2DUnit, UNIT_TYPE_STRUCTURE)) and not IsUnitType(udg_Knockback2DUnit, UNIT_TYPE_DEAD) and (udg_K2DUnbiasedCollision[i] or IsUnitAlly(udg_Knockback2DUnit, GetOwningPlayer(u))) and TriggerEvaluate(gg_trg_Knockback_2D) then
set udg_Knockback2DAngle = bj_RADTODEG * Atan2(GetUnitY(udg_Knockback2DUnit) - udg_K2DY, GetUnitX(udg_Knockback2DUnit) - udg_K2DX)
set udg_Knockback2DDistance = udg_K2DDistanceLeft[i]
set udg_Knockback2DBounces = udg_K2DBounce[i]
set udg_Knockback2DCollision = udg_K2DCollision[i]
if udg_K2DHeight[i] != 0.00 then
set udg_Knockback2DHeight = GetUnitFlyHeight(u) - GetUnitDefaultFlyHeight(u)
endif
set udg_Knockback2DLoopFX = udg_K2DFXModel[i]
set udg_Knockback2DTime = udg_K2DTimeLeft[i]
set udg_Knockback2DUnbiasedCollision = udg_K2DUnbiasedCollision[i]
call TriggerExecute(gg_trg_Knockback_2D)
set udg_Knockback2DSource = u //in case of a recursive knockback
endif
endloop
endif
set udg_K2DVelocity[i] = udg_K2DVelocity[i] - udg_K2DFriction[i]
else
call TriggerExecute(gg_trg_Knockback_2D_Destroy)
endif
endloop
set u = null
//Disable dummy after the loop finishes so it doesn't interfere with the map
call PauseUnit(udg_K2DDebrisKiller, true)
endfunction
//===========================================================================
function StartKnockback2DTimer takes nothing returns nothing
call TimerStart(udg_K2DTimer, udg_K2DTimeout, true, function Knockback2DLooper)
endfunction
function InitTrig_Knockback_2D_System takes nothing returns nothing
endfunction
//TESH.scrollpos=146
//TESH.alwaysfold=0
//***************************************************************************
//***************************************************************************
//***************************************************************************
// L O T U S I C E
// By: Elphis (Nyuu)
// Version: 1.0
//
// Sepll Description:
// ` - Using the power of frost, ice beam summons on the ground at the same time creating freezing weather,
// after the ice beam achieve maximum strength, it immediately ice scrapers on the ground, any enemies in range
// 300, it will pierce, and push enemies out of range, and every 0.2 seconds, it will emit a stream of ejected ice,
// freezing enemies, and those who freezes in 500 range, it will pull enemy into the deep of the ice place.
//
// Damage level 1: 1.5
// Damage level 2: 3
// Damage level 3: 4.5
// Damage level 4: 6
// - Installation:
// - Import/copy Lotus Ice code to your map
// - Import/copy the custom ability and unit to your map and change the SPELL_ID, DUMMY_CASTER, DUMMY_DEG_1, DUMMY_DEG_2, DUMMY_DEG_3 and DUMMY_MISSLE if needed
// - You may view the raw ID of the objects by pressing CTRL+D in the object editor
// - You may play with the configurables below
//
//
//***************************************************************************
//***************************************************************************
//***************************************************************************
library LotusIce
globals
private constant real PERIODIC = .031250000
//Spell rawcode, change if needed
private constant integer SPELL_ID = 'A000'
//Dummy 1 rawcode, change if needed
private constant integer DUMMY_DEG_1 = 'e000'
//Dummy 2 rawcode, change if needed
private constant integer DUMMY_DEG_2 = 'e001'
//Dummy 3 rawcode, change if needed
private constant integer DUMMY_DEG_3 = 'e002'
//Dummy missle rawcode, change if needed
private constant integer DUMMY_MISSLE = 'e003'
//Dummy caster rawcode, change if needed
private constant integer CASTER_DUMMY = 'e004'
//Buff rawcode, change if needed
private constant integer BUFF_ID = 'B000'
//Weather type when spell is active
private constant integer WEATHER_TYPE = 'SNhs'
//Total ice count
private constant integer DUMMY_COUNT = 10
//Frost effect count random number, incease => laggy, decrease => ice fairy
private constant integer EFFECT_NUMBER = 2
//Total wave of frost
private constant integer FROST_COUNT = 4
//Damage base of spell, increase => instantly dead, decrease => you dead
private constant real DAMAGE_BASE = 1.5
//Push unit radius
private constant real KNOCK_RADIUS = 300.
//Damage radius, increase => incredible spell, decrease => useless spell
private constant real DMG_RADIUS = 100.
//Pull unit when the enemies has freezed
private constant real PULL_RANGE = 500.
//Push speed, increase => fast push, decrease => slow push
private constant real ENEMIES_KNOCK = 5.
//Pull unit speed
private constant real ENEMIES_PULL = 0.5
//Frost missle speed
private constant real MISSLE_SPEED = 20.
//Main ice scale
private constant real ICE_SCALE_1 = 2.
//Second ice scale
private constant real ICE_SCALE_2 = 1.
//Third ice scale
private constant real ICE_SCALE_3 = 1.
//Scale increase per periodic
private constant real SCALE_PER_PERIOD= .07
private constant real ICE_AREA_1 = 150.
private constant real ICE_AREA_2 = 200.
private constant real RANGE_MISSLE_1 = 600.
private constant real RANGE_MISSLE_2 = 700.
//Range increase per wave of frost
private constant real RANGE_PER_PERIOD= 150.
//Freeze radius when the wave of frost is active
private constant real FREEZE_RADIUS = 150.
//Frost wave intevar
private constant real FROST_INTEVAR = 0.1
//Damage intevar
private constant real DAMAGE_INTEVAR = 0.5
//Lotus ice spell duration
private constant real LOTUS_DURATION = 3.
//Frost of wave repeat time
private constant real FROST_REPEAT = 0.8
//Frost effect
private constant string ICE_EFFECT = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"
//Order id of dummy spell
private constant string ORDER_ID = "thunderbolt"
//Create a dummy on init function, so this spell never create dummy again
private constant boolean DO_DUMMY_INIT = true
//******************************DAMAGE DATA SETTINGS******************************
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_HERO
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_DEATH
private constant weapontype WEAPON_TYPE = WEAPON_TYPE_CLAW_HEAVY_SLICE
//********************************************************************************
//***************************Non - Configurable*****************************
/* */
/**/private integer MUI = -1 /**/
/* */
/**/private constant timer TIMER = CreateTimer() /**/
/* */
/**/private constant timer TIMER_2 = CreateTimer() /**/
/* */
/**/private integer array StructData /**/
/* */
/**/private integer PMUI = -1 /**/
/* */
/**/private integer array PStructData /**/
/* */
/**/private integer TMUI = -1 /**/
/* */
/**/private integer array TStructData /**/
/* */
/**/private group G = CreateGroup() /**/
/* */
/**/private unit Dummy /**/
/* */
/**/private real Main_Time = 0. /**/
/* */
/**/private rect RECT = Rect(0.,0.,0.,0.) /**/
/* */
//***************************************************************************
/**/private constant real FACING = ICE_AREA_1+ICE_AREA_2/**/
/**/private constant real MAX_COUNT = DUMMY_COUNT*2 /**/
//***************************************************************************
endglobals
//Damage settings********************************************
constant function damageSetting takes integer lvl returns real
return DAMAGE_BASE*lvl
endfunction
//************************************************************
//Duration settings*******************************************
constant function durationSetting takes integer lvl returns real
return LOTUS_DURATION+lvl
endfunction
//************************************************************
//Conditions function*****************************************
constant function conditionFunc takes player caster_owner,unit other returns boolean
/**/ //Assure a better death check//
/**/return IsUnitEnemy(other,caster_owner) and /**/GetUnitTypeId(other) != 0/**/and not IsUnitType(other,UNIT_TYPE_DEAD)
endfunction
//************************************************************
private struct LotusIce
unit dummy
weathereffect weather
real vinc
real value_inc
real frost_rep
real frost_int
real frost_inc
real ag
real gx
real gy
real lotus_dur
boolean frost_active = false
boolean spell_active = true
integer frost_count = FROST_COUNT
integer fade
integer value_fade = 0
player playe
static method onPeriodic takes nothing returns nothing
local integer i = 0
local integer l = 0
local real a
local real x
local real y
local unit f = null
local thistype this
loop
exitwhen i > MUI
set this = StructData[i]
if spell_active then
if value_inc < ICE_SCALE_1 then
set value_inc = value_inc + vinc
set value_fade = value_fade + fade
call SetUnitScale(dummy,value_inc,0.,0.)
call SetUnitVertexColor(dummy,255,255,255,value_fade)
else
if lotus_dur > 0. then
set lotus_dur = lotus_dur - PERIODIC
set Main_Time = lotus_dur
if frost_rep < FROST_REPEAT and frost_count == FROST_COUNT then
set frost_rep = frost_rep + PERIODIC
else
set frost_rep = 0.
set frost_active = true
endif
if frost_active then
if frost_int < FROST_INTEVAR then
set frost_int = frost_int + PERIODIC
else
set frost_int = 0.
if frost_count > 0 then
set frost_inc = frost_inc + RANGE_PER_PERIOD
set frost_count = frost_count - 1
static if not DO_DUMMY_INIT then
set Dummy = CreateUnit(Player(15),CASTER_DUMMY,0.,0.,0.)
endif
loop
exitwhen i > DUMMY_COUNT
set a = .0174533*i*ag
set x = gx + frost_inc * Cos(a)
set y = gy + frost_inc * Sin(a)
call DestroyEffect(AddSpecialEffect(ICE_EFFECT,x,y))
call GroupEnumUnitsInRange(G,x,y,FREEZE_RADIUS,null)
loop
set f = FirstOfGroup(G)
exitwhen f == null
if conditionFunc(playe,f) then
call SetUnitX(Dummy,GetUnitX(f))
call SetUnitY(Dummy,GetUnitY(f))
call IssueTargetOrder(Dummy,ORDER_ID,f)
endif
call GroupRemoveUnit(G,f)
endloop
set i = i + 1
endloop
static if not DO_DUMMY_INIT then
call RemoveUnit(Dummy)
endif
else
set frost_inc = 0.
set frost_count = FROST_COUNT
set frost_active = false
endif
endif
endif
else
set spell_active = false
endif
endif
elseif value_inc > 0. then
set value_inc = value_inc - vinc
set value_fade = value_fade - fade
call SetUnitScale(dummy,value_inc,0.,0.)
call SetUnitVertexColor(dummy,255,255,255,value_fade)
else
set StructData[i] = StructData[MUI]
set StructData[MUI] = -2
set MUI = MUI - 1
if MUI == -1 then
call PauseTimer(TIMER)
endif
call RemoveUnit(dummy)
call RemoveWeatherEffect(weather)
set weather = null
set dummy = null
set playe = null
call destroy()
endif
set i = i + 1
endloop
endmethod
static method onCast takes nothing returns boolean
local thistype this
local integer i
local integer l
local integer alvl
local integer unitid
local real dx
local real dy
local real angle
local real cs
local real sc
local real rg
local real icea
local real cos
local real sin
local unit caster
if GetSpellAbilityId() != SPELL_ID then
set caster = null
return false
endif
set this = allocate()
set MUI = MUI + 1
set StructData[MUI] = this
set playe = GetTriggerPlayer()
set caster = GetTriggerUnit()
set gx = GetSpellTargetX()
set gy = GetSpellTargetY()
call SetRect(RECT,gx-FACING,gy-FACING,gx+FACING,gy+FACING)
set weather = AddWeatherEffect(RECT,WEATHER_TYPE)
call EnableWeatherEffect( weather, true )
set alvl = GetUnitAbilityLevel(caster,SPELL_ID)
set lotus_dur = durationSetting(alvl)
set ag = 360./DUMMY_COUNT
set i = 0
set fade = R2I(255./RANGE_MISSLE_2*MISSLE_SPEED)
set dummy = CreateUnit(Player(15),DUMMY_DEG_1,gx,gy,0.)
call SetUnitScale(dummy,0.,0.,0.)
call SetUnitVertexColor(dummy,255,255,255,0)
loop
exitwhen i > MAX_COUNT
if i < DUMMY_COUNT then
set cs = .0174533*i*ag
set cos = Cos(cs)
set sin = Sin(cs)
set rg = RANGE_MISSLE_1
set frost_int = gx + FACING * cos
set frost_inc = gy + FACING * sin
set value_inc = gx + rg * cos
set frost_rep = gy + rg * sin
set unitid = DUMMY_DEG_2
set icea = ICE_AREA_1
set dx = gx + icea * cos
set dy = gy + icea * sin
set sc = ICE_SCALE_2
else
set rg = RANGE_MISSLE_2
set l = i - DUMMY_COUNT
set cs = .0174533*l*ag
set cos = Cos(cs)
set sin = Sin(cs)
set frost_int = gx + FACING * cos
set frost_inc = gy + FACING * sin
set value_inc = gx + rg * cos
set frost_rep = gy + rg * sin
set unitid = DUMMY_DEG_3
set rg = RANGE_MISSLE_2
set icea = ICE_AREA_2
set dx = gx + icea * cos
set dy = gy + icea * sin
set sc = ICE_SCALE_3
endif
set angle = 57.29583 * Atan2(frost_inc - dy, frost_int - dx)
set vinc = 57.29583 * Atan2(gy - frost_rep, gx - value_inc)
call LotusIce_LotusIcePlugin.add(CreateUnit(Player(15),DUMMY_MISSLE,value_inc,frost_rep,vinc),unitid,dx,dy,angle,vinc,rg,icea,sc,gx,gy,i,damageSetting(alvl),playe,caster,dummy)
set i = i + 1
endloop
set value_inc = 0.
set frost_rep = 0.
set frost_int = 0.
set frost_inc = 0.
set vinc = ICE_SCALE_1/RANGE_MISSLE_2*MISSLE_SPEED
if MUI == 0 then
call TimerStart(TIMER,PERIODIC,true,function thistype.onPeriodic)
endif
set caster = null
return false
endmethod
static method onInit takes nothing returns nothing
local integer i = 0
local trigger t = CreateTrigger()
loop
exitwhen i > 15
call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
set i = i + 1
endloop
call TriggerAddCondition(t,function thistype.onCast)
static if DO_DUMMY_INIT then
set Dummy = CreateUnit(Player(15),CASTER_DUMMY,0.,0.,0.)
endif
endmethod
endstruct
public struct LotusIcePlugin
unit dummy
unit caster
unit mdummy
integer dummyid
integer count
boolean spell_active = true
player playe
real scale = 0.
real dmg
real tx
real ty
real dx
real dy
real df
real cos
real sin
real maxsc
real icearea
real distance
real dmg_int = 0.
static method onPeriodic takes nothing returns nothing
local integer i = 0
local real a
local real x
local real y
local boolean pull
local boolean dmg_active = false
local unit f = null
local thistype this
loop
exitwhen i > PMUI
set this = PStructData[i]
if spell_active then
if distance > icearea then
set distance = distance - MISSLE_SPEED
set x = GetUnitX(dummy) + MISSLE_SPEED * cos
set y = GetUnitY(dummy) + MISSLE_SPEED * sin
call SetUnitX(dummy,x)
call SetUnitY(dummy,y)
elseif scale < maxsc then
if GetUnitTypeId(dummy) > 0 then
if GetRandomInt(0,100) <= EFFECT_NUMBER then
call DestroyEffect(AddSpecialEffect(ICE_EFFECT,dx,dy))
endif
call RemoveUnit(dummy)
set dummy = CreateUnit(Player(15),dummyid,dx,dy,df)
call SetUnitScale(dummy,0.,0.,0.)
endif
set scale = scale + SCALE_PER_PERIOD
call SetUnitScale(dummy,scale,0.,0.)
else
if dmg_int < DAMAGE_INTEVAR then
set dmg_int = dmg_int + PERIODIC
else
set dmg_int = 0.
set dmg_active = true
endif
if GetUnitAbilityLevel(f,BUFF_ID) == 0 then
call GroupEnumUnitsInRange(G,dx,dy,KNOCK_RADIUS,null)
set pull = false
else
call GroupEnumUnitsInRange(G,dx,dy,PULL_RANGE,null)
set pull = true
endif
loop
set f = FirstOfGroup(G)
exitwhen f == null
if conditionFunc(playe,f) then
set x = GetUnitX(f)
set y = GetUnitY(f)
if GetUnitAbilityLevel(f,BUFF_ID) == 0 then
set df = 57.29583 * Atan2(y - dy,x - dx)
set a = .0174533*df
set x = x + ENEMIES_KNOCK * Cos(a)
set y = y + ENEMIES_KNOCK * Sin(a)
else
set df = 57.29583 * Atan2(dy - y,dx - x)
set a = .0174533*df
set x = x + ENEMIES_PULL * Cos(a)
set y = y + ENEMIES_PULL * Sin(a)
endif
call SetUnitX(f,x)
call SetUnitY(f,y)
endif
call GroupRemoveUnit(G,f)
endloop
if dmg_active then
call GroupEnumUnitsInRange(G,dx,dy,DMG_RADIUS,null)
loop
set f = FirstOfGroup(G)
exitwhen f == null
if conditionFunc(playe,f) then
call UnitDamageTarget(caster,f,dmg,true,false,ATTACK_TYPE,DAMAGE_TYPE,WEAPON_TYPE)
endif
call GroupRemoveUnit(G,f)
endloop
endif
if GetUnitTypeId(mdummy) == 0 then
set spell_active = false
endif
endif
elseif scale > 0. then
set scale = scale - SCALE_PER_PERIOD
call SetUnitScale(dummy,scale,0.,0.)
else
set PStructData[i] = PStructData[PMUI]
set PStructData[PMUI] = -2
set PMUI = PMUI - 1
if PMUI == -1 then
call PauseTimer(TIMER_2)
endif
call RemoveUnit(dummy)
set dummy = null
set caster = null
set playe = null
call destroy()
endif
set i = i + 1
endloop
endmethod
static method add takes unit u,integer unitid,real x,real y,real f,real f1,real rg,real icea,real sc,real t,real tt,integer c,real damage,player p,unit ct,unit maind returns nothing
local thistype this = allocate()
set PMUI = PMUI + 1
set PStructData[PMUI] = this
set maxsc = sc
set dummy = u
set dummyid = unitid
set dx = x
set dy = y
set df = f
set cos = Cos(.0174533*f1)
set sin = Sin(.0174533*f1)
set icearea = icea
set distance = rg
set count = c
set tx = t
set ty = tt
set dmg = damage
set playe = p
set caster = ct
set mdummy = maind
if PMUI == 0 then
call TimerStart(TIMER_2,PERIODIC,true,function thistype.onPeriodic)
endif
endmethod
endstruct
endlibrary